@turquoisehealth/pit-viper 2.194.3-dev.1 → 2.194.4

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 (176) hide show
  1. package/_site/assets/css/pit-viper-a11y.css +258 -10
  2. package/_site/assets/css/pit-viper-consumer.css +258 -10
  3. package/_site/assets/css/pit-viper-v2-scoped.css +223 -10
  4. package/_site/assets/css/pit-viper-v2.css +258 -10
  5. package/_site/assets/css/pit-viper.css +258 -10
  6. package/package.json +15 -15
  7. package/pv-components/dist/stats/vue/base/stats.html +1 -1
  8. package/pv-components/dist/stats/vue/visualizations/stats.html +1 -1
  9. package/pv-components/dist/stats/web/pv-accordion-stats.html +1 -1
  10. package/pv-components/dist/stats/web/pv-action-bar-stats.html +1 -1
  11. package/pv-components/dist/stats/web/pv-ai-button-stats.html +1 -1
  12. package/pv-components/dist/stats/web/pv-avatar-group-stats.html +1 -1
  13. package/pv-components/dist/stats/web/pv-avatar-stats.html +1 -1
  14. package/pv-components/dist/stats/web/pv-banner-stats.html +1 -1
  15. package/pv-components/dist/stats/web/pv-breadcrumbs-stats.html +1 -1
  16. package/pv-components/dist/stats/web/pv-button-stats.html +1 -1
  17. package/pv-components/dist/stats/web/pv-card-stats.html +1 -1
  18. package/pv-components/dist/stats/web/pv-checkbox-stats.html +1 -1
  19. package/pv-components/dist/stats/web/pv-company-label-stats.html +1 -1
  20. package/pv-components/dist/stats/web/pv-company-logo-stats.html +1 -1
  21. package/pv-components/dist/stats/web/pv-company-tag-stats.html +1 -1
  22. package/pv-components/dist/stats/web/pv-counter-badge-stats.html +1 -1
  23. package/pv-components/dist/stats/web/pv-date-picker-stats.html +1 -1
  24. package/pv-components/dist/stats/web/pv-date-time-stats.html +1 -1
  25. package/pv-components/dist/stats/web/pv-distribution-bar-stats.html +1 -1
  26. package/pv-components/dist/stats/web/pv-drawer-stats.html +1 -1
  27. package/pv-components/dist/stats/web/pv-dropdown-stats.html +1 -1
  28. package/pv-components/dist/stats/web/pv-expandable-content-stats.html +1 -1
  29. package/pv-components/dist/stats/web/pv-filter-panel-stats.html +4950 -0
  30. package/pv-components/dist/stats/web/pv-ghost-input-stats.html +1 -1
  31. package/pv-components/dist/stats/web/pv-header-stats.html +1 -1
  32. package/pv-components/dist/stats/web/pv-horizontal-scroller-stats.html +4950 -0
  33. package/pv-components/dist/stats/web/pv-icon-stats.html +1 -1
  34. package/pv-components/dist/stats/web/pv-input-stats.html +1 -1
  35. package/pv-components/dist/stats/web/pv-insight-card-stats.html +1 -1
  36. package/pv-components/dist/stats/web/pv-menu-stats.html +1 -1
  37. package/pv-components/dist/stats/web/pv-modal-stats.html +1 -1
  38. package/pv-components/dist/stats/web/pv-multi-select-button-stats.html +1 -1
  39. package/pv-components/dist/stats/web/pv-pagination-stats.html +1 -1
  40. package/pv-components/dist/stats/web/pv-pill-stats.html +1 -1
  41. package/pv-components/dist/stats/web/pv-popover-menu-stats.html +1 -1
  42. package/pv-components/dist/stats/web/pv-popover-stats.html +1 -1
  43. package/pv-components/dist/stats/web/pv-popover-v2-stats.html +1 -1
  44. package/pv-components/dist/stats/web/pv-progress-bar-stats.html +1 -1
  45. package/pv-components/dist/stats/web/pv-query-builder-input-stats.html +1 -1
  46. package/pv-components/dist/stats/web/pv-radio-group-stats.html +1 -1
  47. package/pv-components/dist/stats/web/pv-range-stats.html +1 -1
  48. package/pv-components/dist/stats/web/pv-rating-stats.html +1 -1
  49. package/pv-components/dist/stats/web/pv-release-badge-stats.html +1 -1
  50. package/pv-components/dist/stats/web/pv-search-input-stats.html +1 -1
  51. package/pv-components/dist/stats/web/pv-segmented-control-stats.html +1 -1
  52. package/pv-components/dist/stats/web/pv-select-button-stats.html +1 -1
  53. package/pv-components/dist/stats/web/pv-selectable-card-stats.html +1 -1
  54. package/pv-components/dist/stats/web/pv-side-panel-stats.html +1 -1
  55. package/pv-components/dist/stats/web/pv-skeleton-stats.html +1 -1
  56. package/pv-components/dist/stats/web/pv-spinner-stats.html +1 -1
  57. package/pv-components/dist/stats/web/pv-sprite-stats.html +1 -1
  58. package/pv-components/dist/stats/web/pv-stepper-stats.html +1 -1
  59. package/pv-components/dist/stats/web/pv-suggestion-tag-stats.html +1 -1
  60. package/pv-components/dist/stats/web/pv-switch-stats.html +1 -1
  61. package/pv-components/dist/stats/web/pv-tab-list-stats.html +1 -1
  62. package/pv-components/dist/stats/web/pv-table-of-contents-stats.html +1 -1
  63. package/pv-components/dist/stats/web/pv-tabs-stats.html +1 -1
  64. package/pv-components/dist/stats/web/pv-tag-stats.html +1 -1
  65. package/pv-components/dist/stats/web/pv-text-area-stats.html +1 -1
  66. package/pv-components/dist/stats/web/pv-toast-stats.html +1 -1
  67. package/pv-components/dist/stats/web/pv-toggle-button-stats.html +1 -1
  68. package/pv-components/dist/stats/web/pv-toggle-group-stats.html +1 -1
  69. package/pv-components/dist/stats/web/pv-tooltip-stats.html +1 -1
  70. package/pv-components/dist/stats/web/pv-tooltip-v2-stats.html +1 -1
  71. package/pv-components/dist/stats/web/pv-tree-stats.html +1 -1
  72. package/pv-components/dist/stats/web/pv-widget-stats.html +1 -1
  73. package/pv-components/dist/vue/base/components/base/PvFilterPanel/PvFilterPanel.vue.d.ts +73 -0
  74. package/pv-components/dist/vue/base/components/base/PvFilterPanel/PvFilterPanelAccordion.vue.d.ts +18 -0
  75. package/pv-components/dist/vue/base/components/base/PvFilterPanel/PvFilterPanelAppliedFiltersSection.vue.d.ts +12 -0
  76. package/pv-components/dist/vue/base/components/base/PvFilterPanel/PvFilterPanelCategoryButtonRow.vue.d.ts +14 -0
  77. package/pv-components/dist/vue/base/components/base/PvFilterPanel/PvFilterPanelOptionRow.vue.d.ts +34 -0
  78. package/pv-components/dist/vue/base/components/base/PvFilterPanel/advancedFilterModel.d.ts +26 -0
  79. package/pv-components/dist/vue/base/components/base/PvFilterPanel/aggregateFilterModel.d.ts +56 -0
  80. package/pv-components/dist/vue/base/components/base/PvFilterPanel/filterOptionDisplay.d.ts +28 -0
  81. package/pv-components/dist/vue/base/components/base/PvFilterPanel/filterOptionValue.d.ts +15 -0
  82. package/pv-components/dist/vue/base/components/base/PvFilterPanel/types.d.ts +402 -0
  83. package/pv-components/dist/vue/base/components/base/PvFilterPanel/usePvFilterStore.d.ts +5 -0
  84. package/pv-components/dist/vue/base/components/base/PvHorizontalScroller/PvHorizontalScroller.vue.d.ts +36 -0
  85. package/pv-components/dist/vue/base/components/base/PvHorizontalScroller/types.d.ts +21 -0
  86. package/pv-components/dist/vue/base/components/base/PvRange/PvRange.vue.d.ts +27 -15
  87. package/pv-components/dist/vue/base/components/base/PvRange/types.d.ts +44 -0
  88. package/pv-components/dist/vue/base/components/base/index.d.ts +6 -0
  89. package/pv-components/dist/vue/base/pv-components-base.mjs +3729 -1117
  90. package/pv-components/dist/vue/base/pv-components-base.mjs.map +1 -1
  91. package/pv-components/dist/vue/visualizations/components/base/PvFilterPanel/PvFilterPanel.vue.d.ts +73 -0
  92. package/pv-components/dist/vue/visualizations/components/base/PvFilterPanel/PvFilterPanelAccordion.vue.d.ts +18 -0
  93. package/pv-components/dist/vue/visualizations/components/base/PvFilterPanel/PvFilterPanelAppliedFiltersSection.vue.d.ts +12 -0
  94. package/pv-components/dist/vue/visualizations/components/base/PvFilterPanel/PvFilterPanelCategoryButtonRow.vue.d.ts +14 -0
  95. package/pv-components/dist/vue/visualizations/components/base/PvFilterPanel/PvFilterPanelOptionRow.vue.d.ts +34 -0
  96. package/pv-components/dist/vue/visualizations/components/base/PvFilterPanel/advancedFilterModel.d.ts +26 -0
  97. package/pv-components/dist/vue/visualizations/components/base/PvFilterPanel/aggregateFilterModel.d.ts +56 -0
  98. package/pv-components/dist/vue/visualizations/components/base/PvFilterPanel/filterOptionDisplay.d.ts +28 -0
  99. package/pv-components/dist/vue/visualizations/components/base/PvFilterPanel/filterOptionValue.d.ts +15 -0
  100. package/pv-components/dist/vue/visualizations/components/base/PvFilterPanel/types.d.ts +402 -0
  101. package/pv-components/dist/vue/visualizations/components/base/PvFilterPanel/usePvFilterStore.d.ts +5 -0
  102. package/pv-components/dist/vue/visualizations/components/base/PvHorizontalScroller/PvHorizontalScroller.vue.d.ts +36 -0
  103. package/pv-components/dist/vue/visualizations/components/base/PvHorizontalScroller/types.d.ts +21 -0
  104. package/pv-components/dist/vue/visualizations/components/base/PvRange/PvRange.vue.d.ts +27 -15
  105. package/pv-components/dist/vue/visualizations/components/base/PvRange/types.d.ts +44 -0
  106. package/pv-components/dist/vue/visualizations/components/base/index.d.ts +6 -0
  107. package/pv-components/dist/vue/visualizations/components/charts/PvDataTableWithChart/PvDataTableWithChart.vue.d.ts +1 -1
  108. package/pv-components/dist/vue/visualizations/components/tables/PvDataTable/table-components/SetFilter.vue.d.ts +2 -2
  109. package/pv-components/dist/vue/visualizations/pv-components-visualizations.mjs +4 -1
  110. package/pv-components/dist/vue/visualizations/pv-components-visualizations.mjs.map +1 -1
  111. package/pv-components/dist/web/components/pv-accordion/pv-accordion.js +35 -28
  112. package/pv-components/dist/web/components/pv-action-bar/pv-action-bar.js +397 -390
  113. package/pv-components/dist/web/components/pv-ai-button/pv-ai-button.js +35 -28
  114. package/pv-components/dist/web/components/pv-avatar/pv-avatar.js +35 -28
  115. package/pv-components/dist/web/components/pv-avatar-group/pv-avatar-group.js +274 -267
  116. package/pv-components/dist/web/components/pv-banner/pv-banner.js +35 -28
  117. package/pv-components/dist/web/components/pv-breadcrumbs/pv-breadcrumbs.js +356 -349
  118. package/pv-components/dist/web/components/pv-button/pv-button.js +35 -28
  119. package/pv-components/dist/web/components/pv-card/pv-card.js +35 -28
  120. package/pv-components/dist/web/components/pv-checkbox/pv-checkbox.js +35 -28
  121. package/pv-components/dist/web/components/pv-company-label/pv-company-label.js +35 -28
  122. package/pv-components/dist/web/components/pv-company-logo/pv-company-logo.js +131 -124
  123. package/pv-components/dist/web/components/pv-company-tag/pv-company-tag.js +35 -28
  124. package/pv-components/dist/web/components/pv-counter-badge/pv-counter-badge.js +209 -202
  125. package/pv-components/dist/web/components/pv-date-picker/pv-date-picker.js +71 -64
  126. package/pv-components/dist/web/components/pv-date-time/pv-date-time.js +35 -28
  127. package/pv-components/dist/web/components/pv-distribution-bar/pv-distribution-bar.js +508 -501
  128. package/pv-components/dist/web/components/pv-drawer/pv-drawer.js +35 -28
  129. package/pv-components/dist/web/components/pv-dropdown/pv-dropdown.js +410 -403
  130. package/pv-components/dist/web/components/pv-expandable-content/pv-expandable-content.js +49 -42
  131. package/pv-components/dist/web/components/pv-filter-panel/pv-filter-panel.js +10769 -0
  132. package/pv-components/dist/web/components/pv-ghost-input/pv-ghost-input.js +35 -28
  133. package/pv-components/dist/web/components/pv-header/pv-header.js +50 -43
  134. package/pv-components/dist/web/components/pv-horizontal-scroller/pv-horizontal-scroller.js +6476 -0
  135. package/pv-components/dist/web/components/pv-icon/pv-icon.js +513 -506
  136. package/pv-components/dist/web/components/pv-input/pv-input.js +35 -28
  137. package/pv-components/dist/web/components/pv-insight-card/pv-insight-card.js +182 -175
  138. package/pv-components/dist/web/components/pv-menu/pv-menu.js +35 -28
  139. package/pv-components/dist/web/components/pv-modal/pv-modal.js +35 -28
  140. package/pv-components/dist/web/components/pv-multi-select-button/pv-multi-select-button.js +702 -695
  141. package/pv-components/dist/web/components/pv-pagination/pv-pagination.js +35 -28
  142. package/pv-components/dist/web/components/pv-pill/pv-pill.js +356 -349
  143. package/pv-components/dist/web/components/pv-popover/pv-popover.js +35 -28
  144. package/pv-components/dist/web/components/pv-popover-menu/pv-popover-menu.js +168 -161
  145. package/pv-components/dist/web/components/pv-popover-v2/pv-popover-v2.js +35 -28
  146. package/pv-components/dist/web/components/pv-progress-bar/pv-progress-bar.js +103 -96
  147. package/pv-components/dist/web/components/pv-query-builder-input/pv-query-builder-input.js +452 -445
  148. package/pv-components/dist/web/components/pv-radio-group/pv-radio-group.js +35 -28
  149. package/pv-components/dist/web/components/pv-range/pv-range.js +1117 -530
  150. package/pv-components/dist/web/components/pv-rating/pv-rating.js +35 -28
  151. package/pv-components/dist/web/components/pv-release-badge/pv-release-badge.js +209 -202
  152. package/pv-components/dist/web/components/pv-search-input/pv-search-input.js +35 -28
  153. package/pv-components/dist/web/components/pv-segmented-control/pv-segmented-control.js +35 -28
  154. package/pv-components/dist/web/components/pv-select-button/pv-select-button.js +35 -28
  155. package/pv-components/dist/web/components/pv-selectable-card/pv-selectable-card.js +509 -502
  156. package/pv-components/dist/web/components/pv-side-panel/pv-side-panel.js +356 -349
  157. package/pv-components/dist/web/components/pv-skeleton/pv-skeleton.js +35 -28
  158. package/pv-components/dist/web/components/pv-spinner/pv-spinner.js +397 -390
  159. package/pv-components/dist/web/components/pv-sprite/pv-sprite.js +397 -390
  160. package/pv-components/dist/web/components/pv-stepper/pv-stepper.js +35 -28
  161. package/pv-components/dist/web/components/pv-suggestion-tag/pv-suggestion-tag.js +35 -28
  162. package/pv-components/dist/web/components/pv-switch/pv-switch.js +35 -28
  163. package/pv-components/dist/web/components/pv-tab-list/pv-tab-list.js +35 -28
  164. package/pv-components/dist/web/components/pv-table-of-contents/pv-table-of-contents.js +35 -28
  165. package/pv-components/dist/web/components/pv-tabs/pv-tabs.js +35 -28
  166. package/pv-components/dist/web/components/pv-tag/pv-tag.js +402 -395
  167. package/pv-components/dist/web/components/pv-text-area/pv-text-area.js +35 -28
  168. package/pv-components/dist/web/components/pv-toast/pv-toast.js +402 -395
  169. package/pv-components/dist/web/components/pv-toggle-button/pv-toggle-button.js +35 -28
  170. package/pv-components/dist/web/components/pv-toggle-group/pv-toggle-group.js +35 -28
  171. package/pv-components/dist/web/components/pv-tooltip/pv-tooltip.js +35 -28
  172. package/pv-components/dist/web/components/pv-tooltip-v2/pv-tooltip-v2.js +100 -93
  173. package/pv-components/dist/web/components/pv-tree/pv-tree.js +35 -28
  174. package/pv-components/dist/web/components/pv-widget/pv-widget.js +356 -349
  175. package/pv-components/dist/web/pv-components.iife.js +38 -38
  176. package/pv-components/dist/web/pv-components.iife.js.map +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"pv-components-base.mjs","names":["$props","$emit","$emit","$emit","computePosition","flip","offset","getComputedStyle","unwrapElement","$slots","$props","$slots","$slots","$emit","$emit","$emit","$slots","$emit","$emit","$props","$slots","$emit","$slots","$emit","$emit","$slots","$attrs","$emit","$emit","$emit","$emit"],"sources":["../../../src/components/base/PvSpinner/PvSpinner.vue","../../../src/components/base/PvSpinner/PvSpinner.vue","../../../src/components/base/PvButton/helpers.ts","../../../src/web-components/utils.ts","../../../src/components/base/baseProps.ts","../../../src/components/base/PvIcon/PvIcon.vue","../../../src/components/base/PvIcon/PvIcon.vue","../../../src/components/base/PvCounterBadge/PvCounterBadge.vue","../../../src/components/base/PvCounterBadge/PvCounterBadge.vue","../../../src/components/base/PvButton/PvButton.vue","../../../src/components/base/PvButton/PvButton.vue","../../../src/components/base/PvAiButton/PvAiButton.vue","../../../src/components/base/PvAiButton/PvAiButton.vue","../../../src/composables/useSlotPresence.ts","../../../src/components/base/PvTooltip/PvTooltip.vue","../../../src/components/base/PvTooltip/PvTooltip.vue","../../../src/components/base/PvButton/PvButtonWithTooltip.vue","../../../src/components/base/PvButton/PvButtonWithTooltip.vue","../../../src/components/base/PvReleaseBadge/PvReleaseBadge.vue","../../../src/components/base/PvReleaseBadge/PvReleaseBadge.vue","../../../src/components/base/PvTag/PvTag.vue","../../../src/components/base/PvTag/PvTag.vue","../../../src/components/base/PvPill/PvPill.vue","../../../src/components/base/PvPill/PvPill.vue","../../../src/components/base/PvPopover/PvPopover.vue","../../../src/components/base/PvPopover/PvPopover.vue","../../../src/components/base/PvDropdown/PvDropdown.vue","../../../src/components/base/PvDropdown/PvDropdown.vue","../../../src/components/base/PvPopoverMenu/PvPopoverMenu.vue","../../../src/components/base/PvPopoverMenu/PvPopoverMenu.vue","../../../../node_modules/.pnpm/@floating-ui+utils@0.2.11/node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs","../../../../node_modules/.pnpm/@floating-ui+core@1.7.5/node_modules/@floating-ui/core/dist/floating-ui.core.mjs","../../../../node_modules/.pnpm/@floating-ui+utils@0.2.11/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs","../../../../node_modules/.pnpm/@floating-ui+dom@1.7.6/node_modules/@floating-ui/dom/dist/floating-ui.dom.mjs","../../../../node_modules/.pnpm/vue-demi@0.14.10_vue@3.5.32_typescript@5.9.3_/node_modules/vue-demi/lib/index.mjs","../../../../node_modules/.pnpm/@floating-ui+vue@1.1.11_vue@3.5.32_typescript@5.9.3_/node_modules/@floating-ui/vue/dist/floating-ui.vue.mjs","../../../src/components/base/PvPopoverV2/PvPopoverV2.vue","../../../src/components/base/PvPopoverV2/PvPopoverV2.vue","../../../src/components/base/PvTooltipV2/PvTooltipV2.vue","../../../src/components/base/PvTooltipV2/PvTooltipV2.vue","../../../src/components/base/PvSegmentedControl/PvSegmentedControl.vue","../../../src/components/base/PvSegmentedControl/PvSegmentedControl.vue","../../../src/components/base/PvTabList/PvTabList.vue","../../../src/components/base/PvTabList/PvTabList.vue","../../../src/components/base/PvCompanyLogo/PvCompanyLogo.vue","../../../src/components/base/PvCompanyLogo/PvCompanyLogo.vue","../../../src/components/base/PvModal/PvModal.vue","../../../src/components/base/PvModal/PvModal.vue","../../../src/components/base/PvBanner/types.ts","../../../src/components/base/PvBanner/PvBanner.vue","../../../src/components/base/PvBanner/PvBanner.vue","../../../src/components/base/PvCompanyTag/PvCompanyTag.vue","../../../src/components/base/PvCompanyTag/PvCompanyTag.vue","../../../src/components/base/PvSuggestionTag/PvSuggestionTag.vue","../../../src/components/base/PvSuggestionTag/PvSuggestionTag.vue","../../../src/components/base/PvAccordion/PvAccordion.vue","../../../src/components/base/PvAccordion/PvAccordion.vue","../../../src/components/base/PvSearchInput/PvSearchInput.vue","../../../src/components/base/PvSearchInput/PvSearchInput.vue","../../../src/components/base/PvDatePicker/PvDatePicker.vue","../../../src/components/base/PvDatePicker/PvDatePicker.vue","../../../src/components/base/PvDateTime/useDateTime.ts","../../../src/components/base/PvDateTime/PvDateTime.vue","../../../src/components/base/PvDateTime/PvDateTime.vue","../../../src/components/base/PvDrawer/PvDrawer.vue","../../../src/components/base/PvDrawer/PvDrawer.vue","../../../src/components/base/PvTabs/PvTabs.vue","../../../src/components/base/PvTabs/PvTabs.vue","../../../src/components/base/PvBreadcrumbs/PvBreadcrumbs.vue","../../../src/components/base/PvBreadcrumbs/PvBreadcrumbs.vue","../../../src/components/base/PvMenu/PvMenuControlPanel.vue","../../../src/components/base/PvMenu/PvMenuControlPanel.vue","../../../src/components/base/PvAvatar/PvAvatar.vue","../../../src/components/base/PvAvatar/PvAvatar.vue","../../../src/components/base/PvSelectButton/PvSelectButtonTrigger/PvSelectButtonTrigger.vue","../../../src/components/base/PvSelectButton/PvSelectButtonTrigger/PvSelectButtonTrigger.vue","../../../src/components/base/PvMenu/PvMenuEmptyState.vue","../../../src/components/base/PvMenu/cascadeUtils.ts","../../../src/components/base/PvMenu/items/PvMenuBaseItem.vue","../../../src/components/base/PvMenu/items/PvMenuBaseItem.vue","../../../src/components/base/PvSwitch/PvSwitch.vue","../../../src/components/base/PvSwitch/PvSwitch.vue","../../../src/components/base/PvMenu/items/PvMenuItemAction.vue","../../../src/components/base/PvMenu/items/PvMenuItemAction.vue","../../../src/components/base/PvMenu/symbols.ts","../../../src/components/base/PvMenu/items/PvMenuItemVariant.vue","../../../src/components/base/PvMenu/items/PvMenuItemVariant.vue","../../../src/components/base/PvMenu/items/PvMenuItem.vue","../../../src/components/base/PvMenu/items/PvMenuItem.vue","../../../src/components/base/PvMenu/PvMenu.vue","../../../src/components/base/PvMenu/PvMenu.vue","../../../src/components/base/PvMultiSelectButton/PvMultiSelectButton.vue","../../../src/components/base/PvMultiSelectButton/PvMultiSelectButton.vue","../../../src/components/base/PvSelectButton/PvSelectButton.vue","../../../src/components/base/PvSelectButton/PvSelectButton.vue","../../../src/components/base/PvPagination/usePagination.ts","../../../src/components/base/PvPagination/PvPagination.vue","../../../src/components/base/PvPagination/PvPagination.vue","../../../src/components/base/PvSelectableCard/PvSelectableCard.vue","../../../src/components/base/PvSelectableCard/PvSelectableCard.vue","../../../src/components/layout/PvSidePanel/PvSidePanel.vue","../../../src/components/layout/PvSidePanel/PvSidePanel.vue","../../../src/components/base/PvGhostInput/PvGhostInput.vue","../../../src/components/base/PvGhostInput/PvGhostInput.vue","../../../src/components/base/PvHeader/PvHeader.vue","../../../src/components/base/PvHeader/PvHeader.vue","../../../src/components/base/PvCompanyLabel/PvCompanyLabel.vue","../../../src/components/base/PvCompanyLabel/PvCompanyLabel.vue","../../../src/components/base/PvAvatarGroup/PvAvatarGroup.vue","../../../src/components/base/PvAvatarGroup/PvAvatarGroup.vue","../../../src/components/base/PvToggleButton/PvToggleButton.vue","../../../src/components/base/PvToggleButton/PvToggleButton.vue","../../../src/components/base/PvToggleGroup/PvToggleGroup.vue","../../../src/components/base/PvToggleGroup/PvToggleGroup.vue","../../../src/components/base/PvCheckbox/PvCheckbox.vue","../../../src/components/base/PvCheckbox/PvCheckbox.vue","../../../src/components/base/PvRadioGroup/PvRadioGroup.vue","../../../src/components/base/PvRadioGroup/PvRadioGroup.vue","../../../src/components/base/PvSprite/PvSprite.vue","../../../src/components/base/PvSprite/PvSprite.vue","../../../src/components/base/PvSkeleton/PvSkeleton.vue","../../../src/components/base/PvSkeleton/PvSkeleton.vue","../../../src/components/base/PvInput/PvInput.vue","../../../src/components/base/PvInput/PvInput.vue","../../../src/components/base/PvRating/PvRating.vue","../../../src/components/base/PvRating/PvRating.vue","../../../src/components/base/PvCard/PvCard.vue","../../../src/components/base/PvCard/PvCard.vue","../../../src/components/base/PvWidget/PvWidget.vue","../../../src/components/base/PvWidget/PvWidget.vue","../../../src/components/base/PvInsightCard/PvInsightCard.vue","../../../src/components/base/PvInsightCard/PvInsightCard.vue","../../../src/components/base/PvExpandableContent/PvExpandableContent.vue","../../../src/components/base/PvExpandableContent/PvExpandableContent.vue","../../../src/components/base/PvToast/PvToast.vue","../../../src/components/base/PvToast/PvToast.vue","../../../src/components/base/PvActionBar/PvActionBar.vue","../../../src/components/base/PvActionBar/PvActionBar.vue","../../../src/components/base/PvTextArea/PvTextArea.vue","../../../src/components/base/PvTextArea/PvTextArea.vue","../../../src/components/base/PvTree/PvSimpleItemTree.vue","../../../src/components/base/PvTree/PvSimpleItemTree.vue","../../../src/components/base/PvTree/PvTreeReorderIcon.vue","../../../src/components/base/PvTree/PvTreeReorderIcon.vue","../../../src/components/base/PvTree/PvButtonTreeItem.vue","../../../src/components/base/PvTree/PvButtonTreeItem.vue","../../../src/components/base/PvTree/PvCheckboxTreeItem.vue","../../../src/components/base/PvTree/PvCheckboxTreeItem.vue","../../../src/components/base/PvTree/composables/useHoverIcon.ts","../../../src/components/base/PvTree/symbols.ts","../../../src/components/base/PvTree/composables/useDraggingState.ts","../../../src/components/base/PvTree/composables/useDragAndDrop.ts","../../../src/components/base/PvTree/composables/useDragAndDropIndicator.ts","../../../src/components/base/PvTree/PvSimpleNestedTreeItem.vue","../../../src/components/base/PvTree/PvSimpleNestedTreeItem.vue","../../../src/components/base/PvTree/PvSimpleNestedTree.vue","../../../src/components/base/PvTree/PvSimpleNestedTree.vue","../../../src/components/base/PvTree/PvTreeItem.vue","../../../src/components/base/PvTree/PvTreeItem.vue","../../../src/components/base/PvTree/composables/useTreeUpdate.ts","../../../src/components/base/PvTree/PvTree.vue","../../../src/components/base/PvTree/PvTree.vue","../../../src/components/base/PvTree/PvTreeGroup.vue","../../../src/components/base/PvTree/PvTreeGroup.vue","../../../src/components/base/PvProgressBar/PvProgressBar.vue","../../../src/components/base/PvProgressBar/PvProgressBar.vue","../../../src/components/base/PvDistributionBar/PvDistributionBar.vue","../../../src/components/base/PvDistributionBar/PvDistributionBar.vue","../../../src/components/base/PvQueryBuilderInput/useQueryBuilder.ts","../../../src/components/base/PvQueryBuilderInput/QueryBuilderMenuOptionRenderer.vue","../../../src/components/base/PvQueryBuilderInput/QueryBuilderMenuOptionRenderer.vue","../../../src/components/base/PvQueryBuilderInput/QueryFormatter.vue","../../../src/components/base/PvQueryBuilderInput/QueryFormatter.vue","../../../src/components/base/PvQueryBuilderInput/PvQueryBuilderInput.vue","../../../src/components/base/PvQueryBuilderInput/PvQueryBuilderInput.vue","../../../src/components/base/PvRange/PvRange.vue","../../../src/components/base/PvRange/PvRange.vue","../../../src/components/base/PvTableOfContents/PvTableOfContents.vue","../../../src/components/base/PvTableOfContents/PvTableOfContents.vue","../../../src/components/base/PvStepper/PvStepper.vue","../../../src/components/base/PvStepper/PvStepper.vue","../../../src/components/base/PvComponentsConfig/primeVue.config.ts","../../../src/components/base/PvComponentsConfig/usePvComponents.ts"],"sourcesContent":["<script setup lang=\"ts\">\nimport { PvSpinnerSize, PvSpinnerVariant } from \"./types\";\n\ninterface PvSpinnerProps {\n /** The size of the spinner. Controls the rendered diameter via a CSS custom property. */\n size?: PvSpinnerSize;\n /** The color variant of the spinner. Use \"white\" on dark backgrounds and \"dark\" on light backgrounds. */\n variant?: PvSpinnerVariant;\n}\n\nconst mapSizeToPx: Record<PvSpinnerSize, string> = {\n xs: \"0.75rem\",\n sm: \"1rem\",\n md: \"1.25rem\",\n lg: \"1.5rem\",\n xl: \"2rem\",\n};\n\nconst mapVariantToPvClass: Record<PvSpinnerVariant, string> = {\n primary: \"pv-spinner\",\n dark: \"pv-spinner-dark\",\n white: \"pv-spinner-light\",\n};\n\nwithDefaults(defineProps<PvSpinnerProps>(), {\n size: \"lg\",\n variant: \"primary\",\n});\n</script>\n\n<template>\n <div data-testid=\"pv-spinner\" :class=\"mapVariantToPvClass[variant]\" :style=\"{ '--size': mapSizeToPx[size] }\" />\n</template>\n","<script setup lang=\"ts\">\nimport { PvSpinnerSize, PvSpinnerVariant } from \"./types\";\n\ninterface PvSpinnerProps {\n /** The size of the spinner. Controls the rendered diameter via a CSS custom property. */\n size?: PvSpinnerSize;\n /** The color variant of the spinner. Use \"white\" on dark backgrounds and \"dark\" on light backgrounds. */\n variant?: PvSpinnerVariant;\n}\n\nconst mapSizeToPx: Record<PvSpinnerSize, string> = {\n xs: \"0.75rem\",\n sm: \"1rem\",\n md: \"1.25rem\",\n lg: \"1.5rem\",\n xl: \"2rem\",\n};\n\nconst mapVariantToPvClass: Record<PvSpinnerVariant, string> = {\n primary: \"pv-spinner\",\n dark: \"pv-spinner-dark\",\n white: \"pv-spinner-light\",\n};\n\nwithDefaults(defineProps<PvSpinnerProps>(), {\n size: \"lg\",\n variant: \"primary\",\n});\n</script>\n\n<template>\n <div data-testid=\"pv-spinner\" :class=\"mapVariantToPvClass[variant]\" :style=\"{ '--size': mapSizeToPx[size] }\" />\n</template>\n","import { PvButtonSize } from \"@/components/base/PvButton/types.ts\";\n\nexport const supportedInverseButtonVariants = [\"ghost\"];\n\nconst sizeToClassMap: Record<PvButtonSize, string | undefined> = {\n md: \"pv-button-small\",\n lg: undefined,\n xl: \"pv-button-large\",\n};\n\nexport const pvButtonSizeToClass = (size: PvButtonSize | null | undefined): string | null => {\n if (size == null || !sizeToClassMap.hasOwnProperty(size)) {\n return null;\n }\n return sizeToClassMap[size] || null;\n};\n","/**\n * Utility functions for web components\n */\n\nimport { ref, getCurrentInstance } from \"vue\";\n\n/**\n * Composable to detect if a component is running as a web component\n * Returns a reactive ref that's set to true/false on mount\n *\n * @returns Reactive ref boolean indicating if running as web component\n *\n * @example\n * import { useIsWebComponent } from '@/web-components/utils';\n *\n * export default {\n * setup() {\n * const isWc = useIsWebComponent();\n * // isWc.value is true if running as web component, false if Vue component\n * }\n * }\n */\nexport function useIsWebComponent() {\n const isWc = ref(false);\n const instance = getCurrentInstance();\n const root = instance?.root || {};\n if (\"isCE\" in root && root.isCE === true) {\n isWc.value = true;\n }\n return isWc;\n}\n","export const PvSizes = [\"xs\", \"sm\", \"md\", \"lg\", \"xl\", \"2x\"] as const;\nexport type PvSize = (typeof PvSizes)[number];\n\nexport const PvTheme = [\"white\", \"dark\"] as const;\nexport type PvThemes = (typeof PvTheme)[number];\n\nexport const PvVariants = [\"primary\", \"secondary\", \"tertiary\", \"ghost\", \"destructive\", \"transparent\"] as const;\nexport type PvVariants = (typeof PvVariants)[number];\n\nexport const PvColorVariants = [\"default\", \"success\", \"warning\", \"critical\", \"highlight\"] as const;\nexport type PvColorVariants = (typeof PvColorVariants)[number];\n\nexport const PvInputVariants = [\"h1\", \"h2\", \"h3\", \"h4\", \"text-md\", \"text-sm\", \"text-lg\", \"caption\"] as const;\nexport type PvInputVariants = (typeof PvInputVariants)[number];\n\nexport const PvTextInputColors = [\"white\", \"grey\"] as const;\nexport type PvTextInputColors = (typeof PvTextInputColors)[number];\n\nexport const sizeMap: Record<PvSize, string> = {\n xs: \"12px\",\n sm: \"16px\",\n md: \"20px\",\n lg: \"24px\",\n xl: \"32px\",\n \"2x\": \"40px\",\n};\n\nexport const PvIconSizes = [undefined, 10, 12, 20, 24, 32, 64] as const;\nexport type PvIconSize = (typeof PvIconSizes)[number];\n\nexport type PvAlignmentPositions =\n | \"bottom-left\"\n | \"bottom-center\"\n | \"bottom-right\"\n | \"top-left\"\n | \"top-center\"\n | \"top-right\"\n | \"center-left\"\n | \"center-right\";\n","<script lang=\"ts\">\nimport { PvIconSize, PvIconSizes } from \"../baseProps\";\n</script>\n<script setup lang=\"ts\">\nimport { computed, ref, Ref } from \"vue\";\nimport { useIsWebComponent } from \"@/web-components/utils\";\n\ntype PvIconProps = {\n /** Name of the icon from the SVG sprite sheet (e.g. \"user\", \"check-circle\"). */\n name: string;\n /** Pixel size of the icon. When omitted the icon inherits its container's size. */\n size?: PvIconSize;\n};\n\nconst props = defineProps<PvIconProps>();\nconst isWeb = useIsWebComponent();\n\nconst globalSpritePath: Ref<string | null> = ref(null);\n\nconst classes = computed(() => ({\n \"pv-icon\": true,\n [`pv-icon-${props.size}`]: props.size != null && PvIconSizes.includes(props.size),\n}));\n\nconst svgHref = computed(() => {\n // If the global sprite path is set, use it\n if (isWeb.value && globalSpritePath.value) {\n return `${globalSpritePath.value}#${props.name}`;\n }\n return `#${props.name}`;\n});\n\n// @ts-expect-error ignore type error for globalThis\nif (globalThis.__PV_GLOBAL_SPRITE_PATH__) {\n // We only want to use sprite paths for web components\n // @ts-expect-error ignore type error for globalThis\n globalSpritePath.value = globalThis.__PV_GLOBAL_SPRITE_PATH__;\n}\n</script>\n\n<template>\n <svg data-testid=\"pv-icon\" aria-hidden=\"true\" :class=\"classes\">\n <use :xlink:href=\"svgHref\"></use>\n </svg>\n</template>\n","<script lang=\"ts\">\nimport { PvIconSize, PvIconSizes } from \"../baseProps\";\n</script>\n<script setup lang=\"ts\">\nimport { computed, ref, Ref } from \"vue\";\nimport { useIsWebComponent } from \"@/web-components/utils\";\n\ntype PvIconProps = {\n /** Name of the icon from the SVG sprite sheet (e.g. \"user\", \"check-circle\"). */\n name: string;\n /** Pixel size of the icon. When omitted the icon inherits its container's size. */\n size?: PvIconSize;\n};\n\nconst props = defineProps<PvIconProps>();\nconst isWeb = useIsWebComponent();\n\nconst globalSpritePath: Ref<string | null> = ref(null);\n\nconst classes = computed(() => ({\n \"pv-icon\": true,\n [`pv-icon-${props.size}`]: props.size != null && PvIconSizes.includes(props.size),\n}));\n\nconst svgHref = computed(() => {\n // If the global sprite path is set, use it\n if (isWeb.value && globalSpritePath.value) {\n return `${globalSpritePath.value}#${props.name}`;\n }\n return `#${props.name}`;\n});\n\n// @ts-expect-error ignore type error for globalThis\nif (globalThis.__PV_GLOBAL_SPRITE_PATH__) {\n // We only want to use sprite paths for web components\n // @ts-expect-error ignore type error for globalThis\n globalSpritePath.value = globalThis.__PV_GLOBAL_SPRITE_PATH__;\n}\n</script>\n\n<template>\n <svg data-testid=\"pv-icon\" aria-hidden=\"true\" :class=\"classes\">\n <use :xlink:href=\"svgHref\"></use>\n </svg>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvCounterBadgeSize, PvCounterBadgeVariant } from \"./types\";\n\nexport interface PvCounterBadgeProps {\n /** Numeric value to display */\n value?: number;\n /** Text prefix displayed before the value */\n prefix?: string;\n /** Visual style variant */\n variant?: PvCounterBadgeVariant;\n /** Display size of the badge */\n size?: PvCounterBadgeSize;\n /** Maximum value before showing overflow indicator (e.g. \"99+\") */\n maxValue?: number;\n}\n\nconst props = withDefaults(defineProps<PvCounterBadgeProps>(), {\n variant: \"primary\",\n maxValue: 99,\n size: \"sm\",\n prefix: \"\",\n});\n\nconst size = computed(() => {\n if (props.size == \"md\") {\n return \"md\";\n } else if (props.size == \"sm\") {\n return \"sm\";\n }\n return \"sm\";\n});\n\nconst displayValue = computed(() => {\n if (props.maxValue && props.value && props.value > props.maxValue) {\n return `${props.maxValue}+`;\n }\n if (props.value != null) {\n return `${props.prefix}${props.value}`;\n }\n return \"-\";\n});\n\nconst classes = computed(() => ({\n \"pv-inline-block pv-inset-square pv-radius pv-text-center\": true,\n \"pv-badge-md pv-text-body-md\": size.value == \"md\",\n \"pv-badge-sm pv-text-body-sm\": size.value == \"sm\",\n \"pv-surface-brand-inverse pv-text-inverse\": props.variant == \"primary\",\n \"pv-badge-secondary\": props.variant == \"secondary\",\n \"pv-surface-lighten-5\": props.variant == \"tertiary\",\n \"pv-text-secondary\": props.variant == \"ghost\" || props.variant == \"tertiary\",\n \"pv-surface\": props.variant == \"ghost\",\n}));\n</script>\n<template>\n <div :class=\"classes\" data-testid=\"pv-counter-badge\">\n {{ displayValue }}\n </div>\n</template>\n\n<style scoped>\n.pv-badge-md {\n --inset-size: 2px 2px;\n min-height: 20px;\n max-height: 20px;\n min-width: 20px;\n font-weight: 500;\n}\n.pv-badge-sm {\n --inset-size: 0 2px;\n min-height: 16px;\n max-height: 16px;\n min-width: 16px;\n font-weight: 500;\n}\n.pv-surface-lighten-5 {\n background-color: #e0e5e4;\n}\n.pv-text-secondary {\n color: #4b595c;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvCounterBadgeSize, PvCounterBadgeVariant } from \"./types\";\n\nexport interface PvCounterBadgeProps {\n /** Numeric value to display */\n value?: number;\n /** Text prefix displayed before the value */\n prefix?: string;\n /** Visual style variant */\n variant?: PvCounterBadgeVariant;\n /** Display size of the badge */\n size?: PvCounterBadgeSize;\n /** Maximum value before showing overflow indicator (e.g. \"99+\") */\n maxValue?: number;\n}\n\nconst props = withDefaults(defineProps<PvCounterBadgeProps>(), {\n variant: \"primary\",\n maxValue: 99,\n size: \"sm\",\n prefix: \"\",\n});\n\nconst size = computed(() => {\n if (props.size == \"md\") {\n return \"md\";\n } else if (props.size == \"sm\") {\n return \"sm\";\n }\n return \"sm\";\n});\n\nconst displayValue = computed(() => {\n if (props.maxValue && props.value && props.value > props.maxValue) {\n return `${props.maxValue}+`;\n }\n if (props.value != null) {\n return `${props.prefix}${props.value}`;\n }\n return \"-\";\n});\n\nconst classes = computed(() => ({\n \"pv-inline-block pv-inset-square pv-radius pv-text-center\": true,\n \"pv-badge-md pv-text-body-md\": size.value == \"md\",\n \"pv-badge-sm pv-text-body-sm\": size.value == \"sm\",\n \"pv-surface-brand-inverse pv-text-inverse\": props.variant == \"primary\",\n \"pv-badge-secondary\": props.variant == \"secondary\",\n \"pv-surface-lighten-5\": props.variant == \"tertiary\",\n \"pv-text-secondary\": props.variant == \"ghost\" || props.variant == \"tertiary\",\n \"pv-surface\": props.variant == \"ghost\",\n}));\n</script>\n<template>\n <div :class=\"classes\" data-testid=\"pv-counter-badge\">\n {{ displayValue }}\n </div>\n</template>\n\n<style scoped>\n.pv-badge-md {\n --inset-size: 2px 2px;\n min-height: 20px;\n max-height: 20px;\n min-width: 20px;\n font-weight: 500;\n}\n.pv-badge-sm {\n --inset-size: 0 2px;\n min-height: 16px;\n max-height: 16px;\n min-width: 16px;\n font-weight: 500;\n}\n.pv-surface-lighten-5 {\n background-color: #e0e5e4;\n}\n.pv-text-secondary {\n color: #4b595c;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvButtonProps } from \"./types\";\nimport PvSpinner from \"../PvSpinner/PvSpinner.vue\";\nimport { pvButtonSizeToClass, supportedInverseButtonVariants } from \"@/components/base/PvButton/helpers.ts\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport PvCounterBadge from \"../PvCounterBadge/PvCounterBadge.vue\";\n\nconst props = withDefaults(defineProps<PvButtonProps>(), {\n variant: \"primary\",\n disabled: false,\n size: \"lg\",\n loading: false,\n inverse: false,\n});\n\nconst computedAriaLabel = computed(() => (!props.label || props.loading ? props.label || props.ariaLabel : undefined));\n\nconst classes = computed(() => {\n const output = [];\n if (props.inverse && supportedInverseButtonVariants.includes(props.variant)) {\n output.push(`pv-button-${props.variant}-inverse`);\n } else {\n output.push(`pv-button-${props.variant}`);\n }\n const sizeClass = pvButtonSizeToClass(props.size);\n if (sizeClass) {\n output.push(sizeClass);\n }\n return output;\n});\n</script>\n\n<template>\n <button type=\"button\" :class=\"classes\" :disabled=\"disabled\" :aria-label=\"computedAriaLabel\" data-testid=\"pv-button\">\n <PvSpinner v-if=\"loading\" size=\"sm\" />\n <template v-else>\n <PvCounterBadge v-if=\"leftCounterBadge\" :value=\"leftCounterBadge\" variant=\"tertiary\" />\n <PvIcon v-if=\"leftIcon\" :name=\"leftIcon\" data-testid=\"pv-button-left-icon\" />\n <span v-if=\"label\" data-testid=\"pv-button-label\">{{ label }}</span>\n <PvCounterBadge v-if=\"rightCounterBadge\" :value=\"rightCounterBadge\" variant=\"tertiary\" />\n <PvIcon v-if=\"rightIcon\" :name=\"rightIcon\" data-testid=\"pv-button-right-icon\" />\n </template>\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvButtonProps } from \"./types\";\nimport PvSpinner from \"../PvSpinner/PvSpinner.vue\";\nimport { pvButtonSizeToClass, supportedInverseButtonVariants } from \"@/components/base/PvButton/helpers.ts\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport PvCounterBadge from \"../PvCounterBadge/PvCounterBadge.vue\";\n\nconst props = withDefaults(defineProps<PvButtonProps>(), {\n variant: \"primary\",\n disabled: false,\n size: \"lg\",\n loading: false,\n inverse: false,\n});\n\nconst computedAriaLabel = computed(() => (!props.label || props.loading ? props.label || props.ariaLabel : undefined));\n\nconst classes = computed(() => {\n const output = [];\n if (props.inverse && supportedInverseButtonVariants.includes(props.variant)) {\n output.push(`pv-button-${props.variant}-inverse`);\n } else {\n output.push(`pv-button-${props.variant}`);\n }\n const sizeClass = pvButtonSizeToClass(props.size);\n if (sizeClass) {\n output.push(sizeClass);\n }\n return output;\n});\n</script>\n\n<template>\n <button type=\"button\" :class=\"classes\" :disabled=\"disabled\" :aria-label=\"computedAriaLabel\" data-testid=\"pv-button\">\n <PvSpinner v-if=\"loading\" size=\"sm\" />\n <template v-else>\n <PvCounterBadge v-if=\"leftCounterBadge\" :value=\"leftCounterBadge\" variant=\"tertiary\" />\n <PvIcon v-if=\"leftIcon\" :name=\"leftIcon\" data-testid=\"pv-button-left-icon\" />\n <span v-if=\"label\" data-testid=\"pv-button-label\">{{ label }}</span>\n <PvCounterBadge v-if=\"rightCounterBadge\" :value=\"rightCounterBadge\" variant=\"tertiary\" />\n <PvIcon v-if=\"rightIcon\" :name=\"rightIcon\" data-testid=\"pv-button-right-icon\" />\n </template>\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport PvSpinner from \"../PvSpinner/PvSpinner.vue\";\nimport { PvButtonSize } from \"@/components/base/PvButton/types.ts\";\nimport { pvButtonSizeToClass } from \"@/components/base/PvButton/helpers.ts\";\nimport { computed } from \"vue\";\n\ninterface PvAiButtonProps {\n /** Size of the AI button */\n size?: PvButtonSize;\n /** Text label displayed next to the AI icon. Omit for icon-only. */\n label?: string;\n /** Show a loading spinner in place of the icon and label */\n loading?: boolean;\n /** Prevent the button from being clicked */\n disabled?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvAiButtonProps>(), {\n size: \"md\",\n label: \"AskTQ\",\n});\n\nconst classes = computed(() => {\n const output = [\"pv-button-ai\"];\n const sizeClass = pvButtonSizeToClass(props.size);\n if (sizeClass) {\n output.push(sizeClass);\n }\n return output;\n});\n\n// Set aria-label when there is no visible text: icon-only mode or loading state (spinner replaces label).\nconst computedAriaLabel = computed(() => (!props.label || props.loading ? props.label || undefined : undefined));\n</script>\n\n<template>\n <button :disabled=\"disabled\" :class=\"classes\" :aria-label=\"computedAriaLabel\">\n <PvSpinner v-if=\"loading\" :size=\"size\" />\n <template v-else>\n <PvIcon class=\"pv-text-brand\" name=\"ai-filled\" />\n <span v-if=\"label\">{{ label }}</span>\n </template>\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport PvSpinner from \"../PvSpinner/PvSpinner.vue\";\nimport { PvButtonSize } from \"@/components/base/PvButton/types.ts\";\nimport { pvButtonSizeToClass } from \"@/components/base/PvButton/helpers.ts\";\nimport { computed } from \"vue\";\n\ninterface PvAiButtonProps {\n /** Size of the AI button */\n size?: PvButtonSize;\n /** Text label displayed next to the AI icon. Omit for icon-only. */\n label?: string;\n /** Show a loading spinner in place of the icon and label */\n loading?: boolean;\n /** Prevent the button from being clicked */\n disabled?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvAiButtonProps>(), {\n size: \"md\",\n label: \"AskTQ\",\n});\n\nconst classes = computed(() => {\n const output = [\"pv-button-ai\"];\n const sizeClass = pvButtonSizeToClass(props.size);\n if (sizeClass) {\n output.push(sizeClass);\n }\n return output;\n});\n\n// Set aria-label when there is no visible text: icon-only mode or loading state (spinner replaces label).\nconst computedAriaLabel = computed(() => (!props.label || props.loading ? props.label || undefined : undefined));\n</script>\n\n<template>\n <button :disabled=\"disabled\" :class=\"classes\" :aria-label=\"computedAriaLabel\">\n <PvSpinner v-if=\"loading\" :size=\"size\" />\n <template v-else>\n <PvIcon class=\"pv-text-brand\" name=\"ai-filled\" />\n <span v-if=\"label\">{{ label }}</span>\n </template>\n </button>\n</template>\n","import { computed, onBeforeUnmount, onMounted, ref, unref, useSlots, watch } from \"vue\";\nimport type { Ref } from \"vue\";\nimport { useIsWebComponent } from \"@/web-components/utils\";\n\ntype MaybeRef<T> = T | Ref<T>;\n\nexport type UseSlotPresenceOptions = {\n /**\n * Host element for native slot detection (required for web components).\n * When running as a web component, light DOM children of this element are inspected.\n */\n host?: MaybeRef<HTMLElement | null | undefined>;\n\n /**\n * A slots object (useful for tests or to override `useSlots()`).\n * Only used when running as a Vue component (not a web component).\n */\n vueSlots?: Record<string, unknown> | null | undefined;\n\n /**\n * Watch light DOM changes so presence updates if children are added/removed.\n * Only applies to web component mode. Defaults to true.\n */\n observe?: boolean;\n\n /**\n * Listen to slotchange events on shadow DOM slots.\n * Only applies to web component mode. Defaults to true.\n */\n listenSlotChange?: boolean;\n\n /**\n * If true, whitespace-only text nodes count as content in the default slot.\n * Only applies to web component mode. Defaults to false.\n */\n countWhitespaceTextInDefaultSlot?: boolean;\n};\n\nfunction isMeaningfulTextNode(node: Node, countWhitespace: boolean) {\n if (node.nodeType !== Node.TEXT_NODE) return false;\n const txt = node.textContent ?? \"\";\n return countWhitespace ? txt.length > 0 : txt.trim().length > 0;\n}\n\nfunction hasNativeSlottedContent(host: HTMLElement, name: string, countWhitespaceTextInDefaultSlot: boolean): boolean {\n const slotName = name === \"default\" ? \"\" : name;\n const nodes = Array.from(host.childNodes);\n\n if (slotName === \"\") {\n // Default slot: nodes without a `slot` attribute\n return nodes.some((n) => {\n if (n.nodeType === Node.ELEMENT_NODE) {\n const el = n as Element;\n return !el.hasAttribute(\"slot\");\n }\n return isMeaningfulTextNode(n, countWhitespaceTextInDefaultSlot);\n });\n }\n\n // Named slot: element children with slot=\"name\"\n return nodes.some((n) => {\n if (n.nodeType !== Node.ELEMENT_NODE) return false;\n const el = n as Element;\n return el.getAttribute(\"slot\") === slotName;\n });\n}\n\nfunction getShadowSlotEl(host: HTMLElement, name: string): HTMLSlotElement | null {\n const sr = host.shadowRoot;\n if (!sr) return null;\n if (name === \"default\" || name === \"\") {\n return sr.querySelector(\"slot:not([name])\");\n }\n return sr.querySelector(`slot[name=\"${CSS.escape(name)}\"]`);\n}\n\n/**\n * Returns a computed boolean indicating if a slot has content.\n *\n * Automatically detects if running as a Vue component or web component:\n * - Vue component: checks Vue's slot system via useSlots()\n * - Web component: inspects light DOM children of the host element\n */\nexport function useSlotPresence(slotName: string, options: UseSlotPresenceOptions = {}) {\n const { host, vueSlots, observe = true, listenSlotChange = true, countWhitespaceTextInDefaultSlot = false } = options;\n\n const isWebComponent = useIsWebComponent();\n const slots = vueSlots ?? useSlots();\n\n // Vue slot presence (used when not a web component)\n const hasVueSlot = computed(() => {\n if (isWebComponent.value || !slots) return false;\n const key = slotName === \"default\" || slotName === \"\" ? \"default\" : slotName;\n return !!(slots as Record<string, unknown>)[key];\n });\n\n // Native/web-component slot presence\n const hasNativeSlot = ref(false);\n\n let mo: MutationObserver | null = null;\n let shadowSlot: HTMLSlotElement | null = null;\n\n const cleanup = () => {\n if (mo) {\n mo.disconnect();\n mo = null;\n }\n if (shadowSlot) {\n shadowSlot.removeEventListener(\"slotchange\", updateNative);\n shadowSlot = null;\n }\n };\n\n const updateNative = () => {\n if (!isWebComponent.value) {\n hasNativeSlot.value = false;\n return;\n }\n\n const el = unref(host);\n if (!el) {\n hasNativeSlot.value = false;\n return;\n }\n\n // Prefer assignedNodes if we can access the <slot> element in open shadowRoot\n const slotEl = listenSlotChange ? getShadowSlotEl(el, slotName) : null;\n if (slotEl) {\n const assigned = slotEl.assignedNodes({ flatten: true });\n hasNativeSlot.value = assigned.some((n) => {\n if (n.nodeType === Node.ELEMENT_NODE) return true;\n return isMeaningfulTextNode(n, countWhitespaceTextInDefaultSlot);\n });\n return;\n }\n\n // Fallback: inspect light DOM children\n hasNativeSlot.value = hasNativeSlottedContent(el, slotName, countWhitespaceTextInDefaultSlot);\n };\n\n const attach = () => {\n if (!isWebComponent.value) return;\n\n cleanup();\n\n const el = unref(host);\n if (!el) {\n hasNativeSlot.value = false;\n return;\n }\n\n updateNative();\n\n if (listenSlotChange) {\n shadowSlot = getShadowSlotEl(el, slotName);\n if (shadowSlot) shadowSlot.addEventListener(\"slotchange\", updateNative);\n }\n\n if (observe) {\n mo = new MutationObserver(() => updateNative());\n mo.observe(el, {\n childList: true,\n subtree: false,\n attributes: true,\n attributeFilter: [\"slot\"],\n characterData: true,\n });\n }\n };\n\n onMounted(attach);\n onBeforeUnmount(cleanup);\n\n // If host ref changes, reattach\n watch(\n () => unref(host),\n () => {\n if (isWebComponent.value) attach();\n },\n );\n\n // Select presence based on component type\n const present = computed(() => (isWebComponent.value ? hasNativeSlot.value : hasVueSlot.value));\n\n return {\n present,\n hasVueSlot,\n hasNativeSlot,\n refresh: updateNative,\n };\n}\n","<script setup lang=\"ts\">\nimport { PvTooltipPositions, PvTooltipVariants, PvTooltipSize } from \"./types\";\nimport { useSlotPresence } from \"@/composables/useSlotPresence\";\n\ninterface PvTooltipProps {\n /** Color theme variant */\n variant?: PvTooltipVariants;\n /** Position of the tooltip relative to the trigger element */\n tooltipPosition?: PvTooltipPositions;\n /** Accessibility label reference ID linking trigger to tooltip content */\n ariaLabelledBy?: string;\n /** Size of the tooltip content area */\n size?: PvTooltipSize;\n /** When true, tooltip hides immediately when cursor leaves the trigger */\n disableInteractive?: boolean;\n /** Delay in milliseconds before showing the tooltip */\n delay?: number;\n}\n\nwithDefaults(defineProps<PvTooltipProps>(), {\n variant: \"white\",\n ariaLabelledBy: \"ariaLabelledById\",\n tooltipPosition: \"top-right\",\n size: \"md\",\n disableInteractive: false,\n delay: 0,\n});\n\nconst { present: hasTooltip } = useSlotPresence(\"tooltip-content\");\n</script>\n\n<template>\n <div\n data-testid=\"pv-tooltip\"\n :class=\"[\n {\n 'pv-tooltip': hasTooltip,\n 'pv-tooltip-small': hasTooltip && size === 'sm',\n },\n ]\"\n :data-position=\"tooltipPosition\"\n :data-style=\"variant === 'white' ? 'white' : 'dark'\"\n :data-static=\"disableInteractive ? true : undefined\"\n :aria-labelledby=\"hasTooltip ? ariaLabelledBy : undefined\"\n >\n <slot name=\"label\" />\n <div v-if=\"hasTooltip\" role=\"tooltip\" :id=\"ariaLabelledBy\" data-testid=\"pv-tooltip-content\">\n <slot name=\"tooltip-content\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { PvTooltipPositions, PvTooltipVariants, PvTooltipSize } from \"./types\";\nimport { useSlotPresence } from \"@/composables/useSlotPresence\";\n\ninterface PvTooltipProps {\n /** Color theme variant */\n variant?: PvTooltipVariants;\n /** Position of the tooltip relative to the trigger element */\n tooltipPosition?: PvTooltipPositions;\n /** Accessibility label reference ID linking trigger to tooltip content */\n ariaLabelledBy?: string;\n /** Size of the tooltip content area */\n size?: PvTooltipSize;\n /** When true, tooltip hides immediately when cursor leaves the trigger */\n disableInteractive?: boolean;\n /** Delay in milliseconds before showing the tooltip */\n delay?: number;\n}\n\nwithDefaults(defineProps<PvTooltipProps>(), {\n variant: \"white\",\n ariaLabelledBy: \"ariaLabelledById\",\n tooltipPosition: \"top-right\",\n size: \"md\",\n disableInteractive: false,\n delay: 0,\n});\n\nconst { present: hasTooltip } = useSlotPresence(\"tooltip-content\");\n</script>\n\n<template>\n <div\n data-testid=\"pv-tooltip\"\n :class=\"[\n {\n 'pv-tooltip': hasTooltip,\n 'pv-tooltip-small': hasTooltip && size === 'sm',\n },\n ]\"\n :data-position=\"tooltipPosition\"\n :data-style=\"variant === 'white' ? 'white' : 'dark'\"\n :data-static=\"disableInteractive ? true : undefined\"\n :aria-labelledby=\"hasTooltip ? ariaLabelledBy : undefined\"\n >\n <slot name=\"label\" />\n <div v-if=\"hasTooltip\" role=\"tooltip\" :id=\"ariaLabelledBy\" data-testid=\"pv-tooltip-content\">\n <slot name=\"tooltip-content\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { PvButtonWithTooltipProps } from \"./types\";\nimport PvButton from \"./PvButton.vue\";\nimport PvTooltip from \"../PvTooltip/PvTooltip.vue\";\nimport { computed } from \"vue\";\n\nconst props = withDefaults(defineProps<PvButtonWithTooltipProps>(), {\n tooltipVariant: \"dark\",\n delay: 500,\n});\n\nconst pvToolTipSize = computed(() => {\n // for md buttons, use sm, else use md\n return props.size === \"md\" ? \"sm\" : \"md\";\n});\n</script>\n\n<template>\n <PvTooltip :variant=\"tooltipVariant\" :tooltip-position=\"tooltipPosition\" :delay=\"delay\" :size=\"pvToolTipSize\">\n <template #tooltip-content>\n <p class=\"pv-text-body-sm\">{{ tooltipText }}</p>\n </template>\n <template #label>\n <PvButton v-bind=\"$props\" />\n </template>\n </PvTooltip>\n</template>\n","<script setup lang=\"ts\">\nimport { PvButtonWithTooltipProps } from \"./types\";\nimport PvButton from \"./PvButton.vue\";\nimport PvTooltip from \"../PvTooltip/PvTooltip.vue\";\nimport { computed } from \"vue\";\n\nconst props = withDefaults(defineProps<PvButtonWithTooltipProps>(), {\n tooltipVariant: \"dark\",\n delay: 500,\n});\n\nconst pvToolTipSize = computed(() => {\n // for md buttons, use sm, else use md\n return props.size === \"md\" ? \"sm\" : \"md\";\n});\n</script>\n\n<template>\n <PvTooltip :variant=\"tooltipVariant\" :tooltip-position=\"tooltipPosition\" :delay=\"delay\" :size=\"pvToolTipSize\">\n <template #tooltip-content>\n <p class=\"pv-text-body-sm\">{{ tooltipText }}</p>\n </template>\n <template #label>\n <PvButton v-bind=\"$props\" />\n </template>\n </PvTooltip>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvReleaseBadgeVariant } from \"./types\";\n\nexport interface PvReleaseBadgeProps {\n /** Release stage variant that determines the badge label and color */\n variant: PvReleaseBadgeVariant;\n /** Apply inverse styling (neutral background) */\n inverse?: boolean;\n}\nconst props = defineProps<PvReleaseBadgeProps>();\n\nconst displayLabel = computed(() => {\n if (props.variant == \"release-alpha\") {\n return \"ALPHA\";\n } else if (props.variant == \"release-beta\") {\n return \"BETA\";\n } else {\n return \"\";\n }\n});\n\nconst classes = computed(() => {\n if (props.inverse) {\n return \"pv-tag-inverse\";\n }\n return {\n \"pv-tag-yellow\": props.variant == \"release-alpha\",\n \"pv-tag-purple\": props.variant == \"release-beta\",\n };\n});\n</script>\n\n<template>\n <div :class=\"classes\">\n {{ displayLabel }}\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvReleaseBadgeVariant } from \"./types\";\n\nexport interface PvReleaseBadgeProps {\n /** Release stage variant that determines the badge label and color */\n variant: PvReleaseBadgeVariant;\n /** Apply inverse styling (neutral background) */\n inverse?: boolean;\n}\nconst props = defineProps<PvReleaseBadgeProps>();\n\nconst displayLabel = computed(() => {\n if (props.variant == \"release-alpha\") {\n return \"ALPHA\";\n } else if (props.variant == \"release-beta\") {\n return \"BETA\";\n } else {\n return \"\";\n }\n});\n\nconst classes = computed(() => {\n if (props.inverse) {\n return \"pv-tag-inverse\";\n }\n return {\n \"pv-tag-yellow\": props.variant == \"release-alpha\",\n \"pv-tag-purple\": props.variant == \"release-beta\",\n };\n});\n</script>\n\n<template>\n <div :class=\"classes\">\n {{ displayLabel }}\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, CSSProperties } from \"vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { TagSize, TagVariant } from \"./types\";\n\nexport interface PvTagProps {\n /**\n * Tag size\n */\n size?: TagSize;\n /**\n * Tag visual variant\n */\n variant?: TagVariant;\n /**\n * Tag Icon\n */\n icon?: string;\n /**\n * Icon class\n */\n iconClasses?: string[];\n /**\n * Tag Label\n */\n label: string;\n /**\n * Show left clear icon\n */\n showClear?: boolean;\n /**\n * Show rounded state\n */\n rounded?: boolean;\n /**\n * Spine - dotted state\n */\n spine?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvTagProps>(), {\n size: \"md\",\n variant: \"tertiary\",\n});\n\ndefineEmits<{\n (e: \"handle-close\", payload: string): void;\n (e: \"handle-click\", payload: string): void;\n}>();\n\nconst tagSizeClass = computed(() => {\n switch (props.size) {\n case \"lg\": {\n return \"pv-tag-lg\";\n }\n case \"sm\": {\n return \"pv-tag-sm\";\n }\n default: {\n return \"\";\n }\n }\n});\n\nconst tagVariantClass = computed(() => {\n switch (props.variant) {\n case \"primary\": {\n return \"pv-tag-primary\";\n }\n case \"tertiary\": {\n return \"pv-tag-tertiary\";\n }\n case \"transparent\": {\n return \"pv-tag-tertiary\";\n }\n default: {\n return \"\";\n }\n }\n});\n\nconst pvTagStyles = computed(() => {\n const baseStyles: CSSProperties = {\n \"max-width\": \"100%\",\n \"--flex-gap\": \"4px\",\n };\n\n if (props.variant === \"transparent\") {\n baseStyles[\"--tag-background-color\"] = \"transparent\";\n }\n\n return baseStyles;\n});\n</script>\n\n<template>\n <button\n :class=\"[tagVariantClass, tagSizeClass, 'pv-flex']\"\n @click=\"$emit('handle-click', label)\"\n :style=\"pvTagStyles\"\n data-testid=\"pv-tag\"\n :data-style=\"rounded ? 'rounded' : undefined\"\n >\n <PvIcon data-testid=\"pv-tag-icon\" v-if=\"icon\" :class=\"iconClasses\" :name=\"icon\" :size=\"12\" />\n <span\n :class=\"[\n 'pv-truncate',\n {\n 'pv-underline-dotted': spine,\n },\n ]\"\n >\n {{ label }}\n </span>\n <PvIcon\n data-testid=\"pv-tag-close-icon\"\n :size=\"12\"\n name=\"close\"\n v-if=\"showClear\"\n @click.stop=\"$emit('handle-close', label)\"\n />\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, CSSProperties } from \"vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { TagSize, TagVariant } from \"./types\";\n\nexport interface PvTagProps {\n /**\n * Tag size\n */\n size?: TagSize;\n /**\n * Tag visual variant\n */\n variant?: TagVariant;\n /**\n * Tag Icon\n */\n icon?: string;\n /**\n * Icon class\n */\n iconClasses?: string[];\n /**\n * Tag Label\n */\n label: string;\n /**\n * Show left clear icon\n */\n showClear?: boolean;\n /**\n * Show rounded state\n */\n rounded?: boolean;\n /**\n * Spine - dotted state\n */\n spine?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvTagProps>(), {\n size: \"md\",\n variant: \"tertiary\",\n});\n\ndefineEmits<{\n (e: \"handle-close\", payload: string): void;\n (e: \"handle-click\", payload: string): void;\n}>();\n\nconst tagSizeClass = computed(() => {\n switch (props.size) {\n case \"lg\": {\n return \"pv-tag-lg\";\n }\n case \"sm\": {\n return \"pv-tag-sm\";\n }\n default: {\n return \"\";\n }\n }\n});\n\nconst tagVariantClass = computed(() => {\n switch (props.variant) {\n case \"primary\": {\n return \"pv-tag-primary\";\n }\n case \"tertiary\": {\n return \"pv-tag-tertiary\";\n }\n case \"transparent\": {\n return \"pv-tag-tertiary\";\n }\n default: {\n return \"\";\n }\n }\n});\n\nconst pvTagStyles = computed(() => {\n const baseStyles: CSSProperties = {\n \"max-width\": \"100%\",\n \"--flex-gap\": \"4px\",\n };\n\n if (props.variant === \"transparent\") {\n baseStyles[\"--tag-background-color\"] = \"transparent\";\n }\n\n return baseStyles;\n});\n</script>\n\n<template>\n <button\n :class=\"[tagVariantClass, tagSizeClass, 'pv-flex']\"\n @click=\"$emit('handle-click', label)\"\n :style=\"pvTagStyles\"\n data-testid=\"pv-tag\"\n :data-style=\"rounded ? 'rounded' : undefined\"\n >\n <PvIcon data-testid=\"pv-tag-icon\" v-if=\"icon\" :class=\"iconClasses\" :name=\"icon\" :size=\"12\" />\n <span\n :class=\"[\n 'pv-truncate',\n {\n 'pv-underline-dotted': spine,\n },\n ]\"\n >\n {{ label }}\n </span>\n <PvIcon\n data-testid=\"pv-tag-close-icon\"\n :size=\"12\"\n name=\"close\"\n v-if=\"showClear\"\n @click.stop=\"$emit('handle-close', label)\"\n />\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { PillSize, PillVariant, PillDotVariant } from \"./types\";\n\nexport interface PvPillProps {\n /**\n * Pill size\n */\n size?: PillSize;\n /**\n * Pill color variant\n */\n variant?: PillVariant;\n /**\n * Icon name displayed before the label\n */\n icon?: string;\n /**\n * Colored dot indicator displayed before the label. When set, forces neutral (tertiary) styling regardless of the variant prop.\n */\n dotVariant?: PillDotVariant;\n /**\n * Pill label text\n */\n label: string;\n}\n\nconst props = withDefaults(defineProps<PvPillProps>(), {\n size: \"md\",\n variant: \"default\",\n});\n\nconst tagSizeClass = computed(() => {\n switch (props.size) {\n case \"lg\": {\n return \"pv-tag-lg\";\n }\n case \"sm\": {\n return \"pv-tag-sm\";\n }\n default: {\n return \"\";\n }\n }\n});\n\nconst tagVariantClass = computed(() => {\n if (props.dotVariant) {\n return \"pv-tag-tertiary\";\n }\n switch (props.variant) {\n case \"default\": {\n return \"pv-tag-tertiary\";\n }\n case \"success\": {\n return \"pv-tag-green\";\n }\n case \"warning\": {\n return \"pv-tag-orange\";\n }\n case \"critical\": {\n return \"pv-tag-red\";\n }\n case \"highlight\": {\n return \"pv-tag-turquoise\";\n }\n default: {\n return \"pv-tag-tertiary\";\n }\n }\n});\n</script>\n\n<template>\n <div\n :class=\"[tagVariantClass, tagSizeClass, 'pv-flex']\"\n @click=\"$emit('handle-click', label)\"\n data-style=\"rounded\"\n style=\"width: fit-content; --flex-gap: 4px\"\n >\n <span v-if=\"dotVariant\" style=\"margin-inline-end: 0px\" :class=\"`pv-status-${dotVariant}`\"></span>\n <PvIcon v-if=\"icon\" :name=\"icon\" :size=\"12\" />\n <span>\n {{ label }}\n </span>\n </div>\n</template>\n\n<style scoped>\n[class*=\"pv-status\"] {\n &::before,\n &::after {\n margin-inline-end: 0px;\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { PillSize, PillVariant, PillDotVariant } from \"./types\";\n\nexport interface PvPillProps {\n /**\n * Pill size\n */\n size?: PillSize;\n /**\n * Pill color variant\n */\n variant?: PillVariant;\n /**\n * Icon name displayed before the label\n */\n icon?: string;\n /**\n * Colored dot indicator displayed before the label. When set, forces neutral (tertiary) styling regardless of the variant prop.\n */\n dotVariant?: PillDotVariant;\n /**\n * Pill label text\n */\n label: string;\n}\n\nconst props = withDefaults(defineProps<PvPillProps>(), {\n size: \"md\",\n variant: \"default\",\n});\n\nconst tagSizeClass = computed(() => {\n switch (props.size) {\n case \"lg\": {\n return \"pv-tag-lg\";\n }\n case \"sm\": {\n return \"pv-tag-sm\";\n }\n default: {\n return \"\";\n }\n }\n});\n\nconst tagVariantClass = computed(() => {\n if (props.dotVariant) {\n return \"pv-tag-tertiary\";\n }\n switch (props.variant) {\n case \"default\": {\n return \"pv-tag-tertiary\";\n }\n case \"success\": {\n return \"pv-tag-green\";\n }\n case \"warning\": {\n return \"pv-tag-orange\";\n }\n case \"critical\": {\n return \"pv-tag-red\";\n }\n case \"highlight\": {\n return \"pv-tag-turquoise\";\n }\n default: {\n return \"pv-tag-tertiary\";\n }\n }\n});\n</script>\n\n<template>\n <div\n :class=\"[tagVariantClass, tagSizeClass, 'pv-flex']\"\n @click=\"$emit('handle-click', label)\"\n data-style=\"rounded\"\n style=\"width: fit-content; --flex-gap: 4px\"\n >\n <span v-if=\"dotVariant\" style=\"margin-inline-end: 0px\" :class=\"`pv-status-${dotVariant}`\"></span>\n <PvIcon v-if=\"icon\" :name=\"icon\" :size=\"12\" />\n <span>\n {{ label }}\n </span>\n </div>\n</template>\n\n<style scoped>\n[class*=\"pv-status\"] {\n &::before,\n &::after {\n margin-inline-end: 0px;\n }\n}\n</style>\n","<script lang=\"ts\">\nimport { CSSProperties } from \"vue\";\n\nexport interface PvPopoverProps {\n /** Alignment of the popover relative to its trigger. */\n alignment?: \"top\" | \"right\" | \"top right\" | undefined;\n /** Custom CSS properties applied to the popover root element. */\n cssCustomProperties?: CSSProperties;\n /** Custom CSS properties applied to the inner list element (when isList is true). */\n cssCustomListProperties?: CSSProperties;\n /** When true, renders the content inside a `<ul>` list element. */\n isList?: boolean;\n /** When true and isList is true, enables drag-and-drop reordering of list items. */\n isSortable?: boolean;\n}\n</script>\n<script setup lang=\"ts\">\nimport { useSortable } from \"@vueuse/integrations/useSortable.mjs\";\nimport { useTemplateRef, ref } from \"vue\";\n\nconst popoverRoot = ref<HTMLElement | null>(null);\nconst el = useTemplateRef<HTMLElement>(\"popoverList\");\n\nconst props = withDefaults(defineProps<PvPopoverProps>(), {\n alignment: undefined,\n isList: false,\n cssCustomProperties: () => ({}),\n});\n\nconst emit = defineEmits<{\n (e: \"list-order-updated\", value: string[]): void;\n}>();\n\nif (props.isSortable && props.isList) {\n useSortable(el, [], {\n animation: 150,\n onUpdate: () => {\n const newIds = Array.from(el.value?.children || []).map((child) => (child as HTMLElement).id);\n emit(\"list-order-updated\", newIds);\n },\n });\n}\n\ndefineExpose({ popoverRoot });\n</script>\n<template>\n <div\n ref=\"popoverRoot\"\n class=\"pv-popover\"\n data-testid=\"pv-popover\"\n :data-align=\"alignment\"\n :style=\"cssCustomProperties\"\n >\n <ul v-if=\"isList\" ref=\"popoverList\" role=\"list\" class=\"pv-popover-list\" :style=\"cssCustomListProperties\">\n <slot></slot>\n </ul>\n <slot v-else></slot>\n </div>\n</template>\n\n<style scoped>\n.pv-popover-list {\n font-size: 14px;\n}\n</style>\n","<script lang=\"ts\">\nimport { CSSProperties } from \"vue\";\n\nexport interface PvPopoverProps {\n /** Alignment of the popover relative to its trigger. */\n alignment?: \"top\" | \"right\" | \"top right\" | undefined;\n /** Custom CSS properties applied to the popover root element. */\n cssCustomProperties?: CSSProperties;\n /** Custom CSS properties applied to the inner list element (when isList is true). */\n cssCustomListProperties?: CSSProperties;\n /** When true, renders the content inside a `<ul>` list element. */\n isList?: boolean;\n /** When true and isList is true, enables drag-and-drop reordering of list items. */\n isSortable?: boolean;\n}\n</script>\n<script setup lang=\"ts\">\nimport { useSortable } from \"@vueuse/integrations/useSortable.mjs\";\nimport { useTemplateRef, ref } from \"vue\";\n\nconst popoverRoot = ref<HTMLElement | null>(null);\nconst el = useTemplateRef<HTMLElement>(\"popoverList\");\n\nconst props = withDefaults(defineProps<PvPopoverProps>(), {\n alignment: undefined,\n isList: false,\n cssCustomProperties: () => ({}),\n});\n\nconst emit = defineEmits<{\n (e: \"list-order-updated\", value: string[]): void;\n}>();\n\nif (props.isSortable && props.isList) {\n useSortable(el, [], {\n animation: 150,\n onUpdate: () => {\n const newIds = Array.from(el.value?.children || []).map((child) => (child as HTMLElement).id);\n emit(\"list-order-updated\", newIds);\n },\n });\n}\n\ndefineExpose({ popoverRoot });\n</script>\n<template>\n <div\n ref=\"popoverRoot\"\n class=\"pv-popover\"\n data-testid=\"pv-popover\"\n :data-align=\"alignment\"\n :style=\"cssCustomProperties\"\n >\n <ul v-if=\"isList\" ref=\"popoverList\" role=\"list\" class=\"pv-popover-list\" :style=\"cssCustomListProperties\">\n <slot></slot>\n </ul>\n <slot v-else></slot>\n </div>\n</template>\n\n<style scoped>\n.pv-popover-list {\n font-size: 14px;\n}\n</style>\n","<script lang=\"ts\">\nimport { CSSProperties } from \"vue\";\n\nexport interface PvDropdownProps {\n defaultOpen?: boolean;\n popoverCssProperties?: CSSProperties;\n alignment?: \"top\" | \"right\" | \"top right\" | undefined;\n isList?: boolean;\n isSortable?: boolean;\n icon?: boolean;\n disabled?: boolean;\n isLoading?: boolean;\n useTeleport?: boolean;\n teleportLocation?: string;\n}\n</script>\n<script setup lang=\"ts\">\nimport { computed, ref, watch, nextTick } from \"vue\";\nimport PvPopover from \"../PvPopover/PvPopover.vue\";\nimport { vOnClickOutside } from \"@vueuse/components\";\nconst props = withDefaults(defineProps<PvDropdownProps>(), {\n alignment: undefined,\n isList: false,\n defaultOpen: false,\n disabled: false,\n isLoading: false,\n useTeleport: false,\n teleportLocation: \"body\",\n});\nconst emits = defineEmits<{\n (e: \"dropdown-open\"): void;\n (e: \"dropdown-closed\"): void;\n (e: \"list-order-updated\", value: string[]): void;\n}>();\nconst open = ref<boolean>(props.defaultOpen);\n\nconst triggerRef = ref<HTMLElement | null>(null);\nconst popoverRef = ref<{ popoverRoot: HTMLElement | null } | null>(null);\nconst triggerRect = ref<DOMRect | null>(null);\nconst popoverRect = ref<DOMRect | null>(null);\n\nconst updateRects = () => {\n if (triggerRef.value) {\n triggerRect.value = triggerRef.value.getBoundingClientRect();\n }\n if (popoverRef.value?.popoverRoot) {\n popoverRect.value = popoverRef.value.popoverRoot.getBoundingClientRect();\n }\n};\n\nconst popoverClasses = computed(() => {\n const classes = {\n \"pv-hide\": !open.value,\n };\n return classes;\n});\nconst handleClickTrigger = (e: MouseEvent) => {\n open.value = !open.value;\n};\n\nconst closeDropdown = () => {\n open.value = false;\n};\n\ndefineExpose({\n closeDropdown,\n});\n\nwatch(open, (newValue) => {\n if (newValue) {\n nextTick(() => {\n updateRects();\n emits(\"dropdown-open\");\n });\n } else {\n emits(\"dropdown-closed\");\n }\n});\n\nconst leftOffset = computed(() => {\n if (!triggerRect.value || !popoverRect.value) return 0;\n\n if (props.alignment === \"right\" || props.alignment === \"top right\") {\n return (\n triggerRect.value.left + triggerRect.value.width - popoverRect.value.width\n );\n }\n return triggerRect.value.left;\n});\n\nconst topOffset = computed(() => {\n if (!triggerRect.value || !popoverRect.value) return 0;\n\n if (props.alignment === \"top\" || props.alignment === \"top right\") {\n return triggerRect.value.top - popoverRect.value.height;\n }\n\n return triggerRect.value.top + window.scrollY + triggerRect.value.height;\n});\n\nconst popoverPositionStyle = computed(() => {\n if (!props.useTeleport) {\n return props.popoverCssProperties;\n }\n const teleportStyles = {\n position: \"absolute\",\n left: `${leftOffset.value}px`,\n top: `${topOffset.value}px`,\n zIndex: 10,\n } as CSSProperties;\n return {\n ...teleportStyles,\n ...props.popoverCssProperties,\n };\n});\n</script>\n<template>\n <div\n class=\"pv-relative\"\n v-on-click-outside=\"closeDropdown\"\n style=\"width: fit-content\"\n >\n <button\n ref=\"triggerRef\"\n :class=\"{ 'pv-select': !icon, 'pv-icon-button': icon }\"\n style=\"width: auto\"\n @click=\"handleClickTrigger\"\n :disabled=\"disabled\"\n >\n <slot name=\"trigger\">Open</slot>\n </button>\n <Teleport :to=\"teleportLocation\" :disabled=\"!useTeleport\">\n <PvPopover\n ref=\"popoverRef\"\n :class=\"popoverClasses\"\n :css-custom-properties=\"popoverPositionStyle\"\n :alignment=\"alignment\"\n :isList=\"isList\"\n :isSortable=\"isSortable\"\n @list-order-updated=\"$emit('list-order-updated', $event)\"\n ><slot\n ><span v-if=\"isLoading\" class=\"pv-shimmer\">Loading...</span></slot\n ></PvPopover\n >\n </Teleport>\n </div>\n</template>\n\n<style scoped>\n.pv-icon-button {\n background-color: transparent;\n border: none;\n}\n.pv-icon-button:hover {\n cursor: pointer;\n color: #176f6f;\n}\n.pv-select {\n padding-top: 4px;\n padding-bottom: 4px;\n}\n</style>\n","<script lang=\"ts\">\nimport { CSSProperties } from \"vue\";\n\nexport interface PvDropdownProps {\n defaultOpen?: boolean;\n popoverCssProperties?: CSSProperties;\n alignment?: \"top\" | \"right\" | \"top right\" | undefined;\n isList?: boolean;\n isSortable?: boolean;\n icon?: boolean;\n disabled?: boolean;\n isLoading?: boolean;\n useTeleport?: boolean;\n teleportLocation?: string;\n}\n</script>\n<script setup lang=\"ts\">\nimport { computed, ref, watch, nextTick } from \"vue\";\nimport PvPopover from \"../PvPopover/PvPopover.vue\";\nimport { vOnClickOutside } from \"@vueuse/components\";\nconst props = withDefaults(defineProps<PvDropdownProps>(), {\n alignment: undefined,\n isList: false,\n defaultOpen: false,\n disabled: false,\n isLoading: false,\n useTeleport: false,\n teleportLocation: \"body\",\n});\nconst emits = defineEmits<{\n (e: \"dropdown-open\"): void;\n (e: \"dropdown-closed\"): void;\n (e: \"list-order-updated\", value: string[]): void;\n}>();\nconst open = ref<boolean>(props.defaultOpen);\n\nconst triggerRef = ref<HTMLElement | null>(null);\nconst popoverRef = ref<{ popoverRoot: HTMLElement | null } | null>(null);\nconst triggerRect = ref<DOMRect | null>(null);\nconst popoverRect = ref<DOMRect | null>(null);\n\nconst updateRects = () => {\n if (triggerRef.value) {\n triggerRect.value = triggerRef.value.getBoundingClientRect();\n }\n if (popoverRef.value?.popoverRoot) {\n popoverRect.value = popoverRef.value.popoverRoot.getBoundingClientRect();\n }\n};\n\nconst popoverClasses = computed(() => {\n const classes = {\n \"pv-hide\": !open.value,\n };\n return classes;\n});\nconst handleClickTrigger = (e: MouseEvent) => {\n open.value = !open.value;\n};\n\nconst closeDropdown = () => {\n open.value = false;\n};\n\ndefineExpose({\n closeDropdown,\n});\n\nwatch(open, (newValue) => {\n if (newValue) {\n nextTick(() => {\n updateRects();\n emits(\"dropdown-open\");\n });\n } else {\n emits(\"dropdown-closed\");\n }\n});\n\nconst leftOffset = computed(() => {\n if (!triggerRect.value || !popoverRect.value) return 0;\n\n if (props.alignment === \"right\" || props.alignment === \"top right\") {\n return (\n triggerRect.value.left + triggerRect.value.width - popoverRect.value.width\n );\n }\n return triggerRect.value.left;\n});\n\nconst topOffset = computed(() => {\n if (!triggerRect.value || !popoverRect.value) return 0;\n\n if (props.alignment === \"top\" || props.alignment === \"top right\") {\n return triggerRect.value.top - popoverRect.value.height;\n }\n\n return triggerRect.value.top + window.scrollY + triggerRect.value.height;\n});\n\nconst popoverPositionStyle = computed(() => {\n if (!props.useTeleport) {\n return props.popoverCssProperties;\n }\n const teleportStyles = {\n position: \"absolute\",\n left: `${leftOffset.value}px`,\n top: `${topOffset.value}px`,\n zIndex: 10,\n } as CSSProperties;\n return {\n ...teleportStyles,\n ...props.popoverCssProperties,\n };\n});\n</script>\n<template>\n <div\n class=\"pv-relative\"\n v-on-click-outside=\"closeDropdown\"\n style=\"width: fit-content\"\n >\n <button\n ref=\"triggerRef\"\n :class=\"{ 'pv-select': !icon, 'pv-icon-button': icon }\"\n style=\"width: auto\"\n @click=\"handleClickTrigger\"\n :disabled=\"disabled\"\n >\n <slot name=\"trigger\">Open</slot>\n </button>\n <Teleport :to=\"teleportLocation\" :disabled=\"!useTeleport\">\n <PvPopover\n ref=\"popoverRef\"\n :class=\"popoverClasses\"\n :css-custom-properties=\"popoverPositionStyle\"\n :alignment=\"alignment\"\n :isList=\"isList\"\n :isSortable=\"isSortable\"\n @list-order-updated=\"$emit('list-order-updated', $event)\"\n ><slot\n ><span v-if=\"isLoading\" class=\"pv-shimmer\">Loading...</span></slot\n ></PvPopover\n >\n </Teleport>\n </div>\n</template>\n\n<style scoped>\n.pv-icon-button {\n background-color: transparent;\n border: none;\n}\n.pv-icon-button:hover {\n cursor: pointer;\n color: #176f6f;\n}\n.pv-select {\n padding-top: 4px;\n padding-bottom: 4px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport PvPopover from \"../PvPopover/PvPopover.vue\";\nimport { CSSProperties } from \"vue\";\n\nwithDefaults(\n defineProps<{\n /** Alignment of the popover dropdown relative to its trigger. */\n alignment?: \"top\" | \"right\" | \"top right\" | undefined;\n /** Custom CSS properties applied to the popover container. */\n cssCustomProperties?: CSSProperties;\n }>(),\n {\n alignment: undefined,\n cssCustomProperties: () => ({}),\n },\n);\n</script>\n\n<template>\n <nav class=\"pv-popover-menu\">\n <slot name=\"trigger\"></slot>\n <PvPopover is-list :alignment=\"alignment\" :css-custom-properties=\"cssCustomProperties\">\n <slot name=\"content\"></slot>\n </PvPopover>\n </nav>\n</template>\n","<script setup lang=\"ts\">\nimport PvPopover from \"../PvPopover/PvPopover.vue\";\nimport { CSSProperties } from \"vue\";\n\nwithDefaults(\n defineProps<{\n /** Alignment of the popover dropdown relative to its trigger. */\n alignment?: \"top\" | \"right\" | \"top right\" | undefined;\n /** Custom CSS properties applied to the popover container. */\n cssCustomProperties?: CSSProperties;\n }>(),\n {\n alignment: undefined,\n cssCustomProperties: () => ({}),\n },\n);\n</script>\n\n<template>\n <nav class=\"pv-popover-menu\">\n <slot name=\"trigger\"></slot>\n <PvPopover is-list :alignment=\"alignment\" :css-custom-properties=\"cssCustomProperties\">\n <slot name=\"content\"></slot>\n </PvPopover>\n </nav>\n</template>\n","/**\n * Custom positioning reference element.\n * @see https://floating-ui.com/docs/virtual-elements\n */\n\nconst sides = ['top', 'right', 'bottom', 'left'];\nconst alignments = ['start', 'end'];\nconst placements = /*#__PURE__*/sides.reduce((acc, side) => acc.concat(side, side + \"-\" + alignments[0], side + \"-\" + alignments[1]), []);\nconst min = Math.min;\nconst max = Math.max;\nconst round = Math.round;\nconst floor = Math.floor;\nconst createCoords = v => ({\n x: v,\n y: v\n});\nconst oppositeSideMap = {\n left: 'right',\n right: 'left',\n bottom: 'top',\n top: 'bottom'\n};\nfunction clamp(start, value, end) {\n return max(start, min(value, end));\n}\nfunction evaluate(value, param) {\n return typeof value === 'function' ? value(param) : value;\n}\nfunction getSide(placement) {\n return placement.split('-')[0];\n}\nfunction getAlignment(placement) {\n return placement.split('-')[1];\n}\nfunction getOppositeAxis(axis) {\n return axis === 'x' ? 'y' : 'x';\n}\nfunction getAxisLength(axis) {\n return axis === 'y' ? 'height' : 'width';\n}\nfunction getSideAxis(placement) {\n const firstChar = placement[0];\n return firstChar === 't' || firstChar === 'b' ? 'y' : 'x';\n}\nfunction getAlignmentAxis(placement) {\n return getOppositeAxis(getSideAxis(placement));\n}\nfunction getAlignmentSides(placement, rects, rtl) {\n if (rtl === void 0) {\n rtl = false;\n }\n const alignment = getAlignment(placement);\n const alignmentAxis = getAlignmentAxis(placement);\n const length = getAxisLength(alignmentAxis);\n let mainAlignmentSide = alignmentAxis === 'x' ? alignment === (rtl ? 'end' : 'start') ? 'right' : 'left' : alignment === 'start' ? 'bottom' : 'top';\n if (rects.reference[length] > rects.floating[length]) {\n mainAlignmentSide = getOppositePlacement(mainAlignmentSide);\n }\n return [mainAlignmentSide, getOppositePlacement(mainAlignmentSide)];\n}\nfunction getExpandedPlacements(placement) {\n const oppositePlacement = getOppositePlacement(placement);\n return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];\n}\nfunction getOppositeAlignmentPlacement(placement) {\n return placement.includes('start') ? placement.replace('start', 'end') : placement.replace('end', 'start');\n}\nconst lrPlacement = ['left', 'right'];\nconst rlPlacement = ['right', 'left'];\nconst tbPlacement = ['top', 'bottom'];\nconst btPlacement = ['bottom', 'top'];\nfunction getSideList(side, isStart, rtl) {\n switch (side) {\n case 'top':\n case 'bottom':\n if (rtl) return isStart ? rlPlacement : lrPlacement;\n return isStart ? lrPlacement : rlPlacement;\n case 'left':\n case 'right':\n return isStart ? tbPlacement : btPlacement;\n default:\n return [];\n }\n}\nfunction getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {\n const alignment = getAlignment(placement);\n let list = getSideList(getSide(placement), direction === 'start', rtl);\n if (alignment) {\n list = list.map(side => side + \"-\" + alignment);\n if (flipAlignment) {\n list = list.concat(list.map(getOppositeAlignmentPlacement));\n }\n }\n return list;\n}\nfunction getOppositePlacement(placement) {\n const side = getSide(placement);\n return oppositeSideMap[side] + placement.slice(side.length);\n}\nfunction expandPaddingObject(padding) {\n return {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n ...padding\n };\n}\nfunction getPaddingObject(padding) {\n return typeof padding !== 'number' ? expandPaddingObject(padding) : {\n top: padding,\n right: padding,\n bottom: padding,\n left: padding\n };\n}\nfunction rectToClientRect(rect) {\n const {\n x,\n y,\n width,\n height\n } = rect;\n return {\n width,\n height,\n top: y,\n left: x,\n right: x + width,\n bottom: y + height,\n x,\n y\n };\n}\n\nexport { alignments, clamp, createCoords, evaluate, expandPaddingObject, floor, getAlignment, getAlignmentAxis, getAlignmentSides, getAxisLength, getExpandedPlacements, getOppositeAlignmentPlacement, getOppositeAxis, getOppositeAxisPlacements, getOppositePlacement, getPaddingObject, getSide, getSideAxis, max, min, placements, rectToClientRect, round, sides };\n","import { getSideAxis, getAlignmentAxis, getAxisLength, getSide, getAlignment, evaluate, getPaddingObject, rectToClientRect, min, clamp, placements, getAlignmentSides, getOppositeAlignmentPlacement, getOppositePlacement, getExpandedPlacements, getOppositeAxisPlacements, sides, max, getOppositeAxis } from '@floating-ui/utils';\nexport { rectToClientRect } from '@floating-ui/utils';\n\nfunction computeCoordsFromPlacement(_ref, placement, rtl) {\n let {\n reference,\n floating\n } = _ref;\n const sideAxis = getSideAxis(placement);\n const alignmentAxis = getAlignmentAxis(placement);\n const alignLength = getAxisLength(alignmentAxis);\n const side = getSide(placement);\n const isVertical = sideAxis === 'y';\n const commonX = reference.x + reference.width / 2 - floating.width / 2;\n const commonY = reference.y + reference.height / 2 - floating.height / 2;\n const commonAlign = reference[alignLength] / 2 - floating[alignLength] / 2;\n let coords;\n switch (side) {\n case 'top':\n coords = {\n x: commonX,\n y: reference.y - floating.height\n };\n break;\n case 'bottom':\n coords = {\n x: commonX,\n y: reference.y + reference.height\n };\n break;\n case 'right':\n coords = {\n x: reference.x + reference.width,\n y: commonY\n };\n break;\n case 'left':\n coords = {\n x: reference.x - floating.width,\n y: commonY\n };\n break;\n default:\n coords = {\n x: reference.x,\n y: reference.y\n };\n }\n switch (getAlignment(placement)) {\n case 'start':\n coords[alignmentAxis] -= commonAlign * (rtl && isVertical ? -1 : 1);\n break;\n case 'end':\n coords[alignmentAxis] += commonAlign * (rtl && isVertical ? -1 : 1);\n break;\n }\n return coords;\n}\n\n/**\n * Resolves with an object of overflow side offsets that determine how much the\n * element is overflowing a given clipping boundary on each side.\n * - positive = overflowing the boundary by that number of pixels\n * - negative = how many pixels left before it will overflow\n * - 0 = lies flush with the boundary\n * @see https://floating-ui.com/docs/detectOverflow\n */\nasync function detectOverflow(state, options) {\n var _await$platform$isEle;\n if (options === void 0) {\n options = {};\n }\n const {\n x,\n y,\n platform,\n rects,\n elements,\n strategy\n } = state;\n const {\n boundary = 'clippingAncestors',\n rootBoundary = 'viewport',\n elementContext = 'floating',\n altBoundary = false,\n padding = 0\n } = evaluate(options, state);\n const paddingObject = getPaddingObject(padding);\n const altContext = elementContext === 'floating' ? 'reference' : 'floating';\n const element = elements[altBoundary ? altContext : elementContext];\n const clippingClientRect = rectToClientRect(await platform.getClippingRect({\n element: ((_await$platform$isEle = await (platform.isElement == null ? void 0 : platform.isElement(element))) != null ? _await$platform$isEle : true) ? element : element.contextElement || (await (platform.getDocumentElement == null ? void 0 : platform.getDocumentElement(elements.floating))),\n boundary,\n rootBoundary,\n strategy\n }));\n const rect = elementContext === 'floating' ? {\n x,\n y,\n width: rects.floating.width,\n height: rects.floating.height\n } : rects.reference;\n const offsetParent = await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(elements.floating));\n const offsetScale = (await (platform.isElement == null ? void 0 : platform.isElement(offsetParent))) ? (await (platform.getScale == null ? void 0 : platform.getScale(offsetParent))) || {\n x: 1,\n y: 1\n } : {\n x: 1,\n y: 1\n };\n const elementClientRect = rectToClientRect(platform.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform.convertOffsetParentRelativeRectToViewportRelativeRect({\n elements,\n rect,\n offsetParent,\n strategy\n }) : rect);\n return {\n top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y,\n bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y,\n left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x,\n right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x\n };\n}\n\n// Maximum number of resets that can occur before bailing to avoid infinite reset loops.\nconst MAX_RESET_COUNT = 50;\n\n/**\n * Computes the `x` and `y` coordinates that will place the floating element\n * next to a given reference element.\n *\n * This export does not have any `platform` interface logic. You will need to\n * write one for the platform you are using Floating UI with.\n */\nconst computePosition = async (reference, floating, config) => {\n const {\n placement = 'bottom',\n strategy = 'absolute',\n middleware = [],\n platform\n } = config;\n const platformWithDetectOverflow = platform.detectOverflow ? platform : {\n ...platform,\n detectOverflow\n };\n const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(floating));\n let rects = await platform.getElementRects({\n reference,\n floating,\n strategy\n });\n let {\n x,\n y\n } = computeCoordsFromPlacement(rects, placement, rtl);\n let statefulPlacement = placement;\n let resetCount = 0;\n const middlewareData = {};\n for (let i = 0; i < middleware.length; i++) {\n const currentMiddleware = middleware[i];\n if (!currentMiddleware) {\n continue;\n }\n const {\n name,\n fn\n } = currentMiddleware;\n const {\n x: nextX,\n y: nextY,\n data,\n reset\n } = await fn({\n x,\n y,\n initialPlacement: placement,\n placement: statefulPlacement,\n strategy,\n middlewareData,\n rects,\n platform: platformWithDetectOverflow,\n elements: {\n reference,\n floating\n }\n });\n x = nextX != null ? nextX : x;\n y = nextY != null ? nextY : y;\n middlewareData[name] = {\n ...middlewareData[name],\n ...data\n };\n if (reset && resetCount < MAX_RESET_COUNT) {\n resetCount++;\n if (typeof reset === 'object') {\n if (reset.placement) {\n statefulPlacement = reset.placement;\n }\n if (reset.rects) {\n rects = reset.rects === true ? await platform.getElementRects({\n reference,\n floating,\n strategy\n }) : reset.rects;\n }\n ({\n x,\n y\n } = computeCoordsFromPlacement(rects, statefulPlacement, rtl));\n }\n i = -1;\n }\n }\n return {\n x,\n y,\n placement: statefulPlacement,\n strategy,\n middlewareData\n };\n};\n\n/**\n * Provides data to position an inner element of the floating element so that it\n * appears centered to the reference element.\n * @see https://floating-ui.com/docs/arrow\n */\nconst arrow = options => ({\n name: 'arrow',\n options,\n async fn(state) {\n const {\n x,\n y,\n placement,\n rects,\n platform,\n elements,\n middlewareData\n } = state;\n // Since `element` is required, we don't Partial<> the type.\n const {\n element,\n padding = 0\n } = evaluate(options, state) || {};\n if (element == null) {\n return {};\n }\n const paddingObject = getPaddingObject(padding);\n const coords = {\n x,\n y\n };\n const axis = getAlignmentAxis(placement);\n const length = getAxisLength(axis);\n const arrowDimensions = await platform.getDimensions(element);\n const isYAxis = axis === 'y';\n const minProp = isYAxis ? 'top' : 'left';\n const maxProp = isYAxis ? 'bottom' : 'right';\n const clientProp = isYAxis ? 'clientHeight' : 'clientWidth';\n const endDiff = rects.reference[length] + rects.reference[axis] - coords[axis] - rects.floating[length];\n const startDiff = coords[axis] - rects.reference[axis];\n const arrowOffsetParent = await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(element));\n let clientSize = arrowOffsetParent ? arrowOffsetParent[clientProp] : 0;\n\n // DOM platform can return `window` as the `offsetParent`.\n if (!clientSize || !(await (platform.isElement == null ? void 0 : platform.isElement(arrowOffsetParent)))) {\n clientSize = elements.floating[clientProp] || rects.floating[length];\n }\n const centerToReference = endDiff / 2 - startDiff / 2;\n\n // If the padding is large enough that it causes the arrow to no longer be\n // centered, modify the padding so that it is centered.\n const largestPossiblePadding = clientSize / 2 - arrowDimensions[length] / 2 - 1;\n const minPadding = min(paddingObject[minProp], largestPossiblePadding);\n const maxPadding = min(paddingObject[maxProp], largestPossiblePadding);\n\n // Make sure the arrow doesn't overflow the floating element if the center\n // point is outside the floating element's bounds.\n const min$1 = minPadding;\n const max = clientSize - arrowDimensions[length] - maxPadding;\n const center = clientSize / 2 - arrowDimensions[length] / 2 + centerToReference;\n const offset = clamp(min$1, center, max);\n\n // If the reference is small enough that the arrow's padding causes it to\n // to point to nothing for an aligned placement, adjust the offset of the\n // floating element itself. To ensure `shift()` continues to take action,\n // a single reset is performed when this is true.\n const shouldAddOffset = !middlewareData.arrow && getAlignment(placement) != null && center !== offset && rects.reference[length] / 2 - (center < min$1 ? minPadding : maxPadding) - arrowDimensions[length] / 2 < 0;\n const alignmentOffset = shouldAddOffset ? center < min$1 ? center - min$1 : center - max : 0;\n return {\n [axis]: coords[axis] + alignmentOffset,\n data: {\n [axis]: offset,\n centerOffset: center - offset - alignmentOffset,\n ...(shouldAddOffset && {\n alignmentOffset\n })\n },\n reset: shouldAddOffset\n };\n }\n});\n\nfunction getPlacementList(alignment, autoAlignment, allowedPlacements) {\n const allowedPlacementsSortedByAlignment = alignment ? [...allowedPlacements.filter(placement => getAlignment(placement) === alignment), ...allowedPlacements.filter(placement => getAlignment(placement) !== alignment)] : allowedPlacements.filter(placement => getSide(placement) === placement);\n return allowedPlacementsSortedByAlignment.filter(placement => {\n if (alignment) {\n return getAlignment(placement) === alignment || (autoAlignment ? getOppositeAlignmentPlacement(placement) !== placement : false);\n }\n return true;\n });\n}\n/**\n * Optimizes the visibility of the floating element by choosing the placement\n * that has the most space available automatically, without needing to specify a\n * preferred placement. Alternative to `flip`.\n * @see https://floating-ui.com/docs/autoPlacement\n */\nconst autoPlacement = function (options) {\n if (options === void 0) {\n options = {};\n }\n return {\n name: 'autoPlacement',\n options,\n async fn(state) {\n var _middlewareData$autoP, _middlewareData$autoP2, _placementsThatFitOnE;\n const {\n rects,\n middlewareData,\n placement,\n platform,\n elements\n } = state;\n const {\n crossAxis = false,\n alignment,\n allowedPlacements = placements,\n autoAlignment = true,\n ...detectOverflowOptions\n } = evaluate(options, state);\n const placements$1 = alignment !== undefined || allowedPlacements === placements ? getPlacementList(alignment || null, autoAlignment, allowedPlacements) : allowedPlacements;\n const overflow = await platform.detectOverflow(state, detectOverflowOptions);\n const currentIndex = ((_middlewareData$autoP = middlewareData.autoPlacement) == null ? void 0 : _middlewareData$autoP.index) || 0;\n const currentPlacement = placements$1[currentIndex];\n if (currentPlacement == null) {\n return {};\n }\n const alignmentSides = getAlignmentSides(currentPlacement, rects, await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating)));\n\n // Make `computeCoords` start from the right place.\n if (placement !== currentPlacement) {\n return {\n reset: {\n placement: placements$1[0]\n }\n };\n }\n const currentOverflows = [overflow[getSide(currentPlacement)], overflow[alignmentSides[0]], overflow[alignmentSides[1]]];\n const allOverflows = [...(((_middlewareData$autoP2 = middlewareData.autoPlacement) == null ? void 0 : _middlewareData$autoP2.overflows) || []), {\n placement: currentPlacement,\n overflows: currentOverflows\n }];\n const nextPlacement = placements$1[currentIndex + 1];\n\n // There are more placements to check.\n if (nextPlacement) {\n return {\n data: {\n index: currentIndex + 1,\n overflows: allOverflows\n },\n reset: {\n placement: nextPlacement\n }\n };\n }\n const placementsSortedByMostSpace = allOverflows.map(d => {\n const alignment = getAlignment(d.placement);\n return [d.placement, alignment && crossAxis ?\n // Check along the mainAxis and main crossAxis side.\n d.overflows.slice(0, 2).reduce((acc, v) => acc + v, 0) :\n // Check only the mainAxis.\n d.overflows[0], d.overflows];\n }).sort((a, b) => a[1] - b[1]);\n const placementsThatFitOnEachSide = placementsSortedByMostSpace.filter(d => d[2].slice(0,\n // Aligned placements should not check their opposite crossAxis\n // side.\n getAlignment(d[0]) ? 2 : 3).every(v => v <= 0));\n const resetPlacement = ((_placementsThatFitOnE = placementsThatFitOnEachSide[0]) == null ? void 0 : _placementsThatFitOnE[0]) || placementsSortedByMostSpace[0][0];\n if (resetPlacement !== placement) {\n return {\n data: {\n index: currentIndex + 1,\n overflows: allOverflows\n },\n reset: {\n placement: resetPlacement\n }\n };\n }\n return {};\n }\n };\n};\n\n/**\n * Optimizes the visibility of the floating element by flipping the `placement`\n * in order to keep it in view when the preferred placement(s) will overflow the\n * clipping boundary. Alternative to `autoPlacement`.\n * @see https://floating-ui.com/docs/flip\n */\nconst flip = function (options) {\n if (options === void 0) {\n options = {};\n }\n return {\n name: 'flip',\n options,\n async fn(state) {\n var _middlewareData$arrow, _middlewareData$flip;\n const {\n placement,\n middlewareData,\n rects,\n initialPlacement,\n platform,\n elements\n } = state;\n const {\n mainAxis: checkMainAxis = true,\n crossAxis: checkCrossAxis = true,\n fallbackPlacements: specifiedFallbackPlacements,\n fallbackStrategy = 'bestFit',\n fallbackAxisSideDirection = 'none',\n flipAlignment = true,\n ...detectOverflowOptions\n } = evaluate(options, state);\n\n // If a reset by the arrow was caused due to an alignment offset being\n // added, we should skip any logic now since `flip()` has already done its\n // work.\n // https://github.com/floating-ui/floating-ui/issues/2549#issuecomment-1719601643\n if ((_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {\n return {};\n }\n const side = getSide(placement);\n const initialSideAxis = getSideAxis(initialPlacement);\n const isBasePlacement = getSide(initialPlacement) === initialPlacement;\n const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating));\n const fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipAlignment ? [getOppositePlacement(initialPlacement)] : getExpandedPlacements(initialPlacement));\n const hasFallbackAxisSideDirection = fallbackAxisSideDirection !== 'none';\n if (!specifiedFallbackPlacements && hasFallbackAxisSideDirection) {\n fallbackPlacements.push(...getOppositeAxisPlacements(initialPlacement, flipAlignment, fallbackAxisSideDirection, rtl));\n }\n const placements = [initialPlacement, ...fallbackPlacements];\n const overflow = await platform.detectOverflow(state, detectOverflowOptions);\n const overflows = [];\n let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || [];\n if (checkMainAxis) {\n overflows.push(overflow[side]);\n }\n if (checkCrossAxis) {\n const sides = getAlignmentSides(placement, rects, rtl);\n overflows.push(overflow[sides[0]], overflow[sides[1]]);\n }\n overflowsData = [...overflowsData, {\n placement,\n overflows\n }];\n\n // One or more sides is overflowing.\n if (!overflows.every(side => side <= 0)) {\n var _middlewareData$flip2, _overflowsData$filter;\n const nextIndex = (((_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) || 0) + 1;\n const nextPlacement = placements[nextIndex];\n if (nextPlacement) {\n const ignoreCrossAxisOverflow = checkCrossAxis === 'alignment' ? initialSideAxis !== getSideAxis(nextPlacement) : false;\n if (!ignoreCrossAxisOverflow ||\n // We leave the current main axis only if every placement on that axis\n // overflows the main axis.\n overflowsData.every(d => getSideAxis(d.placement) === initialSideAxis ? d.overflows[0] > 0 : true)) {\n // Try next placement and re-run the lifecycle.\n return {\n data: {\n index: nextIndex,\n overflows: overflowsData\n },\n reset: {\n placement: nextPlacement\n }\n };\n }\n }\n\n // First, find the candidates that fit on the mainAxis side of overflow,\n // then find the placement that fits the best on the main crossAxis side.\n let resetPlacement = (_overflowsData$filter = overflowsData.filter(d => d.overflows[0] <= 0).sort((a, b) => a.overflows[1] - b.overflows[1])[0]) == null ? void 0 : _overflowsData$filter.placement;\n\n // Otherwise fallback.\n if (!resetPlacement) {\n switch (fallbackStrategy) {\n case 'bestFit':\n {\n var _overflowsData$filter2;\n const placement = (_overflowsData$filter2 = overflowsData.filter(d => {\n if (hasFallbackAxisSideDirection) {\n const currentSideAxis = getSideAxis(d.placement);\n return currentSideAxis === initialSideAxis ||\n // Create a bias to the `y` side axis due to horizontal\n // reading directions favoring greater width.\n currentSideAxis === 'y';\n }\n return true;\n }).map(d => [d.placement, d.overflows.filter(overflow => overflow > 0).reduce((acc, overflow) => acc + overflow, 0)]).sort((a, b) => a[1] - b[1])[0]) == null ? void 0 : _overflowsData$filter2[0];\n if (placement) {\n resetPlacement = placement;\n }\n break;\n }\n case 'initialPlacement':\n resetPlacement = initialPlacement;\n break;\n }\n }\n if (placement !== resetPlacement) {\n return {\n reset: {\n placement: resetPlacement\n }\n };\n }\n }\n return {};\n }\n };\n};\n\nfunction getSideOffsets(overflow, rect) {\n return {\n top: overflow.top - rect.height,\n right: overflow.right - rect.width,\n bottom: overflow.bottom - rect.height,\n left: overflow.left - rect.width\n };\n}\nfunction isAnySideFullyClipped(overflow) {\n return sides.some(side => overflow[side] >= 0);\n}\n/**\n * Provides data to hide the floating element in applicable situations, such as\n * when it is not in the same clipping context as the reference element.\n * @see https://floating-ui.com/docs/hide\n */\nconst hide = function (options) {\n if (options === void 0) {\n options = {};\n }\n return {\n name: 'hide',\n options,\n async fn(state) {\n const {\n rects,\n platform\n } = state;\n const {\n strategy = 'referenceHidden',\n ...detectOverflowOptions\n } = evaluate(options, state);\n switch (strategy) {\n case 'referenceHidden':\n {\n const overflow = await platform.detectOverflow(state, {\n ...detectOverflowOptions,\n elementContext: 'reference'\n });\n const offsets = getSideOffsets(overflow, rects.reference);\n return {\n data: {\n referenceHiddenOffsets: offsets,\n referenceHidden: isAnySideFullyClipped(offsets)\n }\n };\n }\n case 'escaped':\n {\n const overflow = await platform.detectOverflow(state, {\n ...detectOverflowOptions,\n altBoundary: true\n });\n const offsets = getSideOffsets(overflow, rects.floating);\n return {\n data: {\n escapedOffsets: offsets,\n escaped: isAnySideFullyClipped(offsets)\n }\n };\n }\n default:\n {\n return {};\n }\n }\n }\n };\n};\n\nfunction getBoundingRect(rects) {\n const minX = min(...rects.map(rect => rect.left));\n const minY = min(...rects.map(rect => rect.top));\n const maxX = max(...rects.map(rect => rect.right));\n const maxY = max(...rects.map(rect => rect.bottom));\n return {\n x: minX,\n y: minY,\n width: maxX - minX,\n height: maxY - minY\n };\n}\nfunction getRectsByLine(rects) {\n const sortedRects = rects.slice().sort((a, b) => a.y - b.y);\n const groups = [];\n let prevRect = null;\n for (let i = 0; i < sortedRects.length; i++) {\n const rect = sortedRects[i];\n if (!prevRect || rect.y - prevRect.y > prevRect.height / 2) {\n groups.push([rect]);\n } else {\n groups[groups.length - 1].push(rect);\n }\n prevRect = rect;\n }\n return groups.map(rect => rectToClientRect(getBoundingRect(rect)));\n}\n/**\n * Provides improved positioning for inline reference elements that can span\n * over multiple lines, such as hyperlinks or range selections.\n * @see https://floating-ui.com/docs/inline\n */\nconst inline = function (options) {\n if (options === void 0) {\n options = {};\n }\n return {\n name: 'inline',\n options,\n async fn(state) {\n const {\n placement,\n elements,\n rects,\n platform,\n strategy\n } = state;\n // A MouseEvent's client{X,Y} coords can be up to 2 pixels off a\n // ClientRect's bounds, despite the event listener being triggered. A\n // padding of 2 seems to handle this issue.\n const {\n padding = 2,\n x,\n y\n } = evaluate(options, state);\n const nativeClientRects = Array.from((await (platform.getClientRects == null ? void 0 : platform.getClientRects(elements.reference))) || []);\n const clientRects = getRectsByLine(nativeClientRects);\n const fallback = rectToClientRect(getBoundingRect(nativeClientRects));\n const paddingObject = getPaddingObject(padding);\n function getBoundingClientRect() {\n // There are two rects and they are disjoined.\n if (clientRects.length === 2 && clientRects[0].left > clientRects[1].right && x != null && y != null) {\n // Find the first rect in which the point is fully inside.\n return clientRects.find(rect => x > rect.left - paddingObject.left && x < rect.right + paddingObject.right && y > rect.top - paddingObject.top && y < rect.bottom + paddingObject.bottom) || fallback;\n }\n\n // There are 2 or more connected rects.\n if (clientRects.length >= 2) {\n if (getSideAxis(placement) === 'y') {\n const firstRect = clientRects[0];\n const lastRect = clientRects[clientRects.length - 1];\n const isTop = getSide(placement) === 'top';\n const top = firstRect.top;\n const bottom = lastRect.bottom;\n const left = isTop ? firstRect.left : lastRect.left;\n const right = isTop ? firstRect.right : lastRect.right;\n const width = right - left;\n const height = bottom - top;\n return {\n top,\n bottom,\n left,\n right,\n width,\n height,\n x: left,\n y: top\n };\n }\n const isLeftSide = getSide(placement) === 'left';\n const maxRight = max(...clientRects.map(rect => rect.right));\n const minLeft = min(...clientRects.map(rect => rect.left));\n const measureRects = clientRects.filter(rect => isLeftSide ? rect.left === minLeft : rect.right === maxRight);\n const top = measureRects[0].top;\n const bottom = measureRects[measureRects.length - 1].bottom;\n const left = minLeft;\n const right = maxRight;\n const width = right - left;\n const height = bottom - top;\n return {\n top,\n bottom,\n left,\n right,\n width,\n height,\n x: left,\n y: top\n };\n }\n return fallback;\n }\n const resetRects = await platform.getElementRects({\n reference: {\n getBoundingClientRect\n },\n floating: elements.floating,\n strategy\n });\n if (rects.reference.x !== resetRects.reference.x || rects.reference.y !== resetRects.reference.y || rects.reference.width !== resetRects.reference.width || rects.reference.height !== resetRects.reference.height) {\n return {\n reset: {\n rects: resetRects\n }\n };\n }\n return {};\n }\n };\n};\n\nconst originSides = /*#__PURE__*/new Set(['left', 'top']);\n\n// For type backwards-compatibility, the `OffsetOptions` type was also\n// Derivable.\n\nasync function convertValueToCoords(state, options) {\n const {\n placement,\n platform,\n elements\n } = state;\n const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating));\n const side = getSide(placement);\n const alignment = getAlignment(placement);\n const isVertical = getSideAxis(placement) === 'y';\n const mainAxisMulti = originSides.has(side) ? -1 : 1;\n const crossAxisMulti = rtl && isVertical ? -1 : 1;\n const rawValue = evaluate(options, state);\n\n // eslint-disable-next-line prefer-const\n let {\n mainAxis,\n crossAxis,\n alignmentAxis\n } = typeof rawValue === 'number' ? {\n mainAxis: rawValue,\n crossAxis: 0,\n alignmentAxis: null\n } : {\n mainAxis: rawValue.mainAxis || 0,\n crossAxis: rawValue.crossAxis || 0,\n alignmentAxis: rawValue.alignmentAxis\n };\n if (alignment && typeof alignmentAxis === 'number') {\n crossAxis = alignment === 'end' ? alignmentAxis * -1 : alignmentAxis;\n }\n return isVertical ? {\n x: crossAxis * crossAxisMulti,\n y: mainAxis * mainAxisMulti\n } : {\n x: mainAxis * mainAxisMulti,\n y: crossAxis * crossAxisMulti\n };\n}\n\n/**\n * Modifies the placement by translating the floating element along the\n * specified axes.\n * A number (shorthand for `mainAxis` or distance), or an axes configuration\n * object may be passed.\n * @see https://floating-ui.com/docs/offset\n */\nconst offset = function (options) {\n if (options === void 0) {\n options = 0;\n }\n return {\n name: 'offset',\n options,\n async fn(state) {\n var _middlewareData$offse, _middlewareData$arrow;\n const {\n x,\n y,\n placement,\n middlewareData\n } = state;\n const diffCoords = await convertValueToCoords(state, options);\n\n // If the placement is the same and the arrow caused an alignment offset\n // then we don't need to change the positioning coordinates.\n if (placement === ((_middlewareData$offse = middlewareData.offset) == null ? void 0 : _middlewareData$offse.placement) && (_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {\n return {};\n }\n return {\n x: x + diffCoords.x,\n y: y + diffCoords.y,\n data: {\n ...diffCoords,\n placement\n }\n };\n }\n };\n};\n\n/**\n * Optimizes the visibility of the floating element by shifting it in order to\n * keep it in view when it will overflow the clipping boundary.\n * @see https://floating-ui.com/docs/shift\n */\nconst shift = function (options) {\n if (options === void 0) {\n options = {};\n }\n return {\n name: 'shift',\n options,\n async fn(state) {\n const {\n x,\n y,\n placement,\n platform\n } = state;\n const {\n mainAxis: checkMainAxis = true,\n crossAxis: checkCrossAxis = false,\n limiter = {\n fn: _ref => {\n let {\n x,\n y\n } = _ref;\n return {\n x,\n y\n };\n }\n },\n ...detectOverflowOptions\n } = evaluate(options, state);\n const coords = {\n x,\n y\n };\n const overflow = await platform.detectOverflow(state, detectOverflowOptions);\n const crossAxis = getSideAxis(getSide(placement));\n const mainAxis = getOppositeAxis(crossAxis);\n let mainAxisCoord = coords[mainAxis];\n let crossAxisCoord = coords[crossAxis];\n if (checkMainAxis) {\n const minSide = mainAxis === 'y' ? 'top' : 'left';\n const maxSide = mainAxis === 'y' ? 'bottom' : 'right';\n const min = mainAxisCoord + overflow[minSide];\n const max = mainAxisCoord - overflow[maxSide];\n mainAxisCoord = clamp(min, mainAxisCoord, max);\n }\n if (checkCrossAxis) {\n const minSide = crossAxis === 'y' ? 'top' : 'left';\n const maxSide = crossAxis === 'y' ? 'bottom' : 'right';\n const min = crossAxisCoord + overflow[minSide];\n const max = crossAxisCoord - overflow[maxSide];\n crossAxisCoord = clamp(min, crossAxisCoord, max);\n }\n const limitedCoords = limiter.fn({\n ...state,\n [mainAxis]: mainAxisCoord,\n [crossAxis]: crossAxisCoord\n });\n return {\n ...limitedCoords,\n data: {\n x: limitedCoords.x - x,\n y: limitedCoords.y - y,\n enabled: {\n [mainAxis]: checkMainAxis,\n [crossAxis]: checkCrossAxis\n }\n }\n };\n }\n };\n};\n/**\n * Built-in `limiter` that will stop `shift()` at a certain point.\n */\nconst limitShift = function (options) {\n if (options === void 0) {\n options = {};\n }\n return {\n options,\n fn(state) {\n const {\n x,\n y,\n placement,\n rects,\n middlewareData\n } = state;\n const {\n offset = 0,\n mainAxis: checkMainAxis = true,\n crossAxis: checkCrossAxis = true\n } = evaluate(options, state);\n const coords = {\n x,\n y\n };\n const crossAxis = getSideAxis(placement);\n const mainAxis = getOppositeAxis(crossAxis);\n let mainAxisCoord = coords[mainAxis];\n let crossAxisCoord = coords[crossAxis];\n const rawOffset = evaluate(offset, state);\n const computedOffset = typeof rawOffset === 'number' ? {\n mainAxis: rawOffset,\n crossAxis: 0\n } : {\n mainAxis: 0,\n crossAxis: 0,\n ...rawOffset\n };\n if (checkMainAxis) {\n const len = mainAxis === 'y' ? 'height' : 'width';\n const limitMin = rects.reference[mainAxis] - rects.floating[len] + computedOffset.mainAxis;\n const limitMax = rects.reference[mainAxis] + rects.reference[len] - computedOffset.mainAxis;\n if (mainAxisCoord < limitMin) {\n mainAxisCoord = limitMin;\n } else if (mainAxisCoord > limitMax) {\n mainAxisCoord = limitMax;\n }\n }\n if (checkCrossAxis) {\n var _middlewareData$offse, _middlewareData$offse2;\n const len = mainAxis === 'y' ? 'width' : 'height';\n const isOriginSide = originSides.has(getSide(placement));\n const limitMin = rects.reference[crossAxis] - rects.floating[len] + (isOriginSide ? ((_middlewareData$offse = middlewareData.offset) == null ? void 0 : _middlewareData$offse[crossAxis]) || 0 : 0) + (isOriginSide ? 0 : computedOffset.crossAxis);\n const limitMax = rects.reference[crossAxis] + rects.reference[len] + (isOriginSide ? 0 : ((_middlewareData$offse2 = middlewareData.offset) == null ? void 0 : _middlewareData$offse2[crossAxis]) || 0) - (isOriginSide ? computedOffset.crossAxis : 0);\n if (crossAxisCoord < limitMin) {\n crossAxisCoord = limitMin;\n } else if (crossAxisCoord > limitMax) {\n crossAxisCoord = limitMax;\n }\n }\n return {\n [mainAxis]: mainAxisCoord,\n [crossAxis]: crossAxisCoord\n };\n }\n };\n};\n\n/**\n * Provides data that allows you to change the size of the floating element —\n * for instance, prevent it from overflowing the clipping boundary or match the\n * width of the reference element.\n * @see https://floating-ui.com/docs/size\n */\nconst size = function (options) {\n if (options === void 0) {\n options = {};\n }\n return {\n name: 'size',\n options,\n async fn(state) {\n var _state$middlewareData, _state$middlewareData2;\n const {\n placement,\n rects,\n platform,\n elements\n } = state;\n const {\n apply = () => {},\n ...detectOverflowOptions\n } = evaluate(options, state);\n const overflow = await platform.detectOverflow(state, detectOverflowOptions);\n const side = getSide(placement);\n const alignment = getAlignment(placement);\n const isYAxis = getSideAxis(placement) === 'y';\n const {\n width,\n height\n } = rects.floating;\n let heightSide;\n let widthSide;\n if (side === 'top' || side === 'bottom') {\n heightSide = side;\n widthSide = alignment === ((await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating))) ? 'start' : 'end') ? 'left' : 'right';\n } else {\n widthSide = side;\n heightSide = alignment === 'end' ? 'top' : 'bottom';\n }\n const maximumClippingHeight = height - overflow.top - overflow.bottom;\n const maximumClippingWidth = width - overflow.left - overflow.right;\n const overflowAvailableHeight = min(height - overflow[heightSide], maximumClippingHeight);\n const overflowAvailableWidth = min(width - overflow[widthSide], maximumClippingWidth);\n const noShift = !state.middlewareData.shift;\n let availableHeight = overflowAvailableHeight;\n let availableWidth = overflowAvailableWidth;\n if ((_state$middlewareData = state.middlewareData.shift) != null && _state$middlewareData.enabled.x) {\n availableWidth = maximumClippingWidth;\n }\n if ((_state$middlewareData2 = state.middlewareData.shift) != null && _state$middlewareData2.enabled.y) {\n availableHeight = maximumClippingHeight;\n }\n if (noShift && !alignment) {\n const xMin = max(overflow.left, 0);\n const xMax = max(overflow.right, 0);\n const yMin = max(overflow.top, 0);\n const yMax = max(overflow.bottom, 0);\n if (isYAxis) {\n availableWidth = width - 2 * (xMin !== 0 || xMax !== 0 ? xMin + xMax : max(overflow.left, overflow.right));\n } else {\n availableHeight = height - 2 * (yMin !== 0 || yMax !== 0 ? yMin + yMax : max(overflow.top, overflow.bottom));\n }\n }\n await apply({\n ...state,\n availableWidth,\n availableHeight\n });\n const nextDimensions = await platform.getDimensions(elements.floating);\n if (width !== nextDimensions.width || height !== nextDimensions.height) {\n return {\n reset: {\n rects: true\n }\n };\n }\n return {};\n }\n };\n};\n\nexport { arrow, autoPlacement, computePosition, detectOverflow, flip, hide, inline, limitShift, offset, shift, size };\n","function hasWindow() {\n return typeof window !== 'undefined';\n}\nfunction getNodeName(node) {\n if (isNode(node)) {\n return (node.nodeName || '').toLowerCase();\n }\n // Mocked nodes in testing environments may not be instances of Node. By\n // returning `#document` an infinite loop won't occur.\n // https://github.com/floating-ui/floating-ui/issues/2317\n return '#document';\n}\nfunction getWindow(node) {\n var _node$ownerDocument;\n return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;\n}\nfunction getDocumentElement(node) {\n var _ref;\n return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;\n}\nfunction isNode(value) {\n if (!hasWindow()) {\n return false;\n }\n return value instanceof Node || value instanceof getWindow(value).Node;\n}\nfunction isElement(value) {\n if (!hasWindow()) {\n return false;\n }\n return value instanceof Element || value instanceof getWindow(value).Element;\n}\nfunction isHTMLElement(value) {\n if (!hasWindow()) {\n return false;\n }\n return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;\n}\nfunction isShadowRoot(value) {\n if (!hasWindow() || typeof ShadowRoot === 'undefined') {\n return false;\n }\n return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;\n}\nfunction isOverflowElement(element) {\n const {\n overflow,\n overflowX,\n overflowY,\n display\n } = getComputedStyle(element);\n return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && display !== 'inline' && display !== 'contents';\n}\nfunction isTableElement(element) {\n return /^(table|td|th)$/.test(getNodeName(element));\n}\nfunction isTopLayer(element) {\n try {\n if (element.matches(':popover-open')) {\n return true;\n }\n } catch (_e) {\n // no-op\n }\n try {\n return element.matches(':modal');\n } catch (_e) {\n return false;\n }\n}\nconst willChangeRe = /transform|translate|scale|rotate|perspective|filter/;\nconst containRe = /paint|layout|strict|content/;\nconst isNotNone = value => !!value && value !== 'none';\nlet isWebKitValue;\nfunction isContainingBlock(elementOrCss) {\n const css = isElement(elementOrCss) ? getComputedStyle(elementOrCss) : elementOrCss;\n\n // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block\n // https://drafts.csswg.org/css-transforms-2/#individual-transforms\n return isNotNone(css.transform) || isNotNone(css.translate) || isNotNone(css.scale) || isNotNone(css.rotate) || isNotNone(css.perspective) || !isWebKit() && (isNotNone(css.backdropFilter) || isNotNone(css.filter)) || willChangeRe.test(css.willChange || '') || containRe.test(css.contain || '');\n}\nfunction getContainingBlock(element) {\n let currentNode = getParentNode(element);\n while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {\n if (isContainingBlock(currentNode)) {\n return currentNode;\n } else if (isTopLayer(currentNode)) {\n return null;\n }\n currentNode = getParentNode(currentNode);\n }\n return null;\n}\nfunction isWebKit() {\n if (isWebKitValue == null) {\n isWebKitValue = typeof CSS !== 'undefined' && CSS.supports && CSS.supports('-webkit-backdrop-filter', 'none');\n }\n return isWebKitValue;\n}\nfunction isLastTraversableNode(node) {\n return /^(html|body|#document)$/.test(getNodeName(node));\n}\nfunction getComputedStyle(element) {\n return getWindow(element).getComputedStyle(element);\n}\nfunction getNodeScroll(element) {\n if (isElement(element)) {\n return {\n scrollLeft: element.scrollLeft,\n scrollTop: element.scrollTop\n };\n }\n return {\n scrollLeft: element.scrollX,\n scrollTop: element.scrollY\n };\n}\nfunction getParentNode(node) {\n if (getNodeName(node) === 'html') {\n return node;\n }\n const result =\n // Step into the shadow DOM of the parent of a slotted node.\n node.assignedSlot ||\n // DOM Element detected.\n node.parentNode ||\n // ShadowRoot detected.\n isShadowRoot(node) && node.host ||\n // Fallback.\n getDocumentElement(node);\n return isShadowRoot(result) ? result.host : result;\n}\nfunction getNearestOverflowAncestor(node) {\n const parentNode = getParentNode(node);\n if (isLastTraversableNode(parentNode)) {\n return node.ownerDocument ? node.ownerDocument.body : node.body;\n }\n if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {\n return parentNode;\n }\n return getNearestOverflowAncestor(parentNode);\n}\nfunction getOverflowAncestors(node, list, traverseIframes) {\n var _node$ownerDocument2;\n if (list === void 0) {\n list = [];\n }\n if (traverseIframes === void 0) {\n traverseIframes = true;\n }\n const scrollableAncestor = getNearestOverflowAncestor(node);\n const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);\n const win = getWindow(scrollableAncestor);\n if (isBody) {\n const frameElement = getFrameElement(win);\n return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);\n } else {\n return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));\n }\n}\nfunction getFrameElement(win) {\n return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;\n}\n\nexport { getComputedStyle, getContainingBlock, getDocumentElement, getFrameElement, getNearestOverflowAncestor, getNodeName, getNodeScroll, getOverflowAncestors, getParentNode, getWindow, isContainingBlock, isElement, isHTMLElement, isLastTraversableNode, isNode, isOverflowElement, isShadowRoot, isTableElement, isTopLayer, isWebKit };\n","import { rectToClientRect, arrow as arrow$1, autoPlacement as autoPlacement$1, detectOverflow as detectOverflow$1, flip as flip$1, hide as hide$1, inline as inline$1, limitShift as limitShift$1, offset as offset$1, shift as shift$1, size as size$1, computePosition as computePosition$1 } from '@floating-ui/core';\nimport { round, createCoords, max, min, floor } from '@floating-ui/utils';\nimport { getComputedStyle as getComputedStyle$1, isHTMLElement, isElement, getWindow, isWebKit, getFrameElement, getNodeScroll, getDocumentElement, isTopLayer, getNodeName, isOverflowElement, getOverflowAncestors, getParentNode, isLastTraversableNode, isContainingBlock, isTableElement, getContainingBlock } from '@floating-ui/utils/dom';\nexport { getOverflowAncestors } from '@floating-ui/utils/dom';\n\nfunction getCssDimensions(element) {\n const css = getComputedStyle$1(element);\n // In testing environments, the `width` and `height` properties are empty\n // strings for SVG elements, returning NaN. Fallback to `0` in this case.\n let width = parseFloat(css.width) || 0;\n let height = parseFloat(css.height) || 0;\n const hasOffset = isHTMLElement(element);\n const offsetWidth = hasOffset ? element.offsetWidth : width;\n const offsetHeight = hasOffset ? element.offsetHeight : height;\n const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight;\n if (shouldFallback) {\n width = offsetWidth;\n height = offsetHeight;\n }\n return {\n width,\n height,\n $: shouldFallback\n };\n}\n\nfunction unwrapElement(element) {\n return !isElement(element) ? element.contextElement : element;\n}\n\nfunction getScale(element) {\n const domElement = unwrapElement(element);\n if (!isHTMLElement(domElement)) {\n return createCoords(1);\n }\n const rect = domElement.getBoundingClientRect();\n const {\n width,\n height,\n $\n } = getCssDimensions(domElement);\n let x = ($ ? round(rect.width) : rect.width) / width;\n let y = ($ ? round(rect.height) : rect.height) / height;\n\n // 0, NaN, or Infinity should always fallback to 1.\n\n if (!x || !Number.isFinite(x)) {\n x = 1;\n }\n if (!y || !Number.isFinite(y)) {\n y = 1;\n }\n return {\n x,\n y\n };\n}\n\nconst noOffsets = /*#__PURE__*/createCoords(0);\nfunction getVisualOffsets(element) {\n const win = getWindow(element);\n if (!isWebKit() || !win.visualViewport) {\n return noOffsets;\n }\n return {\n x: win.visualViewport.offsetLeft,\n y: win.visualViewport.offsetTop\n };\n}\nfunction shouldAddVisualOffsets(element, isFixed, floatingOffsetParent) {\n if (isFixed === void 0) {\n isFixed = false;\n }\n if (!floatingOffsetParent || isFixed && floatingOffsetParent !== getWindow(element)) {\n return false;\n }\n return isFixed;\n}\n\nfunction getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {\n if (includeScale === void 0) {\n includeScale = false;\n }\n if (isFixedStrategy === void 0) {\n isFixedStrategy = false;\n }\n const clientRect = element.getBoundingClientRect();\n const domElement = unwrapElement(element);\n let scale = createCoords(1);\n if (includeScale) {\n if (offsetParent) {\n if (isElement(offsetParent)) {\n scale = getScale(offsetParent);\n }\n } else {\n scale = getScale(element);\n }\n }\n const visualOffsets = shouldAddVisualOffsets(domElement, isFixedStrategy, offsetParent) ? getVisualOffsets(domElement) : createCoords(0);\n let x = (clientRect.left + visualOffsets.x) / scale.x;\n let y = (clientRect.top + visualOffsets.y) / scale.y;\n let width = clientRect.width / scale.x;\n let height = clientRect.height / scale.y;\n if (domElement) {\n const win = getWindow(domElement);\n const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;\n let currentWin = win;\n let currentIFrame = getFrameElement(currentWin);\n while (currentIFrame && offsetParent && offsetWin !== currentWin) {\n const iframeScale = getScale(currentIFrame);\n const iframeRect = currentIFrame.getBoundingClientRect();\n const css = getComputedStyle$1(currentIFrame);\n const left = iframeRect.left + (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;\n const top = iframeRect.top + (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;\n x *= iframeScale.x;\n y *= iframeScale.y;\n width *= iframeScale.x;\n height *= iframeScale.y;\n x += left;\n y += top;\n currentWin = getWindow(currentIFrame);\n currentIFrame = getFrameElement(currentWin);\n }\n }\n return rectToClientRect({\n width,\n height,\n x,\n y\n });\n}\n\n// If <html> has a CSS width greater than the viewport, then this will be\n// incorrect for RTL.\nfunction getWindowScrollBarX(element, rect) {\n const leftScroll = getNodeScroll(element).scrollLeft;\n if (!rect) {\n return getBoundingClientRect(getDocumentElement(element)).left + leftScroll;\n }\n return rect.left + leftScroll;\n}\n\nfunction getHTMLOffset(documentElement, scroll) {\n const htmlRect = documentElement.getBoundingClientRect();\n const x = htmlRect.left + scroll.scrollLeft - getWindowScrollBarX(documentElement, htmlRect);\n const y = htmlRect.top + scroll.scrollTop;\n return {\n x,\n y\n };\n}\n\nfunction convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {\n let {\n elements,\n rect,\n offsetParent,\n strategy\n } = _ref;\n const isFixed = strategy === 'fixed';\n const documentElement = getDocumentElement(offsetParent);\n const topLayer = elements ? isTopLayer(elements.floating) : false;\n if (offsetParent === documentElement || topLayer && isFixed) {\n return rect;\n }\n let scroll = {\n scrollLeft: 0,\n scrollTop: 0\n };\n let scale = createCoords(1);\n const offsets = createCoords(0);\n const isOffsetParentAnElement = isHTMLElement(offsetParent);\n if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {\n if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {\n scroll = getNodeScroll(offsetParent);\n }\n if (isOffsetParentAnElement) {\n const offsetRect = getBoundingClientRect(offsetParent);\n scale = getScale(offsetParent);\n offsets.x = offsetRect.x + offsetParent.clientLeft;\n offsets.y = offsetRect.y + offsetParent.clientTop;\n }\n }\n const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);\n return {\n width: rect.width * scale.x,\n height: rect.height * scale.y,\n x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x + htmlOffset.x,\n y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y + htmlOffset.y\n };\n}\n\nfunction getClientRects(element) {\n return Array.from(element.getClientRects());\n}\n\n// Gets the entire size of the scrollable document area, even extending outside\n// of the `<html>` and `<body>` rect bounds if horizontally scrollable.\nfunction getDocumentRect(element) {\n const html = getDocumentElement(element);\n const scroll = getNodeScroll(element);\n const body = element.ownerDocument.body;\n const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);\n const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);\n let x = -scroll.scrollLeft + getWindowScrollBarX(element);\n const y = -scroll.scrollTop;\n if (getComputedStyle$1(body).direction === 'rtl') {\n x += max(html.clientWidth, body.clientWidth) - width;\n }\n return {\n width,\n height,\n x,\n y\n };\n}\n\n// Safety check: ensure the scrollbar space is reasonable in case this\n// calculation is affected by unusual styles.\n// Most scrollbars leave 15-18px of space.\nconst SCROLLBAR_MAX = 25;\nfunction getViewportRect(element, strategy) {\n const win = getWindow(element);\n const html = getDocumentElement(element);\n const visualViewport = win.visualViewport;\n let width = html.clientWidth;\n let height = html.clientHeight;\n let x = 0;\n let y = 0;\n if (visualViewport) {\n width = visualViewport.width;\n height = visualViewport.height;\n const visualViewportBased = isWebKit();\n if (!visualViewportBased || visualViewportBased && strategy === 'fixed') {\n x = visualViewport.offsetLeft;\n y = visualViewport.offsetTop;\n }\n }\n const windowScrollbarX = getWindowScrollBarX(html);\n // <html> `overflow: hidden` + `scrollbar-gutter: stable` reduces the\n // visual width of the <html> but this is not considered in the size\n // of `html.clientWidth`.\n if (windowScrollbarX <= 0) {\n const doc = html.ownerDocument;\n const body = doc.body;\n const bodyStyles = getComputedStyle(body);\n const bodyMarginInline = doc.compatMode === 'CSS1Compat' ? parseFloat(bodyStyles.marginLeft) + parseFloat(bodyStyles.marginRight) || 0 : 0;\n const clippingStableScrollbarWidth = Math.abs(html.clientWidth - body.clientWidth - bodyMarginInline);\n if (clippingStableScrollbarWidth <= SCROLLBAR_MAX) {\n width -= clippingStableScrollbarWidth;\n }\n } else if (windowScrollbarX <= SCROLLBAR_MAX) {\n // If the <body> scrollbar is on the left, the width needs to be extended\n // by the scrollbar amount so there isn't extra space on the right.\n width += windowScrollbarX;\n }\n return {\n width,\n height,\n x,\n y\n };\n}\n\n// Returns the inner client rect, subtracting scrollbars if present.\nfunction getInnerBoundingClientRect(element, strategy) {\n const clientRect = getBoundingClientRect(element, true, strategy === 'fixed');\n const top = clientRect.top + element.clientTop;\n const left = clientRect.left + element.clientLeft;\n const scale = isHTMLElement(element) ? getScale(element) : createCoords(1);\n const width = element.clientWidth * scale.x;\n const height = element.clientHeight * scale.y;\n const x = left * scale.x;\n const y = top * scale.y;\n return {\n width,\n height,\n x,\n y\n };\n}\nfunction getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {\n let rect;\n if (clippingAncestor === 'viewport') {\n rect = getViewportRect(element, strategy);\n } else if (clippingAncestor === 'document') {\n rect = getDocumentRect(getDocumentElement(element));\n } else if (isElement(clippingAncestor)) {\n rect = getInnerBoundingClientRect(clippingAncestor, strategy);\n } else {\n const visualOffsets = getVisualOffsets(element);\n rect = {\n x: clippingAncestor.x - visualOffsets.x,\n y: clippingAncestor.y - visualOffsets.y,\n width: clippingAncestor.width,\n height: clippingAncestor.height\n };\n }\n return rectToClientRect(rect);\n}\nfunction hasFixedPositionAncestor(element, stopNode) {\n const parentNode = getParentNode(element);\n if (parentNode === stopNode || !isElement(parentNode) || isLastTraversableNode(parentNode)) {\n return false;\n }\n return getComputedStyle$1(parentNode).position === 'fixed' || hasFixedPositionAncestor(parentNode, stopNode);\n}\n\n// A \"clipping ancestor\" is an `overflow` element with the characteristic of\n// clipping (or hiding) child elements. This returns all clipping ancestors\n// of the given element up the tree.\nfunction getClippingElementAncestors(element, cache) {\n const cachedResult = cache.get(element);\n if (cachedResult) {\n return cachedResult;\n }\n let result = getOverflowAncestors(element, [], false).filter(el => isElement(el) && getNodeName(el) !== 'body');\n let currentContainingBlockComputedStyle = null;\n const elementIsFixed = getComputedStyle$1(element).position === 'fixed';\n let currentNode = elementIsFixed ? getParentNode(element) : element;\n\n // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block\n while (isElement(currentNode) && !isLastTraversableNode(currentNode)) {\n const computedStyle = getComputedStyle$1(currentNode);\n const currentNodeIsContaining = isContainingBlock(currentNode);\n if (!currentNodeIsContaining && computedStyle.position === 'fixed') {\n currentContainingBlockComputedStyle = null;\n }\n const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === 'static' && !!currentContainingBlockComputedStyle && (currentContainingBlockComputedStyle.position === 'absolute' || currentContainingBlockComputedStyle.position === 'fixed') || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode);\n if (shouldDropCurrentNode) {\n // Drop non-containing blocks.\n result = result.filter(ancestor => ancestor !== currentNode);\n } else {\n // Record last containing block for next iteration.\n currentContainingBlockComputedStyle = computedStyle;\n }\n currentNode = getParentNode(currentNode);\n }\n cache.set(element, result);\n return result;\n}\n\n// Gets the maximum area that the element is visible in due to any number of\n// clipping ancestors.\nfunction getClippingRect(_ref) {\n let {\n element,\n boundary,\n rootBoundary,\n strategy\n } = _ref;\n const elementClippingAncestors = boundary === 'clippingAncestors' ? isTopLayer(element) ? [] : getClippingElementAncestors(element, this._c) : [].concat(boundary);\n const clippingAncestors = [...elementClippingAncestors, rootBoundary];\n const firstRect = getClientRectFromClippingAncestor(element, clippingAncestors[0], strategy);\n let top = firstRect.top;\n let right = firstRect.right;\n let bottom = firstRect.bottom;\n let left = firstRect.left;\n for (let i = 1; i < clippingAncestors.length; i++) {\n const rect = getClientRectFromClippingAncestor(element, clippingAncestors[i], strategy);\n top = max(rect.top, top);\n right = min(rect.right, right);\n bottom = min(rect.bottom, bottom);\n left = max(rect.left, left);\n }\n return {\n width: right - left,\n height: bottom - top,\n x: left,\n y: top\n };\n}\n\nfunction getDimensions(element) {\n const {\n width,\n height\n } = getCssDimensions(element);\n return {\n width,\n height\n };\n}\n\nfunction getRectRelativeToOffsetParent(element, offsetParent, strategy) {\n const isOffsetParentAnElement = isHTMLElement(offsetParent);\n const documentElement = getDocumentElement(offsetParent);\n const isFixed = strategy === 'fixed';\n const rect = getBoundingClientRect(element, true, isFixed, offsetParent);\n let scroll = {\n scrollLeft: 0,\n scrollTop: 0\n };\n const offsets = createCoords(0);\n\n // If the <body> scrollbar appears on the left (e.g. RTL systems). Use\n // Firefox with layout.scrollbar.side = 3 in about:config to test this.\n function setLeftRTLScrollbarOffset() {\n offsets.x = getWindowScrollBarX(documentElement);\n }\n if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {\n if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {\n scroll = getNodeScroll(offsetParent);\n }\n if (isOffsetParentAnElement) {\n const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent);\n offsets.x = offsetRect.x + offsetParent.clientLeft;\n offsets.y = offsetRect.y + offsetParent.clientTop;\n } else if (documentElement) {\n setLeftRTLScrollbarOffset();\n }\n }\n if (isFixed && !isOffsetParentAnElement && documentElement) {\n setLeftRTLScrollbarOffset();\n }\n const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);\n const x = rect.left + scroll.scrollLeft - offsets.x - htmlOffset.x;\n const y = rect.top + scroll.scrollTop - offsets.y - htmlOffset.y;\n return {\n x,\n y,\n width: rect.width,\n height: rect.height\n };\n}\n\nfunction isStaticPositioned(element) {\n return getComputedStyle$1(element).position === 'static';\n}\n\nfunction getTrueOffsetParent(element, polyfill) {\n if (!isHTMLElement(element) || getComputedStyle$1(element).position === 'fixed') {\n return null;\n }\n if (polyfill) {\n return polyfill(element);\n }\n let rawOffsetParent = element.offsetParent;\n\n // Firefox returns the <html> element as the offsetParent if it's non-static,\n // while Chrome and Safari return the <body> element. The <body> element must\n // be used to perform the correct calculations even if the <html> element is\n // non-static.\n if (getDocumentElement(element) === rawOffsetParent) {\n rawOffsetParent = rawOffsetParent.ownerDocument.body;\n }\n return rawOffsetParent;\n}\n\n// Gets the closest ancestor positioned element. Handles some edge cases,\n// such as table ancestors and cross browser bugs.\nfunction getOffsetParent(element, polyfill) {\n const win = getWindow(element);\n if (isTopLayer(element)) {\n return win;\n }\n if (!isHTMLElement(element)) {\n let svgOffsetParent = getParentNode(element);\n while (svgOffsetParent && !isLastTraversableNode(svgOffsetParent)) {\n if (isElement(svgOffsetParent) && !isStaticPositioned(svgOffsetParent)) {\n return svgOffsetParent;\n }\n svgOffsetParent = getParentNode(svgOffsetParent);\n }\n return win;\n }\n let offsetParent = getTrueOffsetParent(element, polyfill);\n while (offsetParent && isTableElement(offsetParent) && isStaticPositioned(offsetParent)) {\n offsetParent = getTrueOffsetParent(offsetParent, polyfill);\n }\n if (offsetParent && isLastTraversableNode(offsetParent) && isStaticPositioned(offsetParent) && !isContainingBlock(offsetParent)) {\n return win;\n }\n return offsetParent || getContainingBlock(element) || win;\n}\n\nconst getElementRects = async function (data) {\n const getOffsetParentFn = this.getOffsetParent || getOffsetParent;\n const getDimensionsFn = this.getDimensions;\n const floatingDimensions = await getDimensionsFn(data.floating);\n return {\n reference: getRectRelativeToOffsetParent(data.reference, await getOffsetParentFn(data.floating), data.strategy),\n floating: {\n x: 0,\n y: 0,\n width: floatingDimensions.width,\n height: floatingDimensions.height\n }\n };\n};\n\nfunction isRTL(element) {\n return getComputedStyle$1(element).direction === 'rtl';\n}\n\nconst platform = {\n convertOffsetParentRelativeRectToViewportRelativeRect,\n getDocumentElement,\n getClippingRect,\n getOffsetParent,\n getElementRects,\n getClientRects,\n getDimensions,\n getScale,\n isElement,\n isRTL\n};\n\nfunction rectsAreEqual(a, b) {\n return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;\n}\n\n// https://samthor.au/2021/observing-dom/\nfunction observeMove(element, onMove) {\n let io = null;\n let timeoutId;\n const root = getDocumentElement(element);\n function cleanup() {\n var _io;\n clearTimeout(timeoutId);\n (_io = io) == null || _io.disconnect();\n io = null;\n }\n function refresh(skip, threshold) {\n if (skip === void 0) {\n skip = false;\n }\n if (threshold === void 0) {\n threshold = 1;\n }\n cleanup();\n const elementRectForRootMargin = element.getBoundingClientRect();\n const {\n left,\n top,\n width,\n height\n } = elementRectForRootMargin;\n if (!skip) {\n onMove();\n }\n if (!width || !height) {\n return;\n }\n const insetTop = floor(top);\n const insetRight = floor(root.clientWidth - (left + width));\n const insetBottom = floor(root.clientHeight - (top + height));\n const insetLeft = floor(left);\n const rootMargin = -insetTop + \"px \" + -insetRight + \"px \" + -insetBottom + \"px \" + -insetLeft + \"px\";\n const options = {\n rootMargin,\n threshold: max(0, min(1, threshold)) || 1\n };\n let isFirstUpdate = true;\n function handleObserve(entries) {\n const ratio = entries[0].intersectionRatio;\n if (ratio !== threshold) {\n if (!isFirstUpdate) {\n return refresh();\n }\n if (!ratio) {\n // If the reference is clipped, the ratio is 0. Throttle the refresh\n // to prevent an infinite loop of updates.\n timeoutId = setTimeout(() => {\n refresh(false, 1e-7);\n }, 1000);\n } else {\n refresh(false, ratio);\n }\n }\n if (ratio === 1 && !rectsAreEqual(elementRectForRootMargin, element.getBoundingClientRect())) {\n // It's possible that even though the ratio is reported as 1, the\n // element is not actually fully within the IntersectionObserver's root\n // area anymore. This can happen under performance constraints. This may\n // be a bug in the browser's IntersectionObserver implementation. To\n // work around this, we compare the element's bounding rect now with\n // what it was at the time we created the IntersectionObserver. If they\n // are not equal then the element moved, so we refresh.\n refresh();\n }\n isFirstUpdate = false;\n }\n\n // Older browsers don't support a `document` as the root and will throw an\n // error.\n try {\n io = new IntersectionObserver(handleObserve, {\n ...options,\n // Handle <iframe>s\n root: root.ownerDocument\n });\n } catch (_e) {\n io = new IntersectionObserver(handleObserve, options);\n }\n io.observe(element);\n }\n refresh(true);\n return cleanup;\n}\n\n/**\n * Automatically updates the position of the floating element when necessary.\n * Should only be called when the floating element is mounted on the DOM or\n * visible on the screen.\n * @returns cleanup function that should be invoked when the floating element is\n * removed from the DOM or hidden from the screen.\n * @see https://floating-ui.com/docs/autoUpdate\n */\nfunction autoUpdate(reference, floating, update, options) {\n if (options === void 0) {\n options = {};\n }\n const {\n ancestorScroll = true,\n ancestorResize = true,\n elementResize = typeof ResizeObserver === 'function',\n layoutShift = typeof IntersectionObserver === 'function',\n animationFrame = false\n } = options;\n const referenceEl = unwrapElement(reference);\n const ancestors = ancestorScroll || ancestorResize ? [...(referenceEl ? getOverflowAncestors(referenceEl) : []), ...(floating ? getOverflowAncestors(floating) : [])] : [];\n ancestors.forEach(ancestor => {\n ancestorScroll && ancestor.addEventListener('scroll', update, {\n passive: true\n });\n ancestorResize && ancestor.addEventListener('resize', update);\n });\n const cleanupIo = referenceEl && layoutShift ? observeMove(referenceEl, update) : null;\n let reobserveFrame = -1;\n let resizeObserver = null;\n if (elementResize) {\n resizeObserver = new ResizeObserver(_ref => {\n let [firstEntry] = _ref;\n if (firstEntry && firstEntry.target === referenceEl && resizeObserver && floating) {\n // Prevent update loops when using the `size` middleware.\n // https://github.com/floating-ui/floating-ui/issues/1740\n resizeObserver.unobserve(floating);\n cancelAnimationFrame(reobserveFrame);\n reobserveFrame = requestAnimationFrame(() => {\n var _resizeObserver;\n (_resizeObserver = resizeObserver) == null || _resizeObserver.observe(floating);\n });\n }\n update();\n });\n if (referenceEl && !animationFrame) {\n resizeObserver.observe(referenceEl);\n }\n if (floating) {\n resizeObserver.observe(floating);\n }\n }\n let frameId;\n let prevRefRect = animationFrame ? getBoundingClientRect(reference) : null;\n if (animationFrame) {\n frameLoop();\n }\n function frameLoop() {\n const nextRefRect = getBoundingClientRect(reference);\n if (prevRefRect && !rectsAreEqual(prevRefRect, nextRefRect)) {\n update();\n }\n prevRefRect = nextRefRect;\n frameId = requestAnimationFrame(frameLoop);\n }\n update();\n return () => {\n var _resizeObserver2;\n ancestors.forEach(ancestor => {\n ancestorScroll && ancestor.removeEventListener('scroll', update);\n ancestorResize && ancestor.removeEventListener('resize', update);\n });\n cleanupIo == null || cleanupIo();\n (_resizeObserver2 = resizeObserver) == null || _resizeObserver2.disconnect();\n resizeObserver = null;\n if (animationFrame) {\n cancelAnimationFrame(frameId);\n }\n };\n}\n\n/**\n * Resolves with an object of overflow side offsets that determine how much the\n * element is overflowing a given clipping boundary on each side.\n * - positive = overflowing the boundary by that number of pixels\n * - negative = how many pixels left before it will overflow\n * - 0 = lies flush with the boundary\n * @see https://floating-ui.com/docs/detectOverflow\n */\nconst detectOverflow = detectOverflow$1;\n\n/**\n * Modifies the placement by translating the floating element along the\n * specified axes.\n * A number (shorthand for `mainAxis` or distance), or an axes configuration\n * object may be passed.\n * @see https://floating-ui.com/docs/offset\n */\nconst offset = offset$1;\n\n/**\n * Optimizes the visibility of the floating element by choosing the placement\n * that has the most space available automatically, without needing to specify a\n * preferred placement. Alternative to `flip`.\n * @see https://floating-ui.com/docs/autoPlacement\n */\nconst autoPlacement = autoPlacement$1;\n\n/**\n * Optimizes the visibility of the floating element by shifting it in order to\n * keep it in view when it will overflow the clipping boundary.\n * @see https://floating-ui.com/docs/shift\n */\nconst shift = shift$1;\n\n/**\n * Optimizes the visibility of the floating element by flipping the `placement`\n * in order to keep it in view when the preferred placement(s) will overflow the\n * clipping boundary. Alternative to `autoPlacement`.\n * @see https://floating-ui.com/docs/flip\n */\nconst flip = flip$1;\n\n/**\n * Provides data that allows you to change the size of the floating element —\n * for instance, prevent it from overflowing the clipping boundary or match the\n * width of the reference element.\n * @see https://floating-ui.com/docs/size\n */\nconst size = size$1;\n\n/**\n * Provides data to hide the floating element in applicable situations, such as\n * when it is not in the same clipping context as the reference element.\n * @see https://floating-ui.com/docs/hide\n */\nconst hide = hide$1;\n\n/**\n * Provides data to position an inner element of the floating element so that it\n * appears centered to the reference element.\n * @see https://floating-ui.com/docs/arrow\n */\nconst arrow = arrow$1;\n\n/**\n * Provides improved positioning for inline reference elements that can span\n * over multiple lines, such as hyperlinks or range selections.\n * @see https://floating-ui.com/docs/inline\n */\nconst inline = inline$1;\n\n/**\n * Built-in `limiter` that will stop `shift()` at a certain point.\n */\nconst limitShift = limitShift$1;\n\n/**\n * Computes the `x` and `y` coordinates that will place the floating element\n * next to a given reference element.\n */\nconst computePosition = (reference, floating, options) => {\n // This caches the expensive `getClippingElementAncestors` function so that\n // multiple lifecycle resets re-use the same result. It only lives for a\n // single call. If other functions become expensive, we can add them as well.\n const cache = new Map();\n const mergedOptions = {\n platform,\n ...options\n };\n const platformWithCache = {\n ...mergedOptions.platform,\n _c: cache\n };\n return computePosition$1(reference, floating, {\n ...mergedOptions,\n platform: platformWithCache\n });\n};\n\nexport { arrow, autoPlacement, autoUpdate, computePosition, detectOverflow, flip, hide, inline, limitShift, offset, platform, shift, size };\n","import * as Vue from 'vue'\n\nvar isVue2 = false\nvar isVue3 = true\nvar Vue2 = undefined\n\nfunction install() {}\n\nexport function set(target, key, val) {\n if (Array.isArray(target)) {\n target.length = Math.max(target.length, key)\n target.splice(key, 1, val)\n return val\n }\n target[key] = val\n return val\n}\n\nexport function del(target, key) {\n if (Array.isArray(target)) {\n target.splice(key, 1)\n return\n }\n delete target[key]\n}\n\nexport * from 'vue'\nexport {\n Vue,\n Vue2,\n isVue2,\n isVue3,\n install,\n}\n","import { arrow as arrow$1, computePosition } from '@floating-ui/dom';\nexport { autoPlacement, autoUpdate, computePosition, detectOverflow, flip, getOverflowAncestors, hide, inline, limitShift, offset, platform, shift, size } from '@floating-ui/dom';\nimport { isNode, getNodeName } from '@floating-ui/utils/dom';\nimport { unref, computed, ref, shallowRef, watch, getCurrentScope, onScopeDispose, shallowReadonly } from 'vue-demi';\n\nfunction isComponentPublicInstance(target) {\n return target != null && typeof target === 'object' && '$el' in target;\n}\nfunction unwrapElement(target) {\n if (isComponentPublicInstance(target)) {\n const element = target.$el;\n return isNode(element) && getNodeName(element) === '#comment' ? null : element;\n }\n return target;\n}\n\nfunction toValue(source) {\n return typeof source === 'function' ? source() : unref(source);\n}\n\n/**\n * Positions an inner element of the floating element such that it is centered to the reference element.\n * @param options The arrow options.\n * @see https://floating-ui.com/docs/arrow\n */\nfunction arrow(options) {\n return {\n name: 'arrow',\n options,\n fn(args) {\n const element = unwrapElement(toValue(options.element));\n if (element == null) {\n return {};\n }\n return arrow$1({\n element,\n padding: options.padding\n }).fn(args);\n }\n };\n}\n\nfunction getDPR(element) {\n if (typeof window === 'undefined') {\n return 1;\n }\n const win = element.ownerDocument.defaultView || window;\n return win.devicePixelRatio || 1;\n}\n\nfunction roundByDPR(element, value) {\n const dpr = getDPR(element);\n return Math.round(value * dpr) / dpr;\n}\n\n/**\n * Computes the `x` and `y` coordinates that will place the floating element next to a reference element when it is given a certain CSS positioning strategy.\n * @param reference The reference template ref.\n * @param floating The floating template ref.\n * @param options The floating options.\n * @see https://floating-ui.com/docs/vue\n */\nfunction useFloating(reference, floating, options) {\n if (options === void 0) {\n options = {};\n }\n const whileElementsMountedOption = options.whileElementsMounted;\n const openOption = computed(() => {\n var _toValue;\n return (_toValue = toValue(options.open)) != null ? _toValue : true;\n });\n const middlewareOption = computed(() => toValue(options.middleware));\n const placementOption = computed(() => {\n var _toValue2;\n return (_toValue2 = toValue(options.placement)) != null ? _toValue2 : 'bottom';\n });\n const strategyOption = computed(() => {\n var _toValue3;\n return (_toValue3 = toValue(options.strategy)) != null ? _toValue3 : 'absolute';\n });\n const transformOption = computed(() => {\n var _toValue4;\n return (_toValue4 = toValue(options.transform)) != null ? _toValue4 : true;\n });\n const referenceElement = computed(() => unwrapElement(reference.value));\n const floatingElement = computed(() => unwrapElement(floating.value));\n const x = ref(0);\n const y = ref(0);\n const strategy = ref(strategyOption.value);\n const placement = ref(placementOption.value);\n const middlewareData = shallowRef({});\n const isPositioned = ref(false);\n const floatingStyles = computed(() => {\n const initialStyles = {\n position: strategy.value,\n left: '0',\n top: '0'\n };\n if (!floatingElement.value) {\n return initialStyles;\n }\n const xVal = roundByDPR(floatingElement.value, x.value);\n const yVal = roundByDPR(floatingElement.value, y.value);\n if (transformOption.value) {\n return {\n ...initialStyles,\n transform: \"translate(\" + xVal + \"px, \" + yVal + \"px)\",\n ...(getDPR(floatingElement.value) >= 1.5 && {\n willChange: 'transform'\n })\n };\n }\n return {\n position: strategy.value,\n left: xVal + \"px\",\n top: yVal + \"px\"\n };\n });\n let whileElementsMountedCleanup;\n function update() {\n if (referenceElement.value == null || floatingElement.value == null) {\n return;\n }\n const open = openOption.value;\n computePosition(referenceElement.value, floatingElement.value, {\n middleware: middlewareOption.value,\n placement: placementOption.value,\n strategy: strategyOption.value\n }).then(position => {\n x.value = position.x;\n y.value = position.y;\n strategy.value = position.strategy;\n placement.value = position.placement;\n middlewareData.value = position.middlewareData;\n /**\n * The floating element's position may be recomputed while it's closed\n * but still mounted (such as when transitioning out). To ensure\n * `isPositioned` will be `false` initially on the next open, avoid\n * setting it to `true` when `open === false` (must be specified).\n */\n isPositioned.value = open !== false;\n });\n }\n function cleanup() {\n if (typeof whileElementsMountedCleanup === 'function') {\n whileElementsMountedCleanup();\n whileElementsMountedCleanup = undefined;\n }\n }\n function attach() {\n cleanup();\n if (whileElementsMountedOption === undefined) {\n update();\n return;\n }\n if (referenceElement.value != null && floatingElement.value != null) {\n whileElementsMountedCleanup = whileElementsMountedOption(referenceElement.value, floatingElement.value, update);\n return;\n }\n }\n function reset() {\n if (!openOption.value) {\n isPositioned.value = false;\n }\n }\n watch([middlewareOption, placementOption, strategyOption, openOption], update, {\n flush: 'sync'\n });\n watch([referenceElement, floatingElement], attach, {\n flush: 'sync'\n });\n watch(openOption, reset, {\n flush: 'sync'\n });\n if (getCurrentScope()) {\n onScopeDispose(cleanup);\n }\n return {\n x: shallowReadonly(x),\n y: shallowReadonly(y),\n strategy: shallowReadonly(strategy),\n placement: shallowReadonly(placement),\n middlewareData: shallowReadonly(middlewareData),\n isPositioned: shallowReadonly(isPositioned),\n floatingStyles,\n update\n };\n}\n\nexport { arrow, useFloating };\n","<script setup lang=\"ts\">\nimport { ref, onMounted, onUnmounted, computed, watch } from \"vue\";\nimport { flip, useFloating, AlignedPlacement, Placement, offset } from \"@floating-ui/vue\";\nimport { useDebounceFn, useElementHover, useElementBounding } from \"@vueuse/core\";\nimport { PvPopoverV2Props } from \"@/components/base/PvPopoverV2/types.ts\";\nimport { vOnClickOutside } from \"@vueuse/components\";\nimport { PvAlignmentPositions } from \"@/components/base/baseProps.ts\";\n\nconst props = withDefaults(defineProps<PvPopoverV2Props>(), {\n disableAutoPlacement: false,\n position: \"bottom-left\",\n positioningStrategy: \"absolute\",\n disableInteractive: false,\n useTeleport: false,\n disableClickOutsideToClose: false,\n showOnHover: false,\n delay: 25,\n zIndex: 10,\n teleportLocation: \"body\",\n});\n\nconst isOpen = defineModel<boolean>();\n\nconst triggerWrapper = ref<HTMLElement | null>(null);\nconst reference = ref<HTMLElement | null>(null);\nconst floating = ref<HTMLElement | null>(null);\n\nconst triggerHovered = useElementHover(triggerWrapper);\nconst floatingHovered = useElementHover(floating);\n\n/**\n * We use our own placement mapping name to ensure that have the same naming across the PitViper components.\n */\nconst placementMapping: Record<PvAlignmentPositions, AlignedPlacement | Placement> = {\n \"top-center\": \"top\",\n \"bottom-center\": \"bottom\",\n \"center-left\": \"left\",\n \"center-right\": \"right\",\n \"top-left\": \"top-start\",\n \"top-right\": \"top-end\",\n \"bottom-left\": \"bottom-start\",\n \"bottom-right\": \"bottom-end\",\n};\n\nonMounted(() => {\n if (triggerWrapper.value) {\n // Set reference to the first child element (the actual trigger)\n reference.value = triggerWrapper.value.firstElementChild as HTMLElement | null;\n }\n});\n\nconst middleware = [];\n\nif (!props.disableAutoPlacement) {\n middleware?.push(\n flip({\n fallbackStrategy: \"initialPlacement\",\n }),\n );\n}\n\nif (props.offset) {\n middleware?.push(offset(props.offset));\n}\n\nconst { floatingStyles, update } = useFloating(reference, floating, {\n placement: placementMapping[props.position],\n strategy: props.positioningStrategy,\n middleware: middleware,\n});\n\n// Update popover position when it opens\nwatch(isOpen, (newVal) => {\n if (newVal && reference.value && floating.value) {\n update();\n }\n});\n\n// Track trigger position and size changes\nconst elementBounds = useElementBounding(reference);\n\nconst handleBoundsChange = useDebounceFn(() => {\n if (isOpen.value) {\n update();\n }\n}, 5);\n\nwatch([elementBounds.top, elementBounds.left, elementBounds.width, elementBounds.height], handleBoundsChange);\n\nconst popoverStyles = computed(() => {\n return {\n ...floatingStyles.value,\n zIndex: props.zIndex ?? 10,\n };\n});\n\nlet openDelayTimeout: ReturnType<typeof setTimeout> | undefined;\n\nconst clearOpenDelayTimeout = () => {\n if (openDelayTimeout) {\n clearTimeout(openDelayTimeout);\n openDelayTimeout = undefined;\n }\n};\n\nconst setPopoverState = (state: boolean) => {\n clearOpenDelayTimeout();\n\n if (state && props.delay > 0) {\n openDelayTimeout = setTimeout(() => {\n isOpen.value = true;\n openDelayTimeout = undefined;\n }, props.delay);\n return;\n }\n\n // Closing should always be immediate, even when opening is delayed.\n isOpen.value = state;\n};\n\nconst ignoreForClickOutside = computed(() => {\n const list: (string | HTMLElement | null)[] = [floating.value].filter(Boolean);\n list.push(\".p-datepicker-panel\");\n\n if (props.ignoreClickOutsideClasses) {\n list.push(...props.ignoreClickOutsideClasses.map((cls) => `.${cls}`));\n }\n\n return list;\n});\n\nconst isHovered = computed(() => {\n if (!props.showOnHover) return false;\n return props.disableInteractive ? triggerHovered.value : triggerHovered.value || floatingHovered.value;\n});\n\nconst handleTriggerClick = () => {\n if (!props.showOnHover) {\n setPopoverState(openDelayTimeout ? false : !isOpen.value);\n }\n};\n\nconst handleClickOutside = () => {\n if (!props.disableClickOutsideToClose) {\n setPopoverState(false);\n }\n};\n\n// Watch hover state and update popover accordingly\nwatch(isHovered, (newVal) => {\n if (props.showOnHover) {\n setPopoverState(newVal);\n }\n});\n\nonUnmounted(() => {\n clearOpenDelayTimeout();\n});\n</script>\n\n<template>\n <div v-on-click-outside=\"[handleClickOutside, { ignore: ignoreForClickOutside }]\" style=\"width: fit-content\">\n <div ref=\"triggerWrapper\" @click=\"handleTriggerClick\">\n <slot name=\"trigger\"> </slot>\n </div>\n <Teleport v-if=\"$slots.content\" :to=\"teleportLocation\" :disabled=\"!props.useTeleport\">\n <div class=\"pv-floating\" ref=\"floating\" v-show=\"isOpen\" :style=\"popoverStyles\">\n <slot name=\"content\"></slot>\n </div>\n </Teleport>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { ref, onMounted, onUnmounted, computed, watch } from \"vue\";\nimport { flip, useFloating, AlignedPlacement, Placement, offset } from \"@floating-ui/vue\";\nimport { useDebounceFn, useElementHover, useElementBounding } from \"@vueuse/core\";\nimport { PvPopoverV2Props } from \"@/components/base/PvPopoverV2/types.ts\";\nimport { vOnClickOutside } from \"@vueuse/components\";\nimport { PvAlignmentPositions } from \"@/components/base/baseProps.ts\";\n\nconst props = withDefaults(defineProps<PvPopoverV2Props>(), {\n disableAutoPlacement: false,\n position: \"bottom-left\",\n positioningStrategy: \"absolute\",\n disableInteractive: false,\n useTeleport: false,\n disableClickOutsideToClose: false,\n showOnHover: false,\n delay: 25,\n zIndex: 10,\n teleportLocation: \"body\",\n});\n\nconst isOpen = defineModel<boolean>();\n\nconst triggerWrapper = ref<HTMLElement | null>(null);\nconst reference = ref<HTMLElement | null>(null);\nconst floating = ref<HTMLElement | null>(null);\n\nconst triggerHovered = useElementHover(triggerWrapper);\nconst floatingHovered = useElementHover(floating);\n\n/**\n * We use our own placement mapping name to ensure that have the same naming across the PitViper components.\n */\nconst placementMapping: Record<PvAlignmentPositions, AlignedPlacement | Placement> = {\n \"top-center\": \"top\",\n \"bottom-center\": \"bottom\",\n \"center-left\": \"left\",\n \"center-right\": \"right\",\n \"top-left\": \"top-start\",\n \"top-right\": \"top-end\",\n \"bottom-left\": \"bottom-start\",\n \"bottom-right\": \"bottom-end\",\n};\n\nonMounted(() => {\n if (triggerWrapper.value) {\n // Set reference to the first child element (the actual trigger)\n reference.value = triggerWrapper.value.firstElementChild as HTMLElement | null;\n }\n});\n\nconst middleware = [];\n\nif (!props.disableAutoPlacement) {\n middleware?.push(\n flip({\n fallbackStrategy: \"initialPlacement\",\n }),\n );\n}\n\nif (props.offset) {\n middleware?.push(offset(props.offset));\n}\n\nconst { floatingStyles, update } = useFloating(reference, floating, {\n placement: placementMapping[props.position],\n strategy: props.positioningStrategy,\n middleware: middleware,\n});\n\n// Update popover position when it opens\nwatch(isOpen, (newVal) => {\n if (newVal && reference.value && floating.value) {\n update();\n }\n});\n\n// Track trigger position and size changes\nconst elementBounds = useElementBounding(reference);\n\nconst handleBoundsChange = useDebounceFn(() => {\n if (isOpen.value) {\n update();\n }\n}, 5);\n\nwatch([elementBounds.top, elementBounds.left, elementBounds.width, elementBounds.height], handleBoundsChange);\n\nconst popoverStyles = computed(() => {\n return {\n ...floatingStyles.value,\n zIndex: props.zIndex ?? 10,\n };\n});\n\nlet openDelayTimeout: ReturnType<typeof setTimeout> | undefined;\n\nconst clearOpenDelayTimeout = () => {\n if (openDelayTimeout) {\n clearTimeout(openDelayTimeout);\n openDelayTimeout = undefined;\n }\n};\n\nconst setPopoverState = (state: boolean) => {\n clearOpenDelayTimeout();\n\n if (state && props.delay > 0) {\n openDelayTimeout = setTimeout(() => {\n isOpen.value = true;\n openDelayTimeout = undefined;\n }, props.delay);\n return;\n }\n\n // Closing should always be immediate, even when opening is delayed.\n isOpen.value = state;\n};\n\nconst ignoreForClickOutside = computed(() => {\n const list: (string | HTMLElement | null)[] = [floating.value].filter(Boolean);\n list.push(\".p-datepicker-panel\");\n\n if (props.ignoreClickOutsideClasses) {\n list.push(...props.ignoreClickOutsideClasses.map((cls) => `.${cls}`));\n }\n\n return list;\n});\n\nconst isHovered = computed(() => {\n if (!props.showOnHover) return false;\n return props.disableInteractive ? triggerHovered.value : triggerHovered.value || floatingHovered.value;\n});\n\nconst handleTriggerClick = () => {\n if (!props.showOnHover) {\n setPopoverState(openDelayTimeout ? false : !isOpen.value);\n }\n};\n\nconst handleClickOutside = () => {\n if (!props.disableClickOutsideToClose) {\n setPopoverState(false);\n }\n};\n\n// Watch hover state and update popover accordingly\nwatch(isHovered, (newVal) => {\n if (props.showOnHover) {\n setPopoverState(newVal);\n }\n});\n\nonUnmounted(() => {\n clearOpenDelayTimeout();\n});\n</script>\n\n<template>\n <div v-on-click-outside=\"[handleClickOutside, { ignore: ignoreForClickOutside }]\" style=\"width: fit-content\">\n <div ref=\"triggerWrapper\" @click=\"handleTriggerClick\">\n <slot name=\"trigger\"> </slot>\n </div>\n <Teleport v-if=\"$slots.content\" :to=\"teleportLocation\" :disabled=\"!props.useTeleport\">\n <div class=\"pv-floating\" ref=\"floating\" v-show=\"isOpen\" :style=\"popoverStyles\">\n <slot name=\"content\"></slot>\n </div>\n </Teleport>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { PvTooltipV2Props } from \"./types\";\nimport PvPopoverV2 from \"@/components/base/PvPopoverV2/PvPopoverV2.vue\";\n\nwithDefaults(defineProps<PvTooltipV2Props>(), {\n variant: \"dark\",\n position: \"top-center\",\n size: \"md\",\n disableInteractive: false,\n delay: 0,\n showOnHover: true,\n});\n</script>\n\n<template>\n <PvPopoverV2 v-bind=\"$props\">\n <template #trigger>\n <slot name=\"trigger\">\n <p>{{ label }}</p>\n </slot>\n </template>\n <template #content v-if=\"$slots.content || description\">\n <div\n class=\"pv-tooltip-v2-content\"\n role=\"tooltip\"\n :data-variant=\"variant\"\n :class=\"{ 'pv-tooltip-v2-content-small': size === 'sm' }\"\n >\n <slot name=\"content\">\n {{ description }}\n </slot>\n </div>\n </template>\n </PvPopoverV2>\n</template>\n","<script setup lang=\"ts\">\nimport { PvTooltipV2Props } from \"./types\";\nimport PvPopoverV2 from \"@/components/base/PvPopoverV2/PvPopoverV2.vue\";\n\nwithDefaults(defineProps<PvTooltipV2Props>(), {\n variant: \"dark\",\n position: \"top-center\",\n size: \"md\",\n disableInteractive: false,\n delay: 0,\n showOnHover: true,\n});\n</script>\n\n<template>\n <PvPopoverV2 v-bind=\"$props\">\n <template #trigger>\n <slot name=\"trigger\">\n <p>{{ label }}</p>\n </slot>\n </template>\n <template #content v-if=\"$slots.content || description\">\n <div\n class=\"pv-tooltip-v2-content\"\n role=\"tooltip\"\n :data-variant=\"variant\"\n :class=\"{ 'pv-tooltip-v2-content-small': size === 'sm' }\"\n >\n <slot name=\"content\">\n {{ description }}\n </slot>\n </div>\n </template>\n </PvPopoverV2>\n</template>\n","<script setup lang=\"ts\">\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport PvTooltipV2 from \"@/components/base/PvTooltipV2/PvTooltipV2.vue\";\nimport { PvSegmentControlSize, PvSegmentedControlOption } from \"./types\";\n\ninterface PvSegmentControlProps {\n /** The list of options rendered as segments. Each option can have a label, icon, or both. */\n options: PvSegmentedControlOption[];\n /**\n * Controls the overall height of the segmented control.\n */\n size?: PvSegmentControlSize;\n}\n\nwithDefaults(defineProps<PvSegmentControlProps>(), {\n size: \"lg\",\n options: () => [],\n});\n\nconst modelValue = defineModel<string>({ required: true });\n\nconst selectOption = (option: PvSegmentedControlOption) => {\n if (option.disabled) return;\n modelValue.value = option.value;\n};\n</script>\n\n<template>\n <div\n :class=\"[\n 'pv-segmented-control',\n {\n 'pv-segmented-control-large': size === 'xl',\n },\n ]\"\n >\n <PvTooltipV2\n v-for=\"option in options\"\n :key=\"option.value\"\n variant=\"dark\"\n position=\"bottom-right\"\n style=\"width: 100%\"\n >\n <template #trigger>\n <PvButton\n class=\"pv-full-width\"\n variant=\"ghost\"\n :label=\"option.label\"\n :ariaLabel=\"option.ariaLabel\"\n :left-icon=\"option.iconPosition === 'left' ? option.icon : undefined\"\n :right-icon=\"option.iconPosition === 'right' ? option.icon : undefined\"\n :disabled=\"option.disabled\"\n :class=\"{ 'pv-disabled': option.disabled }\"\n :data-active=\"modelValue === option.value ? true : null\"\n @click=\"selectOption(option)\"\n />\n </template>\n <template v-if=\"option.disabledReason\" #content>\n {{ option.disabledReason }}\n </template>\n </PvTooltipV2>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport PvTooltipV2 from \"@/components/base/PvTooltipV2/PvTooltipV2.vue\";\nimport { PvSegmentControlSize, PvSegmentedControlOption } from \"./types\";\n\ninterface PvSegmentControlProps {\n /** The list of options rendered as segments. Each option can have a label, icon, or both. */\n options: PvSegmentedControlOption[];\n /**\n * Controls the overall height of the segmented control.\n */\n size?: PvSegmentControlSize;\n}\n\nwithDefaults(defineProps<PvSegmentControlProps>(), {\n size: \"lg\",\n options: () => [],\n});\n\nconst modelValue = defineModel<string>({ required: true });\n\nconst selectOption = (option: PvSegmentedControlOption) => {\n if (option.disabled) return;\n modelValue.value = option.value;\n};\n</script>\n\n<template>\n <div\n :class=\"[\n 'pv-segmented-control',\n {\n 'pv-segmented-control-large': size === 'xl',\n },\n ]\"\n >\n <PvTooltipV2\n v-for=\"option in options\"\n :key=\"option.value\"\n variant=\"dark\"\n position=\"bottom-right\"\n style=\"width: 100%\"\n >\n <template #trigger>\n <PvButton\n class=\"pv-full-width\"\n variant=\"ghost\"\n :label=\"option.label\"\n :ariaLabel=\"option.ariaLabel\"\n :left-icon=\"option.iconPosition === 'left' ? option.icon : undefined\"\n :right-icon=\"option.iconPosition === 'right' ? option.icon : undefined\"\n :disabled=\"option.disabled\"\n :class=\"{ 'pv-disabled': option.disabled }\"\n :data-active=\"modelValue === option.value ? true : null\"\n @click=\"selectOption(option)\"\n />\n </template>\n <template v-if=\"option.disabledReason\" #content>\n {{ option.disabledReason }}\n </template>\n </PvTooltipV2>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { Option } from \"@/types\";\nexport interface PvTabListBaseProps {\n modelValue: string;\n options: Option[];\n}\n\ndefineProps<PvTabListBaseProps>();\n\nconst emit = defineEmits([\"update:modelValue\"]);\n\nconst selectOption = (value: string) => {\n emit(\"update:modelValue\", value);\n};\n</script>\n\n<template>\n <div>\n <ul role=\"list\" class=\"pv-tab-list\">\n <li\n v-for=\"option in options\"\n :key=\"option.value\"\n style=\"cursor: pointer\"\n @click=\"selectOption(option.value)\"\n :data-active=\"modelValue === option.value ? true : null\"\n >\n <button class=\"pv-text-body-xs\" style=\"font-weight: 500\">\n {{ option.label }}\n </button>\n </li>\n </ul>\n </div>\n</template>\n\n<style scoped>\n.pv-tab-list {\n border: none;\n}\n.pv-tab-list :where(li)[data-active]:after {\n content: \"\";\n display: block;\n height: 2px;\n width: 100%;\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background-color: #176f6f;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { Option } from \"@/types\";\nexport interface PvTabListBaseProps {\n modelValue: string;\n options: Option[];\n}\n\ndefineProps<PvTabListBaseProps>();\n\nconst emit = defineEmits([\"update:modelValue\"]);\n\nconst selectOption = (value: string) => {\n emit(\"update:modelValue\", value);\n};\n</script>\n\n<template>\n <div>\n <ul role=\"list\" class=\"pv-tab-list\">\n <li\n v-for=\"option in options\"\n :key=\"option.value\"\n style=\"cursor: pointer\"\n @click=\"selectOption(option.value)\"\n :data-active=\"modelValue === option.value ? true : null\"\n >\n <button class=\"pv-text-body-xs\" style=\"font-weight: 500\">\n {{ option.label }}\n </button>\n </li>\n </ul>\n </div>\n</template>\n\n<style scoped>\n.pv-tab-list {\n border: none;\n}\n.pv-tab-list :where(li)[data-active]:after {\n content: \"\";\n display: block;\n height: 2px;\n width: 100%;\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background-color: #176f6f;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from \"vue\";\nimport { sizeMap } from \"@/components/base/baseProps\";\nimport { PvCompanyLogoSize } from \"./types\";\n\ntype PvCompanyLogoProps = {\n /** Base URL path where company logo SVGs are hosted. */\n basePath?: string;\n /** Company name used to resolve the logo filename. */\n name: string;\n /** Display size of the logo. Maps to a fixed pixel width. */\n size?: PvCompanyLogoSize;\n /** When provided, overrides the computed image URL entirely (ignores `name` and `basePath`). */\n srcPathOverride?: string;\n};\n\nconst props = withDefaults(defineProps<PvCompanyLogoProps>(), {\n basePath: \"https://static-assets.turquoise.health/shared-logos/prd/payers\",\n size: \"md\",\n});\n\nconst isValidSrc = ref(true);\n\nconst iconSize = computed(() => {\n return sizeMap[props.size] || \"32px\"; // Default to md size if not found\n});\n\nconst classes = computed(() => ({\n [`pv-icon`]: isValidSrc.value,\n [`pv-company-${props.size}`]: props.size && !isValidSrc.value,\n}));\n\nconst styles = computed(() => ({\n width: iconSize.value,\n}));\n\nconst modifiedName = computed((): string => {\n const snakeCaseName = props.name\n .toLowerCase()\n .replace(/[^a-z\\s]/g, \"\")\n .trim()\n .replace(/\\s+/g, \"_\");\n return `${snakeCaseName}.svg`;\n});\n\nconst imageSource = computed(() => {\n if (props.srcPathOverride) {\n return props.srcPathOverride;\n }\n return `${props.basePath}/${modifiedName.value}`;\n});\n\n// reset the isValidSrc when the name changes, and let @error handler set it to false if the image fails to load\nwatch(imageSource, () => {\n isValidSrc.value = true;\n});\n</script>\n\n<template>\n <div class=\"pv-flex\" data-testid=\"pv-company-logo\">\n <div v-if=\"isValidSrc\" :class=\"classes\" :style=\"styles\">\n <img :src=\"imageSource\" alt=\"\" @error=\"isValidSrc = false\" />\n </div>\n <div v-else :class=\"classes\"></div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from \"vue\";\nimport { sizeMap } from \"@/components/base/baseProps\";\nimport { PvCompanyLogoSize } from \"./types\";\n\ntype PvCompanyLogoProps = {\n /** Base URL path where company logo SVGs are hosted. */\n basePath?: string;\n /** Company name used to resolve the logo filename. */\n name: string;\n /** Display size of the logo. Maps to a fixed pixel width. */\n size?: PvCompanyLogoSize;\n /** When provided, overrides the computed image URL entirely (ignores `name` and `basePath`). */\n srcPathOverride?: string;\n};\n\nconst props = withDefaults(defineProps<PvCompanyLogoProps>(), {\n basePath: \"https://static-assets.turquoise.health/shared-logos/prd/payers\",\n size: \"md\",\n});\n\nconst isValidSrc = ref(true);\n\nconst iconSize = computed(() => {\n return sizeMap[props.size] || \"32px\"; // Default to md size if not found\n});\n\nconst classes = computed(() => ({\n [`pv-icon`]: isValidSrc.value,\n [`pv-company-${props.size}`]: props.size && !isValidSrc.value,\n}));\n\nconst styles = computed(() => ({\n width: iconSize.value,\n}));\n\nconst modifiedName = computed((): string => {\n const snakeCaseName = props.name\n .toLowerCase()\n .replace(/[^a-z\\s]/g, \"\")\n .trim()\n .replace(/\\s+/g, \"_\");\n return `${snakeCaseName}.svg`;\n});\n\nconst imageSource = computed(() => {\n if (props.srcPathOverride) {\n return props.srcPathOverride;\n }\n return `${props.basePath}/${modifiedName.value}`;\n});\n\n// reset the isValidSrc when the name changes, and let @error handler set it to false if the image fails to load\nwatch(imageSource, () => {\n isValidSrc.value = true;\n});\n</script>\n\n<template>\n <div class=\"pv-flex\" data-testid=\"pv-company-logo\">\n <div v-if=\"isValidSrc\" :class=\"classes\" :style=\"styles\">\n <img :src=\"imageSource\" alt=\"\" @error=\"isValidSrc = false\" />\n </div>\n <div v-else :class=\"classes\"></div>\n </div>\n</template>\n","<script lang=\"ts\">\nimport { watch, useTemplateRef } from \"vue\";\n</script>\n\n<script setup lang=\"ts\">\nexport interface ModalProps {\n header: string;\n subheader?: string;\n disableCloseOnClickOutside?: boolean;\n hideFooter?: boolean;\n}\n\nconst props = withDefaults(defineProps<ModalProps>(), {\n disableCloseOnClickOutside: false,\n hideFooter: false,\n});\n\nconst dialogRef = useTemplateRef<HTMLDialogElement | null>(\"dialog\");\nconst showModal = defineModel<boolean>({\n required: true,\n});\n\nwatch(\n () => showModal.value,\n () => {\n if (showModal.value) {\n dialogRef.value?.showModal();\n } else {\n dialogRef.value?.close();\n }\n },\n);\n\nconst handleClose = () => {\n showModal.value = false;\n};\n\nconst handleBackdropClick = (e: MouseEvent) => {\n if (!props.disableCloseOnClickOutside && e.target === dialogRef.value) {\n handleClose();\n }\n};\n</script>\n\n<template>\n <dialog\n class=\"pv-modal-sm\"\n ref=\"dialog\"\n style=\"--max-width: 480px\"\n v-on:close=\"handleClose\"\n v-on:click=\"handleBackdropClick\"\n >\n <div class=\"pv-inset-squish-12\">\n <div class=\"pv-flex pv-flex-vertical pv-stack-16\" style=\"--flex-align: flex-start\">\n <span class=\"pv-heading-3\">{{ header }}</span>\n <span v-if=\"subheader\" class=\"pv-text-body-md\">{{ subheader }}</span>\n </div>\n <slot name=\"body\" />\n </div>\n <div v-if=\"!hideFooter\" class=\"pv-inset-squish-12 pv-border-top\" style=\"--color-border: #d2d8dc\">\n <slot name=\"footer\" />\n </div>\n </dialog>\n</template>\n","<script lang=\"ts\">\nimport { watch, useTemplateRef } from \"vue\";\n</script>\n\n<script setup lang=\"ts\">\nexport interface ModalProps {\n header: string;\n subheader?: string;\n disableCloseOnClickOutside?: boolean;\n hideFooter?: boolean;\n}\n\nconst props = withDefaults(defineProps<ModalProps>(), {\n disableCloseOnClickOutside: false,\n hideFooter: false,\n});\n\nconst dialogRef = useTemplateRef<HTMLDialogElement | null>(\"dialog\");\nconst showModal = defineModel<boolean>({\n required: true,\n});\n\nwatch(\n () => showModal.value,\n () => {\n if (showModal.value) {\n dialogRef.value?.showModal();\n } else {\n dialogRef.value?.close();\n }\n },\n);\n\nconst handleClose = () => {\n showModal.value = false;\n};\n\nconst handleBackdropClick = (e: MouseEvent) => {\n if (!props.disableCloseOnClickOutside && e.target === dialogRef.value) {\n handleClose();\n }\n};\n</script>\n\n<template>\n <dialog\n class=\"pv-modal-sm\"\n ref=\"dialog\"\n style=\"--max-width: 480px\"\n v-on:close=\"handleClose\"\n v-on:click=\"handleBackdropClick\"\n >\n <div class=\"pv-inset-squish-12\">\n <div class=\"pv-flex pv-flex-vertical pv-stack-16\" style=\"--flex-align: flex-start\">\n <span class=\"pv-heading-3\">{{ header }}</span>\n <span v-if=\"subheader\" class=\"pv-text-body-md\">{{ subheader }}</span>\n </div>\n <slot name=\"body\" />\n </div>\n <div v-if=\"!hideFooter\" class=\"pv-inset-squish-12 pv-border-top\" style=\"--color-border: #d2d8dc\">\n <slot name=\"footer\" />\n </div>\n </dialog>\n</template>\n","export enum BannerOrientationsEnum {\n Vertical = \"Vertical\",\n Horizontal = \"Horizontal\",\n}\n\nexport enum BannerVariantsEnum {\n Primary = \"Primary\",\n Secondary = \"Secondary\",\n Tertiary = \"Tertiary\",\n}\n\nexport type BannerOrientations = `${BannerOrientationsEnum}`;\nexport type BannerVariants = `${BannerVariantsEnum}`;\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { BannerOrientations, BannerVariants, BannerVariantsEnum, BannerOrientationsEnum } from \"./types\";\n\nexport interface PvBannerProps {\n /** Primary text displayed in the banner */\n label: string;\n /** Secondary descriptive text displayed below the label */\n description?: string;\n /** Icon name to display alongside the banner content */\n icon?: string;\n /** Visual style variant of the banner */\n variant?: BannerVariants;\n /** Layout orientation of the banner */\n orientation?: BannerOrientations;\n}\n\nwithDefaults(defineProps<PvBannerProps>(), {\n orientation: BannerOrientationsEnum.Horizontal,\n variant: BannerVariantsEnum.Primary,\n});\n</script>\n\n<template>\n <div\n data-testid=\"pv-banner\"\n :class=\"[\n {\n 'pv-banner-primary': variant === BannerVariantsEnum.Primary,\n 'pv-banner-secondary': variant === BannerVariantsEnum.Secondary,\n 'pv-banner-tertiary': variant === BannerVariantsEnum.Tertiary,\n 'pv-flex pv-space-between': orientation === BannerOrientationsEnum.Horizontal,\n },\n ]\"\n >\n <div\n :class=\"[\n 'pv-flex',\n {\n 'pv-stack-16': orientation === BannerOrientationsEnum.Vertical && $slots.action,\n },\n ]\"\n >\n <slot name=\"left\"></slot>\n <PvIcon v-if=\"icon\" data-testid=\"pv-banner-icon\" class=\"pv-text-brand\" :name=\"icon\" />\n <div>\n <p\n :class=\"[\n ' pv-text-title-md pv-line-clamp',\n {\n 'pv-stack-4': description,\n },\n ]\"\n style=\"--lines: 2; font-weight: 500\"\n :title=\"label\"\n >\n {{ label }}\n </p>\n <p v-if=\"description\" class=\"pv-text-body-sm pv-line-clamp\" style=\"--lines: 2\" :title=\"description\">\n {{ description }}\n </p>\n </div>\n </div>\n <div class=\"pv-flex\">\n <slot name=\"action\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { BannerOrientations, BannerVariants, BannerVariantsEnum, BannerOrientationsEnum } from \"./types\";\n\nexport interface PvBannerProps {\n /** Primary text displayed in the banner */\n label: string;\n /** Secondary descriptive text displayed below the label */\n description?: string;\n /** Icon name to display alongside the banner content */\n icon?: string;\n /** Visual style variant of the banner */\n variant?: BannerVariants;\n /** Layout orientation of the banner */\n orientation?: BannerOrientations;\n}\n\nwithDefaults(defineProps<PvBannerProps>(), {\n orientation: BannerOrientationsEnum.Horizontal,\n variant: BannerVariantsEnum.Primary,\n});\n</script>\n\n<template>\n <div\n data-testid=\"pv-banner\"\n :class=\"[\n {\n 'pv-banner-primary': variant === BannerVariantsEnum.Primary,\n 'pv-banner-secondary': variant === BannerVariantsEnum.Secondary,\n 'pv-banner-tertiary': variant === BannerVariantsEnum.Tertiary,\n 'pv-flex pv-space-between': orientation === BannerOrientationsEnum.Horizontal,\n },\n ]\"\n >\n <div\n :class=\"[\n 'pv-flex',\n {\n 'pv-stack-16': orientation === BannerOrientationsEnum.Vertical && $slots.action,\n },\n ]\"\n >\n <slot name=\"left\"></slot>\n <PvIcon v-if=\"icon\" data-testid=\"pv-banner-icon\" class=\"pv-text-brand\" :name=\"icon\" />\n <div>\n <p\n :class=\"[\n ' pv-text-title-md pv-line-clamp',\n {\n 'pv-stack-4': description,\n },\n ]\"\n style=\"--lines: 2; font-weight: 500\"\n :title=\"label\"\n >\n {{ label }}\n </p>\n <p v-if=\"description\" class=\"pv-text-body-sm pv-line-clamp\" style=\"--lines: 2\" :title=\"description\">\n {{ description }}\n </p>\n </div>\n </div>\n <div class=\"pv-flex\">\n <slot name=\"action\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport PvCompanyLogo from \"../PvCompanyLogo/PvCompanyLogo.vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { TagSize } from \"@/components/base/PvTag/types\";\n\nexport interface PvCompanyTag {\n /**\n * Company name. Displayed on the left\n */\n companyName: string;\n /**\n * Tag size\n */\n size?: TagSize;\n /**\n * Show clear left icon\n */\n showClear?: boolean;\n /**\n * Spine - dotted state\n */\n spine?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvCompanyTag>(), {\n showClear: false,\n size: \"md\",\n});\n\ndefineEmits<{\n (e: \"handle-close\", companyName: string): void;\n (e: \"handle-click\", companyName: string): void;\n}>();\n\nconst tagSizeClass = computed(() => {\n switch (props.size) {\n case \"lg\": {\n return \"pv-tag-lg\";\n }\n case \"sm\": {\n return \"pv-tag-sm\";\n }\n default: {\n return \"\";\n }\n }\n});\n</script>\n\n<template>\n <button\n :class=\"['pv-tag-tertiary', tagSizeClass]\"\n @click=\"$emit('handle-click', companyName)\"\n data-testid=\"pv-company-tag\"\n >\n <PvCompanyLogo\n :class=\"size === 'lg' ? 'pv-company-sm' : 'pv-company-xs'\"\n data-testid=\"pv-company-tag-icon\"\n :size=\"size === 'lg' ? 'sm' : 'xs'\"\n :name=\"companyName\"\n />\n <span\n :class=\"[\n {\n 'pv-underline-dotted': spine,\n },\n ]\"\n >\n {{ companyName }}\n </span>\n <PvIcon\n data-testid=\"pv-company-tag-close-icon\"\n :size=\"12\"\n name=\"close\"\n v-if=\"showClear\"\n @click.stop=\"$emit('handle-close', companyName)\"\n />\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport PvCompanyLogo from \"../PvCompanyLogo/PvCompanyLogo.vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { TagSize } from \"@/components/base/PvTag/types\";\n\nexport interface PvCompanyTag {\n /**\n * Company name. Displayed on the left\n */\n companyName: string;\n /**\n * Tag size\n */\n size?: TagSize;\n /**\n * Show clear left icon\n */\n showClear?: boolean;\n /**\n * Spine - dotted state\n */\n spine?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvCompanyTag>(), {\n showClear: false,\n size: \"md\",\n});\n\ndefineEmits<{\n (e: \"handle-close\", companyName: string): void;\n (e: \"handle-click\", companyName: string): void;\n}>();\n\nconst tagSizeClass = computed(() => {\n switch (props.size) {\n case \"lg\": {\n return \"pv-tag-lg\";\n }\n case \"sm\": {\n return \"pv-tag-sm\";\n }\n default: {\n return \"\";\n }\n }\n});\n</script>\n\n<template>\n <button\n :class=\"['pv-tag-tertiary', tagSizeClass]\"\n @click=\"$emit('handle-click', companyName)\"\n data-testid=\"pv-company-tag\"\n >\n <PvCompanyLogo\n :class=\"size === 'lg' ? 'pv-company-sm' : 'pv-company-xs'\"\n data-testid=\"pv-company-tag-icon\"\n :size=\"size === 'lg' ? 'sm' : 'xs'\"\n :name=\"companyName\"\n />\n <span\n :class=\"[\n {\n 'pv-underline-dotted': spine,\n },\n ]\"\n >\n {{ companyName }}\n </span>\n <PvIcon\n data-testid=\"pv-company-tag-close-icon\"\n :size=\"12\"\n name=\"close\"\n v-if=\"showClear\"\n @click.stop=\"$emit('handle-close', companyName)\"\n />\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport { TagSize } from \"@/components/base/PvTag/types\";\n\nexport interface PvSuggestionTag {\n /**\n * Tag size\n */\n size?: TagSize;\n /**\n * Tag Label\n */\n label: string;\n /**\n * Tag Icon\n */\n icon?: string;\n /**\n * Icon class\n */\n iconClasses?: string[];\n /**\n * Show rounded state\n */\n rounded?: boolean;\n /**\n * Disable the tag, preventing interaction\n */\n disabled?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvSuggestionTag>(), {\n size: \"md\",\n disabled: false,\n});\n\ndefineEmits<{\n (e: \"handle-click\", label: string): void;\n}>();\n\nconst tagSizeClass = computed(() => {\n switch (props.size) {\n case \"lg\": {\n return \"pv-tag-lg\";\n }\n case \"sm\": {\n return \"pv-tag-sm\";\n }\n default: {\n return \"\";\n }\n }\n});\n</script>\n\n<template>\n <button\n :class=\"['pv-border-dashed pv-tag-secondary', tagSizeClass]\"\n @click=\"$emit('handle-click', label)\"\n data-testid=\"pv-suggestion-tag\"\n style=\"max-width: 100%\"\n :data-style=\"rounded ? 'rounded' : undefined\"\n :disabled=\"disabled\"\n :title=\"label\"\n >\n <PvIcon data-testid=\"pv-suggestion-tag-icon\" v-if=\"icon\" :name=\"icon\" :size=\"12\" :class=\"iconClasses\" />\n <span class=\"pv-truncate\">\n {{ label }}\n </span>\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport { TagSize } from \"@/components/base/PvTag/types\";\n\nexport interface PvSuggestionTag {\n /**\n * Tag size\n */\n size?: TagSize;\n /**\n * Tag Label\n */\n label: string;\n /**\n * Tag Icon\n */\n icon?: string;\n /**\n * Icon class\n */\n iconClasses?: string[];\n /**\n * Show rounded state\n */\n rounded?: boolean;\n /**\n * Disable the tag, preventing interaction\n */\n disabled?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvSuggestionTag>(), {\n size: \"md\",\n disabled: false,\n});\n\ndefineEmits<{\n (e: \"handle-click\", label: string): void;\n}>();\n\nconst tagSizeClass = computed(() => {\n switch (props.size) {\n case \"lg\": {\n return \"pv-tag-lg\";\n }\n case \"sm\": {\n return \"pv-tag-sm\";\n }\n default: {\n return \"\";\n }\n }\n});\n</script>\n\n<template>\n <button\n :class=\"['pv-border-dashed pv-tag-secondary', tagSizeClass]\"\n @click=\"$emit('handle-click', label)\"\n data-testid=\"pv-suggestion-tag\"\n style=\"max-width: 100%\"\n :data-style=\"rounded ? 'rounded' : undefined\"\n :disabled=\"disabled\"\n :title=\"label\"\n >\n <PvIcon data-testid=\"pv-suggestion-tag-icon\" v-if=\"icon\" :name=\"icon\" :size=\"12\" :class=\"iconClasses\" />\n <span class=\"pv-truncate\">\n {{ label }}\n </span>\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport PvCounterBadge from \"../PvCounterBadge/PvCounterBadge.vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { ChevronPosition } from \"./types\";\nimport { computed } from \"vue\";\nimport type { CSSProperties } from \"vue\";\n\ninterface PvAccordionProps {\n /** Position of the chevron icon relative to the header text */\n chevronPosition?: ChevronPosition;\n /** Orientation of the chevron for the open/closed states (up-down vs right-down) */\n chevronVariant?: \"vertical\" | \"horizontal\";\n /** Whether the accordion is open by default on initial render */\n defaultOpen?: boolean;\n /** Optional counter badge value displayed next to the header text */\n counter?: number;\n /** Enables a custom trigger slot instead of the default header text */\n enableTriggerSlot?: boolean;\n /** Makes the trigger element expand to fill its container width */\n enableTriggerFullWidth?: boolean;\n /** Text displayed as the accordion header */\n header?: string;\n /** Custom CSS styles applied to the summary/trigger element */\n summaryStyles?: CSSProperties;\n /** CSS class bindings applied to the summary/trigger element */\n summaryClasses?: Record<string, boolean>;\n /** Custom CSS styles applied to the content container */\n contentStyles?: CSSProperties;\n}\n\nconst props = withDefaults(defineProps<PvAccordionProps>(), {\n chevronVariant: \"vertical\",\n chevronPosition: \"right\",\n enableTriggerSlot: false,\n enableTriggerFullWidth: false,\n});\n\nconst accordionOpen = defineModel<boolean>();\n\ndefineEmits<{\n (e: \"summary-mouseenter\"): void;\n (e: \"summary-mouseleave\"): void;\n}>();\n\nif (props.defaultOpen !== undefined) {\n accordionOpen.value = props.defaultOpen;\n}\n\nconst toggleAccordionState = (event: Event) => {\n const detailsElement = event.target as HTMLDetailsElement;\n accordionOpen.value = detailsElement.open;\n};\n\nconst triggerStyles = {\n width: props.enableTriggerFullWidth ? \"100%\" : \"fit-content\",\n};\n\nconst chevronState = computed(() => {\n if (props.chevronVariant === \"horizontal\") {\n if (props.chevronPosition === \"left\") {\n return accordionOpen.value ? \"chevron-down\" : \"chevron-right\";\n } else {\n return accordionOpen.value ? \"chevron-down\" : \"chevron-left\";\n }\n } else {\n return accordionOpen.value ? \"chevron-up\" : \"chevron-down\";\n }\n});\n</script>\n\n<template>\n <details data-testid=\"pv-accordion\" class=\"pv-accordion\" :open=\"accordionOpen\" @toggle=\"toggleAccordionState\">\n <summary\n :class=\"['pv-flex pv-space-between pv-relative', summaryClasses]\"\n :style=\"{ ...triggerStyles, ...summaryStyles }\"\n @mouseenter=\"$emit('summary-mouseenter')\"\n @mouseleave=\"$emit('summary-mouseleave')\"\n >\n <PvIcon v-if=\"chevronPosition === 'left'\" :name=\"chevronState\" />\n <template v-if=\"enableTriggerSlot\">\n <slot name=\"trigger\" />\n </template>\n <template v-else>\n <span>\n {{ header }}\n </span>\n <PvCounterBadge v-if=\"counter\" :value=\"counter\" variant=\"secondary\" size=\"sm\" />\n </template>\n <PvIcon v-if=\"chevronPosition === 'right'\" :name=\"chevronState\" />\n </summary>\n <div :style=\"contentStyles\">\n <slot />\n </div>\n </details>\n</template>\n\n<style scoped>\nsummary {\n background-image: none;\n padding-right: 2px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport PvCounterBadge from \"../PvCounterBadge/PvCounterBadge.vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { ChevronPosition } from \"./types\";\nimport { computed } from \"vue\";\nimport type { CSSProperties } from \"vue\";\n\ninterface PvAccordionProps {\n /** Position of the chevron icon relative to the header text */\n chevronPosition?: ChevronPosition;\n /** Orientation of the chevron for the open/closed states (up-down vs right-down) */\n chevronVariant?: \"vertical\" | \"horizontal\";\n /** Whether the accordion is open by default on initial render */\n defaultOpen?: boolean;\n /** Optional counter badge value displayed next to the header text */\n counter?: number;\n /** Enables a custom trigger slot instead of the default header text */\n enableTriggerSlot?: boolean;\n /** Makes the trigger element expand to fill its container width */\n enableTriggerFullWidth?: boolean;\n /** Text displayed as the accordion header */\n header?: string;\n /** Custom CSS styles applied to the summary/trigger element */\n summaryStyles?: CSSProperties;\n /** CSS class bindings applied to the summary/trigger element */\n summaryClasses?: Record<string, boolean>;\n /** Custom CSS styles applied to the content container */\n contentStyles?: CSSProperties;\n}\n\nconst props = withDefaults(defineProps<PvAccordionProps>(), {\n chevronVariant: \"vertical\",\n chevronPosition: \"right\",\n enableTriggerSlot: false,\n enableTriggerFullWidth: false,\n});\n\nconst accordionOpen = defineModel<boolean>();\n\ndefineEmits<{\n (e: \"summary-mouseenter\"): void;\n (e: \"summary-mouseleave\"): void;\n}>();\n\nif (props.defaultOpen !== undefined) {\n accordionOpen.value = props.defaultOpen;\n}\n\nconst toggleAccordionState = (event: Event) => {\n const detailsElement = event.target as HTMLDetailsElement;\n accordionOpen.value = detailsElement.open;\n};\n\nconst triggerStyles = {\n width: props.enableTriggerFullWidth ? \"100%\" : \"fit-content\",\n};\n\nconst chevronState = computed(() => {\n if (props.chevronVariant === \"horizontal\") {\n if (props.chevronPosition === \"left\") {\n return accordionOpen.value ? \"chevron-down\" : \"chevron-right\";\n } else {\n return accordionOpen.value ? \"chevron-down\" : \"chevron-left\";\n }\n } else {\n return accordionOpen.value ? \"chevron-up\" : \"chevron-down\";\n }\n});\n</script>\n\n<template>\n <details data-testid=\"pv-accordion\" class=\"pv-accordion\" :open=\"accordionOpen\" @toggle=\"toggleAccordionState\">\n <summary\n :class=\"['pv-flex pv-space-between pv-relative', summaryClasses]\"\n :style=\"{ ...triggerStyles, ...summaryStyles }\"\n @mouseenter=\"$emit('summary-mouseenter')\"\n @mouseleave=\"$emit('summary-mouseleave')\"\n >\n <PvIcon v-if=\"chevronPosition === 'left'\" :name=\"chevronState\" />\n <template v-if=\"enableTriggerSlot\">\n <slot name=\"trigger\" />\n </template>\n <template v-else>\n <span>\n {{ header }}\n </span>\n <PvCounterBadge v-if=\"counter\" :value=\"counter\" variant=\"secondary\" size=\"sm\" />\n </template>\n <PvIcon v-if=\"chevronPosition === 'right'\" :name=\"chevronState\" />\n </summary>\n <div :style=\"contentStyles\">\n <slot />\n </div>\n </details>\n</template>\n\n<style scoped>\nsummary {\n background-image: none;\n padding-right: 2px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, useTemplateRef, onMounted } from \"vue\";\nimport { onKeyStroke } from \"@vueuse/core\";\n\nexport interface PvSearchInputProps {\n /**\n * Placeholder text shown when the input is empty.\n */\n placeholder?: string;\n /**\n * When true, the input is non-interactive and visually dimmed.\n */\n disabled?: boolean;\n /** When true, displays a keyboard shortcut badge (\"/\" key) and registers the hotkey to focus the input. */\n displayShortcut?: boolean;\n}\n\nexport interface PvSearchInputExposed {\n input: HTMLInputElement | null;\n}\n\nconst props = withDefaults(defineProps<PvSearchInputProps>(), {\n placeholder: \"Search\",\n disabled: false,\n});\n\nconst SHORTCUT = \"/\";\n\nconst input = useTemplateRef<HTMLInputElement | null>(\"search-input\");\nconst modelValue = defineModel<string>({ required: false, default: \"\" });\n\nconst pvSearchInputClasses = computed(() => {\n return {\n \"pv-input-search\": true,\n \"pv-full-width\": true,\n \"pv-input-padded-end\": true,\n };\n});\n\nonMounted(() => {\n if (!props.displayShortcut) return;\n\n onKeyStroke(SHORTCUT, (e) => {\n const target = e.target as HTMLElement | null;\n\n const isTyping =\n target instanceof HTMLInputElement ||\n target instanceof HTMLTextAreaElement ||\n (target?.isContentEditable ?? false);\n\n const isCurrentInputFocused = document.activeElement === input.value;\n\n if (!isTyping || isCurrentInputFocused) {\n if (!isCurrentInputFocused) {\n e.preventDefault();\n input.value?.focus();\n }\n }\n });\n});\n\ndefineExpose({ input });\n</script>\n\n<template>\n <div class=\"pv-relative\">\n <input\n ref=\"search-input\"\n v-model=\"modelValue\"\n data-testid=\"pv-search-input\"\n type=\"text\"\n :disabled=\"disabled\"\n :class=\"pvSearchInputClasses\"\n :placeholder=\"placeholder\"\n />\n <kbd v-if=\"displayShortcut\" data-testid=\"pv-search-input-shortcut\" class=\"pv-kbd\">\n {{ SHORTCUT }}\n </kbd>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useTemplateRef, onMounted } from \"vue\";\nimport { onKeyStroke } from \"@vueuse/core\";\n\nexport interface PvSearchInputProps {\n /**\n * Placeholder text shown when the input is empty.\n */\n placeholder?: string;\n /**\n * When true, the input is non-interactive and visually dimmed.\n */\n disabled?: boolean;\n /** When true, displays a keyboard shortcut badge (\"/\" key) and registers the hotkey to focus the input. */\n displayShortcut?: boolean;\n}\n\nexport interface PvSearchInputExposed {\n input: HTMLInputElement | null;\n}\n\nconst props = withDefaults(defineProps<PvSearchInputProps>(), {\n placeholder: \"Search\",\n disabled: false,\n});\n\nconst SHORTCUT = \"/\";\n\nconst input = useTemplateRef<HTMLInputElement | null>(\"search-input\");\nconst modelValue = defineModel<string>({ required: false, default: \"\" });\n\nconst pvSearchInputClasses = computed(() => {\n return {\n \"pv-input-search\": true,\n \"pv-full-width\": true,\n \"pv-input-padded-end\": true,\n };\n});\n\nonMounted(() => {\n if (!props.displayShortcut) return;\n\n onKeyStroke(SHORTCUT, (e) => {\n const target = e.target as HTMLElement | null;\n\n const isTyping =\n target instanceof HTMLInputElement ||\n target instanceof HTMLTextAreaElement ||\n (target?.isContentEditable ?? false);\n\n const isCurrentInputFocused = document.activeElement === input.value;\n\n if (!isTyping || isCurrentInputFocused) {\n if (!isCurrentInputFocused) {\n e.preventDefault();\n input.value?.focus();\n }\n }\n });\n});\n\ndefineExpose({ input });\n</script>\n\n<template>\n <div class=\"pv-relative\">\n <input\n ref=\"search-input\"\n v-model=\"modelValue\"\n data-testid=\"pv-search-input\"\n type=\"text\"\n :disabled=\"disabled\"\n :class=\"pvSearchInputClasses\"\n :placeholder=\"placeholder\"\n />\n <kbd v-if=\"displayShortcut\" data-testid=\"pv-search-input-shortcut\" class=\"pv-kbd\">\n {{ SHORTCUT }}\n </kbd>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport DatePicker from \"primevue/datepicker\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\n\nexport interface PvDatePickerProps {\n /**\n * Defines the quantity of the selection.\n */\n selectionMode?: \"single\" | \"multiple\" | \"range\" | undefined;\n /**\n * Format of the date. Defaults to PrimeVue Locale configuration.\n */\n dateFormat?: string | undefined;\n /**\n * When enabled, displays the datepicker as inline instead of an overlay.\n */\n inline?: boolean | undefined;\n /**\n * Whether days in other months shown before or after the current month are selectable. This only applies if the showOtherMonths option is set to true.\n */\n selectOtherMonths?: boolean | undefined;\n /**\n * Number of months to display.\n */\n numberOfMonths?: number | undefined;\n /**\n * Type of view to display.\n */\n view?: \"date\" | \"month\" | \"year\" | undefined;\n /**\n * The minimum selectable date.\n */\n minDate?: Date | undefined;\n /**\n * The maximum selectable date.\n */\n maxDate?: Date | undefined;\n /**\n * Array with dates to disable.\n */\n disabledDates?: Date[] | undefined;\n /**\n * Array with disabled weekday numbers.\n */\n disabledDays?: number[] | undefined;\n /**\n * Maximum number of selectable dates in multiple mode.\n */\n maxDateCount?: number | undefined;\n /**\n * Whether to display today and clear buttons at the footer.\n */\n showButtonBar?: boolean | undefined;\n /**\n * When enabled, datepicker will show week numbers.\n */\n showWeek?: boolean | undefined;\n /**\n * Whether to allow entering the date manually via typing.\n */\n manualInput?: boolean | undefined;\n /**\n * When present, it specifies that the component should be disabled.\n */\n disabled?: boolean | undefined;\n /**\n * When present, it specifies that the component should have invalid state style.\n */\n invalid?: boolean | undefined;\n /**\n * When present, it specifies that an input field is read-only.\n */\n readonly?: boolean | undefined;\n /**\n * Placeholder text for the input.\n */\n placeholder?: string | undefined;\n /**\n * When enabled, displays a button with icon next to input.\n */\n showIcon?: boolean;\n /**\n * When input should take 100% width\n */\n fullWidth?: boolean;\n /**\n * A valid query selector or an HTMLElement to specify where the overlay gets attached.\n */\n appendTo?: \"body\" | \"self\" | undefined;\n /**\n * Style class of the datepicker panel.\n */\n panelClass?: string | undefined;\n}\n\nconst date = defineModel<Date>({ required: true });\nconst props = withDefaults(defineProps<PvDatePickerProps>(), {\n appendTo: \"body\",\n});\n</script>\n\n<template>\n <DatePicker\n v-model=\"date\"\n v-bind=\"props\"\n :showIcon=\"showIcon\"\n :iconDisplay=\"showIcon ? 'input' : undefined\"\n :fluid=\"fullWidth\"\n >\n <template #inputicon=\"slotProps\">\n <PvIcon name=\"calendar\" @click=\"slotProps.clickCallback\" />\n </template>\n </DatePicker>\n</template>\n","<script setup lang=\"ts\">\nimport DatePicker from \"primevue/datepicker\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\n\nexport interface PvDatePickerProps {\n /**\n * Defines the quantity of the selection.\n */\n selectionMode?: \"single\" | \"multiple\" | \"range\" | undefined;\n /**\n * Format of the date. Defaults to PrimeVue Locale configuration.\n */\n dateFormat?: string | undefined;\n /**\n * When enabled, displays the datepicker as inline instead of an overlay.\n */\n inline?: boolean | undefined;\n /**\n * Whether days in other months shown before or after the current month are selectable. This only applies if the showOtherMonths option is set to true.\n */\n selectOtherMonths?: boolean | undefined;\n /**\n * Number of months to display.\n */\n numberOfMonths?: number | undefined;\n /**\n * Type of view to display.\n */\n view?: \"date\" | \"month\" | \"year\" | undefined;\n /**\n * The minimum selectable date.\n */\n minDate?: Date | undefined;\n /**\n * The maximum selectable date.\n */\n maxDate?: Date | undefined;\n /**\n * Array with dates to disable.\n */\n disabledDates?: Date[] | undefined;\n /**\n * Array with disabled weekday numbers.\n */\n disabledDays?: number[] | undefined;\n /**\n * Maximum number of selectable dates in multiple mode.\n */\n maxDateCount?: number | undefined;\n /**\n * Whether to display today and clear buttons at the footer.\n */\n showButtonBar?: boolean | undefined;\n /**\n * When enabled, datepicker will show week numbers.\n */\n showWeek?: boolean | undefined;\n /**\n * Whether to allow entering the date manually via typing.\n */\n manualInput?: boolean | undefined;\n /**\n * When present, it specifies that the component should be disabled.\n */\n disabled?: boolean | undefined;\n /**\n * When present, it specifies that the component should have invalid state style.\n */\n invalid?: boolean | undefined;\n /**\n * When present, it specifies that an input field is read-only.\n */\n readonly?: boolean | undefined;\n /**\n * Placeholder text for the input.\n */\n placeholder?: string | undefined;\n /**\n * When enabled, displays a button with icon next to input.\n */\n showIcon?: boolean;\n /**\n * When input should take 100% width\n */\n fullWidth?: boolean;\n /**\n * A valid query selector or an HTMLElement to specify where the overlay gets attached.\n */\n appendTo?: \"body\" | \"self\" | undefined;\n /**\n * Style class of the datepicker panel.\n */\n panelClass?: string | undefined;\n}\n\nconst date = defineModel<Date>({ required: true });\nconst props = withDefaults(defineProps<PvDatePickerProps>(), {\n appendTo: \"body\",\n});\n</script>\n\n<template>\n <DatePicker\n v-model=\"date\"\n v-bind=\"props\"\n :showIcon=\"showIcon\"\n :iconDisplay=\"showIcon ? 'input' : undefined\"\n :fluid=\"fullWidth\"\n >\n <template #inputicon=\"slotProps\">\n <PvIcon name=\"calendar\" @click=\"slotProps.clickCallback\" />\n </template>\n </DatePicker>\n</template>\n","import dayjs from \"dayjs\";\nimport utc from \"dayjs/plugin/utc\";\nimport timezone from \"dayjs/plugin/timezone\";\nimport customParseFormat from \"dayjs/plugin/advancedFormat\";\n\ndayjs.extend(customParseFormat);\ndayjs.extend(utc);\ndayjs.extend(timezone);\n\nexport const useDateTime = () => {\n const getCondensedDate = ({ date }: { date: Date }) => {\n return dayjs(date).format(\"MM/DD/YYYY\");\n };\n\n const getTime = ({ date, timezone }: { date: Date; timezone?: string }) => {\n if (timezone === undefined) {\n return dayjs(date).format(\"h:mm A\");\n } else {\n return dayjs(date).tz(timezone).format(\"h:mm A z\");\n }\n };\n\n return {\n getCondensedDate,\n getTime,\n };\n};\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvSize } from \"../baseProps\";\nimport { useDateTime } from \"./useDateTime\";\n\ntype DateTimeSize = Extract<PvSize, \"xs\" | \"sm\">;\n\ninterface PvDateTimeProps {\n /** Display format: \"condensed\" for MM/DD/YYYY, \"time\" for h:mm AM/PM */\n variants?: \"condensed\" | \"time\";\n /** IANA timezone identifier for time display (e.g. \"America/New_York\") */\n timezone?: string;\n /** Date object to format and display */\n date: Date;\n /** Text size of the displayed date/time */\n size?: DateTimeSize;\n}\n\nconst props = withDefaults(defineProps<PvDateTimeProps>(), {\n variants: \"condensed\",\n size: \"sm\",\n});\n\nconst { getCondensedDate, getTime } = useDateTime();\n\nconst dataFormat = computed(() => {\n switch (props.variants) {\n case \"time\": {\n return getTime({ date: props.date, timezone: props.timezone });\n }\n case \"condensed\": {\n return getCondensedDate({ date: props.date });\n }\n default: {\n return \"\";\n }\n }\n});\n</script>\n\n<template>\n <span\n data-testid=\"pv-date-time\"\n :class=\"[\n 'pv-text-secondary',\n {\n 'pv-text-body-xxs': size === 'xs',\n 'pv-text-body-md': size === 'sm',\n },\n ]\"\n >\n {{ dataFormat }}\n </span>\n</template>\n\n<style scoped>\n.pv-text-secondary {\n color: #4b595c;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvSize } from \"../baseProps\";\nimport { useDateTime } from \"./useDateTime\";\n\ntype DateTimeSize = Extract<PvSize, \"xs\" | \"sm\">;\n\ninterface PvDateTimeProps {\n /** Display format: \"condensed\" for MM/DD/YYYY, \"time\" for h:mm AM/PM */\n variants?: \"condensed\" | \"time\";\n /** IANA timezone identifier for time display (e.g. \"America/New_York\") */\n timezone?: string;\n /** Date object to format and display */\n date: Date;\n /** Text size of the displayed date/time */\n size?: DateTimeSize;\n}\n\nconst props = withDefaults(defineProps<PvDateTimeProps>(), {\n variants: \"condensed\",\n size: \"sm\",\n});\n\nconst { getCondensedDate, getTime } = useDateTime();\n\nconst dataFormat = computed(() => {\n switch (props.variants) {\n case \"time\": {\n return getTime({ date: props.date, timezone: props.timezone });\n }\n case \"condensed\": {\n return getCondensedDate({ date: props.date });\n }\n default: {\n return \"\";\n }\n }\n});\n</script>\n\n<template>\n <span\n data-testid=\"pv-date-time\"\n :class=\"[\n 'pv-text-secondary',\n {\n 'pv-text-body-xxs': size === 'xs',\n 'pv-text-body-md': size === 'sm',\n },\n ]\"\n >\n {{ dataFormat }}\n </span>\n</template>\n\n<style scoped>\n.pv-text-secondary {\n color: #4b595c;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { watch, useTemplateRef, onMounted } from \"vue\";\nimport { onKeyStroke, onClickOutside } from \"@vueuse/core\";\n\nimport PvSearchInput, { PvSearchInputProps } from \"../PvSearchInput/PvSearchInput.vue\";\nimport PvButton from \"../PvButton/PvButton.vue\";\n\nexport interface PvDrawer {\n header?: string;\n subheader?: string;\n showSearchbar?: boolean;\n closeOnClickOutside?: boolean;\n searchInputProps?: PvSearchInputProps;\n}\n\nconst props = withDefaults(defineProps<PvDrawer>(), {\n closeOnClickOutside: false,\n});\n\nconst emit = defineEmits<{\n (e: \"click-outside\"): void;\n}>();\n\nconst sidePanel = useTemplateRef(\"sidePanel\");\nconst searchInput = defineModel<string>(\"searchInput\", {\n required: false,\n});\nconst showDrawer = defineModel<boolean>({\n required: true,\n});\n\nonMounted(() => {\n if (showDrawer.value) {\n sidePanel?.value?.setAttribute(\"open\", \"true\");\n }\n\n if (props.closeOnClickOutside) {\n attachClickOutsideHandler();\n }\n});\n\nconst attachClickOutsideHandler = () => {\n if (!sidePanel.value) return;\n\n onClickOutside(\n sidePanel.value,\n () => {\n if (showDrawer.value) {\n emit(\"click-outside\");\n handleClose();\n }\n },\n { ignore: [\".pv-click-outside-ignore\"] },\n );\n};\n\nconst handleClose = () => {\n sidePanel?.value?.removeAttribute(\"open\");\n showDrawer.value = false;\n};\n\nwatch(\n () => showDrawer.value,\n () => {\n if (showDrawer.value) {\n sidePanel?.value?.setAttribute(\"open\", \"true\");\n } else {\n sidePanel?.value?.removeAttribute(\"open\");\n }\n },\n);\n\nonKeyStroke(\"Escape\", () => {\n if (sidePanel.value && showDrawer.value) {\n handleClose();\n }\n});\n</script>\n\n<template>\n <div\n class=\"pv-drawer pv-surface\"\n ref=\"sidePanel\"\n data-testid=\"pv-drawer\"\n style=\"display: flex; flex-direction: column; height: 100%\"\n >\n <!-- Header Section (Fixed) -->\n <div class=\"pv-inset-squish-12 pv-border-bottom\" style=\"flex-shrink: 0\">\n <slot v-if=\"$slots.header\" name=\"header\" />\n <template v-else>\n <div class=\"pv-flex-vertical pv-stack-16\" style=\"--flex-align: flex-start\">\n <div class=\"pv-flex pv-full-width\">\n <span class=\"pv-full-width pv-heading-3\">{{ header }}</span>\n <PvButton\n left-icon=\"close\"\n ariaLabel=\"Close\"\n size=\"md\"\n @click=\"handleClose\"\n data-testid=\"pv-side-panel-close-button\"\n variant=\"ghost\"\n />\n </div>\n <span v-if=\"subheader\" class=\"pv-text-body-md\">{{ subheader }}</span>\n </div>\n <div v-if=\"showSearchbar && searchInput !== undefined\" class=\"pv-inset-inline-16\">\n <PvSearchInput\n data-testid=\"pv-side-panel-input-search\"\n v-model=\"searchInput\"\n v-bind=\"props.searchInputProps\"\n />\n </div>\n </template>\n </div>\n\n <!-- Main Content Section (Scrollable) -->\n <div class=\"pv-inset-inline-16\" style=\"flex: 1; overflow-y: auto; min-height: 0\">\n <slot />\n </div>\n\n <!-- Footer Section (Fixed) -->\n <div v-if=\"$slots.footer\" class=\"pv-inset-squish-12 pv-border-top\" style=\"flex-shrink: 0\">\n <slot name=\"footer\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { watch, useTemplateRef, onMounted } from \"vue\";\nimport { onKeyStroke, onClickOutside } from \"@vueuse/core\";\n\nimport PvSearchInput, { PvSearchInputProps } from \"../PvSearchInput/PvSearchInput.vue\";\nimport PvButton from \"../PvButton/PvButton.vue\";\n\nexport interface PvDrawer {\n header?: string;\n subheader?: string;\n showSearchbar?: boolean;\n closeOnClickOutside?: boolean;\n searchInputProps?: PvSearchInputProps;\n}\n\nconst props = withDefaults(defineProps<PvDrawer>(), {\n closeOnClickOutside: false,\n});\n\nconst emit = defineEmits<{\n (e: \"click-outside\"): void;\n}>();\n\nconst sidePanel = useTemplateRef(\"sidePanel\");\nconst searchInput = defineModel<string>(\"searchInput\", {\n required: false,\n});\nconst showDrawer = defineModel<boolean>({\n required: true,\n});\n\nonMounted(() => {\n if (showDrawer.value) {\n sidePanel?.value?.setAttribute(\"open\", \"true\");\n }\n\n if (props.closeOnClickOutside) {\n attachClickOutsideHandler();\n }\n});\n\nconst attachClickOutsideHandler = () => {\n if (!sidePanel.value) return;\n\n onClickOutside(\n sidePanel.value,\n () => {\n if (showDrawer.value) {\n emit(\"click-outside\");\n handleClose();\n }\n },\n { ignore: [\".pv-click-outside-ignore\"] },\n );\n};\n\nconst handleClose = () => {\n sidePanel?.value?.removeAttribute(\"open\");\n showDrawer.value = false;\n};\n\nwatch(\n () => showDrawer.value,\n () => {\n if (showDrawer.value) {\n sidePanel?.value?.setAttribute(\"open\", \"true\");\n } else {\n sidePanel?.value?.removeAttribute(\"open\");\n }\n },\n);\n\nonKeyStroke(\"Escape\", () => {\n if (sidePanel.value && showDrawer.value) {\n handleClose();\n }\n});\n</script>\n\n<template>\n <div\n class=\"pv-drawer pv-surface\"\n ref=\"sidePanel\"\n data-testid=\"pv-drawer\"\n style=\"display: flex; flex-direction: column; height: 100%\"\n >\n <!-- Header Section (Fixed) -->\n <div class=\"pv-inset-squish-12 pv-border-bottom\" style=\"flex-shrink: 0\">\n <slot v-if=\"$slots.header\" name=\"header\" />\n <template v-else>\n <div class=\"pv-flex-vertical pv-stack-16\" style=\"--flex-align: flex-start\">\n <div class=\"pv-flex pv-full-width\">\n <span class=\"pv-full-width pv-heading-3\">{{ header }}</span>\n <PvButton\n left-icon=\"close\"\n ariaLabel=\"Close\"\n size=\"md\"\n @click=\"handleClose\"\n data-testid=\"pv-side-panel-close-button\"\n variant=\"ghost\"\n />\n </div>\n <span v-if=\"subheader\" class=\"pv-text-body-md\">{{ subheader }}</span>\n </div>\n <div v-if=\"showSearchbar && searchInput !== undefined\" class=\"pv-inset-inline-16\">\n <PvSearchInput\n data-testid=\"pv-side-panel-input-search\"\n v-model=\"searchInput\"\n v-bind=\"props.searchInputProps\"\n />\n </div>\n </template>\n </div>\n\n <!-- Main Content Section (Scrollable) -->\n <div class=\"pv-inset-inline-16\" style=\"flex: 1; overflow-y: auto; min-height: 0\">\n <slot />\n </div>\n\n <!-- Footer Section (Fixed) -->\n <div v-if=\"$slots.footer\" class=\"pv-inset-squish-12 pv-border-top\" style=\"flex-shrink: 0\">\n <slot name=\"footer\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvCounterBadge from \"../PvCounterBadge/PvCounterBadge.vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { Tab, TabSize } from \"./types\";\n\ninterface PvTabsProps {\n /** Array of tab objects defining each tab's label, icon, and counter */\n tabs: Tab[];\n /** Size of the tab list */\n size?: TabSize;\n}\n\nwithDefaults(defineProps<PvTabsProps>(), {\n size: \"lg\",\n});\n\nconst selectedTab = defineModel<string>({ required: true });\n\nconst handleSelectTab = (tab: string) => {\n selectedTab.value = tab;\n};\n\nconst isTabSelected = (tab: Tab) => {\n return tab.label === selectedTab.value ? true : null;\n};\n</script>\n\n<template>\n <ul\n data-testid=\"pv-tabs\"\n role=\"list\"\n :class=\"{\n 'pv-tab-list-small': size === 'lg',\n 'pv-tab-list': size === 'xl',\n }\"\n >\n <li\n v-for=\"tab in tabs\"\n :key=\"tab.label\"\n :data-active=\"isTabSelected(tab)\"\n data-testid=\"pv-tab\"\n type=\"button\"\n @click=\"() => handleSelectTab(tab.label)\"\n >\n <button type=\"button\">\n <PvIcon v-if=\"tab.icon\" :name=\"tab.icon\" />\n {{ tab.label }}\n <PvCounterBadge\n v-if=\"tab.counter\"\n :value=\"tab.counter\"\n :variant=\"isTabSelected(tab) ? 'primary' : 'tertiary'\"\n size=\"sm\"\n />\n </button>\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\">\nimport PvCounterBadge from \"../PvCounterBadge/PvCounterBadge.vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { Tab, TabSize } from \"./types\";\n\ninterface PvTabsProps {\n /** Array of tab objects defining each tab's label, icon, and counter */\n tabs: Tab[];\n /** Size of the tab list */\n size?: TabSize;\n}\n\nwithDefaults(defineProps<PvTabsProps>(), {\n size: \"lg\",\n});\n\nconst selectedTab = defineModel<string>({ required: true });\n\nconst handleSelectTab = (tab: string) => {\n selectedTab.value = tab;\n};\n\nconst isTabSelected = (tab: Tab) => {\n return tab.label === selectedTab.value ? true : null;\n};\n</script>\n\n<template>\n <ul\n data-testid=\"pv-tabs\"\n role=\"list\"\n :class=\"{\n 'pv-tab-list-small': size === 'lg',\n 'pv-tab-list': size === 'xl',\n }\"\n >\n <li\n v-for=\"tab in tabs\"\n :key=\"tab.label\"\n :data-active=\"isTabSelected(tab)\"\n data-testid=\"pv-tab\"\n type=\"button\"\n @click=\"() => handleSelectTab(tab.label)\"\n >\n <button type=\"button\">\n <PvIcon v-if=\"tab.icon\" :name=\"tab.icon\" />\n {{ tab.label }}\n <PvCounterBadge\n v-if=\"tab.counter\"\n :value=\"tab.counter\"\n :variant=\"isTabSelected(tab) ? 'primary' : 'tertiary'\"\n size=\"sm\"\n />\n </button>\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\">\nimport { PvBreadcrumbsOptions } from \"./types\";\n\ninterface PvBreadcrumbsProps {\n /** Array of breadcrumb items defining the navigation trail */\n options: PvBreadcrumbsOptions[];\n}\n\ndefineProps<PvBreadcrumbsProps>();\n</script>\n\n<template>\n <ul class=\"pv-breadcrumbs\" role=\"list\" data-testid=\"pv-breadcrumbs\">\n <li v-for=\"option in options\" :key=\"option.label\">\n <a v-if=\"option.href\" :href=\"option.href\">{{ option.label }}</a>\n <template v-else>{{ option.label }}</template>\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\">\nimport { PvBreadcrumbsOptions } from \"./types\";\n\ninterface PvBreadcrumbsProps {\n /** Array of breadcrumb items defining the navigation trail */\n options: PvBreadcrumbsOptions[];\n}\n\ndefineProps<PvBreadcrumbsProps>();\n</script>\n\n<template>\n <ul class=\"pv-breadcrumbs\" role=\"list\" data-testid=\"pv-breadcrumbs\">\n <li v-for=\"option in options\" :key=\"option.label\">\n <a v-if=\"option.href\" :href=\"option.href\">{{ option.label }}</a>\n <template v-else>{{ option.label }}</template>\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\">\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport { MenuActionsVariant } from \"@/components/base/PvMultiSelectButton/types.ts\";\n\ndefineProps<{\n variant?: MenuActionsVariant;\n disabled?: boolean;\n}>();\n\ndefineEmits<{\n (e: \"handle-select-all\"): void;\n (e: \"handle-clear-all\"): void;\n (e: \"handle-cancel\"): void;\n (e: \"handle-confirm\"): void;\n}>();\n</script>\n\n<template>\n <div data-testid=\"pv-select-menu-control-panel\" class=\"pv-flex pv-space-between\">\n <template v-if=\"variant === 'select-clear'\">\n <PvButton\n variant=\"ghost\"\n data-testid=\"pv-select-menu-item-select-all\"\n @click=\"$emit('handle-select-all')\"\n label=\"Select All\"\n :disabled=\"disabled\"\n />\n <PvButton\n label=\"Clear All\"\n variant=\"ghost\"\n data-testid=\"pv-select-menu-item-clear-all\"\n @click=\"$emit('handle-clear-all')\"\n :disabled=\"disabled\"\n />\n </template>\n <template v-else-if=\"variant === 'cancel-confirm'\">\n <PvButton\n label=\"Cancel\"\n variant=\"ghost\"\n data-testid=\"pv-select-menu-item-cancel\"\n @click=\"$emit('handle-cancel')\"\n :disabled=\"disabled\"\n />\n <PvButton\n label=\"Confirm\"\n data-testid=\"pv-select-menu-item-confirm\"\n @click=\"$emit('handle-confirm')\"\n :disabled=\"disabled\"\n />\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport { MenuActionsVariant } from \"@/components/base/PvMultiSelectButton/types.ts\";\n\ndefineProps<{\n variant?: MenuActionsVariant;\n disabled?: boolean;\n}>();\n\ndefineEmits<{\n (e: \"handle-select-all\"): void;\n (e: \"handle-clear-all\"): void;\n (e: \"handle-cancel\"): void;\n (e: \"handle-confirm\"): void;\n}>();\n</script>\n\n<template>\n <div data-testid=\"pv-select-menu-control-panel\" class=\"pv-flex pv-space-between\">\n <template v-if=\"variant === 'select-clear'\">\n <PvButton\n variant=\"ghost\"\n data-testid=\"pv-select-menu-item-select-all\"\n @click=\"$emit('handle-select-all')\"\n label=\"Select All\"\n :disabled=\"disabled\"\n />\n <PvButton\n label=\"Clear All\"\n variant=\"ghost\"\n data-testid=\"pv-select-menu-item-clear-all\"\n @click=\"$emit('handle-clear-all')\"\n :disabled=\"disabled\"\n />\n </template>\n <template v-else-if=\"variant === 'cancel-confirm'\">\n <PvButton\n label=\"Cancel\"\n variant=\"ghost\"\n data-testid=\"pv-select-menu-item-cancel\"\n @click=\"$emit('handle-cancel')\"\n :disabled=\"disabled\"\n />\n <PvButton\n label=\"Confirm\"\n data-testid=\"pv-select-menu-item-confirm\"\n @click=\"$emit('handle-confirm')\"\n :disabled=\"disabled\"\n />\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { PvIconSize } from \"../baseProps\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport type { PvAvatarProps, PvAvatarSize } from \"./types\";\n\nconst avatarSizeToClass: Record<PvAvatarSize, string> = {\n sm: \"pv-avatar-16\",\n md: \"pv-avatar-20\",\n lg: \"pv-avatar-xs\",\n xl: \"pv-avatar-sm\",\n \"2x\": \"pv-avatar-md\",\n};\n\nconst iconSizeToAvatarSize: Partial<Record<PvAvatarSize, PvIconSize>> = {\n sm: 10,\n md: 12,\n lg: undefined,\n xl: 20,\n \"2x\": 20,\n};\n\nwithDefaults(defineProps<PvAvatarProps>(), {\n shape: \"circle\",\n size: \"lg\",\n});\n</script>\n\n<template>\n <div :class=\"avatarSizeToClass[size]\" data-testid=\"pv-avatar\" :data-style=\"variant\" :data-shape=\"shape\">\n <PvIcon v-if=\"icon\" :name=\"icon\" :size=\"iconSizeToAvatarSize[size]\" />\n <template v-else-if=\"initials\">{{ initials }}</template>\n <template v-else-if=\"image\">\n <img :src=\"image\" :alt=\"alt ?? ''\" />\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { PvIconSize } from \"../baseProps\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport type { PvAvatarProps, PvAvatarSize } from \"./types\";\n\nconst avatarSizeToClass: Record<PvAvatarSize, string> = {\n sm: \"pv-avatar-16\",\n md: \"pv-avatar-20\",\n lg: \"pv-avatar-xs\",\n xl: \"pv-avatar-sm\",\n \"2x\": \"pv-avatar-md\",\n};\n\nconst iconSizeToAvatarSize: Partial<Record<PvAvatarSize, PvIconSize>> = {\n sm: 10,\n md: 12,\n lg: undefined,\n xl: 20,\n \"2x\": 20,\n};\n\nwithDefaults(defineProps<PvAvatarProps>(), {\n shape: \"circle\",\n size: \"lg\",\n});\n</script>\n\n<template>\n <div :class=\"avatarSizeToClass[size]\" data-testid=\"pv-avatar\" :data-style=\"variant\" :data-shape=\"shape\">\n <PvIcon v-if=\"icon\" :name=\"icon\" :size=\"iconSizeToAvatarSize[size]\" />\n <template v-else-if=\"initials\">{{ initials }}</template>\n <template v-else-if=\"image\">\n <img :src=\"image\" :alt=\"alt ?? ''\" />\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../../PvIcon/PvIcon.vue\";\nimport PvCounterBadge from \"../../PvCounterBadge/PvCounterBadge.vue\";\nimport PvCompanyLogo from \"../../PvCompanyLogo/PvCompanyLogo.vue\";\nimport PvAvatar from \"../../PvAvatar/PvAvatar.vue\";\nimport PvTooltip from \"../../PvTooltip/PvTooltip.vue\";\nimport { computed } from \"vue\";\nimport { pvButtonSizeToClass, supportedInverseButtonVariants } from \"@/components/base/PvButton/helpers.ts\";\nimport type { PvSelectButtonTriggerProps } from \"./types\";\n\nconst props = withDefaults(defineProps<PvSelectButtonTriggerProps>(), {\n size: \"lg\",\n variant: \"secondary\",\n showDropdown: true,\n counterStyle: \"primary\",\n});\n\ndefineEmits<{\n (e: \"handle-clear\"): void;\n}>();\n\nconst classes = computed(() => {\n const output = [\"pv-flex\", \"pv-space-between\", \"pv-full-width\"];\n if (props.inverse && supportedInverseButtonVariants.includes(props.variant)) {\n output.push(`pv-button-${props.variant}-inverse`);\n } else {\n output.push(`pv-button-${props.variant}`);\n }\n const sizeClass = pvButtonSizeToClass(props.size);\n if (sizeClass) {\n output.push(sizeClass);\n }\n return output;\n});\n\nconst labelValue = computed(() => {\n if (props.isLoading) {\n return \"Loading...\";\n }\n\n if (props.selectedItems && props.selectedItems.length > 0 && props.counterStyle === \"secondary\") {\n return props.selectedItems[0].text;\n }\n\n return props.label;\n});\n\nconst rendererProps = computed(() => {\n if (!props.selectedOption) return undefined;\n\n return {\n ...props.selectedOption,\n menuOptionConfig: props.menuOptionConfig,\n queryText: null,\n selected: true,\n };\n});\n</script>\n\n<template>\n <button\n data-testid=\"pv-multi-select-button-trigger\"\n :class=\"classes\"\n style=\"--flex-gap: 0.25rem\"\n :disabled=\"disabled || isLoading\"\n >\n <div class=\"pv-flex\">\n <p\n data-testid=\"pv-select-prefix-label\"\n v-if=\"prefixLabel\"\n class=\"pv-border-right pv-text-quaternary\"\n style=\"padding-right: 4px\"\n >\n {{ prefixLabel }}\n </p>\n <PvCounterBadge\n v-if=\"counterPosition === 'left' && counterValue && counterStyle === 'primary'\"\n data-testid=\"pv-multi-select-left-counter-badge\"\n :value=\"counterValue\"\n :variant=\"counterBadgeVariant\"\n size=\"sm\"\n />\n <template v-if=\"!isLoading && renderer && rendererProps\">\n <component :is=\"renderer\" v-bind=\"rendererProps\" />\n </template>\n <template v-else>\n <PvIcon v-if=\"icon\" data-testid=\"pv-multi-select-button-icon\" :name=\"icon\" />\n <PvCompanyLogo v-if=\"companyLogo\" :name=\"companyLogo\" size=\"sm\" />\n <PvAvatar\n v-if=\"avatar\"\n class=\"pv-select-button-trigger-avatar\"\n data-testid=\"pv-multi-select-button-avatar\"\n :initials=\"avatar.initials\"\n :image=\"avatar.image\"\n :variant=\"avatar.variant\"\n :shape=\"avatar.shape\"\n size=\"sm\"\n />\n <span v-if=\"isLoading || label\">\n {{ labelValue }}\n </span>\n </template>\n <PvCounterBadge\n v-if=\"counterPosition === 'right' && counterValue && counterStyle === 'primary'\"\n data-testid=\"pv-multi-select-right-counter-badge\"\n :value=\"counterValue\"\n :variant=\"counterBadgeVariant\"\n size=\"sm\"\n />\n <PvCounterBadge\n v-if=\"counterStyle === 'secondary' && (counterValue ?? 0) >= 2\"\n data-testid=\"pv-multi-select-secondary-counter-badge\"\n prefix=\"+\"\n :value=\"(counterValue ?? 0) - 1\"\n variant=\"tertiary\"\n size=\"sm\"\n />\n </div>\n\n <PvIcon v-if=\"showDropdown\" :name=\"open ? 'chevron-up' : 'chevron-down'\" />\n <PvTooltip v-if=\"showClear\" size=\"sm\" variant=\"dark\" tooltip-position=\"top-left\">\n <template #label>\n <PvIcon name=\"close\" @click.stop=\"$emit('handle-clear')\" />\n </template>\n <template #tooltip-content> Clear Selections </template>\n </PvTooltip>\n </button>\n</template>\n\n<style scoped>\n.pv-select-button-trigger-avatar {\n font-size: 0.5rem;\n font-weight: 700;\n}\n</style>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../../PvIcon/PvIcon.vue\";\nimport PvCounterBadge from \"../../PvCounterBadge/PvCounterBadge.vue\";\nimport PvCompanyLogo from \"../../PvCompanyLogo/PvCompanyLogo.vue\";\nimport PvAvatar from \"../../PvAvatar/PvAvatar.vue\";\nimport PvTooltip from \"../../PvTooltip/PvTooltip.vue\";\nimport { computed } from \"vue\";\nimport { pvButtonSizeToClass, supportedInverseButtonVariants } from \"@/components/base/PvButton/helpers.ts\";\nimport type { PvSelectButtonTriggerProps } from \"./types\";\n\nconst props = withDefaults(defineProps<PvSelectButtonTriggerProps>(), {\n size: \"lg\",\n variant: \"secondary\",\n showDropdown: true,\n counterStyle: \"primary\",\n});\n\ndefineEmits<{\n (e: \"handle-clear\"): void;\n}>();\n\nconst classes = computed(() => {\n const output = [\"pv-flex\", \"pv-space-between\", \"pv-full-width\"];\n if (props.inverse && supportedInverseButtonVariants.includes(props.variant)) {\n output.push(`pv-button-${props.variant}-inverse`);\n } else {\n output.push(`pv-button-${props.variant}`);\n }\n const sizeClass = pvButtonSizeToClass(props.size);\n if (sizeClass) {\n output.push(sizeClass);\n }\n return output;\n});\n\nconst labelValue = computed(() => {\n if (props.isLoading) {\n return \"Loading...\";\n }\n\n if (props.selectedItems && props.selectedItems.length > 0 && props.counterStyle === \"secondary\") {\n return props.selectedItems[0].text;\n }\n\n return props.label;\n});\n\nconst rendererProps = computed(() => {\n if (!props.selectedOption) return undefined;\n\n return {\n ...props.selectedOption,\n menuOptionConfig: props.menuOptionConfig,\n queryText: null,\n selected: true,\n };\n});\n</script>\n\n<template>\n <button\n data-testid=\"pv-multi-select-button-trigger\"\n :class=\"classes\"\n style=\"--flex-gap: 0.25rem\"\n :disabled=\"disabled || isLoading\"\n >\n <div class=\"pv-flex\">\n <p\n data-testid=\"pv-select-prefix-label\"\n v-if=\"prefixLabel\"\n class=\"pv-border-right pv-text-quaternary\"\n style=\"padding-right: 4px\"\n >\n {{ prefixLabel }}\n </p>\n <PvCounterBadge\n v-if=\"counterPosition === 'left' && counterValue && counterStyle === 'primary'\"\n data-testid=\"pv-multi-select-left-counter-badge\"\n :value=\"counterValue\"\n :variant=\"counterBadgeVariant\"\n size=\"sm\"\n />\n <template v-if=\"!isLoading && renderer && rendererProps\">\n <component :is=\"renderer\" v-bind=\"rendererProps\" />\n </template>\n <template v-else>\n <PvIcon v-if=\"icon\" data-testid=\"pv-multi-select-button-icon\" :name=\"icon\" />\n <PvCompanyLogo v-if=\"companyLogo\" :name=\"companyLogo\" size=\"sm\" />\n <PvAvatar\n v-if=\"avatar\"\n class=\"pv-select-button-trigger-avatar\"\n data-testid=\"pv-multi-select-button-avatar\"\n :initials=\"avatar.initials\"\n :image=\"avatar.image\"\n :variant=\"avatar.variant\"\n :shape=\"avatar.shape\"\n size=\"sm\"\n />\n <span v-if=\"isLoading || label\">\n {{ labelValue }}\n </span>\n </template>\n <PvCounterBadge\n v-if=\"counterPosition === 'right' && counterValue && counterStyle === 'primary'\"\n data-testid=\"pv-multi-select-right-counter-badge\"\n :value=\"counterValue\"\n :variant=\"counterBadgeVariant\"\n size=\"sm\"\n />\n <PvCounterBadge\n v-if=\"counterStyle === 'secondary' && (counterValue ?? 0) >= 2\"\n data-testid=\"pv-multi-select-secondary-counter-badge\"\n prefix=\"+\"\n :value=\"(counterValue ?? 0) - 1\"\n variant=\"tertiary\"\n size=\"sm\"\n />\n </div>\n\n <PvIcon v-if=\"showDropdown\" :name=\"open ? 'chevron-up' : 'chevron-down'\" />\n <PvTooltip v-if=\"showClear\" size=\"sm\" variant=\"dark\" tooltip-position=\"top-left\">\n <template #label>\n <PvIcon name=\"close\" @click.stop=\"$emit('handle-clear')\" />\n </template>\n <template #tooltip-content> Clear Selections </template>\n </PvTooltip>\n </button>\n</template>\n\n<style scoped>\n.pv-select-button-trigger-avatar {\n font-size: 0.5rem;\n font-weight: 700;\n}\n</style>\n","<template>\n <div class=\"pv-text-subdued pv-text-center pv-text-body-md pv-inset-square-12\">No Results Found</div>\n</template>\n","import type { MenuOption, MultiSelectState } from \"@/types\";\n\n/**\n * Returns true when an option has children, whether they are already loaded or\n * only represented by the server-provided `totalChildCount` for lazy-loading.\n * Fully loaded children still count as cascade children — this helper answers\n * \"is this a parent?\", not \"are there more children to load?\".\n */\nexport function hasCascadeChildren<T>(option: MenuOption<T>): boolean {\n return !!option.children?.length || (option.totalChildCount ?? 0) > 0;\n}\n\n/** Recursively collect all leaf (childless) options from a tree. */\nexport function collectLeafOptions<T>(options: MenuOption<T>[]): MenuOption<T>[] {\n return options.flatMap((option) => {\n if (option.children?.length) return collectLeafOptions(option.children);\n return (option.totalChildCount ?? 0) > 0 ? [] : [option];\n });\n}\n\n/**\n * Merge two sets of leaf options, deduplicating by ID.\n *\n * Returns a single array containing every leaf from `base`, plus any leaves\n * from `overlay` whose ID doesn't already appear in `base`. This is used to\n * combine original (unfiltered) leaves with dynamically loaded (see-more)\n * leaves so that the full set is available for selection / checked-state logic.\n */\nexport function mergeLeafOptions<T>(base: MenuOption<T>[], overlay: MenuOption<T>[]): MenuOption<T>[] {\n const seenIds = new Set(base.map((l) => l.id));\n const extras = overlay.filter((l) => !seenIds.has(l.id));\n return extras.length > 0 ? [...base, ...extras] : base;\n}\n\n/**\n * Count selected items, collapsing fully-selected parents to 1.\n *\n * Walks the option tree bottom-up. A parent whose leaf descendants are ALL\n * selected counts as 1 (replacing the individual counts of its sub-tree).\n * Selected leaves not under a fully-selected parent each count as 1.\n *\n * This is order-independent — it walks the tree structure directly and does\n * not depend on Map iteration order.\n */\nexport function countWithCollapsedParents<T>(options: MenuOption<T>[], selectedIds: Set<string>): number {\n const walk = (nodes: MenuOption<T>[]): { leafCount: number; selectedLeafCount: number; displayCount: number } => {\n let leafCount = 0;\n let selectedLeafCount = 0;\n let displayCount = 0;\n\n for (const node of nodes) {\n if (node.children?.length) {\n const sub = walk(node.children);\n leafCount += sub.leafCount;\n selectedLeafCount += sub.selectedLeafCount;\n if (sub.leafCount > 0 && sub.leafCount === sub.selectedLeafCount) {\n displayCount += 1;\n } else {\n displayCount += sub.displayCount;\n }\n } else {\n leafCount += 1;\n if (selectedIds.has(node.id)) {\n selectedLeafCount += 1;\n displayCount += 1;\n }\n }\n }\n\n return { leafCount, selectedLeafCount, displayCount };\n };\n\n return walk(options).displayCount;\n}\n\nexport function countFromSelectionState(state: MultiSelectState): number {\n return state.filter((node) => node.state === \"selected\").length;\n}\n\n/**\n * Recursively filter a tree for a search value.\n *\n * - If a node's own text matches, it is kept with all its children intact.\n * - If a node's own text does NOT match but one or more of its descendants do,\n * the node is kept as a container showing only the matching descendants.\n * This means a search term that matches a child will surface that child even\n * when the parent label itself doesn't contain the search term.\n * - Nodes with no match anywhere in their subtree are removed entirely.\n */\nexport function filterOptionsRecursive<T>(\n options: MenuOption<T>[],\n searchValue: string,\n showParentOnChildQueryMatch = true,\n): MenuOption<T>[] {\n return options.flatMap((option) => {\n const selfMatches =\n option.text.toLocaleLowerCase().includes(searchValue) ||\n option.searchText?.toLocaleLowerCase().includes(searchValue);\n\n if (selfMatches) return [option]; // keep with all children intact\n\n if (option.children?.length) {\n const filteredChildren = filterOptionsRecursive(option.children, searchValue, showParentOnChildQueryMatch);\n if (filteredChildren.length) {\n return showParentOnChildQueryMatch ? [{ ...option, children: filteredChildren }] : filteredChildren;\n }\n }\n\n return [];\n });\n}\n","<script setup lang=\"ts\">\nimport PvCompanyLogo from \"@/components/base/PvCompanyLogo/PvCompanyLogo.vue\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport PvAvatar from \"@/components/base/PvAvatar/PvAvatar.vue\";\nimport PvCounterBadge from \"@/components/base/PvCounterBadge/PvCounterBadge.vue\";\nimport type { MenuOption, MenuOptionConfig } from \"@/types.ts\";\nimport { computed, onMounted, ref, watch } from \"vue\";\n\ndefineOptions({\n inheritAttrs: false,\n});\n\ninterface PvMenuBaseItemProps extends MenuOption {\n menuOptionConfig?: MenuOptionConfig;\n queryText?: string | null;\n}\n\nconst props = defineProps<PvMenuBaseItemProps>();\n\nconst mainText = ref<HTMLElement | null>(null);\nconst subText = ref<HTMLElement | null>(null);\n\nconst renderedSubText = computed(() => {\n return props.subText || null;\n});\n\nconst escapeRegex = (str: string): string => {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n};\n\nconst highlightText = (element: HTMLElement, originalText: string, searchQuery: string) => {\n const escapedSearch = escapeRegex(searchQuery);\n const regex = new RegExp(`(${escapedSearch})`, \"gi\");\n element.innerHTML = originalText.replace(\n regex,\n '<span data-test-id=\"pv-matched-text\" style=\"font-weight: bold;\">$1</span>',\n );\n};\n\nconst applyHighlight = () => {\n if (props.queryText) {\n const mainTextMatches = new RegExp(escapeRegex(props.queryText), \"gi\").test(props.text);\n if (mainText.value) {\n highlightText(mainText.value, props.text, props.queryText);\n }\n if (subText.value && renderedSubText.value) {\n if (mainTextMatches) {\n subText.value.textContent = renderedSubText.value;\n } else {\n highlightText(subText.value, renderedSubText.value, props.queryText);\n }\n }\n } else {\n if (mainText.value) {\n mainText.value.textContent = props.text;\n }\n if (subText.value && renderedSubText.value) {\n subText.value.textContent = renderedSubText.value;\n }\n }\n};\n\nonMounted(() => {\n applyHighlight();\n});\n\nwatch(\n () => props.queryText,\n () => {\n applyHighlight();\n },\n);\n</script>\n\n<template>\n <PvAvatar\n v-if=\"avatar\"\n :initials=\"avatar.initials\"\n :image=\"avatar.image\"\n :variant=\"avatar.variant\"\n :shape=\"avatar.shape\"\n size=\"lg\"\n />\n <PvIcon :class=\"{ 'pv-text-subdued': !disabled }\" v-if=\"icon\" :name=\"icon\" />\n <PvCompanyLogo v-if=\"companyName\" :name=\"companyName\" size=\"sm\" />\n <div class=\"pv-full-width pv-truncate pv-flex-vertical\" style=\"align-items: flex-start; --flex-gap: 0\">\n <span class=\"pv-text-body-md pv-full-width pv-truncate\" :title=\"text\">\n <span ref=\"mainText\">{{ text }}</span>\n <span v-if=\"subduedText\" :class=\"{ 'pv-text-subdued': !disabled }\" style=\"padding-left: 4px\">\n {{ subduedText }}\n </span>\n </span>\n <span\n ref=\"subText\"\n v-if=\"renderedSubText\"\n :class=\"['pv-text-body-xs', 'pv-full-width', 'pv-truncate', { 'pv-text-subdued': !disabled }]\"\n :title=\"renderedSubText\"\n >\n {{ renderedSubText }}\n </span>\n </div>\n <PvCounterBadge\n v-if=\"secondaryText && typeof secondaryText === 'number'\"\n :value=\"secondaryText\"\n :variant=\"menuOptionConfig?.counterBadgeVariant\"\n />\n <span v-else-if=\"secondaryText && typeof secondaryText === 'string'\" class=\"pv-text-subdued pv-text-body-md\">{{\n secondaryText\n }}</span>\n</template>\n","<script setup lang=\"ts\">\nimport PvCompanyLogo from \"@/components/base/PvCompanyLogo/PvCompanyLogo.vue\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport PvAvatar from \"@/components/base/PvAvatar/PvAvatar.vue\";\nimport PvCounterBadge from \"@/components/base/PvCounterBadge/PvCounterBadge.vue\";\nimport type { MenuOption, MenuOptionConfig } from \"@/types.ts\";\nimport { computed, onMounted, ref, watch } from \"vue\";\n\ndefineOptions({\n inheritAttrs: false,\n});\n\ninterface PvMenuBaseItemProps extends MenuOption {\n menuOptionConfig?: MenuOptionConfig;\n queryText?: string | null;\n}\n\nconst props = defineProps<PvMenuBaseItemProps>();\n\nconst mainText = ref<HTMLElement | null>(null);\nconst subText = ref<HTMLElement | null>(null);\n\nconst renderedSubText = computed(() => {\n return props.subText || null;\n});\n\nconst escapeRegex = (str: string): string => {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n};\n\nconst highlightText = (element: HTMLElement, originalText: string, searchQuery: string) => {\n const escapedSearch = escapeRegex(searchQuery);\n const regex = new RegExp(`(${escapedSearch})`, \"gi\");\n element.innerHTML = originalText.replace(\n regex,\n '<span data-test-id=\"pv-matched-text\" style=\"font-weight: bold;\">$1</span>',\n );\n};\n\nconst applyHighlight = () => {\n if (props.queryText) {\n const mainTextMatches = new RegExp(escapeRegex(props.queryText), \"gi\").test(props.text);\n if (mainText.value) {\n highlightText(mainText.value, props.text, props.queryText);\n }\n if (subText.value && renderedSubText.value) {\n if (mainTextMatches) {\n subText.value.textContent = renderedSubText.value;\n } else {\n highlightText(subText.value, renderedSubText.value, props.queryText);\n }\n }\n } else {\n if (mainText.value) {\n mainText.value.textContent = props.text;\n }\n if (subText.value && renderedSubText.value) {\n subText.value.textContent = renderedSubText.value;\n }\n }\n};\n\nonMounted(() => {\n applyHighlight();\n});\n\nwatch(\n () => props.queryText,\n () => {\n applyHighlight();\n },\n);\n</script>\n\n<template>\n <PvAvatar\n v-if=\"avatar\"\n :initials=\"avatar.initials\"\n :image=\"avatar.image\"\n :variant=\"avatar.variant\"\n :shape=\"avatar.shape\"\n size=\"lg\"\n />\n <PvIcon :class=\"{ 'pv-text-subdued': !disabled }\" v-if=\"icon\" :name=\"icon\" />\n <PvCompanyLogo v-if=\"companyName\" :name=\"companyName\" size=\"sm\" />\n <div class=\"pv-full-width pv-truncate pv-flex-vertical\" style=\"align-items: flex-start; --flex-gap: 0\">\n <span class=\"pv-text-body-md pv-full-width pv-truncate\" :title=\"text\">\n <span ref=\"mainText\">{{ text }}</span>\n <span v-if=\"subduedText\" :class=\"{ 'pv-text-subdued': !disabled }\" style=\"padding-left: 4px\">\n {{ subduedText }}\n </span>\n </span>\n <span\n ref=\"subText\"\n v-if=\"renderedSubText\"\n :class=\"['pv-text-body-xs', 'pv-full-width', 'pv-truncate', { 'pv-text-subdued': !disabled }]\"\n :title=\"renderedSubText\"\n >\n {{ renderedSubText }}\n </span>\n </div>\n <PvCounterBadge\n v-if=\"secondaryText && typeof secondaryText === 'number'\"\n :value=\"secondaryText\"\n :variant=\"menuOptionConfig?.counterBadgeVariant\"\n />\n <span v-else-if=\"secondaryText && typeof secondaryText === 'string'\" class=\"pv-text-subdued pv-text-body-md\">{{\n secondaryText\n }}</span>\n</template>\n","<script setup lang=\"ts\">\nimport { useId } from \"vue\";\nimport { PvSwitchSize } from \"./types\";\n\ninterface PvSwitchProps {\n /**\n * The visual size of the switch track and thumb.\n */\n size?: PvSwitchSize;\n /** Optional text label displayed next to the switch. */\n label?: string;\n /** Accessible name for the switch when no visible label is provided. */\n ariaLabel?: string;\n /** When true, the switch is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** HTML id for the underlying checkbox input. Auto-generated when omitted. */\n id?: string;\n /**\n * When true, hides the checkmark icon inside the switch thumb.\n */\n hideCheckIcon?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvSwitchProps>(), {\n size: \"md\",\n disabled: false,\n hideCheckIcon: false,\n});\n\nconst inputId = props.id ?? useId();\n\nconst value = defineModel<boolean>({ required: true });\n</script>\n\n<template>\n <label\n :for=\"inputId\"\n :class=\"[\n 'pv-label pv-switch pv-label-hover',\n {\n 'pv-input-small': size === 'md',\n 'pv-input-xsmall': size === 'sm',\n 'pv-switch-hide-check': hideCheckIcon,\n },\n ]\"\n >\n <span v-if=\"label\">{{ label }}</span>\n <input v-model=\"value\" :disabled=\"disabled\" :aria-label=\"ariaLabel\" type=\"checkbox\" role=\"switch\" :id=\"inputId\" />\n </label>\n</template>\n\n<style scoped>\n.pv-switch-hide-check :deep(input[type=\"checkbox\"]:checked:after),\n.pv-switch-hide-check :deep(input[type=\"checkbox\"]:checked:not(:disabled):hover:after),\n.pv-switch-hide-check :deep(input[type=\"checkbox\"]:checked:not(:disabled):focus-visible:after),\n.pv-switch-hide-check :deep(input[type=\"checkbox\"]:checked:not(:disabled):active:after),\n.pv-switch-hide-check :deep(input[type=\"checkbox\"]:checked:disabled:after) {\n background-image: unset;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { useId } from \"vue\";\nimport { PvSwitchSize } from \"./types\";\n\ninterface PvSwitchProps {\n /**\n * The visual size of the switch track and thumb.\n */\n size?: PvSwitchSize;\n /** Optional text label displayed next to the switch. */\n label?: string;\n /** Accessible name for the switch when no visible label is provided. */\n ariaLabel?: string;\n /** When true, the switch is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** HTML id for the underlying checkbox input. Auto-generated when omitted. */\n id?: string;\n /**\n * When true, hides the checkmark icon inside the switch thumb.\n */\n hideCheckIcon?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvSwitchProps>(), {\n size: \"md\",\n disabled: false,\n hideCheckIcon: false,\n});\n\nconst inputId = props.id ?? useId();\n\nconst value = defineModel<boolean>({ required: true });\n</script>\n\n<template>\n <label\n :for=\"inputId\"\n :class=\"[\n 'pv-label pv-switch pv-label-hover',\n {\n 'pv-input-small': size === 'md',\n 'pv-input-xsmall': size === 'sm',\n 'pv-switch-hide-check': hideCheckIcon,\n },\n ]\"\n >\n <span v-if=\"label\">{{ label }}</span>\n <input v-model=\"value\" :disabled=\"disabled\" :aria-label=\"ariaLabel\" type=\"checkbox\" role=\"switch\" :id=\"inputId\" />\n </label>\n</template>\n\n<style scoped>\n.pv-switch-hide-check :deep(input[type=\"checkbox\"]:checked:after),\n.pv-switch-hide-check :deep(input[type=\"checkbox\"]:checked:not(:disabled):hover:after),\n.pv-switch-hide-check :deep(input[type=\"checkbox\"]:checked:not(:disabled):focus-visible:after),\n.pv-switch-hide-check :deep(input[type=\"checkbox\"]:checked:not(:disabled):active:after),\n.pv-switch-hide-check :deep(input[type=\"checkbox\"]:checked:disabled:after) {\n background-image: unset;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport PvTooltipV2 from \"@/components/base/PvTooltipV2/PvTooltipV2.vue\";\nimport { MenuAction, MenuOption } from \"@/types\";\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\n\ninterface PvMenuItemActionProps {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n action: MenuAction<any>;\n option: MenuOption;\n}\n\nconst props = defineProps<PvMenuItemActionProps>();\n\nconst actionIcon = computed(() => {\n return typeof props.action.icon === \"function\" ? props.action.icon(props.option) : props.action.icon;\n});\n\nconst actionDisabled = computed(() => {\n return typeof props.action.isDisabled === \"function\"\n ? props.action.isDisabled(props.option)\n : props.action.isDisabled;\n});\n\nconst actionTooltip = computed(() => {\n return typeof props.action.tooltipText === \"function\"\n ? props.action.tooltipText(props.option)\n : props.action.tooltipText;\n});\n\nconst alwaysShow = computed(() => {\n return typeof props.action.alwaysShow === \"function\"\n ? props.action.alwaysShow(props.option)\n : props.action.alwaysShow;\n});\n\nconst handleActionClick = () => {\n if (!actionDisabled.value) {\n props.action.action(props.option);\n }\n};\n</script>\n<template>\n <PvTooltipV2 :disableInteractive=\"true\" :useTeleport=\"true\" variant=\"white\">\n <template #trigger>\n <PvButton\n variant=\"ghost\"\n class=\"pv-text-brand\"\n :leftIcon=\"actionIcon\"\n :class=\"{ 'pv-menu-action-button': !alwaysShow }\"\n @click.stop=\"handleActionClick\"\n :disabled=\"actionDisabled\"\n />\n </template>\n <template #content v-if=\"actionTooltip\">\n <div>\n {{ actionTooltip }}\n </div>\n </template>\n </PvTooltipV2>\n</template>\n\n<style scoped>\n.pv-menu-action-button {\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.pv-label:hover .pv-menu-action-button {\n opacity: 1;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport PvTooltipV2 from \"@/components/base/PvTooltipV2/PvTooltipV2.vue\";\nimport { MenuAction, MenuOption } from \"@/types\";\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\n\ninterface PvMenuItemActionProps {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n action: MenuAction<any>;\n option: MenuOption;\n}\n\nconst props = defineProps<PvMenuItemActionProps>();\n\nconst actionIcon = computed(() => {\n return typeof props.action.icon === \"function\" ? props.action.icon(props.option) : props.action.icon;\n});\n\nconst actionDisabled = computed(() => {\n return typeof props.action.isDisabled === \"function\"\n ? props.action.isDisabled(props.option)\n : props.action.isDisabled;\n});\n\nconst actionTooltip = computed(() => {\n return typeof props.action.tooltipText === \"function\"\n ? props.action.tooltipText(props.option)\n : props.action.tooltipText;\n});\n\nconst alwaysShow = computed(() => {\n return typeof props.action.alwaysShow === \"function\"\n ? props.action.alwaysShow(props.option)\n : props.action.alwaysShow;\n});\n\nconst handleActionClick = () => {\n if (!actionDisabled.value) {\n props.action.action(props.option);\n }\n};\n</script>\n<template>\n <PvTooltipV2 :disableInteractive=\"true\" :useTeleport=\"true\" variant=\"white\">\n <template #trigger>\n <PvButton\n variant=\"ghost\"\n class=\"pv-text-brand\"\n :leftIcon=\"actionIcon\"\n :class=\"{ 'pv-menu-action-button': !alwaysShow }\"\n @click.stop=\"handleActionClick\"\n :disabled=\"actionDisabled\"\n />\n </template>\n <template #content v-if=\"actionTooltip\">\n <div>\n {{ actionTooltip }}\n </div>\n </template>\n </PvTooltipV2>\n</template>\n\n<style scoped>\n.pv-menu-action-button {\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.pv-label:hover .pv-menu-action-button {\n opacity: 1;\n}\n</style>\n","import type { ComputedRef, InjectionKey, Ref } from \"vue\";\nimport type { MenuOption } from \"@/types\";\n\nexport const SelectedItemsKey: InjectionKey<Ref<MenuOption[]>> = Symbol(\"SelectedItemsKey\");\nexport const EnableCascadeSelectionKey: InjectionKey<ComputedRef<boolean>> = Symbol(\"EnableCascadeSelectionKey\");\nexport const OriginalOptionsMapKey: InjectionKey<ComputedRef<Map<string, MenuOption>>> = Symbol(\n \"OriginalOptionsMapKey\",\n);\nexport const CascadeSelectedParentIdsKey: InjectionKey<Ref<Set<string>>> = Symbol(\"CascadeSelectedParentIdsKey\");\nexport const CascadeDeselectedChildIdsKey: InjectionKey<Ref<Map<string, Set<string>>>> = Symbol(\n \"CascadeDeselectedChildIdsKey\",\n);\nexport const ParentSelectsAllChildrenKey: InjectionKey<ComputedRef<boolean>> = Symbol(\"ParentSelectsAllChildrenKey\");\nexport const EnableChildExpansionKey: InjectionKey<ComputedRef<boolean>> = Symbol(\"EnableChildExpansionKey\");\n","<script lang=\"ts\" setup>\nimport { computed, getCurrentInstance, inject, nextTick, ref, useTemplateRef } from \"vue\";\n\nimport PvMenuBaseItem from \"@/components/base/PvMenu/items/PvMenuBaseItem.vue\";\nimport PvSwitch from \"@/components/base/PvSwitch/PvSwitch.vue\";\nimport { MenuOption, MenuOptionConfig, MenuOptionSelectedEvent } from \"@/types.ts\";\nimport PvMenuItemAction from \"@/components/base/PvMenu/items/PvMenuItemAction.vue\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport { collectLeafOptions, hasCascadeChildren, mergeLeafOptions } from \"@/components/base/PvMenu/cascadeUtils\";\nimport {\n SelectedItemsKey,\n EnableCascadeSelectionKey,\n OriginalOptionsMapKey,\n CascadeSelectedParentIdsKey,\n} from \"@/components/base/PvMenu/symbols\";\n\nexport interface PvMenuItemVariantProps extends MenuOption {\n selected?: boolean;\n indeterminate?: boolean;\n queryText?: string | null;\n highlightSearchText?: boolean;\n menuOptionConfig?: MenuOptionConfig;\n showChevron?: boolean;\n chevronIcon?: string;\n expanded?: boolean;\n}\n\nconst props = defineProps<PvMenuItemVariantProps>();\n\nconst inputRef = useTemplateRef<HTMLInputElement>(\"inputRef\");\n\nconst selectedItems = inject(SelectedItemsKey, undefined);\nconst enableCascadeSelection = inject(EnableCascadeSelectionKey, ref(false));\nconst originalOptionsMap = inject(OriginalOptionsMapKey, undefined);\nconst cascadeSelectedParentIds = inject(CascadeSelectedParentIdsKey, undefined);\n\n// Resolve the effective leaf options for this parent node. Always use original\n// (unfiltered) children so the checked/indeterminate state reflects all children.\n// When children have been dynamically loaded (see-more), props.children may have\n// more entries than the original snapshot — use whichever is larger.\nconst effectiveLeafOptions = computed(() => {\n if (!enableCascadeSelection.value || !hasCascadeChildren(props)) return [];\n const currentLeaves = props.children ? collectLeafOptions(props.children) : [];\n if (originalOptionsMap?.value) {\n const originalOption = originalOptionsMap.value.get(props.id);\n const originalLeaves = originalOption?.children ? collectLeafOptions(originalOption.children) : [];\n return mergeLeafOptions(originalLeaves, currentLeaves);\n }\n return currentLeaves;\n});\n\nconst isChecked = computed(() => {\n if (!selectedItems?.value) return props.selected ?? false;\n if (enableCascadeSelection.value && hasCascadeChildren(props)) {\n const leafOptions = effectiveLeafOptions.value;\n const originalLeafCount = leafOptions.length;\n const selectedCount = leafOptions.filter((lo) => selectedItems.value.some((item) => item.id === lo.id)).length;\n // Parent was explicitly clicked and all loaded children are selected → checked\n if (cascadeSelectedParentIds?.value?.has(props.id) && selectedCount >= originalLeafCount) {\n return true;\n }\n const totalCount = props.totalChildCount ?? originalLeafCount;\n return totalCount > 0 && selectedCount >= totalCount;\n }\n return selectedItems.value.some((item) => item.id === props.id);\n});\n\nconst isIndeterminate = computed(() => {\n if (!selectedItems?.value || !enableCascadeSelection.value || !hasCascadeChildren(props)) {\n return props.indeterminate ?? false;\n }\n const leafOptions = effectiveLeafOptions.value;\n const originalLeafCount = leafOptions.length;\n const selectedCount = leafOptions.filter((lo) => selectedItems.value.some((item) => item.id === lo.id)).length;\n // Parent was explicitly clicked and all loaded children are selected → not indeterminate\n if (cascadeSelectedParentIds?.value?.has(props.id) && selectedCount >= originalLeafCount) {\n return false;\n }\n const totalCount = props.totalChildCount ?? originalLeafCount;\n return selectedCount > 0 && selectedCount < totalCount;\n});\n\nconst computedClassList = computed(() => {\n const classes = props.classList ? [...props.classList] : [];\n if (props.disabled) {\n classes.push(\"pv-menu-item-disabled\");\n } else {\n classes.push(\"pv-menu-item\");\n }\n return classes;\n});\n\nconst disabledStyle = computed(() => {\n if (props.disabled && props.menuOptionConfig?.disabledVariant !== \"ghost\") {\n return { background: \"#ececec\" };\n }\n return {};\n});\n\nconst computedOption = computed(() => {\n const option: MenuOption = {\n ...props,\n avatar: props.menuOptionConfig?.variant === \"avatar\" ? props.avatar : undefined,\n icon: props.menuOptionConfig?.variant === \"icon\" ? props.icon : undefined,\n companyName: props.menuOptionConfig?.variant === \"company\" ? props.companyName || props.text : undefined,\n };\n return option;\n});\n\nconst inputHidden = computed(() => {\n const variant = props.menuOptionConfig?.variant;\n return variant !== \"checkbox\" && variant !== \"radio\";\n});\n\n// we only show the input for checkbox and radio variants\nconst inputType = computed(() => {\n return props.menuOptionConfig?.variant === \"radio\" ? \"radio\" : \"checkbox\";\n});\n\nconst inputName = `${inputType.value}-${getCurrentInstance()?.uid}`;\n\nconst inputClass = computed(() => {\n return props.menuOptionConfig?.variant === \"checkbox\" ? \"pv-checkbox\" : \"pv-radio\";\n});\n\nconst dataTestId = computed(() => {\n const type =\n props.menuOptionConfig?.variant === \"checkbox\"\n ? \"-checkbox\"\n : props.menuOptionConfig?.variant === \"radio\"\n ? \"-radio\"\n : \"\";\n return `pv-menu${type}-item`;\n});\n\nconst emits = defineEmits<{\n (e: \"handle-selected\", payload: MenuOptionSelectedEvent): void;\n (e: \"toggle-expanded\"): void;\n}>();\n\nconst handleSelected = (event: Event) => {\n if (props.disabled) {\n return;\n }\n const option: MenuOption = {\n ...props,\n };\n emits(\"handle-selected\", {\n option,\n event,\n });\n // After the reactive state settles, force-sync the DOM checked/indeterminate\n // properties. Vue skips patching when the computed value doesn't change (e.g.\n // indeterminate parent: isChecked was false before and is still false after\n // deselecting all children), leaving the browser-toggled state stale.\n nextTick(() => {\n if (inputRef.value) {\n inputRef.value.checked = isChecked.value;\n inputRef.value.indeterminate = isIndeterminate.value;\n }\n });\n};\n</script>\n\n<template>\n <label\n class=\"pv-label pv-label-hover pv-flex pv-stack-4 pv-inset-square-8\"\n :class=\"computedClassList\"\n :style=\"[\n disabledStyle,\n { cursor: 'pointer', paddingTop: subText ? '4px' : undefined, paddingBottom: subText ? '4px' : undefined },\n ]\"\n :data-testid=\"dataTestId\"\n >\n <input\n ref=\"inputRef\"\n :hidden=\"inputHidden\"\n :type=\"inputType\"\n :name=\"inputName\"\n :checked=\"isChecked\"\n :indeterminate=\"isIndeterminate\"\n :class=\"inputClass\"\n :disabled=\"disabled\"\n @change=\"handleSelected\"\n />\n <template v-if=\"menuOptionConfig?.renderer\">\n <component :is=\"menuOptionConfig?.renderer\" v-bind=\"$props\" />\n </template>\n <template v-else>\n <PvMenuBaseItem\n v-bind=\"computedOption\"\n :menuOptionConfig=\"menuOptionConfig\"\n :queryText=\"queryText\"\n :highlightSearchText=\"highlightSearchText\"\n />\n </template>\n <PvIcon v-if=\"menuOptionConfig?.variant === 'checkmark' && isChecked\" name=\"check\" class=\"pv-text-success\" />\n <PvSwitch\n v-if=\"menuOptionConfig?.variant === 'toggle'\"\n :modelValue=\"isChecked\"\n :ariaLabel=\"props.text || 'Toggle'\"\n size=\"sm\"\n hideCheckIcon\n style=\"pointer-events: none\"\n />\n <PvMenuItemAction v-if=\"menuOptionConfig?.action\" :action=\"menuOptionConfig?.action\" :option=\"props\" />\n <button\n v-if=\"showChevron\"\n type=\"button\"\n class=\"pv-button-ghost pv-menu-item-expand-chevron\"\n :aria-label=\"props.text ? `Toggle children for ${props.text}` : 'Toggle children'\"\n :aria-expanded=\"expanded\"\n @click.prevent.stop=\"emits('toggle-expanded')\"\n >\n <PvIcon :name=\"chevronIcon ?? 'chevron-right'\" :size=\"12\" />\n </button>\n </label>\n</template>\n\n<style scoped>\n.pv-menu-item-disabled {\n pointer-events: none;\n border-radius: 4px;\n color: #7d898d;\n}\n.pv-menu-item {\n cursor: pointer;\n transition-duration: 150ms;\n transition-property: background-color;\n border-radius: var(--popover-list-item-radius, 4px);\n &:hover,\n &:focus-visible {\n background-color: var(--popover-list-item-hover-background-color, #f5f5f5);\n }\n &:active {\n background-color: var(--popover-list-item-pressed-background-color, #ebebeb);\n }\n}\n.pv-radio:indeterminate {\n background-color: unset !important;\n border-color: var(--color-border, #e3e7ea) !important;\n}\n.pv-menu-item-expand-chevron {\n padding: 4px;\n margin-left: auto;\n flex-shrink: 0;\n}\n.pv-menu-item-disabled .pv-menu-item-expand-chevron {\n pointer-events: auto;\n color: inherit;\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { computed, getCurrentInstance, inject, nextTick, ref, useTemplateRef } from \"vue\";\n\nimport PvMenuBaseItem from \"@/components/base/PvMenu/items/PvMenuBaseItem.vue\";\nimport PvSwitch from \"@/components/base/PvSwitch/PvSwitch.vue\";\nimport { MenuOption, MenuOptionConfig, MenuOptionSelectedEvent } from \"@/types.ts\";\nimport PvMenuItemAction from \"@/components/base/PvMenu/items/PvMenuItemAction.vue\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport { collectLeafOptions, hasCascadeChildren, mergeLeafOptions } from \"@/components/base/PvMenu/cascadeUtils\";\nimport {\n SelectedItemsKey,\n EnableCascadeSelectionKey,\n OriginalOptionsMapKey,\n CascadeSelectedParentIdsKey,\n} from \"@/components/base/PvMenu/symbols\";\n\nexport interface PvMenuItemVariantProps extends MenuOption {\n selected?: boolean;\n indeterminate?: boolean;\n queryText?: string | null;\n highlightSearchText?: boolean;\n menuOptionConfig?: MenuOptionConfig;\n showChevron?: boolean;\n chevronIcon?: string;\n expanded?: boolean;\n}\n\nconst props = defineProps<PvMenuItemVariantProps>();\n\nconst inputRef = useTemplateRef<HTMLInputElement>(\"inputRef\");\n\nconst selectedItems = inject(SelectedItemsKey, undefined);\nconst enableCascadeSelection = inject(EnableCascadeSelectionKey, ref(false));\nconst originalOptionsMap = inject(OriginalOptionsMapKey, undefined);\nconst cascadeSelectedParentIds = inject(CascadeSelectedParentIdsKey, undefined);\n\n// Resolve the effective leaf options for this parent node. Always use original\n// (unfiltered) children so the checked/indeterminate state reflects all children.\n// When children have been dynamically loaded (see-more), props.children may have\n// more entries than the original snapshot — use whichever is larger.\nconst effectiveLeafOptions = computed(() => {\n if (!enableCascadeSelection.value || !hasCascadeChildren(props)) return [];\n const currentLeaves = props.children ? collectLeafOptions(props.children) : [];\n if (originalOptionsMap?.value) {\n const originalOption = originalOptionsMap.value.get(props.id);\n const originalLeaves = originalOption?.children ? collectLeafOptions(originalOption.children) : [];\n return mergeLeafOptions(originalLeaves, currentLeaves);\n }\n return currentLeaves;\n});\n\nconst isChecked = computed(() => {\n if (!selectedItems?.value) return props.selected ?? false;\n if (enableCascadeSelection.value && hasCascadeChildren(props)) {\n const leafOptions = effectiveLeafOptions.value;\n const originalLeafCount = leafOptions.length;\n const selectedCount = leafOptions.filter((lo) => selectedItems.value.some((item) => item.id === lo.id)).length;\n // Parent was explicitly clicked and all loaded children are selected → checked\n if (cascadeSelectedParentIds?.value?.has(props.id) && selectedCount >= originalLeafCount) {\n return true;\n }\n const totalCount = props.totalChildCount ?? originalLeafCount;\n return totalCount > 0 && selectedCount >= totalCount;\n }\n return selectedItems.value.some((item) => item.id === props.id);\n});\n\nconst isIndeterminate = computed(() => {\n if (!selectedItems?.value || !enableCascadeSelection.value || !hasCascadeChildren(props)) {\n return props.indeterminate ?? false;\n }\n const leafOptions = effectiveLeafOptions.value;\n const originalLeafCount = leafOptions.length;\n const selectedCount = leafOptions.filter((lo) => selectedItems.value.some((item) => item.id === lo.id)).length;\n // Parent was explicitly clicked and all loaded children are selected → not indeterminate\n if (cascadeSelectedParentIds?.value?.has(props.id) && selectedCount >= originalLeafCount) {\n return false;\n }\n const totalCount = props.totalChildCount ?? originalLeafCount;\n return selectedCount > 0 && selectedCount < totalCount;\n});\n\nconst computedClassList = computed(() => {\n const classes = props.classList ? [...props.classList] : [];\n if (props.disabled) {\n classes.push(\"pv-menu-item-disabled\");\n } else {\n classes.push(\"pv-menu-item\");\n }\n return classes;\n});\n\nconst disabledStyle = computed(() => {\n if (props.disabled && props.menuOptionConfig?.disabledVariant !== \"ghost\") {\n return { background: \"#ececec\" };\n }\n return {};\n});\n\nconst computedOption = computed(() => {\n const option: MenuOption = {\n ...props,\n avatar: props.menuOptionConfig?.variant === \"avatar\" ? props.avatar : undefined,\n icon: props.menuOptionConfig?.variant === \"icon\" ? props.icon : undefined,\n companyName: props.menuOptionConfig?.variant === \"company\" ? props.companyName || props.text : undefined,\n };\n return option;\n});\n\nconst inputHidden = computed(() => {\n const variant = props.menuOptionConfig?.variant;\n return variant !== \"checkbox\" && variant !== \"radio\";\n});\n\n// we only show the input for checkbox and radio variants\nconst inputType = computed(() => {\n return props.menuOptionConfig?.variant === \"radio\" ? \"radio\" : \"checkbox\";\n});\n\nconst inputName = `${inputType.value}-${getCurrentInstance()?.uid}`;\n\nconst inputClass = computed(() => {\n return props.menuOptionConfig?.variant === \"checkbox\" ? \"pv-checkbox\" : \"pv-radio\";\n});\n\nconst dataTestId = computed(() => {\n const type =\n props.menuOptionConfig?.variant === \"checkbox\"\n ? \"-checkbox\"\n : props.menuOptionConfig?.variant === \"radio\"\n ? \"-radio\"\n : \"\";\n return `pv-menu${type}-item`;\n});\n\nconst emits = defineEmits<{\n (e: \"handle-selected\", payload: MenuOptionSelectedEvent): void;\n (e: \"toggle-expanded\"): void;\n}>();\n\nconst handleSelected = (event: Event) => {\n if (props.disabled) {\n return;\n }\n const option: MenuOption = {\n ...props,\n };\n emits(\"handle-selected\", {\n option,\n event,\n });\n // After the reactive state settles, force-sync the DOM checked/indeterminate\n // properties. Vue skips patching when the computed value doesn't change (e.g.\n // indeterminate parent: isChecked was false before and is still false after\n // deselecting all children), leaving the browser-toggled state stale.\n nextTick(() => {\n if (inputRef.value) {\n inputRef.value.checked = isChecked.value;\n inputRef.value.indeterminate = isIndeterminate.value;\n }\n });\n};\n</script>\n\n<template>\n <label\n class=\"pv-label pv-label-hover pv-flex pv-stack-4 pv-inset-square-8\"\n :class=\"computedClassList\"\n :style=\"[\n disabledStyle,\n { cursor: 'pointer', paddingTop: subText ? '4px' : undefined, paddingBottom: subText ? '4px' : undefined },\n ]\"\n :data-testid=\"dataTestId\"\n >\n <input\n ref=\"inputRef\"\n :hidden=\"inputHidden\"\n :type=\"inputType\"\n :name=\"inputName\"\n :checked=\"isChecked\"\n :indeterminate=\"isIndeterminate\"\n :class=\"inputClass\"\n :disabled=\"disabled\"\n @change=\"handleSelected\"\n />\n <template v-if=\"menuOptionConfig?.renderer\">\n <component :is=\"menuOptionConfig?.renderer\" v-bind=\"$props\" />\n </template>\n <template v-else>\n <PvMenuBaseItem\n v-bind=\"computedOption\"\n :menuOptionConfig=\"menuOptionConfig\"\n :queryText=\"queryText\"\n :highlightSearchText=\"highlightSearchText\"\n />\n </template>\n <PvIcon v-if=\"menuOptionConfig?.variant === 'checkmark' && isChecked\" name=\"check\" class=\"pv-text-success\" />\n <PvSwitch\n v-if=\"menuOptionConfig?.variant === 'toggle'\"\n :modelValue=\"isChecked\"\n :ariaLabel=\"props.text || 'Toggle'\"\n size=\"sm\"\n hideCheckIcon\n style=\"pointer-events: none\"\n />\n <PvMenuItemAction v-if=\"menuOptionConfig?.action\" :action=\"menuOptionConfig?.action\" :option=\"props\" />\n <button\n v-if=\"showChevron\"\n type=\"button\"\n class=\"pv-button-ghost pv-menu-item-expand-chevron\"\n :aria-label=\"props.text ? `Toggle children for ${props.text}` : 'Toggle children'\"\n :aria-expanded=\"expanded\"\n @click.prevent.stop=\"emits('toggle-expanded')\"\n >\n <PvIcon :name=\"chevronIcon ?? 'chevron-right'\" :size=\"12\" />\n </button>\n </label>\n</template>\n\n<style scoped>\n.pv-menu-item-disabled {\n pointer-events: none;\n border-radius: 4px;\n color: #7d898d;\n}\n.pv-menu-item {\n cursor: pointer;\n transition-duration: 150ms;\n transition-property: background-color;\n border-radius: var(--popover-list-item-radius, 4px);\n &:hover,\n &:focus-visible {\n background-color: var(--popover-list-item-hover-background-color, #f5f5f5);\n }\n &:active {\n background-color: var(--popover-list-item-pressed-background-color, #ebebeb);\n }\n}\n.pv-radio:indeterminate {\n background-color: unset !important;\n border-color: var(--color-border, #e3e7ea) !important;\n}\n.pv-menu-item-expand-chevron {\n padding: 4px;\n margin-left: auto;\n flex-shrink: 0;\n}\n.pv-menu-item-disabled .pv-menu-item-expand-chevron {\n pointer-events: auto;\n color: inherit;\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { computed, inject, ref, watch } from \"vue\";\n\nimport { MenuOption, MenuOptionConfig, MenuOptionSelectedEvent, SeeMoreEvent } from \"@/types.ts\";\nimport { hasCascadeChildren } from \"@/components/base/PvMenu/cascadeUtils\";\nimport PvMenuItemVariant from \"@/components/base/PvMenu/items/PvMenuItemVariant.vue\";\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport {\n SelectedItemsKey,\n EnableChildExpansionKey,\n CascadeSelectedParentIdsKey,\n CascadeDeselectedChildIdsKey,\n ParentSelectsAllChildrenKey,\n} from \"@/components/base/PvMenu/symbols\";\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst MAX_LEVEL_DEPTH = 4;\n\ninterface PvMenuItemProps extends MenuOption {\n level?: number;\n config?: MenuOptionConfig;\n queryText?: string | null;\n highlightSearchText?: boolean;\n itemClass?: string;\n}\n\nconst props = withDefaults(defineProps<PvMenuItemProps>(), {\n level: 0,\n});\nconst injectedSelectedItems = inject(SelectedItemsKey, undefined);\nconst modelSelectedIds = defineModel<string[]>(\"selectedIds\", { default: () => [] });\n\nconst enableChildExpansion = inject(EnableChildExpansionKey, ref(false));\nconst parentSelectsAllChildren = inject(ParentSelectsAllChildrenKey, ref(false));\nconst cascadeSelectedParentIds = inject(CascadeSelectedParentIdsKey, undefined);\nconst cascadeDeselectedChildIds = inject(CascadeDeselectedChildIdsKey, undefined);\n\nconst isExpanded = ref(props.defaultExpanded ?? false);\nconst isSeeMoreLoading = ref(false);\nconst hasExhaustedChildren = ref(false);\nconst childOptions = ref<MenuOption[]>(props.children ?? []);\nconst lazyLoadedChildIds = ref<Set<string>>(new Set());\n\nwatch(\n () => props.children,\n (newChildren) => {\n if (!newChildren) {\n childOptions.value = [];\n return;\n }\n // Preserve lazily loaded children (from handleSeeMore) that aren't in the\n // new prop value, but drop any original children that were filtered out.\n const lazyChildren = childOptions.value.filter((c) => lazyLoadedChildIds.value.has(c.id));\n const newChildIds = new Set(newChildren.map((c) => c.id));\n const extras = lazyChildren.filter((c) => !newChildIds.has(c.id));\n childOptions.value = [...newChildren, ...extras];\n hasExhaustedChildren.value = false;\n },\n);\n\nconst toggleExpanded = () => {\n isExpanded.value = !isExpanded.value;\n};\n\nconst paddingLeft = computed(() => ({ paddingLeft: `${props.level * 12 + 12}px` }));\n\n// Omit PvMenuItem-only props so v-bind doesn't leak them as DOM attributes\n// on PvMenuItemVariant (which doesn't declare them).\nconst variantProps = computed(() => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { level, config, itemClass, ...rest } = props;\n return rest;\n});\n\nconst hasChildren = computed(() => {\n return hasCascadeChildren({ ...props, children: childOptions.value }) && props.level < MAX_LEVEL_DEPTH;\n});\n\nconst showSubMenu = computed(() => {\n if (!hasChildren.value) return false;\n if (enableChildExpansion.value) return isExpanded.value || !!props.disabled;\n return true;\n});\n\nconst chevronIcon = computed(() => {\n return isExpanded.value ? \"chevron-down\" : \"chevron-right\";\n});\n\nconst optionIsSelected = (option: PvMenuItemProps): boolean => {\n if (injectedSelectedItems && Array.isArray(injectedSelectedItems.value)) {\n return injectedSelectedItems.value.some((item) => item.id === option.id);\n }\n return modelSelectedIds.value.includes(option.id);\n};\n\nconst isChildVisibleInReadOnly = (childOption: MenuOption): boolean => {\n if (optionIsSelected(childOption)) return true;\n if (cascadeSelectedParentIds?.value?.has(props.id)) {\n const deselected = cascadeDeselectedChildIds?.value?.get(props.id);\n return !deselected?.has(childOption.id);\n }\n return false;\n};\n\nconst emits = defineEmits<{\n (e: \"handle-selected\", payload: MenuOptionSelectedEvent): void;\n (e: \"see-more\", payload: SeeMoreEvent): void;\n}>();\n\nconst hasMoreChildren = computed(() => {\n if (hasExhaustedChildren.value) return false;\n if (props.totalChildCount == null) return false;\n return props.totalChildCount > childOptions.value.length;\n});\n\nconst handleSeeMoreClick = async () => {\n if (isSeeMoreLoading.value) return;\n\n if (!props.handleSeeMore) {\n emits(\"see-more\", { parentId: props.id, offset: childOptions.value.length });\n return;\n }\n\n const parentIsSelected = cascadeSelectedParentIds?.value?.has(props.id) ?? false;\n\n isSeeMoreLoading.value = true;\n try {\n const newChildren = await props.handleSeeMore({ parentId: props.id, offset: childOptions.value.length });\n if (Array.isArray(newChildren) && newChildren.length > 0) {\n const existingIds = new Set(childOptions.value.map((c) => c.id));\n const uniqueNewChildren = newChildren.filter((c) => !existingIds.has(c.id));\n if (uniqueNewChildren.length === 0) {\n hasExhaustedChildren.value = true;\n return;\n }\n const nextLazy = new Set(lazyLoadedChildIds.value);\n for (const c of uniqueNewChildren) nextLazy.add(c.id);\n lazyLoadedChildIds.value = nextLazy;\n childOptions.value = [...childOptions.value, ...uniqueNewChildren];\n // If the parent was selected, auto-select newly loaded children\n // (excluding any that were explicitly deselected by the user)\n if (parentIsSelected && injectedSelectedItems?.value) {\n const deselected = cascadeDeselectedChildIds?.value?.get(props.id);\n const candidates = deselected ? uniqueNewChildren.filter((c) => !deselected.has(c.id)) : uniqueNewChildren;\n if (candidates.length > 0) {\n const existingSelectedIds = new Set(injectedSelectedItems.value.map((item) => item.id));\n const toSelect = candidates.filter((c) => !existingSelectedIds.has(c.id));\n if (toSelect.length > 0) {\n injectedSelectedItems.value = [...injectedSelectedItems.value, ...toSelect];\n }\n }\n }\n } else if (Array.isArray(newChildren)) {\n hasExhaustedChildren.value = true;\n }\n } finally {\n isSeeMoreLoading.value = false;\n }\n};\n\nconst handleSelected = (event: MenuOptionSelectedEvent) => {\n // If this item is expandable and has children, clicking it toggles expansion\n // rather than selection — unless parentSelectsAllChildren is enabled, in which\n // case the parent click should cascade-select all children (expansion stays\n // available via the chevron button).\n if (\n enableChildExpansion.value &&\n hasChildren.value &&\n event.option.id === props.id &&\n !parentSelectsAllChildren.value\n ) {\n toggleExpanded();\n return;\n }\n if (!injectedSelectedItems) {\n const index = modelSelectedIds.value.indexOf(event.option.id);\n if (index > -1) {\n modelSelectedIds.value = [...modelSelectedIds.value.slice(0, index), ...modelSelectedIds.value.slice(index + 1)];\n } else {\n modelSelectedIds.value = [...modelSelectedIds.value, event.option.id];\n }\n }\n emits(\"handle-selected\", event);\n};\n\n// Bubble child handle-selected events without toggling modelSelectedIds again\n// (the child PvMenuItem already updated the shared modelSelectedIds via v-model).\nconst handleChildSelected = (event: MenuOptionSelectedEvent) => {\n emits(\"handle-selected\", event);\n};\n</script>\n\n<template v-if=\"level < MAX_LEVEL_DEPTH\">\n <PvMenuItemVariant\n v-bind=\"variantProps\"\n :children=\"childOptions\"\n :menuOptionConfig=\"config\"\n :queryText=\"queryText\"\n :highlightSearchText=\"highlightSearchText\"\n :showChevron=\"enableChildExpansion && hasChildren\"\n :chevronIcon=\"chevronIcon\"\n :expanded=\"isExpanded\"\n @handle-selected=\"handleSelected\"\n @toggle-expanded=\"toggleExpanded\"\n :selected=\"optionIsSelected(props)\"\n />\n <ul v-if=\"showSubMenu\" role=\"list\" :style=\"paddingLeft\">\n <li\n v-for=\"childOption in childOptions\"\n v-show=\"!props.disabled || isChildVisibleInReadOnly(childOption)\"\n :key=\"childOption.id\"\n :data-active=\"optionIsSelected(childOption) ? 'true' : null\"\n :class=\"itemClass\"\n >\n <PvMenuItem\n v-bind=\"childOption\"\n :disabled=\"props.disabled || childOption.disabled\"\n v-model:selectedIds=\"modelSelectedIds\"\n :config=\"childOption.config ?? config\"\n :queryText=\"queryText\"\n :highlightSearchText=\"highlightSearchText\"\n :level=\"level + 1\"\n @handle-selected=\"handleChildSelected\"\n @see-more=\"emits('see-more', $event)\"\n />\n </li>\n <li v-if=\"hasMoreChildren\">\n <PvButton\n class=\"pv-text-brand\"\n variant=\"ghost\"\n label=\"See more\"\n :loading=\"isSeeMoreLoading\"\n data-testid=\"pv-menu-item-see-more\"\n @click=\"handleSeeMoreClick\"\n />\n </li>\n </ul>\n</template>\n","<script lang=\"ts\" setup>\nimport { computed, inject, ref, watch } from \"vue\";\n\nimport { MenuOption, MenuOptionConfig, MenuOptionSelectedEvent, SeeMoreEvent } from \"@/types.ts\";\nimport { hasCascadeChildren } from \"@/components/base/PvMenu/cascadeUtils\";\nimport PvMenuItemVariant from \"@/components/base/PvMenu/items/PvMenuItemVariant.vue\";\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport {\n SelectedItemsKey,\n EnableChildExpansionKey,\n CascadeSelectedParentIdsKey,\n CascadeDeselectedChildIdsKey,\n ParentSelectsAllChildrenKey,\n} from \"@/components/base/PvMenu/symbols\";\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst MAX_LEVEL_DEPTH = 4;\n\ninterface PvMenuItemProps extends MenuOption {\n level?: number;\n config?: MenuOptionConfig;\n queryText?: string | null;\n highlightSearchText?: boolean;\n itemClass?: string;\n}\n\nconst props = withDefaults(defineProps<PvMenuItemProps>(), {\n level: 0,\n});\nconst injectedSelectedItems = inject(SelectedItemsKey, undefined);\nconst modelSelectedIds = defineModel<string[]>(\"selectedIds\", { default: () => [] });\n\nconst enableChildExpansion = inject(EnableChildExpansionKey, ref(false));\nconst parentSelectsAllChildren = inject(ParentSelectsAllChildrenKey, ref(false));\nconst cascadeSelectedParentIds = inject(CascadeSelectedParentIdsKey, undefined);\nconst cascadeDeselectedChildIds = inject(CascadeDeselectedChildIdsKey, undefined);\n\nconst isExpanded = ref(props.defaultExpanded ?? false);\nconst isSeeMoreLoading = ref(false);\nconst hasExhaustedChildren = ref(false);\nconst childOptions = ref<MenuOption[]>(props.children ?? []);\nconst lazyLoadedChildIds = ref<Set<string>>(new Set());\n\nwatch(\n () => props.children,\n (newChildren) => {\n if (!newChildren) {\n childOptions.value = [];\n return;\n }\n // Preserve lazily loaded children (from handleSeeMore) that aren't in the\n // new prop value, but drop any original children that were filtered out.\n const lazyChildren = childOptions.value.filter((c) => lazyLoadedChildIds.value.has(c.id));\n const newChildIds = new Set(newChildren.map((c) => c.id));\n const extras = lazyChildren.filter((c) => !newChildIds.has(c.id));\n childOptions.value = [...newChildren, ...extras];\n hasExhaustedChildren.value = false;\n },\n);\n\nconst toggleExpanded = () => {\n isExpanded.value = !isExpanded.value;\n};\n\nconst paddingLeft = computed(() => ({ paddingLeft: `${props.level * 12 + 12}px` }));\n\n// Omit PvMenuItem-only props so v-bind doesn't leak them as DOM attributes\n// on PvMenuItemVariant (which doesn't declare them).\nconst variantProps = computed(() => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { level, config, itemClass, ...rest } = props;\n return rest;\n});\n\nconst hasChildren = computed(() => {\n return hasCascadeChildren({ ...props, children: childOptions.value }) && props.level < MAX_LEVEL_DEPTH;\n});\n\nconst showSubMenu = computed(() => {\n if (!hasChildren.value) return false;\n if (enableChildExpansion.value) return isExpanded.value || !!props.disabled;\n return true;\n});\n\nconst chevronIcon = computed(() => {\n return isExpanded.value ? \"chevron-down\" : \"chevron-right\";\n});\n\nconst optionIsSelected = (option: PvMenuItemProps): boolean => {\n if (injectedSelectedItems && Array.isArray(injectedSelectedItems.value)) {\n return injectedSelectedItems.value.some((item) => item.id === option.id);\n }\n return modelSelectedIds.value.includes(option.id);\n};\n\nconst isChildVisibleInReadOnly = (childOption: MenuOption): boolean => {\n if (optionIsSelected(childOption)) return true;\n if (cascadeSelectedParentIds?.value?.has(props.id)) {\n const deselected = cascadeDeselectedChildIds?.value?.get(props.id);\n return !deselected?.has(childOption.id);\n }\n return false;\n};\n\nconst emits = defineEmits<{\n (e: \"handle-selected\", payload: MenuOptionSelectedEvent): void;\n (e: \"see-more\", payload: SeeMoreEvent): void;\n}>();\n\nconst hasMoreChildren = computed(() => {\n if (hasExhaustedChildren.value) return false;\n if (props.totalChildCount == null) return false;\n return props.totalChildCount > childOptions.value.length;\n});\n\nconst handleSeeMoreClick = async () => {\n if (isSeeMoreLoading.value) return;\n\n if (!props.handleSeeMore) {\n emits(\"see-more\", { parentId: props.id, offset: childOptions.value.length });\n return;\n }\n\n const parentIsSelected = cascadeSelectedParentIds?.value?.has(props.id) ?? false;\n\n isSeeMoreLoading.value = true;\n try {\n const newChildren = await props.handleSeeMore({ parentId: props.id, offset: childOptions.value.length });\n if (Array.isArray(newChildren) && newChildren.length > 0) {\n const existingIds = new Set(childOptions.value.map((c) => c.id));\n const uniqueNewChildren = newChildren.filter((c) => !existingIds.has(c.id));\n if (uniqueNewChildren.length === 0) {\n hasExhaustedChildren.value = true;\n return;\n }\n const nextLazy = new Set(lazyLoadedChildIds.value);\n for (const c of uniqueNewChildren) nextLazy.add(c.id);\n lazyLoadedChildIds.value = nextLazy;\n childOptions.value = [...childOptions.value, ...uniqueNewChildren];\n // If the parent was selected, auto-select newly loaded children\n // (excluding any that were explicitly deselected by the user)\n if (parentIsSelected && injectedSelectedItems?.value) {\n const deselected = cascadeDeselectedChildIds?.value?.get(props.id);\n const candidates = deselected ? uniqueNewChildren.filter((c) => !deselected.has(c.id)) : uniqueNewChildren;\n if (candidates.length > 0) {\n const existingSelectedIds = new Set(injectedSelectedItems.value.map((item) => item.id));\n const toSelect = candidates.filter((c) => !existingSelectedIds.has(c.id));\n if (toSelect.length > 0) {\n injectedSelectedItems.value = [...injectedSelectedItems.value, ...toSelect];\n }\n }\n }\n } else if (Array.isArray(newChildren)) {\n hasExhaustedChildren.value = true;\n }\n } finally {\n isSeeMoreLoading.value = false;\n }\n};\n\nconst handleSelected = (event: MenuOptionSelectedEvent) => {\n // If this item is expandable and has children, clicking it toggles expansion\n // rather than selection — unless parentSelectsAllChildren is enabled, in which\n // case the parent click should cascade-select all children (expansion stays\n // available via the chevron button).\n if (\n enableChildExpansion.value &&\n hasChildren.value &&\n event.option.id === props.id &&\n !parentSelectsAllChildren.value\n ) {\n toggleExpanded();\n return;\n }\n if (!injectedSelectedItems) {\n const index = modelSelectedIds.value.indexOf(event.option.id);\n if (index > -1) {\n modelSelectedIds.value = [...modelSelectedIds.value.slice(0, index), ...modelSelectedIds.value.slice(index + 1)];\n } else {\n modelSelectedIds.value = [...modelSelectedIds.value, event.option.id];\n }\n }\n emits(\"handle-selected\", event);\n};\n\n// Bubble child handle-selected events without toggling modelSelectedIds again\n// (the child PvMenuItem already updated the shared modelSelectedIds via v-model).\nconst handleChildSelected = (event: MenuOptionSelectedEvent) => {\n emits(\"handle-selected\", event);\n};\n</script>\n\n<template v-if=\"level < MAX_LEVEL_DEPTH\">\n <PvMenuItemVariant\n v-bind=\"variantProps\"\n :children=\"childOptions\"\n :menuOptionConfig=\"config\"\n :queryText=\"queryText\"\n :highlightSearchText=\"highlightSearchText\"\n :showChevron=\"enableChildExpansion && hasChildren\"\n :chevronIcon=\"chevronIcon\"\n :expanded=\"isExpanded\"\n @handle-selected=\"handleSelected\"\n @toggle-expanded=\"toggleExpanded\"\n :selected=\"optionIsSelected(props)\"\n />\n <ul v-if=\"showSubMenu\" role=\"list\" :style=\"paddingLeft\">\n <li\n v-for=\"childOption in childOptions\"\n v-show=\"!props.disabled || isChildVisibleInReadOnly(childOption)\"\n :key=\"childOption.id\"\n :data-active=\"optionIsSelected(childOption) ? 'true' : null\"\n :class=\"itemClass\"\n >\n <PvMenuItem\n v-bind=\"childOption\"\n :disabled=\"props.disabled || childOption.disabled\"\n v-model:selectedIds=\"modelSelectedIds\"\n :config=\"childOption.config ?? config\"\n :queryText=\"queryText\"\n :highlightSearchText=\"highlightSearchText\"\n :level=\"level + 1\"\n @handle-selected=\"handleChildSelected\"\n @see-more=\"emits('see-more', $event)\"\n />\n </li>\n <li v-if=\"hasMoreChildren\">\n <PvButton\n class=\"pv-text-brand\"\n variant=\"ghost\"\n label=\"See more\"\n :loading=\"isSeeMoreLoading\"\n data-testid=\"pv-menu-item-see-more\"\n @click=\"handleSeeMoreClick\"\n />\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, inject, provide, ref, shallowRef, watch } from \"vue\";\n\nimport { MenuOption, MenuOptionSelectedEvent, SeeMoreEvent } from \"@/types\";\nimport PvMenuItem from \"@/components/base/PvMenu/items/PvMenuItem.vue\";\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport { PvMenuProps } from \"./types\";\nimport { collectLeafOptions, hasCascadeChildren, mergeLeafOptions } from \"./cascadeUtils\";\nimport {\n SelectedItemsKey,\n EnableCascadeSelectionKey,\n OriginalOptionsMapKey,\n ParentSelectsAllChildrenKey,\n CascadeSelectedParentIdsKey,\n CascadeDeselectedChildIdsKey,\n} from \"./symbols\";\n\nconst props = defineProps<PvMenuProps>();\n\nconst emit = defineEmits<{\n (e: \"handle-selected\", payload: MenuOptionSelectedEvent): void;\n (e: \"see-more\", payload: SeeMoreEvent): void;\n}>();\n\nconst selectedItems = defineModel<MenuOption[]>(\"selectedItems\", { default: () => [] });\n\n// Vue 3.5 defineModel doesn't update local value synchronously when the prop\n// is passed by a parent (it only emits and waits for the parent to re-render).\n// This local ref is updated immediately so consecutive selections read correct state.\nconst localSelectedItems = shallowRef<MenuOption[]>(selectedItems.value);\n\nwatch(selectedItems, (newVal) => {\n localSelectedItems.value = newVal;\n});\n\n// Sync back to the model when descendants mutate localSelectedItems directly\n// (e.g. auto-selecting lazy-loaded children in PvMenuItem.handleSeeMoreClick).\nwatch(localSelectedItems, (newVal) => {\n if (newVal !== selectedItems.value) {\n selectedItems.value = newVal;\n }\n});\n\nprovide(SelectedItemsKey, localSelectedItems);\nprovide(\n EnableCascadeSelectionKey,\n computed(() => !!props.enableCascadeSelection),\n);\n\nconst originalOptionsMap = inject(OriginalOptionsMapKey, undefined);\nconst parentSelectsAllChildren = inject(ParentSelectsAllChildrenKey, ref(false));\nconst cascadeSelectedParentIds = inject(CascadeSelectedParentIdsKey, undefined);\nconst cascadeDeselectedChildIds = inject(CascadeDeselectedChildIdsKey, undefined);\n\nconst isSingleSelect = computed(() => props.singleSelect || props.config?.variant === \"radio\");\n\nconst handleItemSelected = (event: MenuOptionSelectedEvent) => {\n if (props.readOnly) return;\n const option = event.option;\n let newSelection: MenuOption[];\n\n if (props.enableCascadeSelection && hasCascadeChildren(option)) {\n // Only leaf options are added to the selection — the parent itself is never\n // included because it is purely an organisational node, not a selectable value.\n // When parentSelectsAllChildren is true, use the original (unfiltered)\n // children so clicking a parent selects all children regardless of search query.\n let leafOptions: MenuOption[];\n if (parentSelectsAllChildren.value && originalOptionsMap?.value) {\n const originalOption = originalOptionsMap.value.get(option.id);\n const originalLeaves = originalOption?.children ? collectLeafOptions(originalOption.children) : [];\n const currentLeaves = option.children ? collectLeafOptions(option.children) : [];\n leafOptions = mergeLeafOptions(originalLeaves, currentLeaves);\n } else {\n leafOptions = option.children ? collectLeafOptions(option.children) : [];\n }\n const leafIds = leafOptions.map((o) => o.id);\n const current = localSelectedItems.value;\n const parentSelected = cascadeSelectedParentIds?.value?.has(option.id) ?? false;\n const anySelected = parentSelected || leafIds.some((id) => current.some((item) => item.id === id));\n newSelection = anySelected ? current.filter((item) => !leafIds.includes(item.id)) : [...current, ...leafOptions];\n\n // Track whether this parent was explicitly clicked for cascade selection\n if (cascadeSelectedParentIds?.value) {\n const next = new Set(cascadeSelectedParentIds.value);\n if (anySelected) {\n next.delete(option.id);\n } else {\n next.add(option.id);\n }\n cascadeSelectedParentIds.value = next;\n }\n // Clear deselected children tracking when parent is explicitly toggled\n if (cascadeDeselectedChildIds?.value?.has(option.id)) {\n const next = new Map(cascadeDeselectedChildIds.value);\n next.delete(option.id);\n cascadeDeselectedChildIds.value = next;\n }\n } else if (isSingleSelect.value) {\n if (localSelectedItems.value.length === 1 && localSelectedItems.value[0].id === option.id) {\n newSelection = [];\n } else {\n newSelection = [option];\n }\n } else {\n const index = localSelectedItems.value.findIndex((item) => item.id === option.id);\n if (index > -1) {\n newSelection = [...localSelectedItems.value.slice(0, index), ...localSelectedItems.value.slice(index + 1)];\n } else {\n newSelection = [...localSelectedItems.value, option];\n }\n\n // Track individually deselected/re-selected children under selected parents\n // so dynamically loaded children (see-more) can inherit the correct state.\n if (props.enableCascadeSelection && cascadeSelectedParentIds?.value && cascadeDeselectedChildIds?.value) {\n const isDeselecting = index > -1;\n for (const parentId of cascadeSelectedParentIds.value) {\n // Find if this child belongs to this parent\n const parentOption = originalOptionsMap?.value?.get(parentId);\n const parentChildren = parentOption?.children ?? props.options.find((o) => o.id === parentId)?.children;\n if (!parentChildren) continue;\n const leaves = collectLeafOptions(parentChildren);\n // Also check the option itself as it may have been dynamically loaded\n const isChildOfParent =\n leaves.some((l) => l.id === option.id) ||\n props.options.find((o) => o.id === parentId)?.children?.some((c) => c.id === option.id);\n if (!isChildOfParent) continue;\n\n const next = new Map(cascadeDeselectedChildIds.value);\n const deselected = new Set(next.get(parentId) ?? []);\n if (isDeselecting) {\n deselected.add(option.id);\n } else {\n deselected.delete(option.id);\n }\n if (deselected.size > 0) {\n next.set(parentId, deselected);\n } else {\n next.delete(parentId);\n }\n cascadeDeselectedChildIds.value = next;\n break;\n }\n }\n }\n\n localSelectedItems.value = newSelection;\n selectedItems.value = newSelection;\n\n emit(\"handle-selected\", event);\n};\n\nconst selectedIds = computed(() => new Set(localSelectedItems.value.map((item) => item.id)));\n\nconst hasSelectedDescendant = (children: MenuOption[]): boolean => {\n for (const child of children) {\n if (selectedIds.value.has(child.id)) return true;\n if (child.children?.length && hasSelectedDescendant(child.children)) return true;\n }\n return false;\n};\n\nconst isActive = (option: MenuOption): true | null => {\n if (selectedIds.value.has(option.id)) {\n return true;\n }\n if (props.enableCascadeSelection && cascadeSelectedParentIds?.value?.has(option.id)) {\n return true;\n }\n if (props.enableCascadeSelection && option.children?.length && hasSelectedDescendant(option.children)) {\n return true;\n }\n return null;\n};\n\nconst isVisible = (option: MenuOption, isLoading?: boolean): boolean => {\n if (!isLoading) return true;\n if (selectedIds.value.has(option.id)) return true;\n if (cascadeSelectedParentIds?.value?.has(option.id)) return true;\n if (option.children?.length && hasSelectedDescendant(option.children)) return true;\n return false;\n};\n</script>\n\n<template>\n <ul role=\"list\" class=\"pv-popover-list\">\n <li\n v-for=\"option in options\"\n v-show=\"isVisible(option, isLoading || props.readOnly)\"\n :key=\"option.id\"\n :data-active=\"isActive(option)\"\n :data-testid=\"itemTestId\"\n :class=\"itemClass\"\n >\n <PvMenuItem\n v-bind=\"option\"\n :disabled=\"props.readOnly || option.disabled\"\n :config=\"config\"\n :itemClass=\"itemClass\"\n :queryText=\"queryText\"\n @handle-selected=\"handleItemSelected\"\n @see-more=\"emit('see-more', $event)\"\n />\n </li>\n <li v-if=\"hasMoreOptions && !props.readOnly\">\n <PvButton\n class=\"pv-text-brand\"\n variant=\"ghost\"\n label=\"See more\"\n :loading=\"isSeeMoreLoading\"\n :disabled=\"isSeeMoreLoading\"\n data-testid=\"pv-menu-see-more\"\n @click=\"emit('see-more', { parentId: undefined })\"\n />\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, inject, provide, ref, shallowRef, watch } from \"vue\";\n\nimport { MenuOption, MenuOptionSelectedEvent, SeeMoreEvent } from \"@/types\";\nimport PvMenuItem from \"@/components/base/PvMenu/items/PvMenuItem.vue\";\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport { PvMenuProps } from \"./types\";\nimport { collectLeafOptions, hasCascadeChildren, mergeLeafOptions } from \"./cascadeUtils\";\nimport {\n SelectedItemsKey,\n EnableCascadeSelectionKey,\n OriginalOptionsMapKey,\n ParentSelectsAllChildrenKey,\n CascadeSelectedParentIdsKey,\n CascadeDeselectedChildIdsKey,\n} from \"./symbols\";\n\nconst props = defineProps<PvMenuProps>();\n\nconst emit = defineEmits<{\n (e: \"handle-selected\", payload: MenuOptionSelectedEvent): void;\n (e: \"see-more\", payload: SeeMoreEvent): void;\n}>();\n\nconst selectedItems = defineModel<MenuOption[]>(\"selectedItems\", { default: () => [] });\n\n// Vue 3.5 defineModel doesn't update local value synchronously when the prop\n// is passed by a parent (it only emits and waits for the parent to re-render).\n// This local ref is updated immediately so consecutive selections read correct state.\nconst localSelectedItems = shallowRef<MenuOption[]>(selectedItems.value);\n\nwatch(selectedItems, (newVal) => {\n localSelectedItems.value = newVal;\n});\n\n// Sync back to the model when descendants mutate localSelectedItems directly\n// (e.g. auto-selecting lazy-loaded children in PvMenuItem.handleSeeMoreClick).\nwatch(localSelectedItems, (newVal) => {\n if (newVal !== selectedItems.value) {\n selectedItems.value = newVal;\n }\n});\n\nprovide(SelectedItemsKey, localSelectedItems);\nprovide(\n EnableCascadeSelectionKey,\n computed(() => !!props.enableCascadeSelection),\n);\n\nconst originalOptionsMap = inject(OriginalOptionsMapKey, undefined);\nconst parentSelectsAllChildren = inject(ParentSelectsAllChildrenKey, ref(false));\nconst cascadeSelectedParentIds = inject(CascadeSelectedParentIdsKey, undefined);\nconst cascadeDeselectedChildIds = inject(CascadeDeselectedChildIdsKey, undefined);\n\nconst isSingleSelect = computed(() => props.singleSelect || props.config?.variant === \"radio\");\n\nconst handleItemSelected = (event: MenuOptionSelectedEvent) => {\n if (props.readOnly) return;\n const option = event.option;\n let newSelection: MenuOption[];\n\n if (props.enableCascadeSelection && hasCascadeChildren(option)) {\n // Only leaf options are added to the selection — the parent itself is never\n // included because it is purely an organisational node, not a selectable value.\n // When parentSelectsAllChildren is true, use the original (unfiltered)\n // children so clicking a parent selects all children regardless of search query.\n let leafOptions: MenuOption[];\n if (parentSelectsAllChildren.value && originalOptionsMap?.value) {\n const originalOption = originalOptionsMap.value.get(option.id);\n const originalLeaves = originalOption?.children ? collectLeafOptions(originalOption.children) : [];\n const currentLeaves = option.children ? collectLeafOptions(option.children) : [];\n leafOptions = mergeLeafOptions(originalLeaves, currentLeaves);\n } else {\n leafOptions = option.children ? collectLeafOptions(option.children) : [];\n }\n const leafIds = leafOptions.map((o) => o.id);\n const current = localSelectedItems.value;\n const parentSelected = cascadeSelectedParentIds?.value?.has(option.id) ?? false;\n const anySelected = parentSelected || leafIds.some((id) => current.some((item) => item.id === id));\n newSelection = anySelected ? current.filter((item) => !leafIds.includes(item.id)) : [...current, ...leafOptions];\n\n // Track whether this parent was explicitly clicked for cascade selection\n if (cascadeSelectedParentIds?.value) {\n const next = new Set(cascadeSelectedParentIds.value);\n if (anySelected) {\n next.delete(option.id);\n } else {\n next.add(option.id);\n }\n cascadeSelectedParentIds.value = next;\n }\n // Clear deselected children tracking when parent is explicitly toggled\n if (cascadeDeselectedChildIds?.value?.has(option.id)) {\n const next = new Map(cascadeDeselectedChildIds.value);\n next.delete(option.id);\n cascadeDeselectedChildIds.value = next;\n }\n } else if (isSingleSelect.value) {\n if (localSelectedItems.value.length === 1 && localSelectedItems.value[0].id === option.id) {\n newSelection = [];\n } else {\n newSelection = [option];\n }\n } else {\n const index = localSelectedItems.value.findIndex((item) => item.id === option.id);\n if (index > -1) {\n newSelection = [...localSelectedItems.value.slice(0, index), ...localSelectedItems.value.slice(index + 1)];\n } else {\n newSelection = [...localSelectedItems.value, option];\n }\n\n // Track individually deselected/re-selected children under selected parents\n // so dynamically loaded children (see-more) can inherit the correct state.\n if (props.enableCascadeSelection && cascadeSelectedParentIds?.value && cascadeDeselectedChildIds?.value) {\n const isDeselecting = index > -1;\n for (const parentId of cascadeSelectedParentIds.value) {\n // Find if this child belongs to this parent\n const parentOption = originalOptionsMap?.value?.get(parentId);\n const parentChildren = parentOption?.children ?? props.options.find((o) => o.id === parentId)?.children;\n if (!parentChildren) continue;\n const leaves = collectLeafOptions(parentChildren);\n // Also check the option itself as it may have been dynamically loaded\n const isChildOfParent =\n leaves.some((l) => l.id === option.id) ||\n props.options.find((o) => o.id === parentId)?.children?.some((c) => c.id === option.id);\n if (!isChildOfParent) continue;\n\n const next = new Map(cascadeDeselectedChildIds.value);\n const deselected = new Set(next.get(parentId) ?? []);\n if (isDeselecting) {\n deselected.add(option.id);\n } else {\n deselected.delete(option.id);\n }\n if (deselected.size > 0) {\n next.set(parentId, deselected);\n } else {\n next.delete(parentId);\n }\n cascadeDeselectedChildIds.value = next;\n break;\n }\n }\n }\n\n localSelectedItems.value = newSelection;\n selectedItems.value = newSelection;\n\n emit(\"handle-selected\", event);\n};\n\nconst selectedIds = computed(() => new Set(localSelectedItems.value.map((item) => item.id)));\n\nconst hasSelectedDescendant = (children: MenuOption[]): boolean => {\n for (const child of children) {\n if (selectedIds.value.has(child.id)) return true;\n if (child.children?.length && hasSelectedDescendant(child.children)) return true;\n }\n return false;\n};\n\nconst isActive = (option: MenuOption): true | null => {\n if (selectedIds.value.has(option.id)) {\n return true;\n }\n if (props.enableCascadeSelection && cascadeSelectedParentIds?.value?.has(option.id)) {\n return true;\n }\n if (props.enableCascadeSelection && option.children?.length && hasSelectedDescendant(option.children)) {\n return true;\n }\n return null;\n};\n\nconst isVisible = (option: MenuOption, isLoading?: boolean): boolean => {\n if (!isLoading) return true;\n if (selectedIds.value.has(option.id)) return true;\n if (cascadeSelectedParentIds?.value?.has(option.id)) return true;\n if (option.children?.length && hasSelectedDescendant(option.children)) return true;\n return false;\n};\n</script>\n\n<template>\n <ul role=\"list\" class=\"pv-popover-list\">\n <li\n v-for=\"option in options\"\n v-show=\"isVisible(option, isLoading || props.readOnly)\"\n :key=\"option.id\"\n :data-active=\"isActive(option)\"\n :data-testid=\"itemTestId\"\n :class=\"itemClass\"\n >\n <PvMenuItem\n v-bind=\"option\"\n :disabled=\"props.readOnly || option.disabled\"\n :config=\"config\"\n :itemClass=\"itemClass\"\n :queryText=\"queryText\"\n @handle-selected=\"handleItemSelected\"\n @see-more=\"emit('see-more', $event)\"\n />\n </li>\n <li v-if=\"hasMoreOptions && !props.readOnly\">\n <PvButton\n class=\"pv-text-brand\"\n variant=\"ghost\"\n label=\"See more\"\n :loading=\"isSeeMoreLoading\"\n :disabled=\"isSeeMoreLoading\"\n data-testid=\"pv-menu-see-more\"\n @click=\"emit('see-more', { parentId: undefined })\"\n />\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\" generic=\"T\">\nimport { watch, useTemplateRef, computed, nextTick, shallowRef, provide } from \"vue\";\nimport { useToggle, onKeyStroke } from \"@vueuse/core\";\n\nimport { PvSearchInputExposed } from \"@/components/base/PvSearchInput/PvSearchInput.vue\";\nimport PvSelectControlPanel from \"../PvMenu/PvMenuControlPanel.vue\";\nimport PvSearchInput from \"../PvSearchInput/PvSearchInput.vue\";\nimport PvSelectButtonTrigger from \"@/components/base/PvSelectButton/PvSelectButtonTrigger/PvSelectButtonTrigger.vue\";\nimport PvMenuEmptyState from \"../PvMenu/PvMenuEmptyState.vue\";\nimport PvMenu from \"../PvMenu/PvMenu.vue\";\nimport PvSpinner from \"@/components/base/PvSpinner/PvSpinner.vue\";\n\nimport { PvMultiSelectButtonProps } from \"./types\";\nimport { MenuOption, MenuOptionConfig, MultiSelectState, SelectionNode, SeeMoreEvent } from \"@/types\";\nimport {\n collectLeafOptions,\n countFromSelectionState,\n countWithCollapsedParents,\n filterOptionsRecursive,\n hasCascadeChildren,\n} from \"../PvMenu/cascadeUtils\";\nimport {\n OriginalOptionsMapKey,\n CascadeSelectedParentIdsKey,\n CascadeDeselectedChildIdsKey,\n ParentSelectsAllChildrenKey,\n EnableChildExpansionKey,\n} from \"../PvMenu/symbols\";\nimport PvPopoverV2 from \"@/components/base/PvPopoverV2/PvPopoverV2.vue\";\nimport { useSlotPresence } from \"@/composables/useSlotPresence\";\n\nconst props = withDefaults(defineProps<PvMultiSelectButtonProps<T>>(), {\n counterPosition: \"left\",\n variant: \"secondary\",\n size: \"lg\",\n label: \"Select\",\n disableDropdownIcon: false,\n disableClearIcon: false,\n disableSearchInput: false,\n readOnly: false,\n optionsVariant: \"checkbox\",\n options: () => [] as MenuOption<T>[],\n menuActionsVariant: \"select-clear\",\n highlightSearchText: false,\n enableCascadeSelection: false,\n counterStyle: \"primary\",\n});\n\nconst optionConfig = computed(() => {\n const config: MenuOptionConfig = {\n renderer: props.optionsRenderer,\n action: props.optionsAction,\n variant: props.optionsVariant,\n counterBadgeVariant: props.counterBadgeVariant,\n };\n return config;\n});\n\n// Build a map from option id → original (unfiltered) option so that descendants\n// can look up the full children list when parentSelectsAllChildren is true.\nconst originalOptionsMap = computed(() => {\n const map = new Map<string, MenuOption<T>>();\n const buildMap = (options: MenuOption<T>[]) => {\n for (const option of options) {\n map.set(option.id, option);\n if (option.children?.length) buildMap(option.children);\n }\n };\n buildMap(props.options);\n return map;\n});\n\nconst cascadeSelectedParentIds = shallowRef<Set<string>>(new Set());\nconst cascadeDeselectedChildIds = shallowRef<Map<string, Set<string>>>(new Map());\n\nprovide(OriginalOptionsMapKey, originalOptionsMap);\nprovide(CascadeSelectedParentIdsKey, cascadeSelectedParentIds);\nprovide(CascadeDeselectedChildIdsKey, cascadeDeselectedChildIds);\nprovide(\n ParentSelectsAllChildrenKey,\n computed(() => props.parentSelectsAllChildren),\n);\nprovide(\n EnableChildExpansionKey,\n computed(() => !!props.enableChildExpansion),\n);\n\nconst emits = defineEmits<{\n (e: \"dropdown-open\"): void;\n (e: \"dropdown-closed\"): void;\n (e: \"see-more\", payload: SeeMoreEvent): void;\n}>();\n\n/** Pre-computed mapping of parent option ID → its leaf descendant options. */\nconst parentLeafMap = computed(() => {\n const map = new Map<string, MenuOption<T>[]>();\n for (const [id, option] of originalOptionsMap.value) {\n if (hasCascadeChildren(option)) {\n map.set(id, option.children ? collectLeafOptions(option.children) : []);\n }\n }\n return map;\n});\n\nconst getSelectionState = (): MultiSelectState => {\n const parentLeafIds = new Set<string>();\n if (cascadeSelectedParentIds.value.size > 0) {\n for (const parentId of cascadeSelectedParentIds.value) {\n const leaves = parentLeafMap.value.get(parentId);\n if (leaves) {\n for (const leaf of leaves) parentLeafIds.add(leaf.id);\n }\n }\n }\n\n const nodes: SelectionNode[] = [];\n\n for (const parentId of cascadeSelectedParentIds.value) {\n const deselected = cascadeDeselectedChildIds.value.get(parentId);\n const node: SelectionNode = { id: parentId, state: \"selected\" };\n if (deselected?.size) {\n node.children = [...deselected].map((childId) => ({\n id: childId,\n state: \"deselected\" as const,\n }));\n }\n nodes.push(node);\n }\n\n for (const item of selectedItems.value) {\n if (!parentLeafIds.has(item.id)) {\n nodes.push({ id: item.id, state: \"selected\" });\n }\n }\n\n return nodes;\n};\n\nconst hasMoreOptions = computed(() => {\n if (props.hasMoreOptions != null) return props.hasMoreOptions;\n if (props.totalOptionCount == null) return false;\n return props.totalOptionCount > props.options.length;\n});\n\nconst counterValue = computed(() => {\n const additional = props.additionalCounter ?? 0;\n if (props.enableCascadeSelection && props.countSelectedParents && modelSelectionState.value?.length) {\n return countFromSelectionState(modelSelectionState.value) + additional;\n }\n if (!props.countSelectedParents || !props.enableCascadeSelection) {\n return selectedItems.value.length + additional;\n }\n const selectedIds = new Set(selectedItems.value.map((item) => item.id));\n return countWithCollapsedParents(props.options, selectedIds) + additional;\n});\n\nconst hasSelection = computed(() => {\n if (selectedItems.value.length > 0) return true;\n if (props.enableCascadeSelection && modelSelectionState.value?.length) {\n return modelSelectionState.value.some((node) => node.state === \"selected\");\n }\n return false;\n});\n\nconst handleSeeMore = (payload?: SeeMoreEvent) => {\n emits(\"see-more\", payload ?? {});\n};\n\nconst searchInputComponentRef = useTemplateRef<PvSearchInputExposed | null>(\"searchInputRef\");\n\nconst [open, handleOpen] = useToggle<boolean>(props.defaultOpen);\nconst modelSelectedItems = defineModel<MenuOption<T>[]>({\n required: false,\n default: () => [],\n});\nconst modelSelectionState = defineModel<MultiSelectState>(\"selectionState\");\nconst searchInput = defineModel<string>(\"searchInput\", {\n required: false,\n default: \"\",\n});\n\nconst suppressChangesUntilConfirmed = computed(() => {\n return props.menuActionsVariant === \"cancel-confirm\";\n});\n\nconst storeSelectedItems = (newSelection: MenuOption<T>[]) => {\n selectedItems.value = newSelection;\n if (!suppressChangesUntilConfirmed.value) {\n modelSelectedItems.value = newSelection;\n modelSelectionState.value = getSelectionState();\n }\n};\n\nconst applyPendingSelection = () => {\n if (suppressChangesUntilConfirmed.value) {\n modelSelectedItems.value = selectedItems.value;\n modelSelectionState.value = getSelectionState();\n }\n};\n\nconst resetPendingSelection = () => {\n if (suppressChangesUntilConfirmed.value) {\n selectedItems.value = modelSelectedItems.value;\n }\n};\n\n// with cancel-confirm, we hold changes until confirmed\nconst selectedItems = shallowRef<MenuOption<T>[]>(modelSelectedItems.value);\n\nconst findOptionById = (id: string): MenuOption<T> | undefined => originalOptionsMap.value.get(id);\n\nconst syncFromSelectionState = (state: MultiSelectState | undefined) => {\n if (!props.enableCascadeSelection || !state) return;\n\n const nextSelectedParents = new Set<string>();\n const nextDeselectedChildren = new Map<string, Set<string>>();\n const nextSelectedItems: MenuOption<T>[] = [];\n const selectedIds = new Set<string>();\n\n const addSelectedItem = (option: MenuOption<T> | undefined, id: string) => {\n if (selectedIds.has(id)) return;\n selectedIds.add(id);\n // Placeholder for unresolved nodes — the trigger badge prefers `…` over the\n // raw scoped token (e.g. `__provider_id__PV_1004__health_system__Kaiser`)\n // until the props.options watcher re-runs this sync with metadata loaded.\n nextSelectedItems.push(option ?? ({ id, text: \"…\" } as MenuOption<T>));\n };\n\n for (const node of state) {\n if (node.state !== \"selected\") continue;\n\n const deselectedIds = new Set(\n (node.children || []).filter((child) => child.state === \"deselected\").map((child) => child.id),\n );\n const leafOptions = parentLeafMap.value.get(node.id);\n\n if (leafOptions) {\n nextSelectedParents.add(node.id);\n if (deselectedIds.size > 0) {\n nextDeselectedChildren.set(node.id, deselectedIds);\n }\n for (const leaf of leafOptions) {\n if (!deselectedIds.has(leaf.id)) {\n addSelectedItem(leaf, leaf.id);\n }\n }\n continue;\n }\n\n addSelectedItem(findOptionById(node.id), node.id);\n }\n\n cascadeSelectedParentIds.value = nextSelectedParents;\n cascadeDeselectedChildIds.value = nextDeselectedChildren;\n selectedItems.value = nextSelectedItems;\n};\n\nconst menuSelectedItems = computed({\n get: () => selectedItems.value,\n set: (newValue: MenuOption<T>[]) => {\n if (!props.readOnly) storeSelectedItems(newValue);\n },\n});\n\nconst closeDropdown = () => {\n searchInput.value = \"\";\n open.value = false;\n};\n\nconst popoverOffset = computed(() => {\n // get width of trigger element to offset popover correctly when overlay trigger is enabled\n const size = props.size === \"lg\" ? 24 : 30;\n return props.overlayTrigger ? -size : undefined;\n});\n\n// sync when parent updates modelSelectedItems directly\nwatch(\n () => modelSelectedItems.value,\n (newValue) => {\n if (props.enableCascadeSelection && modelSelectionState.value?.length && newValue.length === 0) {\n syncFromSelectionState(modelSelectionState.value);\n return;\n }\n selectedItems.value = newValue;\n },\n);\n\nwatch(\n () => [modelSelectionState.value, props.options] as const,\n () => {\n syncFromSelectionState(modelSelectionState.value);\n },\n { deep: true, immediate: true },\n);\n\nwatch(open, (newValue) => {\n if (newValue) {\n resetPendingSelection();\n nextTick(() => {\n // if overlay trigger is enabled and search input exists, auto-target the search input\n if (props.overlayTrigger && !props.disableSearchInput) {\n searchInputComponentRef.value?.input?.focus();\n }\n emits(\"dropdown-open\");\n });\n } else {\n // on close, discard pending changes\n resetPendingSelection();\n emits(\"dropdown-closed\");\n }\n});\n\nconst filteredOptions = computed(() => {\n if (searchInput.value === \"\") return props.options;\n const searchValue = searchInput.value.toLocaleLowerCase();\n\n if (props.enableCascadeSelection) {\n return filterOptionsRecursive(props.options, searchValue, !props.hideParentOnChildQueryMatch);\n }\n\n return props.options.filter(\n (option) =>\n option.text.toLocaleLowerCase().includes(searchValue) ||\n option.searchText?.toLocaleLowerCase().includes(searchValue),\n );\n});\n\nconst handleSelectAll = () => {\n // Mark all parents as cascade-selected (select-all intent) before\n // storing so the selection state snapshot is accurate.\n if (props.enableCascadeSelection) {\n const parentIds = new Set<string>();\n const collectParentIds = (options: MenuOption<T>[]) => {\n for (const option of options) {\n if (hasCascadeChildren(option)) {\n parentIds.add(option.id);\n if (option.children?.length) collectParentIds(option.children);\n }\n }\n };\n collectParentIds(filteredOptions.value as MenuOption<T>[]);\n cascadeSelectedParentIds.value = parentIds;\n cascadeDeselectedChildIds.value = new Map();\n }\n\n // select all visible item values (excluded ones filtered out by search)\n const toSelect = props.enableCascadeSelection\n ? collectLeafOptions(filteredOptions.value as MenuOption<T>[])\n : filteredOptions.value;\n storeSelectedItems(toSelect);\n};\n\nconst handleClearAll = () => {\n cascadeSelectedParentIds.value = new Set();\n cascadeDeselectedChildIds.value = new Map();\n storeSelectedItems([]);\n};\n\nconst handleCancelSelection = () => {\n resetPendingSelection();\n closeDropdown();\n};\n\nconst handleConfirmSelection = () => {\n applyPendingSelection();\n closeDropdown();\n};\n\nconst groupingOptions = computed(() => {\n if (!props.groupings) return;\n\n const groupingMap = new Map<string, MenuOption[]>();\n\n props.groupings.forEach((group) => {\n groupingMap.set(group, []);\n });\n\n groupingMap.set(\"other\", []);\n\n for (const option of props.options) {\n const groupKey = option.groupingLabel;\n const targetGroup = groupKey && groupingMap.has(groupKey) ? groupKey : \"other\";\n groupingMap.get(targetGroup)!.push(option);\n }\n\n for (const [key, options] of groupingMap) {\n if (options.length === 0) {\n groupingMap.delete(key);\n }\n }\n\n return Array.from(groupingMap.entries());\n});\n\nconst showGroupings = computed(() => {\n return props.groupings && searchInput.value === \"\";\n});\n\nconst allSlotProps = computed(() => ({\n ...props,\n selectedItems: modelSelectedItems.value,\n searchInput: searchInput.value,\n slotContext: props.slotContext,\n isOpen: open.value,\n isLoading: props.isLoading,\n}));\n\nconst popoverContentRef = useTemplateRef<HTMLElement | null>(\"popoverContentRef\");\nconst slotHost = computed(() => {\n const rootNode = popoverContentRef.value?.getRootNode();\n return rootNode instanceof ShadowRoot ? (rootNode.host as HTMLElement) : null;\n});\nconst { present: hasHeaderSlot } = useSlotPresence(\"header\", { host: slotHost });\nconst { present: hasNoResultsSlot } = useSlotPresence(\"no-results\", { host: slotHost });\nconst { present: hasFooterSlot } = useSlotPresence(\"footer\", { host: slotHost });\n\nonKeyStroke(\"Escape\", () => {\n if (!open.value) return;\n\n closeDropdown();\n});\n</script>\n\n<template>\n <PvPopoverV2 v-model=\"open\" v-bind=\"popoverProperties\" :offset=\"popoverOffset\">\n <template #trigger>\n <PvSelectButtonTrigger\n ref=\"select-button-trigger-ref\"\n :variant=\"variant\"\n :size=\"size\"\n :disabled=\"disabled\"\n :counterPosition=\"counterPosition\"\n :prefixLabel=\"prefixLabel\"\n :label=\"label\"\n :icon=\"icon\"\n :companyLogo=\"companyLogo\"\n :showClear=\"!disableClearIcon && hasSelection\"\n :showDropdown=\"!disableDropdownIcon && !hasSelection\"\n :open=\"open\"\n :counter-value=\"counterValue\"\n :counter-style=\"counterStyle\"\n :selected-items=\"selectedItems\"\n @handle-clear=\"handleClearAll\"\n @handle-toggle-dropdown=\"handleOpen()\"\n />\n </template>\n <template #content>\n <div\n ref=\"popoverContentRef\"\n class=\"pv-popover\"\n data-test-id=\"pv-popover\"\n :style=\"{ '--position': 'unset', ...popoverCssProperties }\"\n >\n <template v-if=\"!disableSearchInput\">\n <div class=\"pv-inset-square-8 pv-border-bottom\">\n <PvSearchInput\n ref=\"searchInputRef\"\n v-model:model-value=\"searchInput\"\n class=\"pv-stack-4\"\n :placeholder=\"searchPlaceholder\"\n :disabled=\"readOnly\"\n />\n </div>\n </template>\n <div v-if=\"hasHeaderSlot\" class=\"pv-inset-square-8\">\n <slot name=\"header\" v-bind=\"allSlotProps\" />\n </div>\n <template v-if=\"filteredOptions.length > 0\">\n <template v-if=\"showGroupings\">\n <div v-for=\"([label, options], index) in groupingOptions\" :key=\"label\">\n <slot v-if=\"$slots[label]\" :name=\"label\" />\n <span\n class=\"pv-text-body-sm pv-inset-inline\"\n style=\"color: #89989b; --inset-size: 8px\"\n v-else-if=\"label !== 'other'\"\n >{{ label }}</span\n >\n <PvMenu\n v-model:selectedItems=\"menuSelectedItems\"\n :options=\"options\"\n :config=\"optionConfig\"\n :queryText=\"highlightSearchText ? searchInput : null\"\n :itemTestId=\"`pv-multiselect-${label}-item`\"\n itemClass=\"pv-stack-4\"\n :isLoading=\"isLoading\"\n :isSeeMoreLoading=\"isSeeMoreLoading\"\n :enableCascadeSelection=\"enableCascadeSelection\"\n :hasMoreOptions=\"index === groupingOptions!.length - 1 && hasMoreOptions && !isLoading\"\n :readOnly=\"readOnly\"\n @see-more=\"handleSeeMore\"\n />\n <div\n v-if=\"groupingOptions && index !== groupingOptions.length - 1\"\n class=\"pv-border-top\"\n style=\"margin: 8px 0\"\n />\n </div>\n </template>\n <template v-else>\n <PvMenu\n v-model:selectedItems=\"menuSelectedItems\"\n :options=\"filteredOptions\"\n :config=\"optionConfig\"\n :queryText=\"highlightSearchText ? searchInput : null\"\n :itemTestId=\"`pv-multiselect-${label}-item`\"\n itemClass=\"pv-stack-4\"\n :enableCascadeSelection=\"enableCascadeSelection\"\n :isSeeMoreLoading=\"isSeeMoreLoading\"\n :hasMoreOptions=\"hasMoreOptions && !isLoading\"\n :readOnly=\"readOnly\"\n @see-more=\"handleSeeMore\"\n />\n </template>\n </template>\n <div v-if=\"isLoading\" class=\"pv-flex pv-inset-square-8\" style=\"justify-content: center\">\n <PvSpinner variant=\"dark\" />\n </div>\n <template v-else-if=\"filteredOptions.length === 0\">\n <slot v-if=\"hasNoResultsSlot\" name=\"no-results\" v-bind=\"allSlotProps\" />\n <PvMenuEmptyState v-else />\n </template>\n <div\n class=\"pv-sticky pv-surface pv-border-top pv-inset-square-8\"\n style=\"--flex-justify: space-between; --bottom: 0\"\n >\n <slot v-if=\"hasFooterSlot\" name=\"footer\" v-bind=\"allSlotProps\" />\n <PvSelectControlPanel\n v-if=\"menuActionsVariant && !readOnly\"\n :variant=\"menuActionsVariant\"\n :disabled=\"isLoading\"\n @handle-clear-all=\"handleClearAll\"\n @handle-select-all=\"handleSelectAll\"\n @handle-cancel=\"handleCancelSelection\"\n @handle-confirm=\"handleConfirmSelection\"\n />\n </div>\n </div>\n </template>\n </PvPopoverV2>\n</template>\n","<script setup lang=\"ts\" generic=\"T\">\nimport { watch, useTemplateRef, computed, nextTick, shallowRef, provide } from \"vue\";\nimport { useToggle, onKeyStroke } from \"@vueuse/core\";\n\nimport { PvSearchInputExposed } from \"@/components/base/PvSearchInput/PvSearchInput.vue\";\nimport PvSelectControlPanel from \"../PvMenu/PvMenuControlPanel.vue\";\nimport PvSearchInput from \"../PvSearchInput/PvSearchInput.vue\";\nimport PvSelectButtonTrigger from \"@/components/base/PvSelectButton/PvSelectButtonTrigger/PvSelectButtonTrigger.vue\";\nimport PvMenuEmptyState from \"../PvMenu/PvMenuEmptyState.vue\";\nimport PvMenu from \"../PvMenu/PvMenu.vue\";\nimport PvSpinner from \"@/components/base/PvSpinner/PvSpinner.vue\";\n\nimport { PvMultiSelectButtonProps } from \"./types\";\nimport { MenuOption, MenuOptionConfig, MultiSelectState, SelectionNode, SeeMoreEvent } from \"@/types\";\nimport {\n collectLeafOptions,\n countFromSelectionState,\n countWithCollapsedParents,\n filterOptionsRecursive,\n hasCascadeChildren,\n} from \"../PvMenu/cascadeUtils\";\nimport {\n OriginalOptionsMapKey,\n CascadeSelectedParentIdsKey,\n CascadeDeselectedChildIdsKey,\n ParentSelectsAllChildrenKey,\n EnableChildExpansionKey,\n} from \"../PvMenu/symbols\";\nimport PvPopoverV2 from \"@/components/base/PvPopoverV2/PvPopoverV2.vue\";\nimport { useSlotPresence } from \"@/composables/useSlotPresence\";\n\nconst props = withDefaults(defineProps<PvMultiSelectButtonProps<T>>(), {\n counterPosition: \"left\",\n variant: \"secondary\",\n size: \"lg\",\n label: \"Select\",\n disableDropdownIcon: false,\n disableClearIcon: false,\n disableSearchInput: false,\n readOnly: false,\n optionsVariant: \"checkbox\",\n options: () => [] as MenuOption<T>[],\n menuActionsVariant: \"select-clear\",\n highlightSearchText: false,\n enableCascadeSelection: false,\n counterStyle: \"primary\",\n});\n\nconst optionConfig = computed(() => {\n const config: MenuOptionConfig = {\n renderer: props.optionsRenderer,\n action: props.optionsAction,\n variant: props.optionsVariant,\n counterBadgeVariant: props.counterBadgeVariant,\n };\n return config;\n});\n\n// Build a map from option id → original (unfiltered) option so that descendants\n// can look up the full children list when parentSelectsAllChildren is true.\nconst originalOptionsMap = computed(() => {\n const map = new Map<string, MenuOption<T>>();\n const buildMap = (options: MenuOption<T>[]) => {\n for (const option of options) {\n map.set(option.id, option);\n if (option.children?.length) buildMap(option.children);\n }\n };\n buildMap(props.options);\n return map;\n});\n\nconst cascadeSelectedParentIds = shallowRef<Set<string>>(new Set());\nconst cascadeDeselectedChildIds = shallowRef<Map<string, Set<string>>>(new Map());\n\nprovide(OriginalOptionsMapKey, originalOptionsMap);\nprovide(CascadeSelectedParentIdsKey, cascadeSelectedParentIds);\nprovide(CascadeDeselectedChildIdsKey, cascadeDeselectedChildIds);\nprovide(\n ParentSelectsAllChildrenKey,\n computed(() => props.parentSelectsAllChildren),\n);\nprovide(\n EnableChildExpansionKey,\n computed(() => !!props.enableChildExpansion),\n);\n\nconst emits = defineEmits<{\n (e: \"dropdown-open\"): void;\n (e: \"dropdown-closed\"): void;\n (e: \"see-more\", payload: SeeMoreEvent): void;\n}>();\n\n/** Pre-computed mapping of parent option ID → its leaf descendant options. */\nconst parentLeafMap = computed(() => {\n const map = new Map<string, MenuOption<T>[]>();\n for (const [id, option] of originalOptionsMap.value) {\n if (hasCascadeChildren(option)) {\n map.set(id, option.children ? collectLeafOptions(option.children) : []);\n }\n }\n return map;\n});\n\nconst getSelectionState = (): MultiSelectState => {\n const parentLeafIds = new Set<string>();\n if (cascadeSelectedParentIds.value.size > 0) {\n for (const parentId of cascadeSelectedParentIds.value) {\n const leaves = parentLeafMap.value.get(parentId);\n if (leaves) {\n for (const leaf of leaves) parentLeafIds.add(leaf.id);\n }\n }\n }\n\n const nodes: SelectionNode[] = [];\n\n for (const parentId of cascadeSelectedParentIds.value) {\n const deselected = cascadeDeselectedChildIds.value.get(parentId);\n const node: SelectionNode = { id: parentId, state: \"selected\" };\n if (deselected?.size) {\n node.children = [...deselected].map((childId) => ({\n id: childId,\n state: \"deselected\" as const,\n }));\n }\n nodes.push(node);\n }\n\n for (const item of selectedItems.value) {\n if (!parentLeafIds.has(item.id)) {\n nodes.push({ id: item.id, state: \"selected\" });\n }\n }\n\n return nodes;\n};\n\nconst hasMoreOptions = computed(() => {\n if (props.hasMoreOptions != null) return props.hasMoreOptions;\n if (props.totalOptionCount == null) return false;\n return props.totalOptionCount > props.options.length;\n});\n\nconst counterValue = computed(() => {\n const additional = props.additionalCounter ?? 0;\n if (props.enableCascadeSelection && props.countSelectedParents && modelSelectionState.value?.length) {\n return countFromSelectionState(modelSelectionState.value) + additional;\n }\n if (!props.countSelectedParents || !props.enableCascadeSelection) {\n return selectedItems.value.length + additional;\n }\n const selectedIds = new Set(selectedItems.value.map((item) => item.id));\n return countWithCollapsedParents(props.options, selectedIds) + additional;\n});\n\nconst hasSelection = computed(() => {\n if (selectedItems.value.length > 0) return true;\n if (props.enableCascadeSelection && modelSelectionState.value?.length) {\n return modelSelectionState.value.some((node) => node.state === \"selected\");\n }\n return false;\n});\n\nconst handleSeeMore = (payload?: SeeMoreEvent) => {\n emits(\"see-more\", payload ?? {});\n};\n\nconst searchInputComponentRef = useTemplateRef<PvSearchInputExposed | null>(\"searchInputRef\");\n\nconst [open, handleOpen] = useToggle<boolean>(props.defaultOpen);\nconst modelSelectedItems = defineModel<MenuOption<T>[]>({\n required: false,\n default: () => [],\n});\nconst modelSelectionState = defineModel<MultiSelectState>(\"selectionState\");\nconst searchInput = defineModel<string>(\"searchInput\", {\n required: false,\n default: \"\",\n});\n\nconst suppressChangesUntilConfirmed = computed(() => {\n return props.menuActionsVariant === \"cancel-confirm\";\n});\n\nconst storeSelectedItems = (newSelection: MenuOption<T>[]) => {\n selectedItems.value = newSelection;\n if (!suppressChangesUntilConfirmed.value) {\n modelSelectedItems.value = newSelection;\n modelSelectionState.value = getSelectionState();\n }\n};\n\nconst applyPendingSelection = () => {\n if (suppressChangesUntilConfirmed.value) {\n modelSelectedItems.value = selectedItems.value;\n modelSelectionState.value = getSelectionState();\n }\n};\n\nconst resetPendingSelection = () => {\n if (suppressChangesUntilConfirmed.value) {\n selectedItems.value = modelSelectedItems.value;\n }\n};\n\n// with cancel-confirm, we hold changes until confirmed\nconst selectedItems = shallowRef<MenuOption<T>[]>(modelSelectedItems.value);\n\nconst findOptionById = (id: string): MenuOption<T> | undefined => originalOptionsMap.value.get(id);\n\nconst syncFromSelectionState = (state: MultiSelectState | undefined) => {\n if (!props.enableCascadeSelection || !state) return;\n\n const nextSelectedParents = new Set<string>();\n const nextDeselectedChildren = new Map<string, Set<string>>();\n const nextSelectedItems: MenuOption<T>[] = [];\n const selectedIds = new Set<string>();\n\n const addSelectedItem = (option: MenuOption<T> | undefined, id: string) => {\n if (selectedIds.has(id)) return;\n selectedIds.add(id);\n // Placeholder for unresolved nodes — the trigger badge prefers `…` over the\n // raw scoped token (e.g. `__provider_id__PV_1004__health_system__Kaiser`)\n // until the props.options watcher re-runs this sync with metadata loaded.\n nextSelectedItems.push(option ?? ({ id, text: \"…\" } as MenuOption<T>));\n };\n\n for (const node of state) {\n if (node.state !== \"selected\") continue;\n\n const deselectedIds = new Set(\n (node.children || []).filter((child) => child.state === \"deselected\").map((child) => child.id),\n );\n const leafOptions = parentLeafMap.value.get(node.id);\n\n if (leafOptions) {\n nextSelectedParents.add(node.id);\n if (deselectedIds.size > 0) {\n nextDeselectedChildren.set(node.id, deselectedIds);\n }\n for (const leaf of leafOptions) {\n if (!deselectedIds.has(leaf.id)) {\n addSelectedItem(leaf, leaf.id);\n }\n }\n continue;\n }\n\n addSelectedItem(findOptionById(node.id), node.id);\n }\n\n cascadeSelectedParentIds.value = nextSelectedParents;\n cascadeDeselectedChildIds.value = nextDeselectedChildren;\n selectedItems.value = nextSelectedItems;\n};\n\nconst menuSelectedItems = computed({\n get: () => selectedItems.value,\n set: (newValue: MenuOption<T>[]) => {\n if (!props.readOnly) storeSelectedItems(newValue);\n },\n});\n\nconst closeDropdown = () => {\n searchInput.value = \"\";\n open.value = false;\n};\n\nconst popoverOffset = computed(() => {\n // get width of trigger element to offset popover correctly when overlay trigger is enabled\n const size = props.size === \"lg\" ? 24 : 30;\n return props.overlayTrigger ? -size : undefined;\n});\n\n// sync when parent updates modelSelectedItems directly\nwatch(\n () => modelSelectedItems.value,\n (newValue) => {\n if (props.enableCascadeSelection && modelSelectionState.value?.length && newValue.length === 0) {\n syncFromSelectionState(modelSelectionState.value);\n return;\n }\n selectedItems.value = newValue;\n },\n);\n\nwatch(\n () => [modelSelectionState.value, props.options] as const,\n () => {\n syncFromSelectionState(modelSelectionState.value);\n },\n { deep: true, immediate: true },\n);\n\nwatch(open, (newValue) => {\n if (newValue) {\n resetPendingSelection();\n nextTick(() => {\n // if overlay trigger is enabled and search input exists, auto-target the search input\n if (props.overlayTrigger && !props.disableSearchInput) {\n searchInputComponentRef.value?.input?.focus();\n }\n emits(\"dropdown-open\");\n });\n } else {\n // on close, discard pending changes\n resetPendingSelection();\n emits(\"dropdown-closed\");\n }\n});\n\nconst filteredOptions = computed(() => {\n if (searchInput.value === \"\") return props.options;\n const searchValue = searchInput.value.toLocaleLowerCase();\n\n if (props.enableCascadeSelection) {\n return filterOptionsRecursive(props.options, searchValue, !props.hideParentOnChildQueryMatch);\n }\n\n return props.options.filter(\n (option) =>\n option.text.toLocaleLowerCase().includes(searchValue) ||\n option.searchText?.toLocaleLowerCase().includes(searchValue),\n );\n});\n\nconst handleSelectAll = () => {\n // Mark all parents as cascade-selected (select-all intent) before\n // storing so the selection state snapshot is accurate.\n if (props.enableCascadeSelection) {\n const parentIds = new Set<string>();\n const collectParentIds = (options: MenuOption<T>[]) => {\n for (const option of options) {\n if (hasCascadeChildren(option)) {\n parentIds.add(option.id);\n if (option.children?.length) collectParentIds(option.children);\n }\n }\n };\n collectParentIds(filteredOptions.value as MenuOption<T>[]);\n cascadeSelectedParentIds.value = parentIds;\n cascadeDeselectedChildIds.value = new Map();\n }\n\n // select all visible item values (excluded ones filtered out by search)\n const toSelect = props.enableCascadeSelection\n ? collectLeafOptions(filteredOptions.value as MenuOption<T>[])\n : filteredOptions.value;\n storeSelectedItems(toSelect);\n};\n\nconst handleClearAll = () => {\n cascadeSelectedParentIds.value = new Set();\n cascadeDeselectedChildIds.value = new Map();\n storeSelectedItems([]);\n};\n\nconst handleCancelSelection = () => {\n resetPendingSelection();\n closeDropdown();\n};\n\nconst handleConfirmSelection = () => {\n applyPendingSelection();\n closeDropdown();\n};\n\nconst groupingOptions = computed(() => {\n if (!props.groupings) return;\n\n const groupingMap = new Map<string, MenuOption[]>();\n\n props.groupings.forEach((group) => {\n groupingMap.set(group, []);\n });\n\n groupingMap.set(\"other\", []);\n\n for (const option of props.options) {\n const groupKey = option.groupingLabel;\n const targetGroup = groupKey && groupingMap.has(groupKey) ? groupKey : \"other\";\n groupingMap.get(targetGroup)!.push(option);\n }\n\n for (const [key, options] of groupingMap) {\n if (options.length === 0) {\n groupingMap.delete(key);\n }\n }\n\n return Array.from(groupingMap.entries());\n});\n\nconst showGroupings = computed(() => {\n return props.groupings && searchInput.value === \"\";\n});\n\nconst allSlotProps = computed(() => ({\n ...props,\n selectedItems: modelSelectedItems.value,\n searchInput: searchInput.value,\n slotContext: props.slotContext,\n isOpen: open.value,\n isLoading: props.isLoading,\n}));\n\nconst popoverContentRef = useTemplateRef<HTMLElement | null>(\"popoverContentRef\");\nconst slotHost = computed(() => {\n const rootNode = popoverContentRef.value?.getRootNode();\n return rootNode instanceof ShadowRoot ? (rootNode.host as HTMLElement) : null;\n});\nconst { present: hasHeaderSlot } = useSlotPresence(\"header\", { host: slotHost });\nconst { present: hasNoResultsSlot } = useSlotPresence(\"no-results\", { host: slotHost });\nconst { present: hasFooterSlot } = useSlotPresence(\"footer\", { host: slotHost });\n\nonKeyStroke(\"Escape\", () => {\n if (!open.value) return;\n\n closeDropdown();\n});\n</script>\n\n<template>\n <PvPopoverV2 v-model=\"open\" v-bind=\"popoverProperties\" :offset=\"popoverOffset\">\n <template #trigger>\n <PvSelectButtonTrigger\n ref=\"select-button-trigger-ref\"\n :variant=\"variant\"\n :size=\"size\"\n :disabled=\"disabled\"\n :counterPosition=\"counterPosition\"\n :prefixLabel=\"prefixLabel\"\n :label=\"label\"\n :icon=\"icon\"\n :companyLogo=\"companyLogo\"\n :showClear=\"!disableClearIcon && hasSelection\"\n :showDropdown=\"!disableDropdownIcon && !hasSelection\"\n :open=\"open\"\n :counter-value=\"counterValue\"\n :counter-style=\"counterStyle\"\n :selected-items=\"selectedItems\"\n @handle-clear=\"handleClearAll\"\n @handle-toggle-dropdown=\"handleOpen()\"\n />\n </template>\n <template #content>\n <div\n ref=\"popoverContentRef\"\n class=\"pv-popover\"\n data-test-id=\"pv-popover\"\n :style=\"{ '--position': 'unset', ...popoverCssProperties }\"\n >\n <template v-if=\"!disableSearchInput\">\n <div class=\"pv-inset-square-8 pv-border-bottom\">\n <PvSearchInput\n ref=\"searchInputRef\"\n v-model:model-value=\"searchInput\"\n class=\"pv-stack-4\"\n :placeholder=\"searchPlaceholder\"\n :disabled=\"readOnly\"\n />\n </div>\n </template>\n <div v-if=\"hasHeaderSlot\" class=\"pv-inset-square-8\">\n <slot name=\"header\" v-bind=\"allSlotProps\" />\n </div>\n <template v-if=\"filteredOptions.length > 0\">\n <template v-if=\"showGroupings\">\n <div v-for=\"([label, options], index) in groupingOptions\" :key=\"label\">\n <slot v-if=\"$slots[label]\" :name=\"label\" />\n <span\n class=\"pv-text-body-sm pv-inset-inline\"\n style=\"color: #89989b; --inset-size: 8px\"\n v-else-if=\"label !== 'other'\"\n >{{ label }}</span\n >\n <PvMenu\n v-model:selectedItems=\"menuSelectedItems\"\n :options=\"options\"\n :config=\"optionConfig\"\n :queryText=\"highlightSearchText ? searchInput : null\"\n :itemTestId=\"`pv-multiselect-${label}-item`\"\n itemClass=\"pv-stack-4\"\n :isLoading=\"isLoading\"\n :isSeeMoreLoading=\"isSeeMoreLoading\"\n :enableCascadeSelection=\"enableCascadeSelection\"\n :hasMoreOptions=\"index === groupingOptions!.length - 1 && hasMoreOptions && !isLoading\"\n :readOnly=\"readOnly\"\n @see-more=\"handleSeeMore\"\n />\n <div\n v-if=\"groupingOptions && index !== groupingOptions.length - 1\"\n class=\"pv-border-top\"\n style=\"margin: 8px 0\"\n />\n </div>\n </template>\n <template v-else>\n <PvMenu\n v-model:selectedItems=\"menuSelectedItems\"\n :options=\"filteredOptions\"\n :config=\"optionConfig\"\n :queryText=\"highlightSearchText ? searchInput : null\"\n :itemTestId=\"`pv-multiselect-${label}-item`\"\n itemClass=\"pv-stack-4\"\n :enableCascadeSelection=\"enableCascadeSelection\"\n :isSeeMoreLoading=\"isSeeMoreLoading\"\n :hasMoreOptions=\"hasMoreOptions && !isLoading\"\n :readOnly=\"readOnly\"\n @see-more=\"handleSeeMore\"\n />\n </template>\n </template>\n <div v-if=\"isLoading\" class=\"pv-flex pv-inset-square-8\" style=\"justify-content: center\">\n <PvSpinner variant=\"dark\" />\n </div>\n <template v-else-if=\"filteredOptions.length === 0\">\n <slot v-if=\"hasNoResultsSlot\" name=\"no-results\" v-bind=\"allSlotProps\" />\n <PvMenuEmptyState v-else />\n </template>\n <div\n class=\"pv-sticky pv-surface pv-border-top pv-inset-square-8\"\n style=\"--flex-justify: space-between; --bottom: 0\"\n >\n <slot v-if=\"hasFooterSlot\" name=\"footer\" v-bind=\"allSlotProps\" />\n <PvSelectControlPanel\n v-if=\"menuActionsVariant && !readOnly\"\n :variant=\"menuActionsVariant\"\n :disabled=\"isLoading\"\n @handle-clear-all=\"handleClearAll\"\n @handle-select-all=\"handleSelectAll\"\n @handle-cancel=\"handleCancelSelection\"\n @handle-confirm=\"handleConfirmSelection\"\n />\n </div>\n </div>\n </template>\n </PvPopoverV2>\n</template>\n","<script setup lang=\"ts\" generic=\"T\">\nimport { watch, computed } from \"vue\";\nimport type { CSSProperties, Component } from \"vue\";\n\nimport { useToggle, onKeyStroke } from \"@vueuse/core\";\n\nimport PvSearchInput from \"../PvSearchInput/PvSearchInput.vue\";\nimport PvSelectButtonTrigger from \"@/components/base/PvSelectButton/PvSelectButtonTrigger/PvSelectButtonTrigger.vue\";\nimport PvMenuEmptyState from \"../PvMenu/PvMenuEmptyState.vue\";\n\nimport type { PvSelectButtonSize, PvSelectButtonVariant } from \"./types\";\nimport type { MenuAction, MenuOption, MenuOptionConfig, MenuOptionsVariant } from \"@/types\";\nimport type { PvCounterBadgeVariant } from \"../PvCounterBadge/types\";\nimport type { PvPopoverV2Props } from \"@/components/base/PvPopoverV2/types.ts\";\nimport PvPopoverV2 from \"@/components/base/PvPopoverV2/PvPopoverV2.vue\";\nimport PvMenu from \"@/components/base/PvMenu/PvMenu.vue\";\n\nexport interface PvSelectButtonProps<T = unknown> {\n /** Whether the dropdown is open on initial render */\n defaultOpen?: boolean;\n /** Prevent the button from being clicked */\n disabled?: boolean;\n /** Show a loading state on the trigger button */\n isLoading?: boolean;\n /** Visual style of the trigger button */\n variant?: PvSelectButtonVariant;\n /** Inverse button colors for dark backgrounds */\n inverse?: boolean;\n /** Size of the trigger button */\n size?: PvSelectButtonSize;\n /** Configuration passed to the underlying PvPopoverV2 */\n popoverProperties?: PvPopoverV2Props;\n /** Custom CSS properties applied to the popover container */\n popoverCssProperties?: CSSProperties;\n /** Static text shown before the label on the trigger button */\n prefixLabel?: string;\n /** Text label on the trigger button; updates to the selected option's text when an item is chosen */\n label?: string;\n /** Hide the search input inside the dropdown */\n disableSearchInput?: boolean;\n /** Placeholder text for the search input */\n searchPlaceholder?: string;\n /** Visual style of menu options (simple, icon, company, avatar, radio) */\n optionsVariant?: Exclude<MenuOptionsVariant, \"checkbox\">;\n /** The list of selectable options */\n options?: MenuOption<T>[];\n /** Custom Vue component used to render each option */\n optionsRenderer?: Component;\n /** Action configuration for per-option action buttons */\n optionsAction?: MenuAction<T>;\n /** Prevent deselecting the currently selected item */\n disableDeselect?: boolean;\n /** Where to place the counter badge on the trigger */\n counterPosition?: \"left\" | \"right\";\n /** Variant of the counter badge which appears on the button and menu items */\n counterBadgeVariant?: PvCounterBadgeVariant;\n /** Whether to highlight the search text in the options list */\n highlightSearchText?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvSelectButtonProps<T>>(), {\n variant: \"secondary\",\n size: \"lg\",\n label: \"Select an option\",\n disableDeselect: false,\n disableSearchInput: false,\n optionsVariant: \"simple\",\n options: () => [] as MenuOption<T>[],\n highlightSearchText: false,\n});\n\nconst optionConfig = computed(() => {\n const config: MenuOptionConfig = {\n renderer: props.optionsRenderer,\n action: props.optionsAction,\n variant: props.optionsVariant,\n counterBadgeVariant: props.counterBadgeVariant,\n };\n return config;\n});\n\nconst emits = defineEmits<{\n (e: \"dropdown-open\"): void;\n (e: \"dropdown-closed\"): void;\n}>();\n\nconst [open] = useToggle<boolean>(props.defaultOpen);\nconst selectedItem = defineModel<MenuOption>({ required: false });\nconst searchInput = defineModel<string>(\"searchInput\", {\n required: false,\n default: \"\",\n});\n\nwatch(open, (newValue) => {\n if (newValue) {\n emits(\"dropdown-open\");\n } else {\n emits(\"dropdown-closed\");\n }\n});\n\nconst buttonDisplayLabel = computed(() => {\n if (selectedItem.value && selectedItem.value.text) {\n return selectedItem.value.text;\n }\n return props.label;\n});\n\nconst buttonIcon = computed(() => {\n if (selectedItem.value && selectedItem.value.icon) {\n return selectedItem.value.icon;\n }\n return undefined;\n});\n\nconst buttonCompanyLogo = computed(() => {\n if (selectedItem.value && selectedItem.value.companyName) {\n return selectedItem.value.companyName;\n }\n return undefined;\n});\n\nconst buttonAvatar = computed(() => selectedItem.value?.avatar);\n\nconst filteredOptions = computed(() => {\n const searchValue = searchInput.value.trim().toLowerCase();\n if (!searchValue) return props.options;\n\n const searchRecursive = (options: MenuOption[]): MenuOption[] => {\n const result: MenuOption[] = [];\n\n for (const option of options) {\n const matches =\n option.text.toLowerCase().includes(searchValue) || option.searchText?.toLowerCase().includes(searchValue);\n const filteredChildren = searchRecursive(option.children || []);\n\n if (matches) {\n // Parent matches → keep parent, with filtered children\n result.push({\n ...option,\n searchText: searchValue,\n children: filteredChildren,\n });\n } else {\n // Parent does NOT match:\n result.push(...filteredChildren);\n }\n }\n\n return result;\n };\n\n return searchRecursive(props.options);\n});\n\nconst menuSelectedItems = computed({\n get: () => (selectedItem.value ? [selectedItem.value] : []),\n set: (items: MenuOption[]) => {\n if (props.optionsVariant === \"radio\" || props.disableDeselect) {\n if (items.length > 0) {\n selectedItem.value = items[0];\n }\n } else {\n selectedItem.value = items.length > 0 ? items[0] : undefined;\n }\n },\n});\n\nconst handleSelectItem = () => {\n closeDropdown();\n};\n\nconst handleClear = () => {\n selectedItem.value = undefined;\n};\n\nconst closeDropdown = () => {\n open.value = false;\n searchInput.value = \"\";\n};\n\nonKeyStroke(\"Escape\", () => {\n if (!open.value) return;\n\n closeDropdown();\n});\n</script>\n\n<template>\n <PvPopoverV2 v-model=\"open\" v-bind=\"popoverProperties\">\n <template #trigger>\n <PvSelectButtonTrigger\n class=\"pv-full-width\"\n ref=\"select-button-trigger-ref\"\n :variant=\"variant\"\n :inverse=\"inverse\"\n :size=\"size\"\n :disabled=\"disabled\"\n :prefixLabel=\"prefixLabel\"\n :label=\"buttonDisplayLabel\"\n :icon=\"buttonIcon\"\n :companyLogo=\"buttonCompanyLogo\"\n :avatar=\"buttonAvatar\"\n :showClear=\"false\"\n :showDropdown=\"true\"\n :open=\"open\"\n :counter-position=\"counterPosition\"\n :counter-value=\"\n selectedItem?.secondaryText && typeof selectedItem.secondaryText === 'number'\n ? selectedItem.secondaryText\n : undefined\n \"\n :counter-badge-variant=\"counterBadgeVariant\"\n :isLoading=\"isLoading\"\n :menuOptionConfig=\"optionConfig\"\n :renderer=\"optionsRenderer\"\n :selectedOption=\"selectedItem\"\n @handle-clear=\"handleClear\"\n />\n </template>\n <template #content>\n <div class=\"pv-popover\" data-test-id=\"pv-popover\" :style=\"popoverCssProperties\" style=\"position: unset\">\n <template v-if=\"!disableSearchInput\">\n <div class=\"pv-inset-square-8 pv-border-bottom\">\n <PvSearchInput v-model:model-value=\"searchInput\" class=\"pv-stack-4\" :placeholder=\"searchPlaceholder\" />\n </div>\n </template>\n <template v-if=\"filteredOptions.length > 0\">\n <PvMenu\n v-model:selectedItems=\"menuSelectedItems\"\n :options=\"filteredOptions\"\n :config=\"optionConfig\"\n :queryText=\"highlightSearchText ? searchInput : null\"\n :singleSelect=\"true\"\n @handle-selected=\"handleSelectItem\"\n />\n </template>\n <PvMenuEmptyState v-else />\n </div>\n </template>\n </PvPopoverV2>\n</template>\n","<script setup lang=\"ts\" generic=\"T\">\nimport { watch, computed } from \"vue\";\nimport type { CSSProperties, Component } from \"vue\";\n\nimport { useToggle, onKeyStroke } from \"@vueuse/core\";\n\nimport PvSearchInput from \"../PvSearchInput/PvSearchInput.vue\";\nimport PvSelectButtonTrigger from \"@/components/base/PvSelectButton/PvSelectButtonTrigger/PvSelectButtonTrigger.vue\";\nimport PvMenuEmptyState from \"../PvMenu/PvMenuEmptyState.vue\";\n\nimport type { PvSelectButtonSize, PvSelectButtonVariant } from \"./types\";\nimport type { MenuAction, MenuOption, MenuOptionConfig, MenuOptionsVariant } from \"@/types\";\nimport type { PvCounterBadgeVariant } from \"../PvCounterBadge/types\";\nimport type { PvPopoverV2Props } from \"@/components/base/PvPopoverV2/types.ts\";\nimport PvPopoverV2 from \"@/components/base/PvPopoverV2/PvPopoverV2.vue\";\nimport PvMenu from \"@/components/base/PvMenu/PvMenu.vue\";\n\nexport interface PvSelectButtonProps<T = unknown> {\n /** Whether the dropdown is open on initial render */\n defaultOpen?: boolean;\n /** Prevent the button from being clicked */\n disabled?: boolean;\n /** Show a loading state on the trigger button */\n isLoading?: boolean;\n /** Visual style of the trigger button */\n variant?: PvSelectButtonVariant;\n /** Inverse button colors for dark backgrounds */\n inverse?: boolean;\n /** Size of the trigger button */\n size?: PvSelectButtonSize;\n /** Configuration passed to the underlying PvPopoverV2 */\n popoverProperties?: PvPopoverV2Props;\n /** Custom CSS properties applied to the popover container */\n popoverCssProperties?: CSSProperties;\n /** Static text shown before the label on the trigger button */\n prefixLabel?: string;\n /** Text label on the trigger button; updates to the selected option's text when an item is chosen */\n label?: string;\n /** Hide the search input inside the dropdown */\n disableSearchInput?: boolean;\n /** Placeholder text for the search input */\n searchPlaceholder?: string;\n /** Visual style of menu options (simple, icon, company, avatar, radio) */\n optionsVariant?: Exclude<MenuOptionsVariant, \"checkbox\">;\n /** The list of selectable options */\n options?: MenuOption<T>[];\n /** Custom Vue component used to render each option */\n optionsRenderer?: Component;\n /** Action configuration for per-option action buttons */\n optionsAction?: MenuAction<T>;\n /** Prevent deselecting the currently selected item */\n disableDeselect?: boolean;\n /** Where to place the counter badge on the trigger */\n counterPosition?: \"left\" | \"right\";\n /** Variant of the counter badge which appears on the button and menu items */\n counterBadgeVariant?: PvCounterBadgeVariant;\n /** Whether to highlight the search text in the options list */\n highlightSearchText?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvSelectButtonProps<T>>(), {\n variant: \"secondary\",\n size: \"lg\",\n label: \"Select an option\",\n disableDeselect: false,\n disableSearchInput: false,\n optionsVariant: \"simple\",\n options: () => [] as MenuOption<T>[],\n highlightSearchText: false,\n});\n\nconst optionConfig = computed(() => {\n const config: MenuOptionConfig = {\n renderer: props.optionsRenderer,\n action: props.optionsAction,\n variant: props.optionsVariant,\n counterBadgeVariant: props.counterBadgeVariant,\n };\n return config;\n});\n\nconst emits = defineEmits<{\n (e: \"dropdown-open\"): void;\n (e: \"dropdown-closed\"): void;\n}>();\n\nconst [open] = useToggle<boolean>(props.defaultOpen);\nconst selectedItem = defineModel<MenuOption>({ required: false });\nconst searchInput = defineModel<string>(\"searchInput\", {\n required: false,\n default: \"\",\n});\n\nwatch(open, (newValue) => {\n if (newValue) {\n emits(\"dropdown-open\");\n } else {\n emits(\"dropdown-closed\");\n }\n});\n\nconst buttonDisplayLabel = computed(() => {\n if (selectedItem.value && selectedItem.value.text) {\n return selectedItem.value.text;\n }\n return props.label;\n});\n\nconst buttonIcon = computed(() => {\n if (selectedItem.value && selectedItem.value.icon) {\n return selectedItem.value.icon;\n }\n return undefined;\n});\n\nconst buttonCompanyLogo = computed(() => {\n if (selectedItem.value && selectedItem.value.companyName) {\n return selectedItem.value.companyName;\n }\n return undefined;\n});\n\nconst buttonAvatar = computed(() => selectedItem.value?.avatar);\n\nconst filteredOptions = computed(() => {\n const searchValue = searchInput.value.trim().toLowerCase();\n if (!searchValue) return props.options;\n\n const searchRecursive = (options: MenuOption[]): MenuOption[] => {\n const result: MenuOption[] = [];\n\n for (const option of options) {\n const matches =\n option.text.toLowerCase().includes(searchValue) || option.searchText?.toLowerCase().includes(searchValue);\n const filteredChildren = searchRecursive(option.children || []);\n\n if (matches) {\n // Parent matches → keep parent, with filtered children\n result.push({\n ...option,\n searchText: searchValue,\n children: filteredChildren,\n });\n } else {\n // Parent does NOT match:\n result.push(...filteredChildren);\n }\n }\n\n return result;\n };\n\n return searchRecursive(props.options);\n});\n\nconst menuSelectedItems = computed({\n get: () => (selectedItem.value ? [selectedItem.value] : []),\n set: (items: MenuOption[]) => {\n if (props.optionsVariant === \"radio\" || props.disableDeselect) {\n if (items.length > 0) {\n selectedItem.value = items[0];\n }\n } else {\n selectedItem.value = items.length > 0 ? items[0] : undefined;\n }\n },\n});\n\nconst handleSelectItem = () => {\n closeDropdown();\n};\n\nconst handleClear = () => {\n selectedItem.value = undefined;\n};\n\nconst closeDropdown = () => {\n open.value = false;\n searchInput.value = \"\";\n};\n\nonKeyStroke(\"Escape\", () => {\n if (!open.value) return;\n\n closeDropdown();\n});\n</script>\n\n<template>\n <PvPopoverV2 v-model=\"open\" v-bind=\"popoverProperties\">\n <template #trigger>\n <PvSelectButtonTrigger\n class=\"pv-full-width\"\n ref=\"select-button-trigger-ref\"\n :variant=\"variant\"\n :inverse=\"inverse\"\n :size=\"size\"\n :disabled=\"disabled\"\n :prefixLabel=\"prefixLabel\"\n :label=\"buttonDisplayLabel\"\n :icon=\"buttonIcon\"\n :companyLogo=\"buttonCompanyLogo\"\n :avatar=\"buttonAvatar\"\n :showClear=\"false\"\n :showDropdown=\"true\"\n :open=\"open\"\n :counter-position=\"counterPosition\"\n :counter-value=\"\n selectedItem?.secondaryText && typeof selectedItem.secondaryText === 'number'\n ? selectedItem.secondaryText\n : undefined\n \"\n :counter-badge-variant=\"counterBadgeVariant\"\n :isLoading=\"isLoading\"\n :menuOptionConfig=\"optionConfig\"\n :renderer=\"optionsRenderer\"\n :selectedOption=\"selectedItem\"\n @handle-clear=\"handleClear\"\n />\n </template>\n <template #content>\n <div class=\"pv-popover\" data-test-id=\"pv-popover\" :style=\"popoverCssProperties\" style=\"position: unset\">\n <template v-if=\"!disableSearchInput\">\n <div class=\"pv-inset-square-8 pv-border-bottom\">\n <PvSearchInput v-model:model-value=\"searchInput\" class=\"pv-stack-4\" :placeholder=\"searchPlaceholder\" />\n </div>\n </template>\n <template v-if=\"filteredOptions.length > 0\">\n <PvMenu\n v-model:selectedItems=\"menuSelectedItems\"\n :options=\"filteredOptions\"\n :config=\"optionConfig\"\n :queryText=\"highlightSearchText ? searchInput : null\"\n :singleSelect=\"true\"\n @handle-selected=\"handleSelectItem\"\n />\n </template>\n <PvMenuEmptyState v-else />\n </div>\n </template>\n </PvPopoverV2>\n</template>\n","import { PvPaginationVariant } from \"./types\";\n\nconst variantToNumber: Record<PvPaginationVariant, number> = {\n short: 5,\n long: 7,\n};\n\nexport const usePagination = ({\n variant = \"long\",\n}: {\n variant?: PvPaginationVariant;\n} = {}) => {\n /**\n * Number of reserved pagination slots for:\n * - First page\n * - Last page\n * - Ellipsis (\"...\") indicators\n * These help keep the pagination compact and readable.\n */\n const FIRST_LAST_DOTS = 3;\n\n const getPaginations = ({\n currentPage,\n pages,\n }: {\n currentPage: number;\n pages: number;\n }) => {\n if (pages <= variantToNumber[variant]) {\n return Array.from({ length: pages }, (_, i) => ({\n page: i + 1,\n label: (i + 1).toString(),\n }));\n }\n\n const pagination: {\n page: number;\n label: string;\n }[] = [\n {\n page: 1,\n label: \"1\",\n },\n ];\n\n const recalculatedMaxNumberToShow =\n variantToNumber[variant] - FIRST_LAST_DOTS;\n\n const halfPagesAhead = Math.floor(recalculatedMaxNumberToShow / 2);\n\n let start = currentPage - halfPagesAhead;\n let end = currentPage + halfPagesAhead;\n\n const showFirstDots = start > 2;\n const showSecondDots = end < pages - 1;\n\n if (start <= 2) {\n start = 2;\n end = start + recalculatedMaxNumberToShow - 1;\n }\n\n if (end >= pages - 1) {\n end = pages - 1;\n start = end - recalculatedMaxNumberToShow + 1;\n }\n\n if (showFirstDots) {\n pagination.push({\n page: 0,\n label: \"...\",\n });\n }\n\n if (showFirstDots && showSecondDots) {\n for (let i = start + 1; i <= end - 1; i++) {\n pagination.push({ page: i, label: i.toString() });\n }\n } else {\n for (let i = start; i <= end; i++) {\n pagination.push({ page: i, label: i.toString() });\n }\n }\n\n if (showSecondDots) {\n pagination.push({\n page: 0,\n label: \"...\",\n });\n }\n\n if (pages > 1) {\n pagination.push({ page: pages, label: pages.toString() });\n }\n\n return pagination;\n };\n\n return {\n getPaginations,\n };\n};\n","<script setup lang=\"ts\">\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport { usePagination } from \"./usePagination\";\nimport { PvPaginationSize, PvPaginationVariant } from \"./types\";\n\ninterface PvPaginationProps {\n /** Size of the pagination buttons */\n size?: PvPaginationSize;\n /** Total number of pages available */\n maxPages: number;\n maxNumberToShow?: number;\n /** Display variant controlling the number of visible page buttons (\"short\" shows fewer) */\n variant?: PvPaginationVariant;\n}\n\nconst props = withDefaults(defineProps<PvPaginationProps>(), {\n size: \"lg\",\n variant: \"long\",\n});\n\nconst { getPaginations } = usePagination({\n variant: props.variant,\n});\n\nconst currentPage = defineModel<number>({ required: true });\n</script>\n\n<template>\n <ol role=\"list\" class=\"pv-pagination\" data-testid=\"pv-pagination\" :data-style=\"size === 'lg' ? 'small' : undefined\">\n <li>\n <PvButton\n data-testid=\"pagination-left-arrow-icon\"\n :disabled=\"currentPage === 1\"\n left-icon=\"chevron-left\"\n ariaLabel=\"Previous page\"\n variant=\"ghost\"\n @click=\"$emit('update:modelValue', currentPage - 1)\"\n />\n </li>\n <li\n v-for=\"page in getPaginations({\n currentPage,\n pages: maxPages,\n })\"\n :key=\"page.page\"\n :data-testid=\"`pagination-button-${page.page}`\"\n :aria-current=\"page.page === currentPage ? 'page' : undefined\"\n >\n <button v-if=\"page.label === '...'\" class=\"dots-button\" disabled>\n {{ page.label }}\n </button>\n <button v-else @click=\"$emit('update:modelValue', page.page)\">\n {{ page.label }}\n </button>\n </li>\n <li>\n <PvButton\n data-testid=\"pagination-right-arrow-icon\"\n :disabled=\"currentPage === maxPages\"\n left-icon=\"chevron-right\"\n ariaLabel=\"Next page\"\n variant=\"ghost\"\n @click=\"$emit('update:modelValue', currentPage + 1)\"\n />\n </li>\n </ol>\n</template>\n\n<style scoped>\n.dots-button {\n background-color: transparent;\n color: #4b595c;\n}\n</style>\n","<script setup lang=\"ts\">\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport { usePagination } from \"./usePagination\";\nimport { PvPaginationSize, PvPaginationVariant } from \"./types\";\n\ninterface PvPaginationProps {\n /** Size of the pagination buttons */\n size?: PvPaginationSize;\n /** Total number of pages available */\n maxPages: number;\n maxNumberToShow?: number;\n /** Display variant controlling the number of visible page buttons (\"short\" shows fewer) */\n variant?: PvPaginationVariant;\n}\n\nconst props = withDefaults(defineProps<PvPaginationProps>(), {\n size: \"lg\",\n variant: \"long\",\n});\n\nconst { getPaginations } = usePagination({\n variant: props.variant,\n});\n\nconst currentPage = defineModel<number>({ required: true });\n</script>\n\n<template>\n <ol role=\"list\" class=\"pv-pagination\" data-testid=\"pv-pagination\" :data-style=\"size === 'lg' ? 'small' : undefined\">\n <li>\n <PvButton\n data-testid=\"pagination-left-arrow-icon\"\n :disabled=\"currentPage === 1\"\n left-icon=\"chevron-left\"\n ariaLabel=\"Previous page\"\n variant=\"ghost\"\n @click=\"$emit('update:modelValue', currentPage - 1)\"\n />\n </li>\n <li\n v-for=\"page in getPaginations({\n currentPage,\n pages: maxPages,\n })\"\n :key=\"page.page\"\n :data-testid=\"`pagination-button-${page.page}`\"\n :aria-current=\"page.page === currentPage ? 'page' : undefined\"\n >\n <button v-if=\"page.label === '...'\" class=\"dots-button\" disabled>\n {{ page.label }}\n </button>\n <button v-else @click=\"$emit('update:modelValue', page.page)\">\n {{ page.label }}\n </button>\n </li>\n <li>\n <PvButton\n data-testid=\"pagination-right-arrow-icon\"\n :disabled=\"currentPage === maxPages\"\n left-icon=\"chevron-right\"\n ariaLabel=\"Next page\"\n variant=\"ghost\"\n @click=\"$emit('update:modelValue', currentPage + 1)\"\n />\n </li>\n </ol>\n</template>\n\n<style scoped>\n.dots-button {\n background-color: transparent;\n color: #4b595c;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\ninterface PvSelectableCardProps {\n /** Visual style variant of the selectable card. */\n variant?: \"default\" | \"highlight\";\n /** Value associated with this card, used as the input element's value. */\n value?: string;\n /** Unique identifier for the card's input element. Auto-generated if not provided. */\n id?: string;\n /** When true, renders as a checkbox (allowing deselection). When false, renders as a radio button. */\n deselect?: boolean;\n /** Whether the card is currently in the selected state. */\n selected?: boolean;\n}\n\nconst { variant = \"default\", id } = defineProps<PvSelectableCardProps>();\n\nconst labelId = computed(() => {\n if (id) {\n return id;\n }\n return `${Math.random()}`;\n});\n</script>\n\n<template>\n <label\n data-testid=\"pv-selectable-card\"\n :class=\"[\n 'pv-label-selectable-small',\n {\n 'pv-label-selectable-highlight': variant === 'highlight',\n },\n ]\"\n :for=\"labelId\"\n >\n <input\n :checked=\"selected\"\n class=\"pv-hide\"\n name=\"type\"\n :type=\"deselect ? 'checkbox' : 'radio'\"\n :value=\"value\"\n :id=\"labelId\"\n />\n <slot />\n </label>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\ninterface PvSelectableCardProps {\n /** Visual style variant of the selectable card. */\n variant?: \"default\" | \"highlight\";\n /** Value associated with this card, used as the input element's value. */\n value?: string;\n /** Unique identifier for the card's input element. Auto-generated if not provided. */\n id?: string;\n /** When true, renders as a checkbox (allowing deselection). When false, renders as a radio button. */\n deselect?: boolean;\n /** Whether the card is currently in the selected state. */\n selected?: boolean;\n}\n\nconst { variant = \"default\", id } = defineProps<PvSelectableCardProps>();\n\nconst labelId = computed(() => {\n if (id) {\n return id;\n }\n return `${Math.random()}`;\n});\n</script>\n\n<template>\n <label\n data-testid=\"pv-selectable-card\"\n :class=\"[\n 'pv-label-selectable-small',\n {\n 'pv-label-selectable-highlight': variant === 'highlight',\n },\n ]\"\n :for=\"labelId\"\n >\n <input\n :checked=\"selected\"\n class=\"pv-hide\"\n name=\"type\"\n :type=\"deselect ? 'checkbox' : 'radio'\"\n :value=\"value\"\n :id=\"labelId\"\n />\n <slot />\n </label>\n</template>\n","<script setup lang=\"ts\">\ninterface PvSidePanelProps {\n showLeftSidebar?: boolean;\n showRightSidebar?: boolean;\n}\n\ndefineProps<PvSidePanelProps>();\n</script>\n\n<template>\n <div class=\"pv-layout-two-sidebar\">\n <div\n :data-hidden=\"showLeftSidebar === false ? true : undefined\"\n data-testid=\"pv-side-panel-left\"\n data-layout=\"left-sidebar\"\n >\n <slot name=\"left-sidebar\" />\n </div>\n <div data-layout=\"main-section\">\n <slot name=\"main\" />\n </div>\n <div\n :data-hidden=\"showRightSidebar === false ? true : undefined\"\n data-testid=\"pv-side-panel-right\"\n data-layout=\"right-sidebar\"\n >\n <slot name=\"right-sidebar\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\ninterface PvSidePanelProps {\n showLeftSidebar?: boolean;\n showRightSidebar?: boolean;\n}\n\ndefineProps<PvSidePanelProps>();\n</script>\n\n<template>\n <div class=\"pv-layout-two-sidebar\">\n <div\n :data-hidden=\"showLeftSidebar === false ? true : undefined\"\n data-testid=\"pv-side-panel-left\"\n data-layout=\"left-sidebar\"\n >\n <slot name=\"left-sidebar\" />\n </div>\n <div data-layout=\"main-section\">\n <slot name=\"main\" />\n </div>\n <div\n :data-hidden=\"showRightSidebar === false ? true : undefined\"\n data-testid=\"pv-side-panel-right\"\n data-layout=\"right-sidebar\"\n >\n <slot name=\"right-sidebar\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { onMounted, useTemplateRef, watch, ref } from \"vue\";\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport { PvGhostInputVariant } from \"./types\";\n\ninterface PvGhostInputProps {\n /**\n * The typographic style applied to the input text (e.g. h1, h2, text-md, caption).\n */\n variant?: PvGhostInputVariant;\n /** Placeholder text shown when the input is empty. */\n placeholder?: string;\n /** When true, the input is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** When true, displays an edit (pencil) icon button beside the input that focuses it on click. */\n showEditIcon?: boolean;\n}\n\nconst inputRef = useTemplateRef(\"inputRef\");\n\nconst variantToInputNameMap: Record<PvGhostInputVariant, string> = {\n h1: \"ghost-input-h1\",\n h2: \"ghost-input-h2\",\n h3: \"ghost-input-h3\",\n h4: \"ghost-input-h4\",\n \"text-lg\": \"ghost-input-text-large\",\n \"text-md\": \"ghost-input-text-medium\",\n \"text-sm\": \"ghost-input-text-small\",\n caption: \"ghost-input-caption\",\n};\n\nconst variantToDataStyleMap: Record<PvGhostInputVariant, string> = {\n h1: \"h1\",\n h2: \"h2\",\n h3: \"h3\",\n h4: \"h4\",\n \"text-sm\": \"text-small\",\n \"text-md\": \"text-medium\",\n \"text-lg\": \"text-large\",\n caption: \"caption\",\n};\n\nconst props = withDefaults(defineProps<PvGhostInputProps>(), {\n variant: \"h1\",\n});\n\nconst inputValue = defineModel<string>();\nconst inputWidth = ref(0);\n\nconst handleEditIcon = () => {\n inputRef.value?.focus();\n};\n\nonMounted(() => {\n if (inputValue.value && inputValue.value.length > 0) {\n calculateWidth(inputValue.value);\n } else if (props.placeholder) {\n calculateWidth(props.placeholder);\n } else {\n inputWidth.value = 240;\n }\n});\n\nwatch(\n () => inputValue.value,\n () => {\n if (inputValue.value && inputValue.value.length > 0) {\n calculateWidth(inputValue.value);\n } else if (props.placeholder) {\n calculateWidth(props.placeholder);\n } else {\n inputWidth.value = 240;\n }\n },\n);\n\nconst calculateWidth = (value: string) => {\n if (!inputRef.value) return;\n\n const canvas = document.createElement(\"canvas\");\n const context = canvas.getContext(\"2d\");\n\n if (!context) return;\n\n const style = getComputedStyle(inputRef.value);\n context.font = `${style.fontWeight} ${style.fontSize} ${style.fontFamily}`;\n\n inputWidth.value = context.measureText(value).width + 10;\n};\n</script>\n\n<template>\n <div class=\"pv-ghost-input pv-full-width\" data-testid=\"pv-ghost-input\" :data-style=\"variantToDataStyleMap[variant]\">\n <slot name=\"action\" />\n <input\n ref=\"inputRef\"\n v-bind=\"props\"\n v-model=\"inputValue\"\n type=\"text\"\n :style=\"{\n width: inputWidth + 'px',\n }\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :name=\"variantToInputNameMap[variant]\"\n />\n <PvButton v-if=\"showEditIcon\" left-icon=\"edit\" ariaLabel=\"Edit\" variant=\"ghost\" @click=\"handleEditIcon\" />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { onMounted, useTemplateRef, watch, ref } from \"vue\";\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport { PvGhostInputVariant } from \"./types\";\n\ninterface PvGhostInputProps {\n /**\n * The typographic style applied to the input text (e.g. h1, h2, text-md, caption).\n */\n variant?: PvGhostInputVariant;\n /** Placeholder text shown when the input is empty. */\n placeholder?: string;\n /** When true, the input is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** When true, displays an edit (pencil) icon button beside the input that focuses it on click. */\n showEditIcon?: boolean;\n}\n\nconst inputRef = useTemplateRef(\"inputRef\");\n\nconst variantToInputNameMap: Record<PvGhostInputVariant, string> = {\n h1: \"ghost-input-h1\",\n h2: \"ghost-input-h2\",\n h3: \"ghost-input-h3\",\n h4: \"ghost-input-h4\",\n \"text-lg\": \"ghost-input-text-large\",\n \"text-md\": \"ghost-input-text-medium\",\n \"text-sm\": \"ghost-input-text-small\",\n caption: \"ghost-input-caption\",\n};\n\nconst variantToDataStyleMap: Record<PvGhostInputVariant, string> = {\n h1: \"h1\",\n h2: \"h2\",\n h3: \"h3\",\n h4: \"h4\",\n \"text-sm\": \"text-small\",\n \"text-md\": \"text-medium\",\n \"text-lg\": \"text-large\",\n caption: \"caption\",\n};\n\nconst props = withDefaults(defineProps<PvGhostInputProps>(), {\n variant: \"h1\",\n});\n\nconst inputValue = defineModel<string>();\nconst inputWidth = ref(0);\n\nconst handleEditIcon = () => {\n inputRef.value?.focus();\n};\n\nonMounted(() => {\n if (inputValue.value && inputValue.value.length > 0) {\n calculateWidth(inputValue.value);\n } else if (props.placeholder) {\n calculateWidth(props.placeholder);\n } else {\n inputWidth.value = 240;\n }\n});\n\nwatch(\n () => inputValue.value,\n () => {\n if (inputValue.value && inputValue.value.length > 0) {\n calculateWidth(inputValue.value);\n } else if (props.placeholder) {\n calculateWidth(props.placeholder);\n } else {\n inputWidth.value = 240;\n }\n },\n);\n\nconst calculateWidth = (value: string) => {\n if (!inputRef.value) return;\n\n const canvas = document.createElement(\"canvas\");\n const context = canvas.getContext(\"2d\");\n\n if (!context) return;\n\n const style = getComputedStyle(inputRef.value);\n context.font = `${style.fontWeight} ${style.fontSize} ${style.fontFamily}`;\n\n inputWidth.value = context.measureText(value).width + 10;\n};\n</script>\n\n<template>\n <div class=\"pv-ghost-input pv-full-width\" data-testid=\"pv-ghost-input\" :data-style=\"variantToDataStyleMap[variant]\">\n <slot name=\"action\" />\n <input\n ref=\"inputRef\"\n v-bind=\"props\"\n v-model=\"inputValue\"\n type=\"text\"\n :style=\"{\n width: inputWidth + 'px',\n }\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :name=\"variantToInputNameMap[variant]\"\n />\n <PvButton v-if=\"showEditIcon\" left-icon=\"edit\" ariaLabel=\"Edit\" variant=\"ghost\" @click=\"handleEditIcon\" />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvAiButton from \"../PvAiButton/PvAiButton.vue\";\n\nwithDefaults(\n defineProps<{\n title?: string;\n showAskTqButton?: boolean;\n askTqButtonId?: string;\n headerTitleId?: string;\n headerActionsId?: string;\n sticky?: boolean;\n }>(),\n {\n askTqButtonId: \"asktq-launch-button\",\n headerTitleId: \"header-title\",\n headerActionsId: \"header-actions\",\n sticky: false,\n },\n);\n</script>\n\n<template>\n <div\n class=\"pv-inset-square pv-flex pv-space-between pv-border-bottom\"\n :class=\"{ 'pv-sticky pv-surface': sticky }\"\n style=\"--inset-size: 0.5rem 1rem\"\n >\n <span v-if=\"title\" class=\"pv-text-title-lg\">{{ title }}</span>\n <div :id=\"headerTitleId\" class=\"pv-flex\" v-else>\n <slot name=\"left\" />\n </div>\n <div class=\"pv-flex\">\n <div :id=\"headerActionsId\" class=\"pv-flex\">\n <slot name=\"right\" />\n </div>\n <div v-if=\"showAskTqButton\" class=\"pv-border-left\" style=\"padding-inline-start: 0.5rem\">\n <PvAiButton :id=\"askTqButtonId\" label=\"\" size=\"lg\" />\n </div>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvAiButton from \"../PvAiButton/PvAiButton.vue\";\n\nwithDefaults(\n defineProps<{\n title?: string;\n showAskTqButton?: boolean;\n askTqButtonId?: string;\n headerTitleId?: string;\n headerActionsId?: string;\n sticky?: boolean;\n }>(),\n {\n askTqButtonId: \"asktq-launch-button\",\n headerTitleId: \"header-title\",\n headerActionsId: \"header-actions\",\n sticky: false,\n },\n);\n</script>\n\n<template>\n <div\n class=\"pv-inset-square pv-flex pv-space-between pv-border-bottom\"\n :class=\"{ 'pv-sticky pv-surface': sticky }\"\n style=\"--inset-size: 0.5rem 1rem\"\n >\n <span v-if=\"title\" class=\"pv-text-title-lg\">{{ title }}</span>\n <div :id=\"headerTitleId\" class=\"pv-flex\" v-else>\n <slot name=\"left\" />\n </div>\n <div class=\"pv-flex\">\n <div :id=\"headerActionsId\" class=\"pv-flex\">\n <slot name=\"right\" />\n </div>\n <div v-if=\"showAskTqButton\" class=\"pv-border-left\" style=\"padding-inline-start: 0.5rem\">\n <PvAiButton :id=\"askTqButtonId\" label=\"\" size=\"lg\" />\n </div>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvCompanyLogo from \"../PvCompanyLogo/PvCompanyLogo.vue\";\nimport { PvCompanyLabelSize } from \"./types\";\n\ninterface PvCompanyLabelProps {\n /** Display size of the label and logo */\n size?: PvCompanyLabelSize;\n /** Logo identifier to display; falls back to label if not provided */\n logo?: string;\n /** Text label to display alongside the logo */\n label: string;\n}\n\nwithDefaults(defineProps<PvCompanyLabelProps>(), {\n size: \"md\",\n});\n\nconst mapSizeToLabelSize: Record<PvCompanyLabelSize, string> = {\n xs: \"pv-text-body-xs\",\n sm: \"pv-text-body-md\",\n md: \"pv-text-body-md\",\n};\n</script>\n\n<template>\n <div class=\"pv-flex\">\n <PvCompanyLogo :name=\"logo ? logo : label\" :size=\"size\" />\n <span :class=\"mapSizeToLabelSize[size]\">{{ label }}</span>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvCompanyLogo from \"../PvCompanyLogo/PvCompanyLogo.vue\";\nimport { PvCompanyLabelSize } from \"./types\";\n\ninterface PvCompanyLabelProps {\n /** Display size of the label and logo */\n size?: PvCompanyLabelSize;\n /** Logo identifier to display; falls back to label if not provided */\n logo?: string;\n /** Text label to display alongside the logo */\n label: string;\n}\n\nwithDefaults(defineProps<PvCompanyLabelProps>(), {\n size: \"md\",\n});\n\nconst mapSizeToLabelSize: Record<PvCompanyLabelSize, string> = {\n xs: \"pv-text-body-xs\",\n sm: \"pv-text-body-md\",\n md: \"pv-text-body-md\",\n};\n</script>\n\n<template>\n <div class=\"pv-flex\">\n <PvCompanyLogo :name=\"logo ? logo : label\" :size=\"size\" />\n <span :class=\"mapSizeToLabelSize[size]\">{{ label }}</span>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvAvatarGroupItem } from \"./types\";\n\ninterface PvAvatarGroupProps {\n /** Array of avatar items to render in the group. */\n items: PvAvatarGroupItem[];\n /** Maximum number of avatars to show before displaying an overflow indicator. Capped at 7. */\n maxDisplayed: number;\n}\n\nconst props = defineProps<PvAvatarGroupProps>();\n\nconst displayedItems = computed(() => {\n return props.maxDisplayed >= 7 ? 7 : props.maxDisplayed;\n});\n\nconst extraDisplayedItems = computed(() => {\n const extraNumbers = props.items.length - displayedItems.value;\n return extraNumbers > 0 ? extraNumbers : 0;\n});\n</script>\n\n<template>\n <ul\n class=\"pv-avatar-group\"\n role=\"list\"\n :data-more=\"extraDisplayedItems <= 0 ? undefined : extraDisplayedItems\"\n data-testid=\"pv-avatar-group\"\n >\n <li v-for=\"(item, index) in items.slice(0, displayedItems)\" :key=\"index\" data-testid=\"pv-avatar-group-item\">\n <template v-if=\"item.initials\">{{ item.initials }}</template>\n <img v-else-if=\"item.image\" :src=\"item.image\" :alt=\"item.alt ?? ''\" />\n <div v-else class=\"pv-avatar-sm\"></div>\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvAvatarGroupItem } from \"./types\";\n\ninterface PvAvatarGroupProps {\n /** Array of avatar items to render in the group. */\n items: PvAvatarGroupItem[];\n /** Maximum number of avatars to show before displaying an overflow indicator. Capped at 7. */\n maxDisplayed: number;\n}\n\nconst props = defineProps<PvAvatarGroupProps>();\n\nconst displayedItems = computed(() => {\n return props.maxDisplayed >= 7 ? 7 : props.maxDisplayed;\n});\n\nconst extraDisplayedItems = computed(() => {\n const extraNumbers = props.items.length - displayedItems.value;\n return extraNumbers > 0 ? extraNumbers : 0;\n});\n</script>\n\n<template>\n <ul\n class=\"pv-avatar-group\"\n role=\"list\"\n :data-more=\"extraDisplayedItems <= 0 ? undefined : extraDisplayedItems\"\n data-testid=\"pv-avatar-group\"\n >\n <li v-for=\"(item, index) in items.slice(0, displayedItems)\" :key=\"index\" data-testid=\"pv-avatar-group-item\">\n <template v-if=\"item.initials\">{{ item.initials }}</template>\n <img v-else-if=\"item.image\" :src=\"item.image\" :alt=\"item.alt ?? ''\" />\n <div v-else class=\"pv-avatar-sm\"></div>\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport PvCounterBadge from \"../PvCounterBadge/PvCounterBadge.vue\";\n\nimport { PvCounterBadgeVariant } from \"../PvCounterBadge/types\";\nimport { PvToggleButtonSize, PvToggleButtonVariant } from \"./types\";\n\ninterface PvToggleButton {\n /**\n * The visual size of the toggle button.\n */\n size?: PvToggleButtonSize;\n /**\n * The visual style variant.\n */\n variant?: PvToggleButtonVariant;\n /** When true, applies fully rounded (pill) corners. */\n rounded?: boolean;\n /** When true, the toggle button is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** The value emitted when this toggle is selected (used with radio-style groups). */\n value?: string;\n /** Visible text label displayed inside the toggle. */\n label?: string;\n /** Icon name displayed to the left of the label. */\n leftIcon?: string;\n /** Icon name displayed to the right of the label. */\n rightIcon?: string;\n /** HTML id for the underlying input element. Auto-generated from label when omitted. */\n id?: string;\n /** HTML name attribute, used to group radio-style toggles. */\n name?: string;\n /**\n * When true, renders as a checkbox (can be deselected). When false, renders as a radio (stays selected).\n */\n deselect?: boolean;\n /** Optional counter on the right side of the button */\n rightCounterBadge?: number;\n}\n\nconst props = withDefaults(defineProps<PvToggleButton>(), {\n variant: \"secondary\",\n deselect: true,\n size: \"xl\",\n});\n\nconst modelValue = defineModel<boolean | string>();\n\nconst counterBadgeInactiveVariant: Record<PvToggleButtonVariant, PvCounterBadgeVariant> = {\n secondary: \"tertiary\",\n tertiary: \"tertiary\",\n ghost: \"ghost\",\n};\n\nconst counterBadgeActiveVariant: Record<PvToggleButtonVariant, PvCounterBadgeVariant> = {\n secondary: \"primary\",\n tertiary: \"primary\",\n ghost: \"primary\",\n};\n\nconst counterBadgeVariant = computed(() => {\n return modelValue.value ? counterBadgeActiveVariant[props.variant] : counterBadgeInactiveVariant[props.variant];\n});\n\nconst classes = computed(() => {\n const variantSuffix = props.variant == \"secondary\" ? \"\" : \"-\" + props.variant;\n return {\n [`pv-toggle${variantSuffix}`]: true,\n \"pv-toggle-round\": props.rounded,\n \"pv-toggle-small\": props.size === \"lg\",\n };\n});\n\nconst labelId = computed(() => {\n if (props.id) {\n return props.id;\n }\n\n return `${props.label}-${Math.random()}`;\n});\n</script>\n\n<template>\n <label data-testid=\"pv-toggle-button\" :class=\"classes\" :for=\"labelId\">\n <input\n v-model=\"modelValue\"\n class=\"pv-hide\"\n :id=\"labelId\"\n :type=\"deselect ? 'checkbox' : 'radio'\"\n :value=\"value\"\n :name=\"name\"\n :disabled=\"disabled\"\n />\n <PvIcon v-if=\"leftIcon\" :name=\"leftIcon\" />\n <span v-if=\"label\">{{ label }}</span>\n <PvIcon v-if=\"rightIcon\" :name=\"rightIcon\" />\n <PvCounterBadge v-if=\"rightCounterBadge\" :value=\"rightCounterBadge\" :variant=\"counterBadgeVariant\" />\n </label>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport PvCounterBadge from \"../PvCounterBadge/PvCounterBadge.vue\";\n\nimport { PvCounterBadgeVariant } from \"../PvCounterBadge/types\";\nimport { PvToggleButtonSize, PvToggleButtonVariant } from \"./types\";\n\ninterface PvToggleButton {\n /**\n * The visual size of the toggle button.\n */\n size?: PvToggleButtonSize;\n /**\n * The visual style variant.\n */\n variant?: PvToggleButtonVariant;\n /** When true, applies fully rounded (pill) corners. */\n rounded?: boolean;\n /** When true, the toggle button is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** The value emitted when this toggle is selected (used with radio-style groups). */\n value?: string;\n /** Visible text label displayed inside the toggle. */\n label?: string;\n /** Icon name displayed to the left of the label. */\n leftIcon?: string;\n /** Icon name displayed to the right of the label. */\n rightIcon?: string;\n /** HTML id for the underlying input element. Auto-generated from label when omitted. */\n id?: string;\n /** HTML name attribute, used to group radio-style toggles. */\n name?: string;\n /**\n * When true, renders as a checkbox (can be deselected). When false, renders as a radio (stays selected).\n */\n deselect?: boolean;\n /** Optional counter on the right side of the button */\n rightCounterBadge?: number;\n}\n\nconst props = withDefaults(defineProps<PvToggleButton>(), {\n variant: \"secondary\",\n deselect: true,\n size: \"xl\",\n});\n\nconst modelValue = defineModel<boolean | string>();\n\nconst counterBadgeInactiveVariant: Record<PvToggleButtonVariant, PvCounterBadgeVariant> = {\n secondary: \"tertiary\",\n tertiary: \"tertiary\",\n ghost: \"ghost\",\n};\n\nconst counterBadgeActiveVariant: Record<PvToggleButtonVariant, PvCounterBadgeVariant> = {\n secondary: \"primary\",\n tertiary: \"primary\",\n ghost: \"primary\",\n};\n\nconst counterBadgeVariant = computed(() => {\n return modelValue.value ? counterBadgeActiveVariant[props.variant] : counterBadgeInactiveVariant[props.variant];\n});\n\nconst classes = computed(() => {\n const variantSuffix = props.variant == \"secondary\" ? \"\" : \"-\" + props.variant;\n return {\n [`pv-toggle${variantSuffix}`]: true,\n \"pv-toggle-round\": props.rounded,\n \"pv-toggle-small\": props.size === \"lg\",\n };\n});\n\nconst labelId = computed(() => {\n if (props.id) {\n return props.id;\n }\n\n return `${props.label}-${Math.random()}`;\n});\n</script>\n\n<template>\n <label data-testid=\"pv-toggle-button\" :class=\"classes\" :for=\"labelId\">\n <input\n v-model=\"modelValue\"\n class=\"pv-hide\"\n :id=\"labelId\"\n :type=\"deselect ? 'checkbox' : 'radio'\"\n :value=\"value\"\n :name=\"name\"\n :disabled=\"disabled\"\n />\n <PvIcon v-if=\"leftIcon\" :name=\"leftIcon\" />\n <span v-if=\"label\">{{ label }}</span>\n <PvIcon v-if=\"rightIcon\" :name=\"rightIcon\" />\n <PvCounterBadge v-if=\"rightCounterBadge\" :value=\"rightCounterBadge\" :variant=\"counterBadgeVariant\" />\n </label>\n</template>\n","<script setup lang=\"ts\">\nimport { ref } from \"vue\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport PvTooltipV2 from \"@/components/base/PvTooltipV2/PvTooltipV2.vue\";\nimport { PvToggleGroupOption, PvToggleGroupProps } from \"@/components/base/PvToggleGroup/types.ts\";\n\nconst props = defineProps<PvToggleGroupProps>();\nconst selectedOption = defineModel<PvToggleGroupOption | null>();\n\n// Generate a stable unique ID for this component instance\nconst groupId = ref(`toggle-group-${Math.random().toString(36).substr(2, 9)}`);\n\nconst handleToggle = (option: PvToggleGroupOption) => {\n if (option.disabled) return;\n\n // If clicking the already selected option and allowDeselect is true, deselect it\n if (selectedOption.value?.value === option.value) {\n if (props.allowDeselect) {\n selectedOption.value = null;\n }\n return;\n }\n\n // Select the new option\n selectedOption.value = option;\n};\n</script>\n\n<template>\n <div class=\"pv-flex\">\n <template v-for=\"option in options\" :key=\"option.value\">\n <PvTooltipV2 :description=\"hideLabels ? option.label : ''\">\n <template #trigger>\n <label\n class=\"pv-label pv-label-hover pv-flex pv-toggle-small\"\n :class=\"{ 'pv-disabled': disabled || option.disabled }\"\n >\n <input\n type=\"radio\"\n :name=\"groupId\"\n :value=\"option.value\"\n :checked=\"selectedOption?.value === option.value\"\n class=\"pv-radio\"\n :disabled=\"disabled || option.disabled\"\n @change=\"handleToggle(option)\"\n />\n <PvIcon v-if=\"option.icon\" :name=\"option.icon\" />\n <span v-if=\"!hideLabels\">{{ option.label }}</span>\n </label>\n </template>\n </PvTooltipV2>\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { ref } from \"vue\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport PvTooltipV2 from \"@/components/base/PvTooltipV2/PvTooltipV2.vue\";\nimport { PvToggleGroupOption, PvToggleGroupProps } from \"@/components/base/PvToggleGroup/types.ts\";\n\nconst props = defineProps<PvToggleGroupProps>();\nconst selectedOption = defineModel<PvToggleGroupOption | null>();\n\n// Generate a stable unique ID for this component instance\nconst groupId = ref(`toggle-group-${Math.random().toString(36).substr(2, 9)}`);\n\nconst handleToggle = (option: PvToggleGroupOption) => {\n if (option.disabled) return;\n\n // If clicking the already selected option and allowDeselect is true, deselect it\n if (selectedOption.value?.value === option.value) {\n if (props.allowDeselect) {\n selectedOption.value = null;\n }\n return;\n }\n\n // Select the new option\n selectedOption.value = option;\n};\n</script>\n\n<template>\n <div class=\"pv-flex\">\n <template v-for=\"option in options\" :key=\"option.value\">\n <PvTooltipV2 :description=\"hideLabels ? option.label : ''\">\n <template #trigger>\n <label\n class=\"pv-label pv-label-hover pv-flex pv-toggle-small\"\n :class=\"{ 'pv-disabled': disabled || option.disabled }\"\n >\n <input\n type=\"radio\"\n :name=\"groupId\"\n :value=\"option.value\"\n :checked=\"selectedOption?.value === option.value\"\n class=\"pv-radio\"\n :disabled=\"disabled || option.disabled\"\n @change=\"handleToggle(option)\"\n />\n <PvIcon v-if=\"option.icon\" :name=\"option.icon\" />\n <span v-if=\"!hideLabels\">{{ option.label }}</span>\n </label>\n </template>\n </PvTooltipV2>\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\ninterface PvCheckboxProps {\n /** When true, the checkbox is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** When true, displays the checkbox in an indeterminate (mixed) state. */\n indeterminate?: boolean;\n /** Accessible name when no wrapping <label> is present. */\n ariaLabel?: string;\n}\n\ndefineProps<PvCheckboxProps>();\n\nconst value = defineModel<boolean>();\n</script>\n\n<template>\n <input\n ref=\"checkbox-ref\"\n v-model=\"value\"\n class=\"pv-checkbox\"\n type=\"checkbox\"\n name=\"checkbox\"\n :aria-label=\"ariaLabel\"\n :disabled=\"disabled\"\n :indeterminate=\"indeterminate\"\n />\n</template>\n","<script setup lang=\"ts\">\ninterface PvCheckboxProps {\n /** When true, the checkbox is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** When true, displays the checkbox in an indeterminate (mixed) state. */\n indeterminate?: boolean;\n /** Accessible name when no wrapping <label> is present. */\n ariaLabel?: string;\n}\n\ndefineProps<PvCheckboxProps>();\n\nconst value = defineModel<boolean>();\n</script>\n\n<template>\n <input\n ref=\"checkbox-ref\"\n v-model=\"value\"\n class=\"pv-checkbox\"\n type=\"checkbox\"\n name=\"checkbox\"\n :aria-label=\"ariaLabel\"\n :disabled=\"disabled\"\n :indeterminate=\"indeterminate\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useId } from \"vue\";\nimport type { RadioGroupOption } from \"./types\";\n\ninterface PvRadioGroupProps {\n /** Array of options to render as radio buttons. */\n options?: RadioGroupOption[];\n /** Name attribute shared by all radio inputs. Auto-generated if omitted. */\n name?: string;\n /** Layout direction of the options. */\n orientation?: \"vertical\" | \"horizontal\";\n /** When true, all options are non-interactive and visually dimmed. */\n disabled?: boolean;\n /** Visible label rendered above the group. */\n label?: string;\n /** Accessible label when no visible legend is provided. */\n ariaLabel?: string;\n}\n\nconst props = withDefaults(defineProps<PvRadioGroupProps>(), {\n options: () => [],\n orientation: \"vertical\",\n disabled: false,\n});\n\nconst model = defineModel<string | number | boolean>();\n\nconst generatedName = useId();\nconst labelId = useId();\n\nconst groupName = computed(() => props.name ?? generatedName);\n\nconst radioGroupStyles = computed(() => {\n if (props.orientation === \"vertical\") {\n return {\n \"--flex-align\": \"flex-start\",\n };\n }\n\n return {};\n});\n</script>\n\n<template>\n <div role=\"radiogroup\" :aria-label=\"!label ? ariaLabel : undefined\" :aria-labelledby=\"label ? labelId : undefined\">\n <span v-if=\"label\" :id=\"labelId\" class=\"pv-label pv-stack-8\">{{ label }}</span>\n <div :class=\"orientation === 'horizontal' ? 'pv-flex' : 'pv-flex-vertical'\" :style=\"radioGroupStyles\">\n <label v-for=\"option in options\" :key=\"String(option.value)\" class=\"pv-label pv-flex\">\n <input\n v-model=\"model\"\n class=\"pv-radio\"\n type=\"radio\"\n :name=\"groupName\"\n :value=\"option.value\"\n :disabled=\"disabled || option.disabled\"\n />\n {{ option.label }}\n </label>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useId } from \"vue\";\nimport type { RadioGroupOption } from \"./types\";\n\ninterface PvRadioGroupProps {\n /** Array of options to render as radio buttons. */\n options?: RadioGroupOption[];\n /** Name attribute shared by all radio inputs. Auto-generated if omitted. */\n name?: string;\n /** Layout direction of the options. */\n orientation?: \"vertical\" | \"horizontal\";\n /** When true, all options are non-interactive and visually dimmed. */\n disabled?: boolean;\n /** Visible label rendered above the group. */\n label?: string;\n /** Accessible label when no visible legend is provided. */\n ariaLabel?: string;\n}\n\nconst props = withDefaults(defineProps<PvRadioGroupProps>(), {\n options: () => [],\n orientation: \"vertical\",\n disabled: false,\n});\n\nconst model = defineModel<string | number | boolean>();\n\nconst generatedName = useId();\nconst labelId = useId();\n\nconst groupName = computed(() => props.name ?? generatedName);\n\nconst radioGroupStyles = computed(() => {\n if (props.orientation === \"vertical\") {\n return {\n \"--flex-align\": \"flex-start\",\n };\n }\n\n return {};\n});\n</script>\n\n<template>\n <div role=\"radiogroup\" :aria-label=\"!label ? ariaLabel : undefined\" :aria-labelledby=\"label ? labelId : undefined\">\n <span v-if=\"label\" :id=\"labelId\" class=\"pv-label pv-stack-8\">{{ label }}</span>\n <div :class=\"orientation === 'horizontal' ? 'pv-flex' : 'pv-flex-vertical'\" :style=\"radioGroupStyles\">\n <label v-for=\"option in options\" :key=\"String(option.value)\" class=\"pv-label pv-flex\">\n <input\n v-model=\"model\"\n class=\"pv-radio\"\n type=\"radio\"\n :name=\"groupName\"\n :value=\"option.value\"\n :disabled=\"disabled || option.disabled\"\n />\n {{ option.label }}\n </label>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { onMounted } from \"vue\";\n\ntype PvSpriteProps = {\n src: string;\n variant?: \"v1\" | \"v2\";\n};\n\nconst props = withDefaults(defineProps<PvSpriteProps>(), {\n variant: \"v2\",\n});\n\nonMounted(async () => {\n const file = props.variant === \"v1\" ? \"sprite-v1.svg\" : \"sprite-v2.svg\";\n const fullPath = props.src + file;\n try {\n const response = await fetch(fullPath);\n const svgText = await response.text();\n const target = document.getElementById(\"pv-sprite-content\");\n if (target) {\n target.innerHTML = svgText;\n target.hidden = false; // Optional: show if needed\n }\n } catch (error) {\n console.error(\"Failed to load SVG:\", error);\n }\n});\n</script>\n\n<template>\n <Teleport to=\"body\">\n <div hidden id=\"pv-sprite-content\"></div>\n </Teleport>\n</template>\n","<script setup lang=\"ts\">\nimport { onMounted } from \"vue\";\n\ntype PvSpriteProps = {\n src: string;\n variant?: \"v1\" | \"v2\";\n};\n\nconst props = withDefaults(defineProps<PvSpriteProps>(), {\n variant: \"v2\",\n});\n\nonMounted(async () => {\n const file = props.variant === \"v1\" ? \"sprite-v1.svg\" : \"sprite-v2.svg\";\n const fullPath = props.src + file;\n try {\n const response = await fetch(fullPath);\n const svgText = await response.text();\n const target = document.getElementById(\"pv-sprite-content\");\n if (target) {\n target.innerHTML = svgText;\n target.hidden = false; // Optional: show if needed\n }\n } catch (error) {\n console.error(\"Failed to load SVG:\", error);\n }\n});\n</script>\n\n<template>\n <Teleport to=\"body\">\n <div hidden id=\"pv-sprite-content\"></div>\n </Teleport>\n</template>\n","<script setup lang=\"ts\">\nimport { Skeleton } from \"primevue\";\nimport { PvSekeltonSize, PvSkeletonVariant } from \"./types\";\n\nconst mapSizeToPx: Record<PvSekeltonSize, string> = {\n xs: \"0.75rem\",\n sm: \"1rem\",\n md: \"1.25rem\",\n lg: \"1.5rem\",\n xl: \"2rem\",\n};\n\ninterface PvSkeletonProps {\n /** The size of the skeleton placeholder. Controls height and, for square variant, width. */\n size?: PvSekeltonSize;\n /** The shape variant. \"rectangle\" fills available width; \"square\" uses equal height and width. */\n variant?: PvSkeletonVariant;\n}\n\nwithDefaults(defineProps<PvSkeletonProps>(), {\n size: \"md\",\n variant: \"rectangle\",\n});\n</script>\n\n<template>\n <Skeleton\n data-testid=\"pv-skeleton\"\n :height=\"mapSizeToPx[size]\"\n :width=\"variant === 'square' ? mapSizeToPx[size] : '100%'\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { Skeleton } from \"primevue\";\nimport { PvSekeltonSize, PvSkeletonVariant } from \"./types\";\n\nconst mapSizeToPx: Record<PvSekeltonSize, string> = {\n xs: \"0.75rem\",\n sm: \"1rem\",\n md: \"1.25rem\",\n lg: \"1.5rem\",\n xl: \"2rem\",\n};\n\ninterface PvSkeletonProps {\n /** The size of the skeleton placeholder. Controls height and, for square variant, width. */\n size?: PvSekeltonSize;\n /** The shape variant. \"rectangle\" fills available width; \"square\" uses equal height and width. */\n variant?: PvSkeletonVariant;\n}\n\nwithDefaults(defineProps<PvSkeletonProps>(), {\n size: \"md\",\n variant: \"rectangle\",\n});\n</script>\n\n<template>\n <Skeleton\n data-testid=\"pv-skeleton\"\n :height=\"mapSizeToPx[size]\"\n :width=\"variant === 'square' ? mapSizeToPx[size] : '100%'\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { PvInputType, PvInputVariant } from \"./types\";\ninterface PvInputProps {\n /** When true, applies invalid/error styling to the input and lower label. */\n error?: boolean;\n /** When true, the input is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** Placeholder text shown when the input is empty. */\n placeholder?: string;\n /**\n * The HTML input type.\n */\n type?: PvInputType;\n /** HTML id for the input element. Auto-generated when omitted. */\n id?: string;\n /** Helper or validation text displayed below the input. Turns red when error is true. */\n lowerLabel?: string;\n /**\n * Background color variant of the input field.\n */\n variant?: PvInputVariant;\n /** The step attribute for number inputs (e.g. '0.01' for currency). */\n step?: string;\n}\n\nwithDefaults(defineProps<PvInputProps>(), {\n id: Math.random().toString(),\n type: \"text\",\n variant: \"white\",\n});\n\nconst value = defineModel<string>();\n</script>\n\n<template>\n <label v-if=\"$slots.label\" data-testid=\"pv-input-label\" class=\"pv-label pv-stack-8\" :for=\"id\">\n <slot name=\"label\" />\n </label>\n <input\n v-model=\"value\"\n data-testid=\"pv-input\"\n :class=\"[\n 'pv-input-text',\n {\n 'pv-stack-8': lowerLabel,\n 'pv-surface-accent': variant === 'grey',\n },\n ]\"\n :disabled=\"disabled\"\n :type=\"type\"\n :placeholder=\"placeholder\"\n :id=\"id\"\n :data-invalid=\"error ? true : undefined\"\n :step=\"step\"\n />\n <p\n v-if=\"lowerLabel\"\n data-testid=\"pv-input-lower-label\"\n style=\"margin-left: 12px\"\n :class=\"[\n 'pv-text-body-xs',\n {\n 'pv-text-red': error,\n 'pv-text-subdued': !error,\n },\n ]\"\n >\n {{ lowerLabel }}\n </p>\n</template>\n","<script setup lang=\"ts\">\nimport { PvInputType, PvInputVariant } from \"./types\";\ninterface PvInputProps {\n /** When true, applies invalid/error styling to the input and lower label. */\n error?: boolean;\n /** When true, the input is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** Placeholder text shown when the input is empty. */\n placeholder?: string;\n /**\n * The HTML input type.\n */\n type?: PvInputType;\n /** HTML id for the input element. Auto-generated when omitted. */\n id?: string;\n /** Helper or validation text displayed below the input. Turns red when error is true. */\n lowerLabel?: string;\n /**\n * Background color variant of the input field.\n */\n variant?: PvInputVariant;\n /** The step attribute for number inputs (e.g. '0.01' for currency). */\n step?: string;\n}\n\nwithDefaults(defineProps<PvInputProps>(), {\n id: Math.random().toString(),\n type: \"text\",\n variant: \"white\",\n});\n\nconst value = defineModel<string>();\n</script>\n\n<template>\n <label v-if=\"$slots.label\" data-testid=\"pv-input-label\" class=\"pv-label pv-stack-8\" :for=\"id\">\n <slot name=\"label\" />\n </label>\n <input\n v-model=\"value\"\n data-testid=\"pv-input\"\n :class=\"[\n 'pv-input-text',\n {\n 'pv-stack-8': lowerLabel,\n 'pv-surface-accent': variant === 'grey',\n },\n ]\"\n :disabled=\"disabled\"\n :type=\"type\"\n :placeholder=\"placeholder\"\n :id=\"id\"\n :data-invalid=\"error ? true : undefined\"\n :step=\"step\"\n />\n <p\n v-if=\"lowerLabel\"\n data-testid=\"pv-input-lower-label\"\n style=\"margin-left: 12px\"\n :class=\"[\n 'pv-text-body-xs',\n {\n 'pv-text-red': error,\n 'pv-text-subdued': !error,\n },\n ]\"\n >\n {{ lowerLabel }}\n </p>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvRatingVariant, PvRatingSize } from \"./types\";\n\ninterface PvRatingProps {\n /** Display variant: \"dot\" or \"star\" style */\n variant?: PvRatingVariant;\n /** Rating value between 0 and 5 */\n value: number;\n /** Size of the rating display in pixels */\n size?: PvRatingSize;\n}\n\nconst props = withDefaults(defineProps<PvRatingProps>(), {\n variant: \"dot\",\n size: 20,\n});\n\nconst dataRating = computed(() => {\n return props.variant === \"dot\" ? \"dot\" : undefined;\n});\n</script>\n\n<template>\n <div\n class=\"pv-rating\"\n data-testid=\"pv-rating\"\n :style=\"{\n '--height': `${size}px`,\n }\"\n :data-rating=\"dataRating\"\n >\n <meter id=\"rating\" min=\"0\" max=\"5\" :value=\"value\">4.0 stars</meter>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvRatingVariant, PvRatingSize } from \"./types\";\n\ninterface PvRatingProps {\n /** Display variant: \"dot\" or \"star\" style */\n variant?: PvRatingVariant;\n /** Rating value between 0 and 5 */\n value: number;\n /** Size of the rating display in pixels */\n size?: PvRatingSize;\n}\n\nconst props = withDefaults(defineProps<PvRatingProps>(), {\n variant: \"dot\",\n size: 20,\n});\n\nconst dataRating = computed(() => {\n return props.variant === \"dot\" ? \"dot\" : undefined;\n});\n</script>\n\n<template>\n <div\n class=\"pv-rating\"\n data-testid=\"pv-rating\"\n :style=\"{\n '--height': `${size}px`,\n }\"\n :data-rating=\"dataRating\"\n >\n <meter id=\"rating\" min=\"0\" max=\"5\" :value=\"value\">4.0 stars</meter>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvCardVariant } from \"./types\";\n\ninterface PvCardProps {\n /** URL to navigate to when the card is clicked. Renders the card as an anchor element. */\n href?: string;\n /** Visual style variant of the card. */\n variant?: PvCardVariant;\n /** When true, renders the card as a button element with interactive styling. */\n interactive?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvCardProps>(), {\n variant: \"primary\",\n interactive: false,\n});\n\nconst componentVariant = computed(() => {\n return props.href ? \"a\" : props.interactive ? \"button\" : \"div\";\n});\n\nconst componentType = computed(() => {\n return props.href || props.interactive ? \"button\" : \"div\";\n});\n</script>\n\n<template>\n <component\n :is=\"componentVariant\"\n :href=\"href\"\n :type=\"componentType\"\n :class=\"[\n 'pv-card pv-inset-square-8 pv-inline-block',\n {\n 'pv-card-secondary': variant === 'secondary',\n },\n ]\"\n data-testid=\"pv-card\"\n >\n <slot />\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvCardVariant } from \"./types\";\n\ninterface PvCardProps {\n /** URL to navigate to when the card is clicked. Renders the card as an anchor element. */\n href?: string;\n /** Visual style variant of the card. */\n variant?: PvCardVariant;\n /** When true, renders the card as a button element with interactive styling. */\n interactive?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvCardProps>(), {\n variant: \"primary\",\n interactive: false,\n});\n\nconst componentVariant = computed(() => {\n return props.href ? \"a\" : props.interactive ? \"button\" : \"div\";\n});\n\nconst componentType = computed(() => {\n return props.href || props.interactive ? \"button\" : \"div\";\n});\n</script>\n\n<template>\n <component\n :is=\"componentVariant\"\n :href=\"href\"\n :type=\"componentType\"\n :class=\"[\n 'pv-card pv-inset-square-8 pv-inline-block',\n {\n 'pv-card-secondary': variant === 'secondary',\n },\n ]\"\n data-testid=\"pv-card\"\n >\n <slot />\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport PvCard from \"../PvCard/PvCard.vue\";\n</script>\n\n<template>\n <PvCard class=\"pv-inset-square-16\">\n <slot />\n </PvCard>\n</template>\n","<script setup lang=\"ts\">\nimport PvCard from \"../PvCard/PvCard.vue\";\n</script>\n\n<template>\n <PvCard class=\"pv-inset-square-16\">\n <slot />\n </PvCard>\n</template>\n","<script setup lang=\"ts\">\nimport PvCard from \"../PvCard/PvCard.vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport { computed } from \"vue\";\n\nexport interface PvInsightCardProps {\n /** Name of the icon displayed beside the insight text. */\n icon: string;\n /** Short insight label displayed next to the icon. */\n insight: string;\n /** Optional label displayed above the title in a smaller, tertiary style. */\n upperLabel?: string;\n /** Main heading text of the insight card. */\n title?: string;\n /** Descriptive text displayed below the title. */\n description?: string;\n /** When true, shows a \"new-tab\" icon button in the top-right corner. */\n showButton?: boolean;\n /** When true, the card is rendered as an interactive (clickable) element. */\n interactive?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvInsightCardProps>(), {\n icon: \"ai\",\n showButton: false,\n interactive: false,\n});\n\ndefineEmits<{\n (e: \"click\"): void;\n (e: \"icon-click\"): void;\n}>();\n\nconst displayIconLevel = computed(() => {\n return props.icon || props.insight;\n});\n</script>\n\n<template>\n <PvCard variant=\"secondary\" :interactive=\"interactive\" @click=\"$emit('click')\" class=\"pv-relative\">\n <div class=\"pv-flex-vertical\" style=\"--flex-align: flex-start; --flex-gap: 0.25rem\">\n <div v-if=\"displayIconLevel\" class=\"pv-flex\" style=\"--flex-gap: 0.25rem\">\n <PvIcon v-if=\"icon\" style=\"color: #218c88\" :name=\"icon\" :size=\"12\" />\n <span class=\"pv-text-body-sm\">{{ insight }}</span>\n </div>\n <span v-if=\"upperLabel\" class=\"pv-text-body-sm pv-text-tertiary\">{{ upperLabel }}</span>\n <span v-if=\"title\" class=\"pv-heading-2\">{{ title }}</span>\n <span v-if=\"description\" class=\"pv-text-body-md pv-text-secondary pv-text-subdued\">{{ description }}</span>\n </div>\n <PvButton\n v-if=\"showButton\"\n left-icon=\"new-tab\"\n ariaLabel=\"Open in new tab\"\n variant=\"ghost\"\n size=\"md\"\n class=\"pv-insight-button\"\n @click.stop=\"$emit('icon-click')\"\n />\n </PvCard>\n</template>\n\n<style scoped>\n.pv-insight-button {\n position: absolute;\n top: 0.5rem;\n right: 0.5rem;\n}\n</style>\n","<script setup lang=\"ts\">\nimport PvCard from \"../PvCard/PvCard.vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport { computed } from \"vue\";\n\nexport interface PvInsightCardProps {\n /** Name of the icon displayed beside the insight text. */\n icon: string;\n /** Short insight label displayed next to the icon. */\n insight: string;\n /** Optional label displayed above the title in a smaller, tertiary style. */\n upperLabel?: string;\n /** Main heading text of the insight card. */\n title?: string;\n /** Descriptive text displayed below the title. */\n description?: string;\n /** When true, shows a \"new-tab\" icon button in the top-right corner. */\n showButton?: boolean;\n /** When true, the card is rendered as an interactive (clickable) element. */\n interactive?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvInsightCardProps>(), {\n icon: \"ai\",\n showButton: false,\n interactive: false,\n});\n\ndefineEmits<{\n (e: \"click\"): void;\n (e: \"icon-click\"): void;\n}>();\n\nconst displayIconLevel = computed(() => {\n return props.icon || props.insight;\n});\n</script>\n\n<template>\n <PvCard variant=\"secondary\" :interactive=\"interactive\" @click=\"$emit('click')\" class=\"pv-relative\">\n <div class=\"pv-flex-vertical\" style=\"--flex-align: flex-start; --flex-gap: 0.25rem\">\n <div v-if=\"displayIconLevel\" class=\"pv-flex\" style=\"--flex-gap: 0.25rem\">\n <PvIcon v-if=\"icon\" style=\"color: #218c88\" :name=\"icon\" :size=\"12\" />\n <span class=\"pv-text-body-sm\">{{ insight }}</span>\n </div>\n <span v-if=\"upperLabel\" class=\"pv-text-body-sm pv-text-tertiary\">{{ upperLabel }}</span>\n <span v-if=\"title\" class=\"pv-heading-2\">{{ title }}</span>\n <span v-if=\"description\" class=\"pv-text-body-md pv-text-secondary pv-text-subdued\">{{ description }}</span>\n </div>\n <PvButton\n v-if=\"showButton\"\n left-icon=\"new-tab\"\n ariaLabel=\"Open in new tab\"\n variant=\"ghost\"\n size=\"md\"\n class=\"pv-insight-button\"\n @click.stop=\"$emit('icon-click')\"\n />\n </PvCard>\n</template>\n\n<style scoped>\n.pv-insight-button {\n position: absolute;\n top: 0.5rem;\n right: 0.5rem;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { ref, computed } from \"vue\";\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport { PvExpandableContentSizes, PvExpandableContentVariants } from \"./types\";\n\nconst sizeMap: Record<PvExpandableContentSizes, string> = {\n none: \"0\",\n xs: \"4px\",\n sm: \"8px\",\n md: \"12px\",\n lg: \"16px\",\n};\n\nconst props = withDefaults(\n defineProps<{\n /** Maximum number of visible lines before content is clamped. */\n lines?: number;\n /** Padding size applied to the container. */\n size?: PvExpandableContentSizes;\n /** Visual style variant. \"ghost\" applies an accent surface background. */\n variant?: PvExpandableContentVariants;\n /** When true, the content starts in the expanded state. */\n defaultOpen?: boolean;\n }>(),\n {\n lines: 4,\n size: \"md\",\n variant: \"primary\",\n defaultOpen: false,\n },\n);\n\nconst isExpanded = ref(props.defaultOpen);\n\nconst toggleExpanded = () => {\n isExpanded.value = !isExpanded.value;\n};\n\nconst contentStyle = computed(() => {\n return {\n \"--lines\": isExpanded.value ? \"none\" : props.lines,\n \"max-height\": isExpanded.value ? \"100vh\" : `${props.lines * 1.5}em`,\n };\n});\n</script>\n\n<template>\n <div\n :class=\"[\n 'pv-inset-square expandable-content',\n {\n 'pv-surface-accent': variant === 'ghost',\n },\n ]\"\n :style=\"{ '--inset-size': sizeMap[size] }\"\n >\n <p class=\"pv-line-clamp pv-text-body-md pv-stack-8\" :style=\"contentStyle\">\n <slot />\n </p>\n <PvButton\n :label=\"isExpanded ? 'Show Less' : 'Show More'\"\n variant=\"ghost\"\n size=\"md\"\n @click=\"toggleExpanded\"\n :left-icon=\"isExpanded ? 'chevron-up' : 'chevron-down'\"\n />\n </div>\n</template>\n\n<style scoped>\n.expandable-content {\n border-radius: 0.5rem;\n}\n\n.expandable-content .pv-line-clamp {\n transition: max-height 0.3s ease-in-out;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { ref, computed } from \"vue\";\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport { PvExpandableContentSizes, PvExpandableContentVariants } from \"./types\";\n\nconst sizeMap: Record<PvExpandableContentSizes, string> = {\n none: \"0\",\n xs: \"4px\",\n sm: \"8px\",\n md: \"12px\",\n lg: \"16px\",\n};\n\nconst props = withDefaults(\n defineProps<{\n /** Maximum number of visible lines before content is clamped. */\n lines?: number;\n /** Padding size applied to the container. */\n size?: PvExpandableContentSizes;\n /** Visual style variant. \"ghost\" applies an accent surface background. */\n variant?: PvExpandableContentVariants;\n /** When true, the content starts in the expanded state. */\n defaultOpen?: boolean;\n }>(),\n {\n lines: 4,\n size: \"md\",\n variant: \"primary\",\n defaultOpen: false,\n },\n);\n\nconst isExpanded = ref(props.defaultOpen);\n\nconst toggleExpanded = () => {\n isExpanded.value = !isExpanded.value;\n};\n\nconst contentStyle = computed(() => {\n return {\n \"--lines\": isExpanded.value ? \"none\" : props.lines,\n \"max-height\": isExpanded.value ? \"100vh\" : `${props.lines * 1.5}em`,\n };\n});\n</script>\n\n<template>\n <div\n :class=\"[\n 'pv-inset-square expandable-content',\n {\n 'pv-surface-accent': variant === 'ghost',\n },\n ]\"\n :style=\"{ '--inset-size': sizeMap[size] }\"\n >\n <p class=\"pv-line-clamp pv-text-body-md pv-stack-8\" :style=\"contentStyle\">\n <slot />\n </p>\n <PvButton\n :label=\"isExpanded ? 'Show Less' : 'Show More'\"\n variant=\"ghost\"\n size=\"md\"\n @click=\"toggleExpanded\"\n :left-icon=\"isExpanded ? 'chevron-up' : 'chevron-down'\"\n />\n </div>\n</template>\n\n<style scoped>\n.expandable-content {\n border-radius: 0.5rem;\n}\n\n.expandable-content .pv-line-clamp {\n transition: max-height 0.3s ease-in-out;\n}\n</style>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport type { PvToastVariants } from \"./types\";\n\ninterface PvToastProps {\n /** Visual style variant determining color scheme and default icon */\n variant?: PvToastVariants;\n /** Custom icon name; overrides the default variant icon */\n icon?: string;\n /** Text message displayed in the toast */\n label: string;\n}\n\nconst mapVariantToClass: Record<PvToastVariants, string> = {\n info: \"pv-toast-info\",\n success: \"pv-toast-success\",\n error: \"pv-toast-error\",\n dark: \"pv-toast-dark\",\n};\n\nconst mapVariantToIcon: Record<PvToastVariants, string> = {\n info: \"check-circle\",\n success: \"check-circle\",\n error: \"alert-circle\",\n dark: \"ai\",\n};\n\nwithDefaults(defineProps<PvToastProps>(), {\n variant: \"info\",\n});\n\ndefineEmits<{\n (e: \"handle-close\"): void;\n}>();\n</script>\n\n<template>\n <div :class=\"mapVariantToClass[variant]\">\n <PvIcon :name=\"icon ? icon : mapVariantToIcon[variant]\" :size=\"20\" />\n <p class=\"pv-text-body-md\">\n {{ label }}\n </p>\n <slot />\n <PvButton\n variant=\"ghost\"\n :inverse=\"variant === 'dark'\"\n size=\"lg\"\n left-icon=\"close\"\n ariaLabel=\"Close\"\n @click=\"$emit('handle-close')\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport type { PvToastVariants } from \"./types\";\n\ninterface PvToastProps {\n /** Visual style variant determining color scheme and default icon */\n variant?: PvToastVariants;\n /** Custom icon name; overrides the default variant icon */\n icon?: string;\n /** Text message displayed in the toast */\n label: string;\n}\n\nconst mapVariantToClass: Record<PvToastVariants, string> = {\n info: \"pv-toast-info\",\n success: \"pv-toast-success\",\n error: \"pv-toast-error\",\n dark: \"pv-toast-dark\",\n};\n\nconst mapVariantToIcon: Record<PvToastVariants, string> = {\n info: \"check-circle\",\n success: \"check-circle\",\n error: \"alert-circle\",\n dark: \"ai\",\n};\n\nwithDefaults(defineProps<PvToastProps>(), {\n variant: \"info\",\n});\n\ndefineEmits<{\n (e: \"handle-close\"): void;\n}>();\n</script>\n\n<template>\n <div :class=\"mapVariantToClass[variant]\">\n <PvIcon :name=\"icon ? icon : mapVariantToIcon[variant]\" :size=\"20\" />\n <p class=\"pv-text-body-md\">\n {{ label }}\n </p>\n <slot />\n <PvButton\n variant=\"ghost\"\n :inverse=\"variant === 'dark'\"\n size=\"lg\"\n left-icon=\"close\"\n ariaLabel=\"Close\"\n @click=\"$emit('handle-close')\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { PvActionBarTheme } from \"./types\";\n\ninterface PvActionBarProps {\n /** Visual theme of the action bar. Use \"dark\" on light backgrounds for contrast.\n * When using \"dark\", set the `inverse` prop on child components that support it. */\n variant?: PvActionBarTheme;\n}\n\nwithDefaults(defineProps<PvActionBarProps>(), {\n variant: \"white\",\n});\n\ndefineSlots<{\n /**\n * Default slot for action bar content.\n * sections are divided by the root elements inside the slot.\n */\n default(): never;\n}>();\n</script>\n\n<template>\n <div class=\"pv-action-bar-container\" :data-style=\"variant === 'white' ? 'white' : undefined\">\n <slot name=\"default\" />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { PvActionBarTheme } from \"./types\";\n\ninterface PvActionBarProps {\n /** Visual theme of the action bar. Use \"dark\" on light backgrounds for contrast.\n * When using \"dark\", set the `inverse` prop on child components that support it. */\n variant?: PvActionBarTheme;\n}\n\nwithDefaults(defineProps<PvActionBarProps>(), {\n variant: \"white\",\n});\n\ndefineSlots<{\n /**\n * Default slot for action bar content.\n * sections are divided by the root elements inside the slot.\n */\n default(): never;\n}>();\n</script>\n\n<template>\n <div class=\"pv-action-bar-container\" :data-style=\"variant === 'white' ? 'white' : undefined\">\n <slot name=\"default\" />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { PvTextAreaVariant } from \"./types\";\n\ninterface PvTextareaProps {\n /** When true, applies invalid/error styling to the textarea and lower label. */\n error?: boolean;\n /** When true, the textarea is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** Placeholder text shown when the textarea is empty. */\n placeholder?: string;\n /** HTML id for the textarea element. Auto-generated when omitted. */\n id?: string;\n /** Helper or validation text displayed below the textarea. Turns red when error is true. */\n lowerLabel?: string;\n /**\n * Background color variant of the textarea.\n */\n variant?: PvTextAreaVariant;\n /**\n * Number of visible text rows.\n */\n rows?: number;\n}\n\nwithDefaults(defineProps<PvTextareaProps>(), {\n id: Math.random().toString(),\n variant: \"white\",\n rows: 4,\n});\n\nconst value = defineModel<string>();\n</script>\n\n<template>\n <label v-if=\"$slots.label\" class=\"pv-label pv-stack-8\" :for=\"id\">\n <slot name=\"label\" />\n </label>\n <textarea\n v-bind=\"$attrs\"\n v-model=\"value\"\n :class=\"[\n 'pv-textarea',\n {\n 'pv-stack-8': lowerLabel,\n 'pv-surface-accent': variant === 'grey',\n },\n ]\"\n :rows=\"rows\"\n :disabled=\"disabled\"\n :placeholder=\"placeholder\"\n :id=\"id\"\n :data-invalid=\"error ? true : undefined\"\n />\n <p\n v-if=\"lowerLabel\"\n style=\"margin-left: 12px\"\n :class=\"[\n 'pv-text-body-xs',\n {\n 'pv-text-red': error,\n 'pv-text-subdued': !error,\n },\n ]\"\n >\n {{ lowerLabel }}\n </p>\n</template>\n","<script setup lang=\"ts\">\nimport { PvTextAreaVariant } from \"./types\";\n\ninterface PvTextareaProps {\n /** When true, applies invalid/error styling to the textarea and lower label. */\n error?: boolean;\n /** When true, the textarea is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** Placeholder text shown when the textarea is empty. */\n placeholder?: string;\n /** HTML id for the textarea element. Auto-generated when omitted. */\n id?: string;\n /** Helper or validation text displayed below the textarea. Turns red when error is true. */\n lowerLabel?: string;\n /**\n * Background color variant of the textarea.\n */\n variant?: PvTextAreaVariant;\n /**\n * Number of visible text rows.\n */\n rows?: number;\n}\n\nwithDefaults(defineProps<PvTextareaProps>(), {\n id: Math.random().toString(),\n variant: \"white\",\n rows: 4,\n});\n\nconst value = defineModel<string>();\n</script>\n\n<template>\n <label v-if=\"$slots.label\" class=\"pv-label pv-stack-8\" :for=\"id\">\n <slot name=\"label\" />\n </label>\n <textarea\n v-bind=\"$attrs\"\n v-model=\"value\"\n :class=\"[\n 'pv-textarea',\n {\n 'pv-stack-8': lowerLabel,\n 'pv-surface-accent': variant === 'grey',\n },\n ]\"\n :rows=\"rows\"\n :disabled=\"disabled\"\n :placeholder=\"placeholder\"\n :id=\"id\"\n :data-invalid=\"error ? true : undefined\"\n />\n <p\n v-if=\"lowerLabel\"\n style=\"margin-left: 12px\"\n :class=\"[\n 'pv-text-body-xs',\n {\n 'pv-text-red': error,\n 'pv-text-subdued': !error,\n },\n ]\"\n >\n {{ lowerLabel }}\n </p>\n</template>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\n\ninterface PvSimpleItemTreeProps {\n label: string;\n icon?: string;\n}\n\ndefineProps<PvSimpleItemTreeProps>();\n</script>\n\n<template>\n <div class=\"pv-flex pv-truncate\" style=\"min-width: 0; min-height: 20px\">\n <PvIcon v-if=\"icon\" :name=\"icon\" />\n <span class=\"pv-text-body-md pv-truncate\" style=\"font-weight: 500; min-width: 0\" :title=\"label\">{{ label }}</span>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\n\ninterface PvSimpleItemTreeProps {\n label: string;\n icon?: string;\n}\n\ndefineProps<PvSimpleItemTreeProps>();\n</script>\n\n<template>\n <div class=\"pv-flex pv-truncate\" style=\"min-width: 0; min-height: 20px\">\n <PvIcon v-if=\"icon\" :name=\"icon\" />\n <span class=\"pv-text-body-md pv-truncate\" style=\"font-weight: 500; min-width: 0\" :title=\"label\">{{ label }}</span>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\n</script>\n\n<template>\n <PvIcon name=\"reorder\" class=\"reorder-icon pv-text-tertiary\" />\n</template>\n\n<style scoped>\n.reorder-icon {\n position: absolute;\n left: 0;\n top: 0;\n transform: translateY(25%);\n width: 16px;\n height: 16px;\n min-width: 16px;\n min-height: 16px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\n</script>\n\n<template>\n <PvIcon name=\"reorder\" class=\"reorder-icon pv-text-tertiary\" />\n</template>\n\n<style scoped>\n.reorder-icon {\n position: absolute;\n left: 0;\n top: 0;\n transform: translateY(25%);\n width: 16px;\n height: 16px;\n min-width: 16px;\n min-height: 16px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport type { PvTreeOption } from \"./types\";\n\ninterface PvButtonTreeItemProps {\n selected?: boolean;\n option: PvTreeOption;\n disableSelection?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvButtonTreeItemProps>(), {\n disableSelection: false,\n});\n\nconst emit = defineEmits<{\n (e: \"handle-selected\", payload: { option: PvTreeOption; event: MouseEvent }): void;\n}>();\n\nconst handleTreeSelect = (event: MouseEvent) => {\n if (props.disableSelection) return;\n emit(\"handle-selected\", { option: props.option, event });\n};\n\nconst componentInstance = computed(() => {\n return props.disableSelection ? \"button\" : \"div\";\n});\n</script>\n\n<template>\n <component\n :is=\"componentInstance\"\n :class=\"[\n 'pv-full-width',\n 'pv-flex',\n 'pv-relative',\n 'pv-tree-item',\n { 'pv-tree-item-selected': selected, 'pv-tree-item-disabled': disableSelection },\n ]\"\n @click=\"handleTreeSelect\"\n >\n <slot />\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport type { PvTreeOption } from \"./types\";\n\ninterface PvButtonTreeItemProps {\n selected?: boolean;\n option: PvTreeOption;\n disableSelection?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvButtonTreeItemProps>(), {\n disableSelection: false,\n});\n\nconst emit = defineEmits<{\n (e: \"handle-selected\", payload: { option: PvTreeOption; event: MouseEvent }): void;\n}>();\n\nconst handleTreeSelect = (event: MouseEvent) => {\n if (props.disableSelection) return;\n emit(\"handle-selected\", { option: props.option, event });\n};\n\nconst componentInstance = computed(() => {\n return props.disableSelection ? \"button\" : \"div\";\n});\n</script>\n\n<template>\n <component\n :is=\"componentInstance\"\n :class=\"[\n 'pv-full-width',\n 'pv-flex',\n 'pv-relative',\n 'pv-tree-item',\n { 'pv-tree-item-selected': selected, 'pv-tree-item-disabled': disableSelection },\n ]\"\n @click=\"handleTreeSelect\"\n >\n <slot />\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport PvCheckbox from \"../PvCheckbox/PvCheckbox.vue\";\nimport type { PvTreeOption } from \"./types\";\n\ninterface PvCheckboxTreeItemProps {\n selected?: boolean;\n option: PvTreeOption;\n disableSelection?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvCheckboxTreeItemProps>(), {\n disableSelection: false,\n});\n\nconst emit = defineEmits<{\n (e: \"handle-selected\", payload: { option: PvTreeOption; event: MouseEvent }): void;\n}>();\n\nconst handleSelected = (event: MouseEvent) => {\n if (props.disableSelection) return;\n emit(\"handle-selected\", { option: props.option, event });\n};\n</script>\n\n<template>\n <label\n :class=\"[\n 'pv-relative',\n 'pv-label',\n 'pv-label-hover',\n 'pv-flex',\n 'pv-tree-item',\n 'pv-full-width',\n { 'pv-tree-item-selected': selected, 'pv-tree-item-disabled': disableSelection },\n ]\"\n >\n <PvCheckbox v-if=\"!disableSelection\" :checked=\"selected\" @click=\"handleSelected\" />\n <slot />\n </label>\n</template>\n","<script setup lang=\"ts\">\nimport PvCheckbox from \"../PvCheckbox/PvCheckbox.vue\";\nimport type { PvTreeOption } from \"./types\";\n\ninterface PvCheckboxTreeItemProps {\n selected?: boolean;\n option: PvTreeOption;\n disableSelection?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvCheckboxTreeItemProps>(), {\n disableSelection: false,\n});\n\nconst emit = defineEmits<{\n (e: \"handle-selected\", payload: { option: PvTreeOption; event: MouseEvent }): void;\n}>();\n\nconst handleSelected = (event: MouseEvent) => {\n if (props.disableSelection) return;\n emit(\"handle-selected\", { option: props.option, event });\n};\n</script>\n\n<template>\n <label\n :class=\"[\n 'pv-relative',\n 'pv-label',\n 'pv-label-hover',\n 'pv-flex',\n 'pv-tree-item',\n 'pv-full-width',\n { 'pv-tree-item-selected': selected, 'pv-tree-item-disabled': disableSelection },\n ]\"\n >\n <PvCheckbox v-if=\"!disableSelection\" :checked=\"selected\" @click=\"handleSelected\" />\n <slot />\n </label>\n</template>\n","import { ref } from \"vue\";\n\nexport const useHoverIcon = () => {\n const hoveredId = ref<number | string | null>(null);\n\n const handleMouseEnter = (id: number | string) => {\n hoveredId.value = id;\n };\n\n const handleMouseLeave = () => {\n hoveredId.value = null;\n };\n\n return {\n hoveredId,\n handleMouseEnter,\n handleMouseLeave,\n };\n};\n","import { InjectionKey, Ref } from \"vue\";\n\nexport type DraggingState = Ref<boolean>;\nexport const DraggingStateKey: InjectionKey<DraggingState> = Symbol(\"DraggingStateKey\");\n\nexport type DraggingGroupName = Ref<string | null>;\nexport const DraggingGroupNameKey: InjectionKey<DraggingGroupName> = Symbol(\"DraggingGroupNameKey\");\n\nexport type DropIndicatorType = {\n parentId?: string | number;\n siblingTargetId?: string | number;\n siblingInsertAfter?: boolean;\n};\nexport type DropIndicator = Ref<DropIndicatorType | null>;\nexport const DropIndicatorKey: InjectionKey<DropIndicator> = Symbol(\"DropIndicatorKey\");\n","import { ref, provide, inject } from \"vue\";\nimport { DraggingStateKey, DraggingGroupNameKey, DropIndicatorKey, DropIndicatorType } from \"../symbols\";\n\n/**\n * Provides dragging state to the tree component hierarchy.\n * Called by PvTreeGroup (for cross-tree sharing) or by PvTree itself as a fallback (standalone use).\n */\nexport const provideDraggingState = () => {\n const isDragging = ref(false);\n const draggingGroupName = ref<string | null>(null);\n const dropIndicator = ref<DropIndicatorType | null>(null);\n\n provide(DraggingStateKey, isDragging);\n provide(DraggingGroupNameKey, draggingGroupName);\n provide(DropIndicatorKey, dropIndicator);\n\n return {\n isDragging,\n draggingGroupName,\n dropIndicator,\n };\n};\n\n/**\n * Injects dragging state from the nearest PvTreeGroup or PvTree ancestor.\n * Should be called in PvTreeItem and PvSimpleNestedTree components.\n */\nexport const useDraggingState = () => {\n const isDragging = inject(DraggingStateKey, ref(false));\n const draggingGroupName = inject(DraggingGroupNameKey, ref<string | null>(null));\n const dropIndicator = inject(DropIndicatorKey, ref<DropIndicatorType | null>(null));\n\n const onDragStart = (groupName?: string) => {\n isDragging.value = true;\n draggingGroupName.value = groupName ?? null;\n };\n\n const onDragEnd = () => {\n isDragging.value = false;\n draggingGroupName.value = null;\n clearDropIndicator();\n };\n\n const setDropIndicator = ({ parentId, siblingTargetId, siblingInsertAfter }: DropIndicatorType) => {\n dropIndicator.value = { parentId, siblingTargetId, siblingInsertAfter };\n };\n\n const clearDropIndicator = () => {\n dropIndicator.value = null;\n };\n\n return {\n isDragging,\n draggingGroupName,\n dropIndicator,\n setDropIndicator,\n clearDropIndicator,\n onDragStart,\n onDragEnd,\n };\n};\n","import { PvTreeOption, PvTreeSettings } from \"../types\";\nimport { useDraggingState } from \"./useDraggingState\";\n\nexport const useDragAndDrop = () => {\n const { setDropIndicator, clearDropIndicator } = useDraggingState();\n const getDragGroupConfig = (settings: PvTreeSettings, option: PvTreeOption) => {\n const fieldSetting = settings[option.field];\n const dragGroup = fieldSetting?.dragAndDropConfig;\n\n return {\n // Use a single shared group name by default to allow drag between all tree levels\n name: dragGroup?.name ?? \"pv-tree\",\n pull: dragGroup?.pull ?? true,\n put: dragGroup?.put ?? true,\n };\n };\n\n const getDragAndDropDisabled = (isDraggable: boolean | undefined, settings: PvTreeSettings, option: PvTreeOption) => {\n return !isDraggable || settings[option.field]?.dragAndDropConfig?.disableChildrenDrag;\n };\n\n /**\n * Returns true if an item can be dragged (for showing the reorder icon).\n * Checks: isDraggable is true, disabled is not set, and preventDrag is not set.\n */\n const canItemBeDragged = (isDraggable: boolean | undefined, settings: PvTreeSettings, option: PvTreeOption) => {\n const config = settings[option.field]?.dragAndDropConfig;\n return isDraggable && !config?.disableChildrenDrag && !config?.disableDrag;\n };\n\n /**\n * Vuedraggable move callback to prevent specific items from being dragged.\n * Returns false to cancel the drag, true to allow it.\n */\n const handleMoveCallback = (settings: PvTreeSettings) => {\n return (evt: {\n to: HTMLElement;\n draggedContext: { element: PvTreeOption; futureIndex: number };\n relatedContext: { element: PvTreeOption };\n willInsertAfter: boolean;\n }) => {\n const draggedOption = evt.draggedContext.element;\n const fieldSetting = settings[draggedOption.field];\n\n const toParentId =\n (evt.to as HTMLElement)?.closest?.(\"[data-parent-id]\")?.getAttribute(\"data-parent-id\") ?? undefined;\n\n if (toParentId != null) {\n const hasRelated = evt.relatedContext?.element?.node_id != null;\n const isInsertAsFirstChild = evt.draggedContext.futureIndex === 0;\n\n setDropIndicator({\n parentId: toParentId,\n ...(hasRelated && !isInsertAsFirstChild\n ? {\n siblingTargetId: evt.relatedContext.element.node_id,\n siblingInsertAfter: evt.willInsertAfter,\n }\n : {}),\n });\n } else {\n clearDropIndicator();\n }\n\n if (fieldSetting?.dragAndDropConfig?.disableDrag) {\n return false;\n }\n return true;\n };\n };\n\n const childrenDraggable = (isDraggable: boolean | undefined, settings: PvTreeSettings, option: PvTreeOption) => {\n return isDraggable && !settings[option.field]?.dragAndDropConfig?.disableChildrenDrag;\n };\n\n /**\n * Returns true if the drop zone should be shown for this option.\n * Checks `put` configuration against the dragging group name.\n *\n * @param settings - Tree settings\n * @param option - The option where we want to drop\n * @param draggingGroupName - The group name of the element being dragged (null if not dragging)\n *\n * Logic:\n * - put: false → never accept drops\n * - put: true → accept from any group\n * - put: ['group1', 'group2'] → accept only from specified groups\n * - put: undefined → accept only from same group (by name)\n */\n const canAcceptDrop = (settings: PvTreeSettings, option: PvTreeOption, draggingGroupName: string | null) => {\n const config = settings[option.field]?.dragAndDropConfig;\n const put = config?.put;\n\n // If put is explicitly false, never accept drops\n if (put === false) {\n return false;\n }\n\n // If put is explicitly true, accept from any group\n if (put === true) {\n return true;\n }\n\n // If not dragging yet, allow (will be filtered by isDragging anyway)\n if (!draggingGroupName) {\n return true;\n }\n\n // If put is an array, check if dragging group is in the allowed list\n if (Array.isArray(put)) {\n return put.includes(draggingGroupName);\n }\n\n // Default: accept only from same group (by name)\n const targetGroupName = config?.name ?? \"pv-tree\";\n return targetGroupName === draggingGroupName;\n };\n\n return {\n getDragGroupConfig,\n getDragAndDropDisabled,\n canItemBeDragged,\n handleMoveCallback,\n childrenDraggable,\n canAcceptDrop,\n };\n};\n","import { useDraggingState } from \"./useDraggingState\";\nimport type { PvTreeOption } from \"../types\";\n\nexport const useDragAndDropIndicator = () => {\n const { dropIndicator } = useDraggingState();\n\n const dragAndDropIndicatorClasses = (option: PvTreeOption) => {\n const indicator = dropIndicator.value;\n const hasSiblingTarget = indicator?.siblingTargetId !== undefined && indicator?.siblingTargetId !== null;\n const isSiblingTarget = hasSiblingTarget && indicator?.siblingTargetId === option.node_id;\n\n return {\n \"pv-drop-indicator-bottom\": Boolean(isSiblingTarget && indicator?.siblingInsertAfter),\n \"pv-drop-indicator-top\": Boolean(isSiblingTarget && indicator?.siblingInsertAfter === false),\n \"pv-drop-indicator-parent\": Boolean(indicator?.parentId === option.node_id),\n };\n };\n\n return {\n dragAndDropIndicatorClasses,\n };\n};\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport draggable from \"vuedraggable\";\nimport PvTreeReorderIcon from \"./PvTreeReorderIcon.vue\";\nimport PvButtonTreeItem from \"./PvButtonTreeItem.vue\";\nimport PvCheckboxTreeItem from \"./PvCheckboxTreeItem.vue\";\nimport PvSimpleItemTree from \"./PvSimpleItemTree.vue\";\nimport type { PvTreeOption, PvTreeSettings } from \"./types\";\n\nimport { useHoverIcon } from \"./composables/useHoverIcon\";\nimport { useDragAndDrop } from \"./composables/useDragAndDrop\";\nimport { useDraggingState } from \"./composables/useDraggingState\";\nimport { useDragAndDropIndicator } from \"./composables/useDragAndDropIndicator\";\n\ninterface PvSimpleNestedTreeItemProps {\n option: PvTreeOption;\n settings: PvTreeSettings;\n level: number;\n index: number;\n totalSiblings: number;\n parentField: string;\n selectedOptions?: PvTreeOption[];\n isDraggable?: boolean;\n isParentPathOpen?: boolean;\n isLastItem?: boolean;\n disableSelection?: boolean;\n}\n\nconst props = defineProps<PvSimpleNestedTreeItemProps>();\n\nconst emit = defineEmits<{\n (e: \"handle-tree-select\", payload: { option: PvTreeOption; event: MouseEvent }): void;\n (e: \"update:children\", payload: { optionId: PvTreeOption[\"node_id\"]; newChildren: PvTreeOption[] }): void;\n}>();\n\nconst { isDragging, draggingGroupName, onDragStart, onDragEnd } = useDraggingState();\nconst { dragAndDropIndicatorClasses } = useDragAndDropIndicator();\nconst { hoveredId, handleMouseEnter, handleMouseLeave } = useHoverIcon();\nconst { canItemBeDragged, getDragAndDropDisabled, handleMoveCallback, getDragGroupConfig, canAcceptDrop } =\n useDragAndDrop();\n\nconst handleDragStart = () => {\n const groupConfig = getDragGroupConfig(props.settings, props.option);\n onDragStart(groupConfig.name);\n};\n\nconst isSelected = (id?: string | number) => {\n return props.selectedOptions && props.selectedOptions.some((opt) => opt.node_id === id);\n};\n\nconst componentInstance = computed(() => {\n return props.settings[props.option.field]?.checkbox ? PvCheckboxTreeItem : PvButtonTreeItem;\n});\n\nconst showNestedTree = computed(() => {\n return props.settings[props.parentField]?.showNestedTree;\n});\n\nconst isLastItem = computed(() => {\n return props.index === props.totalSiblings - 1;\n});\n\n// Writable computed for vuedraggable v-model binding\nconst children = computed({\n get: () => [...(props.option.children || [])],\n set: (value) => {\n emit(\"update:children\", { optionId: props.option.node_id, newChildren: value });\n },\n});\n\nconst isVisible = computed(() => props.isParentPathOpen ?? true);\n</script>\n\n<template>\n <div\n :class=\"{ 'tree-item-continued': showNestedTree && !isLastItem }\"\n :style=\"showNestedTree && !isLastItem ? { '--tree-connector-left': `${level * 24 + 8}px` } : {}\"\n >\n <component\n :is=\"componentInstance\"\n :class=\"{\n ...dragAndDropIndicatorClasses(option),\n }\"\n :option=\"option\"\n :selected=\"isSelected(option.node_id)\"\n :disable-selection=\"disableSelection\"\n :label=\"option.label\"\n :icon=\"settings[option.field]?.icon\"\n :style=\"{\n paddingLeft: `${level * 24}px`,\n ...(settings[option.field]?.rendererParams?.onProvideCssStyles?.(option, { isVisible }) ?? {}),\n }\"\n @handle-selected=\"$emit('handle-tree-select', $event)\"\n @mouseenter=\"handleMouseEnter(option.node_id)\"\n @mouseleave=\"handleMouseLeave()\"\n @contextmenu.stop=\"settings[option.field]?.rendererParams?.onContextMenu?.($event, option)\"\n >\n <PvTreeReorderIcon v-show=\"hoveredId === option.node_id && canItemBeDragged(isDraggable, settings, option)\" />\n <div class=\"pv-flex pv-full-width\">\n <div v-if=\"!isLastItem && showNestedTree\" class=\"tree-component-nested-middle-symbol\" />\n <div v-else-if=\"showNestedTree\" class=\"tree-component-end-symbol\" />\n <component\n v-if=\"settings[option.field]?.renderer\"\n :is=\"settings[option.field]?.renderer\"\n :option=\"option\"\n :settings=\"settings\"\n :is-draggable=\"isDraggable\"\n :params=\"settings[option.field]?.rendererParams\"\n />\n <PvSimpleItemTree v-else :label=\"option.label\" :icon=\"settings[option.field]?.icon\" />\n </div>\n </component>\n\n <!-- Drop zone for children -->\n <div :data-parent-id=\"option.node_id\">\n <draggable\n v-model=\"children\"\n :parent-id=\"option.node_id\"\n :group=\"getDragGroupConfig(settings, option)\"\n item-key=\"node_id\"\n :disabled=\"getDragAndDropDisabled(isDraggable, settings, option)\"\n :move=\"handleMoveCallback(settings)\"\n :class=\"{\n 'pv-tree-drop-zone':\n isDragging && children.length === 0 && canAcceptDrop(settings, option, draggingGroupName),\n }\"\n @start=\"handleDragStart\"\n @end=\"onDragEnd\"\n @add=\"onDragEnd\"\n >\n <template #item=\"{ element, index: childIndex }\">\n <PvSimpleNestedTreeItem\n :is-parent-path-open=\"isParentPathOpen\"\n :option=\"element\"\n :settings=\"settings\"\n :level=\"level + 1\"\n :index=\"childIndex\"\n :total-siblings=\"children.length\"\n :parent-field=\"option.field\"\n :selected-options=\"selectedOptions\"\n :is-draggable=\"isDraggable\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"$emit('handle-tree-select', $event)\"\n @update:children=\"$emit('update:children', $event)\"\n />\n </template>\n </draggable>\n </div>\n </div>\n</template>\n\n<style scoped>\n.pv-tree-drop-zone {\n min-height: 0px;\n}\n\n/* Continuation line when this item is not last sibling (runs through nested children) */\n.tree-item-continued {\n position: relative;\n}\n\n.tree-item-continued::before {\n content: \"\";\n position: absolute;\n left: calc(var(--tree-connector-left, 8px) + 1px);\n top: 0;\n bottom: 0;\n width: 1px;\n background: var(--tree-connector-color, #d2d8dc);\n transform: translateX(-50%);\n z-index: 1;\n pointer-events: none;\n}\n\n/* When continuation line is drawn, hide the middle symbol's vertical so we don't double the line */\n.tree-item-continued .tree-component-nested-middle-symbol::before {\n display: none;\n}\n\n/* End symbol box */\n.tree-component-end-symbol {\n width: 16px;\n height: 16px;\n min-width: 16px;\n position: relative;\n}\n\n.tree-component-end-symbol::before,\n.tree-component-end-symbol::after {\n content: \"\";\n position: absolute;\n background: var(--tree-connector-color, #d2d8dc);\n}\n\n.tree-component-end-symbol::before {\n width: 1px;\n height: 14px;\n top: -6px;\n left: 8px;\n transform: translateX(-50%);\n}\n\n.tree-component-end-symbol::after {\n height: 1px;\n width: 8px;\n top: 8px;\n left: 8px;\n}\n\n/* Middle Tree Symbol */\n\n.tree-component-middle-symbol {\n width: 16px;\n height: 16px;\n min-width: 16px;\n position: relative;\n}\n\n.tree-component-middle-symbol::before {\n content: \"\";\n position: absolute;\n background: var(--tree-connector-color, #d2d8dc);\n left: 50%;\n width: 1px;\n height: 28px;\n top: -4px;\n transform: translateX(-50%);\n}\n\n/* Middle Nested Tree symbol box */\n.tree-component-nested-middle-symbol {\n width: 16px;\n height: 16px;\n min-width: 16px;\n position: relative;\n}\n\n.tree-component-nested-middle-symbol::before,\n.tree-component-nested-middle-symbol::after {\n content: \"\";\n position: absolute;\n background: var(--tree-connector-color, #d2d8dc);\n left: 50%;\n}\n\n.tree-component-nested-middle-symbol::before {\n width: 1px;\n height: 28px;\n top: -4px;\n transform: translateX(-50%);\n}\n\n.tree-component-nested-middle-symbol::after {\n height: 1px;\n width: 8px;\n top: 50%;\n transform: translateY(-50%);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport draggable from \"vuedraggable\";\nimport PvTreeReorderIcon from \"./PvTreeReorderIcon.vue\";\nimport PvButtonTreeItem from \"./PvButtonTreeItem.vue\";\nimport PvCheckboxTreeItem from \"./PvCheckboxTreeItem.vue\";\nimport PvSimpleItemTree from \"./PvSimpleItemTree.vue\";\nimport type { PvTreeOption, PvTreeSettings } from \"./types\";\n\nimport { useHoverIcon } from \"./composables/useHoverIcon\";\nimport { useDragAndDrop } from \"./composables/useDragAndDrop\";\nimport { useDraggingState } from \"./composables/useDraggingState\";\nimport { useDragAndDropIndicator } from \"./composables/useDragAndDropIndicator\";\n\ninterface PvSimpleNestedTreeItemProps {\n option: PvTreeOption;\n settings: PvTreeSettings;\n level: number;\n index: number;\n totalSiblings: number;\n parentField: string;\n selectedOptions?: PvTreeOption[];\n isDraggable?: boolean;\n isParentPathOpen?: boolean;\n isLastItem?: boolean;\n disableSelection?: boolean;\n}\n\nconst props = defineProps<PvSimpleNestedTreeItemProps>();\n\nconst emit = defineEmits<{\n (e: \"handle-tree-select\", payload: { option: PvTreeOption; event: MouseEvent }): void;\n (e: \"update:children\", payload: { optionId: PvTreeOption[\"node_id\"]; newChildren: PvTreeOption[] }): void;\n}>();\n\nconst { isDragging, draggingGroupName, onDragStart, onDragEnd } = useDraggingState();\nconst { dragAndDropIndicatorClasses } = useDragAndDropIndicator();\nconst { hoveredId, handleMouseEnter, handleMouseLeave } = useHoverIcon();\nconst { canItemBeDragged, getDragAndDropDisabled, handleMoveCallback, getDragGroupConfig, canAcceptDrop } =\n useDragAndDrop();\n\nconst handleDragStart = () => {\n const groupConfig = getDragGroupConfig(props.settings, props.option);\n onDragStart(groupConfig.name);\n};\n\nconst isSelected = (id?: string | number) => {\n return props.selectedOptions && props.selectedOptions.some((opt) => opt.node_id === id);\n};\n\nconst componentInstance = computed(() => {\n return props.settings[props.option.field]?.checkbox ? PvCheckboxTreeItem : PvButtonTreeItem;\n});\n\nconst showNestedTree = computed(() => {\n return props.settings[props.parentField]?.showNestedTree;\n});\n\nconst isLastItem = computed(() => {\n return props.index === props.totalSiblings - 1;\n});\n\n// Writable computed for vuedraggable v-model binding\nconst children = computed({\n get: () => [...(props.option.children || [])],\n set: (value) => {\n emit(\"update:children\", { optionId: props.option.node_id, newChildren: value });\n },\n});\n\nconst isVisible = computed(() => props.isParentPathOpen ?? true);\n</script>\n\n<template>\n <div\n :class=\"{ 'tree-item-continued': showNestedTree && !isLastItem }\"\n :style=\"showNestedTree && !isLastItem ? { '--tree-connector-left': `${level * 24 + 8}px` } : {}\"\n >\n <component\n :is=\"componentInstance\"\n :class=\"{\n ...dragAndDropIndicatorClasses(option),\n }\"\n :option=\"option\"\n :selected=\"isSelected(option.node_id)\"\n :disable-selection=\"disableSelection\"\n :label=\"option.label\"\n :icon=\"settings[option.field]?.icon\"\n :style=\"{\n paddingLeft: `${level * 24}px`,\n ...(settings[option.field]?.rendererParams?.onProvideCssStyles?.(option, { isVisible }) ?? {}),\n }\"\n @handle-selected=\"$emit('handle-tree-select', $event)\"\n @mouseenter=\"handleMouseEnter(option.node_id)\"\n @mouseleave=\"handleMouseLeave()\"\n @contextmenu.stop=\"settings[option.field]?.rendererParams?.onContextMenu?.($event, option)\"\n >\n <PvTreeReorderIcon v-show=\"hoveredId === option.node_id && canItemBeDragged(isDraggable, settings, option)\" />\n <div class=\"pv-flex pv-full-width\">\n <div v-if=\"!isLastItem && showNestedTree\" class=\"tree-component-nested-middle-symbol\" />\n <div v-else-if=\"showNestedTree\" class=\"tree-component-end-symbol\" />\n <component\n v-if=\"settings[option.field]?.renderer\"\n :is=\"settings[option.field]?.renderer\"\n :option=\"option\"\n :settings=\"settings\"\n :is-draggable=\"isDraggable\"\n :params=\"settings[option.field]?.rendererParams\"\n />\n <PvSimpleItemTree v-else :label=\"option.label\" :icon=\"settings[option.field]?.icon\" />\n </div>\n </component>\n\n <!-- Drop zone for children -->\n <div :data-parent-id=\"option.node_id\">\n <draggable\n v-model=\"children\"\n :parent-id=\"option.node_id\"\n :group=\"getDragGroupConfig(settings, option)\"\n item-key=\"node_id\"\n :disabled=\"getDragAndDropDisabled(isDraggable, settings, option)\"\n :move=\"handleMoveCallback(settings)\"\n :class=\"{\n 'pv-tree-drop-zone':\n isDragging && children.length === 0 && canAcceptDrop(settings, option, draggingGroupName),\n }\"\n @start=\"handleDragStart\"\n @end=\"onDragEnd\"\n @add=\"onDragEnd\"\n >\n <template #item=\"{ element, index: childIndex }\">\n <PvSimpleNestedTreeItem\n :is-parent-path-open=\"isParentPathOpen\"\n :option=\"element\"\n :settings=\"settings\"\n :level=\"level + 1\"\n :index=\"childIndex\"\n :total-siblings=\"children.length\"\n :parent-field=\"option.field\"\n :selected-options=\"selectedOptions\"\n :is-draggable=\"isDraggable\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"$emit('handle-tree-select', $event)\"\n @update:children=\"$emit('update:children', $event)\"\n />\n </template>\n </draggable>\n </div>\n </div>\n</template>\n\n<style scoped>\n.pv-tree-drop-zone {\n min-height: 0px;\n}\n\n/* Continuation line when this item is not last sibling (runs through nested children) */\n.tree-item-continued {\n position: relative;\n}\n\n.tree-item-continued::before {\n content: \"\";\n position: absolute;\n left: calc(var(--tree-connector-left, 8px) + 1px);\n top: 0;\n bottom: 0;\n width: 1px;\n background: var(--tree-connector-color, #d2d8dc);\n transform: translateX(-50%);\n z-index: 1;\n pointer-events: none;\n}\n\n/* When continuation line is drawn, hide the middle symbol's vertical so we don't double the line */\n.tree-item-continued .tree-component-nested-middle-symbol::before {\n display: none;\n}\n\n/* End symbol box */\n.tree-component-end-symbol {\n width: 16px;\n height: 16px;\n min-width: 16px;\n position: relative;\n}\n\n.tree-component-end-symbol::before,\n.tree-component-end-symbol::after {\n content: \"\";\n position: absolute;\n background: var(--tree-connector-color, #d2d8dc);\n}\n\n.tree-component-end-symbol::before {\n width: 1px;\n height: 14px;\n top: -6px;\n left: 8px;\n transform: translateX(-50%);\n}\n\n.tree-component-end-symbol::after {\n height: 1px;\n width: 8px;\n top: 8px;\n left: 8px;\n}\n\n/* Middle Tree Symbol */\n\n.tree-component-middle-symbol {\n width: 16px;\n height: 16px;\n min-width: 16px;\n position: relative;\n}\n\n.tree-component-middle-symbol::before {\n content: \"\";\n position: absolute;\n background: var(--tree-connector-color, #d2d8dc);\n left: 50%;\n width: 1px;\n height: 28px;\n top: -4px;\n transform: translateX(-50%);\n}\n\n/* Middle Nested Tree symbol box */\n.tree-component-nested-middle-symbol {\n width: 16px;\n height: 16px;\n min-width: 16px;\n position: relative;\n}\n\n.tree-component-nested-middle-symbol::before,\n.tree-component-nested-middle-symbol::after {\n content: \"\";\n position: absolute;\n background: var(--tree-connector-color, #d2d8dc);\n left: 50%;\n}\n\n.tree-component-nested-middle-symbol::before {\n width: 1px;\n height: 28px;\n top: -4px;\n transform: translateX(-50%);\n}\n\n.tree-component-nested-middle-symbol::after {\n height: 1px;\n width: 8px;\n top: 50%;\n transform: translateY(-50%);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport draggable from \"vuedraggable\";\nimport PvTreeReorderIcon from \"./PvTreeReorderIcon.vue\";\nimport PvButtonTreeItem from \"./PvButtonTreeItem.vue\";\nimport PvCheckboxTreeItem from \"./PvCheckboxTreeItem.vue\";\nimport PvSimpleItemTree from \"./PvSimpleItemTree.vue\";\nimport PvSimpleNestedTreeItem from \"./PvSimpleNestedTreeItem.vue\";\nimport type { PvTreeOption, PvTreeSettings } from \"./types\";\n\nimport { useHoverIcon } from \"./composables/useHoverIcon\";\nimport { useDragAndDrop } from \"./composables/useDragAndDrop\";\nimport { useDraggingState } from \"./composables/useDraggingState\";\nimport { useDragAndDropIndicator } from \"./composables/useDragAndDropIndicator\";\n\ninterface PvSimpleNestedTreeProps {\n option: PvTreeOption;\n settings: PvTreeSettings;\n level: number;\n selectedOptions?: PvTreeOption[];\n isDraggable?: boolean;\n isParentPathOpen?: boolean;\n disableSelection?: boolean;\n}\n\nconst props = defineProps<PvSimpleNestedTreeProps>();\n\nconst emit = defineEmits<{\n (e: \"handle-tree-select\", payload: { option: PvTreeOption; event: MouseEvent }): void;\n (e: \"update:children\", payload: { optionId: PvTreeOption[\"node_id\"]; newChildren: PvTreeOption[] }): void;\n}>();\n\nconst { hoveredId, handleMouseEnter, handleMouseLeave } = useHoverIcon();\nconst { getDragAndDropDisabled, canItemBeDragged, handleMoveCallback, getDragGroupConfig, canAcceptDrop } =\n useDragAndDrop();\nconst { isDragging, draggingGroupName, onDragStart, onDragEnd } = useDraggingState();\nconst { dragAndDropIndicatorClasses } = useDragAndDropIndicator();\n\nconst handleDragStart = () => {\n const groupConfig = getDragGroupConfig(props.settings, props.option);\n onDragStart(groupConfig.name);\n};\n\nconst additionalNestingLevel = computed(() => {\n return props.settings[props.option.field]?.additionalNestingLevel ?? 0;\n});\n\n/**\n * If we have showNestedTree as a false we want to add one more indentation level\n */\nconst nestedLevelTree = computed(() => {\n return props.settings[props.option.field]?.showNestedTree\n ? props.level + additionalNestingLevel.value\n : props.level + 1 + additionalNestingLevel.value;\n});\n\nconst isSelected = (id?: string | number) => {\n return props.selectedOptions && props.selectedOptions.some((option) => option.node_id === id);\n};\n\nconst componentInstance = (option: PvTreeOption) => {\n return props.settings[option.field]?.checkbox ? PvCheckboxTreeItem : PvButtonTreeItem;\n};\n\n// Writable computed for vuedraggable v-model binding\nconst children = computed({\n get: () => [...(props.option.children || [])],\n set: (value) => {\n emit(\"update:children\", { optionId: props.option.node_id, newChildren: value });\n },\n});\n\nconst isVisible = computed(() => props.isParentPathOpen ?? true);\n</script>\n\n<template>\n <div class=\"pv-flow\" style=\"--flow-size: 0px\">\n <component\n :is=\"componentInstance(option)\"\n :option=\"option\"\n :selected=\"isSelected(option.node_id)\"\n :disable-selection=\"disableSelection\"\n :label=\"option.label\"\n :icon=\"settings[option.field]?.icon\"\n :class=\"{\n ...dragAndDropIndicatorClasses(option),\n }\"\n :style=\"{\n paddingLeft: `${level * 24 + additionalNestingLevel * 24}px`,\n ...(settings[option.field]?.rendererParams?.onProvideCssStyles?.(option, { isVisible }) ?? {}),\n }\"\n @handle-selected=\"$emit('handle-tree-select', $event)\"\n @mouseenter=\"handleMouseEnter(option.node_id)\"\n @mouseleave=\"handleMouseLeave()\"\n @contextmenu.stop=\"settings[option.field]?.rendererParams?.onContextMenu?.($event, option)\"\n >\n <PvTreeReorderIcon v-show=\"hoveredId === option.node_id && canItemBeDragged(isDraggable, settings, option)\" />\n <component\n v-if=\"settings[option.field]?.renderer\"\n :is=\"settings[option.field]?.renderer\"\n :option=\"option\"\n :settings=\"settings\"\n :selected=\"isSelected(option.node_id)\"\n :params=\"settings[option.field]?.rendererParams\"\n />\n <PvSimpleItemTree v-else :label=\"option.label\" :icon=\"settings[option.field]?.icon\" />\n </component>\n <!-- Drop zone for children -->\n <div :data-parent-id=\"option.node_id\">\n <draggable\n v-model=\"children\"\n :parent-id=\"option.node_id\"\n :group=\"getDragGroupConfig(settings, option)\"\n item-key=\"node_id\"\n :disabled=\"getDragAndDropDisabled(isDraggable, settings, option)\"\n :move=\"handleMoveCallback(settings)\"\n :class=\"{\n 'pv-tree-drop-zone':\n isDraggable && isDragging && children.length === 0 && canAcceptDrop(settings, option, draggingGroupName),\n }\"\n @start=\"handleDragStart\"\n @end=\"onDragEnd\"\n @add=\"onDragEnd\"\n >\n <template #item=\"{ element, index }\">\n <PvSimpleNestedTreeItem\n :is-parent-path-open=\"isParentPathOpen\"\n :option=\"element\"\n :settings=\"settings\"\n :level=\"nestedLevelTree\"\n :index=\"index\"\n :total-siblings=\"children.length\"\n :parent-field=\"option.field\"\n :selected-options=\"selectedOptions\"\n :is-draggable=\"isDraggable\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"$emit('handle-tree-select', $event)\"\n @update:children=\"$emit('update:children', $event)\"\n />\n </template>\n </draggable>\n </div>\n </div>\n</template>\n\n<style scoped>\n.pv-tree-drop-zone {\n min-height: 0px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport draggable from \"vuedraggable\";\nimport PvTreeReorderIcon from \"./PvTreeReorderIcon.vue\";\nimport PvButtonTreeItem from \"./PvButtonTreeItem.vue\";\nimport PvCheckboxTreeItem from \"./PvCheckboxTreeItem.vue\";\nimport PvSimpleItemTree from \"./PvSimpleItemTree.vue\";\nimport PvSimpleNestedTreeItem from \"./PvSimpleNestedTreeItem.vue\";\nimport type { PvTreeOption, PvTreeSettings } from \"./types\";\n\nimport { useHoverIcon } from \"./composables/useHoverIcon\";\nimport { useDragAndDrop } from \"./composables/useDragAndDrop\";\nimport { useDraggingState } from \"./composables/useDraggingState\";\nimport { useDragAndDropIndicator } from \"./composables/useDragAndDropIndicator\";\n\ninterface PvSimpleNestedTreeProps {\n option: PvTreeOption;\n settings: PvTreeSettings;\n level: number;\n selectedOptions?: PvTreeOption[];\n isDraggable?: boolean;\n isParentPathOpen?: boolean;\n disableSelection?: boolean;\n}\n\nconst props = defineProps<PvSimpleNestedTreeProps>();\n\nconst emit = defineEmits<{\n (e: \"handle-tree-select\", payload: { option: PvTreeOption; event: MouseEvent }): void;\n (e: \"update:children\", payload: { optionId: PvTreeOption[\"node_id\"]; newChildren: PvTreeOption[] }): void;\n}>();\n\nconst { hoveredId, handleMouseEnter, handleMouseLeave } = useHoverIcon();\nconst { getDragAndDropDisabled, canItemBeDragged, handleMoveCallback, getDragGroupConfig, canAcceptDrop } =\n useDragAndDrop();\nconst { isDragging, draggingGroupName, onDragStart, onDragEnd } = useDraggingState();\nconst { dragAndDropIndicatorClasses } = useDragAndDropIndicator();\n\nconst handleDragStart = () => {\n const groupConfig = getDragGroupConfig(props.settings, props.option);\n onDragStart(groupConfig.name);\n};\n\nconst additionalNestingLevel = computed(() => {\n return props.settings[props.option.field]?.additionalNestingLevel ?? 0;\n});\n\n/**\n * If we have showNestedTree as a false we want to add one more indentation level\n */\nconst nestedLevelTree = computed(() => {\n return props.settings[props.option.field]?.showNestedTree\n ? props.level + additionalNestingLevel.value\n : props.level + 1 + additionalNestingLevel.value;\n});\n\nconst isSelected = (id?: string | number) => {\n return props.selectedOptions && props.selectedOptions.some((option) => option.node_id === id);\n};\n\nconst componentInstance = (option: PvTreeOption) => {\n return props.settings[option.field]?.checkbox ? PvCheckboxTreeItem : PvButtonTreeItem;\n};\n\n// Writable computed for vuedraggable v-model binding\nconst children = computed({\n get: () => [...(props.option.children || [])],\n set: (value) => {\n emit(\"update:children\", { optionId: props.option.node_id, newChildren: value });\n },\n});\n\nconst isVisible = computed(() => props.isParentPathOpen ?? true);\n</script>\n\n<template>\n <div class=\"pv-flow\" style=\"--flow-size: 0px\">\n <component\n :is=\"componentInstance(option)\"\n :option=\"option\"\n :selected=\"isSelected(option.node_id)\"\n :disable-selection=\"disableSelection\"\n :label=\"option.label\"\n :icon=\"settings[option.field]?.icon\"\n :class=\"{\n ...dragAndDropIndicatorClasses(option),\n }\"\n :style=\"{\n paddingLeft: `${level * 24 + additionalNestingLevel * 24}px`,\n ...(settings[option.field]?.rendererParams?.onProvideCssStyles?.(option, { isVisible }) ?? {}),\n }\"\n @handle-selected=\"$emit('handle-tree-select', $event)\"\n @mouseenter=\"handleMouseEnter(option.node_id)\"\n @mouseleave=\"handleMouseLeave()\"\n @contextmenu.stop=\"settings[option.field]?.rendererParams?.onContextMenu?.($event, option)\"\n >\n <PvTreeReorderIcon v-show=\"hoveredId === option.node_id && canItemBeDragged(isDraggable, settings, option)\" />\n <component\n v-if=\"settings[option.field]?.renderer\"\n :is=\"settings[option.field]?.renderer\"\n :option=\"option\"\n :settings=\"settings\"\n :selected=\"isSelected(option.node_id)\"\n :params=\"settings[option.field]?.rendererParams\"\n />\n <PvSimpleItemTree v-else :label=\"option.label\" :icon=\"settings[option.field]?.icon\" />\n </component>\n <!-- Drop zone for children -->\n <div :data-parent-id=\"option.node_id\">\n <draggable\n v-model=\"children\"\n :parent-id=\"option.node_id\"\n :group=\"getDragGroupConfig(settings, option)\"\n item-key=\"node_id\"\n :disabled=\"getDragAndDropDisabled(isDraggable, settings, option)\"\n :move=\"handleMoveCallback(settings)\"\n :class=\"{\n 'pv-tree-drop-zone':\n isDraggable && isDragging && children.length === 0 && canAcceptDrop(settings, option, draggingGroupName),\n }\"\n @start=\"handleDragStart\"\n @end=\"onDragEnd\"\n @add=\"onDragEnd\"\n >\n <template #item=\"{ element, index }\">\n <PvSimpleNestedTreeItem\n :is-parent-path-open=\"isParentPathOpen\"\n :option=\"element\"\n :settings=\"settings\"\n :level=\"nestedLevelTree\"\n :index=\"index\"\n :total-siblings=\"children.length\"\n :parent-field=\"option.field\"\n :selected-options=\"selectedOptions\"\n :is-draggable=\"isDraggable\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"$emit('handle-tree-select', $event)\"\n @update:children=\"$emit('update:children', $event)\"\n />\n </template>\n </draggable>\n </div>\n </div>\n</template>\n\n<style scoped>\n.pv-tree-drop-zone {\n min-height: 0px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from \"vue\";\nimport draggable from \"vuedraggable\";\n\nimport PvAccordion from \"../PvAccordion/PvAccordion.vue\";\nimport PvSimpleItemTree from \"./PvSimpleItemTree.vue\";\nimport PvSimpleNestedTree from \"./PvSimpleNestedTree.vue\";\nimport PvCheckboxTreeItem from \"./PvCheckboxTreeItem.vue\";\nimport PvButtonTreeItem from \"./PvButtonTreeItem.vue\";\nimport PvTreeReorderIcon from \"./PvTreeReorderIcon.vue\";\nimport { useHoverIcon } from \"./composables/useHoverIcon\";\nimport { useDraggingState } from \"./composables/useDraggingState\";\nimport { useDragAndDropIndicator } from \"./composables/useDragAndDropIndicator\";\n\nimport type { PvTreeOption, PvTreeSettings } from \"./types\";\nimport { useDragAndDrop } from \"./composables/useDragAndDrop\";\n\ninterface PvTreeItemProps {\n option: PvTreeOption;\n selectedOptions?: PvTreeOption[];\n level?: number;\n settings: PvTreeSettings;\n isDraggable?: boolean;\n treeOpen?: boolean;\n isParentPathOpen?: boolean;\n isLastRootItem?: boolean;\n disableSelection?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvTreeItemProps>(), {\n level: 0,\n isParentPathOpen: true,\n disableSelection: false,\n});\n\nconst emit = defineEmits<{\n (e: \"handle-tree-select\", payload: { option: PvTreeOption; event: MouseEvent }): void;\n (e: \"update:children\", payload: { optionId: PvTreeOption[\"node_id\"]; newChildren: PvTreeOption[] }): void;\n}>();\n\n// Local accordion state - independent from treeOpen prop\nconst accordionOpen = ref(props.treeOpen ?? props.settings[props.option.field]?.defaultExpanded ?? false);\n\n// Watch treeOpen prop to allow programmatic control (e.g., \"expand all\" button)\nwatch(\n () => props.treeOpen,\n (newValue) => {\n if (newValue !== undefined) {\n accordionOpen.value = newValue;\n }\n },\n);\n\nconst {\n getDragGroupConfig,\n getDragAndDropDisabled,\n canItemBeDragged,\n handleMoveCallback,\n childrenDraggable,\n canAcceptDrop,\n} = useDragAndDrop();\nconst { hoveredId, handleMouseEnter, handleMouseLeave } = useHoverIcon();\nconst { isDragging, draggingGroupName, onDragStart, onDragEnd } = useDraggingState();\nconst { dragAndDropIndicatorClasses } = useDragAndDropIndicator();\n\nconst handleDragStart = () => {\n const groupConfig = getDragGroupConfig(props.settings, props.option);\n onDragStart(groupConfig.name);\n};\n\nconst nestedStyles = (level: number) => {\n return {\n paddingLeft: `${level * 24 + (props.settings[props.option.field]?.additionalNestingLevel ?? 0) * 24}px`,\n \"--border-color\": \"#121313\",\n };\n};\n\nconst isSelected = (id?: string | number) => {\n return props.selectedOptions && props.selectedOptions.some((option) => option.node_id === id);\n};\n\nconst componentInstance = computed(() => {\n return props.settings[props.option.field]?.checkbox ? PvCheckboxTreeItem : PvButtonTreeItem;\n});\n\n// Writable computed for vuedraggable v-model binding\nconst children = computed({\n get: () => [...(props.option.children || [])],\n set: (value) => {\n emit(\"update:children\", { optionId: props.option.node_id, newChildren: value });\n },\n});\n\nconst isAccordionRow = computed(() =>\n Boolean(props.option.children?.length && props.settings[props.option.field]?.accordion),\n);\n\nconst isVisible = computed(() => {\n const pathOpen = props.isParentPathOpen ?? true;\n if (!pathOpen) return false;\n // For accordion row at root (level 0): background only when this accordion is expanded\n // For accordion that is a child (level > 0): background when parent is open (pathOpen)\n if (isAccordionRow.value) return props.level === 0 ? accordionOpen.value : true;\n return true;\n});\n</script>\n\n<template>\n <PvAccordion\n v-if=\"option.children && option.children.length > 0 && settings && settings[option.field]?.accordion\"\n v-model=\"accordionOpen\"\n chevronPosition=\"left\"\n style=\"\n --accordion-content-padding: 2px 0px;\n --accordion-arrow-right-summary-padding: 0.25rem 1.375rem 0.25rem 0.25rem;\n --accordion-content-padding: 0px;\n \"\n :data-parent-id=\"option.node_id\"\n enableTriggerSlot\n enableTriggerFullWidth\n :summaryStyles=\"{\n ...nestedStyles(level),\n ...(settings[option.field]?.rendererParams?.onProvideCssStyles?.(option, { isVisible }) ?? {}),\n 'justify-content': 'flex-start',\n }\"\n :summaryClasses=\"{\n 'pv-tree-item': true,\n ...dragAndDropIndicatorClasses(option),\n }\"\n :defaultOpen=\"settings[option.field]?.defaultExpanded ?? false\"\n chevron-variant=\"horizontal\"\n @summary-mouseenter=\"handleMouseEnter(option.node_id)\"\n @summary-mouseleave=\"handleMouseLeave()\"\n @contextmenu.stop=\"settings[option.field]?.rendererParams?.onContextMenu?.($event, option)\"\n >\n <template #trigger>\n <PvTreeReorderIcon\n v-show=\"hoveredId === option.node_id && canItemBeDragged(isDraggable, settings, option) && level > 0\"\n />\n <template v-if=\"settings[option.field]?.renderer\">\n <component\n :is=\"settings[option.field]?.renderer\"\n :option=\"option\"\n :settings=\"settings\"\n :selected=\"isSelected(option.node_id)\"\n :params=\"settings[option.field]?.rendererParams\"\n />\n </template>\n <template v-else>\n <PvSimpleItemTree :label=\"option.label\" :icon=\"settings[option.field]?.icon\" />\n </template>\n </template>\n <!-- Drop zone for children -->\n <div :data-parent-id=\"option.node_id\">\n <draggable\n v-model=\"children\"\n :parent-id=\"option.node_id\"\n :group=\"getDragGroupConfig(settings, option)\"\n item-key=\"node_id\"\n :disabled=\"getDragAndDropDisabled(isDraggable, settings, option)\"\n :move=\"handleMoveCallback(settings)\"\n :class=\"{\n 'pv-tree-drop-zone':\n isDraggable && children.length === 0 && canAcceptDrop(settings, option, draggingGroupName),\n }\"\n @start=\"handleDragStart\"\n @end=\"onDragEnd\"\n @add=\"onDragEnd\"\n >\n <template #item=\"{ element }\">\n <PvTreeItem\n :is-parent-path-open=\"isParentPathOpen && accordionOpen\"\n :selected-options=\"selectedOptions\"\n :option=\"element\"\n :settings=\"settings\"\n :level=\"level + 1\"\n :is-draggable=\"childrenDraggable(isDraggable, settings, element)\"\n :tree-open=\"treeOpen\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"$emit('handle-tree-select', $event)\"\n @update:children=\"$emit('update:children', $event)\"\n />\n </template>\n </draggable>\n </div>\n </PvAccordion>\n <PvSimpleNestedTree\n v-else-if=\"option.children && option.children.length > 0 && settings && !settings[option.field]?.accordion\"\n :is-parent-path-open=\"isParentPathOpen\"\n :selected-options=\"selectedOptions\"\n :option=\"option\"\n :settings=\"settings\"\n :level=\"level\"\n :is-draggable=\"isDraggable\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"$emit('handle-tree-select', $event)\"\n @update:children=\"$emit('update:children', $event)\"\n :is-last-root-item=\"isLastRootItem\"\n />\n <div v-else>\n <component\n :is=\"componentInstance\"\n :class=\"{\n ...dragAndDropIndicatorClasses(option),\n }\"\n :option=\"option\"\n :selected=\"isSelected(option.node_id)\"\n :disable-selection=\"disableSelection\"\n :label=\"option.label\"\n :icon=\"settings[option.field]?.icon\"\n :style=\"{\n ...nestedStyles(level),\n ...(settings[option.field]?.rendererParams?.onProvideCssStyles?.(option, { isVisible }) ?? {}),\n }\"\n @handle-selected=\"$emit('handle-tree-select', $event)\"\n @mouseenter=\"handleMouseEnter(option.node_id)\"\n @mouseleave=\"handleMouseLeave()\"\n @contextmenu.stop=\"settings[option.field]?.rendererParams?.onContextMenu?.($event, option)\"\n >\n <PvTreeReorderIcon\n v-show=\"hoveredId === option.node_id && canItemBeDragged(isDraggable, settings, option) && level > 0\"\n />\n <component\n v-if=\"settings[option.field]?.renderer\"\n :is=\"settings[option.field]?.renderer\"\n :option=\"option\"\n :settings=\"settings\"\n :params=\"settings[option.field]?.rendererParams\"\n />\n <PvSimpleItemTree v-else :label=\"option.label\" :icon=\"settings[option.field]?.icon\" />\n </component>\n <!-- Drop zone for children -->\n <div :data-parent-id=\"option.node_id\">\n <draggable\n v-model=\"children\"\n :parent-id=\"option.node_id\"\n :group=\"getDragGroupConfig(settings, option)\"\n item-key=\"node_id\"\n :disabled=\"getDragAndDropDisabled(isDraggable, settings, option)\"\n :move=\"handleMoveCallback(settings)\"\n :class=\"{\n 'pv-tree-drop-zone':\n isDragging && children.length === 0 && canAcceptDrop(settings, option, draggingGroupName),\n }\"\n @start=\"handleDragStart\"\n @end=\"onDragEnd\"\n @add=\"onDragEnd\"\n >\n <template #item=\"{ element }\">\n <PvTreeItem\n :is-parent-path-open=\"isParentPathOpen\"\n :selected-options=\"selectedOptions\"\n :option=\"element\"\n :settings=\"settings\"\n :level=\"level + 1\"\n :is-draggable=\"childrenDraggable(isDraggable, settings, element)\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"$emit('handle-tree-select', $event)\"\n @update:children=\"$emit('update:children', $event)\"\n />\n </template>\n </draggable>\n </div>\n </div>\n</template>\n\n<style scoped>\n.pv-tree-drop-zone {\n min-height: 0px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from \"vue\";\nimport draggable from \"vuedraggable\";\n\nimport PvAccordion from \"../PvAccordion/PvAccordion.vue\";\nimport PvSimpleItemTree from \"./PvSimpleItemTree.vue\";\nimport PvSimpleNestedTree from \"./PvSimpleNestedTree.vue\";\nimport PvCheckboxTreeItem from \"./PvCheckboxTreeItem.vue\";\nimport PvButtonTreeItem from \"./PvButtonTreeItem.vue\";\nimport PvTreeReorderIcon from \"./PvTreeReorderIcon.vue\";\nimport { useHoverIcon } from \"./composables/useHoverIcon\";\nimport { useDraggingState } from \"./composables/useDraggingState\";\nimport { useDragAndDropIndicator } from \"./composables/useDragAndDropIndicator\";\n\nimport type { PvTreeOption, PvTreeSettings } from \"./types\";\nimport { useDragAndDrop } from \"./composables/useDragAndDrop\";\n\ninterface PvTreeItemProps {\n option: PvTreeOption;\n selectedOptions?: PvTreeOption[];\n level?: number;\n settings: PvTreeSettings;\n isDraggable?: boolean;\n treeOpen?: boolean;\n isParentPathOpen?: boolean;\n isLastRootItem?: boolean;\n disableSelection?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvTreeItemProps>(), {\n level: 0,\n isParentPathOpen: true,\n disableSelection: false,\n});\n\nconst emit = defineEmits<{\n (e: \"handle-tree-select\", payload: { option: PvTreeOption; event: MouseEvent }): void;\n (e: \"update:children\", payload: { optionId: PvTreeOption[\"node_id\"]; newChildren: PvTreeOption[] }): void;\n}>();\n\n// Local accordion state - independent from treeOpen prop\nconst accordionOpen = ref(props.treeOpen ?? props.settings[props.option.field]?.defaultExpanded ?? false);\n\n// Watch treeOpen prop to allow programmatic control (e.g., \"expand all\" button)\nwatch(\n () => props.treeOpen,\n (newValue) => {\n if (newValue !== undefined) {\n accordionOpen.value = newValue;\n }\n },\n);\n\nconst {\n getDragGroupConfig,\n getDragAndDropDisabled,\n canItemBeDragged,\n handleMoveCallback,\n childrenDraggable,\n canAcceptDrop,\n} = useDragAndDrop();\nconst { hoveredId, handleMouseEnter, handleMouseLeave } = useHoverIcon();\nconst { isDragging, draggingGroupName, onDragStart, onDragEnd } = useDraggingState();\nconst { dragAndDropIndicatorClasses } = useDragAndDropIndicator();\n\nconst handleDragStart = () => {\n const groupConfig = getDragGroupConfig(props.settings, props.option);\n onDragStart(groupConfig.name);\n};\n\nconst nestedStyles = (level: number) => {\n return {\n paddingLeft: `${level * 24 + (props.settings[props.option.field]?.additionalNestingLevel ?? 0) * 24}px`,\n \"--border-color\": \"#121313\",\n };\n};\n\nconst isSelected = (id?: string | number) => {\n return props.selectedOptions && props.selectedOptions.some((option) => option.node_id === id);\n};\n\nconst componentInstance = computed(() => {\n return props.settings[props.option.field]?.checkbox ? PvCheckboxTreeItem : PvButtonTreeItem;\n});\n\n// Writable computed for vuedraggable v-model binding\nconst children = computed({\n get: () => [...(props.option.children || [])],\n set: (value) => {\n emit(\"update:children\", { optionId: props.option.node_id, newChildren: value });\n },\n});\n\nconst isAccordionRow = computed(() =>\n Boolean(props.option.children?.length && props.settings[props.option.field]?.accordion),\n);\n\nconst isVisible = computed(() => {\n const pathOpen = props.isParentPathOpen ?? true;\n if (!pathOpen) return false;\n // For accordion row at root (level 0): background only when this accordion is expanded\n // For accordion that is a child (level > 0): background when parent is open (pathOpen)\n if (isAccordionRow.value) return props.level === 0 ? accordionOpen.value : true;\n return true;\n});\n</script>\n\n<template>\n <PvAccordion\n v-if=\"option.children && option.children.length > 0 && settings && settings[option.field]?.accordion\"\n v-model=\"accordionOpen\"\n chevronPosition=\"left\"\n style=\"\n --accordion-content-padding: 2px 0px;\n --accordion-arrow-right-summary-padding: 0.25rem 1.375rem 0.25rem 0.25rem;\n --accordion-content-padding: 0px;\n \"\n :data-parent-id=\"option.node_id\"\n enableTriggerSlot\n enableTriggerFullWidth\n :summaryStyles=\"{\n ...nestedStyles(level),\n ...(settings[option.field]?.rendererParams?.onProvideCssStyles?.(option, { isVisible }) ?? {}),\n 'justify-content': 'flex-start',\n }\"\n :summaryClasses=\"{\n 'pv-tree-item': true,\n ...dragAndDropIndicatorClasses(option),\n }\"\n :defaultOpen=\"settings[option.field]?.defaultExpanded ?? false\"\n chevron-variant=\"horizontal\"\n @summary-mouseenter=\"handleMouseEnter(option.node_id)\"\n @summary-mouseleave=\"handleMouseLeave()\"\n @contextmenu.stop=\"settings[option.field]?.rendererParams?.onContextMenu?.($event, option)\"\n >\n <template #trigger>\n <PvTreeReorderIcon\n v-show=\"hoveredId === option.node_id && canItemBeDragged(isDraggable, settings, option) && level > 0\"\n />\n <template v-if=\"settings[option.field]?.renderer\">\n <component\n :is=\"settings[option.field]?.renderer\"\n :option=\"option\"\n :settings=\"settings\"\n :selected=\"isSelected(option.node_id)\"\n :params=\"settings[option.field]?.rendererParams\"\n />\n </template>\n <template v-else>\n <PvSimpleItemTree :label=\"option.label\" :icon=\"settings[option.field]?.icon\" />\n </template>\n </template>\n <!-- Drop zone for children -->\n <div :data-parent-id=\"option.node_id\">\n <draggable\n v-model=\"children\"\n :parent-id=\"option.node_id\"\n :group=\"getDragGroupConfig(settings, option)\"\n item-key=\"node_id\"\n :disabled=\"getDragAndDropDisabled(isDraggable, settings, option)\"\n :move=\"handleMoveCallback(settings)\"\n :class=\"{\n 'pv-tree-drop-zone':\n isDraggable && children.length === 0 && canAcceptDrop(settings, option, draggingGroupName),\n }\"\n @start=\"handleDragStart\"\n @end=\"onDragEnd\"\n @add=\"onDragEnd\"\n >\n <template #item=\"{ element }\">\n <PvTreeItem\n :is-parent-path-open=\"isParentPathOpen && accordionOpen\"\n :selected-options=\"selectedOptions\"\n :option=\"element\"\n :settings=\"settings\"\n :level=\"level + 1\"\n :is-draggable=\"childrenDraggable(isDraggable, settings, element)\"\n :tree-open=\"treeOpen\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"$emit('handle-tree-select', $event)\"\n @update:children=\"$emit('update:children', $event)\"\n />\n </template>\n </draggable>\n </div>\n </PvAccordion>\n <PvSimpleNestedTree\n v-else-if=\"option.children && option.children.length > 0 && settings && !settings[option.field]?.accordion\"\n :is-parent-path-open=\"isParentPathOpen\"\n :selected-options=\"selectedOptions\"\n :option=\"option\"\n :settings=\"settings\"\n :level=\"level\"\n :is-draggable=\"isDraggable\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"$emit('handle-tree-select', $event)\"\n @update:children=\"$emit('update:children', $event)\"\n :is-last-root-item=\"isLastRootItem\"\n />\n <div v-else>\n <component\n :is=\"componentInstance\"\n :class=\"{\n ...dragAndDropIndicatorClasses(option),\n }\"\n :option=\"option\"\n :selected=\"isSelected(option.node_id)\"\n :disable-selection=\"disableSelection\"\n :label=\"option.label\"\n :icon=\"settings[option.field]?.icon\"\n :style=\"{\n ...nestedStyles(level),\n ...(settings[option.field]?.rendererParams?.onProvideCssStyles?.(option, { isVisible }) ?? {}),\n }\"\n @handle-selected=\"$emit('handle-tree-select', $event)\"\n @mouseenter=\"handleMouseEnter(option.node_id)\"\n @mouseleave=\"handleMouseLeave()\"\n @contextmenu.stop=\"settings[option.field]?.rendererParams?.onContextMenu?.($event, option)\"\n >\n <PvTreeReorderIcon\n v-show=\"hoveredId === option.node_id && canItemBeDragged(isDraggable, settings, option) && level > 0\"\n />\n <component\n v-if=\"settings[option.field]?.renderer\"\n :is=\"settings[option.field]?.renderer\"\n :option=\"option\"\n :settings=\"settings\"\n :params=\"settings[option.field]?.rendererParams\"\n />\n <PvSimpleItemTree v-else :label=\"option.label\" :icon=\"settings[option.field]?.icon\" />\n </component>\n <!-- Drop zone for children -->\n <div :data-parent-id=\"option.node_id\">\n <draggable\n v-model=\"children\"\n :parent-id=\"option.node_id\"\n :group=\"getDragGroupConfig(settings, option)\"\n item-key=\"node_id\"\n :disabled=\"getDragAndDropDisabled(isDraggable, settings, option)\"\n :move=\"handleMoveCallback(settings)\"\n :class=\"{\n 'pv-tree-drop-zone':\n isDragging && children.length === 0 && canAcceptDrop(settings, option, draggingGroupName),\n }\"\n @start=\"handleDragStart\"\n @end=\"onDragEnd\"\n @add=\"onDragEnd\"\n >\n <template #item=\"{ element }\">\n <PvTreeItem\n :is-parent-path-open=\"isParentPathOpen\"\n :selected-options=\"selectedOptions\"\n :option=\"element\"\n :settings=\"settings\"\n :level=\"level + 1\"\n :is-draggable=\"childrenDraggable(isDraggable, settings, element)\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"$emit('handle-tree-select', $event)\"\n @update:children=\"$emit('update:children', $event)\"\n />\n </template>\n </draggable>\n </div>\n </div>\n</template>\n\n<style scoped>\n.pv-tree-drop-zone {\n min-height: 0px;\n}\n</style>\n","import { nextTick, Ref } from \"vue\";\nimport { cloneDeep } from \"es-toolkit/object\";\nimport { PvTreeOption } from \"../types\";\n\nexport const useTreeUpdate = (options: Ref<PvTreeOption[]>) => {\n const pendingChildrenUpdates: { optionId: PvTreeOption[\"node_id\"]; newChildren: PvTreeOption[] }[] = [];\n let flushScheduled = false;\n\n /**\n * Builds fast lookup indexes for the tree:\n * - nodeById: allows O(1) access to any node by id\n * - parentById: tracks the current parent of each node\n *\n * This avoids repeated full tree traversals during updates.\n */\n function buildIndex(roots: PvTreeOption[]): {\n nodeById: Map<PvTreeOption[\"node_id\"], PvTreeOption>;\n parentById: Map<PvTreeOption[\"node_id\"], PvTreeOption | null>;\n } {\n const nodeById = new Map<PvTreeOption[\"node_id\"], PvTreeOption>();\n const parentById = new Map<PvTreeOption[\"node_id\"], PvTreeOption | null>();\n\n // Iterative DFS to avoid deep recursion on large trees\n const stack: Array<{ node: PvTreeOption; parent: PvTreeOption | null }> = [];\n for (const root of roots) {\n stack.push({ node: root, parent: null });\n }\n\n while (stack.length) {\n const { node, parent } = stack.pop()!;\n nodeById.set(node.node_id, node);\n parentById.set(node.node_id, parent);\n\n if (node.children?.length) {\n for (const child of node.children) {\n stack.push({ node: child, parent: node });\n }\n }\n }\n\n return { nodeById, parentById };\n }\n\n /**\n * Applies all pending children updates in a single flush.\n *\n * Key ideas:\n * - Clone the tree once to keep updates immutable\n * - Build indexes once for fast lookups\n * - Move nodes by re-parenting instead of re-traversing the tree\n */\n const flushPendingChildrenUpdates = () => {\n flushScheduled = false;\n\n // Nothing to do\n if (pendingChildrenUpdates.length === 0) return;\n\n // Take all pending updates and clear the queue\n const updates = pendingChildrenUpdates.splice(0, pendingChildrenUpdates.length);\n\n // Clone the current options tree only once\n const result = cloneDeep(options.value);\n\n // Build fast lookup structures\n const { nodeById, parentById } = buildIndex(result);\n\n /**\n * If multiple updates target the same optionId,\n * the last one wins.\n */\n const lastUpdateByOption = new Map<PvTreeOption[\"node_id\"], PvTreeOption[]>();\n for (const update of updates) {\n lastUpdateByOption.set(update.optionId, update.newChildren);\n }\n\n // Apply normalized updates\n for (const [optionId, newChildren] of lastUpdateByOption) {\n const parentNode = nodeById.get(optionId);\n if (!parentNode) continue;\n\n /**\n * Map children:\n * - If a node already exists in the tree, reuse it (we are moving it)\n * - Otherwise, treat it as a new node\n */\n const mappedChildren = newChildren.map((child) => nodeById.get(child.node_id) ?? child);\n\n /**\n * Register any brand-new nodes in the indexes\n */\n for (const child of mappedChildren) {\n if (!nodeById.has(child.node_id)) {\n nodeById.set(child.node_id, child);\n parentById.set(child.node_id, null);\n }\n }\n\n /**\n * Re-parent children:\n * - Detach from the old parent if necessary\n * - Attach to the new parent\n */\n for (const child of mappedChildren) {\n const oldParent = parentById.get(child.node_id) ?? null;\n\n // Remove from previous parent if it differs from the new one\n if (oldParent && oldParent !== parentNode) {\n oldParent.children = (oldParent.children ?? []).filter((c) => c.node_id !== child.node_id);\n }\n\n parentById.set(child.node_id, parentNode);\n }\n\n // Finally, replace the parent's children list\n parentNode.children = mappedChildren;\n }\n\n // Commit the updated tree\n options.value = result;\n };\n\n const handleUpdateChildren = ({\n optionId,\n newChildren,\n }: {\n optionId: PvTreeOption[\"node_id\"];\n newChildren: PvTreeOption[];\n }) => {\n // Queue the update; flush applies all pending updates in one pass (last per optionId wins).\n pendingChildrenUpdates.push({ optionId, newChildren });\n if (!flushScheduled) {\n flushScheduled = true;\n nextTick(flushPendingChildrenUpdates);\n }\n };\n\n return {\n handleUpdateChildren,\n };\n};\n","<script setup lang=\"ts\">\nimport { computed, inject } from \"vue\";\n\nimport PvTreeItem from \"./PvTreeItem.vue\";\nimport type { PvTreeOption, PvTreeSetting, PvTreeSettings } from \"./types\";\nimport { provideDraggingState } from \"./composables/useDraggingState\";\nimport { DraggingStateKey } from \"./symbols\";\nimport { useTreeUpdate } from \"./composables/useTreeUpdate\";\n\n// Only provide dragging state if a PvTreeGroup hasn't already provided it.\n// This allows multiple trees inside a PvTreeGroup to share the same state\n// for cross-tree drag indicators, while a standalone PvTree remains self-contained.\nif (!inject(DraggingStateKey, null)) {\n provideDraggingState();\n}\n\ninterface PvTreeProps {\n /** Per-field rendering and behavior settings for tree nodes */\n settings: PvTreeSettings;\n /** Default settings applied to all node types before field-specific overrides */\n defaultSettings?: PvTreeSetting;\n /** Enable drag-and-drop reordering of tree items */\n isDraggable?: boolean;\n /** Disable click-to-select behavior on tree items */\n disableSelection?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvTreeProps>(), {\n isDraggable: false,\n disableSelection: false,\n});\n\nconst selectedOptions = defineModel<PvTreeOption[]>(\"selectedOptions\", { required: false });\nconst options = defineModel<PvTreeOption[]>(\"options\", { required: true });\nconst treeOpen = defineModel<boolean>(\"treeOpen\", { required: false });\n\nconst { handleUpdateChildren } = useTreeUpdate(options);\n\nconst handleTreeSelect = (option: PvTreeOption, event: MouseEvent) => {\n if (event.metaKey) {\n if (selectedOptions.value?.some((selectedOption) => selectedOption.node_id === option.node_id)) {\n selectedOptions.value = selectedOptions.value?.filter(\n (selectedOption) => selectedOption.node_id !== option.node_id,\n );\n } else {\n selectedOptions.value = [...(selectedOptions.value || []), option];\n }\n } else {\n if (selectedOptions.value?.some((selectedOption) => selectedOption.node_id === option.node_id)) {\n selectedOptions.value = [];\n } else {\n selectedOptions.value = [option];\n }\n }\n};\n\nconst computedSettings = computed(() => {\n return Object.keys(props.settings).reduce((acc, key) => {\n acc[key] = { ...props.defaultSettings, ...props.settings[key] };\n return acc;\n }, {} as PvTreeSettings);\n});\n</script>\n\n<template>\n <div>\n <div class=\"pv-tree\" :class=\"{ 'pv-tree--disable-selection': disableSelection }\">\n <div v-for=\"(option, index) in options\" :key=\"option.node_id\">\n <PvTreeItem\n :is-last-root-item=\"index === options.length - 1\"\n :is-parent-path-open=\"true\"\n :tree-open=\"treeOpen\"\n :selected-options=\"selectedOptions\"\n :option=\"option\"\n :settings=\"computedSettings\"\n :is-draggable=\"isDraggable\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"({ option, event }) => handleTreeSelect(option, event)\"\n @update:children=\"handleUpdateChildren\"\n />\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n/* This may be moved to a global styles file */\n:deep(.pv-tree-item) {\n padding: 3px 4px;\n cursor: pointer;\n background-color: transparent;\n border: 1px solid transparent;\n}\n\n:deep(.pv-tree-item-disabled) {\n cursor: default !important;\n}\n\n:deep(.pv-tree-item.pv-drop-indicator-top) {\n border-top: 1px solid var(--color-border, #121313);\n}\n:deep(.pv-tree-item.pv-drop-indicator-bottom) {\n border-bottom: 1px solid var(--color-border, #121313);\n}\n\n:deep(.pv-drop-indicator-parent) {\n border: 1px solid var(--color-border, #36c5ba);\n}\n\n:deep(.pv-tree-item-selected) {\n background-color: var(--pv-color-selected, #e4f8f6);\n}\n\n:deep(.pv-tree:not(.pv-tree--disable-selection) .pv-tree-item-selected:hover),\n:deep(.pv-tree:not(.pv-tree--disable-selection) .pv-tree-item:hover) {\n border-radius: 4px;\n background-color: var(--pv-color-hover, #e8f2f4);\n}\n\n:deep(.pv-tree:not(.pv-tree--disable-selection) .pv-tree-item-selected:active),\n:deep(.pv-tree:not(.pv-tree--disable-selection) .pv-tree-item:active) {\n border-radius: 4px;\n background-color: var(--pv-color-active, #c7d8db);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, inject } from \"vue\";\n\nimport PvTreeItem from \"./PvTreeItem.vue\";\nimport type { PvTreeOption, PvTreeSetting, PvTreeSettings } from \"./types\";\nimport { provideDraggingState } from \"./composables/useDraggingState\";\nimport { DraggingStateKey } from \"./symbols\";\nimport { useTreeUpdate } from \"./composables/useTreeUpdate\";\n\n// Only provide dragging state if a PvTreeGroup hasn't already provided it.\n// This allows multiple trees inside a PvTreeGroup to share the same state\n// for cross-tree drag indicators, while a standalone PvTree remains self-contained.\nif (!inject(DraggingStateKey, null)) {\n provideDraggingState();\n}\n\ninterface PvTreeProps {\n /** Per-field rendering and behavior settings for tree nodes */\n settings: PvTreeSettings;\n /** Default settings applied to all node types before field-specific overrides */\n defaultSettings?: PvTreeSetting;\n /** Enable drag-and-drop reordering of tree items */\n isDraggable?: boolean;\n /** Disable click-to-select behavior on tree items */\n disableSelection?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvTreeProps>(), {\n isDraggable: false,\n disableSelection: false,\n});\n\nconst selectedOptions = defineModel<PvTreeOption[]>(\"selectedOptions\", { required: false });\nconst options = defineModel<PvTreeOption[]>(\"options\", { required: true });\nconst treeOpen = defineModel<boolean>(\"treeOpen\", { required: false });\n\nconst { handleUpdateChildren } = useTreeUpdate(options);\n\nconst handleTreeSelect = (option: PvTreeOption, event: MouseEvent) => {\n if (event.metaKey) {\n if (selectedOptions.value?.some((selectedOption) => selectedOption.node_id === option.node_id)) {\n selectedOptions.value = selectedOptions.value?.filter(\n (selectedOption) => selectedOption.node_id !== option.node_id,\n );\n } else {\n selectedOptions.value = [...(selectedOptions.value || []), option];\n }\n } else {\n if (selectedOptions.value?.some((selectedOption) => selectedOption.node_id === option.node_id)) {\n selectedOptions.value = [];\n } else {\n selectedOptions.value = [option];\n }\n }\n};\n\nconst computedSettings = computed(() => {\n return Object.keys(props.settings).reduce((acc, key) => {\n acc[key] = { ...props.defaultSettings, ...props.settings[key] };\n return acc;\n }, {} as PvTreeSettings);\n});\n</script>\n\n<template>\n <div>\n <div class=\"pv-tree\" :class=\"{ 'pv-tree--disable-selection': disableSelection }\">\n <div v-for=\"(option, index) in options\" :key=\"option.node_id\">\n <PvTreeItem\n :is-last-root-item=\"index === options.length - 1\"\n :is-parent-path-open=\"true\"\n :tree-open=\"treeOpen\"\n :selected-options=\"selectedOptions\"\n :option=\"option\"\n :settings=\"computedSettings\"\n :is-draggable=\"isDraggable\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"({ option, event }) => handleTreeSelect(option, event)\"\n @update:children=\"handleUpdateChildren\"\n />\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n/* This may be moved to a global styles file */\n:deep(.pv-tree-item) {\n padding: 3px 4px;\n cursor: pointer;\n background-color: transparent;\n border: 1px solid transparent;\n}\n\n:deep(.pv-tree-item-disabled) {\n cursor: default !important;\n}\n\n:deep(.pv-tree-item.pv-drop-indicator-top) {\n border-top: 1px solid var(--color-border, #121313);\n}\n:deep(.pv-tree-item.pv-drop-indicator-bottom) {\n border-bottom: 1px solid var(--color-border, #121313);\n}\n\n:deep(.pv-drop-indicator-parent) {\n border: 1px solid var(--color-border, #36c5ba);\n}\n\n:deep(.pv-tree-item-selected) {\n background-color: var(--pv-color-selected, #e4f8f6);\n}\n\n:deep(.pv-tree:not(.pv-tree--disable-selection) .pv-tree-item-selected:hover),\n:deep(.pv-tree:not(.pv-tree--disable-selection) .pv-tree-item:hover) {\n border-radius: 4px;\n background-color: var(--pv-color-hover, #e8f2f4);\n}\n\n:deep(.pv-tree:not(.pv-tree--disable-selection) .pv-tree-item-selected:active),\n:deep(.pv-tree:not(.pv-tree--disable-selection) .pv-tree-item:active) {\n border-radius: 4px;\n background-color: var(--pv-color-active, #c7d8db);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { provideDraggingState } from \"./composables/useDraggingState\";\n\n// Provides shared drag state to all PvTree children so cross-tree\n// drop indicators and drag status work correctly across sibling trees.\nprovideDraggingState();\n</script>\n\n<template>\n <slot />\n</template>\n","<script setup lang=\"ts\">\nimport { provideDraggingState } from \"./composables/useDraggingState\";\n\n// Provides shared drag state to all PvTree children so cross-tree\n// drop indicators and drag status work correctly across sibling trees.\nprovideDraggingState();\n</script>\n\n<template>\n <slot />\n</template>\n","<script setup lang=\"ts\">\ninterface PvProgressBarProps {\n /** The current progress value as a percentage (0–100). */\n progress?: number;\n /** When true, displays a text label above the bar showing \"{progress}% Complete\". */\n showLabel?: boolean;\n /** When true, renders the progress bar in a disabled/muted visual state. */\n disabled?: boolean;\n}\n\nconst props = defineProps<PvProgressBarProps>();\n</script>\n\n<template>\n <p v-if=\"props.showLabel\" class=\"pv-text-brand pv-text-title-sm pv-stack-4\">{{ props.progress }}% Complete</p>\n <div\n class=\"pv-progress-bar\"\n :data-disabled=\"props.disabled ? true : undefined\"\n :style=\"{\n '--progress': `${props.progress}%`,\n }\"\n ></div>\n</template>\n","<script setup lang=\"ts\">\ninterface PvProgressBarProps {\n /** The current progress value as a percentage (0–100). */\n progress?: number;\n /** When true, displays a text label above the bar showing \"{progress}% Complete\". */\n showLabel?: boolean;\n /** When true, renders the progress bar in a disabled/muted visual state. */\n disabled?: boolean;\n}\n\nconst props = defineProps<PvProgressBarProps>();\n</script>\n\n<template>\n <p v-if=\"props.showLabel\" class=\"pv-text-brand pv-text-title-sm pv-stack-4\">{{ props.progress }}% Complete</p>\n <div\n class=\"pv-progress-bar\"\n :data-disabled=\"props.disabled ? true : undefined\"\n :style=\"{\n '--progress': `${props.progress}%`,\n }\"\n ></div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\ninterface PvDistributionBarProps {\n /** Array of numeric values representing each segment of the distribution bar. Values are rendered proportionally. Supports up to 7 color-coded segments. */\n values?: number[];\n}\n\nconst props = defineProps<PvDistributionBarProps>();\n\nconst totalValue = computed(() => {\n return props.values?.reduce((acc, curr) => acc + curr, 0) ?? 0;\n});\n\nconst barStyles = (value: number, index: number) => {\n const firstNonZeroIndex = props.values?.findIndex((v) => v > 0) ?? -1;\n const lastNonZeroIndex = props.values?.findLastIndex((v) => v > 0) ?? -1;\n const isFirstVisibleElement = index === firstNonZeroIndex;\n const isLastVisibleElement = index === lastNonZeroIndex;\n const radius = (corner: boolean) => (corner ? \"12px\" : \"0\");\n\n return {\n width: `${(value / totalValue.value) * 100}%`,\n height: \"100%\",\n borderRadius: `${radius(isFirstVisibleElement)} ${radius(isLastVisibleElement)} ${radius(isLastVisibleElement)} ${radius(isFirstVisibleElement)}`,\n };\n};\n\nconst barColors = (index: number) => {\n switch (index) {\n case 0:\n return \"pv-data-surface-visualization-1\";\n case 1:\n return \"pv-data-surface-visualization-2\";\n case 2:\n return \"pv-data-surface-visualization-3\";\n case 3:\n return \"pv-data-surface-visualization-4\";\n case 4:\n return \"pv-data-surface-visualization-5\";\n case 5:\n return \"pv-data-surface-visualization-6\";\n case 6:\n return \"pv-data-surface-visualization-7\";\n default:\n return \"pv-data-surface-visualization-1\";\n }\n};\n</script>\n\n<template>\n <div class=\"pv-flex\" style=\"--flex-gap: 4px; height: 24px\">\n <div v-for=\"(value, index) in values\" :key=\"index\" :class=\"[barColors(index)]\" :style=\"barStyles(value, index)\" />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\ninterface PvDistributionBarProps {\n /** Array of numeric values representing each segment of the distribution bar. Values are rendered proportionally. Supports up to 7 color-coded segments. */\n values?: number[];\n}\n\nconst props = defineProps<PvDistributionBarProps>();\n\nconst totalValue = computed(() => {\n return props.values?.reduce((acc, curr) => acc + curr, 0) ?? 0;\n});\n\nconst barStyles = (value: number, index: number) => {\n const firstNonZeroIndex = props.values?.findIndex((v) => v > 0) ?? -1;\n const lastNonZeroIndex = props.values?.findLastIndex((v) => v > 0) ?? -1;\n const isFirstVisibleElement = index === firstNonZeroIndex;\n const isLastVisibleElement = index === lastNonZeroIndex;\n const radius = (corner: boolean) => (corner ? \"12px\" : \"0\");\n\n return {\n width: `${(value / totalValue.value) * 100}%`,\n height: \"100%\",\n borderRadius: `${radius(isFirstVisibleElement)} ${radius(isLastVisibleElement)} ${radius(isLastVisibleElement)} ${radius(isFirstVisibleElement)}`,\n };\n};\n\nconst barColors = (index: number) => {\n switch (index) {\n case 0:\n return \"pv-data-surface-visualization-1\";\n case 1:\n return \"pv-data-surface-visualization-2\";\n case 2:\n return \"pv-data-surface-visualization-3\";\n case 3:\n return \"pv-data-surface-visualization-4\";\n case 4:\n return \"pv-data-surface-visualization-5\";\n case 5:\n return \"pv-data-surface-visualization-6\";\n case 6:\n return \"pv-data-surface-visualization-7\";\n default:\n return \"pv-data-surface-visualization-1\";\n }\n};\n</script>\n\n<template>\n <div class=\"pv-flex\" style=\"--flex-gap: 4px; height: 24px\">\n <div v-for=\"(value, index) in values\" :key=\"index\" :class=\"[barColors(index)]\" :style=\"barStyles(value, index)\" />\n </div>\n</template>\n","import { MenuOption } from \"@/types\";\n\n// The query builder can be used in two modes:\n// 1. Full - the query is parsed and populates both the filter model and free text terms.\n// 2. Field-only - the query is parsed to extract only the filter model, treating free-text terms as invalid\nexport type QueryBuilderProcessor = \"full\" | \"field-only\";\n\nexport interface QueryBuilderOutput {\n queryTerms: QueryTerm[];\n freeTextTerms?: string[];\n}\n\nexport interface QueryTerm {\n queryField?: string;\n queryDisplayField?: string;\n exactMatch?: boolean;\n queryText?: string;\n}\n\nexport interface QueryBuilderSuggestionMenuOption extends MenuOption {\n queryTerm?: QueryTerm;\n}\n\n/**\n * The filter model is structured as follows:\n * For single conditions\n * {\n * [field]: {\n * filterType: \"text\",\n * type: \"equals\" | \"contains\",\n * filter: string,\n * },\n * }\n * For multiple conditions on the same field, it will be structured as:\n * {\n * [field]: {\n * filterType: \"text\",\n * operator: 'OR',\n * conditions: [\n * {\n * type: \"equals\" | \"contains\",\n * filter: string,\n * }\n * ]\n * },\n * }\n */\n\nexport const useQueryBuilder = () => {\n const addQueryOption = (\n query: QueryBuilderOutput | null,\n option: QueryBuilderSuggestionMenuOption,\n ): QueryBuilderOutput | null => {\n const updatedQuery = query || { queryTerms: [] };\n const newQueryTerm = option.queryTerm || {};\n if (isValidQueryTerm(option) && !containsQueryOption(query, option)) {\n updatedQuery.queryTerms.push(newQueryTerm);\n }\n return updatedQuery;\n };\n const isValidQueryTerm = (option: QueryBuilderSuggestionMenuOption): boolean => {\n // don't allow blank query terms\n if (!option.queryTerm) return false;\n return option.queryTerm.queryText !== undefined && option.queryTerm.queryText.trim() !== \"\";\n };\n const queryTermEquals = (a: QueryTerm, b: QueryTerm): boolean => {\n return (\n a.queryField === b.queryField &&\n a.exactMatch === b.exactMatch &&\n a.queryText === b.queryText &&\n a.queryDisplayField === b.queryDisplayField\n );\n };\n const containsQueryOption = (query: QueryBuilderOutput | null, option: QueryBuilderSuggestionMenuOption): boolean => {\n return !!query && query.queryTerms.some((term) => queryTermEquals(term, option.queryTerm || {}));\n };\n const removeQueryOption = (\n query: QueryBuilderOutput | null,\n option: QueryBuilderSuggestionMenuOption,\n ): QueryBuilderOutput | null => {\n // find and remove the option from the query\n if (!query) return null;\n const index = query.queryTerms.findIndex((term) => queryTermEquals(term, option.queryTerm || {}));\n if (index !== -1) {\n query.queryTerms.splice(index, 1);\n }\n return query;\n };\n return {\n addQueryOption,\n containsQueryOption,\n removeQueryOption,\n };\n};\n","<script setup lang=\"ts\">\nimport { QueryTerm } from \"@/components/base/PvQueryBuilderInput/useQueryBuilder\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport { computed, onMounted, ref } from \"vue\";\nimport { MenuOption } from \"@/types\";\n\nconst props = defineProps<MenuOption<QueryTerm>>();\nconst queryBuilderProps = computed(() => {\n return props.context;\n});\n\nconst queryOptionText = ref<HTMLElement | null>(null);\n\nconst exactMatch = computed(() => {\n return queryBuilderProps.value?.exactMatch || false;\n});\nconst displayText = computed(() => {\n return props.text;\n});\n\nconst currentSearchText = computed(() => {\n return props.searchText || \"\";\n});\n\nconst searchField = computed(() => {\n return queryBuilderProps.value?.queryDisplayField;\n});\nconst primaryIcon = computed(() => {\n const optionIcon = props.icon || \"search\";\n return exactMatch.value ? optionIcon : \"search\";\n});\n\nonMounted(() => {\n if (queryOptionText.value && currentSearchText.value) {\n const regex = new RegExp(`(${currentSearchText.value})`, \"gi\");\n queryOptionText.value.innerHTML = displayText.value.replace(regex, '<span style=\"font-weight: bold;\">$1</span>');\n }\n});\n</script>\n\n<template>\n <div>\n <div class=\"pv-flex\">\n <PvIcon :name=\"primaryIcon\"></PvIcon>\n <div>\n <p ref=\"queryOptionText\" class=\"pv-text-body-md\">{{ displayText }}</p>\n <p v-if=\"searchField\" class=\"pv-text-body-xs\">\n <span v-if=\"!exactMatch\">Search in </span>\n <span class=\"pv-text-subdued pv-text-body-xs\" style=\"font-weight: 500\">{{ searchField }}</span>\n </p>\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.pv-text-tertiary {\n color: #6e8081;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { QueryTerm } from \"@/components/base/PvQueryBuilderInput/useQueryBuilder\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport { computed, onMounted, ref } from \"vue\";\nimport { MenuOption } from \"@/types\";\n\nconst props = defineProps<MenuOption<QueryTerm>>();\nconst queryBuilderProps = computed(() => {\n return props.context;\n});\n\nconst queryOptionText = ref<HTMLElement | null>(null);\n\nconst exactMatch = computed(() => {\n return queryBuilderProps.value?.exactMatch || false;\n});\nconst displayText = computed(() => {\n return props.text;\n});\n\nconst currentSearchText = computed(() => {\n return props.searchText || \"\";\n});\n\nconst searchField = computed(() => {\n return queryBuilderProps.value?.queryDisplayField;\n});\nconst primaryIcon = computed(() => {\n const optionIcon = props.icon || \"search\";\n return exactMatch.value ? optionIcon : \"search\";\n});\n\nonMounted(() => {\n if (queryOptionText.value && currentSearchText.value) {\n const regex = new RegExp(`(${currentSearchText.value})`, \"gi\");\n queryOptionText.value.innerHTML = displayText.value.replace(regex, '<span style=\"font-weight: bold;\">$1</span>');\n }\n});\n</script>\n\n<template>\n <div>\n <div class=\"pv-flex\">\n <PvIcon :name=\"primaryIcon\"></PvIcon>\n <div>\n <p ref=\"queryOptionText\" class=\"pv-text-body-md\">{{ displayText }}</p>\n <p v-if=\"searchField\" class=\"pv-text-body-xs\">\n <span v-if=\"!exactMatch\">Search in </span>\n <span class=\"pv-text-subdued pv-text-body-xs\" style=\"font-weight: 500\">{{ searchField }}</span>\n </p>\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.pv-text-tertiary {\n color: #6e8081;\n}\n</style>\n","<script setup lang=\"ts\">\nimport {\n QueryBuilderOutput,\n QueryBuilderSuggestionMenuOption,\n QueryTerm,\n useQueryBuilder,\n} from \"@/components/base/PvQueryBuilderInput/useQueryBuilder\";\nimport PvTag from \"@/components/base/PvTag/PvTag.vue\";\nimport { computed } from \"vue\";\nimport { TagVariant } from \"@/components/base/PvTag/types\";\n\ninterface QueryFormatterProps {\n queryTermDisplayLimit?: number;\n}\n\nconst props = withDefaults(defineProps<QueryFormatterProps>(), {\n queryTermDisplayLimit: 3,\n});\n\nconst parsedQuery = defineModel<QueryBuilderOutput | null>({ required: true });\nconst wrapContent = defineModel<boolean>(\"wrap-content\", { required: false, default: false });\nconst { removeQueryOption } = useQueryBuilder();\n\nconst displayedQueryTerms = computed(() => {\n // extract filter terms from parsedQuery\n // if enableItemWrap is true, show all terms\n const terms = parsedQuery.value?.queryTerms || [];\n return wrapContent.value ? terms : terms.slice(0, props.queryTermDisplayLimit);\n});\n\nconst overflowQueryTermCount = computed(() => {\n const availableQueryTermCount = parsedQuery.value?.queryTerms.length || 0;\n const currentDisplayCount = displayedQueryTerms.value.length;\n return availableQueryTermCount - currentDisplayCount;\n});\n\nconst tagLabelForQueryTerm = (term: QueryTerm) => {\n // if exact match, don't show field\n if (term.queryField && !term.exactMatch) {\n const displayField = term.queryDisplayField || term.queryField;\n return `${displayField}: '${term.queryText}'`;\n }\n return term.queryText || \"\";\n};\n\nconst tagVariantForQueryTerm = (term: QueryTerm): TagVariant => {\n // return variant based on term type\n return term.exactMatch ? \"primary\" : \"tertiary\";\n};\n\nconst handleTagClick = (term: QueryTerm) => {\n const queryOption: QueryBuilderSuggestionMenuOption = {\n id: \"id\",\n text: term.queryText || \"\",\n queryTerm: {\n queryText: term.queryText,\n queryDisplayField: term.queryDisplayField,\n queryField: term.queryField || \"\",\n exactMatch: term.exactMatch,\n },\n };\n removeQueryOption(parsedQuery.value, queryOption);\n};\n</script>\n\n<template>\n <PvTag\n v-for=\"(queryTerm, index) in displayedQueryTerms\"\n :key=\"`${index}-${queryTerm.queryText}`\"\n :variant=\"tagVariantForQueryTerm(queryTerm)\"\n :label=\"tagLabelForQueryTerm(queryTerm)\"\n :show-clear=\"true\"\n @handle-close=\"handleTagClick(queryTerm)\"\n />\n <PvTag v-if=\"overflowQueryTermCount > 0\" :label=\"`+${overflowQueryTermCount}`\" @handle-click=\"wrapContent = true\" />\n</template>\n\n<style scoped></style>\n","<script setup lang=\"ts\">\nimport {\n QueryBuilderOutput,\n QueryBuilderSuggestionMenuOption,\n QueryTerm,\n useQueryBuilder,\n} from \"@/components/base/PvQueryBuilderInput/useQueryBuilder\";\nimport PvTag from \"@/components/base/PvTag/PvTag.vue\";\nimport { computed } from \"vue\";\nimport { TagVariant } from \"@/components/base/PvTag/types\";\n\ninterface QueryFormatterProps {\n queryTermDisplayLimit?: number;\n}\n\nconst props = withDefaults(defineProps<QueryFormatterProps>(), {\n queryTermDisplayLimit: 3,\n});\n\nconst parsedQuery = defineModel<QueryBuilderOutput | null>({ required: true });\nconst wrapContent = defineModel<boolean>(\"wrap-content\", { required: false, default: false });\nconst { removeQueryOption } = useQueryBuilder();\n\nconst displayedQueryTerms = computed(() => {\n // extract filter terms from parsedQuery\n // if enableItemWrap is true, show all terms\n const terms = parsedQuery.value?.queryTerms || [];\n return wrapContent.value ? terms : terms.slice(0, props.queryTermDisplayLimit);\n});\n\nconst overflowQueryTermCount = computed(() => {\n const availableQueryTermCount = parsedQuery.value?.queryTerms.length || 0;\n const currentDisplayCount = displayedQueryTerms.value.length;\n return availableQueryTermCount - currentDisplayCount;\n});\n\nconst tagLabelForQueryTerm = (term: QueryTerm) => {\n // if exact match, don't show field\n if (term.queryField && !term.exactMatch) {\n const displayField = term.queryDisplayField || term.queryField;\n return `${displayField}: '${term.queryText}'`;\n }\n return term.queryText || \"\";\n};\n\nconst tagVariantForQueryTerm = (term: QueryTerm): TagVariant => {\n // return variant based on term type\n return term.exactMatch ? \"primary\" : \"tertiary\";\n};\n\nconst handleTagClick = (term: QueryTerm) => {\n const queryOption: QueryBuilderSuggestionMenuOption = {\n id: \"id\",\n text: term.queryText || \"\",\n queryTerm: {\n queryText: term.queryText,\n queryDisplayField: term.queryDisplayField,\n queryField: term.queryField || \"\",\n exactMatch: term.exactMatch,\n },\n };\n removeQueryOption(parsedQuery.value, queryOption);\n};\n</script>\n\n<template>\n <PvTag\n v-for=\"(queryTerm, index) in displayedQueryTerms\"\n :key=\"`${index}-${queryTerm.queryText}`\"\n :variant=\"tagVariantForQueryTerm(queryTerm)\"\n :label=\"tagLabelForQueryTerm(queryTerm)\"\n :show-clear=\"true\"\n @handle-close=\"handleTagClick(queryTerm)\"\n />\n <PvTag v-if=\"overflowQueryTermCount > 0\" :label=\"`+${overflowQueryTermCount}`\" @handle-click=\"wrapContent = true\" />\n</template>\n\n<style scoped></style>\n","<script setup lang=\"ts\">\nimport { computed, ComputedRef, ref, useTemplateRef, watch } from \"vue\";\nimport {\n QueryBuilderOutput,\n QueryBuilderProcessor,\n QueryBuilderSuggestionMenuOption,\n QueryTerm,\n useQueryBuilder,\n} from \"@/components/base/PvQueryBuilderInput/useQueryBuilder\";\nimport PvPopover from \"@/components/base/PvPopover/PvPopover.vue\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport PvMenuItem from \"@/components/base/PvMenu/items/PvMenuItem.vue\";\nimport { vOnClickOutside } from \"@vueuse/components\";\nimport QueryBuilderMenuOptionRenderer from \"@/components/base/PvQueryBuilderInput/QueryBuilderMenuOptionRenderer.vue\";\nimport QueryFormatter from \"@/components/base/PvQueryBuilderInput/QueryFormatter.vue\";\nimport type { MenuOption } from \"@/types\";\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport PvSpinner from \"@/components/base/PvSpinner/PvSpinner.vue\";\nimport { onKeyStroke } from \"@vueuse/core\";\n\nexport interface PvQueryBuilderInputProps {\n /**\n * Placeholder text shown in the input when no query is active.\n */\n placeholder?: string;\n /**\n * When true, the input is non-interactive and visually dimmed.\n */\n disabled?: boolean;\n /** When true, displays a keyboard shortcut badge next to the input. */\n displayShortcut?: boolean;\n /**\n * Determines how user input is parsed into structured query terms.\n * - `'full'`: free-text and field-based queries.\n * - `'field-only'`: only options with a queryField are shown.\n */\n processor?: QueryBuilderProcessor;\n /**\n * When true, shows a loading spinner in the suggestion dropdown.\n */\n optionsLoading?: boolean;\n /**\n * When true, users can press Enter to add free-text terms without selecting a suggestion.\n */\n enableCustomOptionsInput?: boolean;\n /**\n * When true, hides the search icon on the left side of the input.\n */\n hideSearchIcon?: boolean;\n /**\n * When true, hides the clear button that resets the query.\n */\n hideClearButton?: boolean;\n /**\n * Maximum number of query term pills to display before collapsing.\n */\n queryTermDisplayLimit?: number;\n /**\n * When true, query term pills wrap to the next line instead of scrolling horizontally.\n */\n enableWrapQueryTerms?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvQueryBuilderInputProps>(), {\n placeholder: \"Search\",\n disabled: false,\n processor: \"full\",\n optionsLoading: false,\n enableCustomOptionsInput: false,\n hideSearchIcon: false,\n hideClearButton: false,\n queryTermDisplayLimit: 3,\n enableWrapQueryTerms: false,\n});\n\nconst menuOptionConfig = {\n renderer: QueryBuilderMenuOptionRenderer,\n};\n\n// const wrapper = useTemplateRef<HTMLDivElement | null>(\"query-builder-input\");\nconst input = useTemplateRef<HTMLInputElement | null>(\"search-input\");\nconst inputText = defineModel<string>(\"searchText\", { required: false, default: \"\" });\nconst parsedQuery = defineModel<QueryBuilderOutput | null>(\"query\", { required: true });\nconst queryOptions = defineModel<QueryBuilderSuggestionMenuOption[]>(\"options\", {\n required: false,\n});\nconst { addQueryOption, containsQueryOption } = useQueryBuilder();\nconst displayOptions = ref(false);\nconst isCurrentInputFocused = ref(false);\nconst wrapContent = ref(false);\n\nconst computedPlaceholder = computed(() => {\n return parsedQuery.value !== null ? \"\" : props.placeholder;\n});\n\nconst invalidQueryReason = ref<string | null>(null);\nconst displayInvalidQuery = computed(() => {\n return invalidQueryReason.value !== null && invalidQueryReason.value !== \"\" && !isCurrentInputFocused.value;\n});\n\nconst clearQuery = () => {\n parsedQuery.value = null;\n inputText.value = \"\";\n invalidQueryReason.value = null;\n wrapContent.value = false;\n};\n\nif (props.enableCustomOptionsInput) {\n onKeyStroke(\n \"Enter\",\n () => {\n if (inputText.value.trim()) {\n handleAddSelfAddedOption();\n }\n },\n { target: input },\n );\n}\n\nconst handleAddSelfAddedOption = () => {\n if (inputText.value.trim()) {\n parsedQuery.value = addQueryOption(parsedQuery.value, {\n id: inputText.value.trim(),\n text: inputText.value,\n queryTerm: {\n queryText: inputText.value,\n },\n });\n clearInputText();\n }\n};\n\nconst availableOptions: ComputedRef<MenuOption<QueryTerm>[]> = computed(() => {\n if (!queryOptions.value || queryOptions.value.length === 0) {\n return [];\n }\n let filteredOptions = queryOptions.value;\n // if the processor is field-only, filter out options without a queryField\n if (props.processor === \"field-only\") {\n filteredOptions = queryOptions.value.filter((option) => option.queryTerm?.queryField);\n }\n // filter out options that are already present in the current query\n if (parsedQuery.value) {\n filteredOptions = filteredOptions.filter((option) => !containsQueryOption(parsedQuery.value, option));\n }\n // append the input text to the option text for highlighting in the menu item\n return filteredOptions.map((option) => {\n const menuOption: MenuOption<QueryTerm> = {\n id: option.id,\n text: option.text,\n icon: option.icon,\n disabled: option.disabled,\n searchText: inputText.value,\n context: option.queryTerm,\n };\n return menuOption;\n });\n});\n\n// Watch for changes in available options, input text, or loading state to ensure menu is displayed when typing.\nwatch(\n [availableOptions, inputText, () => props.optionsLoading],\n ([newOptions, newInputText, isLoading]) => {\n // If user is typing and there are options to show OR loading, display the menu\n if (newInputText && newInputText.length > 0 && (newOptions.length > 0 || isLoading)) {\n displayOptions.value = true;\n } else if (!newInputText || newInputText.length === 0) {\n // Clear the menu if no input text\n displayOptions.value = false;\n }\n },\n { immediate: true },\n);\n\nconst handleClickOutside = () => {\n if (props.enableCustomOptionsInput) {\n handleAddSelfAddedOption();\n }\n\n displayOptions.value = false;\n isCurrentInputFocused.value = false;\n wrapContent.value = false;\n};\n\nconst handleOptionSelected = (option: MenuOption<QueryTerm>) => {\n try {\n const queryOption: QueryBuilderSuggestionMenuOption = {\n id: option.id,\n text: option.text,\n queryTerm: option.context,\n icon: option.icon,\n };\n parsedQuery.value = addQueryOption(parsedQuery.value, queryOption);\n //clear input text after adding option\n clearInputText();\n } catch (error) {\n console.error(\"Error adding query option:\", error);\n } finally {\n displayOptions.value = false;\n isCurrentInputFocused.value = false;\n }\n};\n\nfunction handleWrapperClick(event: MouseEvent) {\n const target = event.target as HTMLElement;\n\n // Don't interfere if clicking on a contenteditable element (QueryTerm)\n if (target.isContentEditable || target.closest('[contenteditable=\"true\"]')) {\n return;\n }\n\n // Don't interfere if clicking on buttons or other interactive elements\n if (target.tagName === \"BUTTON\" || target.tagName === \"SVG\" || target.closest(\"button\")) {\n return;\n }\n\n // Focus the main input for everything else\n input.value?.focus();\n}\n\nfunction checkWrapperFocus(event: FocusEvent) {\n if (event.type === \"focus\") {\n isCurrentInputFocused.value = true;\n displayOptions.value = true;\n } else if (event.type === \"blur\") {\n // Use setTimeout to allow other focus events to fire first\n // setTimeout(() => {\n // // Check if any element inside the wrapper is currently focused\n // const wrapperEl = wrapper.value;\n // const activeElement = document.activeElement;\n // if (!wrapperEl || !wrapperEl.contains(activeElement)) {\n // isCurrentInputFocused.value = false;\n // displayOptions.value = false;\n // }\n // }, 100);\n }\n}\n\nconst clearInputText = () => {\n inputText.value = \"\";\n};\n</script>\n\n<template>\n <div\n ref=\"query-builder-input\"\n class=\"pv-relative pv-query-builder-input-wrapper\"\n @focus=\"checkWrapperFocus\"\n @click=\"handleWrapperClick\"\n v-on-click-outside=\"handleClickOutside\"\n >\n <PvIcon v-if=\"!hideSearchIcon\" name=\"search\" />\n <div\n class=\"pv-flex pv-full-width pv-inset-inline pv-query-builder-input\"\n style=\"--inset-size: 4px; --flex-gap: 4px\"\n :style=\"enableWrapQueryTerms || wrapContent ? 'flex-wrap: wrap;' : 'flex-wrap: nowrap;'\"\n >\n <QueryFormatter\n v-model=\"parsedQuery\"\n v-model:wrap-content=\"wrapContent\"\n :query-term-display-limit=\"queryTermDisplayLimit\"\n ></QueryFormatter>\n <input\n v-model=\"inputText\"\n ref=\"search-input\"\n data-testid=\"pv-search-input\"\n type=\"text\"\n :disabled=\"disabled\"\n :placeholder=\"computedPlaceholder\"\n :data-invalid=\"displayInvalidQuery ? 'true' : undefined\"\n @focus=\"checkWrapperFocus\"\n @blur=\"checkWrapperFocus\"\n />\n </div>\n <PvButton v-if=\"parsedQuery && !hideClearButton\" variant=\"ghost\" leftIcon=\"close\" size=\"md\" @click=\"clearQuery\" />\n <p v-if=\"displayInvalidQuery\" class=\"pv-text-red pv-text-body-xs\">\n {{ invalidQueryReason }}\n </p>\n <PvPopover\n v-if=\"availableOptions.length > 0 || optionsLoading\"\n :class=\"{ 'pv-hide': !displayOptions }\"\n :css-custom-properties=\"{ width: '100%', maxWidth: '100%' }\"\n :isList=\"true\"\n >\n <template v-if=\"!optionsLoading\">\n <template v-for=\"(option, index) in availableOptions\" :key=\"`${index}-${option.searchText}`\">\n <PvMenuItem v-bind=\"option\" @handleSelected=\"handleOptionSelected(option)\" :config=\"menuOptionConfig\" />\n </template>\n </template>\n <template v-else>\n <div class=\"pv-text-center\">\n <PvSpinner variant=\"dark\" />\n </div>\n </template>\n </PvPopover>\n </div>\n</template>\n\n<style scoped>\n.pv-query-builder-input-wrapper {\n display: flex;\n align-items: center;\n position: relative;\n width: 100%;\n background: rgb(247, 248, 248);\n padding: 0.25rem;\n border-radius: 0.5rem;\n border: 2px solid transparent;\n font-size: 0.75rem;\n min-height: 2.25rem;\n cursor: text;\n}\n\n.pv-query-builder-input {\n justify-content: start;\n overflow-x: hidden;\n}\n\n.pv-query-builder-input-wrapper input {\n border: none;\n background: transparent;\n outline: none;\n font-size: 0.75rem;\n}\n\n.pv-query-builder-input-wrapper:focus-within {\n border: 2px solid #36c5ba;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ComputedRef, ref, useTemplateRef, watch } from \"vue\";\nimport {\n QueryBuilderOutput,\n QueryBuilderProcessor,\n QueryBuilderSuggestionMenuOption,\n QueryTerm,\n useQueryBuilder,\n} from \"@/components/base/PvQueryBuilderInput/useQueryBuilder\";\nimport PvPopover from \"@/components/base/PvPopover/PvPopover.vue\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport PvMenuItem from \"@/components/base/PvMenu/items/PvMenuItem.vue\";\nimport { vOnClickOutside } from \"@vueuse/components\";\nimport QueryBuilderMenuOptionRenderer from \"@/components/base/PvQueryBuilderInput/QueryBuilderMenuOptionRenderer.vue\";\nimport QueryFormatter from \"@/components/base/PvQueryBuilderInput/QueryFormatter.vue\";\nimport type { MenuOption } from \"@/types\";\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport PvSpinner from \"@/components/base/PvSpinner/PvSpinner.vue\";\nimport { onKeyStroke } from \"@vueuse/core\";\n\nexport interface PvQueryBuilderInputProps {\n /**\n * Placeholder text shown in the input when no query is active.\n */\n placeholder?: string;\n /**\n * When true, the input is non-interactive and visually dimmed.\n */\n disabled?: boolean;\n /** When true, displays a keyboard shortcut badge next to the input. */\n displayShortcut?: boolean;\n /**\n * Determines how user input is parsed into structured query terms.\n * - `'full'`: free-text and field-based queries.\n * - `'field-only'`: only options with a queryField are shown.\n */\n processor?: QueryBuilderProcessor;\n /**\n * When true, shows a loading spinner in the suggestion dropdown.\n */\n optionsLoading?: boolean;\n /**\n * When true, users can press Enter to add free-text terms without selecting a suggestion.\n */\n enableCustomOptionsInput?: boolean;\n /**\n * When true, hides the search icon on the left side of the input.\n */\n hideSearchIcon?: boolean;\n /**\n * When true, hides the clear button that resets the query.\n */\n hideClearButton?: boolean;\n /**\n * Maximum number of query term pills to display before collapsing.\n */\n queryTermDisplayLimit?: number;\n /**\n * When true, query term pills wrap to the next line instead of scrolling horizontally.\n */\n enableWrapQueryTerms?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvQueryBuilderInputProps>(), {\n placeholder: \"Search\",\n disabled: false,\n processor: \"full\",\n optionsLoading: false,\n enableCustomOptionsInput: false,\n hideSearchIcon: false,\n hideClearButton: false,\n queryTermDisplayLimit: 3,\n enableWrapQueryTerms: false,\n});\n\nconst menuOptionConfig = {\n renderer: QueryBuilderMenuOptionRenderer,\n};\n\n// const wrapper = useTemplateRef<HTMLDivElement | null>(\"query-builder-input\");\nconst input = useTemplateRef<HTMLInputElement | null>(\"search-input\");\nconst inputText = defineModel<string>(\"searchText\", { required: false, default: \"\" });\nconst parsedQuery = defineModel<QueryBuilderOutput | null>(\"query\", { required: true });\nconst queryOptions = defineModel<QueryBuilderSuggestionMenuOption[]>(\"options\", {\n required: false,\n});\nconst { addQueryOption, containsQueryOption } = useQueryBuilder();\nconst displayOptions = ref(false);\nconst isCurrentInputFocused = ref(false);\nconst wrapContent = ref(false);\n\nconst computedPlaceholder = computed(() => {\n return parsedQuery.value !== null ? \"\" : props.placeholder;\n});\n\nconst invalidQueryReason = ref<string | null>(null);\nconst displayInvalidQuery = computed(() => {\n return invalidQueryReason.value !== null && invalidQueryReason.value !== \"\" && !isCurrentInputFocused.value;\n});\n\nconst clearQuery = () => {\n parsedQuery.value = null;\n inputText.value = \"\";\n invalidQueryReason.value = null;\n wrapContent.value = false;\n};\n\nif (props.enableCustomOptionsInput) {\n onKeyStroke(\n \"Enter\",\n () => {\n if (inputText.value.trim()) {\n handleAddSelfAddedOption();\n }\n },\n { target: input },\n );\n}\n\nconst handleAddSelfAddedOption = () => {\n if (inputText.value.trim()) {\n parsedQuery.value = addQueryOption(parsedQuery.value, {\n id: inputText.value.trim(),\n text: inputText.value,\n queryTerm: {\n queryText: inputText.value,\n },\n });\n clearInputText();\n }\n};\n\nconst availableOptions: ComputedRef<MenuOption<QueryTerm>[]> = computed(() => {\n if (!queryOptions.value || queryOptions.value.length === 0) {\n return [];\n }\n let filteredOptions = queryOptions.value;\n // if the processor is field-only, filter out options without a queryField\n if (props.processor === \"field-only\") {\n filteredOptions = queryOptions.value.filter((option) => option.queryTerm?.queryField);\n }\n // filter out options that are already present in the current query\n if (parsedQuery.value) {\n filteredOptions = filteredOptions.filter((option) => !containsQueryOption(parsedQuery.value, option));\n }\n // append the input text to the option text for highlighting in the menu item\n return filteredOptions.map((option) => {\n const menuOption: MenuOption<QueryTerm> = {\n id: option.id,\n text: option.text,\n icon: option.icon,\n disabled: option.disabled,\n searchText: inputText.value,\n context: option.queryTerm,\n };\n return menuOption;\n });\n});\n\n// Watch for changes in available options, input text, or loading state to ensure menu is displayed when typing.\nwatch(\n [availableOptions, inputText, () => props.optionsLoading],\n ([newOptions, newInputText, isLoading]) => {\n // If user is typing and there are options to show OR loading, display the menu\n if (newInputText && newInputText.length > 0 && (newOptions.length > 0 || isLoading)) {\n displayOptions.value = true;\n } else if (!newInputText || newInputText.length === 0) {\n // Clear the menu if no input text\n displayOptions.value = false;\n }\n },\n { immediate: true },\n);\n\nconst handleClickOutside = () => {\n if (props.enableCustomOptionsInput) {\n handleAddSelfAddedOption();\n }\n\n displayOptions.value = false;\n isCurrentInputFocused.value = false;\n wrapContent.value = false;\n};\n\nconst handleOptionSelected = (option: MenuOption<QueryTerm>) => {\n try {\n const queryOption: QueryBuilderSuggestionMenuOption = {\n id: option.id,\n text: option.text,\n queryTerm: option.context,\n icon: option.icon,\n };\n parsedQuery.value = addQueryOption(parsedQuery.value, queryOption);\n //clear input text after adding option\n clearInputText();\n } catch (error) {\n console.error(\"Error adding query option:\", error);\n } finally {\n displayOptions.value = false;\n isCurrentInputFocused.value = false;\n }\n};\n\nfunction handleWrapperClick(event: MouseEvent) {\n const target = event.target as HTMLElement;\n\n // Don't interfere if clicking on a contenteditable element (QueryTerm)\n if (target.isContentEditable || target.closest('[contenteditable=\"true\"]')) {\n return;\n }\n\n // Don't interfere if clicking on buttons or other interactive elements\n if (target.tagName === \"BUTTON\" || target.tagName === \"SVG\" || target.closest(\"button\")) {\n return;\n }\n\n // Focus the main input for everything else\n input.value?.focus();\n}\n\nfunction checkWrapperFocus(event: FocusEvent) {\n if (event.type === \"focus\") {\n isCurrentInputFocused.value = true;\n displayOptions.value = true;\n } else if (event.type === \"blur\") {\n // Use setTimeout to allow other focus events to fire first\n // setTimeout(() => {\n // // Check if any element inside the wrapper is currently focused\n // const wrapperEl = wrapper.value;\n // const activeElement = document.activeElement;\n // if (!wrapperEl || !wrapperEl.contains(activeElement)) {\n // isCurrentInputFocused.value = false;\n // displayOptions.value = false;\n // }\n // }, 100);\n }\n}\n\nconst clearInputText = () => {\n inputText.value = \"\";\n};\n</script>\n\n<template>\n <div\n ref=\"query-builder-input\"\n class=\"pv-relative pv-query-builder-input-wrapper\"\n @focus=\"checkWrapperFocus\"\n @click=\"handleWrapperClick\"\n v-on-click-outside=\"handleClickOutside\"\n >\n <PvIcon v-if=\"!hideSearchIcon\" name=\"search\" />\n <div\n class=\"pv-flex pv-full-width pv-inset-inline pv-query-builder-input\"\n style=\"--inset-size: 4px; --flex-gap: 4px\"\n :style=\"enableWrapQueryTerms || wrapContent ? 'flex-wrap: wrap;' : 'flex-wrap: nowrap;'\"\n >\n <QueryFormatter\n v-model=\"parsedQuery\"\n v-model:wrap-content=\"wrapContent\"\n :query-term-display-limit=\"queryTermDisplayLimit\"\n ></QueryFormatter>\n <input\n v-model=\"inputText\"\n ref=\"search-input\"\n data-testid=\"pv-search-input\"\n type=\"text\"\n :disabled=\"disabled\"\n :placeholder=\"computedPlaceholder\"\n :data-invalid=\"displayInvalidQuery ? 'true' : undefined\"\n @focus=\"checkWrapperFocus\"\n @blur=\"checkWrapperFocus\"\n />\n </div>\n <PvButton v-if=\"parsedQuery && !hideClearButton\" variant=\"ghost\" leftIcon=\"close\" size=\"md\" @click=\"clearQuery\" />\n <p v-if=\"displayInvalidQuery\" class=\"pv-text-red pv-text-body-xs\">\n {{ invalidQueryReason }}\n </p>\n <PvPopover\n v-if=\"availableOptions.length > 0 || optionsLoading\"\n :class=\"{ 'pv-hide': !displayOptions }\"\n :css-custom-properties=\"{ width: '100%', maxWidth: '100%' }\"\n :isList=\"true\"\n >\n <template v-if=\"!optionsLoading\">\n <template v-for=\"(option, index) in availableOptions\" :key=\"`${index}-${option.searchText}`\">\n <PvMenuItem v-bind=\"option\" @handleSelected=\"handleOptionSelected(option)\" :config=\"menuOptionConfig\" />\n </template>\n </template>\n <template v-else>\n <div class=\"pv-text-center\">\n <PvSpinner variant=\"dark\" />\n </div>\n </template>\n </PvPopover>\n </div>\n</template>\n\n<style scoped>\n.pv-query-builder-input-wrapper {\n display: flex;\n align-items: center;\n position: relative;\n width: 100%;\n background: rgb(247, 248, 248);\n padding: 0.25rem;\n border-radius: 0.5rem;\n border: 2px solid transparent;\n font-size: 0.75rem;\n min-height: 2.25rem;\n cursor: text;\n}\n\n.pv-query-builder-input {\n justify-content: start;\n overflow-x: hidden;\n}\n\n.pv-query-builder-input-wrapper input {\n border: none;\n background: transparent;\n outline: none;\n font-size: 0.75rem;\n}\n\n.pv-query-builder-input-wrapper:focus-within {\n border: 2px solid #36c5ba;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, useId } from \"vue\";\n\nconst range = defineModel<number>({ required: true });\n\nwithDefaults(\n defineProps<{\n /** Minimum value of the range slider */\n min?: number;\n /** Maximum value of the range slider */\n max?: number;\n /** Step increment between values */\n step?: number;\n /** Accessible name for the range slider */\n ariaLabel?: string;\n }>(),\n {\n min: 0,\n max: 100,\n step: 1,\n },\n);\n\nconst id = useId();\n\nconst rangeStyle = computed(() => {\n return {\n \"--value\": `${range.value}%`,\n };\n});\n</script>\n\n<template>\n <input\n v-model.number=\"range\"\n class=\"pv-range\"\n type=\"range\"\n :id=\"id\"\n :aria-label=\"ariaLabel\"\n :min=\"min\"\n :max=\"max\"\n :step=\"step\"\n :style=\"rangeStyle\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useId } from \"vue\";\n\nconst range = defineModel<number>({ required: true });\n\nwithDefaults(\n defineProps<{\n /** Minimum value of the range slider */\n min?: number;\n /** Maximum value of the range slider */\n max?: number;\n /** Step increment between values */\n step?: number;\n /** Accessible name for the range slider */\n ariaLabel?: string;\n }>(),\n {\n min: 0,\n max: 100,\n step: 1,\n },\n);\n\nconst id = useId();\n\nconst rangeStyle = computed(() => {\n return {\n \"--value\": `${range.value}%`,\n };\n});\n</script>\n\n<template>\n <input\n v-model.number=\"range\"\n class=\"pv-range\"\n type=\"range\"\n :id=\"id\"\n :aria-label=\"ariaLabel\"\n :min=\"min\"\n :max=\"max\"\n :step=\"step\"\n :style=\"rangeStyle\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport type { PvTableOfContentsItem } from \"./types\";\n\ninterface PvTableOfContentsProps {\n /** Items to display in the table of contents */\n items: PvTableOfContentsItem[];\n}\n\ndefineProps<PvTableOfContentsProps>();\n\nconst modelValue = defineModel<string>({ required: false });\nconst emit = defineEmits<{\n (e: \"handle-select\", item: PvTableOfContentsItem): void;\n}>();\n\nconst handleSelect = (event: MouseEvent, item: PvTableOfContentsItem) => {\n if (!item.href) {\n event.preventDefault();\n }\n modelValue.value = item.id;\n emit(\"handle-select\", item);\n};\n</script>\n\n<template>\n <ul class=\"pv-toc\" role=\"list\" style=\"min-width: 160px\">\n <li v-for=\"item in items\" :key=\"item.id\" :aria-current=\"modelValue === item.id ? 'true' : undefined\">\n <a :href=\"item.href ?? '#'\" @click=\"handleSelect($event, item)\">\n <PvIcon v-if=\"item.icon\" :name=\"item.icon\" />\n {{ item.label }}\n </a>\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport type { PvTableOfContentsItem } from \"./types\";\n\ninterface PvTableOfContentsProps {\n /** Items to display in the table of contents */\n items: PvTableOfContentsItem[];\n}\n\ndefineProps<PvTableOfContentsProps>();\n\nconst modelValue = defineModel<string>({ required: false });\nconst emit = defineEmits<{\n (e: \"handle-select\", item: PvTableOfContentsItem): void;\n}>();\n\nconst handleSelect = (event: MouseEvent, item: PvTableOfContentsItem) => {\n if (!item.href) {\n event.preventDefault();\n }\n modelValue.value = item.id;\n emit(\"handle-select\", item);\n};\n</script>\n\n<template>\n <ul class=\"pv-toc\" role=\"list\" style=\"min-width: 160px\">\n <li v-for=\"item in items\" :key=\"item.id\" :aria-current=\"modelValue === item.id ? 'true' : undefined\">\n <a :href=\"item.href ?? '#'\" @click=\"handleSelect($event, item)\">\n <PvIcon v-if=\"item.icon\" :name=\"item.icon\" />\n {{ item.label }}\n </a>\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\">\ninterface StepperProps {\n count?: number;\n active?: number;\n clickable?: boolean;\n}\n\ndefineEmits<{\n (e: \"update:active\", index: number): void;\n}>();\n\nconst props = withDefaults(defineProps<StepperProps>(), {\n count: 5,\n active: 0,\n clickable: false,\n});\n\nif (props.active < 0 || props.active >= props.count) {\n console.warn(`PvStepper: \"active\" (${props.active}) is out of range for \"count\" (${props.count}).`);\n}\n</script>\n\n<template>\n <div class=\"pv-flex\">\n <div\n v-for=\"(_, index) in count\"\n :key=\"index\"\n :data-clickable=\"clickable\"\n :class=\"index === active ? 'pv-stepper-active' : 'pv-stepper-inactive'\"\n @click=\"clickable && $emit('update:active', index)\"\n ></div>\n </div>\n</template>\n","<script setup lang=\"ts\">\ninterface StepperProps {\n count?: number;\n active?: number;\n clickable?: boolean;\n}\n\ndefineEmits<{\n (e: \"update:active\", index: number): void;\n}>();\n\nconst props = withDefaults(defineProps<StepperProps>(), {\n count: 5,\n active: 0,\n clickable: false,\n});\n\nif (props.active < 0 || props.active >= props.count) {\n console.warn(`PvStepper: \"active\" (${props.active}) is out of range for \"count\" (${props.count}).`);\n}\n</script>\n\n<template>\n <div class=\"pv-flex\">\n <div\n v-for=\"(_, index) in count\"\n :key=\"index\"\n :data-clickable=\"clickable\"\n :class=\"index === active ? 'pv-stepper-active' : 'pv-stepper-inactive'\"\n @click=\"clickable && $emit('update:active', index)\"\n ></div>\n </div>\n</template>\n","import Aura from \"@primeuix/themes/aura\";\n\nexport const PvComponentsConfig = {\n theme: {\n preset: Aura,\n options: {\n darkModeSelector: false || \"none\",\n cssLayer: {\n name: \"primevue\",\n order: \"pit-viper-v2, primevue\",\n },\n },\n },\n};\n","import { PrimeVue } from \"@primevue/core\";\nimport { App } from \"vue\";\nimport { PvComponentsConfig } from \"./primeVue.config.ts\";\n\nexport const usePvComponents = (app: App<Element>) => {\n app.use(PrimeVue, PvComponentsConfig);\n};\n"],"x_google_ignoreList":[30,31,32,33,34,35],"mappings":"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"}
1
+ {"version":3,"file":"pv-components-base.mjs","names":["$props","$emit","$emit","$emit","computePosition","flip","offset","getComputedStyle","unwrapElement","$slots","$props","$slots","$slots","$emit","$emit","$emit","$slots","$emit","$emit","$props","$slots","$emit","$slots","$emit","$emit","$slots","$attrs","$emit","$emit","$emit","$emit"],"sources":["../../../src/components/base/PvSpinner/PvSpinner.vue","../../../src/components/base/PvSpinner/PvSpinner.vue","../../../src/components/base/PvButton/helpers.ts","../../../src/web-components/utils.ts","../../../src/components/base/baseProps.ts","../../../src/components/base/PvIcon/PvIcon.vue","../../../src/components/base/PvIcon/PvIcon.vue","../../../src/components/base/PvCounterBadge/PvCounterBadge.vue","../../../src/components/base/PvCounterBadge/PvCounterBadge.vue","../../../src/components/base/PvButton/PvButton.vue","../../../src/components/base/PvButton/PvButton.vue","../../../src/components/base/PvAiButton/PvAiButton.vue","../../../src/components/base/PvAiButton/PvAiButton.vue","../../../src/composables/useSlotPresence.ts","../../../src/components/base/PvTooltip/PvTooltip.vue","../../../src/components/base/PvTooltip/PvTooltip.vue","../../../src/components/base/PvButton/PvButtonWithTooltip.vue","../../../src/components/base/PvButton/PvButtonWithTooltip.vue","../../../src/components/base/PvReleaseBadge/PvReleaseBadge.vue","../../../src/components/base/PvReleaseBadge/PvReleaseBadge.vue","../../../src/components/base/PvTag/PvTag.vue","../../../src/components/base/PvTag/PvTag.vue","../../../src/components/base/PvPill/PvPill.vue","../../../src/components/base/PvPill/PvPill.vue","../../../src/components/base/PvPopover/PvPopover.vue","../../../src/components/base/PvPopover/PvPopover.vue","../../../src/components/base/PvDropdown/PvDropdown.vue","../../../src/components/base/PvDropdown/PvDropdown.vue","../../../src/components/base/PvPopoverMenu/PvPopoverMenu.vue","../../../src/components/base/PvPopoverMenu/PvPopoverMenu.vue","../../../../node_modules/.pnpm/@floating-ui+utils@0.2.11/node_modules/@floating-ui/utils/dist/floating-ui.utils.mjs","../../../../node_modules/.pnpm/@floating-ui+core@1.7.5/node_modules/@floating-ui/core/dist/floating-ui.core.mjs","../../../../node_modules/.pnpm/@floating-ui+utils@0.2.11/node_modules/@floating-ui/utils/dist/floating-ui.utils.dom.mjs","../../../../node_modules/.pnpm/@floating-ui+dom@1.7.6/node_modules/@floating-ui/dom/dist/floating-ui.dom.mjs","../../../../node_modules/.pnpm/vue-demi@0.14.10_vue@3.5.32_typescript@5.9.3_/node_modules/vue-demi/lib/index.mjs","../../../../node_modules/.pnpm/@floating-ui+vue@1.1.11_vue@3.5.32_typescript@5.9.3_/node_modules/@floating-ui/vue/dist/floating-ui.vue.mjs","../../../src/components/base/PvPopoverV2/PvPopoverV2.vue","../../../src/components/base/PvPopoverV2/PvPopoverV2.vue","../../../src/components/base/PvTooltipV2/PvTooltipV2.vue","../../../src/components/base/PvTooltipV2/PvTooltipV2.vue","../../../src/components/base/PvSegmentedControl/PvSegmentedControl.vue","../../../src/components/base/PvSegmentedControl/PvSegmentedControl.vue","../../../src/components/base/PvTabList/PvTabList.vue","../../../src/components/base/PvTabList/PvTabList.vue","../../../src/components/base/PvCompanyLogo/PvCompanyLogo.vue","../../../src/components/base/PvCompanyLogo/PvCompanyLogo.vue","../../../src/components/base/PvModal/PvModal.vue","../../../src/components/base/PvModal/PvModal.vue","../../../src/components/base/PvBanner/types.ts","../../../src/components/base/PvBanner/PvBanner.vue","../../../src/components/base/PvBanner/PvBanner.vue","../../../src/components/base/PvCompanyTag/PvCompanyTag.vue","../../../src/components/base/PvCompanyTag/PvCompanyTag.vue","../../../src/components/base/PvSuggestionTag/PvSuggestionTag.vue","../../../src/components/base/PvSuggestionTag/PvSuggestionTag.vue","../../../src/components/base/PvAccordion/PvAccordion.vue","../../../src/components/base/PvAccordion/PvAccordion.vue","../../../src/components/base/PvSearchInput/PvSearchInput.vue","../../../src/components/base/PvSearchInput/PvSearchInput.vue","../../../src/components/base/PvDatePicker/PvDatePicker.vue","../../../src/components/base/PvDatePicker/PvDatePicker.vue","../../../src/components/base/PvDateTime/useDateTime.ts","../../../src/components/base/PvDateTime/PvDateTime.vue","../../../src/components/base/PvDateTime/PvDateTime.vue","../../../src/components/base/PvDrawer/PvDrawer.vue","../../../src/components/base/PvDrawer/PvDrawer.vue","../../../src/components/base/PvTabs/PvTabs.vue","../../../src/components/base/PvTabs/PvTabs.vue","../../../src/components/base/PvBreadcrumbs/PvBreadcrumbs.vue","../../../src/components/base/PvBreadcrumbs/PvBreadcrumbs.vue","../../../src/components/base/PvMenu/PvMenuControlPanel.vue","../../../src/components/base/PvMenu/PvMenuControlPanel.vue","../../../src/components/base/PvAvatar/PvAvatar.vue","../../../src/components/base/PvAvatar/PvAvatar.vue","../../../src/components/base/PvSelectButton/PvSelectButtonTrigger/PvSelectButtonTrigger.vue","../../../src/components/base/PvSelectButton/PvSelectButtonTrigger/PvSelectButtonTrigger.vue","../../../src/components/base/PvMenu/PvMenuEmptyState.vue","../../../src/components/base/PvMenu/cascadeUtils.ts","../../../src/components/base/PvMenu/items/PvMenuBaseItem.vue","../../../src/components/base/PvMenu/items/PvMenuBaseItem.vue","../../../src/components/base/PvSwitch/PvSwitch.vue","../../../src/components/base/PvSwitch/PvSwitch.vue","../../../src/components/base/PvMenu/items/PvMenuItemAction.vue","../../../src/components/base/PvMenu/items/PvMenuItemAction.vue","../../../src/components/base/PvMenu/symbols.ts","../../../src/components/base/PvMenu/items/PvMenuItemVariant.vue","../../../src/components/base/PvMenu/items/PvMenuItemVariant.vue","../../../src/components/base/PvMenu/items/PvMenuItem.vue","../../../src/components/base/PvMenu/items/PvMenuItem.vue","../../../src/components/base/PvMenu/PvMenu.vue","../../../src/components/base/PvMenu/PvMenu.vue","../../../src/components/base/PvMultiSelectButton/PvMultiSelectButton.vue","../../../src/components/base/PvMultiSelectButton/PvMultiSelectButton.vue","../../../src/components/base/PvSelectButton/PvSelectButton.vue","../../../src/components/base/PvSelectButton/PvSelectButton.vue","../../../src/components/base/PvPagination/usePagination.ts","../../../src/components/base/PvPagination/PvPagination.vue","../../../src/components/base/PvPagination/PvPagination.vue","../../../src/components/base/PvSelectableCard/PvSelectableCard.vue","../../../src/components/base/PvSelectableCard/PvSelectableCard.vue","../../../src/components/layout/PvSidePanel/PvSidePanel.vue","../../../src/components/layout/PvSidePanel/PvSidePanel.vue","../../../src/components/base/PvGhostInput/PvGhostInput.vue","../../../src/components/base/PvGhostInput/PvGhostInput.vue","../../../src/components/base/PvHeader/PvHeader.vue","../../../src/components/base/PvHeader/PvHeader.vue","../../../src/components/base/PvCompanyLabel/PvCompanyLabel.vue","../../../src/components/base/PvCompanyLabel/PvCompanyLabel.vue","../../../src/components/base/PvAvatarGroup/PvAvatarGroup.vue","../../../src/components/base/PvAvatarGroup/PvAvatarGroup.vue","../../../src/components/base/PvToggleButton/PvToggleButton.vue","../../../src/components/base/PvToggleButton/PvToggleButton.vue","../../../src/components/base/PvToggleGroup/PvToggleGroup.vue","../../../src/components/base/PvToggleGroup/PvToggleGroup.vue","../../../src/components/base/PvCheckbox/PvCheckbox.vue","../../../src/components/base/PvCheckbox/PvCheckbox.vue","../../../src/components/base/PvRadioGroup/PvRadioGroup.vue","../../../src/components/base/PvRadioGroup/PvRadioGroup.vue","../../../src/components/base/PvSprite/PvSprite.vue","../../../src/components/base/PvSprite/PvSprite.vue","../../../src/components/base/PvSkeleton/PvSkeleton.vue","../../../src/components/base/PvSkeleton/PvSkeleton.vue","../../../src/components/base/PvInput/PvInput.vue","../../../src/components/base/PvInput/PvInput.vue","../../../src/components/base/PvRating/PvRating.vue","../../../src/components/base/PvRating/PvRating.vue","../../../src/components/base/PvCard/PvCard.vue","../../../src/components/base/PvCard/PvCard.vue","../../../src/components/base/PvWidget/PvWidget.vue","../../../src/components/base/PvWidget/PvWidget.vue","../../../src/components/base/PvInsightCard/PvInsightCard.vue","../../../src/components/base/PvInsightCard/PvInsightCard.vue","../../../src/components/base/PvExpandableContent/PvExpandableContent.vue","../../../src/components/base/PvExpandableContent/PvExpandableContent.vue","../../../src/components/base/PvToast/PvToast.vue","../../../src/components/base/PvToast/PvToast.vue","../../../src/components/base/PvActionBar/PvActionBar.vue","../../../src/components/base/PvActionBar/PvActionBar.vue","../../../src/components/base/PvTextArea/PvTextArea.vue","../../../src/components/base/PvTextArea/PvTextArea.vue","../../../src/components/base/PvTree/PvSimpleItemTree.vue","../../../src/components/base/PvTree/PvSimpleItemTree.vue","../../../src/components/base/PvTree/PvTreeReorderIcon.vue","../../../src/components/base/PvTree/PvTreeReorderIcon.vue","../../../src/components/base/PvTree/PvButtonTreeItem.vue","../../../src/components/base/PvTree/PvButtonTreeItem.vue","../../../src/components/base/PvTree/PvCheckboxTreeItem.vue","../../../src/components/base/PvTree/PvCheckboxTreeItem.vue","../../../src/components/base/PvTree/composables/useHoverIcon.ts","../../../src/components/base/PvTree/symbols.ts","../../../src/components/base/PvTree/composables/useDraggingState.ts","../../../src/components/base/PvTree/composables/useDragAndDrop.ts","../../../src/components/base/PvTree/composables/useDragAndDropIndicator.ts","../../../src/components/base/PvTree/PvSimpleNestedTreeItem.vue","../../../src/components/base/PvTree/PvSimpleNestedTreeItem.vue","../../../src/components/base/PvTree/PvSimpleNestedTree.vue","../../../src/components/base/PvTree/PvSimpleNestedTree.vue","../../../src/components/base/PvTree/PvTreeItem.vue","../../../src/components/base/PvTree/PvTreeItem.vue","../../../src/components/base/PvTree/composables/useTreeUpdate.ts","../../../src/components/base/PvTree/PvTree.vue","../../../src/components/base/PvTree/PvTree.vue","../../../src/components/base/PvTree/PvTreeGroup.vue","../../../src/components/base/PvTree/PvTreeGroup.vue","../../../src/components/base/PvProgressBar/PvProgressBar.vue","../../../src/components/base/PvProgressBar/PvProgressBar.vue","../../../src/components/base/PvDistributionBar/PvDistributionBar.vue","../../../src/components/base/PvDistributionBar/PvDistributionBar.vue","../../../src/components/base/PvFilterPanel/advancedFilterModel.ts","../../../src/components/base/PvFilterPanel/filterOptionValue.ts","../../../src/components/base/PvFilterPanel/aggregateFilterModel.ts","../../../src/components/base/PvFilterPanel/filterOptionDisplay.ts","../../../src/components/base/PvRange/PvRange.vue","../../../src/components/base/PvRange/PvRange.vue","../../../src/components/base/PvFilterPanel/PvFilterPanelOptionRow.vue","../../../src/components/base/PvFilterPanel/PvFilterPanelOptionRow.vue","../../../src/components/base/PvFilterPanel/PvFilterPanelAccordion.vue","../../../src/components/base/PvFilterPanel/PvFilterPanelAccordion.vue","../../../src/components/base/PvFilterPanel/PvFilterPanelAppliedFiltersSection.vue","../../../src/components/base/PvFilterPanel/PvFilterPanelAppliedFiltersSection.vue","../../../src/components/base/PvHorizontalScroller/PvHorizontalScroller.vue","../../../src/components/base/PvHorizontalScroller/PvHorizontalScroller.vue","../../../src/components/base/PvFilterPanel/PvFilterPanelCategoryButtonRow.vue","../../../src/components/base/PvFilterPanel/PvFilterPanelCategoryButtonRow.vue","../../../src/components/base/PvFilterPanel/usePvFilterStore.ts","../../../src/components/base/PvFilterPanel/PvFilterPanel.vue","../../../src/components/base/PvFilterPanel/PvFilterPanel.vue","../../../src/components/base/PvQueryBuilderInput/useQueryBuilder.ts","../../../src/components/base/PvQueryBuilderInput/QueryBuilderMenuOptionRenderer.vue","../../../src/components/base/PvQueryBuilderInput/QueryBuilderMenuOptionRenderer.vue","../../../src/components/base/PvQueryBuilderInput/QueryFormatter.vue","../../../src/components/base/PvQueryBuilderInput/QueryFormatter.vue","../../../src/components/base/PvQueryBuilderInput/PvQueryBuilderInput.vue","../../../src/components/base/PvQueryBuilderInput/PvQueryBuilderInput.vue","../../../src/components/base/PvTableOfContents/PvTableOfContents.vue","../../../src/components/base/PvTableOfContents/PvTableOfContents.vue","../../../src/components/base/PvStepper/PvStepper.vue","../../../src/components/base/PvStepper/PvStepper.vue","../../../src/components/base/PvComponentsConfig/primeVue.config.ts","../../../src/components/base/PvComponentsConfig/usePvComponents.ts"],"sourcesContent":["<script setup lang=\"ts\">\nimport { PvSpinnerSize, PvSpinnerVariant } from \"./types\";\n\ninterface PvSpinnerProps {\n /** The size of the spinner. Controls the rendered diameter via a CSS custom property. */\n size?: PvSpinnerSize;\n /** The color variant of the spinner. Use \"white\" on dark backgrounds and \"dark\" on light backgrounds. */\n variant?: PvSpinnerVariant;\n}\n\nconst mapSizeToPx: Record<PvSpinnerSize, string> = {\n xs: \"0.75rem\",\n sm: \"1rem\",\n md: \"1.25rem\",\n lg: \"1.5rem\",\n xl: \"2rem\",\n};\n\nconst mapVariantToPvClass: Record<PvSpinnerVariant, string> = {\n primary: \"pv-spinner\",\n dark: \"pv-spinner-dark\",\n white: \"pv-spinner-light\",\n};\n\nwithDefaults(defineProps<PvSpinnerProps>(), {\n size: \"lg\",\n variant: \"primary\",\n});\n</script>\n\n<template>\n <div data-testid=\"pv-spinner\" :class=\"mapVariantToPvClass[variant]\" :style=\"{ '--size': mapSizeToPx[size] }\" />\n</template>\n","<script setup lang=\"ts\">\nimport { PvSpinnerSize, PvSpinnerVariant } from \"./types\";\n\ninterface PvSpinnerProps {\n /** The size of the spinner. Controls the rendered diameter via a CSS custom property. */\n size?: PvSpinnerSize;\n /** The color variant of the spinner. Use \"white\" on dark backgrounds and \"dark\" on light backgrounds. */\n variant?: PvSpinnerVariant;\n}\n\nconst mapSizeToPx: Record<PvSpinnerSize, string> = {\n xs: \"0.75rem\",\n sm: \"1rem\",\n md: \"1.25rem\",\n lg: \"1.5rem\",\n xl: \"2rem\",\n};\n\nconst mapVariantToPvClass: Record<PvSpinnerVariant, string> = {\n primary: \"pv-spinner\",\n dark: \"pv-spinner-dark\",\n white: \"pv-spinner-light\",\n};\n\nwithDefaults(defineProps<PvSpinnerProps>(), {\n size: \"lg\",\n variant: \"primary\",\n});\n</script>\n\n<template>\n <div data-testid=\"pv-spinner\" :class=\"mapVariantToPvClass[variant]\" :style=\"{ '--size': mapSizeToPx[size] }\" />\n</template>\n","import { PvButtonSize } from \"@/components/base/PvButton/types.ts\";\n\nexport const supportedInverseButtonVariants = [\"ghost\"];\n\nconst sizeToClassMap: Record<PvButtonSize, string | undefined> = {\n md: \"pv-button-small\",\n lg: undefined,\n xl: \"pv-button-large\",\n};\n\nexport const pvButtonSizeToClass = (size: PvButtonSize | null | undefined): string | null => {\n if (size == null || !sizeToClassMap.hasOwnProperty(size)) {\n return null;\n }\n return sizeToClassMap[size] || null;\n};\n","/**\n * Utility functions for web components\n */\n\nimport { ref, getCurrentInstance } from \"vue\";\n\n/**\n * Composable to detect if a component is running as a web component\n * Returns a reactive ref that's set to true/false on mount\n *\n * @returns Reactive ref boolean indicating if running as web component\n *\n * @example\n * import { useIsWebComponent } from '@/web-components/utils';\n *\n * export default {\n * setup() {\n * const isWc = useIsWebComponent();\n * // isWc.value is true if running as web component, false if Vue component\n * }\n * }\n */\nexport function useIsWebComponent() {\n const isWc = ref(false);\n const instance = getCurrentInstance();\n const root = instance?.root || {};\n if (\"isCE\" in root && root.isCE === true) {\n isWc.value = true;\n }\n return isWc;\n}\n","export const PvSizes = [\"xs\", \"sm\", \"md\", \"lg\", \"xl\", \"2x\"] as const;\nexport type PvSize = (typeof PvSizes)[number];\n\nexport const PvTheme = [\"white\", \"dark\"] as const;\nexport type PvThemes = (typeof PvTheme)[number];\n\nexport const PvVariants = [\"primary\", \"secondary\", \"tertiary\", \"ghost\", \"destructive\", \"transparent\"] as const;\nexport type PvVariants = (typeof PvVariants)[number];\n\nexport const PvColorVariants = [\"default\", \"success\", \"warning\", \"critical\", \"highlight\"] as const;\nexport type PvColorVariants = (typeof PvColorVariants)[number];\n\nexport const PvInputVariants = [\"h1\", \"h2\", \"h3\", \"h4\", \"text-md\", \"text-sm\", \"text-lg\", \"caption\"] as const;\nexport type PvInputVariants = (typeof PvInputVariants)[number];\n\nexport const PvTextInputColors = [\"white\", \"grey\"] as const;\nexport type PvTextInputColors = (typeof PvTextInputColors)[number];\n\nexport const sizeMap: Record<PvSize, string> = {\n xs: \"12px\",\n sm: \"16px\",\n md: \"20px\",\n lg: \"24px\",\n xl: \"32px\",\n \"2x\": \"40px\",\n};\n\nexport const PvIconSizes = [undefined, 10, 12, 20, 24, 32, 64] as const;\nexport type PvIconSize = (typeof PvIconSizes)[number];\n\nexport type PvAlignmentPositions =\n | \"bottom-left\"\n | \"bottom-center\"\n | \"bottom-right\"\n | \"top-left\"\n | \"top-center\"\n | \"top-right\"\n | \"center-left\"\n | \"center-right\";\n","<script lang=\"ts\">\nimport { PvIconSize, PvIconSizes } from \"../baseProps\";\n</script>\n<script setup lang=\"ts\">\nimport { computed, ref, Ref } from \"vue\";\nimport { useIsWebComponent } from \"@/web-components/utils\";\n\ntype PvIconProps = {\n /** Name of the icon from the SVG sprite sheet (e.g. \"user\", \"check-circle\"). */\n name: string;\n /** Pixel size of the icon. When omitted the icon inherits its container's size. */\n size?: PvIconSize;\n};\n\nconst props = defineProps<PvIconProps>();\nconst isWeb = useIsWebComponent();\n\nconst globalSpritePath: Ref<string | null> = ref(null);\n\nconst classes = computed(() => ({\n \"pv-icon\": true,\n [`pv-icon-${props.size}`]: props.size != null && PvIconSizes.includes(props.size),\n}));\n\nconst svgHref = computed(() => {\n // If the global sprite path is set, use it\n if (isWeb.value && globalSpritePath.value) {\n return `${globalSpritePath.value}#${props.name}`;\n }\n return `#${props.name}`;\n});\n\n// @ts-expect-error ignore type error for globalThis\nif (globalThis.__PV_GLOBAL_SPRITE_PATH__) {\n // We only want to use sprite paths for web components\n // @ts-expect-error ignore type error for globalThis\n globalSpritePath.value = globalThis.__PV_GLOBAL_SPRITE_PATH__;\n}\n</script>\n\n<template>\n <svg data-testid=\"pv-icon\" aria-hidden=\"true\" :class=\"classes\">\n <use :xlink:href=\"svgHref\"></use>\n </svg>\n</template>\n","<script lang=\"ts\">\nimport { PvIconSize, PvIconSizes } from \"../baseProps\";\n</script>\n<script setup lang=\"ts\">\nimport { computed, ref, Ref } from \"vue\";\nimport { useIsWebComponent } from \"@/web-components/utils\";\n\ntype PvIconProps = {\n /** Name of the icon from the SVG sprite sheet (e.g. \"user\", \"check-circle\"). */\n name: string;\n /** Pixel size of the icon. When omitted the icon inherits its container's size. */\n size?: PvIconSize;\n};\n\nconst props = defineProps<PvIconProps>();\nconst isWeb = useIsWebComponent();\n\nconst globalSpritePath: Ref<string | null> = ref(null);\n\nconst classes = computed(() => ({\n \"pv-icon\": true,\n [`pv-icon-${props.size}`]: props.size != null && PvIconSizes.includes(props.size),\n}));\n\nconst svgHref = computed(() => {\n // If the global sprite path is set, use it\n if (isWeb.value && globalSpritePath.value) {\n return `${globalSpritePath.value}#${props.name}`;\n }\n return `#${props.name}`;\n});\n\n// @ts-expect-error ignore type error for globalThis\nif (globalThis.__PV_GLOBAL_SPRITE_PATH__) {\n // We only want to use sprite paths for web components\n // @ts-expect-error ignore type error for globalThis\n globalSpritePath.value = globalThis.__PV_GLOBAL_SPRITE_PATH__;\n}\n</script>\n\n<template>\n <svg data-testid=\"pv-icon\" aria-hidden=\"true\" :class=\"classes\">\n <use :xlink:href=\"svgHref\"></use>\n </svg>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvCounterBadgeSize, PvCounterBadgeVariant } from \"./types\";\n\nexport interface PvCounterBadgeProps {\n /** Numeric value to display */\n value?: number;\n /** Text prefix displayed before the value */\n prefix?: string;\n /** Visual style variant */\n variant?: PvCounterBadgeVariant;\n /** Display size of the badge */\n size?: PvCounterBadgeSize;\n /** Maximum value before showing overflow indicator (e.g. \"99+\") */\n maxValue?: number;\n}\n\nconst props = withDefaults(defineProps<PvCounterBadgeProps>(), {\n variant: \"primary\",\n maxValue: 99,\n size: \"sm\",\n prefix: \"\",\n});\n\nconst size = computed(() => {\n if (props.size == \"md\") {\n return \"md\";\n } else if (props.size == \"sm\") {\n return \"sm\";\n }\n return \"sm\";\n});\n\nconst displayValue = computed(() => {\n if (props.maxValue && props.value && props.value > props.maxValue) {\n return `${props.maxValue}+`;\n }\n if (props.value != null) {\n return `${props.prefix}${props.value}`;\n }\n return \"-\";\n});\n\nconst classes = computed(() => ({\n \"pv-inline-block pv-inset-square pv-radius pv-text-center\": true,\n \"pv-badge-md pv-text-body-md\": size.value == \"md\",\n \"pv-badge-sm pv-text-body-sm\": size.value == \"sm\",\n \"pv-surface-brand-inverse pv-text-inverse\": props.variant == \"primary\",\n \"pv-badge-secondary\": props.variant == \"secondary\",\n \"pv-surface-lighten-5\": props.variant == \"tertiary\",\n \"pv-text-secondary\": props.variant == \"ghost\" || props.variant == \"tertiary\",\n \"pv-surface\": props.variant == \"ghost\",\n}));\n</script>\n<template>\n <div :class=\"classes\" data-testid=\"pv-counter-badge\">\n {{ displayValue }}\n </div>\n</template>\n\n<style scoped>\n.pv-badge-md {\n --inset-size: 2px 2px;\n min-height: 20px;\n max-height: 20px;\n min-width: 20px;\n font-weight: 500;\n}\n.pv-badge-sm {\n --inset-size: 0 2px;\n min-height: 16px;\n max-height: 16px;\n min-width: 16px;\n font-weight: 500;\n}\n.pv-surface-lighten-5 {\n background-color: #e0e5e4;\n}\n.pv-text-secondary {\n color: #4b595c;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvCounterBadgeSize, PvCounterBadgeVariant } from \"./types\";\n\nexport interface PvCounterBadgeProps {\n /** Numeric value to display */\n value?: number;\n /** Text prefix displayed before the value */\n prefix?: string;\n /** Visual style variant */\n variant?: PvCounterBadgeVariant;\n /** Display size of the badge */\n size?: PvCounterBadgeSize;\n /** Maximum value before showing overflow indicator (e.g. \"99+\") */\n maxValue?: number;\n}\n\nconst props = withDefaults(defineProps<PvCounterBadgeProps>(), {\n variant: \"primary\",\n maxValue: 99,\n size: \"sm\",\n prefix: \"\",\n});\n\nconst size = computed(() => {\n if (props.size == \"md\") {\n return \"md\";\n } else if (props.size == \"sm\") {\n return \"sm\";\n }\n return \"sm\";\n});\n\nconst displayValue = computed(() => {\n if (props.maxValue && props.value && props.value > props.maxValue) {\n return `${props.maxValue}+`;\n }\n if (props.value != null) {\n return `${props.prefix}${props.value}`;\n }\n return \"-\";\n});\n\nconst classes = computed(() => ({\n \"pv-inline-block pv-inset-square pv-radius pv-text-center\": true,\n \"pv-badge-md pv-text-body-md\": size.value == \"md\",\n \"pv-badge-sm pv-text-body-sm\": size.value == \"sm\",\n \"pv-surface-brand-inverse pv-text-inverse\": props.variant == \"primary\",\n \"pv-badge-secondary\": props.variant == \"secondary\",\n \"pv-surface-lighten-5\": props.variant == \"tertiary\",\n \"pv-text-secondary\": props.variant == \"ghost\" || props.variant == \"tertiary\",\n \"pv-surface\": props.variant == \"ghost\",\n}));\n</script>\n<template>\n <div :class=\"classes\" data-testid=\"pv-counter-badge\">\n {{ displayValue }}\n </div>\n</template>\n\n<style scoped>\n.pv-badge-md {\n --inset-size: 2px 2px;\n min-height: 20px;\n max-height: 20px;\n min-width: 20px;\n font-weight: 500;\n}\n.pv-badge-sm {\n --inset-size: 0 2px;\n min-height: 16px;\n max-height: 16px;\n min-width: 16px;\n font-weight: 500;\n}\n.pv-surface-lighten-5 {\n background-color: #e0e5e4;\n}\n.pv-text-secondary {\n color: #4b595c;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvButtonProps } from \"./types\";\nimport PvSpinner from \"../PvSpinner/PvSpinner.vue\";\nimport { pvButtonSizeToClass, supportedInverseButtonVariants } from \"@/components/base/PvButton/helpers.ts\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport PvCounterBadge from \"../PvCounterBadge/PvCounterBadge.vue\";\n\nconst props = withDefaults(defineProps<PvButtonProps>(), {\n variant: \"primary\",\n disabled: false,\n size: \"lg\",\n loading: false,\n inverse: false,\n});\n\nconst computedAriaLabel = computed(() => (!props.label || props.loading ? props.label || props.ariaLabel : undefined));\n\nconst classes = computed(() => {\n const output = [];\n if (props.inverse && supportedInverseButtonVariants.includes(props.variant)) {\n output.push(`pv-button-${props.variant}-inverse`);\n } else {\n output.push(`pv-button-${props.variant}`);\n }\n const sizeClass = pvButtonSizeToClass(props.size);\n if (sizeClass) {\n output.push(sizeClass);\n }\n return output;\n});\n</script>\n\n<template>\n <button type=\"button\" :class=\"classes\" :disabled=\"disabled\" :aria-label=\"computedAriaLabel\" data-testid=\"pv-button\">\n <PvSpinner v-if=\"loading\" size=\"sm\" />\n <template v-else>\n <PvCounterBadge v-if=\"leftCounterBadge\" :value=\"leftCounterBadge\" variant=\"tertiary\" />\n <PvIcon v-if=\"leftIcon\" :name=\"leftIcon\" data-testid=\"pv-button-left-icon\" />\n <span v-if=\"label\" data-testid=\"pv-button-label\">{{ label }}</span>\n <PvCounterBadge v-if=\"rightCounterBadge\" :value=\"rightCounterBadge\" variant=\"tertiary\" />\n <PvIcon v-if=\"rightIcon\" :name=\"rightIcon\" data-testid=\"pv-button-right-icon\" />\n </template>\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvButtonProps } from \"./types\";\nimport PvSpinner from \"../PvSpinner/PvSpinner.vue\";\nimport { pvButtonSizeToClass, supportedInverseButtonVariants } from \"@/components/base/PvButton/helpers.ts\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport PvCounterBadge from \"../PvCounterBadge/PvCounterBadge.vue\";\n\nconst props = withDefaults(defineProps<PvButtonProps>(), {\n variant: \"primary\",\n disabled: false,\n size: \"lg\",\n loading: false,\n inverse: false,\n});\n\nconst computedAriaLabel = computed(() => (!props.label || props.loading ? props.label || props.ariaLabel : undefined));\n\nconst classes = computed(() => {\n const output = [];\n if (props.inverse && supportedInverseButtonVariants.includes(props.variant)) {\n output.push(`pv-button-${props.variant}-inverse`);\n } else {\n output.push(`pv-button-${props.variant}`);\n }\n const sizeClass = pvButtonSizeToClass(props.size);\n if (sizeClass) {\n output.push(sizeClass);\n }\n return output;\n});\n</script>\n\n<template>\n <button type=\"button\" :class=\"classes\" :disabled=\"disabled\" :aria-label=\"computedAriaLabel\" data-testid=\"pv-button\">\n <PvSpinner v-if=\"loading\" size=\"sm\" />\n <template v-else>\n <PvCounterBadge v-if=\"leftCounterBadge\" :value=\"leftCounterBadge\" variant=\"tertiary\" />\n <PvIcon v-if=\"leftIcon\" :name=\"leftIcon\" data-testid=\"pv-button-left-icon\" />\n <span v-if=\"label\" data-testid=\"pv-button-label\">{{ label }}</span>\n <PvCounterBadge v-if=\"rightCounterBadge\" :value=\"rightCounterBadge\" variant=\"tertiary\" />\n <PvIcon v-if=\"rightIcon\" :name=\"rightIcon\" data-testid=\"pv-button-right-icon\" />\n </template>\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport PvSpinner from \"../PvSpinner/PvSpinner.vue\";\nimport { PvButtonSize } from \"@/components/base/PvButton/types.ts\";\nimport { pvButtonSizeToClass } from \"@/components/base/PvButton/helpers.ts\";\nimport { computed } from \"vue\";\n\ninterface PvAiButtonProps {\n /** Size of the AI button */\n size?: PvButtonSize;\n /** Text label displayed next to the AI icon. Omit for icon-only. */\n label?: string;\n /** Show a loading spinner in place of the icon and label */\n loading?: boolean;\n /** Prevent the button from being clicked */\n disabled?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvAiButtonProps>(), {\n size: \"md\",\n label: \"AskTQ\",\n});\n\nconst classes = computed(() => {\n const output = [\"pv-button-ai\"];\n const sizeClass = pvButtonSizeToClass(props.size);\n if (sizeClass) {\n output.push(sizeClass);\n }\n return output;\n});\n\n// Set aria-label when there is no visible text: icon-only mode or loading state (spinner replaces label).\nconst computedAriaLabel = computed(() => (!props.label || props.loading ? props.label || undefined : undefined));\n</script>\n\n<template>\n <button :disabled=\"disabled\" :class=\"classes\" :aria-label=\"computedAriaLabel\">\n <PvSpinner v-if=\"loading\" :size=\"size\" />\n <template v-else>\n <PvIcon class=\"pv-text-brand\" name=\"ai-filled\" />\n <span v-if=\"label\">{{ label }}</span>\n </template>\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport PvSpinner from \"../PvSpinner/PvSpinner.vue\";\nimport { PvButtonSize } from \"@/components/base/PvButton/types.ts\";\nimport { pvButtonSizeToClass } from \"@/components/base/PvButton/helpers.ts\";\nimport { computed } from \"vue\";\n\ninterface PvAiButtonProps {\n /** Size of the AI button */\n size?: PvButtonSize;\n /** Text label displayed next to the AI icon. Omit for icon-only. */\n label?: string;\n /** Show a loading spinner in place of the icon and label */\n loading?: boolean;\n /** Prevent the button from being clicked */\n disabled?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvAiButtonProps>(), {\n size: \"md\",\n label: \"AskTQ\",\n});\n\nconst classes = computed(() => {\n const output = [\"pv-button-ai\"];\n const sizeClass = pvButtonSizeToClass(props.size);\n if (sizeClass) {\n output.push(sizeClass);\n }\n return output;\n});\n\n// Set aria-label when there is no visible text: icon-only mode or loading state (spinner replaces label).\nconst computedAriaLabel = computed(() => (!props.label || props.loading ? props.label || undefined : undefined));\n</script>\n\n<template>\n <button :disabled=\"disabled\" :class=\"classes\" :aria-label=\"computedAriaLabel\">\n <PvSpinner v-if=\"loading\" :size=\"size\" />\n <template v-else>\n <PvIcon class=\"pv-text-brand\" name=\"ai-filled\" />\n <span v-if=\"label\">{{ label }}</span>\n </template>\n </button>\n</template>\n","import { computed, onBeforeUnmount, onMounted, ref, unref, useSlots, watch } from \"vue\";\nimport type { Ref } from \"vue\";\nimport { useIsWebComponent } from \"@/web-components/utils\";\n\ntype MaybeRef<T> = T | Ref<T>;\n\nexport type UseSlotPresenceOptions = {\n /**\n * Host element for native slot detection (required for web components).\n * When running as a web component, light DOM children of this element are inspected.\n */\n host?: MaybeRef<HTMLElement | null | undefined>;\n\n /**\n * A slots object (useful for tests or to override `useSlots()`).\n * Only used when running as a Vue component (not a web component).\n */\n vueSlots?: Record<string, unknown> | null | undefined;\n\n /**\n * Watch light DOM changes so presence updates if children are added/removed.\n * Only applies to web component mode. Defaults to true.\n */\n observe?: boolean;\n\n /**\n * Listen to slotchange events on shadow DOM slots.\n * Only applies to web component mode. Defaults to true.\n */\n listenSlotChange?: boolean;\n\n /**\n * If true, whitespace-only text nodes count as content in the default slot.\n * Only applies to web component mode. Defaults to false.\n */\n countWhitespaceTextInDefaultSlot?: boolean;\n};\n\nfunction isMeaningfulTextNode(node: Node, countWhitespace: boolean) {\n if (node.nodeType !== Node.TEXT_NODE) return false;\n const txt = node.textContent ?? \"\";\n return countWhitespace ? txt.length > 0 : txt.trim().length > 0;\n}\n\nfunction hasNativeSlottedContent(host: HTMLElement, name: string, countWhitespaceTextInDefaultSlot: boolean): boolean {\n const slotName = name === \"default\" ? \"\" : name;\n const nodes = Array.from(host.childNodes);\n\n if (slotName === \"\") {\n // Default slot: nodes without a `slot` attribute\n return nodes.some((n) => {\n if (n.nodeType === Node.ELEMENT_NODE) {\n const el = n as Element;\n return !el.hasAttribute(\"slot\");\n }\n return isMeaningfulTextNode(n, countWhitespaceTextInDefaultSlot);\n });\n }\n\n // Named slot: element children with slot=\"name\"\n return nodes.some((n) => {\n if (n.nodeType !== Node.ELEMENT_NODE) return false;\n const el = n as Element;\n return el.getAttribute(\"slot\") === slotName;\n });\n}\n\nfunction getShadowSlotEl(host: HTMLElement, name: string): HTMLSlotElement | null {\n const sr = host.shadowRoot;\n if (!sr) return null;\n if (name === \"default\" || name === \"\") {\n return sr.querySelector(\"slot:not([name])\");\n }\n return sr.querySelector(`slot[name=\"${CSS.escape(name)}\"]`);\n}\n\n/**\n * Returns a computed boolean indicating if a slot has content.\n *\n * Automatically detects if running as a Vue component or web component:\n * - Vue component: checks Vue's slot system via useSlots()\n * - Web component: inspects light DOM children of the host element\n */\nexport function useSlotPresence(slotName: string, options: UseSlotPresenceOptions = {}) {\n const { host, vueSlots, observe = true, listenSlotChange = true, countWhitespaceTextInDefaultSlot = false } = options;\n\n const isWebComponent = useIsWebComponent();\n const slots = vueSlots ?? useSlots();\n\n // Vue slot presence (used when not a web component)\n const hasVueSlot = computed(() => {\n if (isWebComponent.value || !slots) return false;\n const key = slotName === \"default\" || slotName === \"\" ? \"default\" : slotName;\n return !!(slots as Record<string, unknown>)[key];\n });\n\n // Native/web-component slot presence\n const hasNativeSlot = ref(false);\n\n let mo: MutationObserver | null = null;\n let shadowSlot: HTMLSlotElement | null = null;\n\n const cleanup = () => {\n if (mo) {\n mo.disconnect();\n mo = null;\n }\n if (shadowSlot) {\n shadowSlot.removeEventListener(\"slotchange\", updateNative);\n shadowSlot = null;\n }\n };\n\n const updateNative = () => {\n if (!isWebComponent.value) {\n hasNativeSlot.value = false;\n return;\n }\n\n const el = unref(host);\n if (!el) {\n hasNativeSlot.value = false;\n return;\n }\n\n // Prefer assignedNodes if we can access the <slot> element in open shadowRoot\n const slotEl = listenSlotChange ? getShadowSlotEl(el, slotName) : null;\n if (slotEl) {\n const assigned = slotEl.assignedNodes({ flatten: true });\n hasNativeSlot.value = assigned.some((n) => {\n if (n.nodeType === Node.ELEMENT_NODE) return true;\n return isMeaningfulTextNode(n, countWhitespaceTextInDefaultSlot);\n });\n return;\n }\n\n // Fallback: inspect light DOM children\n hasNativeSlot.value = hasNativeSlottedContent(el, slotName, countWhitespaceTextInDefaultSlot);\n };\n\n const attach = () => {\n if (!isWebComponent.value) return;\n\n cleanup();\n\n const el = unref(host);\n if (!el) {\n hasNativeSlot.value = false;\n return;\n }\n\n updateNative();\n\n if (listenSlotChange) {\n shadowSlot = getShadowSlotEl(el, slotName);\n if (shadowSlot) shadowSlot.addEventListener(\"slotchange\", updateNative);\n }\n\n if (observe) {\n mo = new MutationObserver(() => updateNative());\n mo.observe(el, {\n childList: true,\n subtree: false,\n attributes: true,\n attributeFilter: [\"slot\"],\n characterData: true,\n });\n }\n };\n\n onMounted(attach);\n onBeforeUnmount(cleanup);\n\n // If host ref changes, reattach\n watch(\n () => unref(host),\n () => {\n if (isWebComponent.value) attach();\n },\n );\n\n // Select presence based on component type\n const present = computed(() => (isWebComponent.value ? hasNativeSlot.value : hasVueSlot.value));\n\n return {\n present,\n hasVueSlot,\n hasNativeSlot,\n refresh: updateNative,\n };\n}\n","<script setup lang=\"ts\">\nimport { PvTooltipPositions, PvTooltipVariants, PvTooltipSize } from \"./types\";\nimport { useSlotPresence } from \"@/composables/useSlotPresence\";\n\ninterface PvTooltipProps {\n /** Color theme variant */\n variant?: PvTooltipVariants;\n /** Position of the tooltip relative to the trigger element */\n tooltipPosition?: PvTooltipPositions;\n /** Accessibility label reference ID linking trigger to tooltip content */\n ariaLabelledBy?: string;\n /** Size of the tooltip content area */\n size?: PvTooltipSize;\n /** When true, tooltip hides immediately when cursor leaves the trigger */\n disableInteractive?: boolean;\n /** Delay in milliseconds before showing the tooltip */\n delay?: number;\n}\n\nwithDefaults(defineProps<PvTooltipProps>(), {\n variant: \"white\",\n ariaLabelledBy: \"ariaLabelledById\",\n tooltipPosition: \"top-right\",\n size: \"md\",\n disableInteractive: false,\n delay: 0,\n});\n\nconst { present: hasTooltip } = useSlotPresence(\"tooltip-content\");\n</script>\n\n<template>\n <div\n data-testid=\"pv-tooltip\"\n :class=\"[\n {\n 'pv-tooltip': hasTooltip,\n 'pv-tooltip-small': hasTooltip && size === 'sm',\n },\n ]\"\n :data-position=\"tooltipPosition\"\n :data-style=\"variant === 'white' ? 'white' : 'dark'\"\n :data-static=\"disableInteractive ? true : undefined\"\n :aria-labelledby=\"hasTooltip ? ariaLabelledBy : undefined\"\n >\n <slot name=\"label\" />\n <div v-if=\"hasTooltip\" role=\"tooltip\" :id=\"ariaLabelledBy\" data-testid=\"pv-tooltip-content\">\n <slot name=\"tooltip-content\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { PvTooltipPositions, PvTooltipVariants, PvTooltipSize } from \"./types\";\nimport { useSlotPresence } from \"@/composables/useSlotPresence\";\n\ninterface PvTooltipProps {\n /** Color theme variant */\n variant?: PvTooltipVariants;\n /** Position of the tooltip relative to the trigger element */\n tooltipPosition?: PvTooltipPositions;\n /** Accessibility label reference ID linking trigger to tooltip content */\n ariaLabelledBy?: string;\n /** Size of the tooltip content area */\n size?: PvTooltipSize;\n /** When true, tooltip hides immediately when cursor leaves the trigger */\n disableInteractive?: boolean;\n /** Delay in milliseconds before showing the tooltip */\n delay?: number;\n}\n\nwithDefaults(defineProps<PvTooltipProps>(), {\n variant: \"white\",\n ariaLabelledBy: \"ariaLabelledById\",\n tooltipPosition: \"top-right\",\n size: \"md\",\n disableInteractive: false,\n delay: 0,\n});\n\nconst { present: hasTooltip } = useSlotPresence(\"tooltip-content\");\n</script>\n\n<template>\n <div\n data-testid=\"pv-tooltip\"\n :class=\"[\n {\n 'pv-tooltip': hasTooltip,\n 'pv-tooltip-small': hasTooltip && size === 'sm',\n },\n ]\"\n :data-position=\"tooltipPosition\"\n :data-style=\"variant === 'white' ? 'white' : 'dark'\"\n :data-static=\"disableInteractive ? true : undefined\"\n :aria-labelledby=\"hasTooltip ? ariaLabelledBy : undefined\"\n >\n <slot name=\"label\" />\n <div v-if=\"hasTooltip\" role=\"tooltip\" :id=\"ariaLabelledBy\" data-testid=\"pv-tooltip-content\">\n <slot name=\"tooltip-content\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { PvButtonWithTooltipProps } from \"./types\";\nimport PvButton from \"./PvButton.vue\";\nimport PvTooltip from \"../PvTooltip/PvTooltip.vue\";\nimport { computed } from \"vue\";\n\nconst props = withDefaults(defineProps<PvButtonWithTooltipProps>(), {\n tooltipVariant: \"dark\",\n delay: 500,\n});\n\nconst pvToolTipSize = computed(() => {\n // for md buttons, use sm, else use md\n return props.size === \"md\" ? \"sm\" : \"md\";\n});\n</script>\n\n<template>\n <PvTooltip :variant=\"tooltipVariant\" :tooltip-position=\"tooltipPosition\" :delay=\"delay\" :size=\"pvToolTipSize\">\n <template #tooltip-content>\n <p class=\"pv-text-body-sm\">{{ tooltipText }}</p>\n </template>\n <template #label>\n <PvButton v-bind=\"$props\" />\n </template>\n </PvTooltip>\n</template>\n","<script setup lang=\"ts\">\nimport { PvButtonWithTooltipProps } from \"./types\";\nimport PvButton from \"./PvButton.vue\";\nimport PvTooltip from \"../PvTooltip/PvTooltip.vue\";\nimport { computed } from \"vue\";\n\nconst props = withDefaults(defineProps<PvButtonWithTooltipProps>(), {\n tooltipVariant: \"dark\",\n delay: 500,\n});\n\nconst pvToolTipSize = computed(() => {\n // for md buttons, use sm, else use md\n return props.size === \"md\" ? \"sm\" : \"md\";\n});\n</script>\n\n<template>\n <PvTooltip :variant=\"tooltipVariant\" :tooltip-position=\"tooltipPosition\" :delay=\"delay\" :size=\"pvToolTipSize\">\n <template #tooltip-content>\n <p class=\"pv-text-body-sm\">{{ tooltipText }}</p>\n </template>\n <template #label>\n <PvButton v-bind=\"$props\" />\n </template>\n </PvTooltip>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvReleaseBadgeVariant } from \"./types\";\n\nexport interface PvReleaseBadgeProps {\n /** Release stage variant that determines the badge label and color */\n variant: PvReleaseBadgeVariant;\n /** Apply inverse styling (neutral background) */\n inverse?: boolean;\n}\nconst props = defineProps<PvReleaseBadgeProps>();\n\nconst displayLabel = computed(() => {\n if (props.variant == \"release-alpha\") {\n return \"ALPHA\";\n } else if (props.variant == \"release-beta\") {\n return \"BETA\";\n } else {\n return \"\";\n }\n});\n\nconst classes = computed(() => {\n if (props.inverse) {\n return \"pv-tag-inverse\";\n }\n return {\n \"pv-tag-yellow\": props.variant == \"release-alpha\",\n \"pv-tag-purple\": props.variant == \"release-beta\",\n };\n});\n</script>\n\n<template>\n <div :class=\"classes\">\n {{ displayLabel }}\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvReleaseBadgeVariant } from \"./types\";\n\nexport interface PvReleaseBadgeProps {\n /** Release stage variant that determines the badge label and color */\n variant: PvReleaseBadgeVariant;\n /** Apply inverse styling (neutral background) */\n inverse?: boolean;\n}\nconst props = defineProps<PvReleaseBadgeProps>();\n\nconst displayLabel = computed(() => {\n if (props.variant == \"release-alpha\") {\n return \"ALPHA\";\n } else if (props.variant == \"release-beta\") {\n return \"BETA\";\n } else {\n return \"\";\n }\n});\n\nconst classes = computed(() => {\n if (props.inverse) {\n return \"pv-tag-inverse\";\n }\n return {\n \"pv-tag-yellow\": props.variant == \"release-alpha\",\n \"pv-tag-purple\": props.variant == \"release-beta\",\n };\n});\n</script>\n\n<template>\n <div :class=\"classes\">\n {{ displayLabel }}\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, CSSProperties } from \"vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { TagSize, TagVariant } from \"./types\";\n\nexport interface PvTagProps {\n /**\n * Tag size\n */\n size?: TagSize;\n /**\n * Tag visual variant\n */\n variant?: TagVariant;\n /**\n * Tag Icon\n */\n icon?: string;\n /**\n * Icon class\n */\n iconClasses?: string[];\n /**\n * Tag Label\n */\n label: string;\n /**\n * Show left clear icon\n */\n showClear?: boolean;\n /**\n * Show rounded state\n */\n rounded?: boolean;\n /**\n * Spine - dotted state\n */\n spine?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvTagProps>(), {\n size: \"md\",\n variant: \"tertiary\",\n});\n\ndefineEmits<{\n (e: \"handle-close\", payload: string): void;\n (e: \"handle-click\", payload: string): void;\n}>();\n\nconst tagSizeClass = computed(() => {\n switch (props.size) {\n case \"lg\": {\n return \"pv-tag-lg\";\n }\n case \"sm\": {\n return \"pv-tag-sm\";\n }\n default: {\n return \"\";\n }\n }\n});\n\nconst tagVariantClass = computed(() => {\n switch (props.variant) {\n case \"primary\": {\n return \"pv-tag-primary\";\n }\n case \"tertiary\": {\n return \"pv-tag-tertiary\";\n }\n case \"transparent\": {\n return \"pv-tag-tertiary\";\n }\n default: {\n return \"\";\n }\n }\n});\n\nconst pvTagStyles = computed(() => {\n const baseStyles: CSSProperties = {\n \"max-width\": \"100%\",\n \"--flex-gap\": \"4px\",\n };\n\n if (props.variant === \"transparent\") {\n baseStyles[\"--tag-background-color\"] = \"transparent\";\n }\n\n return baseStyles;\n});\n</script>\n\n<template>\n <button\n :class=\"[tagVariantClass, tagSizeClass, 'pv-flex']\"\n @click=\"$emit('handle-click', label)\"\n :style=\"pvTagStyles\"\n data-testid=\"pv-tag\"\n :data-style=\"rounded ? 'rounded' : undefined\"\n >\n <PvIcon data-testid=\"pv-tag-icon\" v-if=\"icon\" :class=\"iconClasses\" :name=\"icon\" :size=\"12\" />\n <span\n :class=\"[\n 'pv-truncate',\n {\n 'pv-underline-dotted': spine,\n },\n ]\"\n >\n {{ label }}\n </span>\n <PvIcon\n data-testid=\"pv-tag-close-icon\"\n :size=\"12\"\n name=\"close\"\n v-if=\"showClear\"\n @click.stop=\"$emit('handle-close', label)\"\n />\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, CSSProperties } from \"vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { TagSize, TagVariant } from \"./types\";\n\nexport interface PvTagProps {\n /**\n * Tag size\n */\n size?: TagSize;\n /**\n * Tag visual variant\n */\n variant?: TagVariant;\n /**\n * Tag Icon\n */\n icon?: string;\n /**\n * Icon class\n */\n iconClasses?: string[];\n /**\n * Tag Label\n */\n label: string;\n /**\n * Show left clear icon\n */\n showClear?: boolean;\n /**\n * Show rounded state\n */\n rounded?: boolean;\n /**\n * Spine - dotted state\n */\n spine?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvTagProps>(), {\n size: \"md\",\n variant: \"tertiary\",\n});\n\ndefineEmits<{\n (e: \"handle-close\", payload: string): void;\n (e: \"handle-click\", payload: string): void;\n}>();\n\nconst tagSizeClass = computed(() => {\n switch (props.size) {\n case \"lg\": {\n return \"pv-tag-lg\";\n }\n case \"sm\": {\n return \"pv-tag-sm\";\n }\n default: {\n return \"\";\n }\n }\n});\n\nconst tagVariantClass = computed(() => {\n switch (props.variant) {\n case \"primary\": {\n return \"pv-tag-primary\";\n }\n case \"tertiary\": {\n return \"pv-tag-tertiary\";\n }\n case \"transparent\": {\n return \"pv-tag-tertiary\";\n }\n default: {\n return \"\";\n }\n }\n});\n\nconst pvTagStyles = computed(() => {\n const baseStyles: CSSProperties = {\n \"max-width\": \"100%\",\n \"--flex-gap\": \"4px\",\n };\n\n if (props.variant === \"transparent\") {\n baseStyles[\"--tag-background-color\"] = \"transparent\";\n }\n\n return baseStyles;\n});\n</script>\n\n<template>\n <button\n :class=\"[tagVariantClass, tagSizeClass, 'pv-flex']\"\n @click=\"$emit('handle-click', label)\"\n :style=\"pvTagStyles\"\n data-testid=\"pv-tag\"\n :data-style=\"rounded ? 'rounded' : undefined\"\n >\n <PvIcon data-testid=\"pv-tag-icon\" v-if=\"icon\" :class=\"iconClasses\" :name=\"icon\" :size=\"12\" />\n <span\n :class=\"[\n 'pv-truncate',\n {\n 'pv-underline-dotted': spine,\n },\n ]\"\n >\n {{ label }}\n </span>\n <PvIcon\n data-testid=\"pv-tag-close-icon\"\n :size=\"12\"\n name=\"close\"\n v-if=\"showClear\"\n @click.stop=\"$emit('handle-close', label)\"\n />\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { PillSize, PillVariant, PillDotVariant } from \"./types\";\n\nexport interface PvPillProps {\n /**\n * Pill size\n */\n size?: PillSize;\n /**\n * Pill color variant\n */\n variant?: PillVariant;\n /**\n * Icon name displayed before the label\n */\n icon?: string;\n /**\n * Colored dot indicator displayed before the label. When set, forces neutral (tertiary) styling regardless of the variant prop.\n */\n dotVariant?: PillDotVariant;\n /**\n * Pill label text\n */\n label: string;\n}\n\nconst props = withDefaults(defineProps<PvPillProps>(), {\n size: \"md\",\n variant: \"default\",\n});\n\nconst tagSizeClass = computed(() => {\n switch (props.size) {\n case \"lg\": {\n return \"pv-tag-lg\";\n }\n case \"sm\": {\n return \"pv-tag-sm\";\n }\n default: {\n return \"\";\n }\n }\n});\n\nconst tagVariantClass = computed(() => {\n if (props.dotVariant) {\n return \"pv-tag-tertiary\";\n }\n switch (props.variant) {\n case \"default\": {\n return \"pv-tag-tertiary\";\n }\n case \"success\": {\n return \"pv-tag-green\";\n }\n case \"warning\": {\n return \"pv-tag-orange\";\n }\n case \"critical\": {\n return \"pv-tag-red\";\n }\n case \"highlight\": {\n return \"pv-tag-turquoise\";\n }\n default: {\n return \"pv-tag-tertiary\";\n }\n }\n});\n</script>\n\n<template>\n <div\n :class=\"[tagVariantClass, tagSizeClass, 'pv-flex']\"\n @click=\"$emit('handle-click', label)\"\n data-style=\"rounded\"\n style=\"width: fit-content; --flex-gap: 4px\"\n >\n <span v-if=\"dotVariant\" style=\"margin-inline-end: 0px\" :class=\"`pv-status-${dotVariant}`\"></span>\n <PvIcon v-if=\"icon\" :name=\"icon\" :size=\"12\" />\n <span>\n {{ label }}\n </span>\n </div>\n</template>\n\n<style scoped>\n[class*=\"pv-status\"] {\n &::before,\n &::after {\n margin-inline-end: 0px;\n }\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { PillSize, PillVariant, PillDotVariant } from \"./types\";\n\nexport interface PvPillProps {\n /**\n * Pill size\n */\n size?: PillSize;\n /**\n * Pill color variant\n */\n variant?: PillVariant;\n /**\n * Icon name displayed before the label\n */\n icon?: string;\n /**\n * Colored dot indicator displayed before the label. When set, forces neutral (tertiary) styling regardless of the variant prop.\n */\n dotVariant?: PillDotVariant;\n /**\n * Pill label text\n */\n label: string;\n}\n\nconst props = withDefaults(defineProps<PvPillProps>(), {\n size: \"md\",\n variant: \"default\",\n});\n\nconst tagSizeClass = computed(() => {\n switch (props.size) {\n case \"lg\": {\n return \"pv-tag-lg\";\n }\n case \"sm\": {\n return \"pv-tag-sm\";\n }\n default: {\n return \"\";\n }\n }\n});\n\nconst tagVariantClass = computed(() => {\n if (props.dotVariant) {\n return \"pv-tag-tertiary\";\n }\n switch (props.variant) {\n case \"default\": {\n return \"pv-tag-tertiary\";\n }\n case \"success\": {\n return \"pv-tag-green\";\n }\n case \"warning\": {\n return \"pv-tag-orange\";\n }\n case \"critical\": {\n return \"pv-tag-red\";\n }\n case \"highlight\": {\n return \"pv-tag-turquoise\";\n }\n default: {\n return \"pv-tag-tertiary\";\n }\n }\n});\n</script>\n\n<template>\n <div\n :class=\"[tagVariantClass, tagSizeClass, 'pv-flex']\"\n @click=\"$emit('handle-click', label)\"\n data-style=\"rounded\"\n style=\"width: fit-content; --flex-gap: 4px\"\n >\n <span v-if=\"dotVariant\" style=\"margin-inline-end: 0px\" :class=\"`pv-status-${dotVariant}`\"></span>\n <PvIcon v-if=\"icon\" :name=\"icon\" :size=\"12\" />\n <span>\n {{ label }}\n </span>\n </div>\n</template>\n\n<style scoped>\n[class*=\"pv-status\"] {\n &::before,\n &::after {\n margin-inline-end: 0px;\n }\n}\n</style>\n","<script lang=\"ts\">\nimport { CSSProperties } from \"vue\";\n\nexport interface PvPopoverProps {\n /** Alignment of the popover relative to its trigger. */\n alignment?: \"top\" | \"right\" | \"top right\" | undefined;\n /** Custom CSS properties applied to the popover root element. */\n cssCustomProperties?: CSSProperties;\n /** Custom CSS properties applied to the inner list element (when isList is true). */\n cssCustomListProperties?: CSSProperties;\n /** When true, renders the content inside a `<ul>` list element. */\n isList?: boolean;\n /** When true and isList is true, enables drag-and-drop reordering of list items. */\n isSortable?: boolean;\n}\n</script>\n<script setup lang=\"ts\">\nimport { useSortable } from \"@vueuse/integrations/useSortable.mjs\";\nimport { useTemplateRef, ref } from \"vue\";\n\nconst popoverRoot = ref<HTMLElement | null>(null);\nconst el = useTemplateRef<HTMLElement>(\"popoverList\");\n\nconst props = withDefaults(defineProps<PvPopoverProps>(), {\n alignment: undefined,\n isList: false,\n cssCustomProperties: () => ({}),\n});\n\nconst emit = defineEmits<{\n (e: \"list-order-updated\", value: string[]): void;\n}>();\n\nif (props.isSortable && props.isList) {\n useSortable(el, [], {\n animation: 150,\n onUpdate: () => {\n const newIds = Array.from(el.value?.children || []).map((child) => (child as HTMLElement).id);\n emit(\"list-order-updated\", newIds);\n },\n });\n}\n\ndefineExpose({ popoverRoot });\n</script>\n<template>\n <div\n ref=\"popoverRoot\"\n class=\"pv-popover\"\n data-testid=\"pv-popover\"\n :data-align=\"alignment\"\n :style=\"cssCustomProperties\"\n >\n <ul v-if=\"isList\" ref=\"popoverList\" role=\"list\" class=\"pv-popover-list\" :style=\"cssCustomListProperties\">\n <slot></slot>\n </ul>\n <slot v-else></slot>\n </div>\n</template>\n\n<style scoped>\n.pv-popover-list {\n font-size: 14px;\n}\n</style>\n","<script lang=\"ts\">\nimport { CSSProperties } from \"vue\";\n\nexport interface PvPopoverProps {\n /** Alignment of the popover relative to its trigger. */\n alignment?: \"top\" | \"right\" | \"top right\" | undefined;\n /** Custom CSS properties applied to the popover root element. */\n cssCustomProperties?: CSSProperties;\n /** Custom CSS properties applied to the inner list element (when isList is true). */\n cssCustomListProperties?: CSSProperties;\n /** When true, renders the content inside a `<ul>` list element. */\n isList?: boolean;\n /** When true and isList is true, enables drag-and-drop reordering of list items. */\n isSortable?: boolean;\n}\n</script>\n<script setup lang=\"ts\">\nimport { useSortable } from \"@vueuse/integrations/useSortable.mjs\";\nimport { useTemplateRef, ref } from \"vue\";\n\nconst popoverRoot = ref<HTMLElement | null>(null);\nconst el = useTemplateRef<HTMLElement>(\"popoverList\");\n\nconst props = withDefaults(defineProps<PvPopoverProps>(), {\n alignment: undefined,\n isList: false,\n cssCustomProperties: () => ({}),\n});\n\nconst emit = defineEmits<{\n (e: \"list-order-updated\", value: string[]): void;\n}>();\n\nif (props.isSortable && props.isList) {\n useSortable(el, [], {\n animation: 150,\n onUpdate: () => {\n const newIds = Array.from(el.value?.children || []).map((child) => (child as HTMLElement).id);\n emit(\"list-order-updated\", newIds);\n },\n });\n}\n\ndefineExpose({ popoverRoot });\n</script>\n<template>\n <div\n ref=\"popoverRoot\"\n class=\"pv-popover\"\n data-testid=\"pv-popover\"\n :data-align=\"alignment\"\n :style=\"cssCustomProperties\"\n >\n <ul v-if=\"isList\" ref=\"popoverList\" role=\"list\" class=\"pv-popover-list\" :style=\"cssCustomListProperties\">\n <slot></slot>\n </ul>\n <slot v-else></slot>\n </div>\n</template>\n\n<style scoped>\n.pv-popover-list {\n font-size: 14px;\n}\n</style>\n","<script lang=\"ts\">\nimport { CSSProperties } from \"vue\";\n\nexport interface PvDropdownProps {\n defaultOpen?: boolean;\n popoverCssProperties?: CSSProperties;\n alignment?: \"top\" | \"right\" | \"top right\" | undefined;\n isList?: boolean;\n isSortable?: boolean;\n icon?: boolean;\n disabled?: boolean;\n isLoading?: boolean;\n useTeleport?: boolean;\n teleportLocation?: string;\n}\n</script>\n<script setup lang=\"ts\">\nimport { computed, ref, watch, nextTick } from \"vue\";\nimport PvPopover from \"../PvPopover/PvPopover.vue\";\nimport { vOnClickOutside } from \"@vueuse/components\";\nconst props = withDefaults(defineProps<PvDropdownProps>(), {\n alignment: undefined,\n isList: false,\n defaultOpen: false,\n disabled: false,\n isLoading: false,\n useTeleport: false,\n teleportLocation: \"body\",\n});\nconst emits = defineEmits<{\n (e: \"dropdown-open\"): void;\n (e: \"dropdown-closed\"): void;\n (e: \"list-order-updated\", value: string[]): void;\n}>();\nconst open = ref<boolean>(props.defaultOpen);\n\nconst triggerRef = ref<HTMLElement | null>(null);\nconst popoverRef = ref<{ popoverRoot: HTMLElement | null } | null>(null);\nconst triggerRect = ref<DOMRect | null>(null);\nconst popoverRect = ref<DOMRect | null>(null);\n\nconst updateRects = () => {\n if (triggerRef.value) {\n triggerRect.value = triggerRef.value.getBoundingClientRect();\n }\n if (popoverRef.value?.popoverRoot) {\n popoverRect.value = popoverRef.value.popoverRoot.getBoundingClientRect();\n }\n};\n\nconst popoverClasses = computed(() => {\n const classes = {\n \"pv-hide\": !open.value,\n };\n return classes;\n});\nconst handleClickTrigger = (e: MouseEvent) => {\n open.value = !open.value;\n};\n\nconst closeDropdown = () => {\n open.value = false;\n};\n\ndefineExpose({\n closeDropdown,\n});\n\nwatch(open, (newValue) => {\n if (newValue) {\n nextTick(() => {\n updateRects();\n emits(\"dropdown-open\");\n });\n } else {\n emits(\"dropdown-closed\");\n }\n});\n\nconst leftOffset = computed(() => {\n if (!triggerRect.value || !popoverRect.value) return 0;\n\n if (props.alignment === \"right\" || props.alignment === \"top right\") {\n return (\n triggerRect.value.left + triggerRect.value.width - popoverRect.value.width\n );\n }\n return triggerRect.value.left;\n});\n\nconst topOffset = computed(() => {\n if (!triggerRect.value || !popoverRect.value) return 0;\n\n if (props.alignment === \"top\" || props.alignment === \"top right\") {\n return triggerRect.value.top - popoverRect.value.height;\n }\n\n return triggerRect.value.top + window.scrollY + triggerRect.value.height;\n});\n\nconst popoverPositionStyle = computed(() => {\n if (!props.useTeleport) {\n return props.popoverCssProperties;\n }\n const teleportStyles = {\n position: \"absolute\",\n left: `${leftOffset.value}px`,\n top: `${topOffset.value}px`,\n zIndex: 10,\n } as CSSProperties;\n return {\n ...teleportStyles,\n ...props.popoverCssProperties,\n };\n});\n</script>\n<template>\n <div\n class=\"pv-relative\"\n v-on-click-outside=\"closeDropdown\"\n style=\"width: fit-content\"\n >\n <button\n ref=\"triggerRef\"\n :class=\"{ 'pv-select': !icon, 'pv-icon-button': icon }\"\n style=\"width: auto\"\n @click=\"handleClickTrigger\"\n :disabled=\"disabled\"\n >\n <slot name=\"trigger\">Open</slot>\n </button>\n <Teleport :to=\"teleportLocation\" :disabled=\"!useTeleport\">\n <PvPopover\n ref=\"popoverRef\"\n :class=\"popoverClasses\"\n :css-custom-properties=\"popoverPositionStyle\"\n :alignment=\"alignment\"\n :isList=\"isList\"\n :isSortable=\"isSortable\"\n @list-order-updated=\"$emit('list-order-updated', $event)\"\n ><slot\n ><span v-if=\"isLoading\" class=\"pv-shimmer\">Loading...</span></slot\n ></PvPopover\n >\n </Teleport>\n </div>\n</template>\n\n<style scoped>\n.pv-icon-button {\n background-color: transparent;\n border: none;\n}\n.pv-icon-button:hover {\n cursor: pointer;\n color: #176f6f;\n}\n.pv-select {\n padding-top: 4px;\n padding-bottom: 4px;\n}\n</style>\n","<script lang=\"ts\">\nimport { CSSProperties } from \"vue\";\n\nexport interface PvDropdownProps {\n defaultOpen?: boolean;\n popoverCssProperties?: CSSProperties;\n alignment?: \"top\" | \"right\" | \"top right\" | undefined;\n isList?: boolean;\n isSortable?: boolean;\n icon?: boolean;\n disabled?: boolean;\n isLoading?: boolean;\n useTeleport?: boolean;\n teleportLocation?: string;\n}\n</script>\n<script setup lang=\"ts\">\nimport { computed, ref, watch, nextTick } from \"vue\";\nimport PvPopover from \"../PvPopover/PvPopover.vue\";\nimport { vOnClickOutside } from \"@vueuse/components\";\nconst props = withDefaults(defineProps<PvDropdownProps>(), {\n alignment: undefined,\n isList: false,\n defaultOpen: false,\n disabled: false,\n isLoading: false,\n useTeleport: false,\n teleportLocation: \"body\",\n});\nconst emits = defineEmits<{\n (e: \"dropdown-open\"): void;\n (e: \"dropdown-closed\"): void;\n (e: \"list-order-updated\", value: string[]): void;\n}>();\nconst open = ref<boolean>(props.defaultOpen);\n\nconst triggerRef = ref<HTMLElement | null>(null);\nconst popoverRef = ref<{ popoverRoot: HTMLElement | null } | null>(null);\nconst triggerRect = ref<DOMRect | null>(null);\nconst popoverRect = ref<DOMRect | null>(null);\n\nconst updateRects = () => {\n if (triggerRef.value) {\n triggerRect.value = triggerRef.value.getBoundingClientRect();\n }\n if (popoverRef.value?.popoverRoot) {\n popoverRect.value = popoverRef.value.popoverRoot.getBoundingClientRect();\n }\n};\n\nconst popoverClasses = computed(() => {\n const classes = {\n \"pv-hide\": !open.value,\n };\n return classes;\n});\nconst handleClickTrigger = (e: MouseEvent) => {\n open.value = !open.value;\n};\n\nconst closeDropdown = () => {\n open.value = false;\n};\n\ndefineExpose({\n closeDropdown,\n});\n\nwatch(open, (newValue) => {\n if (newValue) {\n nextTick(() => {\n updateRects();\n emits(\"dropdown-open\");\n });\n } else {\n emits(\"dropdown-closed\");\n }\n});\n\nconst leftOffset = computed(() => {\n if (!triggerRect.value || !popoverRect.value) return 0;\n\n if (props.alignment === \"right\" || props.alignment === \"top right\") {\n return (\n triggerRect.value.left + triggerRect.value.width - popoverRect.value.width\n );\n }\n return triggerRect.value.left;\n});\n\nconst topOffset = computed(() => {\n if (!triggerRect.value || !popoverRect.value) return 0;\n\n if (props.alignment === \"top\" || props.alignment === \"top right\") {\n return triggerRect.value.top - popoverRect.value.height;\n }\n\n return triggerRect.value.top + window.scrollY + triggerRect.value.height;\n});\n\nconst popoverPositionStyle = computed(() => {\n if (!props.useTeleport) {\n return props.popoverCssProperties;\n }\n const teleportStyles = {\n position: \"absolute\",\n left: `${leftOffset.value}px`,\n top: `${topOffset.value}px`,\n zIndex: 10,\n } as CSSProperties;\n return {\n ...teleportStyles,\n ...props.popoverCssProperties,\n };\n});\n</script>\n<template>\n <div\n class=\"pv-relative\"\n v-on-click-outside=\"closeDropdown\"\n style=\"width: fit-content\"\n >\n <button\n ref=\"triggerRef\"\n :class=\"{ 'pv-select': !icon, 'pv-icon-button': icon }\"\n style=\"width: auto\"\n @click=\"handleClickTrigger\"\n :disabled=\"disabled\"\n >\n <slot name=\"trigger\">Open</slot>\n </button>\n <Teleport :to=\"teleportLocation\" :disabled=\"!useTeleport\">\n <PvPopover\n ref=\"popoverRef\"\n :class=\"popoverClasses\"\n :css-custom-properties=\"popoverPositionStyle\"\n :alignment=\"alignment\"\n :isList=\"isList\"\n :isSortable=\"isSortable\"\n @list-order-updated=\"$emit('list-order-updated', $event)\"\n ><slot\n ><span v-if=\"isLoading\" class=\"pv-shimmer\">Loading...</span></slot\n ></PvPopover\n >\n </Teleport>\n </div>\n</template>\n\n<style scoped>\n.pv-icon-button {\n background-color: transparent;\n border: none;\n}\n.pv-icon-button:hover {\n cursor: pointer;\n color: #176f6f;\n}\n.pv-select {\n padding-top: 4px;\n padding-bottom: 4px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport PvPopover from \"../PvPopover/PvPopover.vue\";\nimport { CSSProperties } from \"vue\";\n\nwithDefaults(\n defineProps<{\n /** Alignment of the popover dropdown relative to its trigger. */\n alignment?: \"top\" | \"right\" | \"top right\" | undefined;\n /** Custom CSS properties applied to the popover container. */\n cssCustomProperties?: CSSProperties;\n }>(),\n {\n alignment: undefined,\n cssCustomProperties: () => ({}),\n },\n);\n</script>\n\n<template>\n <nav class=\"pv-popover-menu\">\n <slot name=\"trigger\"></slot>\n <PvPopover is-list :alignment=\"alignment\" :css-custom-properties=\"cssCustomProperties\">\n <slot name=\"content\"></slot>\n </PvPopover>\n </nav>\n</template>\n","<script setup lang=\"ts\">\nimport PvPopover from \"../PvPopover/PvPopover.vue\";\nimport { CSSProperties } from \"vue\";\n\nwithDefaults(\n defineProps<{\n /** Alignment of the popover dropdown relative to its trigger. */\n alignment?: \"top\" | \"right\" | \"top right\" | undefined;\n /** Custom CSS properties applied to the popover container. */\n cssCustomProperties?: CSSProperties;\n }>(),\n {\n alignment: undefined,\n cssCustomProperties: () => ({}),\n },\n);\n</script>\n\n<template>\n <nav class=\"pv-popover-menu\">\n <slot name=\"trigger\"></slot>\n <PvPopover is-list :alignment=\"alignment\" :css-custom-properties=\"cssCustomProperties\">\n <slot name=\"content\"></slot>\n </PvPopover>\n </nav>\n</template>\n","/**\n * Custom positioning reference element.\n * @see https://floating-ui.com/docs/virtual-elements\n */\n\nconst sides = ['top', 'right', 'bottom', 'left'];\nconst alignments = ['start', 'end'];\nconst placements = /*#__PURE__*/sides.reduce((acc, side) => acc.concat(side, side + \"-\" + alignments[0], side + \"-\" + alignments[1]), []);\nconst min = Math.min;\nconst max = Math.max;\nconst round = Math.round;\nconst floor = Math.floor;\nconst createCoords = v => ({\n x: v,\n y: v\n});\nconst oppositeSideMap = {\n left: 'right',\n right: 'left',\n bottom: 'top',\n top: 'bottom'\n};\nfunction clamp(start, value, end) {\n return max(start, min(value, end));\n}\nfunction evaluate(value, param) {\n return typeof value === 'function' ? value(param) : value;\n}\nfunction getSide(placement) {\n return placement.split('-')[0];\n}\nfunction getAlignment(placement) {\n return placement.split('-')[1];\n}\nfunction getOppositeAxis(axis) {\n return axis === 'x' ? 'y' : 'x';\n}\nfunction getAxisLength(axis) {\n return axis === 'y' ? 'height' : 'width';\n}\nfunction getSideAxis(placement) {\n const firstChar = placement[0];\n return firstChar === 't' || firstChar === 'b' ? 'y' : 'x';\n}\nfunction getAlignmentAxis(placement) {\n return getOppositeAxis(getSideAxis(placement));\n}\nfunction getAlignmentSides(placement, rects, rtl) {\n if (rtl === void 0) {\n rtl = false;\n }\n const alignment = getAlignment(placement);\n const alignmentAxis = getAlignmentAxis(placement);\n const length = getAxisLength(alignmentAxis);\n let mainAlignmentSide = alignmentAxis === 'x' ? alignment === (rtl ? 'end' : 'start') ? 'right' : 'left' : alignment === 'start' ? 'bottom' : 'top';\n if (rects.reference[length] > rects.floating[length]) {\n mainAlignmentSide = getOppositePlacement(mainAlignmentSide);\n }\n return [mainAlignmentSide, getOppositePlacement(mainAlignmentSide)];\n}\nfunction getExpandedPlacements(placement) {\n const oppositePlacement = getOppositePlacement(placement);\n return [getOppositeAlignmentPlacement(placement), oppositePlacement, getOppositeAlignmentPlacement(oppositePlacement)];\n}\nfunction getOppositeAlignmentPlacement(placement) {\n return placement.includes('start') ? placement.replace('start', 'end') : placement.replace('end', 'start');\n}\nconst lrPlacement = ['left', 'right'];\nconst rlPlacement = ['right', 'left'];\nconst tbPlacement = ['top', 'bottom'];\nconst btPlacement = ['bottom', 'top'];\nfunction getSideList(side, isStart, rtl) {\n switch (side) {\n case 'top':\n case 'bottom':\n if (rtl) return isStart ? rlPlacement : lrPlacement;\n return isStart ? lrPlacement : rlPlacement;\n case 'left':\n case 'right':\n return isStart ? tbPlacement : btPlacement;\n default:\n return [];\n }\n}\nfunction getOppositeAxisPlacements(placement, flipAlignment, direction, rtl) {\n const alignment = getAlignment(placement);\n let list = getSideList(getSide(placement), direction === 'start', rtl);\n if (alignment) {\n list = list.map(side => side + \"-\" + alignment);\n if (flipAlignment) {\n list = list.concat(list.map(getOppositeAlignmentPlacement));\n }\n }\n return list;\n}\nfunction getOppositePlacement(placement) {\n const side = getSide(placement);\n return oppositeSideMap[side] + placement.slice(side.length);\n}\nfunction expandPaddingObject(padding) {\n return {\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n ...padding\n };\n}\nfunction getPaddingObject(padding) {\n return typeof padding !== 'number' ? expandPaddingObject(padding) : {\n top: padding,\n right: padding,\n bottom: padding,\n left: padding\n };\n}\nfunction rectToClientRect(rect) {\n const {\n x,\n y,\n width,\n height\n } = rect;\n return {\n width,\n height,\n top: y,\n left: x,\n right: x + width,\n bottom: y + height,\n x,\n y\n };\n}\n\nexport { alignments, clamp, createCoords, evaluate, expandPaddingObject, floor, getAlignment, getAlignmentAxis, getAlignmentSides, getAxisLength, getExpandedPlacements, getOppositeAlignmentPlacement, getOppositeAxis, getOppositeAxisPlacements, getOppositePlacement, getPaddingObject, getSide, getSideAxis, max, min, placements, rectToClientRect, round, sides };\n","import { getSideAxis, getAlignmentAxis, getAxisLength, getSide, getAlignment, evaluate, getPaddingObject, rectToClientRect, min, clamp, placements, getAlignmentSides, getOppositeAlignmentPlacement, getOppositePlacement, getExpandedPlacements, getOppositeAxisPlacements, sides, max, getOppositeAxis } from '@floating-ui/utils';\nexport { rectToClientRect } from '@floating-ui/utils';\n\nfunction computeCoordsFromPlacement(_ref, placement, rtl) {\n let {\n reference,\n floating\n } = _ref;\n const sideAxis = getSideAxis(placement);\n const alignmentAxis = getAlignmentAxis(placement);\n const alignLength = getAxisLength(alignmentAxis);\n const side = getSide(placement);\n const isVertical = sideAxis === 'y';\n const commonX = reference.x + reference.width / 2 - floating.width / 2;\n const commonY = reference.y + reference.height / 2 - floating.height / 2;\n const commonAlign = reference[alignLength] / 2 - floating[alignLength] / 2;\n let coords;\n switch (side) {\n case 'top':\n coords = {\n x: commonX,\n y: reference.y - floating.height\n };\n break;\n case 'bottom':\n coords = {\n x: commonX,\n y: reference.y + reference.height\n };\n break;\n case 'right':\n coords = {\n x: reference.x + reference.width,\n y: commonY\n };\n break;\n case 'left':\n coords = {\n x: reference.x - floating.width,\n y: commonY\n };\n break;\n default:\n coords = {\n x: reference.x,\n y: reference.y\n };\n }\n switch (getAlignment(placement)) {\n case 'start':\n coords[alignmentAxis] -= commonAlign * (rtl && isVertical ? -1 : 1);\n break;\n case 'end':\n coords[alignmentAxis] += commonAlign * (rtl && isVertical ? -1 : 1);\n break;\n }\n return coords;\n}\n\n/**\n * Resolves with an object of overflow side offsets that determine how much the\n * element is overflowing a given clipping boundary on each side.\n * - positive = overflowing the boundary by that number of pixels\n * - negative = how many pixels left before it will overflow\n * - 0 = lies flush with the boundary\n * @see https://floating-ui.com/docs/detectOverflow\n */\nasync function detectOverflow(state, options) {\n var _await$platform$isEle;\n if (options === void 0) {\n options = {};\n }\n const {\n x,\n y,\n platform,\n rects,\n elements,\n strategy\n } = state;\n const {\n boundary = 'clippingAncestors',\n rootBoundary = 'viewport',\n elementContext = 'floating',\n altBoundary = false,\n padding = 0\n } = evaluate(options, state);\n const paddingObject = getPaddingObject(padding);\n const altContext = elementContext === 'floating' ? 'reference' : 'floating';\n const element = elements[altBoundary ? altContext : elementContext];\n const clippingClientRect = rectToClientRect(await platform.getClippingRect({\n element: ((_await$platform$isEle = await (platform.isElement == null ? void 0 : platform.isElement(element))) != null ? _await$platform$isEle : true) ? element : element.contextElement || (await (platform.getDocumentElement == null ? void 0 : platform.getDocumentElement(elements.floating))),\n boundary,\n rootBoundary,\n strategy\n }));\n const rect = elementContext === 'floating' ? {\n x,\n y,\n width: rects.floating.width,\n height: rects.floating.height\n } : rects.reference;\n const offsetParent = await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(elements.floating));\n const offsetScale = (await (platform.isElement == null ? void 0 : platform.isElement(offsetParent))) ? (await (platform.getScale == null ? void 0 : platform.getScale(offsetParent))) || {\n x: 1,\n y: 1\n } : {\n x: 1,\n y: 1\n };\n const elementClientRect = rectToClientRect(platform.convertOffsetParentRelativeRectToViewportRelativeRect ? await platform.convertOffsetParentRelativeRectToViewportRelativeRect({\n elements,\n rect,\n offsetParent,\n strategy\n }) : rect);\n return {\n top: (clippingClientRect.top - elementClientRect.top + paddingObject.top) / offsetScale.y,\n bottom: (elementClientRect.bottom - clippingClientRect.bottom + paddingObject.bottom) / offsetScale.y,\n left: (clippingClientRect.left - elementClientRect.left + paddingObject.left) / offsetScale.x,\n right: (elementClientRect.right - clippingClientRect.right + paddingObject.right) / offsetScale.x\n };\n}\n\n// Maximum number of resets that can occur before bailing to avoid infinite reset loops.\nconst MAX_RESET_COUNT = 50;\n\n/**\n * Computes the `x` and `y` coordinates that will place the floating element\n * next to a given reference element.\n *\n * This export does not have any `platform` interface logic. You will need to\n * write one for the platform you are using Floating UI with.\n */\nconst computePosition = async (reference, floating, config) => {\n const {\n placement = 'bottom',\n strategy = 'absolute',\n middleware = [],\n platform\n } = config;\n const platformWithDetectOverflow = platform.detectOverflow ? platform : {\n ...platform,\n detectOverflow\n };\n const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(floating));\n let rects = await platform.getElementRects({\n reference,\n floating,\n strategy\n });\n let {\n x,\n y\n } = computeCoordsFromPlacement(rects, placement, rtl);\n let statefulPlacement = placement;\n let resetCount = 0;\n const middlewareData = {};\n for (let i = 0; i < middleware.length; i++) {\n const currentMiddleware = middleware[i];\n if (!currentMiddleware) {\n continue;\n }\n const {\n name,\n fn\n } = currentMiddleware;\n const {\n x: nextX,\n y: nextY,\n data,\n reset\n } = await fn({\n x,\n y,\n initialPlacement: placement,\n placement: statefulPlacement,\n strategy,\n middlewareData,\n rects,\n platform: platformWithDetectOverflow,\n elements: {\n reference,\n floating\n }\n });\n x = nextX != null ? nextX : x;\n y = nextY != null ? nextY : y;\n middlewareData[name] = {\n ...middlewareData[name],\n ...data\n };\n if (reset && resetCount < MAX_RESET_COUNT) {\n resetCount++;\n if (typeof reset === 'object') {\n if (reset.placement) {\n statefulPlacement = reset.placement;\n }\n if (reset.rects) {\n rects = reset.rects === true ? await platform.getElementRects({\n reference,\n floating,\n strategy\n }) : reset.rects;\n }\n ({\n x,\n y\n } = computeCoordsFromPlacement(rects, statefulPlacement, rtl));\n }\n i = -1;\n }\n }\n return {\n x,\n y,\n placement: statefulPlacement,\n strategy,\n middlewareData\n };\n};\n\n/**\n * Provides data to position an inner element of the floating element so that it\n * appears centered to the reference element.\n * @see https://floating-ui.com/docs/arrow\n */\nconst arrow = options => ({\n name: 'arrow',\n options,\n async fn(state) {\n const {\n x,\n y,\n placement,\n rects,\n platform,\n elements,\n middlewareData\n } = state;\n // Since `element` is required, we don't Partial<> the type.\n const {\n element,\n padding = 0\n } = evaluate(options, state) || {};\n if (element == null) {\n return {};\n }\n const paddingObject = getPaddingObject(padding);\n const coords = {\n x,\n y\n };\n const axis = getAlignmentAxis(placement);\n const length = getAxisLength(axis);\n const arrowDimensions = await platform.getDimensions(element);\n const isYAxis = axis === 'y';\n const minProp = isYAxis ? 'top' : 'left';\n const maxProp = isYAxis ? 'bottom' : 'right';\n const clientProp = isYAxis ? 'clientHeight' : 'clientWidth';\n const endDiff = rects.reference[length] + rects.reference[axis] - coords[axis] - rects.floating[length];\n const startDiff = coords[axis] - rects.reference[axis];\n const arrowOffsetParent = await (platform.getOffsetParent == null ? void 0 : platform.getOffsetParent(element));\n let clientSize = arrowOffsetParent ? arrowOffsetParent[clientProp] : 0;\n\n // DOM platform can return `window` as the `offsetParent`.\n if (!clientSize || !(await (platform.isElement == null ? void 0 : platform.isElement(arrowOffsetParent)))) {\n clientSize = elements.floating[clientProp] || rects.floating[length];\n }\n const centerToReference = endDiff / 2 - startDiff / 2;\n\n // If the padding is large enough that it causes the arrow to no longer be\n // centered, modify the padding so that it is centered.\n const largestPossiblePadding = clientSize / 2 - arrowDimensions[length] / 2 - 1;\n const minPadding = min(paddingObject[minProp], largestPossiblePadding);\n const maxPadding = min(paddingObject[maxProp], largestPossiblePadding);\n\n // Make sure the arrow doesn't overflow the floating element if the center\n // point is outside the floating element's bounds.\n const min$1 = minPadding;\n const max = clientSize - arrowDimensions[length] - maxPadding;\n const center = clientSize / 2 - arrowDimensions[length] / 2 + centerToReference;\n const offset = clamp(min$1, center, max);\n\n // If the reference is small enough that the arrow's padding causes it to\n // to point to nothing for an aligned placement, adjust the offset of the\n // floating element itself. To ensure `shift()` continues to take action,\n // a single reset is performed when this is true.\n const shouldAddOffset = !middlewareData.arrow && getAlignment(placement) != null && center !== offset && rects.reference[length] / 2 - (center < min$1 ? minPadding : maxPadding) - arrowDimensions[length] / 2 < 0;\n const alignmentOffset = shouldAddOffset ? center < min$1 ? center - min$1 : center - max : 0;\n return {\n [axis]: coords[axis] + alignmentOffset,\n data: {\n [axis]: offset,\n centerOffset: center - offset - alignmentOffset,\n ...(shouldAddOffset && {\n alignmentOffset\n })\n },\n reset: shouldAddOffset\n };\n }\n});\n\nfunction getPlacementList(alignment, autoAlignment, allowedPlacements) {\n const allowedPlacementsSortedByAlignment = alignment ? [...allowedPlacements.filter(placement => getAlignment(placement) === alignment), ...allowedPlacements.filter(placement => getAlignment(placement) !== alignment)] : allowedPlacements.filter(placement => getSide(placement) === placement);\n return allowedPlacementsSortedByAlignment.filter(placement => {\n if (alignment) {\n return getAlignment(placement) === alignment || (autoAlignment ? getOppositeAlignmentPlacement(placement) !== placement : false);\n }\n return true;\n });\n}\n/**\n * Optimizes the visibility of the floating element by choosing the placement\n * that has the most space available automatically, without needing to specify a\n * preferred placement. Alternative to `flip`.\n * @see https://floating-ui.com/docs/autoPlacement\n */\nconst autoPlacement = function (options) {\n if (options === void 0) {\n options = {};\n }\n return {\n name: 'autoPlacement',\n options,\n async fn(state) {\n var _middlewareData$autoP, _middlewareData$autoP2, _placementsThatFitOnE;\n const {\n rects,\n middlewareData,\n placement,\n platform,\n elements\n } = state;\n const {\n crossAxis = false,\n alignment,\n allowedPlacements = placements,\n autoAlignment = true,\n ...detectOverflowOptions\n } = evaluate(options, state);\n const placements$1 = alignment !== undefined || allowedPlacements === placements ? getPlacementList(alignment || null, autoAlignment, allowedPlacements) : allowedPlacements;\n const overflow = await platform.detectOverflow(state, detectOverflowOptions);\n const currentIndex = ((_middlewareData$autoP = middlewareData.autoPlacement) == null ? void 0 : _middlewareData$autoP.index) || 0;\n const currentPlacement = placements$1[currentIndex];\n if (currentPlacement == null) {\n return {};\n }\n const alignmentSides = getAlignmentSides(currentPlacement, rects, await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating)));\n\n // Make `computeCoords` start from the right place.\n if (placement !== currentPlacement) {\n return {\n reset: {\n placement: placements$1[0]\n }\n };\n }\n const currentOverflows = [overflow[getSide(currentPlacement)], overflow[alignmentSides[0]], overflow[alignmentSides[1]]];\n const allOverflows = [...(((_middlewareData$autoP2 = middlewareData.autoPlacement) == null ? void 0 : _middlewareData$autoP2.overflows) || []), {\n placement: currentPlacement,\n overflows: currentOverflows\n }];\n const nextPlacement = placements$1[currentIndex + 1];\n\n // There are more placements to check.\n if (nextPlacement) {\n return {\n data: {\n index: currentIndex + 1,\n overflows: allOverflows\n },\n reset: {\n placement: nextPlacement\n }\n };\n }\n const placementsSortedByMostSpace = allOverflows.map(d => {\n const alignment = getAlignment(d.placement);\n return [d.placement, alignment && crossAxis ?\n // Check along the mainAxis and main crossAxis side.\n d.overflows.slice(0, 2).reduce((acc, v) => acc + v, 0) :\n // Check only the mainAxis.\n d.overflows[0], d.overflows];\n }).sort((a, b) => a[1] - b[1]);\n const placementsThatFitOnEachSide = placementsSortedByMostSpace.filter(d => d[2].slice(0,\n // Aligned placements should not check their opposite crossAxis\n // side.\n getAlignment(d[0]) ? 2 : 3).every(v => v <= 0));\n const resetPlacement = ((_placementsThatFitOnE = placementsThatFitOnEachSide[0]) == null ? void 0 : _placementsThatFitOnE[0]) || placementsSortedByMostSpace[0][0];\n if (resetPlacement !== placement) {\n return {\n data: {\n index: currentIndex + 1,\n overflows: allOverflows\n },\n reset: {\n placement: resetPlacement\n }\n };\n }\n return {};\n }\n };\n};\n\n/**\n * Optimizes the visibility of the floating element by flipping the `placement`\n * in order to keep it in view when the preferred placement(s) will overflow the\n * clipping boundary. Alternative to `autoPlacement`.\n * @see https://floating-ui.com/docs/flip\n */\nconst flip = function (options) {\n if (options === void 0) {\n options = {};\n }\n return {\n name: 'flip',\n options,\n async fn(state) {\n var _middlewareData$arrow, _middlewareData$flip;\n const {\n placement,\n middlewareData,\n rects,\n initialPlacement,\n platform,\n elements\n } = state;\n const {\n mainAxis: checkMainAxis = true,\n crossAxis: checkCrossAxis = true,\n fallbackPlacements: specifiedFallbackPlacements,\n fallbackStrategy = 'bestFit',\n fallbackAxisSideDirection = 'none',\n flipAlignment = true,\n ...detectOverflowOptions\n } = evaluate(options, state);\n\n // If a reset by the arrow was caused due to an alignment offset being\n // added, we should skip any logic now since `flip()` has already done its\n // work.\n // https://github.com/floating-ui/floating-ui/issues/2549#issuecomment-1719601643\n if ((_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {\n return {};\n }\n const side = getSide(placement);\n const initialSideAxis = getSideAxis(initialPlacement);\n const isBasePlacement = getSide(initialPlacement) === initialPlacement;\n const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating));\n const fallbackPlacements = specifiedFallbackPlacements || (isBasePlacement || !flipAlignment ? [getOppositePlacement(initialPlacement)] : getExpandedPlacements(initialPlacement));\n const hasFallbackAxisSideDirection = fallbackAxisSideDirection !== 'none';\n if (!specifiedFallbackPlacements && hasFallbackAxisSideDirection) {\n fallbackPlacements.push(...getOppositeAxisPlacements(initialPlacement, flipAlignment, fallbackAxisSideDirection, rtl));\n }\n const placements = [initialPlacement, ...fallbackPlacements];\n const overflow = await platform.detectOverflow(state, detectOverflowOptions);\n const overflows = [];\n let overflowsData = ((_middlewareData$flip = middlewareData.flip) == null ? void 0 : _middlewareData$flip.overflows) || [];\n if (checkMainAxis) {\n overflows.push(overflow[side]);\n }\n if (checkCrossAxis) {\n const sides = getAlignmentSides(placement, rects, rtl);\n overflows.push(overflow[sides[0]], overflow[sides[1]]);\n }\n overflowsData = [...overflowsData, {\n placement,\n overflows\n }];\n\n // One or more sides is overflowing.\n if (!overflows.every(side => side <= 0)) {\n var _middlewareData$flip2, _overflowsData$filter;\n const nextIndex = (((_middlewareData$flip2 = middlewareData.flip) == null ? void 0 : _middlewareData$flip2.index) || 0) + 1;\n const nextPlacement = placements[nextIndex];\n if (nextPlacement) {\n const ignoreCrossAxisOverflow = checkCrossAxis === 'alignment' ? initialSideAxis !== getSideAxis(nextPlacement) : false;\n if (!ignoreCrossAxisOverflow ||\n // We leave the current main axis only if every placement on that axis\n // overflows the main axis.\n overflowsData.every(d => getSideAxis(d.placement) === initialSideAxis ? d.overflows[0] > 0 : true)) {\n // Try next placement and re-run the lifecycle.\n return {\n data: {\n index: nextIndex,\n overflows: overflowsData\n },\n reset: {\n placement: nextPlacement\n }\n };\n }\n }\n\n // First, find the candidates that fit on the mainAxis side of overflow,\n // then find the placement that fits the best on the main crossAxis side.\n let resetPlacement = (_overflowsData$filter = overflowsData.filter(d => d.overflows[0] <= 0).sort((a, b) => a.overflows[1] - b.overflows[1])[0]) == null ? void 0 : _overflowsData$filter.placement;\n\n // Otherwise fallback.\n if (!resetPlacement) {\n switch (fallbackStrategy) {\n case 'bestFit':\n {\n var _overflowsData$filter2;\n const placement = (_overflowsData$filter2 = overflowsData.filter(d => {\n if (hasFallbackAxisSideDirection) {\n const currentSideAxis = getSideAxis(d.placement);\n return currentSideAxis === initialSideAxis ||\n // Create a bias to the `y` side axis due to horizontal\n // reading directions favoring greater width.\n currentSideAxis === 'y';\n }\n return true;\n }).map(d => [d.placement, d.overflows.filter(overflow => overflow > 0).reduce((acc, overflow) => acc + overflow, 0)]).sort((a, b) => a[1] - b[1])[0]) == null ? void 0 : _overflowsData$filter2[0];\n if (placement) {\n resetPlacement = placement;\n }\n break;\n }\n case 'initialPlacement':\n resetPlacement = initialPlacement;\n break;\n }\n }\n if (placement !== resetPlacement) {\n return {\n reset: {\n placement: resetPlacement\n }\n };\n }\n }\n return {};\n }\n };\n};\n\nfunction getSideOffsets(overflow, rect) {\n return {\n top: overflow.top - rect.height,\n right: overflow.right - rect.width,\n bottom: overflow.bottom - rect.height,\n left: overflow.left - rect.width\n };\n}\nfunction isAnySideFullyClipped(overflow) {\n return sides.some(side => overflow[side] >= 0);\n}\n/**\n * Provides data to hide the floating element in applicable situations, such as\n * when it is not in the same clipping context as the reference element.\n * @see https://floating-ui.com/docs/hide\n */\nconst hide = function (options) {\n if (options === void 0) {\n options = {};\n }\n return {\n name: 'hide',\n options,\n async fn(state) {\n const {\n rects,\n platform\n } = state;\n const {\n strategy = 'referenceHidden',\n ...detectOverflowOptions\n } = evaluate(options, state);\n switch (strategy) {\n case 'referenceHidden':\n {\n const overflow = await platform.detectOverflow(state, {\n ...detectOverflowOptions,\n elementContext: 'reference'\n });\n const offsets = getSideOffsets(overflow, rects.reference);\n return {\n data: {\n referenceHiddenOffsets: offsets,\n referenceHidden: isAnySideFullyClipped(offsets)\n }\n };\n }\n case 'escaped':\n {\n const overflow = await platform.detectOverflow(state, {\n ...detectOverflowOptions,\n altBoundary: true\n });\n const offsets = getSideOffsets(overflow, rects.floating);\n return {\n data: {\n escapedOffsets: offsets,\n escaped: isAnySideFullyClipped(offsets)\n }\n };\n }\n default:\n {\n return {};\n }\n }\n }\n };\n};\n\nfunction getBoundingRect(rects) {\n const minX = min(...rects.map(rect => rect.left));\n const minY = min(...rects.map(rect => rect.top));\n const maxX = max(...rects.map(rect => rect.right));\n const maxY = max(...rects.map(rect => rect.bottom));\n return {\n x: minX,\n y: minY,\n width: maxX - minX,\n height: maxY - minY\n };\n}\nfunction getRectsByLine(rects) {\n const sortedRects = rects.slice().sort((a, b) => a.y - b.y);\n const groups = [];\n let prevRect = null;\n for (let i = 0; i < sortedRects.length; i++) {\n const rect = sortedRects[i];\n if (!prevRect || rect.y - prevRect.y > prevRect.height / 2) {\n groups.push([rect]);\n } else {\n groups[groups.length - 1].push(rect);\n }\n prevRect = rect;\n }\n return groups.map(rect => rectToClientRect(getBoundingRect(rect)));\n}\n/**\n * Provides improved positioning for inline reference elements that can span\n * over multiple lines, such as hyperlinks or range selections.\n * @see https://floating-ui.com/docs/inline\n */\nconst inline = function (options) {\n if (options === void 0) {\n options = {};\n }\n return {\n name: 'inline',\n options,\n async fn(state) {\n const {\n placement,\n elements,\n rects,\n platform,\n strategy\n } = state;\n // A MouseEvent's client{X,Y} coords can be up to 2 pixels off a\n // ClientRect's bounds, despite the event listener being triggered. A\n // padding of 2 seems to handle this issue.\n const {\n padding = 2,\n x,\n y\n } = evaluate(options, state);\n const nativeClientRects = Array.from((await (platform.getClientRects == null ? void 0 : platform.getClientRects(elements.reference))) || []);\n const clientRects = getRectsByLine(nativeClientRects);\n const fallback = rectToClientRect(getBoundingRect(nativeClientRects));\n const paddingObject = getPaddingObject(padding);\n function getBoundingClientRect() {\n // There are two rects and they are disjoined.\n if (clientRects.length === 2 && clientRects[0].left > clientRects[1].right && x != null && y != null) {\n // Find the first rect in which the point is fully inside.\n return clientRects.find(rect => x > rect.left - paddingObject.left && x < rect.right + paddingObject.right && y > rect.top - paddingObject.top && y < rect.bottom + paddingObject.bottom) || fallback;\n }\n\n // There are 2 or more connected rects.\n if (clientRects.length >= 2) {\n if (getSideAxis(placement) === 'y') {\n const firstRect = clientRects[0];\n const lastRect = clientRects[clientRects.length - 1];\n const isTop = getSide(placement) === 'top';\n const top = firstRect.top;\n const bottom = lastRect.bottom;\n const left = isTop ? firstRect.left : lastRect.left;\n const right = isTop ? firstRect.right : lastRect.right;\n const width = right - left;\n const height = bottom - top;\n return {\n top,\n bottom,\n left,\n right,\n width,\n height,\n x: left,\n y: top\n };\n }\n const isLeftSide = getSide(placement) === 'left';\n const maxRight = max(...clientRects.map(rect => rect.right));\n const minLeft = min(...clientRects.map(rect => rect.left));\n const measureRects = clientRects.filter(rect => isLeftSide ? rect.left === minLeft : rect.right === maxRight);\n const top = measureRects[0].top;\n const bottom = measureRects[measureRects.length - 1].bottom;\n const left = minLeft;\n const right = maxRight;\n const width = right - left;\n const height = bottom - top;\n return {\n top,\n bottom,\n left,\n right,\n width,\n height,\n x: left,\n y: top\n };\n }\n return fallback;\n }\n const resetRects = await platform.getElementRects({\n reference: {\n getBoundingClientRect\n },\n floating: elements.floating,\n strategy\n });\n if (rects.reference.x !== resetRects.reference.x || rects.reference.y !== resetRects.reference.y || rects.reference.width !== resetRects.reference.width || rects.reference.height !== resetRects.reference.height) {\n return {\n reset: {\n rects: resetRects\n }\n };\n }\n return {};\n }\n };\n};\n\nconst originSides = /*#__PURE__*/new Set(['left', 'top']);\n\n// For type backwards-compatibility, the `OffsetOptions` type was also\n// Derivable.\n\nasync function convertValueToCoords(state, options) {\n const {\n placement,\n platform,\n elements\n } = state;\n const rtl = await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating));\n const side = getSide(placement);\n const alignment = getAlignment(placement);\n const isVertical = getSideAxis(placement) === 'y';\n const mainAxisMulti = originSides.has(side) ? -1 : 1;\n const crossAxisMulti = rtl && isVertical ? -1 : 1;\n const rawValue = evaluate(options, state);\n\n // eslint-disable-next-line prefer-const\n let {\n mainAxis,\n crossAxis,\n alignmentAxis\n } = typeof rawValue === 'number' ? {\n mainAxis: rawValue,\n crossAxis: 0,\n alignmentAxis: null\n } : {\n mainAxis: rawValue.mainAxis || 0,\n crossAxis: rawValue.crossAxis || 0,\n alignmentAxis: rawValue.alignmentAxis\n };\n if (alignment && typeof alignmentAxis === 'number') {\n crossAxis = alignment === 'end' ? alignmentAxis * -1 : alignmentAxis;\n }\n return isVertical ? {\n x: crossAxis * crossAxisMulti,\n y: mainAxis * mainAxisMulti\n } : {\n x: mainAxis * mainAxisMulti,\n y: crossAxis * crossAxisMulti\n };\n}\n\n/**\n * Modifies the placement by translating the floating element along the\n * specified axes.\n * A number (shorthand for `mainAxis` or distance), or an axes configuration\n * object may be passed.\n * @see https://floating-ui.com/docs/offset\n */\nconst offset = function (options) {\n if (options === void 0) {\n options = 0;\n }\n return {\n name: 'offset',\n options,\n async fn(state) {\n var _middlewareData$offse, _middlewareData$arrow;\n const {\n x,\n y,\n placement,\n middlewareData\n } = state;\n const diffCoords = await convertValueToCoords(state, options);\n\n // If the placement is the same and the arrow caused an alignment offset\n // then we don't need to change the positioning coordinates.\n if (placement === ((_middlewareData$offse = middlewareData.offset) == null ? void 0 : _middlewareData$offse.placement) && (_middlewareData$arrow = middlewareData.arrow) != null && _middlewareData$arrow.alignmentOffset) {\n return {};\n }\n return {\n x: x + diffCoords.x,\n y: y + diffCoords.y,\n data: {\n ...diffCoords,\n placement\n }\n };\n }\n };\n};\n\n/**\n * Optimizes the visibility of the floating element by shifting it in order to\n * keep it in view when it will overflow the clipping boundary.\n * @see https://floating-ui.com/docs/shift\n */\nconst shift = function (options) {\n if (options === void 0) {\n options = {};\n }\n return {\n name: 'shift',\n options,\n async fn(state) {\n const {\n x,\n y,\n placement,\n platform\n } = state;\n const {\n mainAxis: checkMainAxis = true,\n crossAxis: checkCrossAxis = false,\n limiter = {\n fn: _ref => {\n let {\n x,\n y\n } = _ref;\n return {\n x,\n y\n };\n }\n },\n ...detectOverflowOptions\n } = evaluate(options, state);\n const coords = {\n x,\n y\n };\n const overflow = await platform.detectOverflow(state, detectOverflowOptions);\n const crossAxis = getSideAxis(getSide(placement));\n const mainAxis = getOppositeAxis(crossAxis);\n let mainAxisCoord = coords[mainAxis];\n let crossAxisCoord = coords[crossAxis];\n if (checkMainAxis) {\n const minSide = mainAxis === 'y' ? 'top' : 'left';\n const maxSide = mainAxis === 'y' ? 'bottom' : 'right';\n const min = mainAxisCoord + overflow[minSide];\n const max = mainAxisCoord - overflow[maxSide];\n mainAxisCoord = clamp(min, mainAxisCoord, max);\n }\n if (checkCrossAxis) {\n const minSide = crossAxis === 'y' ? 'top' : 'left';\n const maxSide = crossAxis === 'y' ? 'bottom' : 'right';\n const min = crossAxisCoord + overflow[minSide];\n const max = crossAxisCoord - overflow[maxSide];\n crossAxisCoord = clamp(min, crossAxisCoord, max);\n }\n const limitedCoords = limiter.fn({\n ...state,\n [mainAxis]: mainAxisCoord,\n [crossAxis]: crossAxisCoord\n });\n return {\n ...limitedCoords,\n data: {\n x: limitedCoords.x - x,\n y: limitedCoords.y - y,\n enabled: {\n [mainAxis]: checkMainAxis,\n [crossAxis]: checkCrossAxis\n }\n }\n };\n }\n };\n};\n/**\n * Built-in `limiter` that will stop `shift()` at a certain point.\n */\nconst limitShift = function (options) {\n if (options === void 0) {\n options = {};\n }\n return {\n options,\n fn(state) {\n const {\n x,\n y,\n placement,\n rects,\n middlewareData\n } = state;\n const {\n offset = 0,\n mainAxis: checkMainAxis = true,\n crossAxis: checkCrossAxis = true\n } = evaluate(options, state);\n const coords = {\n x,\n y\n };\n const crossAxis = getSideAxis(placement);\n const mainAxis = getOppositeAxis(crossAxis);\n let mainAxisCoord = coords[mainAxis];\n let crossAxisCoord = coords[crossAxis];\n const rawOffset = evaluate(offset, state);\n const computedOffset = typeof rawOffset === 'number' ? {\n mainAxis: rawOffset,\n crossAxis: 0\n } : {\n mainAxis: 0,\n crossAxis: 0,\n ...rawOffset\n };\n if (checkMainAxis) {\n const len = mainAxis === 'y' ? 'height' : 'width';\n const limitMin = rects.reference[mainAxis] - rects.floating[len] + computedOffset.mainAxis;\n const limitMax = rects.reference[mainAxis] + rects.reference[len] - computedOffset.mainAxis;\n if (mainAxisCoord < limitMin) {\n mainAxisCoord = limitMin;\n } else if (mainAxisCoord > limitMax) {\n mainAxisCoord = limitMax;\n }\n }\n if (checkCrossAxis) {\n var _middlewareData$offse, _middlewareData$offse2;\n const len = mainAxis === 'y' ? 'width' : 'height';\n const isOriginSide = originSides.has(getSide(placement));\n const limitMin = rects.reference[crossAxis] - rects.floating[len] + (isOriginSide ? ((_middlewareData$offse = middlewareData.offset) == null ? void 0 : _middlewareData$offse[crossAxis]) || 0 : 0) + (isOriginSide ? 0 : computedOffset.crossAxis);\n const limitMax = rects.reference[crossAxis] + rects.reference[len] + (isOriginSide ? 0 : ((_middlewareData$offse2 = middlewareData.offset) == null ? void 0 : _middlewareData$offse2[crossAxis]) || 0) - (isOriginSide ? computedOffset.crossAxis : 0);\n if (crossAxisCoord < limitMin) {\n crossAxisCoord = limitMin;\n } else if (crossAxisCoord > limitMax) {\n crossAxisCoord = limitMax;\n }\n }\n return {\n [mainAxis]: mainAxisCoord,\n [crossAxis]: crossAxisCoord\n };\n }\n };\n};\n\n/**\n * Provides data that allows you to change the size of the floating element —\n * for instance, prevent it from overflowing the clipping boundary or match the\n * width of the reference element.\n * @see https://floating-ui.com/docs/size\n */\nconst size = function (options) {\n if (options === void 0) {\n options = {};\n }\n return {\n name: 'size',\n options,\n async fn(state) {\n var _state$middlewareData, _state$middlewareData2;\n const {\n placement,\n rects,\n platform,\n elements\n } = state;\n const {\n apply = () => {},\n ...detectOverflowOptions\n } = evaluate(options, state);\n const overflow = await platform.detectOverflow(state, detectOverflowOptions);\n const side = getSide(placement);\n const alignment = getAlignment(placement);\n const isYAxis = getSideAxis(placement) === 'y';\n const {\n width,\n height\n } = rects.floating;\n let heightSide;\n let widthSide;\n if (side === 'top' || side === 'bottom') {\n heightSide = side;\n widthSide = alignment === ((await (platform.isRTL == null ? void 0 : platform.isRTL(elements.floating))) ? 'start' : 'end') ? 'left' : 'right';\n } else {\n widthSide = side;\n heightSide = alignment === 'end' ? 'top' : 'bottom';\n }\n const maximumClippingHeight = height - overflow.top - overflow.bottom;\n const maximumClippingWidth = width - overflow.left - overflow.right;\n const overflowAvailableHeight = min(height - overflow[heightSide], maximumClippingHeight);\n const overflowAvailableWidth = min(width - overflow[widthSide], maximumClippingWidth);\n const noShift = !state.middlewareData.shift;\n let availableHeight = overflowAvailableHeight;\n let availableWidth = overflowAvailableWidth;\n if ((_state$middlewareData = state.middlewareData.shift) != null && _state$middlewareData.enabled.x) {\n availableWidth = maximumClippingWidth;\n }\n if ((_state$middlewareData2 = state.middlewareData.shift) != null && _state$middlewareData2.enabled.y) {\n availableHeight = maximumClippingHeight;\n }\n if (noShift && !alignment) {\n const xMin = max(overflow.left, 0);\n const xMax = max(overflow.right, 0);\n const yMin = max(overflow.top, 0);\n const yMax = max(overflow.bottom, 0);\n if (isYAxis) {\n availableWidth = width - 2 * (xMin !== 0 || xMax !== 0 ? xMin + xMax : max(overflow.left, overflow.right));\n } else {\n availableHeight = height - 2 * (yMin !== 0 || yMax !== 0 ? yMin + yMax : max(overflow.top, overflow.bottom));\n }\n }\n await apply({\n ...state,\n availableWidth,\n availableHeight\n });\n const nextDimensions = await platform.getDimensions(elements.floating);\n if (width !== nextDimensions.width || height !== nextDimensions.height) {\n return {\n reset: {\n rects: true\n }\n };\n }\n return {};\n }\n };\n};\n\nexport { arrow, autoPlacement, computePosition, detectOverflow, flip, hide, inline, limitShift, offset, shift, size };\n","function hasWindow() {\n return typeof window !== 'undefined';\n}\nfunction getNodeName(node) {\n if (isNode(node)) {\n return (node.nodeName || '').toLowerCase();\n }\n // Mocked nodes in testing environments may not be instances of Node. By\n // returning `#document` an infinite loop won't occur.\n // https://github.com/floating-ui/floating-ui/issues/2317\n return '#document';\n}\nfunction getWindow(node) {\n var _node$ownerDocument;\n return (node == null || (_node$ownerDocument = node.ownerDocument) == null ? void 0 : _node$ownerDocument.defaultView) || window;\n}\nfunction getDocumentElement(node) {\n var _ref;\n return (_ref = (isNode(node) ? node.ownerDocument : node.document) || window.document) == null ? void 0 : _ref.documentElement;\n}\nfunction isNode(value) {\n if (!hasWindow()) {\n return false;\n }\n return value instanceof Node || value instanceof getWindow(value).Node;\n}\nfunction isElement(value) {\n if (!hasWindow()) {\n return false;\n }\n return value instanceof Element || value instanceof getWindow(value).Element;\n}\nfunction isHTMLElement(value) {\n if (!hasWindow()) {\n return false;\n }\n return value instanceof HTMLElement || value instanceof getWindow(value).HTMLElement;\n}\nfunction isShadowRoot(value) {\n if (!hasWindow() || typeof ShadowRoot === 'undefined') {\n return false;\n }\n return value instanceof ShadowRoot || value instanceof getWindow(value).ShadowRoot;\n}\nfunction isOverflowElement(element) {\n const {\n overflow,\n overflowX,\n overflowY,\n display\n } = getComputedStyle(element);\n return /auto|scroll|overlay|hidden|clip/.test(overflow + overflowY + overflowX) && display !== 'inline' && display !== 'contents';\n}\nfunction isTableElement(element) {\n return /^(table|td|th)$/.test(getNodeName(element));\n}\nfunction isTopLayer(element) {\n try {\n if (element.matches(':popover-open')) {\n return true;\n }\n } catch (_e) {\n // no-op\n }\n try {\n return element.matches(':modal');\n } catch (_e) {\n return false;\n }\n}\nconst willChangeRe = /transform|translate|scale|rotate|perspective|filter/;\nconst containRe = /paint|layout|strict|content/;\nconst isNotNone = value => !!value && value !== 'none';\nlet isWebKitValue;\nfunction isContainingBlock(elementOrCss) {\n const css = isElement(elementOrCss) ? getComputedStyle(elementOrCss) : elementOrCss;\n\n // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block\n // https://drafts.csswg.org/css-transforms-2/#individual-transforms\n return isNotNone(css.transform) || isNotNone(css.translate) || isNotNone(css.scale) || isNotNone(css.rotate) || isNotNone(css.perspective) || !isWebKit() && (isNotNone(css.backdropFilter) || isNotNone(css.filter)) || willChangeRe.test(css.willChange || '') || containRe.test(css.contain || '');\n}\nfunction getContainingBlock(element) {\n let currentNode = getParentNode(element);\n while (isHTMLElement(currentNode) && !isLastTraversableNode(currentNode)) {\n if (isContainingBlock(currentNode)) {\n return currentNode;\n } else if (isTopLayer(currentNode)) {\n return null;\n }\n currentNode = getParentNode(currentNode);\n }\n return null;\n}\nfunction isWebKit() {\n if (isWebKitValue == null) {\n isWebKitValue = typeof CSS !== 'undefined' && CSS.supports && CSS.supports('-webkit-backdrop-filter', 'none');\n }\n return isWebKitValue;\n}\nfunction isLastTraversableNode(node) {\n return /^(html|body|#document)$/.test(getNodeName(node));\n}\nfunction getComputedStyle(element) {\n return getWindow(element).getComputedStyle(element);\n}\nfunction getNodeScroll(element) {\n if (isElement(element)) {\n return {\n scrollLeft: element.scrollLeft,\n scrollTop: element.scrollTop\n };\n }\n return {\n scrollLeft: element.scrollX,\n scrollTop: element.scrollY\n };\n}\nfunction getParentNode(node) {\n if (getNodeName(node) === 'html') {\n return node;\n }\n const result =\n // Step into the shadow DOM of the parent of a slotted node.\n node.assignedSlot ||\n // DOM Element detected.\n node.parentNode ||\n // ShadowRoot detected.\n isShadowRoot(node) && node.host ||\n // Fallback.\n getDocumentElement(node);\n return isShadowRoot(result) ? result.host : result;\n}\nfunction getNearestOverflowAncestor(node) {\n const parentNode = getParentNode(node);\n if (isLastTraversableNode(parentNode)) {\n return node.ownerDocument ? node.ownerDocument.body : node.body;\n }\n if (isHTMLElement(parentNode) && isOverflowElement(parentNode)) {\n return parentNode;\n }\n return getNearestOverflowAncestor(parentNode);\n}\nfunction getOverflowAncestors(node, list, traverseIframes) {\n var _node$ownerDocument2;\n if (list === void 0) {\n list = [];\n }\n if (traverseIframes === void 0) {\n traverseIframes = true;\n }\n const scrollableAncestor = getNearestOverflowAncestor(node);\n const isBody = scrollableAncestor === ((_node$ownerDocument2 = node.ownerDocument) == null ? void 0 : _node$ownerDocument2.body);\n const win = getWindow(scrollableAncestor);\n if (isBody) {\n const frameElement = getFrameElement(win);\n return list.concat(win, win.visualViewport || [], isOverflowElement(scrollableAncestor) ? scrollableAncestor : [], frameElement && traverseIframes ? getOverflowAncestors(frameElement) : []);\n } else {\n return list.concat(scrollableAncestor, getOverflowAncestors(scrollableAncestor, [], traverseIframes));\n }\n}\nfunction getFrameElement(win) {\n return win.parent && Object.getPrototypeOf(win.parent) ? win.frameElement : null;\n}\n\nexport { getComputedStyle, getContainingBlock, getDocumentElement, getFrameElement, getNearestOverflowAncestor, getNodeName, getNodeScroll, getOverflowAncestors, getParentNode, getWindow, isContainingBlock, isElement, isHTMLElement, isLastTraversableNode, isNode, isOverflowElement, isShadowRoot, isTableElement, isTopLayer, isWebKit };\n","import { rectToClientRect, arrow as arrow$1, autoPlacement as autoPlacement$1, detectOverflow as detectOverflow$1, flip as flip$1, hide as hide$1, inline as inline$1, limitShift as limitShift$1, offset as offset$1, shift as shift$1, size as size$1, computePosition as computePosition$1 } from '@floating-ui/core';\nimport { round, createCoords, max, min, floor } from '@floating-ui/utils';\nimport { getComputedStyle as getComputedStyle$1, isHTMLElement, isElement, getWindow, isWebKit, getFrameElement, getNodeScroll, getDocumentElement, isTopLayer, getNodeName, isOverflowElement, getOverflowAncestors, getParentNode, isLastTraversableNode, isContainingBlock, isTableElement, getContainingBlock } from '@floating-ui/utils/dom';\nexport { getOverflowAncestors } from '@floating-ui/utils/dom';\n\nfunction getCssDimensions(element) {\n const css = getComputedStyle$1(element);\n // In testing environments, the `width` and `height` properties are empty\n // strings for SVG elements, returning NaN. Fallback to `0` in this case.\n let width = parseFloat(css.width) || 0;\n let height = parseFloat(css.height) || 0;\n const hasOffset = isHTMLElement(element);\n const offsetWidth = hasOffset ? element.offsetWidth : width;\n const offsetHeight = hasOffset ? element.offsetHeight : height;\n const shouldFallback = round(width) !== offsetWidth || round(height) !== offsetHeight;\n if (shouldFallback) {\n width = offsetWidth;\n height = offsetHeight;\n }\n return {\n width,\n height,\n $: shouldFallback\n };\n}\n\nfunction unwrapElement(element) {\n return !isElement(element) ? element.contextElement : element;\n}\n\nfunction getScale(element) {\n const domElement = unwrapElement(element);\n if (!isHTMLElement(domElement)) {\n return createCoords(1);\n }\n const rect = domElement.getBoundingClientRect();\n const {\n width,\n height,\n $\n } = getCssDimensions(domElement);\n let x = ($ ? round(rect.width) : rect.width) / width;\n let y = ($ ? round(rect.height) : rect.height) / height;\n\n // 0, NaN, or Infinity should always fallback to 1.\n\n if (!x || !Number.isFinite(x)) {\n x = 1;\n }\n if (!y || !Number.isFinite(y)) {\n y = 1;\n }\n return {\n x,\n y\n };\n}\n\nconst noOffsets = /*#__PURE__*/createCoords(0);\nfunction getVisualOffsets(element) {\n const win = getWindow(element);\n if (!isWebKit() || !win.visualViewport) {\n return noOffsets;\n }\n return {\n x: win.visualViewport.offsetLeft,\n y: win.visualViewport.offsetTop\n };\n}\nfunction shouldAddVisualOffsets(element, isFixed, floatingOffsetParent) {\n if (isFixed === void 0) {\n isFixed = false;\n }\n if (!floatingOffsetParent || isFixed && floatingOffsetParent !== getWindow(element)) {\n return false;\n }\n return isFixed;\n}\n\nfunction getBoundingClientRect(element, includeScale, isFixedStrategy, offsetParent) {\n if (includeScale === void 0) {\n includeScale = false;\n }\n if (isFixedStrategy === void 0) {\n isFixedStrategy = false;\n }\n const clientRect = element.getBoundingClientRect();\n const domElement = unwrapElement(element);\n let scale = createCoords(1);\n if (includeScale) {\n if (offsetParent) {\n if (isElement(offsetParent)) {\n scale = getScale(offsetParent);\n }\n } else {\n scale = getScale(element);\n }\n }\n const visualOffsets = shouldAddVisualOffsets(domElement, isFixedStrategy, offsetParent) ? getVisualOffsets(domElement) : createCoords(0);\n let x = (clientRect.left + visualOffsets.x) / scale.x;\n let y = (clientRect.top + visualOffsets.y) / scale.y;\n let width = clientRect.width / scale.x;\n let height = clientRect.height / scale.y;\n if (domElement) {\n const win = getWindow(domElement);\n const offsetWin = offsetParent && isElement(offsetParent) ? getWindow(offsetParent) : offsetParent;\n let currentWin = win;\n let currentIFrame = getFrameElement(currentWin);\n while (currentIFrame && offsetParent && offsetWin !== currentWin) {\n const iframeScale = getScale(currentIFrame);\n const iframeRect = currentIFrame.getBoundingClientRect();\n const css = getComputedStyle$1(currentIFrame);\n const left = iframeRect.left + (currentIFrame.clientLeft + parseFloat(css.paddingLeft)) * iframeScale.x;\n const top = iframeRect.top + (currentIFrame.clientTop + parseFloat(css.paddingTop)) * iframeScale.y;\n x *= iframeScale.x;\n y *= iframeScale.y;\n width *= iframeScale.x;\n height *= iframeScale.y;\n x += left;\n y += top;\n currentWin = getWindow(currentIFrame);\n currentIFrame = getFrameElement(currentWin);\n }\n }\n return rectToClientRect({\n width,\n height,\n x,\n y\n });\n}\n\n// If <html> has a CSS width greater than the viewport, then this will be\n// incorrect for RTL.\nfunction getWindowScrollBarX(element, rect) {\n const leftScroll = getNodeScroll(element).scrollLeft;\n if (!rect) {\n return getBoundingClientRect(getDocumentElement(element)).left + leftScroll;\n }\n return rect.left + leftScroll;\n}\n\nfunction getHTMLOffset(documentElement, scroll) {\n const htmlRect = documentElement.getBoundingClientRect();\n const x = htmlRect.left + scroll.scrollLeft - getWindowScrollBarX(documentElement, htmlRect);\n const y = htmlRect.top + scroll.scrollTop;\n return {\n x,\n y\n };\n}\n\nfunction convertOffsetParentRelativeRectToViewportRelativeRect(_ref) {\n let {\n elements,\n rect,\n offsetParent,\n strategy\n } = _ref;\n const isFixed = strategy === 'fixed';\n const documentElement = getDocumentElement(offsetParent);\n const topLayer = elements ? isTopLayer(elements.floating) : false;\n if (offsetParent === documentElement || topLayer && isFixed) {\n return rect;\n }\n let scroll = {\n scrollLeft: 0,\n scrollTop: 0\n };\n let scale = createCoords(1);\n const offsets = createCoords(0);\n const isOffsetParentAnElement = isHTMLElement(offsetParent);\n if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {\n if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {\n scroll = getNodeScroll(offsetParent);\n }\n if (isOffsetParentAnElement) {\n const offsetRect = getBoundingClientRect(offsetParent);\n scale = getScale(offsetParent);\n offsets.x = offsetRect.x + offsetParent.clientLeft;\n offsets.y = offsetRect.y + offsetParent.clientTop;\n }\n }\n const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);\n return {\n width: rect.width * scale.x,\n height: rect.height * scale.y,\n x: rect.x * scale.x - scroll.scrollLeft * scale.x + offsets.x + htmlOffset.x,\n y: rect.y * scale.y - scroll.scrollTop * scale.y + offsets.y + htmlOffset.y\n };\n}\n\nfunction getClientRects(element) {\n return Array.from(element.getClientRects());\n}\n\n// Gets the entire size of the scrollable document area, even extending outside\n// of the `<html>` and `<body>` rect bounds if horizontally scrollable.\nfunction getDocumentRect(element) {\n const html = getDocumentElement(element);\n const scroll = getNodeScroll(element);\n const body = element.ownerDocument.body;\n const width = max(html.scrollWidth, html.clientWidth, body.scrollWidth, body.clientWidth);\n const height = max(html.scrollHeight, html.clientHeight, body.scrollHeight, body.clientHeight);\n let x = -scroll.scrollLeft + getWindowScrollBarX(element);\n const y = -scroll.scrollTop;\n if (getComputedStyle$1(body).direction === 'rtl') {\n x += max(html.clientWidth, body.clientWidth) - width;\n }\n return {\n width,\n height,\n x,\n y\n };\n}\n\n// Safety check: ensure the scrollbar space is reasonable in case this\n// calculation is affected by unusual styles.\n// Most scrollbars leave 15-18px of space.\nconst SCROLLBAR_MAX = 25;\nfunction getViewportRect(element, strategy) {\n const win = getWindow(element);\n const html = getDocumentElement(element);\n const visualViewport = win.visualViewport;\n let width = html.clientWidth;\n let height = html.clientHeight;\n let x = 0;\n let y = 0;\n if (visualViewport) {\n width = visualViewport.width;\n height = visualViewport.height;\n const visualViewportBased = isWebKit();\n if (!visualViewportBased || visualViewportBased && strategy === 'fixed') {\n x = visualViewport.offsetLeft;\n y = visualViewport.offsetTop;\n }\n }\n const windowScrollbarX = getWindowScrollBarX(html);\n // <html> `overflow: hidden` + `scrollbar-gutter: stable` reduces the\n // visual width of the <html> but this is not considered in the size\n // of `html.clientWidth`.\n if (windowScrollbarX <= 0) {\n const doc = html.ownerDocument;\n const body = doc.body;\n const bodyStyles = getComputedStyle(body);\n const bodyMarginInline = doc.compatMode === 'CSS1Compat' ? parseFloat(bodyStyles.marginLeft) + parseFloat(bodyStyles.marginRight) || 0 : 0;\n const clippingStableScrollbarWidth = Math.abs(html.clientWidth - body.clientWidth - bodyMarginInline);\n if (clippingStableScrollbarWidth <= SCROLLBAR_MAX) {\n width -= clippingStableScrollbarWidth;\n }\n } else if (windowScrollbarX <= SCROLLBAR_MAX) {\n // If the <body> scrollbar is on the left, the width needs to be extended\n // by the scrollbar amount so there isn't extra space on the right.\n width += windowScrollbarX;\n }\n return {\n width,\n height,\n x,\n y\n };\n}\n\n// Returns the inner client rect, subtracting scrollbars if present.\nfunction getInnerBoundingClientRect(element, strategy) {\n const clientRect = getBoundingClientRect(element, true, strategy === 'fixed');\n const top = clientRect.top + element.clientTop;\n const left = clientRect.left + element.clientLeft;\n const scale = isHTMLElement(element) ? getScale(element) : createCoords(1);\n const width = element.clientWidth * scale.x;\n const height = element.clientHeight * scale.y;\n const x = left * scale.x;\n const y = top * scale.y;\n return {\n width,\n height,\n x,\n y\n };\n}\nfunction getClientRectFromClippingAncestor(element, clippingAncestor, strategy) {\n let rect;\n if (clippingAncestor === 'viewport') {\n rect = getViewportRect(element, strategy);\n } else if (clippingAncestor === 'document') {\n rect = getDocumentRect(getDocumentElement(element));\n } else if (isElement(clippingAncestor)) {\n rect = getInnerBoundingClientRect(clippingAncestor, strategy);\n } else {\n const visualOffsets = getVisualOffsets(element);\n rect = {\n x: clippingAncestor.x - visualOffsets.x,\n y: clippingAncestor.y - visualOffsets.y,\n width: clippingAncestor.width,\n height: clippingAncestor.height\n };\n }\n return rectToClientRect(rect);\n}\nfunction hasFixedPositionAncestor(element, stopNode) {\n const parentNode = getParentNode(element);\n if (parentNode === stopNode || !isElement(parentNode) || isLastTraversableNode(parentNode)) {\n return false;\n }\n return getComputedStyle$1(parentNode).position === 'fixed' || hasFixedPositionAncestor(parentNode, stopNode);\n}\n\n// A \"clipping ancestor\" is an `overflow` element with the characteristic of\n// clipping (or hiding) child elements. This returns all clipping ancestors\n// of the given element up the tree.\nfunction getClippingElementAncestors(element, cache) {\n const cachedResult = cache.get(element);\n if (cachedResult) {\n return cachedResult;\n }\n let result = getOverflowAncestors(element, [], false).filter(el => isElement(el) && getNodeName(el) !== 'body');\n let currentContainingBlockComputedStyle = null;\n const elementIsFixed = getComputedStyle$1(element).position === 'fixed';\n let currentNode = elementIsFixed ? getParentNode(element) : element;\n\n // https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block\n while (isElement(currentNode) && !isLastTraversableNode(currentNode)) {\n const computedStyle = getComputedStyle$1(currentNode);\n const currentNodeIsContaining = isContainingBlock(currentNode);\n if (!currentNodeIsContaining && computedStyle.position === 'fixed') {\n currentContainingBlockComputedStyle = null;\n }\n const shouldDropCurrentNode = elementIsFixed ? !currentNodeIsContaining && !currentContainingBlockComputedStyle : !currentNodeIsContaining && computedStyle.position === 'static' && !!currentContainingBlockComputedStyle && (currentContainingBlockComputedStyle.position === 'absolute' || currentContainingBlockComputedStyle.position === 'fixed') || isOverflowElement(currentNode) && !currentNodeIsContaining && hasFixedPositionAncestor(element, currentNode);\n if (shouldDropCurrentNode) {\n // Drop non-containing blocks.\n result = result.filter(ancestor => ancestor !== currentNode);\n } else {\n // Record last containing block for next iteration.\n currentContainingBlockComputedStyle = computedStyle;\n }\n currentNode = getParentNode(currentNode);\n }\n cache.set(element, result);\n return result;\n}\n\n// Gets the maximum area that the element is visible in due to any number of\n// clipping ancestors.\nfunction getClippingRect(_ref) {\n let {\n element,\n boundary,\n rootBoundary,\n strategy\n } = _ref;\n const elementClippingAncestors = boundary === 'clippingAncestors' ? isTopLayer(element) ? [] : getClippingElementAncestors(element, this._c) : [].concat(boundary);\n const clippingAncestors = [...elementClippingAncestors, rootBoundary];\n const firstRect = getClientRectFromClippingAncestor(element, clippingAncestors[0], strategy);\n let top = firstRect.top;\n let right = firstRect.right;\n let bottom = firstRect.bottom;\n let left = firstRect.left;\n for (let i = 1; i < clippingAncestors.length; i++) {\n const rect = getClientRectFromClippingAncestor(element, clippingAncestors[i], strategy);\n top = max(rect.top, top);\n right = min(rect.right, right);\n bottom = min(rect.bottom, bottom);\n left = max(rect.left, left);\n }\n return {\n width: right - left,\n height: bottom - top,\n x: left,\n y: top\n };\n}\n\nfunction getDimensions(element) {\n const {\n width,\n height\n } = getCssDimensions(element);\n return {\n width,\n height\n };\n}\n\nfunction getRectRelativeToOffsetParent(element, offsetParent, strategy) {\n const isOffsetParentAnElement = isHTMLElement(offsetParent);\n const documentElement = getDocumentElement(offsetParent);\n const isFixed = strategy === 'fixed';\n const rect = getBoundingClientRect(element, true, isFixed, offsetParent);\n let scroll = {\n scrollLeft: 0,\n scrollTop: 0\n };\n const offsets = createCoords(0);\n\n // If the <body> scrollbar appears on the left (e.g. RTL systems). Use\n // Firefox with layout.scrollbar.side = 3 in about:config to test this.\n function setLeftRTLScrollbarOffset() {\n offsets.x = getWindowScrollBarX(documentElement);\n }\n if (isOffsetParentAnElement || !isOffsetParentAnElement && !isFixed) {\n if (getNodeName(offsetParent) !== 'body' || isOverflowElement(documentElement)) {\n scroll = getNodeScroll(offsetParent);\n }\n if (isOffsetParentAnElement) {\n const offsetRect = getBoundingClientRect(offsetParent, true, isFixed, offsetParent);\n offsets.x = offsetRect.x + offsetParent.clientLeft;\n offsets.y = offsetRect.y + offsetParent.clientTop;\n } else if (documentElement) {\n setLeftRTLScrollbarOffset();\n }\n }\n if (isFixed && !isOffsetParentAnElement && documentElement) {\n setLeftRTLScrollbarOffset();\n }\n const htmlOffset = documentElement && !isOffsetParentAnElement && !isFixed ? getHTMLOffset(documentElement, scroll) : createCoords(0);\n const x = rect.left + scroll.scrollLeft - offsets.x - htmlOffset.x;\n const y = rect.top + scroll.scrollTop - offsets.y - htmlOffset.y;\n return {\n x,\n y,\n width: rect.width,\n height: rect.height\n };\n}\n\nfunction isStaticPositioned(element) {\n return getComputedStyle$1(element).position === 'static';\n}\n\nfunction getTrueOffsetParent(element, polyfill) {\n if (!isHTMLElement(element) || getComputedStyle$1(element).position === 'fixed') {\n return null;\n }\n if (polyfill) {\n return polyfill(element);\n }\n let rawOffsetParent = element.offsetParent;\n\n // Firefox returns the <html> element as the offsetParent if it's non-static,\n // while Chrome and Safari return the <body> element. The <body> element must\n // be used to perform the correct calculations even if the <html> element is\n // non-static.\n if (getDocumentElement(element) === rawOffsetParent) {\n rawOffsetParent = rawOffsetParent.ownerDocument.body;\n }\n return rawOffsetParent;\n}\n\n// Gets the closest ancestor positioned element. Handles some edge cases,\n// such as table ancestors and cross browser bugs.\nfunction getOffsetParent(element, polyfill) {\n const win = getWindow(element);\n if (isTopLayer(element)) {\n return win;\n }\n if (!isHTMLElement(element)) {\n let svgOffsetParent = getParentNode(element);\n while (svgOffsetParent && !isLastTraversableNode(svgOffsetParent)) {\n if (isElement(svgOffsetParent) && !isStaticPositioned(svgOffsetParent)) {\n return svgOffsetParent;\n }\n svgOffsetParent = getParentNode(svgOffsetParent);\n }\n return win;\n }\n let offsetParent = getTrueOffsetParent(element, polyfill);\n while (offsetParent && isTableElement(offsetParent) && isStaticPositioned(offsetParent)) {\n offsetParent = getTrueOffsetParent(offsetParent, polyfill);\n }\n if (offsetParent && isLastTraversableNode(offsetParent) && isStaticPositioned(offsetParent) && !isContainingBlock(offsetParent)) {\n return win;\n }\n return offsetParent || getContainingBlock(element) || win;\n}\n\nconst getElementRects = async function (data) {\n const getOffsetParentFn = this.getOffsetParent || getOffsetParent;\n const getDimensionsFn = this.getDimensions;\n const floatingDimensions = await getDimensionsFn(data.floating);\n return {\n reference: getRectRelativeToOffsetParent(data.reference, await getOffsetParentFn(data.floating), data.strategy),\n floating: {\n x: 0,\n y: 0,\n width: floatingDimensions.width,\n height: floatingDimensions.height\n }\n };\n};\n\nfunction isRTL(element) {\n return getComputedStyle$1(element).direction === 'rtl';\n}\n\nconst platform = {\n convertOffsetParentRelativeRectToViewportRelativeRect,\n getDocumentElement,\n getClippingRect,\n getOffsetParent,\n getElementRects,\n getClientRects,\n getDimensions,\n getScale,\n isElement,\n isRTL\n};\n\nfunction rectsAreEqual(a, b) {\n return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;\n}\n\n// https://samthor.au/2021/observing-dom/\nfunction observeMove(element, onMove) {\n let io = null;\n let timeoutId;\n const root = getDocumentElement(element);\n function cleanup() {\n var _io;\n clearTimeout(timeoutId);\n (_io = io) == null || _io.disconnect();\n io = null;\n }\n function refresh(skip, threshold) {\n if (skip === void 0) {\n skip = false;\n }\n if (threshold === void 0) {\n threshold = 1;\n }\n cleanup();\n const elementRectForRootMargin = element.getBoundingClientRect();\n const {\n left,\n top,\n width,\n height\n } = elementRectForRootMargin;\n if (!skip) {\n onMove();\n }\n if (!width || !height) {\n return;\n }\n const insetTop = floor(top);\n const insetRight = floor(root.clientWidth - (left + width));\n const insetBottom = floor(root.clientHeight - (top + height));\n const insetLeft = floor(left);\n const rootMargin = -insetTop + \"px \" + -insetRight + \"px \" + -insetBottom + \"px \" + -insetLeft + \"px\";\n const options = {\n rootMargin,\n threshold: max(0, min(1, threshold)) || 1\n };\n let isFirstUpdate = true;\n function handleObserve(entries) {\n const ratio = entries[0].intersectionRatio;\n if (ratio !== threshold) {\n if (!isFirstUpdate) {\n return refresh();\n }\n if (!ratio) {\n // If the reference is clipped, the ratio is 0. Throttle the refresh\n // to prevent an infinite loop of updates.\n timeoutId = setTimeout(() => {\n refresh(false, 1e-7);\n }, 1000);\n } else {\n refresh(false, ratio);\n }\n }\n if (ratio === 1 && !rectsAreEqual(elementRectForRootMargin, element.getBoundingClientRect())) {\n // It's possible that even though the ratio is reported as 1, the\n // element is not actually fully within the IntersectionObserver's root\n // area anymore. This can happen under performance constraints. This may\n // be a bug in the browser's IntersectionObserver implementation. To\n // work around this, we compare the element's bounding rect now with\n // what it was at the time we created the IntersectionObserver. If they\n // are not equal then the element moved, so we refresh.\n refresh();\n }\n isFirstUpdate = false;\n }\n\n // Older browsers don't support a `document` as the root and will throw an\n // error.\n try {\n io = new IntersectionObserver(handleObserve, {\n ...options,\n // Handle <iframe>s\n root: root.ownerDocument\n });\n } catch (_e) {\n io = new IntersectionObserver(handleObserve, options);\n }\n io.observe(element);\n }\n refresh(true);\n return cleanup;\n}\n\n/**\n * Automatically updates the position of the floating element when necessary.\n * Should only be called when the floating element is mounted on the DOM or\n * visible on the screen.\n * @returns cleanup function that should be invoked when the floating element is\n * removed from the DOM or hidden from the screen.\n * @see https://floating-ui.com/docs/autoUpdate\n */\nfunction autoUpdate(reference, floating, update, options) {\n if (options === void 0) {\n options = {};\n }\n const {\n ancestorScroll = true,\n ancestorResize = true,\n elementResize = typeof ResizeObserver === 'function',\n layoutShift = typeof IntersectionObserver === 'function',\n animationFrame = false\n } = options;\n const referenceEl = unwrapElement(reference);\n const ancestors = ancestorScroll || ancestorResize ? [...(referenceEl ? getOverflowAncestors(referenceEl) : []), ...(floating ? getOverflowAncestors(floating) : [])] : [];\n ancestors.forEach(ancestor => {\n ancestorScroll && ancestor.addEventListener('scroll', update, {\n passive: true\n });\n ancestorResize && ancestor.addEventListener('resize', update);\n });\n const cleanupIo = referenceEl && layoutShift ? observeMove(referenceEl, update) : null;\n let reobserveFrame = -1;\n let resizeObserver = null;\n if (elementResize) {\n resizeObserver = new ResizeObserver(_ref => {\n let [firstEntry] = _ref;\n if (firstEntry && firstEntry.target === referenceEl && resizeObserver && floating) {\n // Prevent update loops when using the `size` middleware.\n // https://github.com/floating-ui/floating-ui/issues/1740\n resizeObserver.unobserve(floating);\n cancelAnimationFrame(reobserveFrame);\n reobserveFrame = requestAnimationFrame(() => {\n var _resizeObserver;\n (_resizeObserver = resizeObserver) == null || _resizeObserver.observe(floating);\n });\n }\n update();\n });\n if (referenceEl && !animationFrame) {\n resizeObserver.observe(referenceEl);\n }\n if (floating) {\n resizeObserver.observe(floating);\n }\n }\n let frameId;\n let prevRefRect = animationFrame ? getBoundingClientRect(reference) : null;\n if (animationFrame) {\n frameLoop();\n }\n function frameLoop() {\n const nextRefRect = getBoundingClientRect(reference);\n if (prevRefRect && !rectsAreEqual(prevRefRect, nextRefRect)) {\n update();\n }\n prevRefRect = nextRefRect;\n frameId = requestAnimationFrame(frameLoop);\n }\n update();\n return () => {\n var _resizeObserver2;\n ancestors.forEach(ancestor => {\n ancestorScroll && ancestor.removeEventListener('scroll', update);\n ancestorResize && ancestor.removeEventListener('resize', update);\n });\n cleanupIo == null || cleanupIo();\n (_resizeObserver2 = resizeObserver) == null || _resizeObserver2.disconnect();\n resizeObserver = null;\n if (animationFrame) {\n cancelAnimationFrame(frameId);\n }\n };\n}\n\n/**\n * Resolves with an object of overflow side offsets that determine how much the\n * element is overflowing a given clipping boundary on each side.\n * - positive = overflowing the boundary by that number of pixels\n * - negative = how many pixels left before it will overflow\n * - 0 = lies flush with the boundary\n * @see https://floating-ui.com/docs/detectOverflow\n */\nconst detectOverflow = detectOverflow$1;\n\n/**\n * Modifies the placement by translating the floating element along the\n * specified axes.\n * A number (shorthand for `mainAxis` or distance), or an axes configuration\n * object may be passed.\n * @see https://floating-ui.com/docs/offset\n */\nconst offset = offset$1;\n\n/**\n * Optimizes the visibility of the floating element by choosing the placement\n * that has the most space available automatically, without needing to specify a\n * preferred placement. Alternative to `flip`.\n * @see https://floating-ui.com/docs/autoPlacement\n */\nconst autoPlacement = autoPlacement$1;\n\n/**\n * Optimizes the visibility of the floating element by shifting it in order to\n * keep it in view when it will overflow the clipping boundary.\n * @see https://floating-ui.com/docs/shift\n */\nconst shift = shift$1;\n\n/**\n * Optimizes the visibility of the floating element by flipping the `placement`\n * in order to keep it in view when the preferred placement(s) will overflow the\n * clipping boundary. Alternative to `autoPlacement`.\n * @see https://floating-ui.com/docs/flip\n */\nconst flip = flip$1;\n\n/**\n * Provides data that allows you to change the size of the floating element —\n * for instance, prevent it from overflowing the clipping boundary or match the\n * width of the reference element.\n * @see https://floating-ui.com/docs/size\n */\nconst size = size$1;\n\n/**\n * Provides data to hide the floating element in applicable situations, such as\n * when it is not in the same clipping context as the reference element.\n * @see https://floating-ui.com/docs/hide\n */\nconst hide = hide$1;\n\n/**\n * Provides data to position an inner element of the floating element so that it\n * appears centered to the reference element.\n * @see https://floating-ui.com/docs/arrow\n */\nconst arrow = arrow$1;\n\n/**\n * Provides improved positioning for inline reference elements that can span\n * over multiple lines, such as hyperlinks or range selections.\n * @see https://floating-ui.com/docs/inline\n */\nconst inline = inline$1;\n\n/**\n * Built-in `limiter` that will stop `shift()` at a certain point.\n */\nconst limitShift = limitShift$1;\n\n/**\n * Computes the `x` and `y` coordinates that will place the floating element\n * next to a given reference element.\n */\nconst computePosition = (reference, floating, options) => {\n // This caches the expensive `getClippingElementAncestors` function so that\n // multiple lifecycle resets re-use the same result. It only lives for a\n // single call. If other functions become expensive, we can add them as well.\n const cache = new Map();\n const mergedOptions = {\n platform,\n ...options\n };\n const platformWithCache = {\n ...mergedOptions.platform,\n _c: cache\n };\n return computePosition$1(reference, floating, {\n ...mergedOptions,\n platform: platformWithCache\n });\n};\n\nexport { arrow, autoPlacement, autoUpdate, computePosition, detectOverflow, flip, hide, inline, limitShift, offset, platform, shift, size };\n","import * as Vue from 'vue'\n\nvar isVue2 = false\nvar isVue3 = true\nvar Vue2 = undefined\n\nfunction install() {}\n\nexport function set(target, key, val) {\n if (Array.isArray(target)) {\n target.length = Math.max(target.length, key)\n target.splice(key, 1, val)\n return val\n }\n target[key] = val\n return val\n}\n\nexport function del(target, key) {\n if (Array.isArray(target)) {\n target.splice(key, 1)\n return\n }\n delete target[key]\n}\n\nexport * from 'vue'\nexport {\n Vue,\n Vue2,\n isVue2,\n isVue3,\n install,\n}\n","import { arrow as arrow$1, computePosition } from '@floating-ui/dom';\nexport { autoPlacement, autoUpdate, computePosition, detectOverflow, flip, getOverflowAncestors, hide, inline, limitShift, offset, platform, shift, size } from '@floating-ui/dom';\nimport { isNode, getNodeName } from '@floating-ui/utils/dom';\nimport { unref, computed, ref, shallowRef, watch, getCurrentScope, onScopeDispose, shallowReadonly } from 'vue-demi';\n\nfunction isComponentPublicInstance(target) {\n return target != null && typeof target === 'object' && '$el' in target;\n}\nfunction unwrapElement(target) {\n if (isComponentPublicInstance(target)) {\n const element = target.$el;\n return isNode(element) && getNodeName(element) === '#comment' ? null : element;\n }\n return target;\n}\n\nfunction toValue(source) {\n return typeof source === 'function' ? source() : unref(source);\n}\n\n/**\n * Positions an inner element of the floating element such that it is centered to the reference element.\n * @param options The arrow options.\n * @see https://floating-ui.com/docs/arrow\n */\nfunction arrow(options) {\n return {\n name: 'arrow',\n options,\n fn(args) {\n const element = unwrapElement(toValue(options.element));\n if (element == null) {\n return {};\n }\n return arrow$1({\n element,\n padding: options.padding\n }).fn(args);\n }\n };\n}\n\nfunction getDPR(element) {\n if (typeof window === 'undefined') {\n return 1;\n }\n const win = element.ownerDocument.defaultView || window;\n return win.devicePixelRatio || 1;\n}\n\nfunction roundByDPR(element, value) {\n const dpr = getDPR(element);\n return Math.round(value * dpr) / dpr;\n}\n\n/**\n * Computes the `x` and `y` coordinates that will place the floating element next to a reference element when it is given a certain CSS positioning strategy.\n * @param reference The reference template ref.\n * @param floating The floating template ref.\n * @param options The floating options.\n * @see https://floating-ui.com/docs/vue\n */\nfunction useFloating(reference, floating, options) {\n if (options === void 0) {\n options = {};\n }\n const whileElementsMountedOption = options.whileElementsMounted;\n const openOption = computed(() => {\n var _toValue;\n return (_toValue = toValue(options.open)) != null ? _toValue : true;\n });\n const middlewareOption = computed(() => toValue(options.middleware));\n const placementOption = computed(() => {\n var _toValue2;\n return (_toValue2 = toValue(options.placement)) != null ? _toValue2 : 'bottom';\n });\n const strategyOption = computed(() => {\n var _toValue3;\n return (_toValue3 = toValue(options.strategy)) != null ? _toValue3 : 'absolute';\n });\n const transformOption = computed(() => {\n var _toValue4;\n return (_toValue4 = toValue(options.transform)) != null ? _toValue4 : true;\n });\n const referenceElement = computed(() => unwrapElement(reference.value));\n const floatingElement = computed(() => unwrapElement(floating.value));\n const x = ref(0);\n const y = ref(0);\n const strategy = ref(strategyOption.value);\n const placement = ref(placementOption.value);\n const middlewareData = shallowRef({});\n const isPositioned = ref(false);\n const floatingStyles = computed(() => {\n const initialStyles = {\n position: strategy.value,\n left: '0',\n top: '0'\n };\n if (!floatingElement.value) {\n return initialStyles;\n }\n const xVal = roundByDPR(floatingElement.value, x.value);\n const yVal = roundByDPR(floatingElement.value, y.value);\n if (transformOption.value) {\n return {\n ...initialStyles,\n transform: \"translate(\" + xVal + \"px, \" + yVal + \"px)\",\n ...(getDPR(floatingElement.value) >= 1.5 && {\n willChange: 'transform'\n })\n };\n }\n return {\n position: strategy.value,\n left: xVal + \"px\",\n top: yVal + \"px\"\n };\n });\n let whileElementsMountedCleanup;\n function update() {\n if (referenceElement.value == null || floatingElement.value == null) {\n return;\n }\n const open = openOption.value;\n computePosition(referenceElement.value, floatingElement.value, {\n middleware: middlewareOption.value,\n placement: placementOption.value,\n strategy: strategyOption.value\n }).then(position => {\n x.value = position.x;\n y.value = position.y;\n strategy.value = position.strategy;\n placement.value = position.placement;\n middlewareData.value = position.middlewareData;\n /**\n * The floating element's position may be recomputed while it's closed\n * but still mounted (such as when transitioning out). To ensure\n * `isPositioned` will be `false` initially on the next open, avoid\n * setting it to `true` when `open === false` (must be specified).\n */\n isPositioned.value = open !== false;\n });\n }\n function cleanup() {\n if (typeof whileElementsMountedCleanup === 'function') {\n whileElementsMountedCleanup();\n whileElementsMountedCleanup = undefined;\n }\n }\n function attach() {\n cleanup();\n if (whileElementsMountedOption === undefined) {\n update();\n return;\n }\n if (referenceElement.value != null && floatingElement.value != null) {\n whileElementsMountedCleanup = whileElementsMountedOption(referenceElement.value, floatingElement.value, update);\n return;\n }\n }\n function reset() {\n if (!openOption.value) {\n isPositioned.value = false;\n }\n }\n watch([middlewareOption, placementOption, strategyOption, openOption], update, {\n flush: 'sync'\n });\n watch([referenceElement, floatingElement], attach, {\n flush: 'sync'\n });\n watch(openOption, reset, {\n flush: 'sync'\n });\n if (getCurrentScope()) {\n onScopeDispose(cleanup);\n }\n return {\n x: shallowReadonly(x),\n y: shallowReadonly(y),\n strategy: shallowReadonly(strategy),\n placement: shallowReadonly(placement),\n middlewareData: shallowReadonly(middlewareData),\n isPositioned: shallowReadonly(isPositioned),\n floatingStyles,\n update\n };\n}\n\nexport { arrow, useFloating };\n","<script setup lang=\"ts\">\nimport { ref, onMounted, onUnmounted, computed, watch } from \"vue\";\nimport { flip, useFloating, AlignedPlacement, Placement, offset } from \"@floating-ui/vue\";\nimport { useDebounceFn, useElementHover, useElementBounding } from \"@vueuse/core\";\nimport { PvPopoverV2Props } from \"@/components/base/PvPopoverV2/types.ts\";\nimport { vOnClickOutside } from \"@vueuse/components\";\nimport { PvAlignmentPositions } from \"@/components/base/baseProps.ts\";\n\nconst props = withDefaults(defineProps<PvPopoverV2Props>(), {\n disableAutoPlacement: false,\n position: \"bottom-left\",\n positioningStrategy: \"absolute\",\n disableInteractive: false,\n useTeleport: false,\n disableClickOutsideToClose: false,\n showOnHover: false,\n delay: 25,\n zIndex: 10,\n teleportLocation: \"body\",\n});\n\nconst isOpen = defineModel<boolean>();\n\nconst triggerWrapper = ref<HTMLElement | null>(null);\nconst reference = ref<HTMLElement | null>(null);\nconst floating = ref<HTMLElement | null>(null);\n\nconst triggerHovered = useElementHover(triggerWrapper);\nconst floatingHovered = useElementHover(floating);\n\n/**\n * We use our own placement mapping name to ensure that have the same naming across the PitViper components.\n */\nconst placementMapping: Record<PvAlignmentPositions, AlignedPlacement | Placement> = {\n \"top-center\": \"top\",\n \"bottom-center\": \"bottom\",\n \"center-left\": \"left\",\n \"center-right\": \"right\",\n \"top-left\": \"top-start\",\n \"top-right\": \"top-end\",\n \"bottom-left\": \"bottom-start\",\n \"bottom-right\": \"bottom-end\",\n};\n\nonMounted(() => {\n if (triggerWrapper.value) {\n // Set reference to the first child element (the actual trigger)\n reference.value = triggerWrapper.value.firstElementChild as HTMLElement | null;\n }\n});\n\nconst middleware = [];\n\nif (!props.disableAutoPlacement) {\n middleware?.push(\n flip({\n fallbackStrategy: \"initialPlacement\",\n }),\n );\n}\n\nif (props.offset) {\n middleware?.push(offset(props.offset));\n}\n\nconst { floatingStyles, update } = useFloating(reference, floating, {\n placement: placementMapping[props.position],\n strategy: props.positioningStrategy,\n middleware: middleware,\n});\n\n// Update popover position when it opens\nwatch(isOpen, (newVal) => {\n if (newVal && reference.value && floating.value) {\n update();\n }\n});\n\n// Track trigger position and size changes\nconst elementBounds = useElementBounding(reference);\n\nconst handleBoundsChange = useDebounceFn(() => {\n if (isOpen.value) {\n update();\n }\n}, 5);\n\nwatch([elementBounds.top, elementBounds.left, elementBounds.width, elementBounds.height], handleBoundsChange);\n\nconst popoverStyles = computed(() => {\n return {\n ...floatingStyles.value,\n zIndex: props.zIndex ?? 10,\n };\n});\n\nlet openDelayTimeout: ReturnType<typeof setTimeout> | undefined;\n\nconst clearOpenDelayTimeout = () => {\n if (openDelayTimeout) {\n clearTimeout(openDelayTimeout);\n openDelayTimeout = undefined;\n }\n};\n\nconst setPopoverState = (state: boolean) => {\n clearOpenDelayTimeout();\n\n if (state && props.delay > 0) {\n openDelayTimeout = setTimeout(() => {\n isOpen.value = true;\n openDelayTimeout = undefined;\n }, props.delay);\n return;\n }\n\n // Closing should always be immediate, even when opening is delayed.\n isOpen.value = state;\n};\n\nconst ignoreForClickOutside = computed(() => {\n const list: (string | HTMLElement | null)[] = [floating.value].filter(Boolean);\n list.push(\".p-datepicker-panel\");\n\n if (props.ignoreClickOutsideClasses) {\n list.push(...props.ignoreClickOutsideClasses.map((cls) => `.${cls}`));\n }\n\n return list;\n});\n\nconst isHovered = computed(() => {\n if (!props.showOnHover) return false;\n return props.disableInteractive ? triggerHovered.value : triggerHovered.value || floatingHovered.value;\n});\n\nconst handleTriggerClick = () => {\n if (!props.showOnHover) {\n setPopoverState(openDelayTimeout ? false : !isOpen.value);\n }\n};\n\nconst handleClickOutside = () => {\n if (!props.disableClickOutsideToClose) {\n setPopoverState(false);\n }\n};\n\n// Watch hover state and update popover accordingly\nwatch(isHovered, (newVal) => {\n if (props.showOnHover) {\n setPopoverState(newVal);\n }\n});\n\nonUnmounted(() => {\n clearOpenDelayTimeout();\n});\n</script>\n\n<template>\n <div v-on-click-outside=\"[handleClickOutside, { ignore: ignoreForClickOutside }]\" style=\"width: fit-content\">\n <div ref=\"triggerWrapper\" @click=\"handleTriggerClick\">\n <slot name=\"trigger\"> </slot>\n </div>\n <Teleport v-if=\"$slots.content\" :to=\"teleportLocation\" :disabled=\"!props.useTeleport\">\n <div class=\"pv-floating\" ref=\"floating\" v-show=\"isOpen\" :style=\"popoverStyles\">\n <slot name=\"content\"></slot>\n </div>\n </Teleport>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { ref, onMounted, onUnmounted, computed, watch } from \"vue\";\nimport { flip, useFloating, AlignedPlacement, Placement, offset } from \"@floating-ui/vue\";\nimport { useDebounceFn, useElementHover, useElementBounding } from \"@vueuse/core\";\nimport { PvPopoverV2Props } from \"@/components/base/PvPopoverV2/types.ts\";\nimport { vOnClickOutside } from \"@vueuse/components\";\nimport { PvAlignmentPositions } from \"@/components/base/baseProps.ts\";\n\nconst props = withDefaults(defineProps<PvPopoverV2Props>(), {\n disableAutoPlacement: false,\n position: \"bottom-left\",\n positioningStrategy: \"absolute\",\n disableInteractive: false,\n useTeleport: false,\n disableClickOutsideToClose: false,\n showOnHover: false,\n delay: 25,\n zIndex: 10,\n teleportLocation: \"body\",\n});\n\nconst isOpen = defineModel<boolean>();\n\nconst triggerWrapper = ref<HTMLElement | null>(null);\nconst reference = ref<HTMLElement | null>(null);\nconst floating = ref<HTMLElement | null>(null);\n\nconst triggerHovered = useElementHover(triggerWrapper);\nconst floatingHovered = useElementHover(floating);\n\n/**\n * We use our own placement mapping name to ensure that have the same naming across the PitViper components.\n */\nconst placementMapping: Record<PvAlignmentPositions, AlignedPlacement | Placement> = {\n \"top-center\": \"top\",\n \"bottom-center\": \"bottom\",\n \"center-left\": \"left\",\n \"center-right\": \"right\",\n \"top-left\": \"top-start\",\n \"top-right\": \"top-end\",\n \"bottom-left\": \"bottom-start\",\n \"bottom-right\": \"bottom-end\",\n};\n\nonMounted(() => {\n if (triggerWrapper.value) {\n // Set reference to the first child element (the actual trigger)\n reference.value = triggerWrapper.value.firstElementChild as HTMLElement | null;\n }\n});\n\nconst middleware = [];\n\nif (!props.disableAutoPlacement) {\n middleware?.push(\n flip({\n fallbackStrategy: \"initialPlacement\",\n }),\n );\n}\n\nif (props.offset) {\n middleware?.push(offset(props.offset));\n}\n\nconst { floatingStyles, update } = useFloating(reference, floating, {\n placement: placementMapping[props.position],\n strategy: props.positioningStrategy,\n middleware: middleware,\n});\n\n// Update popover position when it opens\nwatch(isOpen, (newVal) => {\n if (newVal && reference.value && floating.value) {\n update();\n }\n});\n\n// Track trigger position and size changes\nconst elementBounds = useElementBounding(reference);\n\nconst handleBoundsChange = useDebounceFn(() => {\n if (isOpen.value) {\n update();\n }\n}, 5);\n\nwatch([elementBounds.top, elementBounds.left, elementBounds.width, elementBounds.height], handleBoundsChange);\n\nconst popoverStyles = computed(() => {\n return {\n ...floatingStyles.value,\n zIndex: props.zIndex ?? 10,\n };\n});\n\nlet openDelayTimeout: ReturnType<typeof setTimeout> | undefined;\n\nconst clearOpenDelayTimeout = () => {\n if (openDelayTimeout) {\n clearTimeout(openDelayTimeout);\n openDelayTimeout = undefined;\n }\n};\n\nconst setPopoverState = (state: boolean) => {\n clearOpenDelayTimeout();\n\n if (state && props.delay > 0) {\n openDelayTimeout = setTimeout(() => {\n isOpen.value = true;\n openDelayTimeout = undefined;\n }, props.delay);\n return;\n }\n\n // Closing should always be immediate, even when opening is delayed.\n isOpen.value = state;\n};\n\nconst ignoreForClickOutside = computed(() => {\n const list: (string | HTMLElement | null)[] = [floating.value].filter(Boolean);\n list.push(\".p-datepicker-panel\");\n\n if (props.ignoreClickOutsideClasses) {\n list.push(...props.ignoreClickOutsideClasses.map((cls) => `.${cls}`));\n }\n\n return list;\n});\n\nconst isHovered = computed(() => {\n if (!props.showOnHover) return false;\n return props.disableInteractive ? triggerHovered.value : triggerHovered.value || floatingHovered.value;\n});\n\nconst handleTriggerClick = () => {\n if (!props.showOnHover) {\n setPopoverState(openDelayTimeout ? false : !isOpen.value);\n }\n};\n\nconst handleClickOutside = () => {\n if (!props.disableClickOutsideToClose) {\n setPopoverState(false);\n }\n};\n\n// Watch hover state and update popover accordingly\nwatch(isHovered, (newVal) => {\n if (props.showOnHover) {\n setPopoverState(newVal);\n }\n});\n\nonUnmounted(() => {\n clearOpenDelayTimeout();\n});\n</script>\n\n<template>\n <div v-on-click-outside=\"[handleClickOutside, { ignore: ignoreForClickOutside }]\" style=\"width: fit-content\">\n <div ref=\"triggerWrapper\" @click=\"handleTriggerClick\">\n <slot name=\"trigger\"> </slot>\n </div>\n <Teleport v-if=\"$slots.content\" :to=\"teleportLocation\" :disabled=\"!props.useTeleport\">\n <div class=\"pv-floating\" ref=\"floating\" v-show=\"isOpen\" :style=\"popoverStyles\">\n <slot name=\"content\"></slot>\n </div>\n </Teleport>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { PvTooltipV2Props } from \"./types\";\nimport PvPopoverV2 from \"@/components/base/PvPopoverV2/PvPopoverV2.vue\";\n\nwithDefaults(defineProps<PvTooltipV2Props>(), {\n variant: \"dark\",\n position: \"top-center\",\n size: \"md\",\n disableInteractive: false,\n delay: 0,\n showOnHover: true,\n});\n</script>\n\n<template>\n <PvPopoverV2 v-bind=\"$props\">\n <template #trigger>\n <slot name=\"trigger\">\n <p>{{ label }}</p>\n </slot>\n </template>\n <template #content v-if=\"$slots.content || description\">\n <div\n class=\"pv-tooltip-v2-content\"\n role=\"tooltip\"\n :data-variant=\"variant\"\n :class=\"{ 'pv-tooltip-v2-content-small': size === 'sm' }\"\n >\n <slot name=\"content\">\n {{ description }}\n </slot>\n </div>\n </template>\n </PvPopoverV2>\n</template>\n","<script setup lang=\"ts\">\nimport { PvTooltipV2Props } from \"./types\";\nimport PvPopoverV2 from \"@/components/base/PvPopoverV2/PvPopoverV2.vue\";\n\nwithDefaults(defineProps<PvTooltipV2Props>(), {\n variant: \"dark\",\n position: \"top-center\",\n size: \"md\",\n disableInteractive: false,\n delay: 0,\n showOnHover: true,\n});\n</script>\n\n<template>\n <PvPopoverV2 v-bind=\"$props\">\n <template #trigger>\n <slot name=\"trigger\">\n <p>{{ label }}</p>\n </slot>\n </template>\n <template #content v-if=\"$slots.content || description\">\n <div\n class=\"pv-tooltip-v2-content\"\n role=\"tooltip\"\n :data-variant=\"variant\"\n :class=\"{ 'pv-tooltip-v2-content-small': size === 'sm' }\"\n >\n <slot name=\"content\">\n {{ description }}\n </slot>\n </div>\n </template>\n </PvPopoverV2>\n</template>\n","<script setup lang=\"ts\">\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport PvTooltipV2 from \"@/components/base/PvTooltipV2/PvTooltipV2.vue\";\nimport { PvSegmentControlSize, PvSegmentedControlOption } from \"./types\";\n\ninterface PvSegmentControlProps {\n /** The list of options rendered as segments. Each option can have a label, icon, or both. */\n options: PvSegmentedControlOption[];\n /**\n * Controls the overall height of the segmented control.\n */\n size?: PvSegmentControlSize;\n}\n\nwithDefaults(defineProps<PvSegmentControlProps>(), {\n size: \"lg\",\n options: () => [],\n});\n\nconst modelValue = defineModel<string>({ required: true });\n\nconst selectOption = (option: PvSegmentedControlOption) => {\n if (option.disabled) return;\n modelValue.value = option.value;\n};\n</script>\n\n<template>\n <div\n :class=\"[\n 'pv-segmented-control',\n {\n 'pv-segmented-control-large': size === 'xl',\n },\n ]\"\n >\n <PvTooltipV2\n v-for=\"option in options\"\n :key=\"option.value\"\n variant=\"dark\"\n position=\"bottom-right\"\n style=\"width: 100%\"\n >\n <template #trigger>\n <PvButton\n class=\"pv-full-width\"\n variant=\"ghost\"\n :label=\"option.label\"\n :ariaLabel=\"option.ariaLabel\"\n :left-icon=\"option.iconPosition === 'left' ? option.icon : undefined\"\n :right-icon=\"option.iconPosition === 'right' ? option.icon : undefined\"\n :disabled=\"option.disabled\"\n :class=\"{ 'pv-disabled': option.disabled }\"\n :data-active=\"modelValue === option.value ? true : null\"\n @click=\"selectOption(option)\"\n />\n </template>\n <template v-if=\"option.disabledReason\" #content>\n {{ option.disabledReason }}\n </template>\n </PvTooltipV2>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport PvTooltipV2 from \"@/components/base/PvTooltipV2/PvTooltipV2.vue\";\nimport { PvSegmentControlSize, PvSegmentedControlOption } from \"./types\";\n\ninterface PvSegmentControlProps {\n /** The list of options rendered as segments. Each option can have a label, icon, or both. */\n options: PvSegmentedControlOption[];\n /**\n * Controls the overall height of the segmented control.\n */\n size?: PvSegmentControlSize;\n}\n\nwithDefaults(defineProps<PvSegmentControlProps>(), {\n size: \"lg\",\n options: () => [],\n});\n\nconst modelValue = defineModel<string>({ required: true });\n\nconst selectOption = (option: PvSegmentedControlOption) => {\n if (option.disabled) return;\n modelValue.value = option.value;\n};\n</script>\n\n<template>\n <div\n :class=\"[\n 'pv-segmented-control',\n {\n 'pv-segmented-control-large': size === 'xl',\n },\n ]\"\n >\n <PvTooltipV2\n v-for=\"option in options\"\n :key=\"option.value\"\n variant=\"dark\"\n position=\"bottom-right\"\n style=\"width: 100%\"\n >\n <template #trigger>\n <PvButton\n class=\"pv-full-width\"\n variant=\"ghost\"\n :label=\"option.label\"\n :ariaLabel=\"option.ariaLabel\"\n :left-icon=\"option.iconPosition === 'left' ? option.icon : undefined\"\n :right-icon=\"option.iconPosition === 'right' ? option.icon : undefined\"\n :disabled=\"option.disabled\"\n :class=\"{ 'pv-disabled': option.disabled }\"\n :data-active=\"modelValue === option.value ? true : null\"\n @click=\"selectOption(option)\"\n />\n </template>\n <template v-if=\"option.disabledReason\" #content>\n {{ option.disabledReason }}\n </template>\n </PvTooltipV2>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { Option } from \"@/types\";\nexport interface PvTabListBaseProps {\n modelValue: string;\n options: Option[];\n}\n\ndefineProps<PvTabListBaseProps>();\n\nconst emit = defineEmits([\"update:modelValue\"]);\n\nconst selectOption = (value: string) => {\n emit(\"update:modelValue\", value);\n};\n</script>\n\n<template>\n <div>\n <ul role=\"list\" class=\"pv-tab-list\">\n <li\n v-for=\"option in options\"\n :key=\"option.value\"\n style=\"cursor: pointer\"\n @click=\"selectOption(option.value)\"\n :data-active=\"modelValue === option.value ? true : null\"\n >\n <button class=\"pv-text-body-xs\" style=\"font-weight: 500\">\n {{ option.label }}\n </button>\n </li>\n </ul>\n </div>\n</template>\n\n<style scoped>\n.pv-tab-list {\n border: none;\n}\n.pv-tab-list :where(li)[data-active]:after {\n content: \"\";\n display: block;\n height: 2px;\n width: 100%;\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background-color: #176f6f;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { Option } from \"@/types\";\nexport interface PvTabListBaseProps {\n modelValue: string;\n options: Option[];\n}\n\ndefineProps<PvTabListBaseProps>();\n\nconst emit = defineEmits([\"update:modelValue\"]);\n\nconst selectOption = (value: string) => {\n emit(\"update:modelValue\", value);\n};\n</script>\n\n<template>\n <div>\n <ul role=\"list\" class=\"pv-tab-list\">\n <li\n v-for=\"option in options\"\n :key=\"option.value\"\n style=\"cursor: pointer\"\n @click=\"selectOption(option.value)\"\n :data-active=\"modelValue === option.value ? true : null\"\n >\n <button class=\"pv-text-body-xs\" style=\"font-weight: 500\">\n {{ option.label }}\n </button>\n </li>\n </ul>\n </div>\n</template>\n\n<style scoped>\n.pv-tab-list {\n border: none;\n}\n.pv-tab-list :where(li)[data-active]:after {\n content: \"\";\n display: block;\n height: 2px;\n width: 100%;\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n background-color: #176f6f;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from \"vue\";\nimport { sizeMap } from \"@/components/base/baseProps\";\nimport { PvCompanyLogoSize } from \"./types\";\n\ntype PvCompanyLogoProps = {\n /** Base URL path where company logo SVGs are hosted. */\n basePath?: string;\n /** Company name used to resolve the logo filename. */\n name: string;\n /** Display size of the logo. Maps to a fixed pixel width. */\n size?: PvCompanyLogoSize;\n /** When provided, overrides the computed image URL entirely (ignores `name` and `basePath`). */\n srcPathOverride?: string;\n};\n\nconst props = withDefaults(defineProps<PvCompanyLogoProps>(), {\n basePath: \"https://static-assets.turquoise.health/shared-logos/prd/payers\",\n size: \"md\",\n});\n\nconst isValidSrc = ref(true);\n\nconst iconSize = computed(() => {\n return sizeMap[props.size] || \"32px\"; // Default to md size if not found\n});\n\nconst classes = computed(() => ({\n [`pv-icon`]: isValidSrc.value,\n [`pv-company-${props.size}`]: props.size && !isValidSrc.value,\n}));\n\nconst styles = computed(() => ({\n width: iconSize.value,\n}));\n\nconst modifiedName = computed((): string => {\n const snakeCaseName = props.name\n .toLowerCase()\n .replace(/[^a-z\\s]/g, \"\")\n .trim()\n .replace(/\\s+/g, \"_\");\n return `${snakeCaseName}.svg`;\n});\n\nconst imageSource = computed(() => {\n if (props.srcPathOverride) {\n return props.srcPathOverride;\n }\n return `${props.basePath}/${modifiedName.value}`;\n});\n\n// reset the isValidSrc when the name changes, and let @error handler set it to false if the image fails to load\nwatch(imageSource, () => {\n isValidSrc.value = true;\n});\n</script>\n\n<template>\n <div class=\"pv-flex\" data-testid=\"pv-company-logo\">\n <div v-if=\"isValidSrc\" :class=\"classes\" :style=\"styles\">\n <img :src=\"imageSource\" alt=\"\" @error=\"isValidSrc = false\" />\n </div>\n <div v-else :class=\"classes\"></div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from \"vue\";\nimport { sizeMap } from \"@/components/base/baseProps\";\nimport { PvCompanyLogoSize } from \"./types\";\n\ntype PvCompanyLogoProps = {\n /** Base URL path where company logo SVGs are hosted. */\n basePath?: string;\n /** Company name used to resolve the logo filename. */\n name: string;\n /** Display size of the logo. Maps to a fixed pixel width. */\n size?: PvCompanyLogoSize;\n /** When provided, overrides the computed image URL entirely (ignores `name` and `basePath`). */\n srcPathOverride?: string;\n};\n\nconst props = withDefaults(defineProps<PvCompanyLogoProps>(), {\n basePath: \"https://static-assets.turquoise.health/shared-logos/prd/payers\",\n size: \"md\",\n});\n\nconst isValidSrc = ref(true);\n\nconst iconSize = computed(() => {\n return sizeMap[props.size] || \"32px\"; // Default to md size if not found\n});\n\nconst classes = computed(() => ({\n [`pv-icon`]: isValidSrc.value,\n [`pv-company-${props.size}`]: props.size && !isValidSrc.value,\n}));\n\nconst styles = computed(() => ({\n width: iconSize.value,\n}));\n\nconst modifiedName = computed((): string => {\n const snakeCaseName = props.name\n .toLowerCase()\n .replace(/[^a-z\\s]/g, \"\")\n .trim()\n .replace(/\\s+/g, \"_\");\n return `${snakeCaseName}.svg`;\n});\n\nconst imageSource = computed(() => {\n if (props.srcPathOverride) {\n return props.srcPathOverride;\n }\n return `${props.basePath}/${modifiedName.value}`;\n});\n\n// reset the isValidSrc when the name changes, and let @error handler set it to false if the image fails to load\nwatch(imageSource, () => {\n isValidSrc.value = true;\n});\n</script>\n\n<template>\n <div class=\"pv-flex\" data-testid=\"pv-company-logo\">\n <div v-if=\"isValidSrc\" :class=\"classes\" :style=\"styles\">\n <img :src=\"imageSource\" alt=\"\" @error=\"isValidSrc = false\" />\n </div>\n <div v-else :class=\"classes\"></div>\n </div>\n</template>\n","<script lang=\"ts\">\nimport { watch, useTemplateRef } from \"vue\";\n</script>\n\n<script setup lang=\"ts\">\nexport interface ModalProps {\n header: string;\n subheader?: string;\n disableCloseOnClickOutside?: boolean;\n hideFooter?: boolean;\n}\n\nconst props = withDefaults(defineProps<ModalProps>(), {\n disableCloseOnClickOutside: false,\n hideFooter: false,\n});\n\nconst dialogRef = useTemplateRef<HTMLDialogElement | null>(\"dialog\");\nconst showModal = defineModel<boolean>({\n required: true,\n});\n\nwatch(\n () => showModal.value,\n () => {\n if (showModal.value) {\n dialogRef.value?.showModal();\n } else {\n dialogRef.value?.close();\n }\n },\n);\n\nconst handleClose = () => {\n showModal.value = false;\n};\n\nconst handleBackdropClick = (e: MouseEvent) => {\n if (!props.disableCloseOnClickOutside && e.target === dialogRef.value) {\n handleClose();\n }\n};\n</script>\n\n<template>\n <dialog\n class=\"pv-modal-sm\"\n ref=\"dialog\"\n style=\"--max-width: 480px\"\n v-on:close=\"handleClose\"\n v-on:click=\"handleBackdropClick\"\n >\n <div class=\"pv-inset-squish-12\">\n <div class=\"pv-flex pv-flex-vertical pv-stack-16\" style=\"--flex-align: flex-start\">\n <span class=\"pv-heading-3\">{{ header }}</span>\n <span v-if=\"subheader\" class=\"pv-text-body-md\">{{ subheader }}</span>\n </div>\n <slot name=\"body\" />\n </div>\n <div v-if=\"!hideFooter\" class=\"pv-inset-squish-12 pv-border-top\" style=\"--color-border: #d2d8dc\">\n <slot name=\"footer\" />\n </div>\n </dialog>\n</template>\n","<script lang=\"ts\">\nimport { watch, useTemplateRef } from \"vue\";\n</script>\n\n<script setup lang=\"ts\">\nexport interface ModalProps {\n header: string;\n subheader?: string;\n disableCloseOnClickOutside?: boolean;\n hideFooter?: boolean;\n}\n\nconst props = withDefaults(defineProps<ModalProps>(), {\n disableCloseOnClickOutside: false,\n hideFooter: false,\n});\n\nconst dialogRef = useTemplateRef<HTMLDialogElement | null>(\"dialog\");\nconst showModal = defineModel<boolean>({\n required: true,\n});\n\nwatch(\n () => showModal.value,\n () => {\n if (showModal.value) {\n dialogRef.value?.showModal();\n } else {\n dialogRef.value?.close();\n }\n },\n);\n\nconst handleClose = () => {\n showModal.value = false;\n};\n\nconst handleBackdropClick = (e: MouseEvent) => {\n if (!props.disableCloseOnClickOutside && e.target === dialogRef.value) {\n handleClose();\n }\n};\n</script>\n\n<template>\n <dialog\n class=\"pv-modal-sm\"\n ref=\"dialog\"\n style=\"--max-width: 480px\"\n v-on:close=\"handleClose\"\n v-on:click=\"handleBackdropClick\"\n >\n <div class=\"pv-inset-squish-12\">\n <div class=\"pv-flex pv-flex-vertical pv-stack-16\" style=\"--flex-align: flex-start\">\n <span class=\"pv-heading-3\">{{ header }}</span>\n <span v-if=\"subheader\" class=\"pv-text-body-md\">{{ subheader }}</span>\n </div>\n <slot name=\"body\" />\n </div>\n <div v-if=\"!hideFooter\" class=\"pv-inset-squish-12 pv-border-top\" style=\"--color-border: #d2d8dc\">\n <slot name=\"footer\" />\n </div>\n </dialog>\n</template>\n","export enum BannerOrientationsEnum {\n Vertical = \"Vertical\",\n Horizontal = \"Horizontal\",\n}\n\nexport enum BannerVariantsEnum {\n Primary = \"Primary\",\n Secondary = \"Secondary\",\n Tertiary = \"Tertiary\",\n}\n\nexport type BannerOrientations = `${BannerOrientationsEnum}`;\nexport type BannerVariants = `${BannerVariantsEnum}`;\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { BannerOrientations, BannerVariants, BannerVariantsEnum, BannerOrientationsEnum } from \"./types\";\n\nexport interface PvBannerProps {\n /** Primary text displayed in the banner */\n label: string;\n /** Secondary descriptive text displayed below the label */\n description?: string;\n /** Icon name to display alongside the banner content */\n icon?: string;\n /** Visual style variant of the banner */\n variant?: BannerVariants;\n /** Layout orientation of the banner */\n orientation?: BannerOrientations;\n}\n\nwithDefaults(defineProps<PvBannerProps>(), {\n orientation: BannerOrientationsEnum.Horizontal,\n variant: BannerVariantsEnum.Primary,\n});\n</script>\n\n<template>\n <div\n data-testid=\"pv-banner\"\n :class=\"[\n {\n 'pv-banner-primary': variant === BannerVariantsEnum.Primary,\n 'pv-banner-secondary': variant === BannerVariantsEnum.Secondary,\n 'pv-banner-tertiary': variant === BannerVariantsEnum.Tertiary,\n 'pv-flex pv-space-between': orientation === BannerOrientationsEnum.Horizontal,\n },\n ]\"\n >\n <div\n :class=\"[\n 'pv-flex',\n {\n 'pv-stack-16': orientation === BannerOrientationsEnum.Vertical && $slots.action,\n },\n ]\"\n >\n <slot name=\"left\"></slot>\n <PvIcon v-if=\"icon\" data-testid=\"pv-banner-icon\" class=\"pv-text-brand\" :name=\"icon\" />\n <div>\n <p\n :class=\"[\n ' pv-text-title-md pv-line-clamp',\n {\n 'pv-stack-4': description,\n },\n ]\"\n style=\"--lines: 2; font-weight: 500\"\n :title=\"label\"\n >\n {{ label }}\n </p>\n <p v-if=\"description\" class=\"pv-text-body-sm pv-line-clamp\" style=\"--lines: 2\" :title=\"description\">\n {{ description }}\n </p>\n </div>\n </div>\n <div class=\"pv-flex\">\n <slot name=\"action\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { BannerOrientations, BannerVariants, BannerVariantsEnum, BannerOrientationsEnum } from \"./types\";\n\nexport interface PvBannerProps {\n /** Primary text displayed in the banner */\n label: string;\n /** Secondary descriptive text displayed below the label */\n description?: string;\n /** Icon name to display alongside the banner content */\n icon?: string;\n /** Visual style variant of the banner */\n variant?: BannerVariants;\n /** Layout orientation of the banner */\n orientation?: BannerOrientations;\n}\n\nwithDefaults(defineProps<PvBannerProps>(), {\n orientation: BannerOrientationsEnum.Horizontal,\n variant: BannerVariantsEnum.Primary,\n});\n</script>\n\n<template>\n <div\n data-testid=\"pv-banner\"\n :class=\"[\n {\n 'pv-banner-primary': variant === BannerVariantsEnum.Primary,\n 'pv-banner-secondary': variant === BannerVariantsEnum.Secondary,\n 'pv-banner-tertiary': variant === BannerVariantsEnum.Tertiary,\n 'pv-flex pv-space-between': orientation === BannerOrientationsEnum.Horizontal,\n },\n ]\"\n >\n <div\n :class=\"[\n 'pv-flex',\n {\n 'pv-stack-16': orientation === BannerOrientationsEnum.Vertical && $slots.action,\n },\n ]\"\n >\n <slot name=\"left\"></slot>\n <PvIcon v-if=\"icon\" data-testid=\"pv-banner-icon\" class=\"pv-text-brand\" :name=\"icon\" />\n <div>\n <p\n :class=\"[\n ' pv-text-title-md pv-line-clamp',\n {\n 'pv-stack-4': description,\n },\n ]\"\n style=\"--lines: 2; font-weight: 500\"\n :title=\"label\"\n >\n {{ label }}\n </p>\n <p v-if=\"description\" class=\"pv-text-body-sm pv-line-clamp\" style=\"--lines: 2\" :title=\"description\">\n {{ description }}\n </p>\n </div>\n </div>\n <div class=\"pv-flex\">\n <slot name=\"action\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport PvCompanyLogo from \"../PvCompanyLogo/PvCompanyLogo.vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { TagSize } from \"@/components/base/PvTag/types\";\n\nexport interface PvCompanyTag {\n /**\n * Company name. Displayed on the left\n */\n companyName: string;\n /**\n * Tag size\n */\n size?: TagSize;\n /**\n * Show clear left icon\n */\n showClear?: boolean;\n /**\n * Spine - dotted state\n */\n spine?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvCompanyTag>(), {\n showClear: false,\n size: \"md\",\n});\n\ndefineEmits<{\n (e: \"handle-close\", companyName: string): void;\n (e: \"handle-click\", companyName: string): void;\n}>();\n\nconst tagSizeClass = computed(() => {\n switch (props.size) {\n case \"lg\": {\n return \"pv-tag-lg\";\n }\n case \"sm\": {\n return \"pv-tag-sm\";\n }\n default: {\n return \"\";\n }\n }\n});\n</script>\n\n<template>\n <button\n :class=\"['pv-tag-tertiary', tagSizeClass]\"\n @click=\"$emit('handle-click', companyName)\"\n data-testid=\"pv-company-tag\"\n >\n <PvCompanyLogo\n :class=\"size === 'lg' ? 'pv-company-sm' : 'pv-company-xs'\"\n data-testid=\"pv-company-tag-icon\"\n :size=\"size === 'lg' ? 'sm' : 'xs'\"\n :name=\"companyName\"\n />\n <span\n :class=\"[\n {\n 'pv-underline-dotted': spine,\n },\n ]\"\n >\n {{ companyName }}\n </span>\n <PvIcon\n data-testid=\"pv-company-tag-close-icon\"\n :size=\"12\"\n name=\"close\"\n v-if=\"showClear\"\n @click.stop=\"$emit('handle-close', companyName)\"\n />\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport PvCompanyLogo from \"../PvCompanyLogo/PvCompanyLogo.vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { TagSize } from \"@/components/base/PvTag/types\";\n\nexport interface PvCompanyTag {\n /**\n * Company name. Displayed on the left\n */\n companyName: string;\n /**\n * Tag size\n */\n size?: TagSize;\n /**\n * Show clear left icon\n */\n showClear?: boolean;\n /**\n * Spine - dotted state\n */\n spine?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvCompanyTag>(), {\n showClear: false,\n size: \"md\",\n});\n\ndefineEmits<{\n (e: \"handle-close\", companyName: string): void;\n (e: \"handle-click\", companyName: string): void;\n}>();\n\nconst tagSizeClass = computed(() => {\n switch (props.size) {\n case \"lg\": {\n return \"pv-tag-lg\";\n }\n case \"sm\": {\n return \"pv-tag-sm\";\n }\n default: {\n return \"\";\n }\n }\n});\n</script>\n\n<template>\n <button\n :class=\"['pv-tag-tertiary', tagSizeClass]\"\n @click=\"$emit('handle-click', companyName)\"\n data-testid=\"pv-company-tag\"\n >\n <PvCompanyLogo\n :class=\"size === 'lg' ? 'pv-company-sm' : 'pv-company-xs'\"\n data-testid=\"pv-company-tag-icon\"\n :size=\"size === 'lg' ? 'sm' : 'xs'\"\n :name=\"companyName\"\n />\n <span\n :class=\"[\n {\n 'pv-underline-dotted': spine,\n },\n ]\"\n >\n {{ companyName }}\n </span>\n <PvIcon\n data-testid=\"pv-company-tag-close-icon\"\n :size=\"12\"\n name=\"close\"\n v-if=\"showClear\"\n @click.stop=\"$emit('handle-close', companyName)\"\n />\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport { TagSize } from \"@/components/base/PvTag/types\";\n\nexport interface PvSuggestionTag {\n /**\n * Tag size\n */\n size?: TagSize;\n /**\n * Tag Label\n */\n label: string;\n /**\n * Tag Icon\n */\n icon?: string;\n /**\n * Icon class\n */\n iconClasses?: string[];\n /**\n * Show rounded state\n */\n rounded?: boolean;\n /**\n * Disable the tag, preventing interaction\n */\n disabled?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvSuggestionTag>(), {\n size: \"md\",\n disabled: false,\n});\n\ndefineEmits<{\n (e: \"handle-click\", label: string): void;\n}>();\n\nconst tagSizeClass = computed(() => {\n switch (props.size) {\n case \"lg\": {\n return \"pv-tag-lg\";\n }\n case \"sm\": {\n return \"pv-tag-sm\";\n }\n default: {\n return \"\";\n }\n }\n});\n</script>\n\n<template>\n <button\n :class=\"['pv-border-dashed pv-tag-secondary', tagSizeClass]\"\n @click=\"$emit('handle-click', label)\"\n data-testid=\"pv-suggestion-tag\"\n style=\"max-width: 100%\"\n :data-style=\"rounded ? 'rounded' : undefined\"\n :disabled=\"disabled\"\n :title=\"label\"\n >\n <PvIcon data-testid=\"pv-suggestion-tag-icon\" v-if=\"icon\" :name=\"icon\" :size=\"12\" :class=\"iconClasses\" />\n <span class=\"pv-truncate\">\n {{ label }}\n </span>\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport { TagSize } from \"@/components/base/PvTag/types\";\n\nexport interface PvSuggestionTag {\n /**\n * Tag size\n */\n size?: TagSize;\n /**\n * Tag Label\n */\n label: string;\n /**\n * Tag Icon\n */\n icon?: string;\n /**\n * Icon class\n */\n iconClasses?: string[];\n /**\n * Show rounded state\n */\n rounded?: boolean;\n /**\n * Disable the tag, preventing interaction\n */\n disabled?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvSuggestionTag>(), {\n size: \"md\",\n disabled: false,\n});\n\ndefineEmits<{\n (e: \"handle-click\", label: string): void;\n}>();\n\nconst tagSizeClass = computed(() => {\n switch (props.size) {\n case \"lg\": {\n return \"pv-tag-lg\";\n }\n case \"sm\": {\n return \"pv-tag-sm\";\n }\n default: {\n return \"\";\n }\n }\n});\n</script>\n\n<template>\n <button\n :class=\"['pv-border-dashed pv-tag-secondary', tagSizeClass]\"\n @click=\"$emit('handle-click', label)\"\n data-testid=\"pv-suggestion-tag\"\n style=\"max-width: 100%\"\n :data-style=\"rounded ? 'rounded' : undefined\"\n :disabled=\"disabled\"\n :title=\"label\"\n >\n <PvIcon data-testid=\"pv-suggestion-tag-icon\" v-if=\"icon\" :name=\"icon\" :size=\"12\" :class=\"iconClasses\" />\n <span class=\"pv-truncate\">\n {{ label }}\n </span>\n </button>\n</template>\n","<script setup lang=\"ts\">\nimport PvCounterBadge from \"../PvCounterBadge/PvCounterBadge.vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { ChevronPosition } from \"./types\";\nimport { computed } from \"vue\";\nimport type { CSSProperties } from \"vue\";\n\ninterface PvAccordionProps {\n /** Position of the chevron icon relative to the header text */\n chevronPosition?: ChevronPosition;\n /** Orientation of the chevron for the open/closed states (up-down vs right-down) */\n chevronVariant?: \"vertical\" | \"horizontal\";\n /** Whether the accordion is open by default on initial render */\n defaultOpen?: boolean;\n /** Optional counter badge value displayed next to the header text */\n counter?: number;\n /** Enables a custom trigger slot instead of the default header text */\n enableTriggerSlot?: boolean;\n /** Makes the trigger element expand to fill its container width */\n enableTriggerFullWidth?: boolean;\n /** Text displayed as the accordion header */\n header?: string;\n /** Custom CSS styles applied to the summary/trigger element */\n summaryStyles?: CSSProperties;\n /** CSS class bindings applied to the summary/trigger element */\n summaryClasses?: Record<string, boolean>;\n /** Custom CSS styles applied to the content container */\n contentStyles?: CSSProperties;\n}\n\nconst props = withDefaults(defineProps<PvAccordionProps>(), {\n chevronVariant: \"vertical\",\n chevronPosition: \"right\",\n enableTriggerSlot: false,\n enableTriggerFullWidth: false,\n});\n\nconst accordionOpen = defineModel<boolean>();\n\ndefineEmits<{\n (e: \"summary-mouseenter\"): void;\n (e: \"summary-mouseleave\"): void;\n}>();\n\nif (props.defaultOpen !== undefined) {\n accordionOpen.value = props.defaultOpen;\n}\n\nconst toggleAccordionState = (event: Event) => {\n const detailsElement = event.target as HTMLDetailsElement;\n accordionOpen.value = detailsElement.open;\n};\n\nconst triggerStyles = {\n width: props.enableTriggerFullWidth ? \"100%\" : \"fit-content\",\n};\n\nconst chevronState = computed(() => {\n if (props.chevronVariant === \"horizontal\") {\n if (props.chevronPosition === \"left\") {\n return accordionOpen.value ? \"chevron-down\" : \"chevron-right\";\n } else {\n return accordionOpen.value ? \"chevron-down\" : \"chevron-left\";\n }\n } else {\n return accordionOpen.value ? \"chevron-up\" : \"chevron-down\";\n }\n});\n</script>\n\n<template>\n <details data-testid=\"pv-accordion\" class=\"pv-accordion\" :open=\"accordionOpen\" @toggle=\"toggleAccordionState\">\n <summary\n :class=\"['pv-flex pv-space-between pv-relative', summaryClasses]\"\n :style=\"{ ...triggerStyles, ...summaryStyles }\"\n @mouseenter=\"$emit('summary-mouseenter')\"\n @mouseleave=\"$emit('summary-mouseleave')\"\n >\n <PvIcon v-if=\"chevronPosition === 'left'\" :name=\"chevronState\" />\n <template v-if=\"enableTriggerSlot\">\n <slot name=\"trigger\" />\n </template>\n <template v-else>\n <span>\n {{ header }}\n </span>\n <PvCounterBadge v-if=\"counter\" :value=\"counter\" variant=\"secondary\" size=\"sm\" />\n </template>\n <PvIcon v-if=\"chevronPosition === 'right'\" :name=\"chevronState\" />\n </summary>\n <div :style=\"contentStyles\">\n <slot />\n </div>\n </details>\n</template>\n\n<style scoped>\nsummary {\n background-image: none;\n padding-right: 2px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport PvCounterBadge from \"../PvCounterBadge/PvCounterBadge.vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { ChevronPosition } from \"./types\";\nimport { computed } from \"vue\";\nimport type { CSSProperties } from \"vue\";\n\ninterface PvAccordionProps {\n /** Position of the chevron icon relative to the header text */\n chevronPosition?: ChevronPosition;\n /** Orientation of the chevron for the open/closed states (up-down vs right-down) */\n chevronVariant?: \"vertical\" | \"horizontal\";\n /** Whether the accordion is open by default on initial render */\n defaultOpen?: boolean;\n /** Optional counter badge value displayed next to the header text */\n counter?: number;\n /** Enables a custom trigger slot instead of the default header text */\n enableTriggerSlot?: boolean;\n /** Makes the trigger element expand to fill its container width */\n enableTriggerFullWidth?: boolean;\n /** Text displayed as the accordion header */\n header?: string;\n /** Custom CSS styles applied to the summary/trigger element */\n summaryStyles?: CSSProperties;\n /** CSS class bindings applied to the summary/trigger element */\n summaryClasses?: Record<string, boolean>;\n /** Custom CSS styles applied to the content container */\n contentStyles?: CSSProperties;\n}\n\nconst props = withDefaults(defineProps<PvAccordionProps>(), {\n chevronVariant: \"vertical\",\n chevronPosition: \"right\",\n enableTriggerSlot: false,\n enableTriggerFullWidth: false,\n});\n\nconst accordionOpen = defineModel<boolean>();\n\ndefineEmits<{\n (e: \"summary-mouseenter\"): void;\n (e: \"summary-mouseleave\"): void;\n}>();\n\nif (props.defaultOpen !== undefined) {\n accordionOpen.value = props.defaultOpen;\n}\n\nconst toggleAccordionState = (event: Event) => {\n const detailsElement = event.target as HTMLDetailsElement;\n accordionOpen.value = detailsElement.open;\n};\n\nconst triggerStyles = {\n width: props.enableTriggerFullWidth ? \"100%\" : \"fit-content\",\n};\n\nconst chevronState = computed(() => {\n if (props.chevronVariant === \"horizontal\") {\n if (props.chevronPosition === \"left\") {\n return accordionOpen.value ? \"chevron-down\" : \"chevron-right\";\n } else {\n return accordionOpen.value ? \"chevron-down\" : \"chevron-left\";\n }\n } else {\n return accordionOpen.value ? \"chevron-up\" : \"chevron-down\";\n }\n});\n</script>\n\n<template>\n <details data-testid=\"pv-accordion\" class=\"pv-accordion\" :open=\"accordionOpen\" @toggle=\"toggleAccordionState\">\n <summary\n :class=\"['pv-flex pv-space-between pv-relative', summaryClasses]\"\n :style=\"{ ...triggerStyles, ...summaryStyles }\"\n @mouseenter=\"$emit('summary-mouseenter')\"\n @mouseleave=\"$emit('summary-mouseleave')\"\n >\n <PvIcon v-if=\"chevronPosition === 'left'\" :name=\"chevronState\" />\n <template v-if=\"enableTriggerSlot\">\n <slot name=\"trigger\" />\n </template>\n <template v-else>\n <span>\n {{ header }}\n </span>\n <PvCounterBadge v-if=\"counter\" :value=\"counter\" variant=\"secondary\" size=\"sm\" />\n </template>\n <PvIcon v-if=\"chevronPosition === 'right'\" :name=\"chevronState\" />\n </summary>\n <div :style=\"contentStyles\">\n <slot />\n </div>\n </details>\n</template>\n\n<style scoped>\nsummary {\n background-image: none;\n padding-right: 2px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, useTemplateRef, onMounted } from \"vue\";\nimport { onKeyStroke } from \"@vueuse/core\";\n\nexport interface PvSearchInputProps {\n /**\n * Placeholder text shown when the input is empty.\n */\n placeholder?: string;\n /**\n * When true, the input is non-interactive and visually dimmed.\n */\n disabled?: boolean;\n /** When true, displays a keyboard shortcut badge (\"/\" key) and registers the hotkey to focus the input. */\n displayShortcut?: boolean;\n}\n\nexport interface PvSearchInputExposed {\n input: HTMLInputElement | null;\n}\n\nconst props = withDefaults(defineProps<PvSearchInputProps>(), {\n placeholder: \"Search\",\n disabled: false,\n});\n\nconst SHORTCUT = \"/\";\n\nconst input = useTemplateRef<HTMLInputElement | null>(\"search-input\");\nconst modelValue = defineModel<string>({ required: false, default: \"\" });\n\nconst pvSearchInputClasses = computed(() => {\n return {\n \"pv-input-search\": true,\n \"pv-full-width\": true,\n \"pv-input-padded-end\": true,\n };\n});\n\nonMounted(() => {\n if (!props.displayShortcut) return;\n\n onKeyStroke(SHORTCUT, (e) => {\n const target = e.target as HTMLElement | null;\n\n const isTyping =\n target instanceof HTMLInputElement ||\n target instanceof HTMLTextAreaElement ||\n (target?.isContentEditable ?? false);\n\n const isCurrentInputFocused = document.activeElement === input.value;\n\n if (!isTyping || isCurrentInputFocused) {\n if (!isCurrentInputFocused) {\n e.preventDefault();\n input.value?.focus();\n }\n }\n });\n});\n\ndefineExpose({ input });\n</script>\n\n<template>\n <div class=\"pv-relative\">\n <input\n ref=\"search-input\"\n v-model=\"modelValue\"\n data-testid=\"pv-search-input\"\n type=\"text\"\n :disabled=\"disabled\"\n :class=\"pvSearchInputClasses\"\n :placeholder=\"placeholder\"\n />\n <kbd v-if=\"displayShortcut\" data-testid=\"pv-search-input-shortcut\" class=\"pv-kbd\">\n {{ SHORTCUT }}\n </kbd>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useTemplateRef, onMounted } from \"vue\";\nimport { onKeyStroke } from \"@vueuse/core\";\n\nexport interface PvSearchInputProps {\n /**\n * Placeholder text shown when the input is empty.\n */\n placeholder?: string;\n /**\n * When true, the input is non-interactive and visually dimmed.\n */\n disabled?: boolean;\n /** When true, displays a keyboard shortcut badge (\"/\" key) and registers the hotkey to focus the input. */\n displayShortcut?: boolean;\n}\n\nexport interface PvSearchInputExposed {\n input: HTMLInputElement | null;\n}\n\nconst props = withDefaults(defineProps<PvSearchInputProps>(), {\n placeholder: \"Search\",\n disabled: false,\n});\n\nconst SHORTCUT = \"/\";\n\nconst input = useTemplateRef<HTMLInputElement | null>(\"search-input\");\nconst modelValue = defineModel<string>({ required: false, default: \"\" });\n\nconst pvSearchInputClasses = computed(() => {\n return {\n \"pv-input-search\": true,\n \"pv-full-width\": true,\n \"pv-input-padded-end\": true,\n };\n});\n\nonMounted(() => {\n if (!props.displayShortcut) return;\n\n onKeyStroke(SHORTCUT, (e) => {\n const target = e.target as HTMLElement | null;\n\n const isTyping =\n target instanceof HTMLInputElement ||\n target instanceof HTMLTextAreaElement ||\n (target?.isContentEditable ?? false);\n\n const isCurrentInputFocused = document.activeElement === input.value;\n\n if (!isTyping || isCurrentInputFocused) {\n if (!isCurrentInputFocused) {\n e.preventDefault();\n input.value?.focus();\n }\n }\n });\n});\n\ndefineExpose({ input });\n</script>\n\n<template>\n <div class=\"pv-relative\">\n <input\n ref=\"search-input\"\n v-model=\"modelValue\"\n data-testid=\"pv-search-input\"\n type=\"text\"\n :disabled=\"disabled\"\n :class=\"pvSearchInputClasses\"\n :placeholder=\"placeholder\"\n />\n <kbd v-if=\"displayShortcut\" data-testid=\"pv-search-input-shortcut\" class=\"pv-kbd\">\n {{ SHORTCUT }}\n </kbd>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport DatePicker from \"primevue/datepicker\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\n\nexport interface PvDatePickerProps {\n /**\n * Defines the quantity of the selection.\n */\n selectionMode?: \"single\" | \"multiple\" | \"range\" | undefined;\n /**\n * Format of the date. Defaults to PrimeVue Locale configuration.\n */\n dateFormat?: string | undefined;\n /**\n * When enabled, displays the datepicker as inline instead of an overlay.\n */\n inline?: boolean | undefined;\n /**\n * Whether days in other months shown before or after the current month are selectable. This only applies if the showOtherMonths option is set to true.\n */\n selectOtherMonths?: boolean | undefined;\n /**\n * Number of months to display.\n */\n numberOfMonths?: number | undefined;\n /**\n * Type of view to display.\n */\n view?: \"date\" | \"month\" | \"year\" | undefined;\n /**\n * The minimum selectable date.\n */\n minDate?: Date | undefined;\n /**\n * The maximum selectable date.\n */\n maxDate?: Date | undefined;\n /**\n * Array with dates to disable.\n */\n disabledDates?: Date[] | undefined;\n /**\n * Array with disabled weekday numbers.\n */\n disabledDays?: number[] | undefined;\n /**\n * Maximum number of selectable dates in multiple mode.\n */\n maxDateCount?: number | undefined;\n /**\n * Whether to display today and clear buttons at the footer.\n */\n showButtonBar?: boolean | undefined;\n /**\n * When enabled, datepicker will show week numbers.\n */\n showWeek?: boolean | undefined;\n /**\n * Whether to allow entering the date manually via typing.\n */\n manualInput?: boolean | undefined;\n /**\n * When present, it specifies that the component should be disabled.\n */\n disabled?: boolean | undefined;\n /**\n * When present, it specifies that the component should have invalid state style.\n */\n invalid?: boolean | undefined;\n /**\n * When present, it specifies that an input field is read-only.\n */\n readonly?: boolean | undefined;\n /**\n * Placeholder text for the input.\n */\n placeholder?: string | undefined;\n /**\n * When enabled, displays a button with icon next to input.\n */\n showIcon?: boolean;\n /**\n * When input should take 100% width\n */\n fullWidth?: boolean;\n /**\n * A valid query selector or an HTMLElement to specify where the overlay gets attached.\n */\n appendTo?: \"body\" | \"self\" | undefined;\n /**\n * Style class of the datepicker panel.\n */\n panelClass?: string | undefined;\n}\n\nconst date = defineModel<Date>({ required: true });\nconst props = withDefaults(defineProps<PvDatePickerProps>(), {\n appendTo: \"body\",\n});\n</script>\n\n<template>\n <DatePicker\n v-model=\"date\"\n v-bind=\"props\"\n :showIcon=\"showIcon\"\n :iconDisplay=\"showIcon ? 'input' : undefined\"\n :fluid=\"fullWidth\"\n >\n <template #inputicon=\"slotProps\">\n <PvIcon name=\"calendar\" @click=\"slotProps.clickCallback\" />\n </template>\n </DatePicker>\n</template>\n","<script setup lang=\"ts\">\nimport DatePicker from \"primevue/datepicker\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\n\nexport interface PvDatePickerProps {\n /**\n * Defines the quantity of the selection.\n */\n selectionMode?: \"single\" | \"multiple\" | \"range\" | undefined;\n /**\n * Format of the date. Defaults to PrimeVue Locale configuration.\n */\n dateFormat?: string | undefined;\n /**\n * When enabled, displays the datepicker as inline instead of an overlay.\n */\n inline?: boolean | undefined;\n /**\n * Whether days in other months shown before or after the current month are selectable. This only applies if the showOtherMonths option is set to true.\n */\n selectOtherMonths?: boolean | undefined;\n /**\n * Number of months to display.\n */\n numberOfMonths?: number | undefined;\n /**\n * Type of view to display.\n */\n view?: \"date\" | \"month\" | \"year\" | undefined;\n /**\n * The minimum selectable date.\n */\n minDate?: Date | undefined;\n /**\n * The maximum selectable date.\n */\n maxDate?: Date | undefined;\n /**\n * Array with dates to disable.\n */\n disabledDates?: Date[] | undefined;\n /**\n * Array with disabled weekday numbers.\n */\n disabledDays?: number[] | undefined;\n /**\n * Maximum number of selectable dates in multiple mode.\n */\n maxDateCount?: number | undefined;\n /**\n * Whether to display today and clear buttons at the footer.\n */\n showButtonBar?: boolean | undefined;\n /**\n * When enabled, datepicker will show week numbers.\n */\n showWeek?: boolean | undefined;\n /**\n * Whether to allow entering the date manually via typing.\n */\n manualInput?: boolean | undefined;\n /**\n * When present, it specifies that the component should be disabled.\n */\n disabled?: boolean | undefined;\n /**\n * When present, it specifies that the component should have invalid state style.\n */\n invalid?: boolean | undefined;\n /**\n * When present, it specifies that an input field is read-only.\n */\n readonly?: boolean | undefined;\n /**\n * Placeholder text for the input.\n */\n placeholder?: string | undefined;\n /**\n * When enabled, displays a button with icon next to input.\n */\n showIcon?: boolean;\n /**\n * When input should take 100% width\n */\n fullWidth?: boolean;\n /**\n * A valid query selector or an HTMLElement to specify where the overlay gets attached.\n */\n appendTo?: \"body\" | \"self\" | undefined;\n /**\n * Style class of the datepicker panel.\n */\n panelClass?: string | undefined;\n}\n\nconst date = defineModel<Date>({ required: true });\nconst props = withDefaults(defineProps<PvDatePickerProps>(), {\n appendTo: \"body\",\n});\n</script>\n\n<template>\n <DatePicker\n v-model=\"date\"\n v-bind=\"props\"\n :showIcon=\"showIcon\"\n :iconDisplay=\"showIcon ? 'input' : undefined\"\n :fluid=\"fullWidth\"\n >\n <template #inputicon=\"slotProps\">\n <PvIcon name=\"calendar\" @click=\"slotProps.clickCallback\" />\n </template>\n </DatePicker>\n</template>\n","import dayjs from \"dayjs\";\nimport utc from \"dayjs/plugin/utc\";\nimport timezone from \"dayjs/plugin/timezone\";\nimport customParseFormat from \"dayjs/plugin/advancedFormat\";\n\ndayjs.extend(customParseFormat);\ndayjs.extend(utc);\ndayjs.extend(timezone);\n\nexport const useDateTime = () => {\n const getCondensedDate = ({ date }: { date: Date }) => {\n return dayjs(date).format(\"MM/DD/YYYY\");\n };\n\n const getTime = ({ date, timezone }: { date: Date; timezone?: string }) => {\n if (timezone === undefined) {\n return dayjs(date).format(\"h:mm A\");\n } else {\n return dayjs(date).tz(timezone).format(\"h:mm A z\");\n }\n };\n\n return {\n getCondensedDate,\n getTime,\n };\n};\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvSize } from \"../baseProps\";\nimport { useDateTime } from \"./useDateTime\";\n\ntype DateTimeSize = Extract<PvSize, \"xs\" | \"sm\">;\n\ninterface PvDateTimeProps {\n /** Display format: \"condensed\" for MM/DD/YYYY, \"time\" for h:mm AM/PM */\n variants?: \"condensed\" | \"time\";\n /** IANA timezone identifier for time display (e.g. \"America/New_York\") */\n timezone?: string;\n /** Date object to format and display */\n date: Date;\n /** Text size of the displayed date/time */\n size?: DateTimeSize;\n}\n\nconst props = withDefaults(defineProps<PvDateTimeProps>(), {\n variants: \"condensed\",\n size: \"sm\",\n});\n\nconst { getCondensedDate, getTime } = useDateTime();\n\nconst dataFormat = computed(() => {\n switch (props.variants) {\n case \"time\": {\n return getTime({ date: props.date, timezone: props.timezone });\n }\n case \"condensed\": {\n return getCondensedDate({ date: props.date });\n }\n default: {\n return \"\";\n }\n }\n});\n</script>\n\n<template>\n <span\n data-testid=\"pv-date-time\"\n :class=\"[\n 'pv-text-secondary',\n {\n 'pv-text-body-xxs': size === 'xs',\n 'pv-text-body-md': size === 'sm',\n },\n ]\"\n >\n {{ dataFormat }}\n </span>\n</template>\n\n<style scoped>\n.pv-text-secondary {\n color: #4b595c;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvSize } from \"../baseProps\";\nimport { useDateTime } from \"./useDateTime\";\n\ntype DateTimeSize = Extract<PvSize, \"xs\" | \"sm\">;\n\ninterface PvDateTimeProps {\n /** Display format: \"condensed\" for MM/DD/YYYY, \"time\" for h:mm AM/PM */\n variants?: \"condensed\" | \"time\";\n /** IANA timezone identifier for time display (e.g. \"America/New_York\") */\n timezone?: string;\n /** Date object to format and display */\n date: Date;\n /** Text size of the displayed date/time */\n size?: DateTimeSize;\n}\n\nconst props = withDefaults(defineProps<PvDateTimeProps>(), {\n variants: \"condensed\",\n size: \"sm\",\n});\n\nconst { getCondensedDate, getTime } = useDateTime();\n\nconst dataFormat = computed(() => {\n switch (props.variants) {\n case \"time\": {\n return getTime({ date: props.date, timezone: props.timezone });\n }\n case \"condensed\": {\n return getCondensedDate({ date: props.date });\n }\n default: {\n return \"\";\n }\n }\n});\n</script>\n\n<template>\n <span\n data-testid=\"pv-date-time\"\n :class=\"[\n 'pv-text-secondary',\n {\n 'pv-text-body-xxs': size === 'xs',\n 'pv-text-body-md': size === 'sm',\n },\n ]\"\n >\n {{ dataFormat }}\n </span>\n</template>\n\n<style scoped>\n.pv-text-secondary {\n color: #4b595c;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { watch, useTemplateRef, onMounted } from \"vue\";\nimport { onKeyStroke, onClickOutside } from \"@vueuse/core\";\n\nimport PvSearchInput, { PvSearchInputProps } from \"../PvSearchInput/PvSearchInput.vue\";\nimport PvButton from \"../PvButton/PvButton.vue\";\n\nexport interface PvDrawer {\n header?: string;\n subheader?: string;\n showSearchbar?: boolean;\n closeOnClickOutside?: boolean;\n searchInputProps?: PvSearchInputProps;\n}\n\nconst props = withDefaults(defineProps<PvDrawer>(), {\n closeOnClickOutside: false,\n});\n\nconst emit = defineEmits<{\n (e: \"click-outside\"): void;\n}>();\n\nconst sidePanel = useTemplateRef(\"sidePanel\");\nconst searchInput = defineModel<string>(\"searchInput\", {\n required: false,\n});\nconst showDrawer = defineModel<boolean>({\n required: true,\n});\n\nonMounted(() => {\n if (showDrawer.value) {\n sidePanel?.value?.setAttribute(\"open\", \"true\");\n }\n\n if (props.closeOnClickOutside) {\n attachClickOutsideHandler();\n }\n});\n\nconst attachClickOutsideHandler = () => {\n if (!sidePanel.value) return;\n\n onClickOutside(\n sidePanel.value,\n () => {\n if (showDrawer.value) {\n emit(\"click-outside\");\n handleClose();\n }\n },\n { ignore: [\".pv-click-outside-ignore\"] },\n );\n};\n\nconst handleClose = () => {\n sidePanel?.value?.removeAttribute(\"open\");\n showDrawer.value = false;\n};\n\nwatch(\n () => showDrawer.value,\n () => {\n if (showDrawer.value) {\n sidePanel?.value?.setAttribute(\"open\", \"true\");\n } else {\n sidePanel?.value?.removeAttribute(\"open\");\n }\n },\n);\n\nonKeyStroke(\"Escape\", () => {\n if (sidePanel.value && showDrawer.value) {\n handleClose();\n }\n});\n</script>\n\n<template>\n <div\n class=\"pv-drawer pv-surface\"\n ref=\"sidePanel\"\n data-testid=\"pv-drawer\"\n style=\"display: flex; flex-direction: column; height: 100%\"\n >\n <!-- Header Section (Fixed) -->\n <div class=\"pv-inset-squish-12 pv-border-bottom\" style=\"flex-shrink: 0\">\n <slot v-if=\"$slots.header\" name=\"header\" />\n <template v-else>\n <div class=\"pv-flex-vertical pv-stack-16\" style=\"--flex-align: flex-start\">\n <div class=\"pv-flex pv-full-width\">\n <span class=\"pv-full-width pv-heading-3\">{{ header }}</span>\n <PvButton\n left-icon=\"close\"\n ariaLabel=\"Close\"\n size=\"md\"\n @click=\"handleClose\"\n data-testid=\"pv-side-panel-close-button\"\n variant=\"ghost\"\n />\n </div>\n <span v-if=\"subheader\" class=\"pv-text-body-md\">{{ subheader }}</span>\n </div>\n <div v-if=\"showSearchbar && searchInput !== undefined\" class=\"pv-inset-inline-16\">\n <PvSearchInput\n data-testid=\"pv-side-panel-input-search\"\n v-model=\"searchInput\"\n v-bind=\"props.searchInputProps\"\n />\n </div>\n </template>\n </div>\n\n <!-- Main Content Section (Scrollable) -->\n <div class=\"pv-inset-inline-16\" style=\"flex: 1; overflow-y: auto; min-height: 0\">\n <slot />\n </div>\n\n <!-- Footer Section (Fixed) -->\n <div v-if=\"$slots.footer\" class=\"pv-inset-squish-12 pv-border-top\" style=\"flex-shrink: 0\">\n <slot name=\"footer\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { watch, useTemplateRef, onMounted } from \"vue\";\nimport { onKeyStroke, onClickOutside } from \"@vueuse/core\";\n\nimport PvSearchInput, { PvSearchInputProps } from \"../PvSearchInput/PvSearchInput.vue\";\nimport PvButton from \"../PvButton/PvButton.vue\";\n\nexport interface PvDrawer {\n header?: string;\n subheader?: string;\n showSearchbar?: boolean;\n closeOnClickOutside?: boolean;\n searchInputProps?: PvSearchInputProps;\n}\n\nconst props = withDefaults(defineProps<PvDrawer>(), {\n closeOnClickOutside: false,\n});\n\nconst emit = defineEmits<{\n (e: \"click-outside\"): void;\n}>();\n\nconst sidePanel = useTemplateRef(\"sidePanel\");\nconst searchInput = defineModel<string>(\"searchInput\", {\n required: false,\n});\nconst showDrawer = defineModel<boolean>({\n required: true,\n});\n\nonMounted(() => {\n if (showDrawer.value) {\n sidePanel?.value?.setAttribute(\"open\", \"true\");\n }\n\n if (props.closeOnClickOutside) {\n attachClickOutsideHandler();\n }\n});\n\nconst attachClickOutsideHandler = () => {\n if (!sidePanel.value) return;\n\n onClickOutside(\n sidePanel.value,\n () => {\n if (showDrawer.value) {\n emit(\"click-outside\");\n handleClose();\n }\n },\n { ignore: [\".pv-click-outside-ignore\"] },\n );\n};\n\nconst handleClose = () => {\n sidePanel?.value?.removeAttribute(\"open\");\n showDrawer.value = false;\n};\n\nwatch(\n () => showDrawer.value,\n () => {\n if (showDrawer.value) {\n sidePanel?.value?.setAttribute(\"open\", \"true\");\n } else {\n sidePanel?.value?.removeAttribute(\"open\");\n }\n },\n);\n\nonKeyStroke(\"Escape\", () => {\n if (sidePanel.value && showDrawer.value) {\n handleClose();\n }\n});\n</script>\n\n<template>\n <div\n class=\"pv-drawer pv-surface\"\n ref=\"sidePanel\"\n data-testid=\"pv-drawer\"\n style=\"display: flex; flex-direction: column; height: 100%\"\n >\n <!-- Header Section (Fixed) -->\n <div class=\"pv-inset-squish-12 pv-border-bottom\" style=\"flex-shrink: 0\">\n <slot v-if=\"$slots.header\" name=\"header\" />\n <template v-else>\n <div class=\"pv-flex-vertical pv-stack-16\" style=\"--flex-align: flex-start\">\n <div class=\"pv-flex pv-full-width\">\n <span class=\"pv-full-width pv-heading-3\">{{ header }}</span>\n <PvButton\n left-icon=\"close\"\n ariaLabel=\"Close\"\n size=\"md\"\n @click=\"handleClose\"\n data-testid=\"pv-side-panel-close-button\"\n variant=\"ghost\"\n />\n </div>\n <span v-if=\"subheader\" class=\"pv-text-body-md\">{{ subheader }}</span>\n </div>\n <div v-if=\"showSearchbar && searchInput !== undefined\" class=\"pv-inset-inline-16\">\n <PvSearchInput\n data-testid=\"pv-side-panel-input-search\"\n v-model=\"searchInput\"\n v-bind=\"props.searchInputProps\"\n />\n </div>\n </template>\n </div>\n\n <!-- Main Content Section (Scrollable) -->\n <div class=\"pv-inset-inline-16\" style=\"flex: 1; overflow-y: auto; min-height: 0\">\n <slot />\n </div>\n\n <!-- Footer Section (Fixed) -->\n <div v-if=\"$slots.footer\" class=\"pv-inset-squish-12 pv-border-top\" style=\"flex-shrink: 0\">\n <slot name=\"footer\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvCounterBadge from \"../PvCounterBadge/PvCounterBadge.vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { Tab, TabSize } from \"./types\";\n\ninterface PvTabsProps {\n /** Array of tab objects defining each tab's label, icon, and counter */\n tabs: Tab[];\n /** Size of the tab list */\n size?: TabSize;\n}\n\nwithDefaults(defineProps<PvTabsProps>(), {\n size: \"lg\",\n});\n\nconst selectedTab = defineModel<string>({ required: true });\n\nconst handleSelectTab = (tab: string) => {\n selectedTab.value = tab;\n};\n\nconst isTabSelected = (tab: Tab) => {\n return tab.label === selectedTab.value ? true : null;\n};\n</script>\n\n<template>\n <ul\n data-testid=\"pv-tabs\"\n role=\"list\"\n :class=\"{\n 'pv-tab-list-small': size === 'lg',\n 'pv-tab-list': size === 'xl',\n }\"\n >\n <li\n v-for=\"tab in tabs\"\n :key=\"tab.label\"\n :data-active=\"isTabSelected(tab)\"\n data-testid=\"pv-tab\"\n type=\"button\"\n @click=\"() => handleSelectTab(tab.label)\"\n >\n <button type=\"button\">\n <PvIcon v-if=\"tab.icon\" :name=\"tab.icon\" />\n {{ tab.label }}\n <PvCounterBadge\n v-if=\"tab.counter\"\n :value=\"tab.counter\"\n :variant=\"isTabSelected(tab) ? 'primary' : 'tertiary'\"\n size=\"sm\"\n />\n </button>\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\">\nimport PvCounterBadge from \"../PvCounterBadge/PvCounterBadge.vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport { Tab, TabSize } from \"./types\";\n\ninterface PvTabsProps {\n /** Array of tab objects defining each tab's label, icon, and counter */\n tabs: Tab[];\n /** Size of the tab list */\n size?: TabSize;\n}\n\nwithDefaults(defineProps<PvTabsProps>(), {\n size: \"lg\",\n});\n\nconst selectedTab = defineModel<string>({ required: true });\n\nconst handleSelectTab = (tab: string) => {\n selectedTab.value = tab;\n};\n\nconst isTabSelected = (tab: Tab) => {\n return tab.label === selectedTab.value ? true : null;\n};\n</script>\n\n<template>\n <ul\n data-testid=\"pv-tabs\"\n role=\"list\"\n :class=\"{\n 'pv-tab-list-small': size === 'lg',\n 'pv-tab-list': size === 'xl',\n }\"\n >\n <li\n v-for=\"tab in tabs\"\n :key=\"tab.label\"\n :data-active=\"isTabSelected(tab)\"\n data-testid=\"pv-tab\"\n type=\"button\"\n @click=\"() => handleSelectTab(tab.label)\"\n >\n <button type=\"button\">\n <PvIcon v-if=\"tab.icon\" :name=\"tab.icon\" />\n {{ tab.label }}\n <PvCounterBadge\n v-if=\"tab.counter\"\n :value=\"tab.counter\"\n :variant=\"isTabSelected(tab) ? 'primary' : 'tertiary'\"\n size=\"sm\"\n />\n </button>\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\">\nimport { PvBreadcrumbsOptions } from \"./types\";\n\ninterface PvBreadcrumbsProps {\n /** Array of breadcrumb items defining the navigation trail */\n options: PvBreadcrumbsOptions[];\n}\n\ndefineProps<PvBreadcrumbsProps>();\n</script>\n\n<template>\n <ul class=\"pv-breadcrumbs\" role=\"list\" data-testid=\"pv-breadcrumbs\">\n <li v-for=\"option in options\" :key=\"option.label\">\n <a v-if=\"option.href\" :href=\"option.href\">{{ option.label }}</a>\n <template v-else>{{ option.label }}</template>\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\">\nimport { PvBreadcrumbsOptions } from \"./types\";\n\ninterface PvBreadcrumbsProps {\n /** Array of breadcrumb items defining the navigation trail */\n options: PvBreadcrumbsOptions[];\n}\n\ndefineProps<PvBreadcrumbsProps>();\n</script>\n\n<template>\n <ul class=\"pv-breadcrumbs\" role=\"list\" data-testid=\"pv-breadcrumbs\">\n <li v-for=\"option in options\" :key=\"option.label\">\n <a v-if=\"option.href\" :href=\"option.href\">{{ option.label }}</a>\n <template v-else>{{ option.label }}</template>\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\">\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport { MenuActionsVariant } from \"@/components/base/PvMultiSelectButton/types.ts\";\n\ndefineProps<{\n variant?: MenuActionsVariant;\n disabled?: boolean;\n}>();\n\ndefineEmits<{\n (e: \"handle-select-all\"): void;\n (e: \"handle-clear-all\"): void;\n (e: \"handle-cancel\"): void;\n (e: \"handle-confirm\"): void;\n}>();\n</script>\n\n<template>\n <div data-testid=\"pv-select-menu-control-panel\" class=\"pv-flex pv-space-between\">\n <template v-if=\"variant === 'select-clear'\">\n <PvButton\n variant=\"ghost\"\n data-testid=\"pv-select-menu-item-select-all\"\n @click=\"$emit('handle-select-all')\"\n label=\"Select All\"\n :disabled=\"disabled\"\n />\n <PvButton\n label=\"Clear All\"\n variant=\"ghost\"\n data-testid=\"pv-select-menu-item-clear-all\"\n @click=\"$emit('handle-clear-all')\"\n :disabled=\"disabled\"\n />\n </template>\n <template v-else-if=\"variant === 'cancel-confirm'\">\n <PvButton\n label=\"Cancel\"\n variant=\"ghost\"\n data-testid=\"pv-select-menu-item-cancel\"\n @click=\"$emit('handle-cancel')\"\n :disabled=\"disabled\"\n />\n <PvButton\n label=\"Confirm\"\n data-testid=\"pv-select-menu-item-confirm\"\n @click=\"$emit('handle-confirm')\"\n :disabled=\"disabled\"\n />\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport { MenuActionsVariant } from \"@/components/base/PvMultiSelectButton/types.ts\";\n\ndefineProps<{\n variant?: MenuActionsVariant;\n disabled?: boolean;\n}>();\n\ndefineEmits<{\n (e: \"handle-select-all\"): void;\n (e: \"handle-clear-all\"): void;\n (e: \"handle-cancel\"): void;\n (e: \"handle-confirm\"): void;\n}>();\n</script>\n\n<template>\n <div data-testid=\"pv-select-menu-control-panel\" class=\"pv-flex pv-space-between\">\n <template v-if=\"variant === 'select-clear'\">\n <PvButton\n variant=\"ghost\"\n data-testid=\"pv-select-menu-item-select-all\"\n @click=\"$emit('handle-select-all')\"\n label=\"Select All\"\n :disabled=\"disabled\"\n />\n <PvButton\n label=\"Clear All\"\n variant=\"ghost\"\n data-testid=\"pv-select-menu-item-clear-all\"\n @click=\"$emit('handle-clear-all')\"\n :disabled=\"disabled\"\n />\n </template>\n <template v-else-if=\"variant === 'cancel-confirm'\">\n <PvButton\n label=\"Cancel\"\n variant=\"ghost\"\n data-testid=\"pv-select-menu-item-cancel\"\n @click=\"$emit('handle-cancel')\"\n :disabled=\"disabled\"\n />\n <PvButton\n label=\"Confirm\"\n data-testid=\"pv-select-menu-item-confirm\"\n @click=\"$emit('handle-confirm')\"\n :disabled=\"disabled\"\n />\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { PvIconSize } from \"../baseProps\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport type { PvAvatarProps, PvAvatarSize } from \"./types\";\n\nconst avatarSizeToClass: Record<PvAvatarSize, string> = {\n sm: \"pv-avatar-16\",\n md: \"pv-avatar-20\",\n lg: \"pv-avatar-xs\",\n xl: \"pv-avatar-sm\",\n \"2x\": \"pv-avatar-md\",\n};\n\nconst iconSizeToAvatarSize: Partial<Record<PvAvatarSize, PvIconSize>> = {\n sm: 10,\n md: 12,\n lg: undefined,\n xl: 20,\n \"2x\": 20,\n};\n\nwithDefaults(defineProps<PvAvatarProps>(), {\n shape: \"circle\",\n size: \"lg\",\n});\n</script>\n\n<template>\n <div :class=\"avatarSizeToClass[size]\" data-testid=\"pv-avatar\" :data-style=\"variant\" :data-shape=\"shape\">\n <PvIcon v-if=\"icon\" :name=\"icon\" :size=\"iconSizeToAvatarSize[size]\" />\n <template v-else-if=\"initials\">{{ initials }}</template>\n <template v-else-if=\"image\">\n <img :src=\"image\" :alt=\"alt ?? ''\" />\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport type { PvIconSize } from \"../baseProps\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport type { PvAvatarProps, PvAvatarSize } from \"./types\";\n\nconst avatarSizeToClass: Record<PvAvatarSize, string> = {\n sm: \"pv-avatar-16\",\n md: \"pv-avatar-20\",\n lg: \"pv-avatar-xs\",\n xl: \"pv-avatar-sm\",\n \"2x\": \"pv-avatar-md\",\n};\n\nconst iconSizeToAvatarSize: Partial<Record<PvAvatarSize, PvIconSize>> = {\n sm: 10,\n md: 12,\n lg: undefined,\n xl: 20,\n \"2x\": 20,\n};\n\nwithDefaults(defineProps<PvAvatarProps>(), {\n shape: \"circle\",\n size: \"lg\",\n});\n</script>\n\n<template>\n <div :class=\"avatarSizeToClass[size]\" data-testid=\"pv-avatar\" :data-style=\"variant\" :data-shape=\"shape\">\n <PvIcon v-if=\"icon\" :name=\"icon\" :size=\"iconSizeToAvatarSize[size]\" />\n <template v-else-if=\"initials\">{{ initials }}</template>\n <template v-else-if=\"image\">\n <img :src=\"image\" :alt=\"alt ?? ''\" />\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../../PvIcon/PvIcon.vue\";\nimport PvCounterBadge from \"../../PvCounterBadge/PvCounterBadge.vue\";\nimport PvCompanyLogo from \"../../PvCompanyLogo/PvCompanyLogo.vue\";\nimport PvAvatar from \"../../PvAvatar/PvAvatar.vue\";\nimport PvTooltip from \"../../PvTooltip/PvTooltip.vue\";\nimport { computed } from \"vue\";\nimport { pvButtonSizeToClass, supportedInverseButtonVariants } from \"@/components/base/PvButton/helpers.ts\";\nimport type { PvSelectButtonTriggerProps } from \"./types\";\n\nconst props = withDefaults(defineProps<PvSelectButtonTriggerProps>(), {\n size: \"lg\",\n variant: \"secondary\",\n showDropdown: true,\n counterStyle: \"primary\",\n});\n\ndefineEmits<{\n (e: \"handle-clear\"): void;\n}>();\n\nconst classes = computed(() => {\n const output = [\"pv-flex\", \"pv-space-between\", \"pv-full-width\"];\n if (props.inverse && supportedInverseButtonVariants.includes(props.variant)) {\n output.push(`pv-button-${props.variant}-inverse`);\n } else {\n output.push(`pv-button-${props.variant}`);\n }\n const sizeClass = pvButtonSizeToClass(props.size);\n if (sizeClass) {\n output.push(sizeClass);\n }\n return output;\n});\n\nconst labelValue = computed(() => {\n if (props.isLoading) {\n return \"Loading...\";\n }\n\n if (props.selectedItems && props.selectedItems.length > 0 && props.counterStyle === \"secondary\") {\n return props.selectedItems[0].text;\n }\n\n return props.label;\n});\n\nconst rendererProps = computed(() => {\n if (!props.selectedOption) return undefined;\n\n return {\n ...props.selectedOption,\n menuOptionConfig: props.menuOptionConfig,\n queryText: null,\n selected: true,\n };\n});\n</script>\n\n<template>\n <button\n data-testid=\"pv-multi-select-button-trigger\"\n :class=\"classes\"\n style=\"--flex-gap: 0.25rem\"\n :disabled=\"disabled || isLoading\"\n >\n <div class=\"pv-flex\">\n <p\n data-testid=\"pv-select-prefix-label\"\n v-if=\"prefixLabel\"\n class=\"pv-border-right pv-text-quaternary\"\n style=\"padding-right: 4px\"\n >\n {{ prefixLabel }}\n </p>\n <PvCounterBadge\n v-if=\"counterPosition === 'left' && counterValue && counterStyle === 'primary'\"\n data-testid=\"pv-multi-select-left-counter-badge\"\n :value=\"counterValue\"\n :variant=\"counterBadgeVariant\"\n size=\"sm\"\n />\n <template v-if=\"!isLoading && renderer && rendererProps\">\n <component :is=\"renderer\" v-bind=\"rendererProps\" />\n </template>\n <template v-else>\n <PvIcon v-if=\"icon\" data-testid=\"pv-multi-select-button-icon\" :name=\"icon\" />\n <PvCompanyLogo v-if=\"companyLogo\" :name=\"companyLogo\" size=\"sm\" />\n <PvAvatar\n v-if=\"avatar\"\n class=\"pv-select-button-trigger-avatar\"\n data-testid=\"pv-multi-select-button-avatar\"\n :initials=\"avatar.initials\"\n :image=\"avatar.image\"\n :variant=\"avatar.variant\"\n :shape=\"avatar.shape\"\n size=\"sm\"\n />\n <span v-if=\"isLoading || label\">\n {{ labelValue }}\n </span>\n </template>\n <PvCounterBadge\n v-if=\"counterPosition === 'right' && counterValue && counterStyle === 'primary'\"\n data-testid=\"pv-multi-select-right-counter-badge\"\n :value=\"counterValue\"\n :variant=\"counterBadgeVariant\"\n size=\"sm\"\n />\n <PvCounterBadge\n v-if=\"counterStyle === 'secondary' && (counterValue ?? 0) >= 2\"\n data-testid=\"pv-multi-select-secondary-counter-badge\"\n prefix=\"+\"\n :value=\"(counterValue ?? 0) - 1\"\n variant=\"tertiary\"\n size=\"sm\"\n />\n </div>\n\n <PvIcon v-if=\"showDropdown\" :name=\"open ? 'chevron-up' : 'chevron-down'\" />\n <PvTooltip v-if=\"showClear\" size=\"sm\" variant=\"dark\" tooltip-position=\"top-left\">\n <template #label>\n <PvIcon name=\"close\" @click.stop=\"$emit('handle-clear')\" />\n </template>\n <template #tooltip-content> Clear Selections </template>\n </PvTooltip>\n </button>\n</template>\n\n<style scoped>\n.pv-select-button-trigger-avatar {\n font-size: 0.5rem;\n font-weight: 700;\n}\n</style>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../../PvIcon/PvIcon.vue\";\nimport PvCounterBadge from \"../../PvCounterBadge/PvCounterBadge.vue\";\nimport PvCompanyLogo from \"../../PvCompanyLogo/PvCompanyLogo.vue\";\nimport PvAvatar from \"../../PvAvatar/PvAvatar.vue\";\nimport PvTooltip from \"../../PvTooltip/PvTooltip.vue\";\nimport { computed } from \"vue\";\nimport { pvButtonSizeToClass, supportedInverseButtonVariants } from \"@/components/base/PvButton/helpers.ts\";\nimport type { PvSelectButtonTriggerProps } from \"./types\";\n\nconst props = withDefaults(defineProps<PvSelectButtonTriggerProps>(), {\n size: \"lg\",\n variant: \"secondary\",\n showDropdown: true,\n counterStyle: \"primary\",\n});\n\ndefineEmits<{\n (e: \"handle-clear\"): void;\n}>();\n\nconst classes = computed(() => {\n const output = [\"pv-flex\", \"pv-space-between\", \"pv-full-width\"];\n if (props.inverse && supportedInverseButtonVariants.includes(props.variant)) {\n output.push(`pv-button-${props.variant}-inverse`);\n } else {\n output.push(`pv-button-${props.variant}`);\n }\n const sizeClass = pvButtonSizeToClass(props.size);\n if (sizeClass) {\n output.push(sizeClass);\n }\n return output;\n});\n\nconst labelValue = computed(() => {\n if (props.isLoading) {\n return \"Loading...\";\n }\n\n if (props.selectedItems && props.selectedItems.length > 0 && props.counterStyle === \"secondary\") {\n return props.selectedItems[0].text;\n }\n\n return props.label;\n});\n\nconst rendererProps = computed(() => {\n if (!props.selectedOption) return undefined;\n\n return {\n ...props.selectedOption,\n menuOptionConfig: props.menuOptionConfig,\n queryText: null,\n selected: true,\n };\n});\n</script>\n\n<template>\n <button\n data-testid=\"pv-multi-select-button-trigger\"\n :class=\"classes\"\n style=\"--flex-gap: 0.25rem\"\n :disabled=\"disabled || isLoading\"\n >\n <div class=\"pv-flex\">\n <p\n data-testid=\"pv-select-prefix-label\"\n v-if=\"prefixLabel\"\n class=\"pv-border-right pv-text-quaternary\"\n style=\"padding-right: 4px\"\n >\n {{ prefixLabel }}\n </p>\n <PvCounterBadge\n v-if=\"counterPosition === 'left' && counterValue && counterStyle === 'primary'\"\n data-testid=\"pv-multi-select-left-counter-badge\"\n :value=\"counterValue\"\n :variant=\"counterBadgeVariant\"\n size=\"sm\"\n />\n <template v-if=\"!isLoading && renderer && rendererProps\">\n <component :is=\"renderer\" v-bind=\"rendererProps\" />\n </template>\n <template v-else>\n <PvIcon v-if=\"icon\" data-testid=\"pv-multi-select-button-icon\" :name=\"icon\" />\n <PvCompanyLogo v-if=\"companyLogo\" :name=\"companyLogo\" size=\"sm\" />\n <PvAvatar\n v-if=\"avatar\"\n class=\"pv-select-button-trigger-avatar\"\n data-testid=\"pv-multi-select-button-avatar\"\n :initials=\"avatar.initials\"\n :image=\"avatar.image\"\n :variant=\"avatar.variant\"\n :shape=\"avatar.shape\"\n size=\"sm\"\n />\n <span v-if=\"isLoading || label\">\n {{ labelValue }}\n </span>\n </template>\n <PvCounterBadge\n v-if=\"counterPosition === 'right' && counterValue && counterStyle === 'primary'\"\n data-testid=\"pv-multi-select-right-counter-badge\"\n :value=\"counterValue\"\n :variant=\"counterBadgeVariant\"\n size=\"sm\"\n />\n <PvCounterBadge\n v-if=\"counterStyle === 'secondary' && (counterValue ?? 0) >= 2\"\n data-testid=\"pv-multi-select-secondary-counter-badge\"\n prefix=\"+\"\n :value=\"(counterValue ?? 0) - 1\"\n variant=\"tertiary\"\n size=\"sm\"\n />\n </div>\n\n <PvIcon v-if=\"showDropdown\" :name=\"open ? 'chevron-up' : 'chevron-down'\" />\n <PvTooltip v-if=\"showClear\" size=\"sm\" variant=\"dark\" tooltip-position=\"top-left\">\n <template #label>\n <PvIcon name=\"close\" @click.stop=\"$emit('handle-clear')\" />\n </template>\n <template #tooltip-content> Clear Selections </template>\n </PvTooltip>\n </button>\n</template>\n\n<style scoped>\n.pv-select-button-trigger-avatar {\n font-size: 0.5rem;\n font-weight: 700;\n}\n</style>\n","<template>\n <div class=\"pv-text-subdued pv-text-center pv-text-body-md pv-inset-square-12\">No Results Found</div>\n</template>\n","import type { MenuOption, MultiSelectState } from \"@/types\";\n\n/**\n * Returns true when an option has children, whether they are already loaded or\n * only represented by the server-provided `totalChildCount` for lazy-loading.\n * Fully loaded children still count as cascade children — this helper answers\n * \"is this a parent?\", not \"are there more children to load?\".\n */\nexport function hasCascadeChildren<T>(option: MenuOption<T>): boolean {\n return !!option.children?.length || (option.totalChildCount ?? 0) > 0;\n}\n\n/** Recursively collect all leaf (childless) options from a tree. */\nexport function collectLeafOptions<T>(options: MenuOption<T>[]): MenuOption<T>[] {\n return options.flatMap((option) => {\n if (option.children?.length) return collectLeafOptions(option.children);\n return (option.totalChildCount ?? 0) > 0 ? [] : [option];\n });\n}\n\n/**\n * Merge two sets of leaf options, deduplicating by ID.\n *\n * Returns a single array containing every leaf from `base`, plus any leaves\n * from `overlay` whose ID doesn't already appear in `base`. This is used to\n * combine original (unfiltered) leaves with dynamically loaded (see-more)\n * leaves so that the full set is available for selection / checked-state logic.\n */\nexport function mergeLeafOptions<T>(base: MenuOption<T>[], overlay: MenuOption<T>[]): MenuOption<T>[] {\n const seenIds = new Set(base.map((l) => l.id));\n const extras = overlay.filter((l) => !seenIds.has(l.id));\n return extras.length > 0 ? [...base, ...extras] : base;\n}\n\n/**\n * Count selected items, collapsing fully-selected parents to 1.\n *\n * Walks the option tree bottom-up. A parent whose leaf descendants are ALL\n * selected counts as 1 (replacing the individual counts of its sub-tree).\n * Selected leaves not under a fully-selected parent each count as 1.\n *\n * This is order-independent — it walks the tree structure directly and does\n * not depend on Map iteration order.\n */\nexport function countWithCollapsedParents<T>(options: MenuOption<T>[], selectedIds: Set<string>): number {\n const walk = (nodes: MenuOption<T>[]): { leafCount: number; selectedLeafCount: number; displayCount: number } => {\n let leafCount = 0;\n let selectedLeafCount = 0;\n let displayCount = 0;\n\n for (const node of nodes) {\n if (node.children?.length) {\n const sub = walk(node.children);\n leafCount += sub.leafCount;\n selectedLeafCount += sub.selectedLeafCount;\n if (sub.leafCount > 0 && sub.leafCount === sub.selectedLeafCount) {\n displayCount += 1;\n } else {\n displayCount += sub.displayCount;\n }\n } else {\n leafCount += 1;\n if (selectedIds.has(node.id)) {\n selectedLeafCount += 1;\n displayCount += 1;\n }\n }\n }\n\n return { leafCount, selectedLeafCount, displayCount };\n };\n\n return walk(options).displayCount;\n}\n\nexport function countFromSelectionState(state: MultiSelectState): number {\n return state.filter((node) => node.state === \"selected\").length;\n}\n\n/**\n * Recursively filter a tree for a search value.\n *\n * - If a node's own text matches, it is kept with all its children intact.\n * - If a node's own text does NOT match but one or more of its descendants do,\n * the node is kept as a container showing only the matching descendants.\n * This means a search term that matches a child will surface that child even\n * when the parent label itself doesn't contain the search term.\n * - Nodes with no match anywhere in their subtree are removed entirely.\n */\nexport function filterOptionsRecursive<T>(\n options: MenuOption<T>[],\n searchValue: string,\n showParentOnChildQueryMatch = true,\n): MenuOption<T>[] {\n return options.flatMap((option) => {\n const selfMatches =\n option.text.toLocaleLowerCase().includes(searchValue) ||\n option.searchText?.toLocaleLowerCase().includes(searchValue);\n\n if (selfMatches) return [option]; // keep with all children intact\n\n if (option.children?.length) {\n const filteredChildren = filterOptionsRecursive(option.children, searchValue, showParentOnChildQueryMatch);\n if (filteredChildren.length) {\n return showParentOnChildQueryMatch ? [{ ...option, children: filteredChildren }] : filteredChildren;\n }\n }\n\n return [];\n });\n}\n","<script setup lang=\"ts\">\nimport PvCompanyLogo from \"@/components/base/PvCompanyLogo/PvCompanyLogo.vue\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport PvAvatar from \"@/components/base/PvAvatar/PvAvatar.vue\";\nimport PvCounterBadge from \"@/components/base/PvCounterBadge/PvCounterBadge.vue\";\nimport type { MenuOption, MenuOptionConfig } from \"@/types.ts\";\nimport { computed, onMounted, ref, watch } from \"vue\";\n\ndefineOptions({\n inheritAttrs: false,\n});\n\ninterface PvMenuBaseItemProps extends MenuOption {\n menuOptionConfig?: MenuOptionConfig;\n queryText?: string | null;\n}\n\nconst props = defineProps<PvMenuBaseItemProps>();\n\nconst mainText = ref<HTMLElement | null>(null);\nconst subText = ref<HTMLElement | null>(null);\n\nconst renderedSubText = computed(() => {\n return props.subText || null;\n});\n\nconst escapeRegex = (str: string): string => {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n};\n\nconst highlightText = (element: HTMLElement, originalText: string, searchQuery: string) => {\n const escapedSearch = escapeRegex(searchQuery);\n const regex = new RegExp(`(${escapedSearch})`, \"gi\");\n element.innerHTML = originalText.replace(\n regex,\n '<span data-test-id=\"pv-matched-text\" style=\"font-weight: bold;\">$1</span>',\n );\n};\n\nconst applyHighlight = () => {\n if (props.queryText) {\n const mainTextMatches = new RegExp(escapeRegex(props.queryText), \"gi\").test(props.text);\n if (mainText.value) {\n highlightText(mainText.value, props.text, props.queryText);\n }\n if (subText.value && renderedSubText.value) {\n if (mainTextMatches) {\n subText.value.textContent = renderedSubText.value;\n } else {\n highlightText(subText.value, renderedSubText.value, props.queryText);\n }\n }\n } else {\n if (mainText.value) {\n mainText.value.textContent = props.text;\n }\n if (subText.value && renderedSubText.value) {\n subText.value.textContent = renderedSubText.value;\n }\n }\n};\n\nonMounted(() => {\n applyHighlight();\n});\n\nwatch(\n () => props.queryText,\n () => {\n applyHighlight();\n },\n);\n</script>\n\n<template>\n <PvAvatar\n v-if=\"avatar\"\n :initials=\"avatar.initials\"\n :image=\"avatar.image\"\n :variant=\"avatar.variant\"\n :shape=\"avatar.shape\"\n size=\"lg\"\n />\n <PvIcon :class=\"{ 'pv-text-subdued': !disabled }\" v-if=\"icon\" :name=\"icon\" />\n <PvCompanyLogo v-if=\"companyName\" :name=\"companyName\" size=\"sm\" />\n <div class=\"pv-full-width pv-truncate pv-flex-vertical\" style=\"align-items: flex-start; --flex-gap: 0\">\n <span class=\"pv-text-body-md pv-full-width pv-truncate\" :title=\"text\">\n <span ref=\"mainText\">{{ text }}</span>\n <span v-if=\"subduedText\" :class=\"{ 'pv-text-subdued': !disabled }\" style=\"padding-left: 4px\">\n {{ subduedText }}\n </span>\n </span>\n <span\n ref=\"subText\"\n v-if=\"renderedSubText\"\n :class=\"['pv-text-body-xs', 'pv-full-width', 'pv-truncate', { 'pv-text-subdued': !disabled }]\"\n :title=\"renderedSubText\"\n >\n {{ renderedSubText }}\n </span>\n </div>\n <PvCounterBadge\n v-if=\"secondaryText && typeof secondaryText === 'number'\"\n :value=\"secondaryText\"\n :variant=\"menuOptionConfig?.counterBadgeVariant\"\n />\n <span v-else-if=\"secondaryText && typeof secondaryText === 'string'\" class=\"pv-text-subdued pv-text-body-md\">{{\n secondaryText\n }}</span>\n</template>\n","<script setup lang=\"ts\">\nimport PvCompanyLogo from \"@/components/base/PvCompanyLogo/PvCompanyLogo.vue\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport PvAvatar from \"@/components/base/PvAvatar/PvAvatar.vue\";\nimport PvCounterBadge from \"@/components/base/PvCounterBadge/PvCounterBadge.vue\";\nimport type { MenuOption, MenuOptionConfig } from \"@/types.ts\";\nimport { computed, onMounted, ref, watch } from \"vue\";\n\ndefineOptions({\n inheritAttrs: false,\n});\n\ninterface PvMenuBaseItemProps extends MenuOption {\n menuOptionConfig?: MenuOptionConfig;\n queryText?: string | null;\n}\n\nconst props = defineProps<PvMenuBaseItemProps>();\n\nconst mainText = ref<HTMLElement | null>(null);\nconst subText = ref<HTMLElement | null>(null);\n\nconst renderedSubText = computed(() => {\n return props.subText || null;\n});\n\nconst escapeRegex = (str: string): string => {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n};\n\nconst highlightText = (element: HTMLElement, originalText: string, searchQuery: string) => {\n const escapedSearch = escapeRegex(searchQuery);\n const regex = new RegExp(`(${escapedSearch})`, \"gi\");\n element.innerHTML = originalText.replace(\n regex,\n '<span data-test-id=\"pv-matched-text\" style=\"font-weight: bold;\">$1</span>',\n );\n};\n\nconst applyHighlight = () => {\n if (props.queryText) {\n const mainTextMatches = new RegExp(escapeRegex(props.queryText), \"gi\").test(props.text);\n if (mainText.value) {\n highlightText(mainText.value, props.text, props.queryText);\n }\n if (subText.value && renderedSubText.value) {\n if (mainTextMatches) {\n subText.value.textContent = renderedSubText.value;\n } else {\n highlightText(subText.value, renderedSubText.value, props.queryText);\n }\n }\n } else {\n if (mainText.value) {\n mainText.value.textContent = props.text;\n }\n if (subText.value && renderedSubText.value) {\n subText.value.textContent = renderedSubText.value;\n }\n }\n};\n\nonMounted(() => {\n applyHighlight();\n});\n\nwatch(\n () => props.queryText,\n () => {\n applyHighlight();\n },\n);\n</script>\n\n<template>\n <PvAvatar\n v-if=\"avatar\"\n :initials=\"avatar.initials\"\n :image=\"avatar.image\"\n :variant=\"avatar.variant\"\n :shape=\"avatar.shape\"\n size=\"lg\"\n />\n <PvIcon :class=\"{ 'pv-text-subdued': !disabled }\" v-if=\"icon\" :name=\"icon\" />\n <PvCompanyLogo v-if=\"companyName\" :name=\"companyName\" size=\"sm\" />\n <div class=\"pv-full-width pv-truncate pv-flex-vertical\" style=\"align-items: flex-start; --flex-gap: 0\">\n <span class=\"pv-text-body-md pv-full-width pv-truncate\" :title=\"text\">\n <span ref=\"mainText\">{{ text }}</span>\n <span v-if=\"subduedText\" :class=\"{ 'pv-text-subdued': !disabled }\" style=\"padding-left: 4px\">\n {{ subduedText }}\n </span>\n </span>\n <span\n ref=\"subText\"\n v-if=\"renderedSubText\"\n :class=\"['pv-text-body-xs', 'pv-full-width', 'pv-truncate', { 'pv-text-subdued': !disabled }]\"\n :title=\"renderedSubText\"\n >\n {{ renderedSubText }}\n </span>\n </div>\n <PvCounterBadge\n v-if=\"secondaryText && typeof secondaryText === 'number'\"\n :value=\"secondaryText\"\n :variant=\"menuOptionConfig?.counterBadgeVariant\"\n />\n <span v-else-if=\"secondaryText && typeof secondaryText === 'string'\" class=\"pv-text-subdued pv-text-body-md\">{{\n secondaryText\n }}</span>\n</template>\n","<script setup lang=\"ts\">\nimport { useId } from \"vue\";\nimport { PvSwitchSize } from \"./types\";\n\ninterface PvSwitchProps {\n /**\n * The visual size of the switch track and thumb.\n */\n size?: PvSwitchSize;\n /** Optional text label displayed next to the switch. */\n label?: string;\n /** Accessible name for the switch when no visible label is provided. */\n ariaLabel?: string;\n /** When true, the switch is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** HTML id for the underlying checkbox input. Auto-generated when omitted. */\n id?: string;\n /**\n * When true, hides the checkmark icon inside the switch thumb.\n */\n hideCheckIcon?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvSwitchProps>(), {\n size: \"md\",\n disabled: false,\n hideCheckIcon: false,\n});\n\nconst inputId = props.id ?? useId();\n\nconst value = defineModel<boolean>({ required: true });\n</script>\n\n<template>\n <label\n :for=\"inputId\"\n :class=\"[\n 'pv-label pv-switch pv-label-hover',\n {\n 'pv-input-small': size === 'md',\n 'pv-input-xsmall': size === 'sm',\n 'pv-switch-hide-check': hideCheckIcon,\n },\n ]\"\n >\n <span v-if=\"label\">{{ label }}</span>\n <input v-model=\"value\" :disabled=\"disabled\" :aria-label=\"ariaLabel\" type=\"checkbox\" role=\"switch\" :id=\"inputId\" />\n </label>\n</template>\n\n<style scoped>\n.pv-switch-hide-check :deep(input[type=\"checkbox\"]:checked:after),\n.pv-switch-hide-check :deep(input[type=\"checkbox\"]:checked:not(:disabled):hover:after),\n.pv-switch-hide-check :deep(input[type=\"checkbox\"]:checked:not(:disabled):focus-visible:after),\n.pv-switch-hide-check :deep(input[type=\"checkbox\"]:checked:not(:disabled):active:after),\n.pv-switch-hide-check :deep(input[type=\"checkbox\"]:checked:disabled:after) {\n background-image: unset;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { useId } from \"vue\";\nimport { PvSwitchSize } from \"./types\";\n\ninterface PvSwitchProps {\n /**\n * The visual size of the switch track and thumb.\n */\n size?: PvSwitchSize;\n /** Optional text label displayed next to the switch. */\n label?: string;\n /** Accessible name for the switch when no visible label is provided. */\n ariaLabel?: string;\n /** When true, the switch is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** HTML id for the underlying checkbox input. Auto-generated when omitted. */\n id?: string;\n /**\n * When true, hides the checkmark icon inside the switch thumb.\n */\n hideCheckIcon?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvSwitchProps>(), {\n size: \"md\",\n disabled: false,\n hideCheckIcon: false,\n});\n\nconst inputId = props.id ?? useId();\n\nconst value = defineModel<boolean>({ required: true });\n</script>\n\n<template>\n <label\n :for=\"inputId\"\n :class=\"[\n 'pv-label pv-switch pv-label-hover',\n {\n 'pv-input-small': size === 'md',\n 'pv-input-xsmall': size === 'sm',\n 'pv-switch-hide-check': hideCheckIcon,\n },\n ]\"\n >\n <span v-if=\"label\">{{ label }}</span>\n <input v-model=\"value\" :disabled=\"disabled\" :aria-label=\"ariaLabel\" type=\"checkbox\" role=\"switch\" :id=\"inputId\" />\n </label>\n</template>\n\n<style scoped>\n.pv-switch-hide-check :deep(input[type=\"checkbox\"]:checked:after),\n.pv-switch-hide-check :deep(input[type=\"checkbox\"]:checked:not(:disabled):hover:after),\n.pv-switch-hide-check :deep(input[type=\"checkbox\"]:checked:not(:disabled):focus-visible:after),\n.pv-switch-hide-check :deep(input[type=\"checkbox\"]:checked:not(:disabled):active:after),\n.pv-switch-hide-check :deep(input[type=\"checkbox\"]:checked:disabled:after) {\n background-image: unset;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport PvTooltipV2 from \"@/components/base/PvTooltipV2/PvTooltipV2.vue\";\nimport { MenuAction, MenuOption } from \"@/types\";\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\n\ninterface PvMenuItemActionProps {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n action: MenuAction<any>;\n option: MenuOption;\n}\n\nconst props = defineProps<PvMenuItemActionProps>();\n\nconst actionIcon = computed(() => {\n return typeof props.action.icon === \"function\" ? props.action.icon(props.option) : props.action.icon;\n});\n\nconst actionDisabled = computed(() => {\n return typeof props.action.isDisabled === \"function\"\n ? props.action.isDisabled(props.option)\n : props.action.isDisabled;\n});\n\nconst actionTooltip = computed(() => {\n return typeof props.action.tooltipText === \"function\"\n ? props.action.tooltipText(props.option)\n : props.action.tooltipText;\n});\n\nconst alwaysShow = computed(() => {\n return typeof props.action.alwaysShow === \"function\"\n ? props.action.alwaysShow(props.option)\n : props.action.alwaysShow;\n});\n\nconst handleActionClick = () => {\n if (!actionDisabled.value) {\n props.action.action(props.option);\n }\n};\n</script>\n<template>\n <PvTooltipV2 :disableInteractive=\"true\" :useTeleport=\"true\" variant=\"white\">\n <template #trigger>\n <PvButton\n variant=\"ghost\"\n class=\"pv-text-brand\"\n :leftIcon=\"actionIcon\"\n :class=\"{ 'pv-menu-action-button': !alwaysShow }\"\n @click.stop=\"handleActionClick\"\n :disabled=\"actionDisabled\"\n />\n </template>\n <template #content v-if=\"actionTooltip\">\n <div>\n {{ actionTooltip }}\n </div>\n </template>\n </PvTooltipV2>\n</template>\n\n<style scoped>\n.pv-menu-action-button {\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.pv-label:hover .pv-menu-action-button {\n opacity: 1;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport PvTooltipV2 from \"@/components/base/PvTooltipV2/PvTooltipV2.vue\";\nimport { MenuAction, MenuOption } from \"@/types\";\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\n\ninterface PvMenuItemActionProps {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n action: MenuAction<any>;\n option: MenuOption;\n}\n\nconst props = defineProps<PvMenuItemActionProps>();\n\nconst actionIcon = computed(() => {\n return typeof props.action.icon === \"function\" ? props.action.icon(props.option) : props.action.icon;\n});\n\nconst actionDisabled = computed(() => {\n return typeof props.action.isDisabled === \"function\"\n ? props.action.isDisabled(props.option)\n : props.action.isDisabled;\n});\n\nconst actionTooltip = computed(() => {\n return typeof props.action.tooltipText === \"function\"\n ? props.action.tooltipText(props.option)\n : props.action.tooltipText;\n});\n\nconst alwaysShow = computed(() => {\n return typeof props.action.alwaysShow === \"function\"\n ? props.action.alwaysShow(props.option)\n : props.action.alwaysShow;\n});\n\nconst handleActionClick = () => {\n if (!actionDisabled.value) {\n props.action.action(props.option);\n }\n};\n</script>\n<template>\n <PvTooltipV2 :disableInteractive=\"true\" :useTeleport=\"true\" variant=\"white\">\n <template #trigger>\n <PvButton\n variant=\"ghost\"\n class=\"pv-text-brand\"\n :leftIcon=\"actionIcon\"\n :class=\"{ 'pv-menu-action-button': !alwaysShow }\"\n @click.stop=\"handleActionClick\"\n :disabled=\"actionDisabled\"\n />\n </template>\n <template #content v-if=\"actionTooltip\">\n <div>\n {{ actionTooltip }}\n </div>\n </template>\n </PvTooltipV2>\n</template>\n\n<style scoped>\n.pv-menu-action-button {\n opacity: 0;\n transition: opacity 0.2s ease;\n}\n\n.pv-label:hover .pv-menu-action-button {\n opacity: 1;\n}\n</style>\n","import type { ComputedRef, InjectionKey, Ref } from \"vue\";\nimport type { MenuOption } from \"@/types\";\n\nexport const SelectedItemsKey: InjectionKey<Ref<MenuOption[]>> = Symbol(\"SelectedItemsKey\");\nexport const EnableCascadeSelectionKey: InjectionKey<ComputedRef<boolean>> = Symbol(\"EnableCascadeSelectionKey\");\nexport const OriginalOptionsMapKey: InjectionKey<ComputedRef<Map<string, MenuOption>>> = Symbol(\n \"OriginalOptionsMapKey\",\n);\nexport const CascadeSelectedParentIdsKey: InjectionKey<Ref<Set<string>>> = Symbol(\"CascadeSelectedParentIdsKey\");\nexport const CascadeDeselectedChildIdsKey: InjectionKey<Ref<Map<string, Set<string>>>> = Symbol(\n \"CascadeDeselectedChildIdsKey\",\n);\nexport const ParentSelectsAllChildrenKey: InjectionKey<ComputedRef<boolean>> = Symbol(\"ParentSelectsAllChildrenKey\");\nexport const EnableChildExpansionKey: InjectionKey<ComputedRef<boolean>> = Symbol(\"EnableChildExpansionKey\");\n","<script lang=\"ts\" setup>\nimport { computed, getCurrentInstance, inject, nextTick, ref, useTemplateRef } from \"vue\";\n\nimport PvMenuBaseItem from \"@/components/base/PvMenu/items/PvMenuBaseItem.vue\";\nimport PvSwitch from \"@/components/base/PvSwitch/PvSwitch.vue\";\nimport { MenuOption, MenuOptionConfig, MenuOptionSelectedEvent } from \"@/types.ts\";\nimport PvMenuItemAction from \"@/components/base/PvMenu/items/PvMenuItemAction.vue\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport { collectLeafOptions, hasCascadeChildren, mergeLeafOptions } from \"@/components/base/PvMenu/cascadeUtils\";\nimport {\n SelectedItemsKey,\n EnableCascadeSelectionKey,\n OriginalOptionsMapKey,\n CascadeSelectedParentIdsKey,\n} from \"@/components/base/PvMenu/symbols\";\n\nexport interface PvMenuItemVariantProps extends MenuOption {\n selected?: boolean;\n indeterminate?: boolean;\n queryText?: string | null;\n highlightSearchText?: boolean;\n menuOptionConfig?: MenuOptionConfig;\n showChevron?: boolean;\n chevronIcon?: string;\n expanded?: boolean;\n}\n\nconst props = defineProps<PvMenuItemVariantProps>();\n\nconst inputRef = useTemplateRef<HTMLInputElement>(\"inputRef\");\n\nconst selectedItems = inject(SelectedItemsKey, undefined);\nconst enableCascadeSelection = inject(EnableCascadeSelectionKey, ref(false));\nconst originalOptionsMap = inject(OriginalOptionsMapKey, undefined);\nconst cascadeSelectedParentIds = inject(CascadeSelectedParentIdsKey, undefined);\n\n// Resolve the effective leaf options for this parent node. Always use original\n// (unfiltered) children so the checked/indeterminate state reflects all children.\n// When children have been dynamically loaded (see-more), props.children may have\n// more entries than the original snapshot — use whichever is larger.\nconst effectiveLeafOptions = computed(() => {\n if (!enableCascadeSelection.value || !hasCascadeChildren(props)) return [];\n const currentLeaves = props.children ? collectLeafOptions(props.children) : [];\n if (originalOptionsMap?.value) {\n const originalOption = originalOptionsMap.value.get(props.id);\n const originalLeaves = originalOption?.children ? collectLeafOptions(originalOption.children) : [];\n return mergeLeafOptions(originalLeaves, currentLeaves);\n }\n return currentLeaves;\n});\n\nconst isChecked = computed(() => {\n if (!selectedItems?.value) return props.selected ?? false;\n if (enableCascadeSelection.value && hasCascadeChildren(props)) {\n const leafOptions = effectiveLeafOptions.value;\n const originalLeafCount = leafOptions.length;\n const selectedCount = leafOptions.filter((lo) => selectedItems.value.some((item) => item.id === lo.id)).length;\n // Parent was explicitly clicked and all loaded children are selected → checked\n if (cascadeSelectedParentIds?.value?.has(props.id) && selectedCount >= originalLeafCount) {\n return true;\n }\n const totalCount = props.totalChildCount ?? originalLeafCount;\n return totalCount > 0 && selectedCount >= totalCount;\n }\n return selectedItems.value.some((item) => item.id === props.id);\n});\n\nconst isIndeterminate = computed(() => {\n if (!selectedItems?.value || !enableCascadeSelection.value || !hasCascadeChildren(props)) {\n return props.indeterminate ?? false;\n }\n const leafOptions = effectiveLeafOptions.value;\n const originalLeafCount = leafOptions.length;\n const selectedCount = leafOptions.filter((lo) => selectedItems.value.some((item) => item.id === lo.id)).length;\n // Parent was explicitly clicked and all loaded children are selected → not indeterminate\n if (cascadeSelectedParentIds?.value?.has(props.id) && selectedCount >= originalLeafCount) {\n return false;\n }\n const totalCount = props.totalChildCount ?? originalLeafCount;\n return selectedCount > 0 && selectedCount < totalCount;\n});\n\nconst computedClassList = computed(() => {\n const classes = props.classList ? [...props.classList] : [];\n if (props.disabled) {\n classes.push(\"pv-menu-item-disabled\");\n } else {\n classes.push(\"pv-menu-item\");\n }\n return classes;\n});\n\nconst disabledStyle = computed(() => {\n if (props.disabled && props.menuOptionConfig?.disabledVariant !== \"ghost\") {\n return { background: \"#ececec\" };\n }\n return {};\n});\n\nconst computedOption = computed(() => {\n const option: MenuOption = {\n ...props,\n avatar: props.menuOptionConfig?.variant === \"avatar\" ? props.avatar : undefined,\n icon: props.menuOptionConfig?.variant === \"icon\" ? props.icon : undefined,\n companyName: props.menuOptionConfig?.variant === \"company\" ? props.companyName || props.text : undefined,\n };\n return option;\n});\n\nconst inputHidden = computed(() => {\n const variant = props.menuOptionConfig?.variant;\n return variant !== \"checkbox\" && variant !== \"radio\";\n});\n\n// we only show the input for checkbox and radio variants\nconst inputType = computed(() => {\n return props.menuOptionConfig?.variant === \"radio\" ? \"radio\" : \"checkbox\";\n});\n\nconst inputName = `${inputType.value}-${getCurrentInstance()?.uid}`;\n\nconst inputClass = computed(() => {\n return props.menuOptionConfig?.variant === \"checkbox\" ? \"pv-checkbox\" : \"pv-radio\";\n});\n\nconst dataTestId = computed(() => {\n const type =\n props.menuOptionConfig?.variant === \"checkbox\"\n ? \"-checkbox\"\n : props.menuOptionConfig?.variant === \"radio\"\n ? \"-radio\"\n : \"\";\n return `pv-menu${type}-item`;\n});\n\nconst emits = defineEmits<{\n (e: \"handle-selected\", payload: MenuOptionSelectedEvent): void;\n (e: \"toggle-expanded\"): void;\n}>();\n\nconst handleSelected = (event: Event) => {\n if (props.disabled) {\n return;\n }\n const option: MenuOption = {\n ...props,\n };\n emits(\"handle-selected\", {\n option,\n event,\n });\n // After the reactive state settles, force-sync the DOM checked/indeterminate\n // properties. Vue skips patching when the computed value doesn't change (e.g.\n // indeterminate parent: isChecked was false before and is still false after\n // deselecting all children), leaving the browser-toggled state stale.\n nextTick(() => {\n if (inputRef.value) {\n inputRef.value.checked = isChecked.value;\n inputRef.value.indeterminate = isIndeterminate.value;\n }\n });\n};\n</script>\n\n<template>\n <label\n class=\"pv-label pv-label-hover pv-flex pv-stack-4 pv-inset-square-8\"\n :class=\"computedClassList\"\n :style=\"[\n disabledStyle,\n { cursor: 'pointer', paddingTop: subText ? '4px' : undefined, paddingBottom: subText ? '4px' : undefined },\n ]\"\n :data-testid=\"dataTestId\"\n >\n <input\n ref=\"inputRef\"\n :hidden=\"inputHidden\"\n :type=\"inputType\"\n :name=\"inputName\"\n :checked=\"isChecked\"\n :indeterminate=\"isIndeterminate\"\n :class=\"inputClass\"\n :disabled=\"disabled\"\n @change=\"handleSelected\"\n />\n <template v-if=\"menuOptionConfig?.renderer\">\n <component :is=\"menuOptionConfig?.renderer\" v-bind=\"$props\" />\n </template>\n <template v-else>\n <PvMenuBaseItem\n v-bind=\"computedOption\"\n :menuOptionConfig=\"menuOptionConfig\"\n :queryText=\"queryText\"\n :highlightSearchText=\"highlightSearchText\"\n />\n </template>\n <PvIcon v-if=\"menuOptionConfig?.variant === 'checkmark' && isChecked\" name=\"check\" class=\"pv-text-success\" />\n <PvSwitch\n v-if=\"menuOptionConfig?.variant === 'toggle'\"\n :modelValue=\"isChecked\"\n :ariaLabel=\"props.text || 'Toggle'\"\n size=\"sm\"\n hideCheckIcon\n style=\"pointer-events: none\"\n />\n <PvMenuItemAction v-if=\"menuOptionConfig?.action\" :action=\"menuOptionConfig?.action\" :option=\"props\" />\n <button\n v-if=\"showChevron\"\n type=\"button\"\n class=\"pv-button-ghost pv-menu-item-expand-chevron\"\n :aria-label=\"props.text ? `Toggle children for ${props.text}` : 'Toggle children'\"\n :aria-expanded=\"expanded\"\n @click.prevent.stop=\"emits('toggle-expanded')\"\n >\n <PvIcon :name=\"chevronIcon ?? 'chevron-right'\" :size=\"12\" />\n </button>\n </label>\n</template>\n\n<style scoped>\n.pv-menu-item-disabled {\n pointer-events: none;\n border-radius: 4px;\n color: #7d898d;\n}\n.pv-menu-item {\n cursor: pointer;\n transition-duration: 150ms;\n transition-property: background-color;\n border-radius: var(--popover-list-item-radius, 4px);\n &:hover,\n &:focus-visible {\n background-color: var(--popover-list-item-hover-background-color, #f5f5f5);\n }\n &:active {\n background-color: var(--popover-list-item-pressed-background-color, #ebebeb);\n }\n}\n.pv-radio:indeterminate {\n background-color: unset !important;\n border-color: var(--color-border, #e3e7ea) !important;\n}\n.pv-menu-item-expand-chevron {\n padding: 4px;\n margin-left: auto;\n flex-shrink: 0;\n}\n.pv-menu-item-disabled .pv-menu-item-expand-chevron {\n pointer-events: auto;\n color: inherit;\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { computed, getCurrentInstance, inject, nextTick, ref, useTemplateRef } from \"vue\";\n\nimport PvMenuBaseItem from \"@/components/base/PvMenu/items/PvMenuBaseItem.vue\";\nimport PvSwitch from \"@/components/base/PvSwitch/PvSwitch.vue\";\nimport { MenuOption, MenuOptionConfig, MenuOptionSelectedEvent } from \"@/types.ts\";\nimport PvMenuItemAction from \"@/components/base/PvMenu/items/PvMenuItemAction.vue\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport { collectLeafOptions, hasCascadeChildren, mergeLeafOptions } from \"@/components/base/PvMenu/cascadeUtils\";\nimport {\n SelectedItemsKey,\n EnableCascadeSelectionKey,\n OriginalOptionsMapKey,\n CascadeSelectedParentIdsKey,\n} from \"@/components/base/PvMenu/symbols\";\n\nexport interface PvMenuItemVariantProps extends MenuOption {\n selected?: boolean;\n indeterminate?: boolean;\n queryText?: string | null;\n highlightSearchText?: boolean;\n menuOptionConfig?: MenuOptionConfig;\n showChevron?: boolean;\n chevronIcon?: string;\n expanded?: boolean;\n}\n\nconst props = defineProps<PvMenuItemVariantProps>();\n\nconst inputRef = useTemplateRef<HTMLInputElement>(\"inputRef\");\n\nconst selectedItems = inject(SelectedItemsKey, undefined);\nconst enableCascadeSelection = inject(EnableCascadeSelectionKey, ref(false));\nconst originalOptionsMap = inject(OriginalOptionsMapKey, undefined);\nconst cascadeSelectedParentIds = inject(CascadeSelectedParentIdsKey, undefined);\n\n// Resolve the effective leaf options for this parent node. Always use original\n// (unfiltered) children so the checked/indeterminate state reflects all children.\n// When children have been dynamically loaded (see-more), props.children may have\n// more entries than the original snapshot — use whichever is larger.\nconst effectiveLeafOptions = computed(() => {\n if (!enableCascadeSelection.value || !hasCascadeChildren(props)) return [];\n const currentLeaves = props.children ? collectLeafOptions(props.children) : [];\n if (originalOptionsMap?.value) {\n const originalOption = originalOptionsMap.value.get(props.id);\n const originalLeaves = originalOption?.children ? collectLeafOptions(originalOption.children) : [];\n return mergeLeafOptions(originalLeaves, currentLeaves);\n }\n return currentLeaves;\n});\n\nconst isChecked = computed(() => {\n if (!selectedItems?.value) return props.selected ?? false;\n if (enableCascadeSelection.value && hasCascadeChildren(props)) {\n const leafOptions = effectiveLeafOptions.value;\n const originalLeafCount = leafOptions.length;\n const selectedCount = leafOptions.filter((lo) => selectedItems.value.some((item) => item.id === lo.id)).length;\n // Parent was explicitly clicked and all loaded children are selected → checked\n if (cascadeSelectedParentIds?.value?.has(props.id) && selectedCount >= originalLeafCount) {\n return true;\n }\n const totalCount = props.totalChildCount ?? originalLeafCount;\n return totalCount > 0 && selectedCount >= totalCount;\n }\n return selectedItems.value.some((item) => item.id === props.id);\n});\n\nconst isIndeterminate = computed(() => {\n if (!selectedItems?.value || !enableCascadeSelection.value || !hasCascadeChildren(props)) {\n return props.indeterminate ?? false;\n }\n const leafOptions = effectiveLeafOptions.value;\n const originalLeafCount = leafOptions.length;\n const selectedCount = leafOptions.filter((lo) => selectedItems.value.some((item) => item.id === lo.id)).length;\n // Parent was explicitly clicked and all loaded children are selected → not indeterminate\n if (cascadeSelectedParentIds?.value?.has(props.id) && selectedCount >= originalLeafCount) {\n return false;\n }\n const totalCount = props.totalChildCount ?? originalLeafCount;\n return selectedCount > 0 && selectedCount < totalCount;\n});\n\nconst computedClassList = computed(() => {\n const classes = props.classList ? [...props.classList] : [];\n if (props.disabled) {\n classes.push(\"pv-menu-item-disabled\");\n } else {\n classes.push(\"pv-menu-item\");\n }\n return classes;\n});\n\nconst disabledStyle = computed(() => {\n if (props.disabled && props.menuOptionConfig?.disabledVariant !== \"ghost\") {\n return { background: \"#ececec\" };\n }\n return {};\n});\n\nconst computedOption = computed(() => {\n const option: MenuOption = {\n ...props,\n avatar: props.menuOptionConfig?.variant === \"avatar\" ? props.avatar : undefined,\n icon: props.menuOptionConfig?.variant === \"icon\" ? props.icon : undefined,\n companyName: props.menuOptionConfig?.variant === \"company\" ? props.companyName || props.text : undefined,\n };\n return option;\n});\n\nconst inputHidden = computed(() => {\n const variant = props.menuOptionConfig?.variant;\n return variant !== \"checkbox\" && variant !== \"radio\";\n});\n\n// we only show the input for checkbox and radio variants\nconst inputType = computed(() => {\n return props.menuOptionConfig?.variant === \"radio\" ? \"radio\" : \"checkbox\";\n});\n\nconst inputName = `${inputType.value}-${getCurrentInstance()?.uid}`;\n\nconst inputClass = computed(() => {\n return props.menuOptionConfig?.variant === \"checkbox\" ? \"pv-checkbox\" : \"pv-radio\";\n});\n\nconst dataTestId = computed(() => {\n const type =\n props.menuOptionConfig?.variant === \"checkbox\"\n ? \"-checkbox\"\n : props.menuOptionConfig?.variant === \"radio\"\n ? \"-radio\"\n : \"\";\n return `pv-menu${type}-item`;\n});\n\nconst emits = defineEmits<{\n (e: \"handle-selected\", payload: MenuOptionSelectedEvent): void;\n (e: \"toggle-expanded\"): void;\n}>();\n\nconst handleSelected = (event: Event) => {\n if (props.disabled) {\n return;\n }\n const option: MenuOption = {\n ...props,\n };\n emits(\"handle-selected\", {\n option,\n event,\n });\n // After the reactive state settles, force-sync the DOM checked/indeterminate\n // properties. Vue skips patching when the computed value doesn't change (e.g.\n // indeterminate parent: isChecked was false before and is still false after\n // deselecting all children), leaving the browser-toggled state stale.\n nextTick(() => {\n if (inputRef.value) {\n inputRef.value.checked = isChecked.value;\n inputRef.value.indeterminate = isIndeterminate.value;\n }\n });\n};\n</script>\n\n<template>\n <label\n class=\"pv-label pv-label-hover pv-flex pv-stack-4 pv-inset-square-8\"\n :class=\"computedClassList\"\n :style=\"[\n disabledStyle,\n { cursor: 'pointer', paddingTop: subText ? '4px' : undefined, paddingBottom: subText ? '4px' : undefined },\n ]\"\n :data-testid=\"dataTestId\"\n >\n <input\n ref=\"inputRef\"\n :hidden=\"inputHidden\"\n :type=\"inputType\"\n :name=\"inputName\"\n :checked=\"isChecked\"\n :indeterminate=\"isIndeterminate\"\n :class=\"inputClass\"\n :disabled=\"disabled\"\n @change=\"handleSelected\"\n />\n <template v-if=\"menuOptionConfig?.renderer\">\n <component :is=\"menuOptionConfig?.renderer\" v-bind=\"$props\" />\n </template>\n <template v-else>\n <PvMenuBaseItem\n v-bind=\"computedOption\"\n :menuOptionConfig=\"menuOptionConfig\"\n :queryText=\"queryText\"\n :highlightSearchText=\"highlightSearchText\"\n />\n </template>\n <PvIcon v-if=\"menuOptionConfig?.variant === 'checkmark' && isChecked\" name=\"check\" class=\"pv-text-success\" />\n <PvSwitch\n v-if=\"menuOptionConfig?.variant === 'toggle'\"\n :modelValue=\"isChecked\"\n :ariaLabel=\"props.text || 'Toggle'\"\n size=\"sm\"\n hideCheckIcon\n style=\"pointer-events: none\"\n />\n <PvMenuItemAction v-if=\"menuOptionConfig?.action\" :action=\"menuOptionConfig?.action\" :option=\"props\" />\n <button\n v-if=\"showChevron\"\n type=\"button\"\n class=\"pv-button-ghost pv-menu-item-expand-chevron\"\n :aria-label=\"props.text ? `Toggle children for ${props.text}` : 'Toggle children'\"\n :aria-expanded=\"expanded\"\n @click.prevent.stop=\"emits('toggle-expanded')\"\n >\n <PvIcon :name=\"chevronIcon ?? 'chevron-right'\" :size=\"12\" />\n </button>\n </label>\n</template>\n\n<style scoped>\n.pv-menu-item-disabled {\n pointer-events: none;\n border-radius: 4px;\n color: #7d898d;\n}\n.pv-menu-item {\n cursor: pointer;\n transition-duration: 150ms;\n transition-property: background-color;\n border-radius: var(--popover-list-item-radius, 4px);\n &:hover,\n &:focus-visible {\n background-color: var(--popover-list-item-hover-background-color, #f5f5f5);\n }\n &:active {\n background-color: var(--popover-list-item-pressed-background-color, #ebebeb);\n }\n}\n.pv-radio:indeterminate {\n background-color: unset !important;\n border-color: var(--color-border, #e3e7ea) !important;\n}\n.pv-menu-item-expand-chevron {\n padding: 4px;\n margin-left: auto;\n flex-shrink: 0;\n}\n.pv-menu-item-disabled .pv-menu-item-expand-chevron {\n pointer-events: auto;\n color: inherit;\n}\n</style>\n","<script lang=\"ts\" setup>\nimport { computed, inject, ref, watch } from \"vue\";\n\nimport { MenuOption, MenuOptionConfig, MenuOptionSelectedEvent, SeeMoreEvent } from \"@/types.ts\";\nimport { hasCascadeChildren } from \"@/components/base/PvMenu/cascadeUtils\";\nimport PvMenuItemVariant from \"@/components/base/PvMenu/items/PvMenuItemVariant.vue\";\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport {\n SelectedItemsKey,\n EnableChildExpansionKey,\n CascadeSelectedParentIdsKey,\n CascadeDeselectedChildIdsKey,\n ParentSelectsAllChildrenKey,\n} from \"@/components/base/PvMenu/symbols\";\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst MAX_LEVEL_DEPTH = 4;\n\ninterface PvMenuItemProps extends MenuOption {\n level?: number;\n config?: MenuOptionConfig;\n queryText?: string | null;\n highlightSearchText?: boolean;\n itemClass?: string;\n}\n\nconst props = withDefaults(defineProps<PvMenuItemProps>(), {\n level: 0,\n});\nconst injectedSelectedItems = inject(SelectedItemsKey, undefined);\nconst modelSelectedIds = defineModel<string[]>(\"selectedIds\", { default: () => [] });\n\nconst enableChildExpansion = inject(EnableChildExpansionKey, ref(false));\nconst parentSelectsAllChildren = inject(ParentSelectsAllChildrenKey, ref(false));\nconst cascadeSelectedParentIds = inject(CascadeSelectedParentIdsKey, undefined);\nconst cascadeDeselectedChildIds = inject(CascadeDeselectedChildIdsKey, undefined);\n\nconst isExpanded = ref(props.defaultExpanded ?? false);\nconst isSeeMoreLoading = ref(false);\nconst hasExhaustedChildren = ref(false);\nconst childOptions = ref<MenuOption[]>(props.children ?? []);\nconst lazyLoadedChildIds = ref<Set<string>>(new Set());\n\nwatch(\n () => props.children,\n (newChildren) => {\n if (!newChildren) {\n childOptions.value = [];\n return;\n }\n // Preserve lazily loaded children (from handleSeeMore) that aren't in the\n // new prop value, but drop any original children that were filtered out.\n const lazyChildren = childOptions.value.filter((c) => lazyLoadedChildIds.value.has(c.id));\n const newChildIds = new Set(newChildren.map((c) => c.id));\n const extras = lazyChildren.filter((c) => !newChildIds.has(c.id));\n childOptions.value = [...newChildren, ...extras];\n hasExhaustedChildren.value = false;\n },\n);\n\nconst toggleExpanded = () => {\n isExpanded.value = !isExpanded.value;\n};\n\nconst paddingLeft = computed(() => ({ paddingLeft: `${props.level * 12 + 12}px` }));\n\n// Omit PvMenuItem-only props so v-bind doesn't leak them as DOM attributes\n// on PvMenuItemVariant (which doesn't declare them).\nconst variantProps = computed(() => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { level, config, itemClass, ...rest } = props;\n return rest;\n});\n\nconst hasChildren = computed(() => {\n return hasCascadeChildren({ ...props, children: childOptions.value }) && props.level < MAX_LEVEL_DEPTH;\n});\n\nconst showSubMenu = computed(() => {\n if (!hasChildren.value) return false;\n if (enableChildExpansion.value) return isExpanded.value || !!props.disabled;\n return true;\n});\n\nconst chevronIcon = computed(() => {\n return isExpanded.value ? \"chevron-down\" : \"chevron-right\";\n});\n\nconst optionIsSelected = (option: PvMenuItemProps): boolean => {\n if (injectedSelectedItems && Array.isArray(injectedSelectedItems.value)) {\n return injectedSelectedItems.value.some((item) => item.id === option.id);\n }\n return modelSelectedIds.value.includes(option.id);\n};\n\nconst isChildVisibleInReadOnly = (childOption: MenuOption): boolean => {\n if (optionIsSelected(childOption)) return true;\n if (cascadeSelectedParentIds?.value?.has(props.id)) {\n const deselected = cascadeDeselectedChildIds?.value?.get(props.id);\n return !deselected?.has(childOption.id);\n }\n return false;\n};\n\nconst emits = defineEmits<{\n (e: \"handle-selected\", payload: MenuOptionSelectedEvent): void;\n (e: \"see-more\", payload: SeeMoreEvent): void;\n}>();\n\nconst hasMoreChildren = computed(() => {\n if (hasExhaustedChildren.value) return false;\n if (props.totalChildCount == null) return false;\n return props.totalChildCount > childOptions.value.length;\n});\n\nconst handleSeeMoreClick = async () => {\n if (isSeeMoreLoading.value) return;\n\n if (!props.handleSeeMore) {\n emits(\"see-more\", { parentId: props.id, offset: childOptions.value.length });\n return;\n }\n\n const parentIsSelected = cascadeSelectedParentIds?.value?.has(props.id) ?? false;\n\n isSeeMoreLoading.value = true;\n try {\n const newChildren = await props.handleSeeMore({ parentId: props.id, offset: childOptions.value.length });\n if (Array.isArray(newChildren) && newChildren.length > 0) {\n const existingIds = new Set(childOptions.value.map((c) => c.id));\n const uniqueNewChildren = newChildren.filter((c) => !existingIds.has(c.id));\n if (uniqueNewChildren.length === 0) {\n hasExhaustedChildren.value = true;\n return;\n }\n const nextLazy = new Set(lazyLoadedChildIds.value);\n for (const c of uniqueNewChildren) nextLazy.add(c.id);\n lazyLoadedChildIds.value = nextLazy;\n childOptions.value = [...childOptions.value, ...uniqueNewChildren];\n // If the parent was selected, auto-select newly loaded children\n // (excluding any that were explicitly deselected by the user)\n if (parentIsSelected && injectedSelectedItems?.value) {\n const deselected = cascadeDeselectedChildIds?.value?.get(props.id);\n const candidates = deselected ? uniqueNewChildren.filter((c) => !deselected.has(c.id)) : uniqueNewChildren;\n if (candidates.length > 0) {\n const existingSelectedIds = new Set(injectedSelectedItems.value.map((item) => item.id));\n const toSelect = candidates.filter((c) => !existingSelectedIds.has(c.id));\n if (toSelect.length > 0) {\n injectedSelectedItems.value = [...injectedSelectedItems.value, ...toSelect];\n }\n }\n }\n } else if (Array.isArray(newChildren)) {\n hasExhaustedChildren.value = true;\n }\n } finally {\n isSeeMoreLoading.value = false;\n }\n};\n\nconst handleSelected = (event: MenuOptionSelectedEvent) => {\n // If this item is expandable and has children, clicking it toggles expansion\n // rather than selection — unless parentSelectsAllChildren is enabled, in which\n // case the parent click should cascade-select all children (expansion stays\n // available via the chevron button).\n if (\n enableChildExpansion.value &&\n hasChildren.value &&\n event.option.id === props.id &&\n !parentSelectsAllChildren.value\n ) {\n toggleExpanded();\n return;\n }\n if (!injectedSelectedItems) {\n const index = modelSelectedIds.value.indexOf(event.option.id);\n if (index > -1) {\n modelSelectedIds.value = [...modelSelectedIds.value.slice(0, index), ...modelSelectedIds.value.slice(index + 1)];\n } else {\n modelSelectedIds.value = [...modelSelectedIds.value, event.option.id];\n }\n }\n emits(\"handle-selected\", event);\n};\n\n// Bubble child handle-selected events without toggling modelSelectedIds again\n// (the child PvMenuItem already updated the shared modelSelectedIds via v-model).\nconst handleChildSelected = (event: MenuOptionSelectedEvent) => {\n emits(\"handle-selected\", event);\n};\n</script>\n\n<template v-if=\"level < MAX_LEVEL_DEPTH\">\n <PvMenuItemVariant\n v-bind=\"variantProps\"\n :children=\"childOptions\"\n :menuOptionConfig=\"config\"\n :queryText=\"queryText\"\n :highlightSearchText=\"highlightSearchText\"\n :showChevron=\"enableChildExpansion && hasChildren\"\n :chevronIcon=\"chevronIcon\"\n :expanded=\"isExpanded\"\n @handle-selected=\"handleSelected\"\n @toggle-expanded=\"toggleExpanded\"\n :selected=\"optionIsSelected(props)\"\n />\n <ul v-if=\"showSubMenu\" role=\"list\" :style=\"paddingLeft\">\n <li\n v-for=\"childOption in childOptions\"\n v-show=\"!props.disabled || isChildVisibleInReadOnly(childOption)\"\n :key=\"childOption.id\"\n :data-active=\"optionIsSelected(childOption) ? 'true' : null\"\n :class=\"itemClass\"\n >\n <PvMenuItem\n v-bind=\"childOption\"\n :disabled=\"props.disabled || childOption.disabled\"\n v-model:selectedIds=\"modelSelectedIds\"\n :config=\"childOption.config ?? config\"\n :queryText=\"queryText\"\n :highlightSearchText=\"highlightSearchText\"\n :level=\"level + 1\"\n @handle-selected=\"handleChildSelected\"\n @see-more=\"emits('see-more', $event)\"\n />\n </li>\n <li v-if=\"hasMoreChildren\">\n <PvButton\n class=\"pv-text-brand\"\n variant=\"ghost\"\n label=\"See more\"\n :loading=\"isSeeMoreLoading\"\n data-testid=\"pv-menu-item-see-more\"\n @click=\"handleSeeMoreClick\"\n />\n </li>\n </ul>\n</template>\n","<script lang=\"ts\" setup>\nimport { computed, inject, ref, watch } from \"vue\";\n\nimport { MenuOption, MenuOptionConfig, MenuOptionSelectedEvent, SeeMoreEvent } from \"@/types.ts\";\nimport { hasCascadeChildren } from \"@/components/base/PvMenu/cascadeUtils\";\nimport PvMenuItemVariant from \"@/components/base/PvMenu/items/PvMenuItemVariant.vue\";\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport {\n SelectedItemsKey,\n EnableChildExpansionKey,\n CascadeSelectedParentIdsKey,\n CascadeDeselectedChildIdsKey,\n ParentSelectsAllChildrenKey,\n} from \"@/components/base/PvMenu/symbols\";\n\ndefineOptions({\n inheritAttrs: false,\n});\n\nconst MAX_LEVEL_DEPTH = 4;\n\ninterface PvMenuItemProps extends MenuOption {\n level?: number;\n config?: MenuOptionConfig;\n queryText?: string | null;\n highlightSearchText?: boolean;\n itemClass?: string;\n}\n\nconst props = withDefaults(defineProps<PvMenuItemProps>(), {\n level: 0,\n});\nconst injectedSelectedItems = inject(SelectedItemsKey, undefined);\nconst modelSelectedIds = defineModel<string[]>(\"selectedIds\", { default: () => [] });\n\nconst enableChildExpansion = inject(EnableChildExpansionKey, ref(false));\nconst parentSelectsAllChildren = inject(ParentSelectsAllChildrenKey, ref(false));\nconst cascadeSelectedParentIds = inject(CascadeSelectedParentIdsKey, undefined);\nconst cascadeDeselectedChildIds = inject(CascadeDeselectedChildIdsKey, undefined);\n\nconst isExpanded = ref(props.defaultExpanded ?? false);\nconst isSeeMoreLoading = ref(false);\nconst hasExhaustedChildren = ref(false);\nconst childOptions = ref<MenuOption[]>(props.children ?? []);\nconst lazyLoadedChildIds = ref<Set<string>>(new Set());\n\nwatch(\n () => props.children,\n (newChildren) => {\n if (!newChildren) {\n childOptions.value = [];\n return;\n }\n // Preserve lazily loaded children (from handleSeeMore) that aren't in the\n // new prop value, but drop any original children that were filtered out.\n const lazyChildren = childOptions.value.filter((c) => lazyLoadedChildIds.value.has(c.id));\n const newChildIds = new Set(newChildren.map((c) => c.id));\n const extras = lazyChildren.filter((c) => !newChildIds.has(c.id));\n childOptions.value = [...newChildren, ...extras];\n hasExhaustedChildren.value = false;\n },\n);\n\nconst toggleExpanded = () => {\n isExpanded.value = !isExpanded.value;\n};\n\nconst paddingLeft = computed(() => ({ paddingLeft: `${props.level * 12 + 12}px` }));\n\n// Omit PvMenuItem-only props so v-bind doesn't leak them as DOM attributes\n// on PvMenuItemVariant (which doesn't declare them).\nconst variantProps = computed(() => {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { level, config, itemClass, ...rest } = props;\n return rest;\n});\n\nconst hasChildren = computed(() => {\n return hasCascadeChildren({ ...props, children: childOptions.value }) && props.level < MAX_LEVEL_DEPTH;\n});\n\nconst showSubMenu = computed(() => {\n if (!hasChildren.value) return false;\n if (enableChildExpansion.value) return isExpanded.value || !!props.disabled;\n return true;\n});\n\nconst chevronIcon = computed(() => {\n return isExpanded.value ? \"chevron-down\" : \"chevron-right\";\n});\n\nconst optionIsSelected = (option: PvMenuItemProps): boolean => {\n if (injectedSelectedItems && Array.isArray(injectedSelectedItems.value)) {\n return injectedSelectedItems.value.some((item) => item.id === option.id);\n }\n return modelSelectedIds.value.includes(option.id);\n};\n\nconst isChildVisibleInReadOnly = (childOption: MenuOption): boolean => {\n if (optionIsSelected(childOption)) return true;\n if (cascadeSelectedParentIds?.value?.has(props.id)) {\n const deselected = cascadeDeselectedChildIds?.value?.get(props.id);\n return !deselected?.has(childOption.id);\n }\n return false;\n};\n\nconst emits = defineEmits<{\n (e: \"handle-selected\", payload: MenuOptionSelectedEvent): void;\n (e: \"see-more\", payload: SeeMoreEvent): void;\n}>();\n\nconst hasMoreChildren = computed(() => {\n if (hasExhaustedChildren.value) return false;\n if (props.totalChildCount == null) return false;\n return props.totalChildCount > childOptions.value.length;\n});\n\nconst handleSeeMoreClick = async () => {\n if (isSeeMoreLoading.value) return;\n\n if (!props.handleSeeMore) {\n emits(\"see-more\", { parentId: props.id, offset: childOptions.value.length });\n return;\n }\n\n const parentIsSelected = cascadeSelectedParentIds?.value?.has(props.id) ?? false;\n\n isSeeMoreLoading.value = true;\n try {\n const newChildren = await props.handleSeeMore({ parentId: props.id, offset: childOptions.value.length });\n if (Array.isArray(newChildren) && newChildren.length > 0) {\n const existingIds = new Set(childOptions.value.map((c) => c.id));\n const uniqueNewChildren = newChildren.filter((c) => !existingIds.has(c.id));\n if (uniqueNewChildren.length === 0) {\n hasExhaustedChildren.value = true;\n return;\n }\n const nextLazy = new Set(lazyLoadedChildIds.value);\n for (const c of uniqueNewChildren) nextLazy.add(c.id);\n lazyLoadedChildIds.value = nextLazy;\n childOptions.value = [...childOptions.value, ...uniqueNewChildren];\n // If the parent was selected, auto-select newly loaded children\n // (excluding any that were explicitly deselected by the user)\n if (parentIsSelected && injectedSelectedItems?.value) {\n const deselected = cascadeDeselectedChildIds?.value?.get(props.id);\n const candidates = deselected ? uniqueNewChildren.filter((c) => !deselected.has(c.id)) : uniqueNewChildren;\n if (candidates.length > 0) {\n const existingSelectedIds = new Set(injectedSelectedItems.value.map((item) => item.id));\n const toSelect = candidates.filter((c) => !existingSelectedIds.has(c.id));\n if (toSelect.length > 0) {\n injectedSelectedItems.value = [...injectedSelectedItems.value, ...toSelect];\n }\n }\n }\n } else if (Array.isArray(newChildren)) {\n hasExhaustedChildren.value = true;\n }\n } finally {\n isSeeMoreLoading.value = false;\n }\n};\n\nconst handleSelected = (event: MenuOptionSelectedEvent) => {\n // If this item is expandable and has children, clicking it toggles expansion\n // rather than selection — unless parentSelectsAllChildren is enabled, in which\n // case the parent click should cascade-select all children (expansion stays\n // available via the chevron button).\n if (\n enableChildExpansion.value &&\n hasChildren.value &&\n event.option.id === props.id &&\n !parentSelectsAllChildren.value\n ) {\n toggleExpanded();\n return;\n }\n if (!injectedSelectedItems) {\n const index = modelSelectedIds.value.indexOf(event.option.id);\n if (index > -1) {\n modelSelectedIds.value = [...modelSelectedIds.value.slice(0, index), ...modelSelectedIds.value.slice(index + 1)];\n } else {\n modelSelectedIds.value = [...modelSelectedIds.value, event.option.id];\n }\n }\n emits(\"handle-selected\", event);\n};\n\n// Bubble child handle-selected events without toggling modelSelectedIds again\n// (the child PvMenuItem already updated the shared modelSelectedIds via v-model).\nconst handleChildSelected = (event: MenuOptionSelectedEvent) => {\n emits(\"handle-selected\", event);\n};\n</script>\n\n<template v-if=\"level < MAX_LEVEL_DEPTH\">\n <PvMenuItemVariant\n v-bind=\"variantProps\"\n :children=\"childOptions\"\n :menuOptionConfig=\"config\"\n :queryText=\"queryText\"\n :highlightSearchText=\"highlightSearchText\"\n :showChevron=\"enableChildExpansion && hasChildren\"\n :chevronIcon=\"chevronIcon\"\n :expanded=\"isExpanded\"\n @handle-selected=\"handleSelected\"\n @toggle-expanded=\"toggleExpanded\"\n :selected=\"optionIsSelected(props)\"\n />\n <ul v-if=\"showSubMenu\" role=\"list\" :style=\"paddingLeft\">\n <li\n v-for=\"childOption in childOptions\"\n v-show=\"!props.disabled || isChildVisibleInReadOnly(childOption)\"\n :key=\"childOption.id\"\n :data-active=\"optionIsSelected(childOption) ? 'true' : null\"\n :class=\"itemClass\"\n >\n <PvMenuItem\n v-bind=\"childOption\"\n :disabled=\"props.disabled || childOption.disabled\"\n v-model:selectedIds=\"modelSelectedIds\"\n :config=\"childOption.config ?? config\"\n :queryText=\"queryText\"\n :highlightSearchText=\"highlightSearchText\"\n :level=\"level + 1\"\n @handle-selected=\"handleChildSelected\"\n @see-more=\"emits('see-more', $event)\"\n />\n </li>\n <li v-if=\"hasMoreChildren\">\n <PvButton\n class=\"pv-text-brand\"\n variant=\"ghost\"\n label=\"See more\"\n :loading=\"isSeeMoreLoading\"\n data-testid=\"pv-menu-item-see-more\"\n @click=\"handleSeeMoreClick\"\n />\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, inject, provide, ref, shallowRef, watch } from \"vue\";\n\nimport { MenuOption, MenuOptionSelectedEvent, SeeMoreEvent } from \"@/types\";\nimport PvMenuItem from \"@/components/base/PvMenu/items/PvMenuItem.vue\";\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport { PvMenuProps } from \"./types\";\nimport { collectLeafOptions, hasCascadeChildren, mergeLeafOptions } from \"./cascadeUtils\";\nimport {\n SelectedItemsKey,\n EnableCascadeSelectionKey,\n OriginalOptionsMapKey,\n ParentSelectsAllChildrenKey,\n CascadeSelectedParentIdsKey,\n CascadeDeselectedChildIdsKey,\n} from \"./symbols\";\n\nconst props = defineProps<PvMenuProps>();\n\nconst emit = defineEmits<{\n (e: \"handle-selected\", payload: MenuOptionSelectedEvent): void;\n (e: \"see-more\", payload: SeeMoreEvent): void;\n}>();\n\nconst selectedItems = defineModel<MenuOption[]>(\"selectedItems\", { default: () => [] });\n\n// Vue 3.5 defineModel doesn't update local value synchronously when the prop\n// is passed by a parent (it only emits and waits for the parent to re-render).\n// This local ref is updated immediately so consecutive selections read correct state.\nconst localSelectedItems = shallowRef<MenuOption[]>(selectedItems.value);\n\nwatch(selectedItems, (newVal) => {\n localSelectedItems.value = newVal;\n});\n\n// Sync back to the model when descendants mutate localSelectedItems directly\n// (e.g. auto-selecting lazy-loaded children in PvMenuItem.handleSeeMoreClick).\nwatch(localSelectedItems, (newVal) => {\n if (newVal !== selectedItems.value) {\n selectedItems.value = newVal;\n }\n});\n\nprovide(SelectedItemsKey, localSelectedItems);\nprovide(\n EnableCascadeSelectionKey,\n computed(() => !!props.enableCascadeSelection),\n);\n\nconst originalOptionsMap = inject(OriginalOptionsMapKey, undefined);\nconst parentSelectsAllChildren = inject(ParentSelectsAllChildrenKey, ref(false));\nconst cascadeSelectedParentIds = inject(CascadeSelectedParentIdsKey, undefined);\nconst cascadeDeselectedChildIds = inject(CascadeDeselectedChildIdsKey, undefined);\n\nconst isSingleSelect = computed(() => props.singleSelect || props.config?.variant === \"radio\");\n\nconst handleItemSelected = (event: MenuOptionSelectedEvent) => {\n if (props.readOnly) return;\n const option = event.option;\n let newSelection: MenuOption[];\n\n if (props.enableCascadeSelection && hasCascadeChildren(option)) {\n // Only leaf options are added to the selection — the parent itself is never\n // included because it is purely an organisational node, not a selectable value.\n // When parentSelectsAllChildren is true, use the original (unfiltered)\n // children so clicking a parent selects all children regardless of search query.\n let leafOptions: MenuOption[];\n if (parentSelectsAllChildren.value && originalOptionsMap?.value) {\n const originalOption = originalOptionsMap.value.get(option.id);\n const originalLeaves = originalOption?.children ? collectLeafOptions(originalOption.children) : [];\n const currentLeaves = option.children ? collectLeafOptions(option.children) : [];\n leafOptions = mergeLeafOptions(originalLeaves, currentLeaves);\n } else {\n leafOptions = option.children ? collectLeafOptions(option.children) : [];\n }\n const leafIds = leafOptions.map((o) => o.id);\n const current = localSelectedItems.value;\n const parentSelected = cascadeSelectedParentIds?.value?.has(option.id) ?? false;\n const anySelected = parentSelected || leafIds.some((id) => current.some((item) => item.id === id));\n newSelection = anySelected ? current.filter((item) => !leafIds.includes(item.id)) : [...current, ...leafOptions];\n\n // Track whether this parent was explicitly clicked for cascade selection\n if (cascadeSelectedParentIds?.value) {\n const next = new Set(cascadeSelectedParentIds.value);\n if (anySelected) {\n next.delete(option.id);\n } else {\n next.add(option.id);\n }\n cascadeSelectedParentIds.value = next;\n }\n // Clear deselected children tracking when parent is explicitly toggled\n if (cascadeDeselectedChildIds?.value?.has(option.id)) {\n const next = new Map(cascadeDeselectedChildIds.value);\n next.delete(option.id);\n cascadeDeselectedChildIds.value = next;\n }\n } else if (isSingleSelect.value) {\n if (localSelectedItems.value.length === 1 && localSelectedItems.value[0].id === option.id) {\n newSelection = [];\n } else {\n newSelection = [option];\n }\n } else {\n const index = localSelectedItems.value.findIndex((item) => item.id === option.id);\n if (index > -1) {\n newSelection = [...localSelectedItems.value.slice(0, index), ...localSelectedItems.value.slice(index + 1)];\n } else {\n newSelection = [...localSelectedItems.value, option];\n }\n\n // Track individually deselected/re-selected children under selected parents\n // so dynamically loaded children (see-more) can inherit the correct state.\n if (props.enableCascadeSelection && cascadeSelectedParentIds?.value && cascadeDeselectedChildIds?.value) {\n const isDeselecting = index > -1;\n for (const parentId of cascadeSelectedParentIds.value) {\n // Find if this child belongs to this parent\n const parentOption = originalOptionsMap?.value?.get(parentId);\n const parentChildren = parentOption?.children ?? props.options.find((o) => o.id === parentId)?.children;\n if (!parentChildren) continue;\n const leaves = collectLeafOptions(parentChildren);\n // Also check the option itself as it may have been dynamically loaded\n const isChildOfParent =\n leaves.some((l) => l.id === option.id) ||\n props.options.find((o) => o.id === parentId)?.children?.some((c) => c.id === option.id);\n if (!isChildOfParent) continue;\n\n const next = new Map(cascadeDeselectedChildIds.value);\n const deselected = new Set(next.get(parentId) ?? []);\n if (isDeselecting) {\n deselected.add(option.id);\n } else {\n deselected.delete(option.id);\n }\n if (deselected.size > 0) {\n next.set(parentId, deselected);\n } else {\n next.delete(parentId);\n }\n cascadeDeselectedChildIds.value = next;\n break;\n }\n }\n }\n\n localSelectedItems.value = newSelection;\n selectedItems.value = newSelection;\n\n emit(\"handle-selected\", event);\n};\n\nconst selectedIds = computed(() => new Set(localSelectedItems.value.map((item) => item.id)));\n\nconst hasSelectedDescendant = (children: MenuOption[]): boolean => {\n for (const child of children) {\n if (selectedIds.value.has(child.id)) return true;\n if (child.children?.length && hasSelectedDescendant(child.children)) return true;\n }\n return false;\n};\n\nconst isActive = (option: MenuOption): true | null => {\n if (selectedIds.value.has(option.id)) {\n return true;\n }\n if (props.enableCascadeSelection && cascadeSelectedParentIds?.value?.has(option.id)) {\n return true;\n }\n if (props.enableCascadeSelection && option.children?.length && hasSelectedDescendant(option.children)) {\n return true;\n }\n return null;\n};\n\nconst isVisible = (option: MenuOption, isLoading?: boolean): boolean => {\n if (!isLoading) return true;\n if (selectedIds.value.has(option.id)) return true;\n if (cascadeSelectedParentIds?.value?.has(option.id)) return true;\n if (option.children?.length && hasSelectedDescendant(option.children)) return true;\n return false;\n};\n</script>\n\n<template>\n <ul role=\"list\" class=\"pv-popover-list\">\n <li\n v-for=\"option in options\"\n v-show=\"isVisible(option, isLoading || props.readOnly)\"\n :key=\"option.id\"\n :data-active=\"isActive(option)\"\n :data-testid=\"itemTestId\"\n :class=\"itemClass\"\n >\n <PvMenuItem\n v-bind=\"option\"\n :disabled=\"props.readOnly || option.disabled\"\n :config=\"config\"\n :itemClass=\"itemClass\"\n :queryText=\"queryText\"\n @handle-selected=\"handleItemSelected\"\n @see-more=\"emit('see-more', $event)\"\n />\n </li>\n <li v-if=\"hasMoreOptions && !props.readOnly\">\n <PvButton\n class=\"pv-text-brand\"\n variant=\"ghost\"\n label=\"See more\"\n :loading=\"isSeeMoreLoading\"\n :disabled=\"isSeeMoreLoading\"\n data-testid=\"pv-menu-see-more\"\n @click=\"emit('see-more', { parentId: undefined })\"\n />\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, inject, provide, ref, shallowRef, watch } from \"vue\";\n\nimport { MenuOption, MenuOptionSelectedEvent, SeeMoreEvent } from \"@/types\";\nimport PvMenuItem from \"@/components/base/PvMenu/items/PvMenuItem.vue\";\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport { PvMenuProps } from \"./types\";\nimport { collectLeafOptions, hasCascadeChildren, mergeLeafOptions } from \"./cascadeUtils\";\nimport {\n SelectedItemsKey,\n EnableCascadeSelectionKey,\n OriginalOptionsMapKey,\n ParentSelectsAllChildrenKey,\n CascadeSelectedParentIdsKey,\n CascadeDeselectedChildIdsKey,\n} from \"./symbols\";\n\nconst props = defineProps<PvMenuProps>();\n\nconst emit = defineEmits<{\n (e: \"handle-selected\", payload: MenuOptionSelectedEvent): void;\n (e: \"see-more\", payload: SeeMoreEvent): void;\n}>();\n\nconst selectedItems = defineModel<MenuOption[]>(\"selectedItems\", { default: () => [] });\n\n// Vue 3.5 defineModel doesn't update local value synchronously when the prop\n// is passed by a parent (it only emits and waits for the parent to re-render).\n// This local ref is updated immediately so consecutive selections read correct state.\nconst localSelectedItems = shallowRef<MenuOption[]>(selectedItems.value);\n\nwatch(selectedItems, (newVal) => {\n localSelectedItems.value = newVal;\n});\n\n// Sync back to the model when descendants mutate localSelectedItems directly\n// (e.g. auto-selecting lazy-loaded children in PvMenuItem.handleSeeMoreClick).\nwatch(localSelectedItems, (newVal) => {\n if (newVal !== selectedItems.value) {\n selectedItems.value = newVal;\n }\n});\n\nprovide(SelectedItemsKey, localSelectedItems);\nprovide(\n EnableCascadeSelectionKey,\n computed(() => !!props.enableCascadeSelection),\n);\n\nconst originalOptionsMap = inject(OriginalOptionsMapKey, undefined);\nconst parentSelectsAllChildren = inject(ParentSelectsAllChildrenKey, ref(false));\nconst cascadeSelectedParentIds = inject(CascadeSelectedParentIdsKey, undefined);\nconst cascadeDeselectedChildIds = inject(CascadeDeselectedChildIdsKey, undefined);\n\nconst isSingleSelect = computed(() => props.singleSelect || props.config?.variant === \"radio\");\n\nconst handleItemSelected = (event: MenuOptionSelectedEvent) => {\n if (props.readOnly) return;\n const option = event.option;\n let newSelection: MenuOption[];\n\n if (props.enableCascadeSelection && hasCascadeChildren(option)) {\n // Only leaf options are added to the selection — the parent itself is never\n // included because it is purely an organisational node, not a selectable value.\n // When parentSelectsAllChildren is true, use the original (unfiltered)\n // children so clicking a parent selects all children regardless of search query.\n let leafOptions: MenuOption[];\n if (parentSelectsAllChildren.value && originalOptionsMap?.value) {\n const originalOption = originalOptionsMap.value.get(option.id);\n const originalLeaves = originalOption?.children ? collectLeafOptions(originalOption.children) : [];\n const currentLeaves = option.children ? collectLeafOptions(option.children) : [];\n leafOptions = mergeLeafOptions(originalLeaves, currentLeaves);\n } else {\n leafOptions = option.children ? collectLeafOptions(option.children) : [];\n }\n const leafIds = leafOptions.map((o) => o.id);\n const current = localSelectedItems.value;\n const parentSelected = cascadeSelectedParentIds?.value?.has(option.id) ?? false;\n const anySelected = parentSelected || leafIds.some((id) => current.some((item) => item.id === id));\n newSelection = anySelected ? current.filter((item) => !leafIds.includes(item.id)) : [...current, ...leafOptions];\n\n // Track whether this parent was explicitly clicked for cascade selection\n if (cascadeSelectedParentIds?.value) {\n const next = new Set(cascadeSelectedParentIds.value);\n if (anySelected) {\n next.delete(option.id);\n } else {\n next.add(option.id);\n }\n cascadeSelectedParentIds.value = next;\n }\n // Clear deselected children tracking when parent is explicitly toggled\n if (cascadeDeselectedChildIds?.value?.has(option.id)) {\n const next = new Map(cascadeDeselectedChildIds.value);\n next.delete(option.id);\n cascadeDeselectedChildIds.value = next;\n }\n } else if (isSingleSelect.value) {\n if (localSelectedItems.value.length === 1 && localSelectedItems.value[0].id === option.id) {\n newSelection = [];\n } else {\n newSelection = [option];\n }\n } else {\n const index = localSelectedItems.value.findIndex((item) => item.id === option.id);\n if (index > -1) {\n newSelection = [...localSelectedItems.value.slice(0, index), ...localSelectedItems.value.slice(index + 1)];\n } else {\n newSelection = [...localSelectedItems.value, option];\n }\n\n // Track individually deselected/re-selected children under selected parents\n // so dynamically loaded children (see-more) can inherit the correct state.\n if (props.enableCascadeSelection && cascadeSelectedParentIds?.value && cascadeDeselectedChildIds?.value) {\n const isDeselecting = index > -1;\n for (const parentId of cascadeSelectedParentIds.value) {\n // Find if this child belongs to this parent\n const parentOption = originalOptionsMap?.value?.get(parentId);\n const parentChildren = parentOption?.children ?? props.options.find((o) => o.id === parentId)?.children;\n if (!parentChildren) continue;\n const leaves = collectLeafOptions(parentChildren);\n // Also check the option itself as it may have been dynamically loaded\n const isChildOfParent =\n leaves.some((l) => l.id === option.id) ||\n props.options.find((o) => o.id === parentId)?.children?.some((c) => c.id === option.id);\n if (!isChildOfParent) continue;\n\n const next = new Map(cascadeDeselectedChildIds.value);\n const deselected = new Set(next.get(parentId) ?? []);\n if (isDeselecting) {\n deselected.add(option.id);\n } else {\n deselected.delete(option.id);\n }\n if (deselected.size > 0) {\n next.set(parentId, deselected);\n } else {\n next.delete(parentId);\n }\n cascadeDeselectedChildIds.value = next;\n break;\n }\n }\n }\n\n localSelectedItems.value = newSelection;\n selectedItems.value = newSelection;\n\n emit(\"handle-selected\", event);\n};\n\nconst selectedIds = computed(() => new Set(localSelectedItems.value.map((item) => item.id)));\n\nconst hasSelectedDescendant = (children: MenuOption[]): boolean => {\n for (const child of children) {\n if (selectedIds.value.has(child.id)) return true;\n if (child.children?.length && hasSelectedDescendant(child.children)) return true;\n }\n return false;\n};\n\nconst isActive = (option: MenuOption): true | null => {\n if (selectedIds.value.has(option.id)) {\n return true;\n }\n if (props.enableCascadeSelection && cascadeSelectedParentIds?.value?.has(option.id)) {\n return true;\n }\n if (props.enableCascadeSelection && option.children?.length && hasSelectedDescendant(option.children)) {\n return true;\n }\n return null;\n};\n\nconst isVisible = (option: MenuOption, isLoading?: boolean): boolean => {\n if (!isLoading) return true;\n if (selectedIds.value.has(option.id)) return true;\n if (cascadeSelectedParentIds?.value?.has(option.id)) return true;\n if (option.children?.length && hasSelectedDescendant(option.children)) return true;\n return false;\n};\n</script>\n\n<template>\n <ul role=\"list\" class=\"pv-popover-list\">\n <li\n v-for=\"option in options\"\n v-show=\"isVisible(option, isLoading || props.readOnly)\"\n :key=\"option.id\"\n :data-active=\"isActive(option)\"\n :data-testid=\"itemTestId\"\n :class=\"itemClass\"\n >\n <PvMenuItem\n v-bind=\"option\"\n :disabled=\"props.readOnly || option.disabled\"\n :config=\"config\"\n :itemClass=\"itemClass\"\n :queryText=\"queryText\"\n @handle-selected=\"handleItemSelected\"\n @see-more=\"emit('see-more', $event)\"\n />\n </li>\n <li v-if=\"hasMoreOptions && !props.readOnly\">\n <PvButton\n class=\"pv-text-brand\"\n variant=\"ghost\"\n label=\"See more\"\n :loading=\"isSeeMoreLoading\"\n :disabled=\"isSeeMoreLoading\"\n data-testid=\"pv-menu-see-more\"\n @click=\"emit('see-more', { parentId: undefined })\"\n />\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\" generic=\"T\">\nimport { watch, useTemplateRef, computed, nextTick, shallowRef, provide } from \"vue\";\nimport { useToggle, onKeyStroke } from \"@vueuse/core\";\n\nimport { PvSearchInputExposed } from \"@/components/base/PvSearchInput/PvSearchInput.vue\";\nimport PvSelectControlPanel from \"../PvMenu/PvMenuControlPanel.vue\";\nimport PvSearchInput from \"../PvSearchInput/PvSearchInput.vue\";\nimport PvSelectButtonTrigger from \"@/components/base/PvSelectButton/PvSelectButtonTrigger/PvSelectButtonTrigger.vue\";\nimport PvMenuEmptyState from \"../PvMenu/PvMenuEmptyState.vue\";\nimport PvMenu from \"../PvMenu/PvMenu.vue\";\nimport PvSpinner from \"@/components/base/PvSpinner/PvSpinner.vue\";\n\nimport { PvMultiSelectButtonProps } from \"./types\";\nimport { MenuOption, MenuOptionConfig, MultiSelectState, SelectionNode, SeeMoreEvent } from \"@/types\";\nimport {\n collectLeafOptions,\n countFromSelectionState,\n countWithCollapsedParents,\n filterOptionsRecursive,\n hasCascadeChildren,\n} from \"../PvMenu/cascadeUtils\";\nimport {\n OriginalOptionsMapKey,\n CascadeSelectedParentIdsKey,\n CascadeDeselectedChildIdsKey,\n ParentSelectsAllChildrenKey,\n EnableChildExpansionKey,\n} from \"../PvMenu/symbols\";\nimport PvPopoverV2 from \"@/components/base/PvPopoverV2/PvPopoverV2.vue\";\nimport { useSlotPresence } from \"@/composables/useSlotPresence\";\n\nconst props = withDefaults(defineProps<PvMultiSelectButtonProps<T>>(), {\n counterPosition: \"left\",\n variant: \"secondary\",\n size: \"lg\",\n label: \"Select\",\n disableDropdownIcon: false,\n disableClearIcon: false,\n disableSearchInput: false,\n readOnly: false,\n optionsVariant: \"checkbox\",\n options: () => [] as MenuOption<T>[],\n menuActionsVariant: \"select-clear\",\n highlightSearchText: false,\n enableCascadeSelection: false,\n counterStyle: \"primary\",\n});\n\nconst optionConfig = computed(() => {\n const config: MenuOptionConfig = {\n renderer: props.optionsRenderer,\n action: props.optionsAction,\n variant: props.optionsVariant,\n counterBadgeVariant: props.counterBadgeVariant,\n };\n return config;\n});\n\n// Build a map from option id → original (unfiltered) option so that descendants\n// can look up the full children list when parentSelectsAllChildren is true.\nconst originalOptionsMap = computed(() => {\n const map = new Map<string, MenuOption<T>>();\n const buildMap = (options: MenuOption<T>[]) => {\n for (const option of options) {\n map.set(option.id, option);\n if (option.children?.length) buildMap(option.children);\n }\n };\n buildMap(props.options);\n return map;\n});\n\nconst cascadeSelectedParentIds = shallowRef<Set<string>>(new Set());\nconst cascadeDeselectedChildIds = shallowRef<Map<string, Set<string>>>(new Map());\n\nprovide(OriginalOptionsMapKey, originalOptionsMap);\nprovide(CascadeSelectedParentIdsKey, cascadeSelectedParentIds);\nprovide(CascadeDeselectedChildIdsKey, cascadeDeselectedChildIds);\nprovide(\n ParentSelectsAllChildrenKey,\n computed(() => props.parentSelectsAllChildren),\n);\nprovide(\n EnableChildExpansionKey,\n computed(() => !!props.enableChildExpansion),\n);\n\nconst emits = defineEmits<{\n (e: \"dropdown-open\"): void;\n (e: \"dropdown-closed\"): void;\n (e: \"see-more\", payload: SeeMoreEvent): void;\n}>();\n\n/** Pre-computed mapping of parent option ID → its leaf descendant options. */\nconst parentLeafMap = computed(() => {\n const map = new Map<string, MenuOption<T>[]>();\n for (const [id, option] of originalOptionsMap.value) {\n if (hasCascadeChildren(option)) {\n map.set(id, option.children ? collectLeafOptions(option.children) : []);\n }\n }\n return map;\n});\n\nconst getSelectionState = (): MultiSelectState => {\n const parentLeafIds = new Set<string>();\n if (cascadeSelectedParentIds.value.size > 0) {\n for (const parentId of cascadeSelectedParentIds.value) {\n const leaves = parentLeafMap.value.get(parentId);\n if (leaves) {\n for (const leaf of leaves) parentLeafIds.add(leaf.id);\n }\n }\n }\n\n const nodes: SelectionNode[] = [];\n\n for (const parentId of cascadeSelectedParentIds.value) {\n const deselected = cascadeDeselectedChildIds.value.get(parentId);\n const node: SelectionNode = { id: parentId, state: \"selected\" };\n if (deselected?.size) {\n node.children = [...deselected].map((childId) => ({\n id: childId,\n state: \"deselected\" as const,\n }));\n }\n nodes.push(node);\n }\n\n for (const item of selectedItems.value) {\n if (!parentLeafIds.has(item.id)) {\n nodes.push({ id: item.id, state: \"selected\" });\n }\n }\n\n return nodes;\n};\n\nconst hasMoreOptions = computed(() => {\n if (props.hasMoreOptions != null) return props.hasMoreOptions;\n if (props.totalOptionCount == null) return false;\n return props.totalOptionCount > props.options.length;\n});\n\nconst counterValue = computed(() => {\n const additional = props.additionalCounter ?? 0;\n if (props.enableCascadeSelection && props.countSelectedParents && modelSelectionState.value?.length) {\n return countFromSelectionState(modelSelectionState.value) + additional;\n }\n if (!props.countSelectedParents || !props.enableCascadeSelection) {\n return selectedItems.value.length + additional;\n }\n const selectedIds = new Set(selectedItems.value.map((item) => item.id));\n return countWithCollapsedParents(props.options, selectedIds) + additional;\n});\n\nconst hasSelection = computed(() => {\n if (selectedItems.value.length > 0) return true;\n if (props.enableCascadeSelection && modelSelectionState.value?.length) {\n return modelSelectionState.value.some((node) => node.state === \"selected\");\n }\n return false;\n});\n\nconst handleSeeMore = (payload?: SeeMoreEvent) => {\n emits(\"see-more\", payload ?? {});\n};\n\nconst searchInputComponentRef = useTemplateRef<PvSearchInputExposed | null>(\"searchInputRef\");\n\nconst [open, handleOpen] = useToggle<boolean>(props.defaultOpen);\nconst modelSelectedItems = defineModel<MenuOption<T>[]>({\n required: false,\n default: () => [],\n});\nconst modelSelectionState = defineModel<MultiSelectState>(\"selectionState\");\nconst searchInput = defineModel<string>(\"searchInput\", {\n required: false,\n default: \"\",\n});\n\nconst suppressChangesUntilConfirmed = computed(() => {\n return props.menuActionsVariant === \"cancel-confirm\";\n});\n\nconst storeSelectedItems = (newSelection: MenuOption<T>[]) => {\n selectedItems.value = newSelection;\n if (!suppressChangesUntilConfirmed.value) {\n modelSelectedItems.value = newSelection;\n modelSelectionState.value = getSelectionState();\n }\n};\n\nconst applyPendingSelection = () => {\n if (suppressChangesUntilConfirmed.value) {\n modelSelectedItems.value = selectedItems.value;\n modelSelectionState.value = getSelectionState();\n }\n};\n\nconst resetPendingSelection = () => {\n if (suppressChangesUntilConfirmed.value) {\n selectedItems.value = modelSelectedItems.value;\n }\n};\n\n// with cancel-confirm, we hold changes until confirmed\nconst selectedItems = shallowRef<MenuOption<T>[]>(modelSelectedItems.value);\n\nconst findOptionById = (id: string): MenuOption<T> | undefined => originalOptionsMap.value.get(id);\n\nconst syncFromSelectionState = (state: MultiSelectState | undefined) => {\n if (!props.enableCascadeSelection || !state) return;\n\n const nextSelectedParents = new Set<string>();\n const nextDeselectedChildren = new Map<string, Set<string>>();\n const nextSelectedItems: MenuOption<T>[] = [];\n const selectedIds = new Set<string>();\n\n const addSelectedItem = (option: MenuOption<T> | undefined, id: string) => {\n if (selectedIds.has(id)) return;\n selectedIds.add(id);\n // Placeholder for unresolved nodes — the trigger badge prefers `…` over the\n // raw scoped token (e.g. `__provider_id__PV_1004__health_system__Kaiser`)\n // until the props.options watcher re-runs this sync with metadata loaded.\n nextSelectedItems.push(option ?? ({ id, text: \"…\" } as MenuOption<T>));\n };\n\n for (const node of state) {\n if (node.state !== \"selected\") continue;\n\n const deselectedIds = new Set(\n (node.children || []).filter((child) => child.state === \"deselected\").map((child) => child.id),\n );\n const leafOptions = parentLeafMap.value.get(node.id);\n\n if (leafOptions) {\n nextSelectedParents.add(node.id);\n if (deselectedIds.size > 0) {\n nextDeselectedChildren.set(node.id, deselectedIds);\n }\n for (const leaf of leafOptions) {\n if (!deselectedIds.has(leaf.id)) {\n addSelectedItem(leaf, leaf.id);\n }\n }\n continue;\n }\n\n addSelectedItem(findOptionById(node.id), node.id);\n }\n\n cascadeSelectedParentIds.value = nextSelectedParents;\n cascadeDeselectedChildIds.value = nextDeselectedChildren;\n selectedItems.value = nextSelectedItems;\n};\n\nconst menuSelectedItems = computed({\n get: () => selectedItems.value,\n set: (newValue: MenuOption<T>[]) => {\n if (!props.readOnly) storeSelectedItems(newValue);\n },\n});\n\nconst closeDropdown = () => {\n searchInput.value = \"\";\n open.value = false;\n};\n\nconst popoverOffset = computed(() => {\n // get width of trigger element to offset popover correctly when overlay trigger is enabled\n const size = props.size === \"lg\" ? 24 : 30;\n return props.overlayTrigger ? -size : undefined;\n});\n\n// sync when parent updates modelSelectedItems directly\nwatch(\n () => modelSelectedItems.value,\n (newValue) => {\n if (props.enableCascadeSelection && modelSelectionState.value?.length && newValue.length === 0) {\n syncFromSelectionState(modelSelectionState.value);\n return;\n }\n selectedItems.value = newValue;\n },\n);\n\nwatch(\n () => [modelSelectionState.value, props.options] as const,\n () => {\n syncFromSelectionState(modelSelectionState.value);\n },\n { deep: true, immediate: true },\n);\n\nwatch(open, (newValue) => {\n if (newValue) {\n resetPendingSelection();\n nextTick(() => {\n // if overlay trigger is enabled and search input exists, auto-target the search input\n if (props.overlayTrigger && !props.disableSearchInput) {\n searchInputComponentRef.value?.input?.focus();\n }\n emits(\"dropdown-open\");\n });\n } else {\n // on close, discard pending changes\n resetPendingSelection();\n emits(\"dropdown-closed\");\n }\n});\n\nconst filteredOptions = computed(() => {\n if (searchInput.value === \"\") return props.options;\n const searchValue = searchInput.value.toLocaleLowerCase();\n\n if (props.enableCascadeSelection) {\n return filterOptionsRecursive(props.options, searchValue, !props.hideParentOnChildQueryMatch);\n }\n\n return props.options.filter(\n (option) =>\n option.text.toLocaleLowerCase().includes(searchValue) ||\n option.searchText?.toLocaleLowerCase().includes(searchValue),\n );\n});\n\nconst handleSelectAll = () => {\n // Mark all parents as cascade-selected (select-all intent) before\n // storing so the selection state snapshot is accurate.\n if (props.enableCascadeSelection) {\n const parentIds = new Set<string>();\n const collectParentIds = (options: MenuOption<T>[]) => {\n for (const option of options) {\n if (hasCascadeChildren(option)) {\n parentIds.add(option.id);\n if (option.children?.length) collectParentIds(option.children);\n }\n }\n };\n collectParentIds(filteredOptions.value as MenuOption<T>[]);\n cascadeSelectedParentIds.value = parentIds;\n cascadeDeselectedChildIds.value = new Map();\n }\n\n // select all visible item values (excluded ones filtered out by search)\n const toSelect = props.enableCascadeSelection\n ? collectLeafOptions(filteredOptions.value as MenuOption<T>[])\n : filteredOptions.value;\n storeSelectedItems(toSelect);\n};\n\nconst handleClearAll = () => {\n cascadeSelectedParentIds.value = new Set();\n cascadeDeselectedChildIds.value = new Map();\n storeSelectedItems([]);\n};\n\nconst handleCancelSelection = () => {\n resetPendingSelection();\n closeDropdown();\n};\n\nconst handleConfirmSelection = () => {\n applyPendingSelection();\n closeDropdown();\n};\n\nconst groupingOptions = computed(() => {\n if (!props.groupings) return;\n\n const groupingMap = new Map<string, MenuOption[]>();\n\n props.groupings.forEach((group) => {\n groupingMap.set(group, []);\n });\n\n groupingMap.set(\"other\", []);\n\n for (const option of props.options) {\n const groupKey = option.groupingLabel;\n const targetGroup = groupKey && groupingMap.has(groupKey) ? groupKey : \"other\";\n groupingMap.get(targetGroup)!.push(option);\n }\n\n for (const [key, options] of groupingMap) {\n if (options.length === 0) {\n groupingMap.delete(key);\n }\n }\n\n return Array.from(groupingMap.entries());\n});\n\nconst showGroupings = computed(() => {\n return props.groupings && searchInput.value === \"\";\n});\n\nconst allSlotProps = computed(() => ({\n ...props,\n selectedItems: modelSelectedItems.value,\n searchInput: searchInput.value,\n slotContext: props.slotContext,\n isOpen: open.value,\n isLoading: props.isLoading,\n}));\n\nconst popoverContentRef = useTemplateRef<HTMLElement | null>(\"popoverContentRef\");\nconst slotHost = computed(() => {\n const rootNode = popoverContentRef.value?.getRootNode();\n return rootNode instanceof ShadowRoot ? (rootNode.host as HTMLElement) : null;\n});\nconst { present: hasHeaderSlot } = useSlotPresence(\"header\", { host: slotHost });\nconst { present: hasNoResultsSlot } = useSlotPresence(\"no-results\", { host: slotHost });\nconst { present: hasFooterSlot } = useSlotPresence(\"footer\", { host: slotHost });\n\nonKeyStroke(\"Escape\", () => {\n if (!open.value) return;\n\n closeDropdown();\n});\n</script>\n\n<template>\n <PvPopoverV2 v-model=\"open\" v-bind=\"popoverProperties\" :offset=\"popoverOffset\">\n <template #trigger>\n <PvSelectButtonTrigger\n ref=\"select-button-trigger-ref\"\n :variant=\"variant\"\n :size=\"size\"\n :disabled=\"disabled\"\n :counterPosition=\"counterPosition\"\n :prefixLabel=\"prefixLabel\"\n :label=\"label\"\n :icon=\"icon\"\n :companyLogo=\"companyLogo\"\n :showClear=\"!disableClearIcon && hasSelection\"\n :showDropdown=\"!disableDropdownIcon && !hasSelection\"\n :open=\"open\"\n :counter-value=\"counterValue\"\n :counter-style=\"counterStyle\"\n :selected-items=\"selectedItems\"\n @handle-clear=\"handleClearAll\"\n @handle-toggle-dropdown=\"handleOpen()\"\n />\n </template>\n <template #content>\n <div\n ref=\"popoverContentRef\"\n class=\"pv-popover\"\n data-test-id=\"pv-popover\"\n :style=\"{ '--position': 'unset', ...popoverCssProperties }\"\n >\n <template v-if=\"!disableSearchInput\">\n <div class=\"pv-inset-square-8 pv-border-bottom\">\n <PvSearchInput\n ref=\"searchInputRef\"\n v-model:model-value=\"searchInput\"\n class=\"pv-stack-4\"\n :placeholder=\"searchPlaceholder\"\n :disabled=\"readOnly\"\n />\n </div>\n </template>\n <div v-if=\"hasHeaderSlot\" class=\"pv-inset-square-8\">\n <slot name=\"header\" v-bind=\"allSlotProps\" />\n </div>\n <template v-if=\"filteredOptions.length > 0\">\n <template v-if=\"showGroupings\">\n <div v-for=\"([label, options], index) in groupingOptions\" :key=\"label\">\n <slot v-if=\"$slots[label]\" :name=\"label\" />\n <span\n class=\"pv-text-body-sm pv-inset-inline\"\n style=\"color: #89989b; --inset-size: 8px\"\n v-else-if=\"label !== 'other'\"\n >{{ label }}</span\n >\n <PvMenu\n v-model:selectedItems=\"menuSelectedItems\"\n :options=\"options\"\n :config=\"optionConfig\"\n :queryText=\"highlightSearchText ? searchInput : null\"\n :itemTestId=\"`pv-multiselect-${label}-item`\"\n itemClass=\"pv-stack-4\"\n :isLoading=\"isLoading\"\n :isSeeMoreLoading=\"isSeeMoreLoading\"\n :enableCascadeSelection=\"enableCascadeSelection\"\n :hasMoreOptions=\"index === groupingOptions!.length - 1 && hasMoreOptions && !isLoading\"\n :readOnly=\"readOnly\"\n @see-more=\"handleSeeMore\"\n />\n <div\n v-if=\"groupingOptions && index !== groupingOptions.length - 1\"\n class=\"pv-border-top\"\n style=\"margin: 8px 0\"\n />\n </div>\n </template>\n <template v-else>\n <PvMenu\n v-model:selectedItems=\"menuSelectedItems\"\n :options=\"filteredOptions\"\n :config=\"optionConfig\"\n :queryText=\"highlightSearchText ? searchInput : null\"\n :itemTestId=\"`pv-multiselect-${label}-item`\"\n itemClass=\"pv-stack-4\"\n :enableCascadeSelection=\"enableCascadeSelection\"\n :isSeeMoreLoading=\"isSeeMoreLoading\"\n :hasMoreOptions=\"hasMoreOptions && !isLoading\"\n :readOnly=\"readOnly\"\n @see-more=\"handleSeeMore\"\n />\n </template>\n </template>\n <div v-if=\"isLoading\" class=\"pv-flex pv-inset-square-8\" style=\"justify-content: center\">\n <PvSpinner variant=\"dark\" />\n </div>\n <template v-else-if=\"filteredOptions.length === 0\">\n <slot v-if=\"hasNoResultsSlot\" name=\"no-results\" v-bind=\"allSlotProps\" />\n <PvMenuEmptyState v-else />\n </template>\n <div\n class=\"pv-sticky pv-surface pv-border-top pv-inset-square-8\"\n style=\"--flex-justify: space-between; --bottom: 0\"\n >\n <slot v-if=\"hasFooterSlot\" name=\"footer\" v-bind=\"allSlotProps\" />\n <PvSelectControlPanel\n v-if=\"menuActionsVariant && !readOnly\"\n :variant=\"menuActionsVariant\"\n :disabled=\"isLoading\"\n @handle-clear-all=\"handleClearAll\"\n @handle-select-all=\"handleSelectAll\"\n @handle-cancel=\"handleCancelSelection\"\n @handle-confirm=\"handleConfirmSelection\"\n />\n </div>\n </div>\n </template>\n </PvPopoverV2>\n</template>\n","<script setup lang=\"ts\" generic=\"T\">\nimport { watch, useTemplateRef, computed, nextTick, shallowRef, provide } from \"vue\";\nimport { useToggle, onKeyStroke } from \"@vueuse/core\";\n\nimport { PvSearchInputExposed } from \"@/components/base/PvSearchInput/PvSearchInput.vue\";\nimport PvSelectControlPanel from \"../PvMenu/PvMenuControlPanel.vue\";\nimport PvSearchInput from \"../PvSearchInput/PvSearchInput.vue\";\nimport PvSelectButtonTrigger from \"@/components/base/PvSelectButton/PvSelectButtonTrigger/PvSelectButtonTrigger.vue\";\nimport PvMenuEmptyState from \"../PvMenu/PvMenuEmptyState.vue\";\nimport PvMenu from \"../PvMenu/PvMenu.vue\";\nimport PvSpinner from \"@/components/base/PvSpinner/PvSpinner.vue\";\n\nimport { PvMultiSelectButtonProps } from \"./types\";\nimport { MenuOption, MenuOptionConfig, MultiSelectState, SelectionNode, SeeMoreEvent } from \"@/types\";\nimport {\n collectLeafOptions,\n countFromSelectionState,\n countWithCollapsedParents,\n filterOptionsRecursive,\n hasCascadeChildren,\n} from \"../PvMenu/cascadeUtils\";\nimport {\n OriginalOptionsMapKey,\n CascadeSelectedParentIdsKey,\n CascadeDeselectedChildIdsKey,\n ParentSelectsAllChildrenKey,\n EnableChildExpansionKey,\n} from \"../PvMenu/symbols\";\nimport PvPopoverV2 from \"@/components/base/PvPopoverV2/PvPopoverV2.vue\";\nimport { useSlotPresence } from \"@/composables/useSlotPresence\";\n\nconst props = withDefaults(defineProps<PvMultiSelectButtonProps<T>>(), {\n counterPosition: \"left\",\n variant: \"secondary\",\n size: \"lg\",\n label: \"Select\",\n disableDropdownIcon: false,\n disableClearIcon: false,\n disableSearchInput: false,\n readOnly: false,\n optionsVariant: \"checkbox\",\n options: () => [] as MenuOption<T>[],\n menuActionsVariant: \"select-clear\",\n highlightSearchText: false,\n enableCascadeSelection: false,\n counterStyle: \"primary\",\n});\n\nconst optionConfig = computed(() => {\n const config: MenuOptionConfig = {\n renderer: props.optionsRenderer,\n action: props.optionsAction,\n variant: props.optionsVariant,\n counterBadgeVariant: props.counterBadgeVariant,\n };\n return config;\n});\n\n// Build a map from option id → original (unfiltered) option so that descendants\n// can look up the full children list when parentSelectsAllChildren is true.\nconst originalOptionsMap = computed(() => {\n const map = new Map<string, MenuOption<T>>();\n const buildMap = (options: MenuOption<T>[]) => {\n for (const option of options) {\n map.set(option.id, option);\n if (option.children?.length) buildMap(option.children);\n }\n };\n buildMap(props.options);\n return map;\n});\n\nconst cascadeSelectedParentIds = shallowRef<Set<string>>(new Set());\nconst cascadeDeselectedChildIds = shallowRef<Map<string, Set<string>>>(new Map());\n\nprovide(OriginalOptionsMapKey, originalOptionsMap);\nprovide(CascadeSelectedParentIdsKey, cascadeSelectedParentIds);\nprovide(CascadeDeselectedChildIdsKey, cascadeDeselectedChildIds);\nprovide(\n ParentSelectsAllChildrenKey,\n computed(() => props.parentSelectsAllChildren),\n);\nprovide(\n EnableChildExpansionKey,\n computed(() => !!props.enableChildExpansion),\n);\n\nconst emits = defineEmits<{\n (e: \"dropdown-open\"): void;\n (e: \"dropdown-closed\"): void;\n (e: \"see-more\", payload: SeeMoreEvent): void;\n}>();\n\n/** Pre-computed mapping of parent option ID → its leaf descendant options. */\nconst parentLeafMap = computed(() => {\n const map = new Map<string, MenuOption<T>[]>();\n for (const [id, option] of originalOptionsMap.value) {\n if (hasCascadeChildren(option)) {\n map.set(id, option.children ? collectLeafOptions(option.children) : []);\n }\n }\n return map;\n});\n\nconst getSelectionState = (): MultiSelectState => {\n const parentLeafIds = new Set<string>();\n if (cascadeSelectedParentIds.value.size > 0) {\n for (const parentId of cascadeSelectedParentIds.value) {\n const leaves = parentLeafMap.value.get(parentId);\n if (leaves) {\n for (const leaf of leaves) parentLeafIds.add(leaf.id);\n }\n }\n }\n\n const nodes: SelectionNode[] = [];\n\n for (const parentId of cascadeSelectedParentIds.value) {\n const deselected = cascadeDeselectedChildIds.value.get(parentId);\n const node: SelectionNode = { id: parentId, state: \"selected\" };\n if (deselected?.size) {\n node.children = [...deselected].map((childId) => ({\n id: childId,\n state: \"deselected\" as const,\n }));\n }\n nodes.push(node);\n }\n\n for (const item of selectedItems.value) {\n if (!parentLeafIds.has(item.id)) {\n nodes.push({ id: item.id, state: \"selected\" });\n }\n }\n\n return nodes;\n};\n\nconst hasMoreOptions = computed(() => {\n if (props.hasMoreOptions != null) return props.hasMoreOptions;\n if (props.totalOptionCount == null) return false;\n return props.totalOptionCount > props.options.length;\n});\n\nconst counterValue = computed(() => {\n const additional = props.additionalCounter ?? 0;\n if (props.enableCascadeSelection && props.countSelectedParents && modelSelectionState.value?.length) {\n return countFromSelectionState(modelSelectionState.value) + additional;\n }\n if (!props.countSelectedParents || !props.enableCascadeSelection) {\n return selectedItems.value.length + additional;\n }\n const selectedIds = new Set(selectedItems.value.map((item) => item.id));\n return countWithCollapsedParents(props.options, selectedIds) + additional;\n});\n\nconst hasSelection = computed(() => {\n if (selectedItems.value.length > 0) return true;\n if (props.enableCascadeSelection && modelSelectionState.value?.length) {\n return modelSelectionState.value.some((node) => node.state === \"selected\");\n }\n return false;\n});\n\nconst handleSeeMore = (payload?: SeeMoreEvent) => {\n emits(\"see-more\", payload ?? {});\n};\n\nconst searchInputComponentRef = useTemplateRef<PvSearchInputExposed | null>(\"searchInputRef\");\n\nconst [open, handleOpen] = useToggle<boolean>(props.defaultOpen);\nconst modelSelectedItems = defineModel<MenuOption<T>[]>({\n required: false,\n default: () => [],\n});\nconst modelSelectionState = defineModel<MultiSelectState>(\"selectionState\");\nconst searchInput = defineModel<string>(\"searchInput\", {\n required: false,\n default: \"\",\n});\n\nconst suppressChangesUntilConfirmed = computed(() => {\n return props.menuActionsVariant === \"cancel-confirm\";\n});\n\nconst storeSelectedItems = (newSelection: MenuOption<T>[]) => {\n selectedItems.value = newSelection;\n if (!suppressChangesUntilConfirmed.value) {\n modelSelectedItems.value = newSelection;\n modelSelectionState.value = getSelectionState();\n }\n};\n\nconst applyPendingSelection = () => {\n if (suppressChangesUntilConfirmed.value) {\n modelSelectedItems.value = selectedItems.value;\n modelSelectionState.value = getSelectionState();\n }\n};\n\nconst resetPendingSelection = () => {\n if (suppressChangesUntilConfirmed.value) {\n selectedItems.value = modelSelectedItems.value;\n }\n};\n\n// with cancel-confirm, we hold changes until confirmed\nconst selectedItems = shallowRef<MenuOption<T>[]>(modelSelectedItems.value);\n\nconst findOptionById = (id: string): MenuOption<T> | undefined => originalOptionsMap.value.get(id);\n\nconst syncFromSelectionState = (state: MultiSelectState | undefined) => {\n if (!props.enableCascadeSelection || !state) return;\n\n const nextSelectedParents = new Set<string>();\n const nextDeselectedChildren = new Map<string, Set<string>>();\n const nextSelectedItems: MenuOption<T>[] = [];\n const selectedIds = new Set<string>();\n\n const addSelectedItem = (option: MenuOption<T> | undefined, id: string) => {\n if (selectedIds.has(id)) return;\n selectedIds.add(id);\n // Placeholder for unresolved nodes — the trigger badge prefers `…` over the\n // raw scoped token (e.g. `__provider_id__PV_1004__health_system__Kaiser`)\n // until the props.options watcher re-runs this sync with metadata loaded.\n nextSelectedItems.push(option ?? ({ id, text: \"…\" } as MenuOption<T>));\n };\n\n for (const node of state) {\n if (node.state !== \"selected\") continue;\n\n const deselectedIds = new Set(\n (node.children || []).filter((child) => child.state === \"deselected\").map((child) => child.id),\n );\n const leafOptions = parentLeafMap.value.get(node.id);\n\n if (leafOptions) {\n nextSelectedParents.add(node.id);\n if (deselectedIds.size > 0) {\n nextDeselectedChildren.set(node.id, deselectedIds);\n }\n for (const leaf of leafOptions) {\n if (!deselectedIds.has(leaf.id)) {\n addSelectedItem(leaf, leaf.id);\n }\n }\n continue;\n }\n\n addSelectedItem(findOptionById(node.id), node.id);\n }\n\n cascadeSelectedParentIds.value = nextSelectedParents;\n cascadeDeselectedChildIds.value = nextDeselectedChildren;\n selectedItems.value = nextSelectedItems;\n};\n\nconst menuSelectedItems = computed({\n get: () => selectedItems.value,\n set: (newValue: MenuOption<T>[]) => {\n if (!props.readOnly) storeSelectedItems(newValue);\n },\n});\n\nconst closeDropdown = () => {\n searchInput.value = \"\";\n open.value = false;\n};\n\nconst popoverOffset = computed(() => {\n // get width of trigger element to offset popover correctly when overlay trigger is enabled\n const size = props.size === \"lg\" ? 24 : 30;\n return props.overlayTrigger ? -size : undefined;\n});\n\n// sync when parent updates modelSelectedItems directly\nwatch(\n () => modelSelectedItems.value,\n (newValue) => {\n if (props.enableCascadeSelection && modelSelectionState.value?.length && newValue.length === 0) {\n syncFromSelectionState(modelSelectionState.value);\n return;\n }\n selectedItems.value = newValue;\n },\n);\n\nwatch(\n () => [modelSelectionState.value, props.options] as const,\n () => {\n syncFromSelectionState(modelSelectionState.value);\n },\n { deep: true, immediate: true },\n);\n\nwatch(open, (newValue) => {\n if (newValue) {\n resetPendingSelection();\n nextTick(() => {\n // if overlay trigger is enabled and search input exists, auto-target the search input\n if (props.overlayTrigger && !props.disableSearchInput) {\n searchInputComponentRef.value?.input?.focus();\n }\n emits(\"dropdown-open\");\n });\n } else {\n // on close, discard pending changes\n resetPendingSelection();\n emits(\"dropdown-closed\");\n }\n});\n\nconst filteredOptions = computed(() => {\n if (searchInput.value === \"\") return props.options;\n const searchValue = searchInput.value.toLocaleLowerCase();\n\n if (props.enableCascadeSelection) {\n return filterOptionsRecursive(props.options, searchValue, !props.hideParentOnChildQueryMatch);\n }\n\n return props.options.filter(\n (option) =>\n option.text.toLocaleLowerCase().includes(searchValue) ||\n option.searchText?.toLocaleLowerCase().includes(searchValue),\n );\n});\n\nconst handleSelectAll = () => {\n // Mark all parents as cascade-selected (select-all intent) before\n // storing so the selection state snapshot is accurate.\n if (props.enableCascadeSelection) {\n const parentIds = new Set<string>();\n const collectParentIds = (options: MenuOption<T>[]) => {\n for (const option of options) {\n if (hasCascadeChildren(option)) {\n parentIds.add(option.id);\n if (option.children?.length) collectParentIds(option.children);\n }\n }\n };\n collectParentIds(filteredOptions.value as MenuOption<T>[]);\n cascadeSelectedParentIds.value = parentIds;\n cascadeDeselectedChildIds.value = new Map();\n }\n\n // select all visible item values (excluded ones filtered out by search)\n const toSelect = props.enableCascadeSelection\n ? collectLeafOptions(filteredOptions.value as MenuOption<T>[])\n : filteredOptions.value;\n storeSelectedItems(toSelect);\n};\n\nconst handleClearAll = () => {\n cascadeSelectedParentIds.value = new Set();\n cascadeDeselectedChildIds.value = new Map();\n storeSelectedItems([]);\n};\n\nconst handleCancelSelection = () => {\n resetPendingSelection();\n closeDropdown();\n};\n\nconst handleConfirmSelection = () => {\n applyPendingSelection();\n closeDropdown();\n};\n\nconst groupingOptions = computed(() => {\n if (!props.groupings) return;\n\n const groupingMap = new Map<string, MenuOption[]>();\n\n props.groupings.forEach((group) => {\n groupingMap.set(group, []);\n });\n\n groupingMap.set(\"other\", []);\n\n for (const option of props.options) {\n const groupKey = option.groupingLabel;\n const targetGroup = groupKey && groupingMap.has(groupKey) ? groupKey : \"other\";\n groupingMap.get(targetGroup)!.push(option);\n }\n\n for (const [key, options] of groupingMap) {\n if (options.length === 0) {\n groupingMap.delete(key);\n }\n }\n\n return Array.from(groupingMap.entries());\n});\n\nconst showGroupings = computed(() => {\n return props.groupings && searchInput.value === \"\";\n});\n\nconst allSlotProps = computed(() => ({\n ...props,\n selectedItems: modelSelectedItems.value,\n searchInput: searchInput.value,\n slotContext: props.slotContext,\n isOpen: open.value,\n isLoading: props.isLoading,\n}));\n\nconst popoverContentRef = useTemplateRef<HTMLElement | null>(\"popoverContentRef\");\nconst slotHost = computed(() => {\n const rootNode = popoverContentRef.value?.getRootNode();\n return rootNode instanceof ShadowRoot ? (rootNode.host as HTMLElement) : null;\n});\nconst { present: hasHeaderSlot } = useSlotPresence(\"header\", { host: slotHost });\nconst { present: hasNoResultsSlot } = useSlotPresence(\"no-results\", { host: slotHost });\nconst { present: hasFooterSlot } = useSlotPresence(\"footer\", { host: slotHost });\n\nonKeyStroke(\"Escape\", () => {\n if (!open.value) return;\n\n closeDropdown();\n});\n</script>\n\n<template>\n <PvPopoverV2 v-model=\"open\" v-bind=\"popoverProperties\" :offset=\"popoverOffset\">\n <template #trigger>\n <PvSelectButtonTrigger\n ref=\"select-button-trigger-ref\"\n :variant=\"variant\"\n :size=\"size\"\n :disabled=\"disabled\"\n :counterPosition=\"counterPosition\"\n :prefixLabel=\"prefixLabel\"\n :label=\"label\"\n :icon=\"icon\"\n :companyLogo=\"companyLogo\"\n :showClear=\"!disableClearIcon && hasSelection\"\n :showDropdown=\"!disableDropdownIcon && !hasSelection\"\n :open=\"open\"\n :counter-value=\"counterValue\"\n :counter-style=\"counterStyle\"\n :selected-items=\"selectedItems\"\n @handle-clear=\"handleClearAll\"\n @handle-toggle-dropdown=\"handleOpen()\"\n />\n </template>\n <template #content>\n <div\n ref=\"popoverContentRef\"\n class=\"pv-popover\"\n data-test-id=\"pv-popover\"\n :style=\"{ '--position': 'unset', ...popoverCssProperties }\"\n >\n <template v-if=\"!disableSearchInput\">\n <div class=\"pv-inset-square-8 pv-border-bottom\">\n <PvSearchInput\n ref=\"searchInputRef\"\n v-model:model-value=\"searchInput\"\n class=\"pv-stack-4\"\n :placeholder=\"searchPlaceholder\"\n :disabled=\"readOnly\"\n />\n </div>\n </template>\n <div v-if=\"hasHeaderSlot\" class=\"pv-inset-square-8\">\n <slot name=\"header\" v-bind=\"allSlotProps\" />\n </div>\n <template v-if=\"filteredOptions.length > 0\">\n <template v-if=\"showGroupings\">\n <div v-for=\"([label, options], index) in groupingOptions\" :key=\"label\">\n <slot v-if=\"$slots[label]\" :name=\"label\" />\n <span\n class=\"pv-text-body-sm pv-inset-inline\"\n style=\"color: #89989b; --inset-size: 8px\"\n v-else-if=\"label !== 'other'\"\n >{{ label }}</span\n >\n <PvMenu\n v-model:selectedItems=\"menuSelectedItems\"\n :options=\"options\"\n :config=\"optionConfig\"\n :queryText=\"highlightSearchText ? searchInput : null\"\n :itemTestId=\"`pv-multiselect-${label}-item`\"\n itemClass=\"pv-stack-4\"\n :isLoading=\"isLoading\"\n :isSeeMoreLoading=\"isSeeMoreLoading\"\n :enableCascadeSelection=\"enableCascadeSelection\"\n :hasMoreOptions=\"index === groupingOptions!.length - 1 && hasMoreOptions && !isLoading\"\n :readOnly=\"readOnly\"\n @see-more=\"handleSeeMore\"\n />\n <div\n v-if=\"groupingOptions && index !== groupingOptions.length - 1\"\n class=\"pv-border-top\"\n style=\"margin: 8px 0\"\n />\n </div>\n </template>\n <template v-else>\n <PvMenu\n v-model:selectedItems=\"menuSelectedItems\"\n :options=\"filteredOptions\"\n :config=\"optionConfig\"\n :queryText=\"highlightSearchText ? searchInput : null\"\n :itemTestId=\"`pv-multiselect-${label}-item`\"\n itemClass=\"pv-stack-4\"\n :enableCascadeSelection=\"enableCascadeSelection\"\n :isSeeMoreLoading=\"isSeeMoreLoading\"\n :hasMoreOptions=\"hasMoreOptions && !isLoading\"\n :readOnly=\"readOnly\"\n @see-more=\"handleSeeMore\"\n />\n </template>\n </template>\n <div v-if=\"isLoading\" class=\"pv-flex pv-inset-square-8\" style=\"justify-content: center\">\n <PvSpinner variant=\"dark\" />\n </div>\n <template v-else-if=\"filteredOptions.length === 0\">\n <slot v-if=\"hasNoResultsSlot\" name=\"no-results\" v-bind=\"allSlotProps\" />\n <PvMenuEmptyState v-else />\n </template>\n <div\n class=\"pv-sticky pv-surface pv-border-top pv-inset-square-8\"\n style=\"--flex-justify: space-between; --bottom: 0\"\n >\n <slot v-if=\"hasFooterSlot\" name=\"footer\" v-bind=\"allSlotProps\" />\n <PvSelectControlPanel\n v-if=\"menuActionsVariant && !readOnly\"\n :variant=\"menuActionsVariant\"\n :disabled=\"isLoading\"\n @handle-clear-all=\"handleClearAll\"\n @handle-select-all=\"handleSelectAll\"\n @handle-cancel=\"handleCancelSelection\"\n @handle-confirm=\"handleConfirmSelection\"\n />\n </div>\n </div>\n </template>\n </PvPopoverV2>\n</template>\n","<script setup lang=\"ts\" generic=\"T\">\nimport { watch, computed } from \"vue\";\nimport type { CSSProperties, Component } from \"vue\";\n\nimport { useToggle, onKeyStroke } from \"@vueuse/core\";\n\nimport PvSearchInput from \"../PvSearchInput/PvSearchInput.vue\";\nimport PvSelectButtonTrigger from \"@/components/base/PvSelectButton/PvSelectButtonTrigger/PvSelectButtonTrigger.vue\";\nimport PvMenuEmptyState from \"../PvMenu/PvMenuEmptyState.vue\";\n\nimport type { PvSelectButtonSize, PvSelectButtonVariant } from \"./types\";\nimport type { MenuAction, MenuOption, MenuOptionConfig, MenuOptionsVariant } from \"@/types\";\nimport type { PvCounterBadgeVariant } from \"../PvCounterBadge/types\";\nimport type { PvPopoverV2Props } from \"@/components/base/PvPopoverV2/types.ts\";\nimport PvPopoverV2 from \"@/components/base/PvPopoverV2/PvPopoverV2.vue\";\nimport PvMenu from \"@/components/base/PvMenu/PvMenu.vue\";\n\nexport interface PvSelectButtonProps<T = unknown> {\n /** Whether the dropdown is open on initial render */\n defaultOpen?: boolean;\n /** Prevent the button from being clicked */\n disabled?: boolean;\n /** Show a loading state on the trigger button */\n isLoading?: boolean;\n /** Visual style of the trigger button */\n variant?: PvSelectButtonVariant;\n /** Inverse button colors for dark backgrounds */\n inverse?: boolean;\n /** Size of the trigger button */\n size?: PvSelectButtonSize;\n /** Configuration passed to the underlying PvPopoverV2 */\n popoverProperties?: PvPopoverV2Props;\n /** Custom CSS properties applied to the popover container */\n popoverCssProperties?: CSSProperties;\n /** Static text shown before the label on the trigger button */\n prefixLabel?: string;\n /** Text label on the trigger button; updates to the selected option's text when an item is chosen */\n label?: string;\n /** Hide the search input inside the dropdown */\n disableSearchInput?: boolean;\n /** Placeholder text for the search input */\n searchPlaceholder?: string;\n /** Visual style of menu options (simple, icon, company, avatar, radio) */\n optionsVariant?: Exclude<MenuOptionsVariant, \"checkbox\">;\n /** The list of selectable options */\n options?: MenuOption<T>[];\n /** Custom Vue component used to render each option */\n optionsRenderer?: Component;\n /** Action configuration for per-option action buttons */\n optionsAction?: MenuAction<T>;\n /** Prevent deselecting the currently selected item */\n disableDeselect?: boolean;\n /** Where to place the counter badge on the trigger */\n counterPosition?: \"left\" | \"right\";\n /** Variant of the counter badge which appears on the button and menu items */\n counterBadgeVariant?: PvCounterBadgeVariant;\n /** Whether to highlight the search text in the options list */\n highlightSearchText?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvSelectButtonProps<T>>(), {\n variant: \"secondary\",\n size: \"lg\",\n label: \"Select an option\",\n disableDeselect: false,\n disableSearchInput: false,\n optionsVariant: \"simple\",\n options: () => [] as MenuOption<T>[],\n highlightSearchText: false,\n});\n\nconst optionConfig = computed(() => {\n const config: MenuOptionConfig = {\n renderer: props.optionsRenderer,\n action: props.optionsAction,\n variant: props.optionsVariant,\n counterBadgeVariant: props.counterBadgeVariant,\n };\n return config;\n});\n\nconst emits = defineEmits<{\n (e: \"dropdown-open\"): void;\n (e: \"dropdown-closed\"): void;\n}>();\n\nconst [open] = useToggle<boolean>(props.defaultOpen);\nconst selectedItem = defineModel<MenuOption>({ required: false });\nconst searchInput = defineModel<string>(\"searchInput\", {\n required: false,\n default: \"\",\n});\n\nwatch(open, (newValue) => {\n if (newValue) {\n emits(\"dropdown-open\");\n } else {\n emits(\"dropdown-closed\");\n }\n});\n\nconst buttonDisplayLabel = computed(() => {\n if (selectedItem.value && selectedItem.value.text) {\n return selectedItem.value.text;\n }\n return props.label;\n});\n\nconst buttonIcon = computed(() => {\n if (selectedItem.value && selectedItem.value.icon) {\n return selectedItem.value.icon;\n }\n return undefined;\n});\n\nconst buttonCompanyLogo = computed(() => {\n if (selectedItem.value && selectedItem.value.companyName) {\n return selectedItem.value.companyName;\n }\n return undefined;\n});\n\nconst buttonAvatar = computed(() => selectedItem.value?.avatar);\n\nconst filteredOptions = computed(() => {\n const searchValue = searchInput.value.trim().toLowerCase();\n if (!searchValue) return props.options;\n\n const searchRecursive = (options: MenuOption[]): MenuOption[] => {\n const result: MenuOption[] = [];\n\n for (const option of options) {\n const matches =\n option.text.toLowerCase().includes(searchValue) || option.searchText?.toLowerCase().includes(searchValue);\n const filteredChildren = searchRecursive(option.children || []);\n\n if (matches) {\n // Parent matches → keep parent, with filtered children\n result.push({\n ...option,\n searchText: searchValue,\n children: filteredChildren,\n });\n } else {\n // Parent does NOT match:\n result.push(...filteredChildren);\n }\n }\n\n return result;\n };\n\n return searchRecursive(props.options);\n});\n\nconst menuSelectedItems = computed({\n get: () => (selectedItem.value ? [selectedItem.value] : []),\n set: (items: MenuOption[]) => {\n if (props.optionsVariant === \"radio\" || props.disableDeselect) {\n if (items.length > 0) {\n selectedItem.value = items[0];\n }\n } else {\n selectedItem.value = items.length > 0 ? items[0] : undefined;\n }\n },\n});\n\nconst handleSelectItem = () => {\n closeDropdown();\n};\n\nconst handleClear = () => {\n selectedItem.value = undefined;\n};\n\nconst closeDropdown = () => {\n open.value = false;\n searchInput.value = \"\";\n};\n\nonKeyStroke(\"Escape\", () => {\n if (!open.value) return;\n\n closeDropdown();\n});\n</script>\n\n<template>\n <PvPopoverV2 v-model=\"open\" v-bind=\"popoverProperties\">\n <template #trigger>\n <PvSelectButtonTrigger\n class=\"pv-full-width\"\n ref=\"select-button-trigger-ref\"\n :variant=\"variant\"\n :inverse=\"inverse\"\n :size=\"size\"\n :disabled=\"disabled\"\n :prefixLabel=\"prefixLabel\"\n :label=\"buttonDisplayLabel\"\n :icon=\"buttonIcon\"\n :companyLogo=\"buttonCompanyLogo\"\n :avatar=\"buttonAvatar\"\n :showClear=\"false\"\n :showDropdown=\"true\"\n :open=\"open\"\n :counter-position=\"counterPosition\"\n :counter-value=\"\n selectedItem?.secondaryText && typeof selectedItem.secondaryText === 'number'\n ? selectedItem.secondaryText\n : undefined\n \"\n :counter-badge-variant=\"counterBadgeVariant\"\n :isLoading=\"isLoading\"\n :menuOptionConfig=\"optionConfig\"\n :renderer=\"optionsRenderer\"\n :selectedOption=\"selectedItem\"\n @handle-clear=\"handleClear\"\n />\n </template>\n <template #content>\n <div class=\"pv-popover\" data-test-id=\"pv-popover\" :style=\"popoverCssProperties\" style=\"position: unset\">\n <template v-if=\"!disableSearchInput\">\n <div class=\"pv-inset-square-8 pv-border-bottom\">\n <PvSearchInput v-model:model-value=\"searchInput\" class=\"pv-stack-4\" :placeholder=\"searchPlaceholder\" />\n </div>\n </template>\n <template v-if=\"filteredOptions.length > 0\">\n <PvMenu\n v-model:selectedItems=\"menuSelectedItems\"\n :options=\"filteredOptions\"\n :config=\"optionConfig\"\n :queryText=\"highlightSearchText ? searchInput : null\"\n :singleSelect=\"true\"\n @handle-selected=\"handleSelectItem\"\n />\n </template>\n <PvMenuEmptyState v-else />\n </div>\n </template>\n </PvPopoverV2>\n</template>\n","<script setup lang=\"ts\" generic=\"T\">\nimport { watch, computed } from \"vue\";\nimport type { CSSProperties, Component } from \"vue\";\n\nimport { useToggle, onKeyStroke } from \"@vueuse/core\";\n\nimport PvSearchInput from \"../PvSearchInput/PvSearchInput.vue\";\nimport PvSelectButtonTrigger from \"@/components/base/PvSelectButton/PvSelectButtonTrigger/PvSelectButtonTrigger.vue\";\nimport PvMenuEmptyState from \"../PvMenu/PvMenuEmptyState.vue\";\n\nimport type { PvSelectButtonSize, PvSelectButtonVariant } from \"./types\";\nimport type { MenuAction, MenuOption, MenuOptionConfig, MenuOptionsVariant } from \"@/types\";\nimport type { PvCounterBadgeVariant } from \"../PvCounterBadge/types\";\nimport type { PvPopoverV2Props } from \"@/components/base/PvPopoverV2/types.ts\";\nimport PvPopoverV2 from \"@/components/base/PvPopoverV2/PvPopoverV2.vue\";\nimport PvMenu from \"@/components/base/PvMenu/PvMenu.vue\";\n\nexport interface PvSelectButtonProps<T = unknown> {\n /** Whether the dropdown is open on initial render */\n defaultOpen?: boolean;\n /** Prevent the button from being clicked */\n disabled?: boolean;\n /** Show a loading state on the trigger button */\n isLoading?: boolean;\n /** Visual style of the trigger button */\n variant?: PvSelectButtonVariant;\n /** Inverse button colors for dark backgrounds */\n inverse?: boolean;\n /** Size of the trigger button */\n size?: PvSelectButtonSize;\n /** Configuration passed to the underlying PvPopoverV2 */\n popoverProperties?: PvPopoverV2Props;\n /** Custom CSS properties applied to the popover container */\n popoverCssProperties?: CSSProperties;\n /** Static text shown before the label on the trigger button */\n prefixLabel?: string;\n /** Text label on the trigger button; updates to the selected option's text when an item is chosen */\n label?: string;\n /** Hide the search input inside the dropdown */\n disableSearchInput?: boolean;\n /** Placeholder text for the search input */\n searchPlaceholder?: string;\n /** Visual style of menu options (simple, icon, company, avatar, radio) */\n optionsVariant?: Exclude<MenuOptionsVariant, \"checkbox\">;\n /** The list of selectable options */\n options?: MenuOption<T>[];\n /** Custom Vue component used to render each option */\n optionsRenderer?: Component;\n /** Action configuration for per-option action buttons */\n optionsAction?: MenuAction<T>;\n /** Prevent deselecting the currently selected item */\n disableDeselect?: boolean;\n /** Where to place the counter badge on the trigger */\n counterPosition?: \"left\" | \"right\";\n /** Variant of the counter badge which appears on the button and menu items */\n counterBadgeVariant?: PvCounterBadgeVariant;\n /** Whether to highlight the search text in the options list */\n highlightSearchText?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvSelectButtonProps<T>>(), {\n variant: \"secondary\",\n size: \"lg\",\n label: \"Select an option\",\n disableDeselect: false,\n disableSearchInput: false,\n optionsVariant: \"simple\",\n options: () => [] as MenuOption<T>[],\n highlightSearchText: false,\n});\n\nconst optionConfig = computed(() => {\n const config: MenuOptionConfig = {\n renderer: props.optionsRenderer,\n action: props.optionsAction,\n variant: props.optionsVariant,\n counterBadgeVariant: props.counterBadgeVariant,\n };\n return config;\n});\n\nconst emits = defineEmits<{\n (e: \"dropdown-open\"): void;\n (e: \"dropdown-closed\"): void;\n}>();\n\nconst [open] = useToggle<boolean>(props.defaultOpen);\nconst selectedItem = defineModel<MenuOption>({ required: false });\nconst searchInput = defineModel<string>(\"searchInput\", {\n required: false,\n default: \"\",\n});\n\nwatch(open, (newValue) => {\n if (newValue) {\n emits(\"dropdown-open\");\n } else {\n emits(\"dropdown-closed\");\n }\n});\n\nconst buttonDisplayLabel = computed(() => {\n if (selectedItem.value && selectedItem.value.text) {\n return selectedItem.value.text;\n }\n return props.label;\n});\n\nconst buttonIcon = computed(() => {\n if (selectedItem.value && selectedItem.value.icon) {\n return selectedItem.value.icon;\n }\n return undefined;\n});\n\nconst buttonCompanyLogo = computed(() => {\n if (selectedItem.value && selectedItem.value.companyName) {\n return selectedItem.value.companyName;\n }\n return undefined;\n});\n\nconst buttonAvatar = computed(() => selectedItem.value?.avatar);\n\nconst filteredOptions = computed(() => {\n const searchValue = searchInput.value.trim().toLowerCase();\n if (!searchValue) return props.options;\n\n const searchRecursive = (options: MenuOption[]): MenuOption[] => {\n const result: MenuOption[] = [];\n\n for (const option of options) {\n const matches =\n option.text.toLowerCase().includes(searchValue) || option.searchText?.toLowerCase().includes(searchValue);\n const filteredChildren = searchRecursive(option.children || []);\n\n if (matches) {\n // Parent matches → keep parent, with filtered children\n result.push({\n ...option,\n searchText: searchValue,\n children: filteredChildren,\n });\n } else {\n // Parent does NOT match:\n result.push(...filteredChildren);\n }\n }\n\n return result;\n };\n\n return searchRecursive(props.options);\n});\n\nconst menuSelectedItems = computed({\n get: () => (selectedItem.value ? [selectedItem.value] : []),\n set: (items: MenuOption[]) => {\n if (props.optionsVariant === \"radio\" || props.disableDeselect) {\n if (items.length > 0) {\n selectedItem.value = items[0];\n }\n } else {\n selectedItem.value = items.length > 0 ? items[0] : undefined;\n }\n },\n});\n\nconst handleSelectItem = () => {\n closeDropdown();\n};\n\nconst handleClear = () => {\n selectedItem.value = undefined;\n};\n\nconst closeDropdown = () => {\n open.value = false;\n searchInput.value = \"\";\n};\n\nonKeyStroke(\"Escape\", () => {\n if (!open.value) return;\n\n closeDropdown();\n});\n</script>\n\n<template>\n <PvPopoverV2 v-model=\"open\" v-bind=\"popoverProperties\">\n <template #trigger>\n <PvSelectButtonTrigger\n class=\"pv-full-width\"\n ref=\"select-button-trigger-ref\"\n :variant=\"variant\"\n :inverse=\"inverse\"\n :size=\"size\"\n :disabled=\"disabled\"\n :prefixLabel=\"prefixLabel\"\n :label=\"buttonDisplayLabel\"\n :icon=\"buttonIcon\"\n :companyLogo=\"buttonCompanyLogo\"\n :avatar=\"buttonAvatar\"\n :showClear=\"false\"\n :showDropdown=\"true\"\n :open=\"open\"\n :counter-position=\"counterPosition\"\n :counter-value=\"\n selectedItem?.secondaryText && typeof selectedItem.secondaryText === 'number'\n ? selectedItem.secondaryText\n : undefined\n \"\n :counter-badge-variant=\"counterBadgeVariant\"\n :isLoading=\"isLoading\"\n :menuOptionConfig=\"optionConfig\"\n :renderer=\"optionsRenderer\"\n :selectedOption=\"selectedItem\"\n @handle-clear=\"handleClear\"\n />\n </template>\n <template #content>\n <div class=\"pv-popover\" data-test-id=\"pv-popover\" :style=\"popoverCssProperties\" style=\"position: unset\">\n <template v-if=\"!disableSearchInput\">\n <div class=\"pv-inset-square-8 pv-border-bottom\">\n <PvSearchInput v-model:model-value=\"searchInput\" class=\"pv-stack-4\" :placeholder=\"searchPlaceholder\" />\n </div>\n </template>\n <template v-if=\"filteredOptions.length > 0\">\n <PvMenu\n v-model:selectedItems=\"menuSelectedItems\"\n :options=\"filteredOptions\"\n :config=\"optionConfig\"\n :queryText=\"highlightSearchText ? searchInput : null\"\n :singleSelect=\"true\"\n @handle-selected=\"handleSelectItem\"\n />\n </template>\n <PvMenuEmptyState v-else />\n </div>\n </template>\n </PvPopoverV2>\n</template>\n","import { PvPaginationVariant } from \"./types\";\n\nconst variantToNumber: Record<PvPaginationVariant, number> = {\n short: 5,\n long: 7,\n};\n\nexport const usePagination = ({\n variant = \"long\",\n}: {\n variant?: PvPaginationVariant;\n} = {}) => {\n /**\n * Number of reserved pagination slots for:\n * - First page\n * - Last page\n * - Ellipsis (\"...\") indicators\n * These help keep the pagination compact and readable.\n */\n const FIRST_LAST_DOTS = 3;\n\n const getPaginations = ({\n currentPage,\n pages,\n }: {\n currentPage: number;\n pages: number;\n }) => {\n if (pages <= variantToNumber[variant]) {\n return Array.from({ length: pages }, (_, i) => ({\n page: i + 1,\n label: (i + 1).toString(),\n }));\n }\n\n const pagination: {\n page: number;\n label: string;\n }[] = [\n {\n page: 1,\n label: \"1\",\n },\n ];\n\n const recalculatedMaxNumberToShow =\n variantToNumber[variant] - FIRST_LAST_DOTS;\n\n const halfPagesAhead = Math.floor(recalculatedMaxNumberToShow / 2);\n\n let start = currentPage - halfPagesAhead;\n let end = currentPage + halfPagesAhead;\n\n const showFirstDots = start > 2;\n const showSecondDots = end < pages - 1;\n\n if (start <= 2) {\n start = 2;\n end = start + recalculatedMaxNumberToShow - 1;\n }\n\n if (end >= pages - 1) {\n end = pages - 1;\n start = end - recalculatedMaxNumberToShow + 1;\n }\n\n if (showFirstDots) {\n pagination.push({\n page: 0,\n label: \"...\",\n });\n }\n\n if (showFirstDots && showSecondDots) {\n for (let i = start + 1; i <= end - 1; i++) {\n pagination.push({ page: i, label: i.toString() });\n }\n } else {\n for (let i = start; i <= end; i++) {\n pagination.push({ page: i, label: i.toString() });\n }\n }\n\n if (showSecondDots) {\n pagination.push({\n page: 0,\n label: \"...\",\n });\n }\n\n if (pages > 1) {\n pagination.push({ page: pages, label: pages.toString() });\n }\n\n return pagination;\n };\n\n return {\n getPaginations,\n };\n};\n","<script setup lang=\"ts\">\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport { usePagination } from \"./usePagination\";\nimport { PvPaginationSize, PvPaginationVariant } from \"./types\";\n\ninterface PvPaginationProps {\n /** Size of the pagination buttons */\n size?: PvPaginationSize;\n /** Total number of pages available */\n maxPages: number;\n maxNumberToShow?: number;\n /** Display variant controlling the number of visible page buttons (\"short\" shows fewer) */\n variant?: PvPaginationVariant;\n}\n\nconst props = withDefaults(defineProps<PvPaginationProps>(), {\n size: \"lg\",\n variant: \"long\",\n});\n\nconst { getPaginations } = usePagination({\n variant: props.variant,\n});\n\nconst currentPage = defineModel<number>({ required: true });\n</script>\n\n<template>\n <ol role=\"list\" class=\"pv-pagination\" data-testid=\"pv-pagination\" :data-style=\"size === 'lg' ? 'small' : undefined\">\n <li>\n <PvButton\n data-testid=\"pagination-left-arrow-icon\"\n :disabled=\"currentPage === 1\"\n left-icon=\"chevron-left\"\n ariaLabel=\"Previous page\"\n variant=\"ghost\"\n @click=\"$emit('update:modelValue', currentPage - 1)\"\n />\n </li>\n <li\n v-for=\"page in getPaginations({\n currentPage,\n pages: maxPages,\n })\"\n :key=\"page.page\"\n :data-testid=\"`pagination-button-${page.page}`\"\n :aria-current=\"page.page === currentPage ? 'page' : undefined\"\n >\n <button v-if=\"page.label === '...'\" class=\"dots-button\" disabled>\n {{ page.label }}\n </button>\n <button v-else @click=\"$emit('update:modelValue', page.page)\">\n {{ page.label }}\n </button>\n </li>\n <li>\n <PvButton\n data-testid=\"pagination-right-arrow-icon\"\n :disabled=\"currentPage === maxPages\"\n left-icon=\"chevron-right\"\n ariaLabel=\"Next page\"\n variant=\"ghost\"\n @click=\"$emit('update:modelValue', currentPage + 1)\"\n />\n </li>\n </ol>\n</template>\n\n<style scoped>\n.dots-button {\n background-color: transparent;\n color: #4b595c;\n}\n</style>\n","<script setup lang=\"ts\">\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport { usePagination } from \"./usePagination\";\nimport { PvPaginationSize, PvPaginationVariant } from \"./types\";\n\ninterface PvPaginationProps {\n /** Size of the pagination buttons */\n size?: PvPaginationSize;\n /** Total number of pages available */\n maxPages: number;\n maxNumberToShow?: number;\n /** Display variant controlling the number of visible page buttons (\"short\" shows fewer) */\n variant?: PvPaginationVariant;\n}\n\nconst props = withDefaults(defineProps<PvPaginationProps>(), {\n size: \"lg\",\n variant: \"long\",\n});\n\nconst { getPaginations } = usePagination({\n variant: props.variant,\n});\n\nconst currentPage = defineModel<number>({ required: true });\n</script>\n\n<template>\n <ol role=\"list\" class=\"pv-pagination\" data-testid=\"pv-pagination\" :data-style=\"size === 'lg' ? 'small' : undefined\">\n <li>\n <PvButton\n data-testid=\"pagination-left-arrow-icon\"\n :disabled=\"currentPage === 1\"\n left-icon=\"chevron-left\"\n ariaLabel=\"Previous page\"\n variant=\"ghost\"\n @click=\"$emit('update:modelValue', currentPage - 1)\"\n />\n </li>\n <li\n v-for=\"page in getPaginations({\n currentPage,\n pages: maxPages,\n })\"\n :key=\"page.page\"\n :data-testid=\"`pagination-button-${page.page}`\"\n :aria-current=\"page.page === currentPage ? 'page' : undefined\"\n >\n <button v-if=\"page.label === '...'\" class=\"dots-button\" disabled>\n {{ page.label }}\n </button>\n <button v-else @click=\"$emit('update:modelValue', page.page)\">\n {{ page.label }}\n </button>\n </li>\n <li>\n <PvButton\n data-testid=\"pagination-right-arrow-icon\"\n :disabled=\"currentPage === maxPages\"\n left-icon=\"chevron-right\"\n ariaLabel=\"Next page\"\n variant=\"ghost\"\n @click=\"$emit('update:modelValue', currentPage + 1)\"\n />\n </li>\n </ol>\n</template>\n\n<style scoped>\n.dots-button {\n background-color: transparent;\n color: #4b595c;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\ninterface PvSelectableCardProps {\n /** Visual style variant of the selectable card. */\n variant?: \"default\" | \"highlight\";\n /** Value associated with this card, used as the input element's value. */\n value?: string;\n /** Unique identifier for the card's input element. Auto-generated if not provided. */\n id?: string;\n /** When true, renders as a checkbox (allowing deselection). When false, renders as a radio button. */\n deselect?: boolean;\n /** Whether the card is currently in the selected state. */\n selected?: boolean;\n}\n\nconst { variant = \"default\", id } = defineProps<PvSelectableCardProps>();\n\nconst labelId = computed(() => {\n if (id) {\n return id;\n }\n return `${Math.random()}`;\n});\n</script>\n\n<template>\n <label\n data-testid=\"pv-selectable-card\"\n :class=\"[\n 'pv-label-selectable-small',\n {\n 'pv-label-selectable-highlight': variant === 'highlight',\n },\n ]\"\n :for=\"labelId\"\n >\n <input\n :checked=\"selected\"\n class=\"pv-hide\"\n name=\"type\"\n :type=\"deselect ? 'checkbox' : 'radio'\"\n :value=\"value\"\n :id=\"labelId\"\n />\n <slot />\n </label>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\ninterface PvSelectableCardProps {\n /** Visual style variant of the selectable card. */\n variant?: \"default\" | \"highlight\";\n /** Value associated with this card, used as the input element's value. */\n value?: string;\n /** Unique identifier for the card's input element. Auto-generated if not provided. */\n id?: string;\n /** When true, renders as a checkbox (allowing deselection). When false, renders as a radio button. */\n deselect?: boolean;\n /** Whether the card is currently in the selected state. */\n selected?: boolean;\n}\n\nconst { variant = \"default\", id } = defineProps<PvSelectableCardProps>();\n\nconst labelId = computed(() => {\n if (id) {\n return id;\n }\n return `${Math.random()}`;\n});\n</script>\n\n<template>\n <label\n data-testid=\"pv-selectable-card\"\n :class=\"[\n 'pv-label-selectable-small',\n {\n 'pv-label-selectable-highlight': variant === 'highlight',\n },\n ]\"\n :for=\"labelId\"\n >\n <input\n :checked=\"selected\"\n class=\"pv-hide\"\n name=\"type\"\n :type=\"deselect ? 'checkbox' : 'radio'\"\n :value=\"value\"\n :id=\"labelId\"\n />\n <slot />\n </label>\n</template>\n","<script setup lang=\"ts\">\ninterface PvSidePanelProps {\n showLeftSidebar?: boolean;\n showRightSidebar?: boolean;\n}\n\ndefineProps<PvSidePanelProps>();\n</script>\n\n<template>\n <div class=\"pv-layout-two-sidebar\">\n <div\n :data-hidden=\"showLeftSidebar === false ? true : undefined\"\n data-testid=\"pv-side-panel-left\"\n data-layout=\"left-sidebar\"\n >\n <slot name=\"left-sidebar\" />\n </div>\n <div data-layout=\"main-section\">\n <slot name=\"main\" />\n </div>\n <div\n :data-hidden=\"showRightSidebar === false ? true : undefined\"\n data-testid=\"pv-side-panel-right\"\n data-layout=\"right-sidebar\"\n >\n <slot name=\"right-sidebar\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\ninterface PvSidePanelProps {\n showLeftSidebar?: boolean;\n showRightSidebar?: boolean;\n}\n\ndefineProps<PvSidePanelProps>();\n</script>\n\n<template>\n <div class=\"pv-layout-two-sidebar\">\n <div\n :data-hidden=\"showLeftSidebar === false ? true : undefined\"\n data-testid=\"pv-side-panel-left\"\n data-layout=\"left-sidebar\"\n >\n <slot name=\"left-sidebar\" />\n </div>\n <div data-layout=\"main-section\">\n <slot name=\"main\" />\n </div>\n <div\n :data-hidden=\"showRightSidebar === false ? true : undefined\"\n data-testid=\"pv-side-panel-right\"\n data-layout=\"right-sidebar\"\n >\n <slot name=\"right-sidebar\" />\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { onMounted, useTemplateRef, watch, ref } from \"vue\";\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport { PvGhostInputVariant } from \"./types\";\n\ninterface PvGhostInputProps {\n /**\n * The typographic style applied to the input text (e.g. h1, h2, text-md, caption).\n */\n variant?: PvGhostInputVariant;\n /** Placeholder text shown when the input is empty. */\n placeholder?: string;\n /** When true, the input is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** When true, displays an edit (pencil) icon button beside the input that focuses it on click. */\n showEditIcon?: boolean;\n}\n\nconst inputRef = useTemplateRef(\"inputRef\");\n\nconst variantToInputNameMap: Record<PvGhostInputVariant, string> = {\n h1: \"ghost-input-h1\",\n h2: \"ghost-input-h2\",\n h3: \"ghost-input-h3\",\n h4: \"ghost-input-h4\",\n \"text-lg\": \"ghost-input-text-large\",\n \"text-md\": \"ghost-input-text-medium\",\n \"text-sm\": \"ghost-input-text-small\",\n caption: \"ghost-input-caption\",\n};\n\nconst variantToDataStyleMap: Record<PvGhostInputVariant, string> = {\n h1: \"h1\",\n h2: \"h2\",\n h3: \"h3\",\n h4: \"h4\",\n \"text-sm\": \"text-small\",\n \"text-md\": \"text-medium\",\n \"text-lg\": \"text-large\",\n caption: \"caption\",\n};\n\nconst props = withDefaults(defineProps<PvGhostInputProps>(), {\n variant: \"h1\",\n});\n\nconst inputValue = defineModel<string>();\nconst inputWidth = ref(0);\n\nconst handleEditIcon = () => {\n inputRef.value?.focus();\n};\n\nonMounted(() => {\n if (inputValue.value && inputValue.value.length > 0) {\n calculateWidth(inputValue.value);\n } else if (props.placeholder) {\n calculateWidth(props.placeholder);\n } else {\n inputWidth.value = 240;\n }\n});\n\nwatch(\n () => inputValue.value,\n () => {\n if (inputValue.value && inputValue.value.length > 0) {\n calculateWidth(inputValue.value);\n } else if (props.placeholder) {\n calculateWidth(props.placeholder);\n } else {\n inputWidth.value = 240;\n }\n },\n);\n\nconst calculateWidth = (value: string) => {\n if (!inputRef.value) return;\n\n const canvas = document.createElement(\"canvas\");\n const context = canvas.getContext(\"2d\");\n\n if (!context) return;\n\n const style = getComputedStyle(inputRef.value);\n context.font = `${style.fontWeight} ${style.fontSize} ${style.fontFamily}`;\n\n inputWidth.value = context.measureText(value).width + 10;\n};\n</script>\n\n<template>\n <div class=\"pv-ghost-input pv-full-width\" data-testid=\"pv-ghost-input\" :data-style=\"variantToDataStyleMap[variant]\">\n <slot name=\"action\" />\n <input\n ref=\"inputRef\"\n v-bind=\"props\"\n v-model=\"inputValue\"\n type=\"text\"\n :style=\"{\n width: inputWidth + 'px',\n }\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :name=\"variantToInputNameMap[variant]\"\n />\n <PvButton v-if=\"showEditIcon\" left-icon=\"edit\" ariaLabel=\"Edit\" variant=\"ghost\" @click=\"handleEditIcon\" />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { onMounted, useTemplateRef, watch, ref } from \"vue\";\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport { PvGhostInputVariant } from \"./types\";\n\ninterface PvGhostInputProps {\n /**\n * The typographic style applied to the input text (e.g. h1, h2, text-md, caption).\n */\n variant?: PvGhostInputVariant;\n /** Placeholder text shown when the input is empty. */\n placeholder?: string;\n /** When true, the input is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** When true, displays an edit (pencil) icon button beside the input that focuses it on click. */\n showEditIcon?: boolean;\n}\n\nconst inputRef = useTemplateRef(\"inputRef\");\n\nconst variantToInputNameMap: Record<PvGhostInputVariant, string> = {\n h1: \"ghost-input-h1\",\n h2: \"ghost-input-h2\",\n h3: \"ghost-input-h3\",\n h4: \"ghost-input-h4\",\n \"text-lg\": \"ghost-input-text-large\",\n \"text-md\": \"ghost-input-text-medium\",\n \"text-sm\": \"ghost-input-text-small\",\n caption: \"ghost-input-caption\",\n};\n\nconst variantToDataStyleMap: Record<PvGhostInputVariant, string> = {\n h1: \"h1\",\n h2: \"h2\",\n h3: \"h3\",\n h4: \"h4\",\n \"text-sm\": \"text-small\",\n \"text-md\": \"text-medium\",\n \"text-lg\": \"text-large\",\n caption: \"caption\",\n};\n\nconst props = withDefaults(defineProps<PvGhostInputProps>(), {\n variant: \"h1\",\n});\n\nconst inputValue = defineModel<string>();\nconst inputWidth = ref(0);\n\nconst handleEditIcon = () => {\n inputRef.value?.focus();\n};\n\nonMounted(() => {\n if (inputValue.value && inputValue.value.length > 0) {\n calculateWidth(inputValue.value);\n } else if (props.placeholder) {\n calculateWidth(props.placeholder);\n } else {\n inputWidth.value = 240;\n }\n});\n\nwatch(\n () => inputValue.value,\n () => {\n if (inputValue.value && inputValue.value.length > 0) {\n calculateWidth(inputValue.value);\n } else if (props.placeholder) {\n calculateWidth(props.placeholder);\n } else {\n inputWidth.value = 240;\n }\n },\n);\n\nconst calculateWidth = (value: string) => {\n if (!inputRef.value) return;\n\n const canvas = document.createElement(\"canvas\");\n const context = canvas.getContext(\"2d\");\n\n if (!context) return;\n\n const style = getComputedStyle(inputRef.value);\n context.font = `${style.fontWeight} ${style.fontSize} ${style.fontFamily}`;\n\n inputWidth.value = context.measureText(value).width + 10;\n};\n</script>\n\n<template>\n <div class=\"pv-ghost-input pv-full-width\" data-testid=\"pv-ghost-input\" :data-style=\"variantToDataStyleMap[variant]\">\n <slot name=\"action\" />\n <input\n ref=\"inputRef\"\n v-bind=\"props\"\n v-model=\"inputValue\"\n type=\"text\"\n :style=\"{\n width: inputWidth + 'px',\n }\"\n :placeholder=\"placeholder\"\n :disabled=\"disabled\"\n :name=\"variantToInputNameMap[variant]\"\n />\n <PvButton v-if=\"showEditIcon\" left-icon=\"edit\" ariaLabel=\"Edit\" variant=\"ghost\" @click=\"handleEditIcon\" />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvAiButton from \"../PvAiButton/PvAiButton.vue\";\n\nwithDefaults(\n defineProps<{\n title?: string;\n showAskTqButton?: boolean;\n askTqButtonId?: string;\n headerTitleId?: string;\n headerActionsId?: string;\n sticky?: boolean;\n }>(),\n {\n askTqButtonId: \"asktq-launch-button\",\n headerTitleId: \"header-title\",\n headerActionsId: \"header-actions\",\n sticky: false,\n },\n);\n</script>\n\n<template>\n <div\n class=\"pv-inset-square pv-flex pv-space-between pv-border-bottom pv-surface\"\n :class=\"{ 'pv-sticky': sticky }\"\n style=\"--inset-size: 0.5rem 1rem\"\n >\n <span v-if=\"title\" class=\"pv-text-title-lg\">{{ title }}</span>\n <div :id=\"headerTitleId\" class=\"pv-flex\" v-else>\n <slot name=\"left\" />\n </div>\n <div class=\"pv-flex\">\n <div :id=\"headerActionsId\" class=\"pv-flex\">\n <slot name=\"right\" />\n </div>\n <div v-if=\"showAskTqButton\" class=\"pv-border-left\" style=\"padding-inline-start: 0.5rem\">\n <PvAiButton :id=\"askTqButtonId\" label=\"\" size=\"lg\" />\n </div>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvAiButton from \"../PvAiButton/PvAiButton.vue\";\n\nwithDefaults(\n defineProps<{\n title?: string;\n showAskTqButton?: boolean;\n askTqButtonId?: string;\n headerTitleId?: string;\n headerActionsId?: string;\n sticky?: boolean;\n }>(),\n {\n askTqButtonId: \"asktq-launch-button\",\n headerTitleId: \"header-title\",\n headerActionsId: \"header-actions\",\n sticky: false,\n },\n);\n</script>\n\n<template>\n <div\n class=\"pv-inset-square pv-flex pv-space-between pv-border-bottom pv-surface\"\n :class=\"{ 'pv-sticky': sticky }\"\n style=\"--inset-size: 0.5rem 1rem\"\n >\n <span v-if=\"title\" class=\"pv-text-title-lg\">{{ title }}</span>\n <div :id=\"headerTitleId\" class=\"pv-flex\" v-else>\n <slot name=\"left\" />\n </div>\n <div class=\"pv-flex\">\n <div :id=\"headerActionsId\" class=\"pv-flex\">\n <slot name=\"right\" />\n </div>\n <div v-if=\"showAskTqButton\" class=\"pv-border-left\" style=\"padding-inline-start: 0.5rem\">\n <PvAiButton :id=\"askTqButtonId\" label=\"\" size=\"lg\" />\n </div>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvCompanyLogo from \"../PvCompanyLogo/PvCompanyLogo.vue\";\nimport { PvCompanyLabelSize } from \"./types\";\n\ninterface PvCompanyLabelProps {\n /** Display size of the label and logo */\n size?: PvCompanyLabelSize;\n /** Logo identifier to display; falls back to label if not provided */\n logo?: string;\n /** Text label to display alongside the logo */\n label: string;\n}\n\nwithDefaults(defineProps<PvCompanyLabelProps>(), {\n size: \"md\",\n});\n\nconst mapSizeToLabelSize: Record<PvCompanyLabelSize, string> = {\n xs: \"pv-text-body-xs\",\n sm: \"pv-text-body-md\",\n md: \"pv-text-body-md\",\n};\n</script>\n\n<template>\n <div class=\"pv-flex\">\n <PvCompanyLogo :name=\"logo ? logo : label\" :size=\"size\" />\n <span :class=\"mapSizeToLabelSize[size]\">{{ label }}</span>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvCompanyLogo from \"../PvCompanyLogo/PvCompanyLogo.vue\";\nimport { PvCompanyLabelSize } from \"./types\";\n\ninterface PvCompanyLabelProps {\n /** Display size of the label and logo */\n size?: PvCompanyLabelSize;\n /** Logo identifier to display; falls back to label if not provided */\n logo?: string;\n /** Text label to display alongside the logo */\n label: string;\n}\n\nwithDefaults(defineProps<PvCompanyLabelProps>(), {\n size: \"md\",\n});\n\nconst mapSizeToLabelSize: Record<PvCompanyLabelSize, string> = {\n xs: \"pv-text-body-xs\",\n sm: \"pv-text-body-md\",\n md: \"pv-text-body-md\",\n};\n</script>\n\n<template>\n <div class=\"pv-flex\">\n <PvCompanyLogo :name=\"logo ? logo : label\" :size=\"size\" />\n <span :class=\"mapSizeToLabelSize[size]\">{{ label }}</span>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvAvatarGroupItem } from \"./types\";\n\ninterface PvAvatarGroupProps {\n /** Array of avatar items to render in the group. */\n items: PvAvatarGroupItem[];\n /** Maximum number of avatars to show before displaying an overflow indicator. Capped at 7. */\n maxDisplayed: number;\n}\n\nconst props = defineProps<PvAvatarGroupProps>();\n\nconst displayedItems = computed(() => {\n return props.maxDisplayed >= 7 ? 7 : props.maxDisplayed;\n});\n\nconst extraDisplayedItems = computed(() => {\n const extraNumbers = props.items.length - displayedItems.value;\n return extraNumbers > 0 ? extraNumbers : 0;\n});\n</script>\n\n<template>\n <ul\n class=\"pv-avatar-group\"\n role=\"list\"\n :data-more=\"extraDisplayedItems <= 0 ? undefined : extraDisplayedItems\"\n data-testid=\"pv-avatar-group\"\n >\n <li v-for=\"(item, index) in items.slice(0, displayedItems)\" :key=\"index\" data-testid=\"pv-avatar-group-item\">\n <template v-if=\"item.initials\">{{ item.initials }}</template>\n <img v-else-if=\"item.image\" :src=\"item.image\" :alt=\"item.alt ?? ''\" />\n <div v-else class=\"pv-avatar-sm\"></div>\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvAvatarGroupItem } from \"./types\";\n\ninterface PvAvatarGroupProps {\n /** Array of avatar items to render in the group. */\n items: PvAvatarGroupItem[];\n /** Maximum number of avatars to show before displaying an overflow indicator. Capped at 7. */\n maxDisplayed: number;\n}\n\nconst props = defineProps<PvAvatarGroupProps>();\n\nconst displayedItems = computed(() => {\n return props.maxDisplayed >= 7 ? 7 : props.maxDisplayed;\n});\n\nconst extraDisplayedItems = computed(() => {\n const extraNumbers = props.items.length - displayedItems.value;\n return extraNumbers > 0 ? extraNumbers : 0;\n});\n</script>\n\n<template>\n <ul\n class=\"pv-avatar-group\"\n role=\"list\"\n :data-more=\"extraDisplayedItems <= 0 ? undefined : extraDisplayedItems\"\n data-testid=\"pv-avatar-group\"\n >\n <li v-for=\"(item, index) in items.slice(0, displayedItems)\" :key=\"index\" data-testid=\"pv-avatar-group-item\">\n <template v-if=\"item.initials\">{{ item.initials }}</template>\n <img v-else-if=\"item.image\" :src=\"item.image\" :alt=\"item.alt ?? ''\" />\n <div v-else class=\"pv-avatar-sm\"></div>\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport PvCounterBadge from \"../PvCounterBadge/PvCounterBadge.vue\";\n\nimport { PvCounterBadgeVariant } from \"../PvCounterBadge/types\";\nimport { PvToggleButtonSize, PvToggleButtonVariant } from \"./types\";\n\ninterface PvToggleButton {\n /**\n * The visual size of the toggle button.\n */\n size?: PvToggleButtonSize;\n /**\n * The visual style variant.\n */\n variant?: PvToggleButtonVariant;\n /** When true, applies fully rounded (pill) corners. */\n rounded?: boolean;\n /** When true, the toggle button is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** The value emitted when this toggle is selected (used with radio-style groups). */\n value?: string;\n /** Visible text label displayed inside the toggle. */\n label?: string;\n /** Icon name displayed to the left of the label. */\n leftIcon?: string;\n /** Icon name displayed to the right of the label. */\n rightIcon?: string;\n /** HTML id for the underlying input element. Auto-generated from label when omitted. */\n id?: string;\n /** HTML name attribute, used to group radio-style toggles. */\n name?: string;\n /**\n * When true, renders as a checkbox (can be deselected). When false, renders as a radio (stays selected).\n */\n deselect?: boolean;\n /** Optional counter on the right side of the button */\n rightCounterBadge?: number;\n}\n\nconst props = withDefaults(defineProps<PvToggleButton>(), {\n variant: \"secondary\",\n deselect: true,\n size: \"xl\",\n});\n\nconst modelValue = defineModel<boolean | string>();\n\nconst counterBadgeInactiveVariant: Record<PvToggleButtonVariant, PvCounterBadgeVariant> = {\n secondary: \"tertiary\",\n tertiary: \"tertiary\",\n ghost: \"ghost\",\n};\n\nconst counterBadgeActiveVariant: Record<PvToggleButtonVariant, PvCounterBadgeVariant> = {\n secondary: \"primary\",\n tertiary: \"primary\",\n ghost: \"primary\",\n};\n\nconst counterBadgeVariant = computed(() => {\n return modelValue.value ? counterBadgeActiveVariant[props.variant] : counterBadgeInactiveVariant[props.variant];\n});\n\nconst classes = computed(() => {\n const variantSuffix = props.variant == \"secondary\" ? \"\" : \"-\" + props.variant;\n return {\n [`pv-toggle${variantSuffix}`]: true,\n \"pv-toggle-round\": props.rounded,\n \"pv-toggle-small\": props.size === \"lg\",\n };\n});\n\nconst labelId = computed(() => {\n if (props.id) {\n return props.id;\n }\n\n return `${props.label}-${Math.random()}`;\n});\n</script>\n\n<template>\n <label data-testid=\"pv-toggle-button\" :class=\"classes\" :for=\"labelId\">\n <input\n v-model=\"modelValue\"\n class=\"pv-hide\"\n :id=\"labelId\"\n :type=\"deselect ? 'checkbox' : 'radio'\"\n :value=\"value\"\n :name=\"name\"\n :disabled=\"disabled\"\n />\n <PvIcon v-if=\"leftIcon\" :name=\"leftIcon\" />\n <span v-if=\"label\">{{ label }}</span>\n <PvIcon v-if=\"rightIcon\" :name=\"rightIcon\" />\n <PvCounterBadge v-if=\"rightCounterBadge\" :value=\"rightCounterBadge\" :variant=\"counterBadgeVariant\" />\n </label>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport PvCounterBadge from \"../PvCounterBadge/PvCounterBadge.vue\";\n\nimport { PvCounterBadgeVariant } from \"../PvCounterBadge/types\";\nimport { PvToggleButtonSize, PvToggleButtonVariant } from \"./types\";\n\ninterface PvToggleButton {\n /**\n * The visual size of the toggle button.\n */\n size?: PvToggleButtonSize;\n /**\n * The visual style variant.\n */\n variant?: PvToggleButtonVariant;\n /** When true, applies fully rounded (pill) corners. */\n rounded?: boolean;\n /** When true, the toggle button is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** The value emitted when this toggle is selected (used with radio-style groups). */\n value?: string;\n /** Visible text label displayed inside the toggle. */\n label?: string;\n /** Icon name displayed to the left of the label. */\n leftIcon?: string;\n /** Icon name displayed to the right of the label. */\n rightIcon?: string;\n /** HTML id for the underlying input element. Auto-generated from label when omitted. */\n id?: string;\n /** HTML name attribute, used to group radio-style toggles. */\n name?: string;\n /**\n * When true, renders as a checkbox (can be deselected). When false, renders as a radio (stays selected).\n */\n deselect?: boolean;\n /** Optional counter on the right side of the button */\n rightCounterBadge?: number;\n}\n\nconst props = withDefaults(defineProps<PvToggleButton>(), {\n variant: \"secondary\",\n deselect: true,\n size: \"xl\",\n});\n\nconst modelValue = defineModel<boolean | string>();\n\nconst counterBadgeInactiveVariant: Record<PvToggleButtonVariant, PvCounterBadgeVariant> = {\n secondary: \"tertiary\",\n tertiary: \"tertiary\",\n ghost: \"ghost\",\n};\n\nconst counterBadgeActiveVariant: Record<PvToggleButtonVariant, PvCounterBadgeVariant> = {\n secondary: \"primary\",\n tertiary: \"primary\",\n ghost: \"primary\",\n};\n\nconst counterBadgeVariant = computed(() => {\n return modelValue.value ? counterBadgeActiveVariant[props.variant] : counterBadgeInactiveVariant[props.variant];\n});\n\nconst classes = computed(() => {\n const variantSuffix = props.variant == \"secondary\" ? \"\" : \"-\" + props.variant;\n return {\n [`pv-toggle${variantSuffix}`]: true,\n \"pv-toggle-round\": props.rounded,\n \"pv-toggle-small\": props.size === \"lg\",\n };\n});\n\nconst labelId = computed(() => {\n if (props.id) {\n return props.id;\n }\n\n return `${props.label}-${Math.random()}`;\n});\n</script>\n\n<template>\n <label data-testid=\"pv-toggle-button\" :class=\"classes\" :for=\"labelId\">\n <input\n v-model=\"modelValue\"\n class=\"pv-hide\"\n :id=\"labelId\"\n :type=\"deselect ? 'checkbox' : 'radio'\"\n :value=\"value\"\n :name=\"name\"\n :disabled=\"disabled\"\n />\n <PvIcon v-if=\"leftIcon\" :name=\"leftIcon\" />\n <span v-if=\"label\">{{ label }}</span>\n <PvIcon v-if=\"rightIcon\" :name=\"rightIcon\" />\n <PvCounterBadge v-if=\"rightCounterBadge\" :value=\"rightCounterBadge\" :variant=\"counterBadgeVariant\" />\n </label>\n</template>\n","<script setup lang=\"ts\">\nimport { ref } from \"vue\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport PvTooltipV2 from \"@/components/base/PvTooltipV2/PvTooltipV2.vue\";\nimport { PvToggleGroupOption, PvToggleGroupProps } from \"@/components/base/PvToggleGroup/types.ts\";\n\nconst props = defineProps<PvToggleGroupProps>();\nconst selectedOption = defineModel<PvToggleGroupOption | null>();\n\n// Generate a stable unique ID for this component instance\nconst groupId = ref(`toggle-group-${Math.random().toString(36).substr(2, 9)}`);\n\nconst handleToggle = (option: PvToggleGroupOption) => {\n if (option.disabled) return;\n\n // If clicking the already selected option and allowDeselect is true, deselect it\n if (selectedOption.value?.value === option.value) {\n if (props.allowDeselect) {\n selectedOption.value = null;\n }\n return;\n }\n\n // Select the new option\n selectedOption.value = option;\n};\n</script>\n\n<template>\n <div class=\"pv-flex\">\n <template v-for=\"option in options\" :key=\"option.value\">\n <PvTooltipV2 :description=\"hideLabels ? option.label : ''\">\n <template #trigger>\n <label\n class=\"pv-label pv-label-hover pv-flex pv-toggle-small\"\n :class=\"{ 'pv-disabled': disabled || option.disabled }\"\n >\n <input\n type=\"radio\"\n :name=\"groupId\"\n :value=\"option.value\"\n :checked=\"selectedOption?.value === option.value\"\n class=\"pv-radio\"\n :disabled=\"disabled || option.disabled\"\n @change=\"handleToggle(option)\"\n />\n <PvIcon v-if=\"option.icon\" :name=\"option.icon\" />\n <span v-if=\"!hideLabels\">{{ option.label }}</span>\n </label>\n </template>\n </PvTooltipV2>\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { ref } from \"vue\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport PvTooltipV2 from \"@/components/base/PvTooltipV2/PvTooltipV2.vue\";\nimport { PvToggleGroupOption, PvToggleGroupProps } from \"@/components/base/PvToggleGroup/types.ts\";\n\nconst props = defineProps<PvToggleGroupProps>();\nconst selectedOption = defineModel<PvToggleGroupOption | null>();\n\n// Generate a stable unique ID for this component instance\nconst groupId = ref(`toggle-group-${Math.random().toString(36).substr(2, 9)}`);\n\nconst handleToggle = (option: PvToggleGroupOption) => {\n if (option.disabled) return;\n\n // If clicking the already selected option and allowDeselect is true, deselect it\n if (selectedOption.value?.value === option.value) {\n if (props.allowDeselect) {\n selectedOption.value = null;\n }\n return;\n }\n\n // Select the new option\n selectedOption.value = option;\n};\n</script>\n\n<template>\n <div class=\"pv-flex\">\n <template v-for=\"option in options\" :key=\"option.value\">\n <PvTooltipV2 :description=\"hideLabels ? option.label : ''\">\n <template #trigger>\n <label\n class=\"pv-label pv-label-hover pv-flex pv-toggle-small\"\n :class=\"{ 'pv-disabled': disabled || option.disabled }\"\n >\n <input\n type=\"radio\"\n :name=\"groupId\"\n :value=\"option.value\"\n :checked=\"selectedOption?.value === option.value\"\n class=\"pv-radio\"\n :disabled=\"disabled || option.disabled\"\n @change=\"handleToggle(option)\"\n />\n <PvIcon v-if=\"option.icon\" :name=\"option.icon\" />\n <span v-if=\"!hideLabels\">{{ option.label }}</span>\n </label>\n </template>\n </PvTooltipV2>\n </template>\n </div>\n</template>\n","<script setup lang=\"ts\">\ninterface PvCheckboxProps {\n /** When true, the checkbox is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** When true, displays the checkbox in an indeterminate (mixed) state. */\n indeterminate?: boolean;\n /** Accessible name when no wrapping <label> is present. */\n ariaLabel?: string;\n}\n\ndefineProps<PvCheckboxProps>();\n\nconst value = defineModel<boolean>();\n</script>\n\n<template>\n <input\n ref=\"checkbox-ref\"\n v-model=\"value\"\n class=\"pv-checkbox\"\n type=\"checkbox\"\n name=\"checkbox\"\n :aria-label=\"ariaLabel\"\n :disabled=\"disabled\"\n :indeterminate=\"indeterminate\"\n />\n</template>\n","<script setup lang=\"ts\">\ninterface PvCheckboxProps {\n /** When true, the checkbox is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** When true, displays the checkbox in an indeterminate (mixed) state. */\n indeterminate?: boolean;\n /** Accessible name when no wrapping <label> is present. */\n ariaLabel?: string;\n}\n\ndefineProps<PvCheckboxProps>();\n\nconst value = defineModel<boolean>();\n</script>\n\n<template>\n <input\n ref=\"checkbox-ref\"\n v-model=\"value\"\n class=\"pv-checkbox\"\n type=\"checkbox\"\n name=\"checkbox\"\n :aria-label=\"ariaLabel\"\n :disabled=\"disabled\"\n :indeterminate=\"indeterminate\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useId } from \"vue\";\nimport type { RadioGroupOption } from \"./types\";\n\ninterface PvRadioGroupProps {\n /** Array of options to render as radio buttons. */\n options?: RadioGroupOption[];\n /** Name attribute shared by all radio inputs. Auto-generated if omitted. */\n name?: string;\n /** Layout direction of the options. */\n orientation?: \"vertical\" | \"horizontal\";\n /** When true, all options are non-interactive and visually dimmed. */\n disabled?: boolean;\n /** Visible label rendered above the group. */\n label?: string;\n /** Accessible label when no visible legend is provided. */\n ariaLabel?: string;\n}\n\nconst props = withDefaults(defineProps<PvRadioGroupProps>(), {\n options: () => [],\n orientation: \"vertical\",\n disabled: false,\n});\n\nconst model = defineModel<string | number | boolean>();\n\nconst generatedName = useId();\nconst labelId = useId();\n\nconst groupName = computed(() => props.name ?? generatedName);\n\nconst radioGroupStyles = computed(() => {\n if (props.orientation === \"vertical\") {\n return {\n \"--flex-align\": \"flex-start\",\n };\n }\n\n return {};\n});\n</script>\n\n<template>\n <div role=\"radiogroup\" :aria-label=\"!label ? ariaLabel : undefined\" :aria-labelledby=\"label ? labelId : undefined\">\n <span v-if=\"label\" :id=\"labelId\" class=\"pv-label pv-stack-8\">{{ label }}</span>\n <div :class=\"orientation === 'horizontal' ? 'pv-flex' : 'pv-flex-vertical'\" :style=\"radioGroupStyles\">\n <label v-for=\"option in options\" :key=\"String(option.value)\" class=\"pv-label pv-flex\">\n <input\n v-model=\"model\"\n class=\"pv-radio\"\n type=\"radio\"\n :name=\"groupName\"\n :value=\"option.value\"\n :disabled=\"disabled || option.disabled\"\n />\n {{ option.label }}\n </label>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, useId } from \"vue\";\nimport type { RadioGroupOption } from \"./types\";\n\ninterface PvRadioGroupProps {\n /** Array of options to render as radio buttons. */\n options?: RadioGroupOption[];\n /** Name attribute shared by all radio inputs. Auto-generated if omitted. */\n name?: string;\n /** Layout direction of the options. */\n orientation?: \"vertical\" | \"horizontal\";\n /** When true, all options are non-interactive and visually dimmed. */\n disabled?: boolean;\n /** Visible label rendered above the group. */\n label?: string;\n /** Accessible label when no visible legend is provided. */\n ariaLabel?: string;\n}\n\nconst props = withDefaults(defineProps<PvRadioGroupProps>(), {\n options: () => [],\n orientation: \"vertical\",\n disabled: false,\n});\n\nconst model = defineModel<string | number | boolean>();\n\nconst generatedName = useId();\nconst labelId = useId();\n\nconst groupName = computed(() => props.name ?? generatedName);\n\nconst radioGroupStyles = computed(() => {\n if (props.orientation === \"vertical\") {\n return {\n \"--flex-align\": \"flex-start\",\n };\n }\n\n return {};\n});\n</script>\n\n<template>\n <div role=\"radiogroup\" :aria-label=\"!label ? ariaLabel : undefined\" :aria-labelledby=\"label ? labelId : undefined\">\n <span v-if=\"label\" :id=\"labelId\" class=\"pv-label pv-stack-8\">{{ label }}</span>\n <div :class=\"orientation === 'horizontal' ? 'pv-flex' : 'pv-flex-vertical'\" :style=\"radioGroupStyles\">\n <label v-for=\"option in options\" :key=\"String(option.value)\" class=\"pv-label pv-flex\">\n <input\n v-model=\"model\"\n class=\"pv-radio\"\n type=\"radio\"\n :name=\"groupName\"\n :value=\"option.value\"\n :disabled=\"disabled || option.disabled\"\n />\n {{ option.label }}\n </label>\n </div>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { onMounted } from \"vue\";\n\ntype PvSpriteProps = {\n src: string;\n variant?: \"v1\" | \"v2\";\n};\n\nconst props = withDefaults(defineProps<PvSpriteProps>(), {\n variant: \"v2\",\n});\n\nonMounted(async () => {\n const file = props.variant === \"v1\" ? \"sprite-v1.svg\" : \"sprite-v2.svg\";\n const fullPath = props.src + file;\n try {\n const response = await fetch(fullPath);\n const svgText = await response.text();\n const target = document.getElementById(\"pv-sprite-content\");\n if (target) {\n target.innerHTML = svgText;\n target.hidden = false; // Optional: show if needed\n }\n } catch (error) {\n console.error(\"Failed to load SVG:\", error);\n }\n});\n</script>\n\n<template>\n <Teleport to=\"body\">\n <div hidden id=\"pv-sprite-content\"></div>\n </Teleport>\n</template>\n","<script setup lang=\"ts\">\nimport { onMounted } from \"vue\";\n\ntype PvSpriteProps = {\n src: string;\n variant?: \"v1\" | \"v2\";\n};\n\nconst props = withDefaults(defineProps<PvSpriteProps>(), {\n variant: \"v2\",\n});\n\nonMounted(async () => {\n const file = props.variant === \"v1\" ? \"sprite-v1.svg\" : \"sprite-v2.svg\";\n const fullPath = props.src + file;\n try {\n const response = await fetch(fullPath);\n const svgText = await response.text();\n const target = document.getElementById(\"pv-sprite-content\");\n if (target) {\n target.innerHTML = svgText;\n target.hidden = false; // Optional: show if needed\n }\n } catch (error) {\n console.error(\"Failed to load SVG:\", error);\n }\n});\n</script>\n\n<template>\n <Teleport to=\"body\">\n <div hidden id=\"pv-sprite-content\"></div>\n </Teleport>\n</template>\n","<script setup lang=\"ts\">\nimport { Skeleton } from \"primevue\";\nimport { PvSekeltonSize, PvSkeletonVariant } from \"./types\";\n\nconst mapSizeToPx: Record<PvSekeltonSize, string> = {\n xs: \"0.75rem\",\n sm: \"1rem\",\n md: \"1.25rem\",\n lg: \"1.5rem\",\n xl: \"2rem\",\n};\n\ninterface PvSkeletonProps {\n /** The size of the skeleton placeholder. Controls height and, for square variant, width. */\n size?: PvSekeltonSize;\n /** The shape variant. \"rectangle\" fills available width; \"square\" uses equal height and width. */\n variant?: PvSkeletonVariant;\n}\n\nwithDefaults(defineProps<PvSkeletonProps>(), {\n size: \"md\",\n variant: \"rectangle\",\n});\n</script>\n\n<template>\n <Skeleton\n data-testid=\"pv-skeleton\"\n :height=\"mapSizeToPx[size]\"\n :width=\"variant === 'square' ? mapSizeToPx[size] : '100%'\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { Skeleton } from \"primevue\";\nimport { PvSekeltonSize, PvSkeletonVariant } from \"./types\";\n\nconst mapSizeToPx: Record<PvSekeltonSize, string> = {\n xs: \"0.75rem\",\n sm: \"1rem\",\n md: \"1.25rem\",\n lg: \"1.5rem\",\n xl: \"2rem\",\n};\n\ninterface PvSkeletonProps {\n /** The size of the skeleton placeholder. Controls height and, for square variant, width. */\n size?: PvSekeltonSize;\n /** The shape variant. \"rectangle\" fills available width; \"square\" uses equal height and width. */\n variant?: PvSkeletonVariant;\n}\n\nwithDefaults(defineProps<PvSkeletonProps>(), {\n size: \"md\",\n variant: \"rectangle\",\n});\n</script>\n\n<template>\n <Skeleton\n data-testid=\"pv-skeleton\"\n :height=\"mapSizeToPx[size]\"\n :width=\"variant === 'square' ? mapSizeToPx[size] : '100%'\"\n />\n</template>\n","<script setup lang=\"ts\">\nimport { PvInputType, PvInputVariant } from \"./types\";\ninterface PvInputProps {\n /** When true, applies invalid/error styling to the input and lower label. */\n error?: boolean;\n /** When true, the input is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** Placeholder text shown when the input is empty. */\n placeholder?: string;\n /**\n * The HTML input type.\n */\n type?: PvInputType;\n /** HTML id for the input element. Auto-generated when omitted. */\n id?: string;\n /** Helper or validation text displayed below the input. Turns red when error is true. */\n lowerLabel?: string;\n /**\n * Background color variant of the input field.\n */\n variant?: PvInputVariant;\n /** The step attribute for number inputs (e.g. '0.01' for currency). */\n step?: string;\n}\n\nwithDefaults(defineProps<PvInputProps>(), {\n id: Math.random().toString(),\n type: \"text\",\n variant: \"white\",\n});\n\nconst value = defineModel<string>();\n</script>\n\n<template>\n <label v-if=\"$slots.label\" data-testid=\"pv-input-label\" class=\"pv-label pv-stack-8\" :for=\"id\">\n <slot name=\"label\" />\n </label>\n <input\n v-model=\"value\"\n data-testid=\"pv-input\"\n :class=\"[\n 'pv-input-text',\n {\n 'pv-stack-8': lowerLabel,\n 'pv-surface-accent': variant === 'grey',\n },\n ]\"\n :disabled=\"disabled\"\n :type=\"type\"\n :placeholder=\"placeholder\"\n :id=\"id\"\n :data-invalid=\"error ? true : undefined\"\n :step=\"step\"\n />\n <p\n v-if=\"lowerLabel\"\n data-testid=\"pv-input-lower-label\"\n style=\"margin-left: 12px\"\n :class=\"[\n 'pv-text-body-xs',\n {\n 'pv-text-red': error,\n 'pv-text-subdued': !error,\n },\n ]\"\n >\n {{ lowerLabel }}\n </p>\n</template>\n","<script setup lang=\"ts\">\nimport { PvInputType, PvInputVariant } from \"./types\";\ninterface PvInputProps {\n /** When true, applies invalid/error styling to the input and lower label. */\n error?: boolean;\n /** When true, the input is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** Placeholder text shown when the input is empty. */\n placeholder?: string;\n /**\n * The HTML input type.\n */\n type?: PvInputType;\n /** HTML id for the input element. Auto-generated when omitted. */\n id?: string;\n /** Helper or validation text displayed below the input. Turns red when error is true. */\n lowerLabel?: string;\n /**\n * Background color variant of the input field.\n */\n variant?: PvInputVariant;\n /** The step attribute for number inputs (e.g. '0.01' for currency). */\n step?: string;\n}\n\nwithDefaults(defineProps<PvInputProps>(), {\n id: Math.random().toString(),\n type: \"text\",\n variant: \"white\",\n});\n\nconst value = defineModel<string>();\n</script>\n\n<template>\n <label v-if=\"$slots.label\" data-testid=\"pv-input-label\" class=\"pv-label pv-stack-8\" :for=\"id\">\n <slot name=\"label\" />\n </label>\n <input\n v-model=\"value\"\n data-testid=\"pv-input\"\n :class=\"[\n 'pv-input-text',\n {\n 'pv-stack-8': lowerLabel,\n 'pv-surface-accent': variant === 'grey',\n },\n ]\"\n :disabled=\"disabled\"\n :type=\"type\"\n :placeholder=\"placeholder\"\n :id=\"id\"\n :data-invalid=\"error ? true : undefined\"\n :step=\"step\"\n />\n <p\n v-if=\"lowerLabel\"\n data-testid=\"pv-input-lower-label\"\n style=\"margin-left: 12px\"\n :class=\"[\n 'pv-text-body-xs',\n {\n 'pv-text-red': error,\n 'pv-text-subdued': !error,\n },\n ]\"\n >\n {{ lowerLabel }}\n </p>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvRatingVariant, PvRatingSize } from \"./types\";\n\ninterface PvRatingProps {\n /** Display variant: \"dot\" or \"star\" style */\n variant?: PvRatingVariant;\n /** Rating value between 0 and 5 */\n value: number;\n /** Size of the rating display in pixels */\n size?: PvRatingSize;\n}\n\nconst props = withDefaults(defineProps<PvRatingProps>(), {\n variant: \"dot\",\n size: 20,\n});\n\nconst dataRating = computed(() => {\n return props.variant === \"dot\" ? \"dot\" : undefined;\n});\n</script>\n\n<template>\n <div\n class=\"pv-rating\"\n data-testid=\"pv-rating\"\n :style=\"{\n '--height': `${size}px`,\n }\"\n :data-rating=\"dataRating\"\n >\n <meter id=\"rating\" min=\"0\" max=\"5\" :value=\"value\">4.0 stars</meter>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvRatingVariant, PvRatingSize } from \"./types\";\n\ninterface PvRatingProps {\n /** Display variant: \"dot\" or \"star\" style */\n variant?: PvRatingVariant;\n /** Rating value between 0 and 5 */\n value: number;\n /** Size of the rating display in pixels */\n size?: PvRatingSize;\n}\n\nconst props = withDefaults(defineProps<PvRatingProps>(), {\n variant: \"dot\",\n size: 20,\n});\n\nconst dataRating = computed(() => {\n return props.variant === \"dot\" ? \"dot\" : undefined;\n});\n</script>\n\n<template>\n <div\n class=\"pv-rating\"\n data-testid=\"pv-rating\"\n :style=\"{\n '--height': `${size}px`,\n }\"\n :data-rating=\"dataRating\"\n >\n <meter id=\"rating\" min=\"0\" max=\"5\" :value=\"value\">4.0 stars</meter>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvCardVariant } from \"./types\";\n\ninterface PvCardProps {\n /** URL to navigate to when the card is clicked. Renders the card as an anchor element. */\n href?: string;\n /** Visual style variant of the card. */\n variant?: PvCardVariant;\n /** When true, renders the card as a button element with interactive styling. */\n interactive?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvCardProps>(), {\n variant: \"primary\",\n interactive: false,\n});\n\nconst componentVariant = computed(() => {\n return props.href ? \"a\" : props.interactive ? \"button\" : \"div\";\n});\n\nconst componentType = computed(() => {\n return props.href || props.interactive ? \"button\" : \"div\";\n});\n</script>\n\n<template>\n <component\n :is=\"componentVariant\"\n :href=\"href\"\n :type=\"componentType\"\n :class=\"[\n 'pv-card pv-inset-square-8 pv-inline-block',\n {\n 'pv-card-secondary': variant === 'secondary',\n },\n ]\"\n data-testid=\"pv-card\"\n >\n <slot />\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport { PvCardVariant } from \"./types\";\n\ninterface PvCardProps {\n /** URL to navigate to when the card is clicked. Renders the card as an anchor element. */\n href?: string;\n /** Visual style variant of the card. */\n variant?: PvCardVariant;\n /** When true, renders the card as a button element with interactive styling. */\n interactive?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvCardProps>(), {\n variant: \"primary\",\n interactive: false,\n});\n\nconst componentVariant = computed(() => {\n return props.href ? \"a\" : props.interactive ? \"button\" : \"div\";\n});\n\nconst componentType = computed(() => {\n return props.href || props.interactive ? \"button\" : \"div\";\n});\n</script>\n\n<template>\n <component\n :is=\"componentVariant\"\n :href=\"href\"\n :type=\"componentType\"\n :class=\"[\n 'pv-card pv-inset-square-8 pv-inline-block',\n {\n 'pv-card-secondary': variant === 'secondary',\n },\n ]\"\n data-testid=\"pv-card\"\n >\n <slot />\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport PvCard from \"../PvCard/PvCard.vue\";\n</script>\n\n<template>\n <PvCard class=\"pv-inset-square-16\">\n <slot />\n </PvCard>\n</template>\n","<script setup lang=\"ts\">\nimport PvCard from \"../PvCard/PvCard.vue\";\n</script>\n\n<template>\n <PvCard class=\"pv-inset-square-16\">\n <slot />\n </PvCard>\n</template>\n","<script setup lang=\"ts\">\nimport PvCard from \"../PvCard/PvCard.vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport { computed } from \"vue\";\n\nexport interface PvInsightCardProps {\n /** Name of the icon displayed beside the insight text. */\n icon: string;\n /** Short insight label displayed next to the icon. */\n insight: string;\n /** Optional label displayed above the title in a smaller, tertiary style. */\n upperLabel?: string;\n /** Main heading text of the insight card. */\n title?: string;\n /** Descriptive text displayed below the title. */\n description?: string;\n /** When true, shows a \"new-tab\" icon button in the top-right corner. */\n showButton?: boolean;\n /** When true, the card is rendered as an interactive (clickable) element. */\n interactive?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvInsightCardProps>(), {\n icon: \"ai\",\n showButton: false,\n interactive: false,\n});\n\ndefineEmits<{\n (e: \"click\"): void;\n (e: \"icon-click\"): void;\n}>();\n\nconst displayIconLevel = computed(() => {\n return props.icon || props.insight;\n});\n</script>\n\n<template>\n <PvCard variant=\"secondary\" :interactive=\"interactive\" @click=\"$emit('click')\" class=\"pv-relative\">\n <div class=\"pv-flex-vertical\" style=\"--flex-align: flex-start; --flex-gap: 0.25rem\">\n <div v-if=\"displayIconLevel\" class=\"pv-flex\" style=\"--flex-gap: 0.25rem\">\n <PvIcon v-if=\"icon\" style=\"color: #218c88\" :name=\"icon\" :size=\"12\" />\n <span class=\"pv-text-body-sm\">{{ insight }}</span>\n </div>\n <span v-if=\"upperLabel\" class=\"pv-text-body-sm pv-text-tertiary\">{{ upperLabel }}</span>\n <span v-if=\"title\" class=\"pv-heading-2\">{{ title }}</span>\n <span v-if=\"description\" class=\"pv-text-body-md pv-text-secondary pv-text-subdued\">{{ description }}</span>\n </div>\n <PvButton\n v-if=\"showButton\"\n left-icon=\"new-tab\"\n ariaLabel=\"Open in new tab\"\n variant=\"ghost\"\n size=\"md\"\n class=\"pv-insight-button\"\n @click.stop=\"$emit('icon-click')\"\n />\n </PvCard>\n</template>\n\n<style scoped>\n.pv-insight-button {\n position: absolute;\n top: 0.5rem;\n right: 0.5rem;\n}\n</style>\n","<script setup lang=\"ts\">\nimport PvCard from \"../PvCard/PvCard.vue\";\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport { computed } from \"vue\";\n\nexport interface PvInsightCardProps {\n /** Name of the icon displayed beside the insight text. */\n icon: string;\n /** Short insight label displayed next to the icon. */\n insight: string;\n /** Optional label displayed above the title in a smaller, tertiary style. */\n upperLabel?: string;\n /** Main heading text of the insight card. */\n title?: string;\n /** Descriptive text displayed below the title. */\n description?: string;\n /** When true, shows a \"new-tab\" icon button in the top-right corner. */\n showButton?: boolean;\n /** When true, the card is rendered as an interactive (clickable) element. */\n interactive?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvInsightCardProps>(), {\n icon: \"ai\",\n showButton: false,\n interactive: false,\n});\n\ndefineEmits<{\n (e: \"click\"): void;\n (e: \"icon-click\"): void;\n}>();\n\nconst displayIconLevel = computed(() => {\n return props.icon || props.insight;\n});\n</script>\n\n<template>\n <PvCard variant=\"secondary\" :interactive=\"interactive\" @click=\"$emit('click')\" class=\"pv-relative\">\n <div class=\"pv-flex-vertical\" style=\"--flex-align: flex-start; --flex-gap: 0.25rem\">\n <div v-if=\"displayIconLevel\" class=\"pv-flex\" style=\"--flex-gap: 0.25rem\">\n <PvIcon v-if=\"icon\" style=\"color: #218c88\" :name=\"icon\" :size=\"12\" />\n <span class=\"pv-text-body-sm\">{{ insight }}</span>\n </div>\n <span v-if=\"upperLabel\" class=\"pv-text-body-sm pv-text-tertiary\">{{ upperLabel }}</span>\n <span v-if=\"title\" class=\"pv-heading-2\">{{ title }}</span>\n <span v-if=\"description\" class=\"pv-text-body-md pv-text-secondary pv-text-subdued\">{{ description }}</span>\n </div>\n <PvButton\n v-if=\"showButton\"\n left-icon=\"new-tab\"\n ariaLabel=\"Open in new tab\"\n variant=\"ghost\"\n size=\"md\"\n class=\"pv-insight-button\"\n @click.stop=\"$emit('icon-click')\"\n />\n </PvCard>\n</template>\n\n<style scoped>\n.pv-insight-button {\n position: absolute;\n top: 0.5rem;\n right: 0.5rem;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { ref, computed } from \"vue\";\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport { PvExpandableContentSizes, PvExpandableContentVariants } from \"./types\";\n\nconst sizeMap: Record<PvExpandableContentSizes, string> = {\n none: \"0\",\n xs: \"4px\",\n sm: \"8px\",\n md: \"12px\",\n lg: \"16px\",\n};\n\nconst props = withDefaults(\n defineProps<{\n /** Maximum number of visible lines before content is clamped. */\n lines?: number;\n /** Padding size applied to the container. */\n size?: PvExpandableContentSizes;\n /** Visual style variant. \"ghost\" applies an accent surface background. */\n variant?: PvExpandableContentVariants;\n /** When true, the content starts in the expanded state. */\n defaultOpen?: boolean;\n }>(),\n {\n lines: 4,\n size: \"md\",\n variant: \"primary\",\n defaultOpen: false,\n },\n);\n\nconst isExpanded = ref(props.defaultOpen);\n\nconst toggleExpanded = () => {\n isExpanded.value = !isExpanded.value;\n};\n\nconst contentStyle = computed(() => {\n return {\n \"--lines\": isExpanded.value ? \"none\" : props.lines,\n \"max-height\": isExpanded.value ? \"100vh\" : `${props.lines * 1.5}em`,\n };\n});\n</script>\n\n<template>\n <div\n :class=\"[\n 'pv-inset-square expandable-content',\n {\n 'pv-surface-accent': variant === 'ghost',\n },\n ]\"\n :style=\"{ '--inset-size': sizeMap[size] }\"\n >\n <p class=\"pv-line-clamp pv-text-body-md pv-stack-8\" :style=\"contentStyle\">\n <slot />\n </p>\n <PvButton\n :label=\"isExpanded ? 'Show Less' : 'Show More'\"\n variant=\"ghost\"\n size=\"md\"\n @click=\"toggleExpanded\"\n :left-icon=\"isExpanded ? 'chevron-up' : 'chevron-down'\"\n />\n </div>\n</template>\n\n<style scoped>\n.expandable-content {\n border-radius: 0.5rem;\n}\n\n.expandable-content .pv-line-clamp {\n transition: max-height 0.3s ease-in-out;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { ref, computed } from \"vue\";\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport { PvExpandableContentSizes, PvExpandableContentVariants } from \"./types\";\n\nconst sizeMap: Record<PvExpandableContentSizes, string> = {\n none: \"0\",\n xs: \"4px\",\n sm: \"8px\",\n md: \"12px\",\n lg: \"16px\",\n};\n\nconst props = withDefaults(\n defineProps<{\n /** Maximum number of visible lines before content is clamped. */\n lines?: number;\n /** Padding size applied to the container. */\n size?: PvExpandableContentSizes;\n /** Visual style variant. \"ghost\" applies an accent surface background. */\n variant?: PvExpandableContentVariants;\n /** When true, the content starts in the expanded state. */\n defaultOpen?: boolean;\n }>(),\n {\n lines: 4,\n size: \"md\",\n variant: \"primary\",\n defaultOpen: false,\n },\n);\n\nconst isExpanded = ref(props.defaultOpen);\n\nconst toggleExpanded = () => {\n isExpanded.value = !isExpanded.value;\n};\n\nconst contentStyle = computed(() => {\n return {\n \"--lines\": isExpanded.value ? \"none\" : props.lines,\n \"max-height\": isExpanded.value ? \"100vh\" : `${props.lines * 1.5}em`,\n };\n});\n</script>\n\n<template>\n <div\n :class=\"[\n 'pv-inset-square expandable-content',\n {\n 'pv-surface-accent': variant === 'ghost',\n },\n ]\"\n :style=\"{ '--inset-size': sizeMap[size] }\"\n >\n <p class=\"pv-line-clamp pv-text-body-md pv-stack-8\" :style=\"contentStyle\">\n <slot />\n </p>\n <PvButton\n :label=\"isExpanded ? 'Show Less' : 'Show More'\"\n variant=\"ghost\"\n size=\"md\"\n @click=\"toggleExpanded\"\n :left-icon=\"isExpanded ? 'chevron-up' : 'chevron-down'\"\n />\n </div>\n</template>\n\n<style scoped>\n.expandable-content {\n border-radius: 0.5rem;\n}\n\n.expandable-content .pv-line-clamp {\n transition: max-height 0.3s ease-in-out;\n}\n</style>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport type { PvToastVariants } from \"./types\";\n\ninterface PvToastProps {\n /** Visual style variant determining color scheme and default icon */\n variant?: PvToastVariants;\n /** Custom icon name; overrides the default variant icon */\n icon?: string;\n /** Text message displayed in the toast */\n label: string;\n}\n\nconst mapVariantToClass: Record<PvToastVariants, string> = {\n info: \"pv-toast-info\",\n success: \"pv-toast-success\",\n error: \"pv-toast-error\",\n dark: \"pv-toast-dark\",\n};\n\nconst mapVariantToIcon: Record<PvToastVariants, string> = {\n info: \"check-circle\",\n success: \"check-circle\",\n error: \"alert-circle\",\n dark: \"ai\",\n};\n\nwithDefaults(defineProps<PvToastProps>(), {\n variant: \"info\",\n});\n\ndefineEmits<{\n (e: \"handle-close\"): void;\n}>();\n</script>\n\n<template>\n <div :class=\"mapVariantToClass[variant]\">\n <PvIcon :name=\"icon ? icon : mapVariantToIcon[variant]\" :size=\"20\" />\n <p class=\"pv-text-body-md\">\n {{ label }}\n </p>\n <slot />\n <PvButton\n variant=\"ghost\"\n :inverse=\"variant === 'dark'\"\n size=\"lg\"\n left-icon=\"close\"\n ariaLabel=\"Close\"\n @click=\"$emit('handle-close')\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport PvButton from \"../PvButton/PvButton.vue\";\nimport type { PvToastVariants } from \"./types\";\n\ninterface PvToastProps {\n /** Visual style variant determining color scheme and default icon */\n variant?: PvToastVariants;\n /** Custom icon name; overrides the default variant icon */\n icon?: string;\n /** Text message displayed in the toast */\n label: string;\n}\n\nconst mapVariantToClass: Record<PvToastVariants, string> = {\n info: \"pv-toast-info\",\n success: \"pv-toast-success\",\n error: \"pv-toast-error\",\n dark: \"pv-toast-dark\",\n};\n\nconst mapVariantToIcon: Record<PvToastVariants, string> = {\n info: \"check-circle\",\n success: \"check-circle\",\n error: \"alert-circle\",\n dark: \"ai\",\n};\n\nwithDefaults(defineProps<PvToastProps>(), {\n variant: \"info\",\n});\n\ndefineEmits<{\n (e: \"handle-close\"): void;\n}>();\n</script>\n\n<template>\n <div :class=\"mapVariantToClass[variant]\">\n <PvIcon :name=\"icon ? icon : mapVariantToIcon[variant]\" :size=\"20\" />\n <p class=\"pv-text-body-md\">\n {{ label }}\n </p>\n <slot />\n <PvButton\n variant=\"ghost\"\n :inverse=\"variant === 'dark'\"\n size=\"lg\"\n left-icon=\"close\"\n ariaLabel=\"Close\"\n @click=\"$emit('handle-close')\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { PvActionBarTheme } from \"./types\";\n\ninterface PvActionBarProps {\n /** Visual theme of the action bar. Use \"dark\" on light backgrounds for contrast.\n * When using \"dark\", set the `inverse` prop on child components that support it. */\n variant?: PvActionBarTheme;\n}\n\nwithDefaults(defineProps<PvActionBarProps>(), {\n variant: \"white\",\n});\n\ndefineSlots<{\n /**\n * Default slot for action bar content.\n * sections are divided by the root elements inside the slot.\n */\n default(): never;\n}>();\n</script>\n\n<template>\n <div class=\"pv-action-bar-container\" :data-style=\"variant === 'white' ? 'white' : undefined\">\n <slot name=\"default\" />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { PvActionBarTheme } from \"./types\";\n\ninterface PvActionBarProps {\n /** Visual theme of the action bar. Use \"dark\" on light backgrounds for contrast.\n * When using \"dark\", set the `inverse` prop on child components that support it. */\n variant?: PvActionBarTheme;\n}\n\nwithDefaults(defineProps<PvActionBarProps>(), {\n variant: \"white\",\n});\n\ndefineSlots<{\n /**\n * Default slot for action bar content.\n * sections are divided by the root elements inside the slot.\n */\n default(): never;\n}>();\n</script>\n\n<template>\n <div class=\"pv-action-bar-container\" :data-style=\"variant === 'white' ? 'white' : undefined\">\n <slot name=\"default\" />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { PvTextAreaVariant } from \"./types\";\n\ninterface PvTextareaProps {\n /** When true, applies invalid/error styling to the textarea and lower label. */\n error?: boolean;\n /** When true, the textarea is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** Placeholder text shown when the textarea is empty. */\n placeholder?: string;\n /** HTML id for the textarea element. Auto-generated when omitted. */\n id?: string;\n /** Helper or validation text displayed below the textarea. Turns red when error is true. */\n lowerLabel?: string;\n /**\n * Background color variant of the textarea.\n */\n variant?: PvTextAreaVariant;\n /**\n * Number of visible text rows.\n */\n rows?: number;\n}\n\nwithDefaults(defineProps<PvTextareaProps>(), {\n id: Math.random().toString(),\n variant: \"white\",\n rows: 4,\n});\n\nconst value = defineModel<string>();\n</script>\n\n<template>\n <label v-if=\"$slots.label\" class=\"pv-label pv-stack-8\" :for=\"id\">\n <slot name=\"label\" />\n </label>\n <textarea\n v-bind=\"$attrs\"\n v-model=\"value\"\n :class=\"[\n 'pv-textarea',\n {\n 'pv-stack-8': lowerLabel,\n 'pv-surface-accent': variant === 'grey',\n },\n ]\"\n :rows=\"rows\"\n :disabled=\"disabled\"\n :placeholder=\"placeholder\"\n :id=\"id\"\n :data-invalid=\"error ? true : undefined\"\n />\n <p\n v-if=\"lowerLabel\"\n style=\"margin-left: 12px\"\n :class=\"[\n 'pv-text-body-xs',\n {\n 'pv-text-red': error,\n 'pv-text-subdued': !error,\n },\n ]\"\n >\n {{ lowerLabel }}\n </p>\n</template>\n","<script setup lang=\"ts\">\nimport { PvTextAreaVariant } from \"./types\";\n\ninterface PvTextareaProps {\n /** When true, applies invalid/error styling to the textarea and lower label. */\n error?: boolean;\n /** When true, the textarea is non-interactive and visually dimmed. */\n disabled?: boolean;\n /** Placeholder text shown when the textarea is empty. */\n placeholder?: string;\n /** HTML id for the textarea element. Auto-generated when omitted. */\n id?: string;\n /** Helper or validation text displayed below the textarea. Turns red when error is true. */\n lowerLabel?: string;\n /**\n * Background color variant of the textarea.\n */\n variant?: PvTextAreaVariant;\n /**\n * Number of visible text rows.\n */\n rows?: number;\n}\n\nwithDefaults(defineProps<PvTextareaProps>(), {\n id: Math.random().toString(),\n variant: \"white\",\n rows: 4,\n});\n\nconst value = defineModel<string>();\n</script>\n\n<template>\n <label v-if=\"$slots.label\" class=\"pv-label pv-stack-8\" :for=\"id\">\n <slot name=\"label\" />\n </label>\n <textarea\n v-bind=\"$attrs\"\n v-model=\"value\"\n :class=\"[\n 'pv-textarea',\n {\n 'pv-stack-8': lowerLabel,\n 'pv-surface-accent': variant === 'grey',\n },\n ]\"\n :rows=\"rows\"\n :disabled=\"disabled\"\n :placeholder=\"placeholder\"\n :id=\"id\"\n :data-invalid=\"error ? true : undefined\"\n />\n <p\n v-if=\"lowerLabel\"\n style=\"margin-left: 12px\"\n :class=\"[\n 'pv-text-body-xs',\n {\n 'pv-text-red': error,\n 'pv-text-subdued': !error,\n },\n ]\"\n >\n {{ lowerLabel }}\n </p>\n</template>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\n\ninterface PvSimpleItemTreeProps {\n label: string;\n icon?: string;\n}\n\ndefineProps<PvSimpleItemTreeProps>();\n</script>\n\n<template>\n <div class=\"pv-flex pv-truncate\" style=\"min-width: 0; min-height: 20px\">\n <PvIcon v-if=\"icon\" :name=\"icon\" />\n <span class=\"pv-text-body-md pv-truncate\" style=\"font-weight: 500; min-width: 0\" :title=\"label\">{{ label }}</span>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\n\ninterface PvSimpleItemTreeProps {\n label: string;\n icon?: string;\n}\n\ndefineProps<PvSimpleItemTreeProps>();\n</script>\n\n<template>\n <div class=\"pv-flex pv-truncate\" style=\"min-width: 0; min-height: 20px\">\n <PvIcon v-if=\"icon\" :name=\"icon\" />\n <span class=\"pv-text-body-md pv-truncate\" style=\"font-weight: 500; min-width: 0\" :title=\"label\">{{ label }}</span>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\n</script>\n\n<template>\n <PvIcon name=\"reorder\" class=\"reorder-icon pv-text-tertiary\" />\n</template>\n\n<style scoped>\n.reorder-icon {\n position: absolute;\n left: 0;\n top: 0;\n transform: translateY(25%);\n width: 16px;\n height: 16px;\n min-width: 16px;\n min-height: 16px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\n</script>\n\n<template>\n <PvIcon name=\"reorder\" class=\"reorder-icon pv-text-tertiary\" />\n</template>\n\n<style scoped>\n.reorder-icon {\n position: absolute;\n left: 0;\n top: 0;\n transform: translateY(25%);\n width: 16px;\n height: 16px;\n min-width: 16px;\n min-height: 16px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport type { PvTreeOption } from \"./types\";\n\ninterface PvButtonTreeItemProps {\n selected?: boolean;\n option: PvTreeOption;\n disableSelection?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvButtonTreeItemProps>(), {\n disableSelection: false,\n});\n\nconst emit = defineEmits<{\n (e: \"handle-selected\", payload: { option: PvTreeOption; event: MouseEvent }): void;\n}>();\n\nconst handleTreeSelect = (event: MouseEvent) => {\n if (props.disableSelection) return;\n emit(\"handle-selected\", { option: props.option, event });\n};\n\nconst componentInstance = computed(() => {\n return props.disableSelection ? \"button\" : \"div\";\n});\n</script>\n\n<template>\n <component\n :is=\"componentInstance\"\n :class=\"[\n 'pv-full-width',\n 'pv-flex',\n 'pv-relative',\n 'pv-tree-item',\n { 'pv-tree-item-selected': selected, 'pv-tree-item-disabled': disableSelection },\n ]\"\n @click=\"handleTreeSelect\"\n >\n <slot />\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\nimport type { PvTreeOption } from \"./types\";\n\ninterface PvButtonTreeItemProps {\n selected?: boolean;\n option: PvTreeOption;\n disableSelection?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvButtonTreeItemProps>(), {\n disableSelection: false,\n});\n\nconst emit = defineEmits<{\n (e: \"handle-selected\", payload: { option: PvTreeOption; event: MouseEvent }): void;\n}>();\n\nconst handleTreeSelect = (event: MouseEvent) => {\n if (props.disableSelection) return;\n emit(\"handle-selected\", { option: props.option, event });\n};\n\nconst componentInstance = computed(() => {\n return props.disableSelection ? \"button\" : \"div\";\n});\n</script>\n\n<template>\n <component\n :is=\"componentInstance\"\n :class=\"[\n 'pv-full-width',\n 'pv-flex',\n 'pv-relative',\n 'pv-tree-item',\n { 'pv-tree-item-selected': selected, 'pv-tree-item-disabled': disableSelection },\n ]\"\n @click=\"handleTreeSelect\"\n >\n <slot />\n </component>\n</template>\n","<script setup lang=\"ts\">\nimport PvCheckbox from \"../PvCheckbox/PvCheckbox.vue\";\nimport type { PvTreeOption } from \"./types\";\n\ninterface PvCheckboxTreeItemProps {\n selected?: boolean;\n option: PvTreeOption;\n disableSelection?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvCheckboxTreeItemProps>(), {\n disableSelection: false,\n});\n\nconst emit = defineEmits<{\n (e: \"handle-selected\", payload: { option: PvTreeOption; event: MouseEvent }): void;\n}>();\n\nconst handleSelected = (event: MouseEvent) => {\n if (props.disableSelection) return;\n emit(\"handle-selected\", { option: props.option, event });\n};\n</script>\n\n<template>\n <label\n :class=\"[\n 'pv-relative',\n 'pv-label',\n 'pv-label-hover',\n 'pv-flex',\n 'pv-tree-item',\n 'pv-full-width',\n { 'pv-tree-item-selected': selected, 'pv-tree-item-disabled': disableSelection },\n ]\"\n >\n <PvCheckbox v-if=\"!disableSelection\" :checked=\"selected\" @click=\"handleSelected\" />\n <slot />\n </label>\n</template>\n","<script setup lang=\"ts\">\nimport PvCheckbox from \"../PvCheckbox/PvCheckbox.vue\";\nimport type { PvTreeOption } from \"./types\";\n\ninterface PvCheckboxTreeItemProps {\n selected?: boolean;\n option: PvTreeOption;\n disableSelection?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvCheckboxTreeItemProps>(), {\n disableSelection: false,\n});\n\nconst emit = defineEmits<{\n (e: \"handle-selected\", payload: { option: PvTreeOption; event: MouseEvent }): void;\n}>();\n\nconst handleSelected = (event: MouseEvent) => {\n if (props.disableSelection) return;\n emit(\"handle-selected\", { option: props.option, event });\n};\n</script>\n\n<template>\n <label\n :class=\"[\n 'pv-relative',\n 'pv-label',\n 'pv-label-hover',\n 'pv-flex',\n 'pv-tree-item',\n 'pv-full-width',\n { 'pv-tree-item-selected': selected, 'pv-tree-item-disabled': disableSelection },\n ]\"\n >\n <PvCheckbox v-if=\"!disableSelection\" :checked=\"selected\" @click=\"handleSelected\" />\n <slot />\n </label>\n</template>\n","import { ref } from \"vue\";\n\nexport const useHoverIcon = () => {\n const hoveredId = ref<number | string | null>(null);\n\n const handleMouseEnter = (id: number | string) => {\n hoveredId.value = id;\n };\n\n const handleMouseLeave = () => {\n hoveredId.value = null;\n };\n\n return {\n hoveredId,\n handleMouseEnter,\n handleMouseLeave,\n };\n};\n","import { InjectionKey, Ref } from \"vue\";\n\nexport type DraggingState = Ref<boolean>;\nexport const DraggingStateKey: InjectionKey<DraggingState> = Symbol(\"DraggingStateKey\");\n\nexport type DraggingGroupName = Ref<string | null>;\nexport const DraggingGroupNameKey: InjectionKey<DraggingGroupName> = Symbol(\"DraggingGroupNameKey\");\n\nexport type DropIndicatorType = {\n parentId?: string | number;\n siblingTargetId?: string | number;\n siblingInsertAfter?: boolean;\n};\nexport type DropIndicator = Ref<DropIndicatorType | null>;\nexport const DropIndicatorKey: InjectionKey<DropIndicator> = Symbol(\"DropIndicatorKey\");\n","import { ref, provide, inject } from \"vue\";\nimport { DraggingStateKey, DraggingGroupNameKey, DropIndicatorKey, DropIndicatorType } from \"../symbols\";\n\n/**\n * Provides dragging state to the tree component hierarchy.\n * Called by PvTreeGroup (for cross-tree sharing) or by PvTree itself as a fallback (standalone use).\n */\nexport const provideDraggingState = () => {\n const isDragging = ref(false);\n const draggingGroupName = ref<string | null>(null);\n const dropIndicator = ref<DropIndicatorType | null>(null);\n\n provide(DraggingStateKey, isDragging);\n provide(DraggingGroupNameKey, draggingGroupName);\n provide(DropIndicatorKey, dropIndicator);\n\n return {\n isDragging,\n draggingGroupName,\n dropIndicator,\n };\n};\n\n/**\n * Injects dragging state from the nearest PvTreeGroup or PvTree ancestor.\n * Should be called in PvTreeItem and PvSimpleNestedTree components.\n */\nexport const useDraggingState = () => {\n const isDragging = inject(DraggingStateKey, ref(false));\n const draggingGroupName = inject(DraggingGroupNameKey, ref<string | null>(null));\n const dropIndicator = inject(DropIndicatorKey, ref<DropIndicatorType | null>(null));\n\n const onDragStart = (groupName?: string) => {\n isDragging.value = true;\n draggingGroupName.value = groupName ?? null;\n };\n\n const onDragEnd = () => {\n isDragging.value = false;\n draggingGroupName.value = null;\n clearDropIndicator();\n };\n\n const setDropIndicator = ({ parentId, siblingTargetId, siblingInsertAfter }: DropIndicatorType) => {\n dropIndicator.value = { parentId, siblingTargetId, siblingInsertAfter };\n };\n\n const clearDropIndicator = () => {\n dropIndicator.value = null;\n };\n\n return {\n isDragging,\n draggingGroupName,\n dropIndicator,\n setDropIndicator,\n clearDropIndicator,\n onDragStart,\n onDragEnd,\n };\n};\n","import { PvTreeOption, PvTreeSettings } from \"../types\";\nimport { useDraggingState } from \"./useDraggingState\";\n\nexport const useDragAndDrop = () => {\n const { setDropIndicator, clearDropIndicator } = useDraggingState();\n const getDragGroupConfig = (settings: PvTreeSettings, option: PvTreeOption) => {\n const fieldSetting = settings[option.field];\n const dragGroup = fieldSetting?.dragAndDropConfig;\n\n return {\n // Use a single shared group name by default to allow drag between all tree levels\n name: dragGroup?.name ?? \"pv-tree\",\n pull: dragGroup?.pull ?? true,\n put: dragGroup?.put ?? true,\n };\n };\n\n const getDragAndDropDisabled = (isDraggable: boolean | undefined, settings: PvTreeSettings, option: PvTreeOption) => {\n return !isDraggable || settings[option.field]?.dragAndDropConfig?.disableChildrenDrag;\n };\n\n /**\n * Returns true if an item can be dragged (for showing the reorder icon).\n * Checks: isDraggable is true, disabled is not set, and preventDrag is not set.\n */\n const canItemBeDragged = (isDraggable: boolean | undefined, settings: PvTreeSettings, option: PvTreeOption) => {\n const config = settings[option.field]?.dragAndDropConfig;\n return isDraggable && !config?.disableChildrenDrag && !config?.disableDrag;\n };\n\n /**\n * Vuedraggable move callback to prevent specific items from being dragged.\n * Returns false to cancel the drag, true to allow it.\n */\n const handleMoveCallback = (settings: PvTreeSettings) => {\n return (evt: {\n to: HTMLElement;\n draggedContext: { element: PvTreeOption; futureIndex: number };\n relatedContext: { element: PvTreeOption };\n willInsertAfter: boolean;\n }) => {\n const draggedOption = evt.draggedContext.element;\n const fieldSetting = settings[draggedOption.field];\n\n const toParentId =\n (evt.to as HTMLElement)?.closest?.(\"[data-parent-id]\")?.getAttribute(\"data-parent-id\") ?? undefined;\n\n if (toParentId != null) {\n const hasRelated = evt.relatedContext?.element?.node_id != null;\n const isInsertAsFirstChild = evt.draggedContext.futureIndex === 0;\n\n setDropIndicator({\n parentId: toParentId,\n ...(hasRelated && !isInsertAsFirstChild\n ? {\n siblingTargetId: evt.relatedContext.element.node_id,\n siblingInsertAfter: evt.willInsertAfter,\n }\n : {}),\n });\n } else {\n clearDropIndicator();\n }\n\n if (fieldSetting?.dragAndDropConfig?.disableDrag) {\n return false;\n }\n return true;\n };\n };\n\n const childrenDraggable = (isDraggable: boolean | undefined, settings: PvTreeSettings, option: PvTreeOption) => {\n return isDraggable && !settings[option.field]?.dragAndDropConfig?.disableChildrenDrag;\n };\n\n /**\n * Returns true if the drop zone should be shown for this option.\n * Checks `put` configuration against the dragging group name.\n *\n * @param settings - Tree settings\n * @param option - The option where we want to drop\n * @param draggingGroupName - The group name of the element being dragged (null if not dragging)\n *\n * Logic:\n * - put: false → never accept drops\n * - put: true → accept from any group\n * - put: ['group1', 'group2'] → accept only from specified groups\n * - put: undefined → accept only from same group (by name)\n */\n const canAcceptDrop = (settings: PvTreeSettings, option: PvTreeOption, draggingGroupName: string | null) => {\n const config = settings[option.field]?.dragAndDropConfig;\n const put = config?.put;\n\n // If put is explicitly false, never accept drops\n if (put === false) {\n return false;\n }\n\n // If put is explicitly true, accept from any group\n if (put === true) {\n return true;\n }\n\n // If not dragging yet, allow (will be filtered by isDragging anyway)\n if (!draggingGroupName) {\n return true;\n }\n\n // If put is an array, check if dragging group is in the allowed list\n if (Array.isArray(put)) {\n return put.includes(draggingGroupName);\n }\n\n // Default: accept only from same group (by name)\n const targetGroupName = config?.name ?? \"pv-tree\";\n return targetGroupName === draggingGroupName;\n };\n\n return {\n getDragGroupConfig,\n getDragAndDropDisabled,\n canItemBeDragged,\n handleMoveCallback,\n childrenDraggable,\n canAcceptDrop,\n };\n};\n","import { useDraggingState } from \"./useDraggingState\";\nimport type { PvTreeOption } from \"../types\";\n\nexport const useDragAndDropIndicator = () => {\n const { dropIndicator } = useDraggingState();\n\n const dragAndDropIndicatorClasses = (option: PvTreeOption) => {\n const indicator = dropIndicator.value;\n const hasSiblingTarget = indicator?.siblingTargetId !== undefined && indicator?.siblingTargetId !== null;\n const isSiblingTarget = hasSiblingTarget && indicator?.siblingTargetId === option.node_id;\n\n return {\n \"pv-drop-indicator-bottom\": Boolean(isSiblingTarget && indicator?.siblingInsertAfter),\n \"pv-drop-indicator-top\": Boolean(isSiblingTarget && indicator?.siblingInsertAfter === false),\n \"pv-drop-indicator-parent\": Boolean(indicator?.parentId === option.node_id),\n };\n };\n\n return {\n dragAndDropIndicatorClasses,\n };\n};\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport draggable from \"vuedraggable\";\nimport PvTreeReorderIcon from \"./PvTreeReorderIcon.vue\";\nimport PvButtonTreeItem from \"./PvButtonTreeItem.vue\";\nimport PvCheckboxTreeItem from \"./PvCheckboxTreeItem.vue\";\nimport PvSimpleItemTree from \"./PvSimpleItemTree.vue\";\nimport type { PvTreeOption, PvTreeSettings } from \"./types\";\n\nimport { useHoverIcon } from \"./composables/useHoverIcon\";\nimport { useDragAndDrop } from \"./composables/useDragAndDrop\";\nimport { useDraggingState } from \"./composables/useDraggingState\";\nimport { useDragAndDropIndicator } from \"./composables/useDragAndDropIndicator\";\n\ninterface PvSimpleNestedTreeItemProps {\n option: PvTreeOption;\n settings: PvTreeSettings;\n level: number;\n index: number;\n totalSiblings: number;\n parentField: string;\n selectedOptions?: PvTreeOption[];\n isDraggable?: boolean;\n isParentPathOpen?: boolean;\n isLastItem?: boolean;\n disableSelection?: boolean;\n}\n\nconst props = defineProps<PvSimpleNestedTreeItemProps>();\n\nconst emit = defineEmits<{\n (e: \"handle-tree-select\", payload: { option: PvTreeOption; event: MouseEvent }): void;\n (e: \"update:children\", payload: { optionId: PvTreeOption[\"node_id\"]; newChildren: PvTreeOption[] }): void;\n}>();\n\nconst { isDragging, draggingGroupName, onDragStart, onDragEnd } = useDraggingState();\nconst { dragAndDropIndicatorClasses } = useDragAndDropIndicator();\nconst { hoveredId, handleMouseEnter, handleMouseLeave } = useHoverIcon();\nconst { canItemBeDragged, getDragAndDropDisabled, handleMoveCallback, getDragGroupConfig, canAcceptDrop } =\n useDragAndDrop();\n\nconst handleDragStart = () => {\n const groupConfig = getDragGroupConfig(props.settings, props.option);\n onDragStart(groupConfig.name);\n};\n\nconst isSelected = (id?: string | number) => {\n return props.selectedOptions && props.selectedOptions.some((opt) => opt.node_id === id);\n};\n\nconst componentInstance = computed(() => {\n return props.settings[props.option.field]?.checkbox ? PvCheckboxTreeItem : PvButtonTreeItem;\n});\n\nconst showNestedTree = computed(() => {\n return props.settings[props.parentField]?.showNestedTree;\n});\n\nconst isLastItem = computed(() => {\n return props.index === props.totalSiblings - 1;\n});\n\n// Writable computed for vuedraggable v-model binding\nconst children = computed({\n get: () => [...(props.option.children || [])],\n set: (value) => {\n emit(\"update:children\", { optionId: props.option.node_id, newChildren: value });\n },\n});\n\nconst isVisible = computed(() => props.isParentPathOpen ?? true);\n</script>\n\n<template>\n <div\n :class=\"{ 'tree-item-continued': showNestedTree && !isLastItem }\"\n :style=\"showNestedTree && !isLastItem ? { '--tree-connector-left': `${level * 24 + 8}px` } : {}\"\n >\n <component\n :is=\"componentInstance\"\n :class=\"{\n ...dragAndDropIndicatorClasses(option),\n }\"\n :option=\"option\"\n :selected=\"isSelected(option.node_id)\"\n :disable-selection=\"disableSelection\"\n :label=\"option.label\"\n :icon=\"settings[option.field]?.icon\"\n :style=\"{\n paddingLeft: `${level * 24}px`,\n ...(settings[option.field]?.rendererParams?.onProvideCssStyles?.(option, { isVisible }) ?? {}),\n }\"\n @handle-selected=\"$emit('handle-tree-select', $event)\"\n @mouseenter=\"handleMouseEnter(option.node_id)\"\n @mouseleave=\"handleMouseLeave()\"\n @contextmenu.stop=\"settings[option.field]?.rendererParams?.onContextMenu?.($event, option)\"\n >\n <PvTreeReorderIcon v-show=\"hoveredId === option.node_id && canItemBeDragged(isDraggable, settings, option)\" />\n <div class=\"pv-flex pv-full-width\">\n <div v-if=\"!isLastItem && showNestedTree\" class=\"tree-component-nested-middle-symbol\" />\n <div v-else-if=\"showNestedTree\" class=\"tree-component-end-symbol\" />\n <component\n v-if=\"settings[option.field]?.renderer\"\n :is=\"settings[option.field]?.renderer\"\n :option=\"option\"\n :settings=\"settings\"\n :is-draggable=\"isDraggable\"\n :params=\"settings[option.field]?.rendererParams\"\n />\n <PvSimpleItemTree v-else :label=\"option.label\" :icon=\"settings[option.field]?.icon\" />\n </div>\n </component>\n\n <!-- Drop zone for children -->\n <div :data-parent-id=\"option.node_id\">\n <draggable\n v-model=\"children\"\n :parent-id=\"option.node_id\"\n :group=\"getDragGroupConfig(settings, option)\"\n item-key=\"node_id\"\n :disabled=\"getDragAndDropDisabled(isDraggable, settings, option)\"\n :move=\"handleMoveCallback(settings)\"\n :class=\"{\n 'pv-tree-drop-zone':\n isDragging && children.length === 0 && canAcceptDrop(settings, option, draggingGroupName),\n }\"\n @start=\"handleDragStart\"\n @end=\"onDragEnd\"\n @add=\"onDragEnd\"\n >\n <template #item=\"{ element, index: childIndex }\">\n <PvSimpleNestedTreeItem\n :is-parent-path-open=\"isParentPathOpen\"\n :option=\"element\"\n :settings=\"settings\"\n :level=\"level + 1\"\n :index=\"childIndex\"\n :total-siblings=\"children.length\"\n :parent-field=\"option.field\"\n :selected-options=\"selectedOptions\"\n :is-draggable=\"isDraggable\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"$emit('handle-tree-select', $event)\"\n @update:children=\"$emit('update:children', $event)\"\n />\n </template>\n </draggable>\n </div>\n </div>\n</template>\n\n<style scoped>\n.pv-tree-drop-zone {\n min-height: 0px;\n}\n\n/* Continuation line when this item is not last sibling (runs through nested children) */\n.tree-item-continued {\n position: relative;\n}\n\n.tree-item-continued::before {\n content: \"\";\n position: absolute;\n left: calc(var(--tree-connector-left, 8px) + 1px);\n top: 0;\n bottom: 0;\n width: 1px;\n background: var(--tree-connector-color, #d2d8dc);\n transform: translateX(-50%);\n z-index: 1;\n pointer-events: none;\n}\n\n/* When continuation line is drawn, hide the middle symbol's vertical so we don't double the line */\n.tree-item-continued .tree-component-nested-middle-symbol::before {\n display: none;\n}\n\n/* End symbol box */\n.tree-component-end-symbol {\n width: 16px;\n height: 16px;\n min-width: 16px;\n position: relative;\n}\n\n.tree-component-end-symbol::before,\n.tree-component-end-symbol::after {\n content: \"\";\n position: absolute;\n background: var(--tree-connector-color, #d2d8dc);\n}\n\n.tree-component-end-symbol::before {\n width: 1px;\n height: 14px;\n top: -6px;\n left: 8px;\n transform: translateX(-50%);\n}\n\n.tree-component-end-symbol::after {\n height: 1px;\n width: 8px;\n top: 8px;\n left: 8px;\n}\n\n/* Middle Tree Symbol */\n\n.tree-component-middle-symbol {\n width: 16px;\n height: 16px;\n min-width: 16px;\n position: relative;\n}\n\n.tree-component-middle-symbol::before {\n content: \"\";\n position: absolute;\n background: var(--tree-connector-color, #d2d8dc);\n left: 50%;\n width: 1px;\n height: 28px;\n top: -4px;\n transform: translateX(-50%);\n}\n\n/* Middle Nested Tree symbol box */\n.tree-component-nested-middle-symbol {\n width: 16px;\n height: 16px;\n min-width: 16px;\n position: relative;\n}\n\n.tree-component-nested-middle-symbol::before,\n.tree-component-nested-middle-symbol::after {\n content: \"\";\n position: absolute;\n background: var(--tree-connector-color, #d2d8dc);\n left: 50%;\n}\n\n.tree-component-nested-middle-symbol::before {\n width: 1px;\n height: 28px;\n top: -4px;\n transform: translateX(-50%);\n}\n\n.tree-component-nested-middle-symbol::after {\n height: 1px;\n width: 8px;\n top: 50%;\n transform: translateY(-50%);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport draggable from \"vuedraggable\";\nimport PvTreeReorderIcon from \"./PvTreeReorderIcon.vue\";\nimport PvButtonTreeItem from \"./PvButtonTreeItem.vue\";\nimport PvCheckboxTreeItem from \"./PvCheckboxTreeItem.vue\";\nimport PvSimpleItemTree from \"./PvSimpleItemTree.vue\";\nimport type { PvTreeOption, PvTreeSettings } from \"./types\";\n\nimport { useHoverIcon } from \"./composables/useHoverIcon\";\nimport { useDragAndDrop } from \"./composables/useDragAndDrop\";\nimport { useDraggingState } from \"./composables/useDraggingState\";\nimport { useDragAndDropIndicator } from \"./composables/useDragAndDropIndicator\";\n\ninterface PvSimpleNestedTreeItemProps {\n option: PvTreeOption;\n settings: PvTreeSettings;\n level: number;\n index: number;\n totalSiblings: number;\n parentField: string;\n selectedOptions?: PvTreeOption[];\n isDraggable?: boolean;\n isParentPathOpen?: boolean;\n isLastItem?: boolean;\n disableSelection?: boolean;\n}\n\nconst props = defineProps<PvSimpleNestedTreeItemProps>();\n\nconst emit = defineEmits<{\n (e: \"handle-tree-select\", payload: { option: PvTreeOption; event: MouseEvent }): void;\n (e: \"update:children\", payload: { optionId: PvTreeOption[\"node_id\"]; newChildren: PvTreeOption[] }): void;\n}>();\n\nconst { isDragging, draggingGroupName, onDragStart, onDragEnd } = useDraggingState();\nconst { dragAndDropIndicatorClasses } = useDragAndDropIndicator();\nconst { hoveredId, handleMouseEnter, handleMouseLeave } = useHoverIcon();\nconst { canItemBeDragged, getDragAndDropDisabled, handleMoveCallback, getDragGroupConfig, canAcceptDrop } =\n useDragAndDrop();\n\nconst handleDragStart = () => {\n const groupConfig = getDragGroupConfig(props.settings, props.option);\n onDragStart(groupConfig.name);\n};\n\nconst isSelected = (id?: string | number) => {\n return props.selectedOptions && props.selectedOptions.some((opt) => opt.node_id === id);\n};\n\nconst componentInstance = computed(() => {\n return props.settings[props.option.field]?.checkbox ? PvCheckboxTreeItem : PvButtonTreeItem;\n});\n\nconst showNestedTree = computed(() => {\n return props.settings[props.parentField]?.showNestedTree;\n});\n\nconst isLastItem = computed(() => {\n return props.index === props.totalSiblings - 1;\n});\n\n// Writable computed for vuedraggable v-model binding\nconst children = computed({\n get: () => [...(props.option.children || [])],\n set: (value) => {\n emit(\"update:children\", { optionId: props.option.node_id, newChildren: value });\n },\n});\n\nconst isVisible = computed(() => props.isParentPathOpen ?? true);\n</script>\n\n<template>\n <div\n :class=\"{ 'tree-item-continued': showNestedTree && !isLastItem }\"\n :style=\"showNestedTree && !isLastItem ? { '--tree-connector-left': `${level * 24 + 8}px` } : {}\"\n >\n <component\n :is=\"componentInstance\"\n :class=\"{\n ...dragAndDropIndicatorClasses(option),\n }\"\n :option=\"option\"\n :selected=\"isSelected(option.node_id)\"\n :disable-selection=\"disableSelection\"\n :label=\"option.label\"\n :icon=\"settings[option.field]?.icon\"\n :style=\"{\n paddingLeft: `${level * 24}px`,\n ...(settings[option.field]?.rendererParams?.onProvideCssStyles?.(option, { isVisible }) ?? {}),\n }\"\n @handle-selected=\"$emit('handle-tree-select', $event)\"\n @mouseenter=\"handleMouseEnter(option.node_id)\"\n @mouseleave=\"handleMouseLeave()\"\n @contextmenu.stop=\"settings[option.field]?.rendererParams?.onContextMenu?.($event, option)\"\n >\n <PvTreeReorderIcon v-show=\"hoveredId === option.node_id && canItemBeDragged(isDraggable, settings, option)\" />\n <div class=\"pv-flex pv-full-width\">\n <div v-if=\"!isLastItem && showNestedTree\" class=\"tree-component-nested-middle-symbol\" />\n <div v-else-if=\"showNestedTree\" class=\"tree-component-end-symbol\" />\n <component\n v-if=\"settings[option.field]?.renderer\"\n :is=\"settings[option.field]?.renderer\"\n :option=\"option\"\n :settings=\"settings\"\n :is-draggable=\"isDraggable\"\n :params=\"settings[option.field]?.rendererParams\"\n />\n <PvSimpleItemTree v-else :label=\"option.label\" :icon=\"settings[option.field]?.icon\" />\n </div>\n </component>\n\n <!-- Drop zone for children -->\n <div :data-parent-id=\"option.node_id\">\n <draggable\n v-model=\"children\"\n :parent-id=\"option.node_id\"\n :group=\"getDragGroupConfig(settings, option)\"\n item-key=\"node_id\"\n :disabled=\"getDragAndDropDisabled(isDraggable, settings, option)\"\n :move=\"handleMoveCallback(settings)\"\n :class=\"{\n 'pv-tree-drop-zone':\n isDragging && children.length === 0 && canAcceptDrop(settings, option, draggingGroupName),\n }\"\n @start=\"handleDragStart\"\n @end=\"onDragEnd\"\n @add=\"onDragEnd\"\n >\n <template #item=\"{ element, index: childIndex }\">\n <PvSimpleNestedTreeItem\n :is-parent-path-open=\"isParentPathOpen\"\n :option=\"element\"\n :settings=\"settings\"\n :level=\"level + 1\"\n :index=\"childIndex\"\n :total-siblings=\"children.length\"\n :parent-field=\"option.field\"\n :selected-options=\"selectedOptions\"\n :is-draggable=\"isDraggable\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"$emit('handle-tree-select', $event)\"\n @update:children=\"$emit('update:children', $event)\"\n />\n </template>\n </draggable>\n </div>\n </div>\n</template>\n\n<style scoped>\n.pv-tree-drop-zone {\n min-height: 0px;\n}\n\n/* Continuation line when this item is not last sibling (runs through nested children) */\n.tree-item-continued {\n position: relative;\n}\n\n.tree-item-continued::before {\n content: \"\";\n position: absolute;\n left: calc(var(--tree-connector-left, 8px) + 1px);\n top: 0;\n bottom: 0;\n width: 1px;\n background: var(--tree-connector-color, #d2d8dc);\n transform: translateX(-50%);\n z-index: 1;\n pointer-events: none;\n}\n\n/* When continuation line is drawn, hide the middle symbol's vertical so we don't double the line */\n.tree-item-continued .tree-component-nested-middle-symbol::before {\n display: none;\n}\n\n/* End symbol box */\n.tree-component-end-symbol {\n width: 16px;\n height: 16px;\n min-width: 16px;\n position: relative;\n}\n\n.tree-component-end-symbol::before,\n.tree-component-end-symbol::after {\n content: \"\";\n position: absolute;\n background: var(--tree-connector-color, #d2d8dc);\n}\n\n.tree-component-end-symbol::before {\n width: 1px;\n height: 14px;\n top: -6px;\n left: 8px;\n transform: translateX(-50%);\n}\n\n.tree-component-end-symbol::after {\n height: 1px;\n width: 8px;\n top: 8px;\n left: 8px;\n}\n\n/* Middle Tree Symbol */\n\n.tree-component-middle-symbol {\n width: 16px;\n height: 16px;\n min-width: 16px;\n position: relative;\n}\n\n.tree-component-middle-symbol::before {\n content: \"\";\n position: absolute;\n background: var(--tree-connector-color, #d2d8dc);\n left: 50%;\n width: 1px;\n height: 28px;\n top: -4px;\n transform: translateX(-50%);\n}\n\n/* Middle Nested Tree symbol box */\n.tree-component-nested-middle-symbol {\n width: 16px;\n height: 16px;\n min-width: 16px;\n position: relative;\n}\n\n.tree-component-nested-middle-symbol::before,\n.tree-component-nested-middle-symbol::after {\n content: \"\";\n position: absolute;\n background: var(--tree-connector-color, #d2d8dc);\n left: 50%;\n}\n\n.tree-component-nested-middle-symbol::before {\n width: 1px;\n height: 28px;\n top: -4px;\n transform: translateX(-50%);\n}\n\n.tree-component-nested-middle-symbol::after {\n height: 1px;\n width: 8px;\n top: 50%;\n transform: translateY(-50%);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport draggable from \"vuedraggable\";\nimport PvTreeReorderIcon from \"./PvTreeReorderIcon.vue\";\nimport PvButtonTreeItem from \"./PvButtonTreeItem.vue\";\nimport PvCheckboxTreeItem from \"./PvCheckboxTreeItem.vue\";\nimport PvSimpleItemTree from \"./PvSimpleItemTree.vue\";\nimport PvSimpleNestedTreeItem from \"./PvSimpleNestedTreeItem.vue\";\nimport type { PvTreeOption, PvTreeSettings } from \"./types\";\n\nimport { useHoverIcon } from \"./composables/useHoverIcon\";\nimport { useDragAndDrop } from \"./composables/useDragAndDrop\";\nimport { useDraggingState } from \"./composables/useDraggingState\";\nimport { useDragAndDropIndicator } from \"./composables/useDragAndDropIndicator\";\n\ninterface PvSimpleNestedTreeProps {\n option: PvTreeOption;\n settings: PvTreeSettings;\n level: number;\n selectedOptions?: PvTreeOption[];\n isDraggable?: boolean;\n isParentPathOpen?: boolean;\n disableSelection?: boolean;\n}\n\nconst props = defineProps<PvSimpleNestedTreeProps>();\n\nconst emit = defineEmits<{\n (e: \"handle-tree-select\", payload: { option: PvTreeOption; event: MouseEvent }): void;\n (e: \"update:children\", payload: { optionId: PvTreeOption[\"node_id\"]; newChildren: PvTreeOption[] }): void;\n}>();\n\nconst { hoveredId, handleMouseEnter, handleMouseLeave } = useHoverIcon();\nconst { getDragAndDropDisabled, canItemBeDragged, handleMoveCallback, getDragGroupConfig, canAcceptDrop } =\n useDragAndDrop();\nconst { isDragging, draggingGroupName, onDragStart, onDragEnd } = useDraggingState();\nconst { dragAndDropIndicatorClasses } = useDragAndDropIndicator();\n\nconst handleDragStart = () => {\n const groupConfig = getDragGroupConfig(props.settings, props.option);\n onDragStart(groupConfig.name);\n};\n\nconst additionalNestingLevel = computed(() => {\n return props.settings[props.option.field]?.additionalNestingLevel ?? 0;\n});\n\n/**\n * If we have showNestedTree as a false we want to add one more indentation level\n */\nconst nestedLevelTree = computed(() => {\n return props.settings[props.option.field]?.showNestedTree\n ? props.level + additionalNestingLevel.value\n : props.level + 1 + additionalNestingLevel.value;\n});\n\nconst isSelected = (id?: string | number) => {\n return props.selectedOptions && props.selectedOptions.some((option) => option.node_id === id);\n};\n\nconst componentInstance = (option: PvTreeOption) => {\n return props.settings[option.field]?.checkbox ? PvCheckboxTreeItem : PvButtonTreeItem;\n};\n\n// Writable computed for vuedraggable v-model binding\nconst children = computed({\n get: () => [...(props.option.children || [])],\n set: (value) => {\n emit(\"update:children\", { optionId: props.option.node_id, newChildren: value });\n },\n});\n\nconst isVisible = computed(() => props.isParentPathOpen ?? true);\n</script>\n\n<template>\n <div class=\"pv-flow\" style=\"--flow-size: 0px\">\n <component\n :is=\"componentInstance(option)\"\n :option=\"option\"\n :selected=\"isSelected(option.node_id)\"\n :disable-selection=\"disableSelection\"\n :label=\"option.label\"\n :icon=\"settings[option.field]?.icon\"\n :class=\"{\n ...dragAndDropIndicatorClasses(option),\n }\"\n :style=\"{\n paddingLeft: `${level * 24 + additionalNestingLevel * 24}px`,\n ...(settings[option.field]?.rendererParams?.onProvideCssStyles?.(option, { isVisible }) ?? {}),\n }\"\n @handle-selected=\"$emit('handle-tree-select', $event)\"\n @mouseenter=\"handleMouseEnter(option.node_id)\"\n @mouseleave=\"handleMouseLeave()\"\n @contextmenu.stop=\"settings[option.field]?.rendererParams?.onContextMenu?.($event, option)\"\n >\n <PvTreeReorderIcon v-show=\"hoveredId === option.node_id && canItemBeDragged(isDraggable, settings, option)\" />\n <component\n v-if=\"settings[option.field]?.renderer\"\n :is=\"settings[option.field]?.renderer\"\n :option=\"option\"\n :settings=\"settings\"\n :selected=\"isSelected(option.node_id)\"\n :params=\"settings[option.field]?.rendererParams\"\n />\n <PvSimpleItemTree v-else :label=\"option.label\" :icon=\"settings[option.field]?.icon\" />\n </component>\n <!-- Drop zone for children -->\n <div :data-parent-id=\"option.node_id\">\n <draggable\n v-model=\"children\"\n :parent-id=\"option.node_id\"\n :group=\"getDragGroupConfig(settings, option)\"\n item-key=\"node_id\"\n :disabled=\"getDragAndDropDisabled(isDraggable, settings, option)\"\n :move=\"handleMoveCallback(settings)\"\n :class=\"{\n 'pv-tree-drop-zone':\n isDraggable && isDragging && children.length === 0 && canAcceptDrop(settings, option, draggingGroupName),\n }\"\n @start=\"handleDragStart\"\n @end=\"onDragEnd\"\n @add=\"onDragEnd\"\n >\n <template #item=\"{ element, index }\">\n <PvSimpleNestedTreeItem\n :is-parent-path-open=\"isParentPathOpen\"\n :option=\"element\"\n :settings=\"settings\"\n :level=\"nestedLevelTree\"\n :index=\"index\"\n :total-siblings=\"children.length\"\n :parent-field=\"option.field\"\n :selected-options=\"selectedOptions\"\n :is-draggable=\"isDraggable\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"$emit('handle-tree-select', $event)\"\n @update:children=\"$emit('update:children', $event)\"\n />\n </template>\n </draggable>\n </div>\n </div>\n</template>\n\n<style scoped>\n.pv-tree-drop-zone {\n min-height: 0px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\nimport draggable from \"vuedraggable\";\nimport PvTreeReorderIcon from \"./PvTreeReorderIcon.vue\";\nimport PvButtonTreeItem from \"./PvButtonTreeItem.vue\";\nimport PvCheckboxTreeItem from \"./PvCheckboxTreeItem.vue\";\nimport PvSimpleItemTree from \"./PvSimpleItemTree.vue\";\nimport PvSimpleNestedTreeItem from \"./PvSimpleNestedTreeItem.vue\";\nimport type { PvTreeOption, PvTreeSettings } from \"./types\";\n\nimport { useHoverIcon } from \"./composables/useHoverIcon\";\nimport { useDragAndDrop } from \"./composables/useDragAndDrop\";\nimport { useDraggingState } from \"./composables/useDraggingState\";\nimport { useDragAndDropIndicator } from \"./composables/useDragAndDropIndicator\";\n\ninterface PvSimpleNestedTreeProps {\n option: PvTreeOption;\n settings: PvTreeSettings;\n level: number;\n selectedOptions?: PvTreeOption[];\n isDraggable?: boolean;\n isParentPathOpen?: boolean;\n disableSelection?: boolean;\n}\n\nconst props = defineProps<PvSimpleNestedTreeProps>();\n\nconst emit = defineEmits<{\n (e: \"handle-tree-select\", payload: { option: PvTreeOption; event: MouseEvent }): void;\n (e: \"update:children\", payload: { optionId: PvTreeOption[\"node_id\"]; newChildren: PvTreeOption[] }): void;\n}>();\n\nconst { hoveredId, handleMouseEnter, handleMouseLeave } = useHoverIcon();\nconst { getDragAndDropDisabled, canItemBeDragged, handleMoveCallback, getDragGroupConfig, canAcceptDrop } =\n useDragAndDrop();\nconst { isDragging, draggingGroupName, onDragStart, onDragEnd } = useDraggingState();\nconst { dragAndDropIndicatorClasses } = useDragAndDropIndicator();\n\nconst handleDragStart = () => {\n const groupConfig = getDragGroupConfig(props.settings, props.option);\n onDragStart(groupConfig.name);\n};\n\nconst additionalNestingLevel = computed(() => {\n return props.settings[props.option.field]?.additionalNestingLevel ?? 0;\n});\n\n/**\n * If we have showNestedTree as a false we want to add one more indentation level\n */\nconst nestedLevelTree = computed(() => {\n return props.settings[props.option.field]?.showNestedTree\n ? props.level + additionalNestingLevel.value\n : props.level + 1 + additionalNestingLevel.value;\n});\n\nconst isSelected = (id?: string | number) => {\n return props.selectedOptions && props.selectedOptions.some((option) => option.node_id === id);\n};\n\nconst componentInstance = (option: PvTreeOption) => {\n return props.settings[option.field]?.checkbox ? PvCheckboxTreeItem : PvButtonTreeItem;\n};\n\n// Writable computed for vuedraggable v-model binding\nconst children = computed({\n get: () => [...(props.option.children || [])],\n set: (value) => {\n emit(\"update:children\", { optionId: props.option.node_id, newChildren: value });\n },\n});\n\nconst isVisible = computed(() => props.isParentPathOpen ?? true);\n</script>\n\n<template>\n <div class=\"pv-flow\" style=\"--flow-size: 0px\">\n <component\n :is=\"componentInstance(option)\"\n :option=\"option\"\n :selected=\"isSelected(option.node_id)\"\n :disable-selection=\"disableSelection\"\n :label=\"option.label\"\n :icon=\"settings[option.field]?.icon\"\n :class=\"{\n ...dragAndDropIndicatorClasses(option),\n }\"\n :style=\"{\n paddingLeft: `${level * 24 + additionalNestingLevel * 24}px`,\n ...(settings[option.field]?.rendererParams?.onProvideCssStyles?.(option, { isVisible }) ?? {}),\n }\"\n @handle-selected=\"$emit('handle-tree-select', $event)\"\n @mouseenter=\"handleMouseEnter(option.node_id)\"\n @mouseleave=\"handleMouseLeave()\"\n @contextmenu.stop=\"settings[option.field]?.rendererParams?.onContextMenu?.($event, option)\"\n >\n <PvTreeReorderIcon v-show=\"hoveredId === option.node_id && canItemBeDragged(isDraggable, settings, option)\" />\n <component\n v-if=\"settings[option.field]?.renderer\"\n :is=\"settings[option.field]?.renderer\"\n :option=\"option\"\n :settings=\"settings\"\n :selected=\"isSelected(option.node_id)\"\n :params=\"settings[option.field]?.rendererParams\"\n />\n <PvSimpleItemTree v-else :label=\"option.label\" :icon=\"settings[option.field]?.icon\" />\n </component>\n <!-- Drop zone for children -->\n <div :data-parent-id=\"option.node_id\">\n <draggable\n v-model=\"children\"\n :parent-id=\"option.node_id\"\n :group=\"getDragGroupConfig(settings, option)\"\n item-key=\"node_id\"\n :disabled=\"getDragAndDropDisabled(isDraggable, settings, option)\"\n :move=\"handleMoveCallback(settings)\"\n :class=\"{\n 'pv-tree-drop-zone':\n isDraggable && isDragging && children.length === 0 && canAcceptDrop(settings, option, draggingGroupName),\n }\"\n @start=\"handleDragStart\"\n @end=\"onDragEnd\"\n @add=\"onDragEnd\"\n >\n <template #item=\"{ element, index }\">\n <PvSimpleNestedTreeItem\n :is-parent-path-open=\"isParentPathOpen\"\n :option=\"element\"\n :settings=\"settings\"\n :level=\"nestedLevelTree\"\n :index=\"index\"\n :total-siblings=\"children.length\"\n :parent-field=\"option.field\"\n :selected-options=\"selectedOptions\"\n :is-draggable=\"isDraggable\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"$emit('handle-tree-select', $event)\"\n @update:children=\"$emit('update:children', $event)\"\n />\n </template>\n </draggable>\n </div>\n </div>\n</template>\n\n<style scoped>\n.pv-tree-drop-zone {\n min-height: 0px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from \"vue\";\nimport draggable from \"vuedraggable\";\n\nimport PvAccordion from \"../PvAccordion/PvAccordion.vue\";\nimport PvSimpleItemTree from \"./PvSimpleItemTree.vue\";\nimport PvSimpleNestedTree from \"./PvSimpleNestedTree.vue\";\nimport PvCheckboxTreeItem from \"./PvCheckboxTreeItem.vue\";\nimport PvButtonTreeItem from \"./PvButtonTreeItem.vue\";\nimport PvTreeReorderIcon from \"./PvTreeReorderIcon.vue\";\nimport { useHoverIcon } from \"./composables/useHoverIcon\";\nimport { useDraggingState } from \"./composables/useDraggingState\";\nimport { useDragAndDropIndicator } from \"./composables/useDragAndDropIndicator\";\n\nimport type { PvTreeOption, PvTreeSettings } from \"./types\";\nimport { useDragAndDrop } from \"./composables/useDragAndDrop\";\n\ninterface PvTreeItemProps {\n option: PvTreeOption;\n selectedOptions?: PvTreeOption[];\n level?: number;\n settings: PvTreeSettings;\n isDraggable?: boolean;\n treeOpen?: boolean;\n isParentPathOpen?: boolean;\n isLastRootItem?: boolean;\n disableSelection?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvTreeItemProps>(), {\n level: 0,\n isParentPathOpen: true,\n disableSelection: false,\n});\n\nconst emit = defineEmits<{\n (e: \"handle-tree-select\", payload: { option: PvTreeOption; event: MouseEvent }): void;\n (e: \"update:children\", payload: { optionId: PvTreeOption[\"node_id\"]; newChildren: PvTreeOption[] }): void;\n}>();\n\n// Local accordion state - independent from treeOpen prop\nconst accordionOpen = ref(props.treeOpen ?? props.settings[props.option.field]?.defaultExpanded ?? false);\n\n// Watch treeOpen prop to allow programmatic control (e.g., \"expand all\" button)\nwatch(\n () => props.treeOpen,\n (newValue) => {\n if (newValue !== undefined) {\n accordionOpen.value = newValue;\n }\n },\n);\n\nconst {\n getDragGroupConfig,\n getDragAndDropDisabled,\n canItemBeDragged,\n handleMoveCallback,\n childrenDraggable,\n canAcceptDrop,\n} = useDragAndDrop();\nconst { hoveredId, handleMouseEnter, handleMouseLeave } = useHoverIcon();\nconst { isDragging, draggingGroupName, onDragStart, onDragEnd } = useDraggingState();\nconst { dragAndDropIndicatorClasses } = useDragAndDropIndicator();\n\nconst handleDragStart = () => {\n const groupConfig = getDragGroupConfig(props.settings, props.option);\n onDragStart(groupConfig.name);\n};\n\nconst nestedStyles = (level: number) => {\n return {\n paddingLeft: `${level * 24 + (props.settings[props.option.field]?.additionalNestingLevel ?? 0) * 24}px`,\n \"--border-color\": \"#121313\",\n };\n};\n\nconst isSelected = (id?: string | number) => {\n return props.selectedOptions && props.selectedOptions.some((option) => option.node_id === id);\n};\n\nconst componentInstance = computed(() => {\n return props.settings[props.option.field]?.checkbox ? PvCheckboxTreeItem : PvButtonTreeItem;\n});\n\n// Writable computed for vuedraggable v-model binding\nconst children = computed({\n get: () => [...(props.option.children || [])],\n set: (value) => {\n emit(\"update:children\", { optionId: props.option.node_id, newChildren: value });\n },\n});\n\nconst isAccordionRow = computed(() =>\n Boolean(props.option.children?.length && props.settings[props.option.field]?.accordion),\n);\n\nconst isVisible = computed(() => {\n const pathOpen = props.isParentPathOpen ?? true;\n if (!pathOpen) return false;\n // For accordion row at root (level 0): background only when this accordion is expanded\n // For accordion that is a child (level > 0): background when parent is open (pathOpen)\n if (isAccordionRow.value) return props.level === 0 ? accordionOpen.value : true;\n return true;\n});\n</script>\n\n<template>\n <PvAccordion\n v-if=\"option.children && option.children.length > 0 && settings && settings[option.field]?.accordion\"\n v-model=\"accordionOpen\"\n chevronPosition=\"left\"\n style=\"\n --accordion-content-padding: 2px 0px;\n --accordion-arrow-right-summary-padding: 0.25rem 1.375rem 0.25rem 0.25rem;\n --accordion-content-padding: 0px;\n \"\n :data-parent-id=\"option.node_id\"\n enableTriggerSlot\n enableTriggerFullWidth\n :summaryStyles=\"{\n ...nestedStyles(level),\n ...(settings[option.field]?.rendererParams?.onProvideCssStyles?.(option, { isVisible }) ?? {}),\n 'justify-content': 'flex-start',\n }\"\n :summaryClasses=\"{\n 'pv-tree-item': true,\n ...dragAndDropIndicatorClasses(option),\n }\"\n :defaultOpen=\"settings[option.field]?.defaultExpanded ?? false\"\n chevron-variant=\"horizontal\"\n @summary-mouseenter=\"handleMouseEnter(option.node_id)\"\n @summary-mouseleave=\"handleMouseLeave()\"\n @contextmenu.stop=\"settings[option.field]?.rendererParams?.onContextMenu?.($event, option)\"\n >\n <template #trigger>\n <PvTreeReorderIcon\n v-show=\"hoveredId === option.node_id && canItemBeDragged(isDraggable, settings, option) && level > 0\"\n />\n <template v-if=\"settings[option.field]?.renderer\">\n <component\n :is=\"settings[option.field]?.renderer\"\n :option=\"option\"\n :settings=\"settings\"\n :selected=\"isSelected(option.node_id)\"\n :params=\"settings[option.field]?.rendererParams\"\n />\n </template>\n <template v-else>\n <PvSimpleItemTree :label=\"option.label\" :icon=\"settings[option.field]?.icon\" />\n </template>\n </template>\n <!-- Drop zone for children -->\n <div :data-parent-id=\"option.node_id\">\n <draggable\n v-model=\"children\"\n :parent-id=\"option.node_id\"\n :group=\"getDragGroupConfig(settings, option)\"\n item-key=\"node_id\"\n :disabled=\"getDragAndDropDisabled(isDraggable, settings, option)\"\n :move=\"handleMoveCallback(settings)\"\n :class=\"{\n 'pv-tree-drop-zone':\n isDraggable && children.length === 0 && canAcceptDrop(settings, option, draggingGroupName),\n }\"\n @start=\"handleDragStart\"\n @end=\"onDragEnd\"\n @add=\"onDragEnd\"\n >\n <template #item=\"{ element }\">\n <PvTreeItem\n :is-parent-path-open=\"isParentPathOpen && accordionOpen\"\n :selected-options=\"selectedOptions\"\n :option=\"element\"\n :settings=\"settings\"\n :level=\"level + 1\"\n :is-draggable=\"childrenDraggable(isDraggable, settings, element)\"\n :tree-open=\"treeOpen\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"$emit('handle-tree-select', $event)\"\n @update:children=\"$emit('update:children', $event)\"\n />\n </template>\n </draggable>\n </div>\n </PvAccordion>\n <PvSimpleNestedTree\n v-else-if=\"option.children && option.children.length > 0 && settings && !settings[option.field]?.accordion\"\n :is-parent-path-open=\"isParentPathOpen\"\n :selected-options=\"selectedOptions\"\n :option=\"option\"\n :settings=\"settings\"\n :level=\"level\"\n :is-draggable=\"isDraggable\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"$emit('handle-tree-select', $event)\"\n @update:children=\"$emit('update:children', $event)\"\n :is-last-root-item=\"isLastRootItem\"\n />\n <div v-else>\n <component\n :is=\"componentInstance\"\n :class=\"{\n ...dragAndDropIndicatorClasses(option),\n }\"\n :option=\"option\"\n :selected=\"isSelected(option.node_id)\"\n :disable-selection=\"disableSelection\"\n :label=\"option.label\"\n :icon=\"settings[option.field]?.icon\"\n :style=\"{\n ...nestedStyles(level),\n ...(settings[option.field]?.rendererParams?.onProvideCssStyles?.(option, { isVisible }) ?? {}),\n }\"\n @handle-selected=\"$emit('handle-tree-select', $event)\"\n @mouseenter=\"handleMouseEnter(option.node_id)\"\n @mouseleave=\"handleMouseLeave()\"\n @contextmenu.stop=\"settings[option.field]?.rendererParams?.onContextMenu?.($event, option)\"\n >\n <PvTreeReorderIcon\n v-show=\"hoveredId === option.node_id && canItemBeDragged(isDraggable, settings, option) && level > 0\"\n />\n <component\n v-if=\"settings[option.field]?.renderer\"\n :is=\"settings[option.field]?.renderer\"\n :option=\"option\"\n :settings=\"settings\"\n :params=\"settings[option.field]?.rendererParams\"\n />\n <PvSimpleItemTree v-else :label=\"option.label\" :icon=\"settings[option.field]?.icon\" />\n </component>\n <!-- Drop zone for children -->\n <div :data-parent-id=\"option.node_id\">\n <draggable\n v-model=\"children\"\n :parent-id=\"option.node_id\"\n :group=\"getDragGroupConfig(settings, option)\"\n item-key=\"node_id\"\n :disabled=\"getDragAndDropDisabled(isDraggable, settings, option)\"\n :move=\"handleMoveCallback(settings)\"\n :class=\"{\n 'pv-tree-drop-zone':\n isDragging && children.length === 0 && canAcceptDrop(settings, option, draggingGroupName),\n }\"\n @start=\"handleDragStart\"\n @end=\"onDragEnd\"\n @add=\"onDragEnd\"\n >\n <template #item=\"{ element }\">\n <PvTreeItem\n :is-parent-path-open=\"isParentPathOpen\"\n :selected-options=\"selectedOptions\"\n :option=\"element\"\n :settings=\"settings\"\n :level=\"level + 1\"\n :is-draggable=\"childrenDraggable(isDraggable, settings, element)\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"$emit('handle-tree-select', $event)\"\n @update:children=\"$emit('update:children', $event)\"\n />\n </template>\n </draggable>\n </div>\n </div>\n</template>\n\n<style scoped>\n.pv-tree-drop-zone {\n min-height: 0px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from \"vue\";\nimport draggable from \"vuedraggable\";\n\nimport PvAccordion from \"../PvAccordion/PvAccordion.vue\";\nimport PvSimpleItemTree from \"./PvSimpleItemTree.vue\";\nimport PvSimpleNestedTree from \"./PvSimpleNestedTree.vue\";\nimport PvCheckboxTreeItem from \"./PvCheckboxTreeItem.vue\";\nimport PvButtonTreeItem from \"./PvButtonTreeItem.vue\";\nimport PvTreeReorderIcon from \"./PvTreeReorderIcon.vue\";\nimport { useHoverIcon } from \"./composables/useHoverIcon\";\nimport { useDraggingState } from \"./composables/useDraggingState\";\nimport { useDragAndDropIndicator } from \"./composables/useDragAndDropIndicator\";\n\nimport type { PvTreeOption, PvTreeSettings } from \"./types\";\nimport { useDragAndDrop } from \"./composables/useDragAndDrop\";\n\ninterface PvTreeItemProps {\n option: PvTreeOption;\n selectedOptions?: PvTreeOption[];\n level?: number;\n settings: PvTreeSettings;\n isDraggable?: boolean;\n treeOpen?: boolean;\n isParentPathOpen?: boolean;\n isLastRootItem?: boolean;\n disableSelection?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvTreeItemProps>(), {\n level: 0,\n isParentPathOpen: true,\n disableSelection: false,\n});\n\nconst emit = defineEmits<{\n (e: \"handle-tree-select\", payload: { option: PvTreeOption; event: MouseEvent }): void;\n (e: \"update:children\", payload: { optionId: PvTreeOption[\"node_id\"]; newChildren: PvTreeOption[] }): void;\n}>();\n\n// Local accordion state - independent from treeOpen prop\nconst accordionOpen = ref(props.treeOpen ?? props.settings[props.option.field]?.defaultExpanded ?? false);\n\n// Watch treeOpen prop to allow programmatic control (e.g., \"expand all\" button)\nwatch(\n () => props.treeOpen,\n (newValue) => {\n if (newValue !== undefined) {\n accordionOpen.value = newValue;\n }\n },\n);\n\nconst {\n getDragGroupConfig,\n getDragAndDropDisabled,\n canItemBeDragged,\n handleMoveCallback,\n childrenDraggable,\n canAcceptDrop,\n} = useDragAndDrop();\nconst { hoveredId, handleMouseEnter, handleMouseLeave } = useHoverIcon();\nconst { isDragging, draggingGroupName, onDragStart, onDragEnd } = useDraggingState();\nconst { dragAndDropIndicatorClasses } = useDragAndDropIndicator();\n\nconst handleDragStart = () => {\n const groupConfig = getDragGroupConfig(props.settings, props.option);\n onDragStart(groupConfig.name);\n};\n\nconst nestedStyles = (level: number) => {\n return {\n paddingLeft: `${level * 24 + (props.settings[props.option.field]?.additionalNestingLevel ?? 0) * 24}px`,\n \"--border-color\": \"#121313\",\n };\n};\n\nconst isSelected = (id?: string | number) => {\n return props.selectedOptions && props.selectedOptions.some((option) => option.node_id === id);\n};\n\nconst componentInstance = computed(() => {\n return props.settings[props.option.field]?.checkbox ? PvCheckboxTreeItem : PvButtonTreeItem;\n});\n\n// Writable computed for vuedraggable v-model binding\nconst children = computed({\n get: () => [...(props.option.children || [])],\n set: (value) => {\n emit(\"update:children\", { optionId: props.option.node_id, newChildren: value });\n },\n});\n\nconst isAccordionRow = computed(() =>\n Boolean(props.option.children?.length && props.settings[props.option.field]?.accordion),\n);\n\nconst isVisible = computed(() => {\n const pathOpen = props.isParentPathOpen ?? true;\n if (!pathOpen) return false;\n // For accordion row at root (level 0): background only when this accordion is expanded\n // For accordion that is a child (level > 0): background when parent is open (pathOpen)\n if (isAccordionRow.value) return props.level === 0 ? accordionOpen.value : true;\n return true;\n});\n</script>\n\n<template>\n <PvAccordion\n v-if=\"option.children && option.children.length > 0 && settings && settings[option.field]?.accordion\"\n v-model=\"accordionOpen\"\n chevronPosition=\"left\"\n style=\"\n --accordion-content-padding: 2px 0px;\n --accordion-arrow-right-summary-padding: 0.25rem 1.375rem 0.25rem 0.25rem;\n --accordion-content-padding: 0px;\n \"\n :data-parent-id=\"option.node_id\"\n enableTriggerSlot\n enableTriggerFullWidth\n :summaryStyles=\"{\n ...nestedStyles(level),\n ...(settings[option.field]?.rendererParams?.onProvideCssStyles?.(option, { isVisible }) ?? {}),\n 'justify-content': 'flex-start',\n }\"\n :summaryClasses=\"{\n 'pv-tree-item': true,\n ...dragAndDropIndicatorClasses(option),\n }\"\n :defaultOpen=\"settings[option.field]?.defaultExpanded ?? false\"\n chevron-variant=\"horizontal\"\n @summary-mouseenter=\"handleMouseEnter(option.node_id)\"\n @summary-mouseleave=\"handleMouseLeave()\"\n @contextmenu.stop=\"settings[option.field]?.rendererParams?.onContextMenu?.($event, option)\"\n >\n <template #trigger>\n <PvTreeReorderIcon\n v-show=\"hoveredId === option.node_id && canItemBeDragged(isDraggable, settings, option) && level > 0\"\n />\n <template v-if=\"settings[option.field]?.renderer\">\n <component\n :is=\"settings[option.field]?.renderer\"\n :option=\"option\"\n :settings=\"settings\"\n :selected=\"isSelected(option.node_id)\"\n :params=\"settings[option.field]?.rendererParams\"\n />\n </template>\n <template v-else>\n <PvSimpleItemTree :label=\"option.label\" :icon=\"settings[option.field]?.icon\" />\n </template>\n </template>\n <!-- Drop zone for children -->\n <div :data-parent-id=\"option.node_id\">\n <draggable\n v-model=\"children\"\n :parent-id=\"option.node_id\"\n :group=\"getDragGroupConfig(settings, option)\"\n item-key=\"node_id\"\n :disabled=\"getDragAndDropDisabled(isDraggable, settings, option)\"\n :move=\"handleMoveCallback(settings)\"\n :class=\"{\n 'pv-tree-drop-zone':\n isDraggable && children.length === 0 && canAcceptDrop(settings, option, draggingGroupName),\n }\"\n @start=\"handleDragStart\"\n @end=\"onDragEnd\"\n @add=\"onDragEnd\"\n >\n <template #item=\"{ element }\">\n <PvTreeItem\n :is-parent-path-open=\"isParentPathOpen && accordionOpen\"\n :selected-options=\"selectedOptions\"\n :option=\"element\"\n :settings=\"settings\"\n :level=\"level + 1\"\n :is-draggable=\"childrenDraggable(isDraggable, settings, element)\"\n :tree-open=\"treeOpen\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"$emit('handle-tree-select', $event)\"\n @update:children=\"$emit('update:children', $event)\"\n />\n </template>\n </draggable>\n </div>\n </PvAccordion>\n <PvSimpleNestedTree\n v-else-if=\"option.children && option.children.length > 0 && settings && !settings[option.field]?.accordion\"\n :is-parent-path-open=\"isParentPathOpen\"\n :selected-options=\"selectedOptions\"\n :option=\"option\"\n :settings=\"settings\"\n :level=\"level\"\n :is-draggable=\"isDraggable\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"$emit('handle-tree-select', $event)\"\n @update:children=\"$emit('update:children', $event)\"\n :is-last-root-item=\"isLastRootItem\"\n />\n <div v-else>\n <component\n :is=\"componentInstance\"\n :class=\"{\n ...dragAndDropIndicatorClasses(option),\n }\"\n :option=\"option\"\n :selected=\"isSelected(option.node_id)\"\n :disable-selection=\"disableSelection\"\n :label=\"option.label\"\n :icon=\"settings[option.field]?.icon\"\n :style=\"{\n ...nestedStyles(level),\n ...(settings[option.field]?.rendererParams?.onProvideCssStyles?.(option, { isVisible }) ?? {}),\n }\"\n @handle-selected=\"$emit('handle-tree-select', $event)\"\n @mouseenter=\"handleMouseEnter(option.node_id)\"\n @mouseleave=\"handleMouseLeave()\"\n @contextmenu.stop=\"settings[option.field]?.rendererParams?.onContextMenu?.($event, option)\"\n >\n <PvTreeReorderIcon\n v-show=\"hoveredId === option.node_id && canItemBeDragged(isDraggable, settings, option) && level > 0\"\n />\n <component\n v-if=\"settings[option.field]?.renderer\"\n :is=\"settings[option.field]?.renderer\"\n :option=\"option\"\n :settings=\"settings\"\n :params=\"settings[option.field]?.rendererParams\"\n />\n <PvSimpleItemTree v-else :label=\"option.label\" :icon=\"settings[option.field]?.icon\" />\n </component>\n <!-- Drop zone for children -->\n <div :data-parent-id=\"option.node_id\">\n <draggable\n v-model=\"children\"\n :parent-id=\"option.node_id\"\n :group=\"getDragGroupConfig(settings, option)\"\n item-key=\"node_id\"\n :disabled=\"getDragAndDropDisabled(isDraggable, settings, option)\"\n :move=\"handleMoveCallback(settings)\"\n :class=\"{\n 'pv-tree-drop-zone':\n isDragging && children.length === 0 && canAcceptDrop(settings, option, draggingGroupName),\n }\"\n @start=\"handleDragStart\"\n @end=\"onDragEnd\"\n @add=\"onDragEnd\"\n >\n <template #item=\"{ element }\">\n <PvTreeItem\n :is-parent-path-open=\"isParentPathOpen\"\n :selected-options=\"selectedOptions\"\n :option=\"element\"\n :settings=\"settings\"\n :level=\"level + 1\"\n :is-draggable=\"childrenDraggable(isDraggable, settings, element)\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"$emit('handle-tree-select', $event)\"\n @update:children=\"$emit('update:children', $event)\"\n />\n </template>\n </draggable>\n </div>\n </div>\n</template>\n\n<style scoped>\n.pv-tree-drop-zone {\n min-height: 0px;\n}\n</style>\n","import { nextTick, Ref } from \"vue\";\nimport { cloneDeep } from \"es-toolkit/object\";\nimport { PvTreeOption } from \"../types\";\n\nexport const useTreeUpdate = (options: Ref<PvTreeOption[]>) => {\n const pendingChildrenUpdates: { optionId: PvTreeOption[\"node_id\"]; newChildren: PvTreeOption[] }[] = [];\n let flushScheduled = false;\n\n /**\n * Builds fast lookup indexes for the tree:\n * - nodeById: allows O(1) access to any node by id\n * - parentById: tracks the current parent of each node\n *\n * This avoids repeated full tree traversals during updates.\n */\n function buildIndex(roots: PvTreeOption[]): {\n nodeById: Map<PvTreeOption[\"node_id\"], PvTreeOption>;\n parentById: Map<PvTreeOption[\"node_id\"], PvTreeOption | null>;\n } {\n const nodeById = new Map<PvTreeOption[\"node_id\"], PvTreeOption>();\n const parentById = new Map<PvTreeOption[\"node_id\"], PvTreeOption | null>();\n\n // Iterative DFS to avoid deep recursion on large trees\n const stack: Array<{ node: PvTreeOption; parent: PvTreeOption | null }> = [];\n for (const root of roots) {\n stack.push({ node: root, parent: null });\n }\n\n while (stack.length) {\n const { node, parent } = stack.pop()!;\n nodeById.set(node.node_id, node);\n parentById.set(node.node_id, parent);\n\n if (node.children?.length) {\n for (const child of node.children) {\n stack.push({ node: child, parent: node });\n }\n }\n }\n\n return { nodeById, parentById };\n }\n\n /**\n * Applies all pending children updates in a single flush.\n *\n * Key ideas:\n * - Clone the tree once to keep updates immutable\n * - Build indexes once for fast lookups\n * - Move nodes by re-parenting instead of re-traversing the tree\n */\n const flushPendingChildrenUpdates = () => {\n flushScheduled = false;\n\n // Nothing to do\n if (pendingChildrenUpdates.length === 0) return;\n\n // Take all pending updates and clear the queue\n const updates = pendingChildrenUpdates.splice(0, pendingChildrenUpdates.length);\n\n // Clone the current options tree only once\n const result = cloneDeep(options.value);\n\n // Build fast lookup structures\n const { nodeById, parentById } = buildIndex(result);\n\n /**\n * If multiple updates target the same optionId,\n * the last one wins.\n */\n const lastUpdateByOption = new Map<PvTreeOption[\"node_id\"], PvTreeOption[]>();\n for (const update of updates) {\n lastUpdateByOption.set(update.optionId, update.newChildren);\n }\n\n // Apply normalized updates\n for (const [optionId, newChildren] of lastUpdateByOption) {\n const parentNode = nodeById.get(optionId);\n if (!parentNode) continue;\n\n /**\n * Map children:\n * - If a node already exists in the tree, reuse it (we are moving it)\n * - Otherwise, treat it as a new node\n */\n const mappedChildren = newChildren.map((child) => nodeById.get(child.node_id) ?? child);\n\n /**\n * Register any brand-new nodes in the indexes\n */\n for (const child of mappedChildren) {\n if (!nodeById.has(child.node_id)) {\n nodeById.set(child.node_id, child);\n parentById.set(child.node_id, null);\n }\n }\n\n /**\n * Re-parent children:\n * - Detach from the old parent if necessary\n * - Attach to the new parent\n */\n for (const child of mappedChildren) {\n const oldParent = parentById.get(child.node_id) ?? null;\n\n // Remove from previous parent if it differs from the new one\n if (oldParent && oldParent !== parentNode) {\n oldParent.children = (oldParent.children ?? []).filter((c) => c.node_id !== child.node_id);\n }\n\n parentById.set(child.node_id, parentNode);\n }\n\n // Finally, replace the parent's children list\n parentNode.children = mappedChildren;\n }\n\n // Commit the updated tree\n options.value = result;\n };\n\n const handleUpdateChildren = ({\n optionId,\n newChildren,\n }: {\n optionId: PvTreeOption[\"node_id\"];\n newChildren: PvTreeOption[];\n }) => {\n // Queue the update; flush applies all pending updates in one pass (last per optionId wins).\n pendingChildrenUpdates.push({ optionId, newChildren });\n if (!flushScheduled) {\n flushScheduled = true;\n nextTick(flushPendingChildrenUpdates);\n }\n };\n\n return {\n handleUpdateChildren,\n };\n};\n","<script setup lang=\"ts\">\nimport { computed, inject } from \"vue\";\n\nimport PvTreeItem from \"./PvTreeItem.vue\";\nimport type { PvTreeOption, PvTreeSetting, PvTreeSettings } from \"./types\";\nimport { provideDraggingState } from \"./composables/useDraggingState\";\nimport { DraggingStateKey } from \"./symbols\";\nimport { useTreeUpdate } from \"./composables/useTreeUpdate\";\n\n// Only provide dragging state if a PvTreeGroup hasn't already provided it.\n// This allows multiple trees inside a PvTreeGroup to share the same state\n// for cross-tree drag indicators, while a standalone PvTree remains self-contained.\nif (!inject(DraggingStateKey, null)) {\n provideDraggingState();\n}\n\ninterface PvTreeProps {\n /** Per-field rendering and behavior settings for tree nodes */\n settings: PvTreeSettings;\n /** Default settings applied to all node types before field-specific overrides */\n defaultSettings?: PvTreeSetting;\n /** Enable drag-and-drop reordering of tree items */\n isDraggable?: boolean;\n /** Disable click-to-select behavior on tree items */\n disableSelection?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvTreeProps>(), {\n isDraggable: false,\n disableSelection: false,\n});\n\nconst selectedOptions = defineModel<PvTreeOption[]>(\"selectedOptions\", { required: false });\nconst options = defineModel<PvTreeOption[]>(\"options\", { required: true });\nconst treeOpen = defineModel<boolean>(\"treeOpen\", { required: false });\n\nconst { handleUpdateChildren } = useTreeUpdate(options);\n\nconst handleTreeSelect = (option: PvTreeOption, event: MouseEvent) => {\n if (event.metaKey) {\n if (selectedOptions.value?.some((selectedOption) => selectedOption.node_id === option.node_id)) {\n selectedOptions.value = selectedOptions.value?.filter(\n (selectedOption) => selectedOption.node_id !== option.node_id,\n );\n } else {\n selectedOptions.value = [...(selectedOptions.value || []), option];\n }\n } else {\n if (selectedOptions.value?.some((selectedOption) => selectedOption.node_id === option.node_id)) {\n selectedOptions.value = [];\n } else {\n selectedOptions.value = [option];\n }\n }\n};\n\nconst computedSettings = computed(() => {\n return Object.keys(props.settings).reduce((acc, key) => {\n acc[key] = { ...props.defaultSettings, ...props.settings[key] };\n return acc;\n }, {} as PvTreeSettings);\n});\n</script>\n\n<template>\n <div>\n <div class=\"pv-tree\" :class=\"{ 'pv-tree--disable-selection': disableSelection }\">\n <div v-for=\"(option, index) in options\" :key=\"option.node_id\">\n <PvTreeItem\n :is-last-root-item=\"index === options.length - 1\"\n :is-parent-path-open=\"true\"\n :tree-open=\"treeOpen\"\n :selected-options=\"selectedOptions\"\n :option=\"option\"\n :settings=\"computedSettings\"\n :is-draggable=\"isDraggable\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"({ option, event }) => handleTreeSelect(option, event)\"\n @update:children=\"handleUpdateChildren\"\n />\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n/* This may be moved to a global styles file */\n:deep(.pv-tree-item) {\n padding: 3px 4px;\n cursor: pointer;\n background-color: transparent;\n border: 1px solid transparent;\n}\n\n:deep(.pv-tree-item-disabled) {\n cursor: default !important;\n}\n\n:deep(.pv-tree-item.pv-drop-indicator-top) {\n border-top: 1px solid var(--color-border, #121313);\n}\n:deep(.pv-tree-item.pv-drop-indicator-bottom) {\n border-bottom: 1px solid var(--color-border, #121313);\n}\n\n:deep(.pv-drop-indicator-parent) {\n border: 1px solid var(--color-border, #36c5ba);\n}\n\n:deep(.pv-tree-item-selected) {\n background-color: var(--pv-color-selected, #e4f8f6);\n}\n\n:deep(.pv-tree:not(.pv-tree--disable-selection) .pv-tree-item-selected:hover),\n:deep(.pv-tree:not(.pv-tree--disable-selection) .pv-tree-item:hover) {\n border-radius: 4px;\n background-color: var(--pv-color-hover, #e8f2f4);\n}\n\n:deep(.pv-tree:not(.pv-tree--disable-selection) .pv-tree-item-selected:active),\n:deep(.pv-tree:not(.pv-tree--disable-selection) .pv-tree-item:active) {\n border-radius: 4px;\n background-color: var(--pv-color-active, #c7d8db);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, inject } from \"vue\";\n\nimport PvTreeItem from \"./PvTreeItem.vue\";\nimport type { PvTreeOption, PvTreeSetting, PvTreeSettings } from \"./types\";\nimport { provideDraggingState } from \"./composables/useDraggingState\";\nimport { DraggingStateKey } from \"./symbols\";\nimport { useTreeUpdate } from \"./composables/useTreeUpdate\";\n\n// Only provide dragging state if a PvTreeGroup hasn't already provided it.\n// This allows multiple trees inside a PvTreeGroup to share the same state\n// for cross-tree drag indicators, while a standalone PvTree remains self-contained.\nif (!inject(DraggingStateKey, null)) {\n provideDraggingState();\n}\n\ninterface PvTreeProps {\n /** Per-field rendering and behavior settings for tree nodes */\n settings: PvTreeSettings;\n /** Default settings applied to all node types before field-specific overrides */\n defaultSettings?: PvTreeSetting;\n /** Enable drag-and-drop reordering of tree items */\n isDraggable?: boolean;\n /** Disable click-to-select behavior on tree items */\n disableSelection?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvTreeProps>(), {\n isDraggable: false,\n disableSelection: false,\n});\n\nconst selectedOptions = defineModel<PvTreeOption[]>(\"selectedOptions\", { required: false });\nconst options = defineModel<PvTreeOption[]>(\"options\", { required: true });\nconst treeOpen = defineModel<boolean>(\"treeOpen\", { required: false });\n\nconst { handleUpdateChildren } = useTreeUpdate(options);\n\nconst handleTreeSelect = (option: PvTreeOption, event: MouseEvent) => {\n if (event.metaKey) {\n if (selectedOptions.value?.some((selectedOption) => selectedOption.node_id === option.node_id)) {\n selectedOptions.value = selectedOptions.value?.filter(\n (selectedOption) => selectedOption.node_id !== option.node_id,\n );\n } else {\n selectedOptions.value = [...(selectedOptions.value || []), option];\n }\n } else {\n if (selectedOptions.value?.some((selectedOption) => selectedOption.node_id === option.node_id)) {\n selectedOptions.value = [];\n } else {\n selectedOptions.value = [option];\n }\n }\n};\n\nconst computedSettings = computed(() => {\n return Object.keys(props.settings).reduce((acc, key) => {\n acc[key] = { ...props.defaultSettings, ...props.settings[key] };\n return acc;\n }, {} as PvTreeSettings);\n});\n</script>\n\n<template>\n <div>\n <div class=\"pv-tree\" :class=\"{ 'pv-tree--disable-selection': disableSelection }\">\n <div v-for=\"(option, index) in options\" :key=\"option.node_id\">\n <PvTreeItem\n :is-last-root-item=\"index === options.length - 1\"\n :is-parent-path-open=\"true\"\n :tree-open=\"treeOpen\"\n :selected-options=\"selectedOptions\"\n :option=\"option\"\n :settings=\"computedSettings\"\n :is-draggable=\"isDraggable\"\n :disable-selection=\"disableSelection\"\n @handle-tree-select=\"({ option, event }) => handleTreeSelect(option, event)\"\n @update:children=\"handleUpdateChildren\"\n />\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n/* This may be moved to a global styles file */\n:deep(.pv-tree-item) {\n padding: 3px 4px;\n cursor: pointer;\n background-color: transparent;\n border: 1px solid transparent;\n}\n\n:deep(.pv-tree-item-disabled) {\n cursor: default !important;\n}\n\n:deep(.pv-tree-item.pv-drop-indicator-top) {\n border-top: 1px solid var(--color-border, #121313);\n}\n:deep(.pv-tree-item.pv-drop-indicator-bottom) {\n border-bottom: 1px solid var(--color-border, #121313);\n}\n\n:deep(.pv-drop-indicator-parent) {\n border: 1px solid var(--color-border, #36c5ba);\n}\n\n:deep(.pv-tree-item-selected) {\n background-color: var(--pv-color-selected, #e4f8f6);\n}\n\n:deep(.pv-tree:not(.pv-tree--disable-selection) .pv-tree-item-selected:hover),\n:deep(.pv-tree:not(.pv-tree--disable-selection) .pv-tree-item:hover) {\n border-radius: 4px;\n background-color: var(--pv-color-hover, #e8f2f4);\n}\n\n:deep(.pv-tree:not(.pv-tree--disable-selection) .pv-tree-item-selected:active),\n:deep(.pv-tree:not(.pv-tree--disable-selection) .pv-tree-item:active) {\n border-radius: 4px;\n background-color: var(--pv-color-active, #c7d8db);\n}\n</style>\n","<script setup lang=\"ts\">\nimport { provideDraggingState } from \"./composables/useDraggingState\";\n\n// Provides shared drag state to all PvTree children so cross-tree\n// drop indicators and drag status work correctly across sibling trees.\nprovideDraggingState();\n</script>\n\n<template>\n <slot />\n</template>\n","<script setup lang=\"ts\">\nimport { provideDraggingState } from \"./composables/useDraggingState\";\n\n// Provides shared drag state to all PvTree children so cross-tree\n// drop indicators and drag status work correctly across sibling trees.\nprovideDraggingState();\n</script>\n\n<template>\n <slot />\n</template>\n","<script setup lang=\"ts\">\ninterface PvProgressBarProps {\n /** The current progress value as a percentage (0–100). */\n progress?: number;\n /** When true, displays a text label above the bar showing \"{progress}% Complete\". */\n showLabel?: boolean;\n /** When true, renders the progress bar in a disabled/muted visual state. */\n disabled?: boolean;\n}\n\nconst props = defineProps<PvProgressBarProps>();\n</script>\n\n<template>\n <p v-if=\"props.showLabel\" class=\"pv-text-brand pv-text-title-sm pv-stack-4\">{{ props.progress }}% Complete</p>\n <div\n class=\"pv-progress-bar\"\n :data-disabled=\"props.disabled ? true : undefined\"\n :style=\"{\n '--progress': `${props.progress}%`,\n }\"\n ></div>\n</template>\n","<script setup lang=\"ts\">\ninterface PvProgressBarProps {\n /** The current progress value as a percentage (0–100). */\n progress?: number;\n /** When true, displays a text label above the bar showing \"{progress}% Complete\". */\n showLabel?: boolean;\n /** When true, renders the progress bar in a disabled/muted visual state. */\n disabled?: boolean;\n}\n\nconst props = defineProps<PvProgressBarProps>();\n</script>\n\n<template>\n <p v-if=\"props.showLabel\" class=\"pv-text-brand pv-text-title-sm pv-stack-4\">{{ props.progress }}% Complete</p>\n <div\n class=\"pv-progress-bar\"\n :data-disabled=\"props.disabled ? true : undefined\"\n :style=\"{\n '--progress': `${props.progress}%`,\n }\"\n ></div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\ninterface PvDistributionBarProps {\n /** Array of numeric values representing each segment of the distribution bar. Values are rendered proportionally. Supports up to 7 color-coded segments. */\n values?: number[];\n}\n\nconst props = defineProps<PvDistributionBarProps>();\n\nconst totalValue = computed(() => {\n return props.values?.reduce((acc, curr) => acc + curr, 0) ?? 0;\n});\n\nconst barStyles = (value: number, index: number) => {\n const firstNonZeroIndex = props.values?.findIndex((v) => v > 0) ?? -1;\n const lastNonZeroIndex = props.values?.findLastIndex((v) => v > 0) ?? -1;\n const isFirstVisibleElement = index === firstNonZeroIndex;\n const isLastVisibleElement = index === lastNonZeroIndex;\n const radius = (corner: boolean) => (corner ? \"12px\" : \"0\");\n\n return {\n width: `${(value / totalValue.value) * 100}%`,\n height: \"100%\",\n borderRadius: `${radius(isFirstVisibleElement)} ${radius(isLastVisibleElement)} ${radius(isLastVisibleElement)} ${radius(isFirstVisibleElement)}`,\n };\n};\n\nconst barColors = (index: number) => {\n switch (index) {\n case 0:\n return \"pv-data-surface-visualization-1\";\n case 1:\n return \"pv-data-surface-visualization-2\";\n case 2:\n return \"pv-data-surface-visualization-3\";\n case 3:\n return \"pv-data-surface-visualization-4\";\n case 4:\n return \"pv-data-surface-visualization-5\";\n case 5:\n return \"pv-data-surface-visualization-6\";\n case 6:\n return \"pv-data-surface-visualization-7\";\n default:\n return \"pv-data-surface-visualization-1\";\n }\n};\n</script>\n\n<template>\n <div class=\"pv-flex\" style=\"--flex-gap: 4px; height: 24px\">\n <div v-for=\"(value, index) in values\" :key=\"index\" :class=\"[barColors(index)]\" :style=\"barStyles(value, index)\" />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed } from \"vue\";\n\ninterface PvDistributionBarProps {\n /** Array of numeric values representing each segment of the distribution bar. Values are rendered proportionally. Supports up to 7 color-coded segments. */\n values?: number[];\n}\n\nconst props = defineProps<PvDistributionBarProps>();\n\nconst totalValue = computed(() => {\n return props.values?.reduce((acc, curr) => acc + curr, 0) ?? 0;\n});\n\nconst barStyles = (value: number, index: number) => {\n const firstNonZeroIndex = props.values?.findIndex((v) => v > 0) ?? -1;\n const lastNonZeroIndex = props.values?.findLastIndex((v) => v > 0) ?? -1;\n const isFirstVisibleElement = index === firstNonZeroIndex;\n const isLastVisibleElement = index === lastNonZeroIndex;\n const radius = (corner: boolean) => (corner ? \"12px\" : \"0\");\n\n return {\n width: `${(value / totalValue.value) * 100}%`,\n height: \"100%\",\n borderRadius: `${radius(isFirstVisibleElement)} ${radius(isLastVisibleElement)} ${radius(isLastVisibleElement)} ${radius(isFirstVisibleElement)}`,\n };\n};\n\nconst barColors = (index: number) => {\n switch (index) {\n case 0:\n return \"pv-data-surface-visualization-1\";\n case 1:\n return \"pv-data-surface-visualization-2\";\n case 2:\n return \"pv-data-surface-visualization-3\";\n case 3:\n return \"pv-data-surface-visualization-4\";\n case 4:\n return \"pv-data-surface-visualization-5\";\n case 5:\n return \"pv-data-surface-visualization-6\";\n case 6:\n return \"pv-data-surface-visualization-7\";\n default:\n return \"pv-data-surface-visualization-1\";\n }\n};\n</script>\n\n<template>\n <div class=\"pv-flex\" style=\"--flex-gap: 4px; height: 24px\">\n <div v-for=\"(value, index) in values\" :key=\"index\" :class=\"[barColors(index)]\" :style=\"barStyles(value, index)\" />\n </div>\n</template>\n","import type { AdvancedFilterModel } from \"ag-grid-enterprise\";\nimport type { PvFilterPanelColDef, PvFilterPanelFilterModelType } from \"./types\";\n\nexport interface PvFilterPanelRangeValue {\n max: number | null;\n min: number | null;\n}\n\ntype RegularFilterModel = Record<string, RegularFilterCondition>;\n\ntype RegularFilterConditionMatcher = (condition: RegularFilterCondition) => boolean;\n\ninterface RegularFilterCondition {\n filter?: boolean | number | string | null;\n filterModels?: Array<RegularFilterCondition | null | undefined>;\n filterTo?: number | null;\n filterType?: string;\n type?: string;\n values?: unknown[];\n}\n\nexport type PvAdvancedFilterColumnType =\n | \"date\"\n | \"dateString\"\n | \"dateTime\"\n | \"dateTimeString\"\n | \"number\"\n | \"object\"\n | \"text\";\n\ninterface AdvancedFilterCondition {\n colId: string;\n filter?: boolean | number | string;\n filterType: string;\n type: string;\n values?: string[];\n}\n\ninterface AdvancedFilterJoin {\n conditions: AdvancedFilterNode[];\n filterType: \"join\";\n type: \"AND\" | \"OR\";\n}\n\ntype AdvancedFilterNode = AdvancedFilterCondition | AdvancedFilterJoin;\n\nexport interface PvFilterPanelModelIndexEntry {\n booleanValue: boolean | null;\n existsValue: boolean;\n rangeValue: PvFilterPanelRangeValue;\n values: string[];\n}\n\nexport type PvFilterPanelModelIndex = Map<string, PvFilterPanelModelIndexEntry>;\n\nconst createIndexEntry = (): PvFilterPanelModelIndexEntry => ({\n booleanValue: null,\n existsValue: false,\n rangeValue: { max: null, min: null },\n values: [],\n});\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n};\n\nconst isConditionNode = (model: unknown): model is AdvancedFilterCondition => {\n return (\n isRecord(model) &&\n typeof model.colId === \"string\" &&\n typeof model.filterType === \"string\" &&\n typeof model.type === \"string\"\n );\n};\n\nconst isJoinNode = (model: unknown): model is AdvancedFilterJoin => {\n return isRecord(model) && model.filterType === \"join\" && Array.isArray(model.conditions);\n};\n\nconst asAdvancedFilterModel = (node: AdvancedFilterNode | null): AdvancedFilterModel | null => {\n return node as AdvancedFilterModel | null;\n};\n\nconst cloneNode = (node: AdvancedFilterNode): AdvancedFilterNode => {\n if (isJoinNode(node)) {\n return {\n conditions: node.conditions.map(cloneNode),\n filterType: \"join\",\n type: node.type,\n };\n }\n\n return { ...node };\n};\n\nconst normalizeModel = (model: AdvancedFilterModel | null | unknown): AdvancedFilterNode | null => {\n if (!isRecord(model)) return null;\n\n if (isJoinNode(model)) {\n const conditions = model.conditions.flatMap((condition) => {\n const normalized = normalizeModel(condition);\n return normalized ? [normalized] : [];\n });\n\n if (!conditions.length) return null;\n return { conditions, filterType: \"join\", type: model.type === \"OR\" ? \"OR\" : \"AND\" };\n }\n\n if (isConditionNode(model)) {\n return { ...(model as AdvancedFilterCondition) };\n }\n\n return null;\n};\n\nconst toFiniteNumber = (value: number | null): number | null => {\n return typeof value === \"number\" && Number.isFinite(value) ? value : null;\n};\n\nconst isRegularFilterModel = (model: unknown): model is RegularFilterModel => {\n return isRecord(model) && !isJoinNode(model) && !isConditionNode(model);\n};\n\nconst isRegularMultiFilter = (\n condition: RegularFilterCondition | null | undefined,\n): condition is RegularFilterCondition & { filterModels: Array<RegularFilterCondition | null | undefined> } => {\n return condition?.filterType === \"multi\" && Array.isArray(condition.filterModels);\n};\n\nconst regularMultiFilterNameByConditionType: Record<string, string> = {\n number: \"agNumberColumnFilter\",\n set: \"agSetColumnFilter\",\n text: \"agTextColumnFilter\",\n};\n\nconst getColDefMultiFilterDefs = (colDef?: PvFilterPanelColDef): unknown[] => {\n if (colDef?.filter !== \"agMultiColumnFilter\") return [];\n const filterParams = colDef.filterParams as { filters?: unknown[] } | undefined;\n return Array.isArray(filterParams?.filters) ? filterParams.filters : [];\n};\n\nconst getColDefMultiFilterIndex = (colDef: PvFilterPanelColDef | undefined, condition: RegularFilterCondition) => {\n const filterDefs = getColDefMultiFilterDefs(colDef);\n const expectedFilter = condition.filterType ? regularMultiFilterNameByConditionType[condition.filterType] : undefined;\n if (!expectedFilter) return -1;\n\n return filterDefs.findIndex((filterDef) => {\n return isRecord(filterDef) && filterDef.filter === expectedFilter;\n });\n};\n\nconst createRegularMultiCondition = (\n colDef: PvFilterPanelColDef | undefined,\n condition: RegularFilterCondition,\n): RegularFilterCondition | null => {\n const filterDefs = getColDefMultiFilterDefs(colDef);\n if (!filterDefs.length) return null;\n\n const filterModels = Array<RegularFilterCondition | null>(filterDefs.length).fill(null);\n const index = getColDefMultiFilterIndex(colDef, condition);\n if (index < 0) return null;\n filterModels[index] = condition;\n return { filterModels, filterType: \"multi\" };\n};\n\nconst getRegularCondition = (model: unknown, colId: string): RegularFilterCondition | null => {\n if (!isRegularFilterModel(model)) return null;\n const condition = model[colId];\n return isRecord(condition) ? (condition as RegularFilterCondition) : null;\n};\n\nconst getRegularLeafConditions = (condition: RegularFilterCondition | null): RegularFilterCondition[] => {\n if (!condition) return [];\n if (!isRegularMultiFilter(condition)) return [condition];\n return condition.filterModels!.filter((filterModel): filterModel is RegularFilterCondition => isRecord(filterModel));\n};\n\nconst cloneRegularModel = (model: AdvancedFilterModel | null | unknown): RegularFilterModel => {\n return isRegularFilterModel(model) ? { ...model } : {};\n};\n\nconst cloneRegularCondition = (condition: RegularFilterCondition): RegularFilterCondition => {\n if (!isRegularMultiFilter(condition)) return { ...condition };\n return {\n ...condition,\n filterModels: condition.filterModels!.map((filterModel) => (filterModel ? { ...filterModel } : filterModel)),\n };\n};\n\nconst removeRegularColumnFilter = (\n model: AdvancedFilterModel | null | unknown,\n colId: string,\n): RegularFilterModel | null => {\n const nextModel = cloneRegularModel(model);\n delete nextModel[colId];\n return Object.keys(nextModel).length ? nextModel : null;\n};\n\nconst warnedRegularMultiFilterOverwrites = new Set<string>();\n\nconst warnRegularMultiFilterOverwrite = (colId: string, filterType: string | undefined) => {\n const key = `${colId}:${filterType ?? \"unknown\"}`;\n if (warnedRegularMultiFilterOverwrites.has(key)) return;\n console.warn(\n `PvFilterPanel: overwriting an occupied regular multi-filter slot for \"${colId}\" because the target slot was occupied or no empty slot was available.`,\n );\n warnedRegularMultiFilterOverwrites.add(key);\n};\n\nconst updateRegularColumnFilter = (\n model: AdvancedFilterModel | null,\n colId: string,\n condition: RegularFilterCondition | null,\n matchesCondition?: RegularFilterConditionMatcher,\n colDef?: PvFilterPanelColDef,\n): AdvancedFilterModel | null => {\n const existingCondition = getRegularCondition(model, colId);\n\n if (isRegularMultiFilter(existingCondition) && matchesCondition) {\n const nextModel = cloneRegularModel(model);\n const nextCondition = cloneRegularCondition(existingCondition);\n const filterModels = [...(nextCondition.filterModels ?? [])];\n const matchingIndexes = filterModels.flatMap((filterModel, index) =>\n filterModel && matchesCondition(filterModel) ? [index] : [],\n );\n\n if (!condition) {\n for (const index of matchingIndexes) filterModels[index] = null;\n if (filterModels.some(Boolean)) {\n nextModel[colId] = { ...nextCondition, filterModels };\n } else {\n delete nextModel[colId];\n }\n return Object.keys(nextModel).length ? (nextModel as unknown as AdvancedFilterModel) : null;\n }\n\n if (matchingIndexes.length) {\n const [firstIndex, ...extraIndexes] = matchingIndexes;\n filterModels[firstIndex] = condition;\n for (const index of extraIndexes) filterModels[index] = null;\n } else {\n const colDefIndex = getColDefMultiFilterIndex(colDef, condition);\n const emptyIndex = filterModels.findIndex((filterModel) => !filterModel);\n const hasMultiFilterDefs = getColDefMultiFilterDefs(colDef).length > 0;\n if (colDefIndex >= 0) {\n while (filterModels.length <= colDefIndex) filterModels.push(null);\n if (filterModels[colDefIndex]) warnRegularMultiFilterOverwrite(colId, condition.filterType);\n filterModels[colDefIndex] = condition;\n } else if (emptyIndex >= 0) {\n filterModels[emptyIndex] = condition;\n } else if (!hasMultiFilterDefs) {\n filterModels.push(condition);\n } else {\n const replacementIndex = Math.max(0, filterModels.length - 1);\n warnRegularMultiFilterOverwrite(colId, condition.filterType);\n filterModels[replacementIndex] = condition;\n }\n }\n\n nextModel[colId] = { ...nextCondition, filterModels };\n return nextModel as unknown as AdvancedFilterModel;\n }\n\n if (!condition) return removeRegularColumnFilter(model, colId) as AdvancedFilterModel | null;\n const nextModel = cloneRegularModel(model);\n nextModel[colId] = createRegularMultiCondition(colDef, condition) ?? condition;\n return nextModel as unknown as AdvancedFilterModel;\n};\n\nconst walkConditions = (model: AdvancedFilterNode | null, visit: (condition: AdvancedFilterCondition) => void) => {\n if (!model) return;\n\n if (isJoinNode(model)) {\n model.conditions.forEach((condition) => walkConditions(condition, visit));\n return;\n }\n\n visit(model);\n};\n\nconst nodeReferencesOnlyColumn = (model: AdvancedFilterNode, colId: string): boolean => {\n if (isJoinNode(model)) {\n return (\n model.conditions.length > 0 && model.conditions.every((condition) => nodeReferencesOnlyColumn(condition, colId))\n );\n }\n\n return model.colId === colId;\n};\n\nconst getOnlyReferencedColumn = (model: AdvancedFilterNode): string | null => {\n if (!isJoinNode(model)) return model.colId;\n\n const columnIds = new Set<string>();\n walkConditions(model, (condition) => columnIds.add(condition.colId));\n return columnIds.size === 1 ? [...columnIds][0] : null;\n};\n\nconst filterOutColumn = (model: AdvancedFilterNode | null, colId: string): AdvancedFilterNode | null => {\n if (!model) return null;\n if (nodeReferencesOnlyColumn(model, colId)) return null;\n if (!isJoinNode(model) || model.type !== \"AND\") return cloneNode(model);\n\n const conditions = model.conditions.flatMap((condition) =>\n nodeReferencesOnlyColumn(condition, colId) ? [] : [cloneNode(condition)],\n );\n\n if (!conditions.length) return null;\n if (conditions.length === 1) return conditions[0];\n return { conditions, filterType: model.filterType, type: model.type };\n};\n\nconst appendColumnFilter = (\n model: AdvancedFilterModel | null,\n colId: string,\n replacement: AdvancedFilterNode | null,\n): AdvancedFilterModel | null => {\n const base = filterOutColumn(normalizeModel(model), colId);\n if (!replacement) return asAdvancedFilterModel(base);\n if (!base) return asAdvancedFilterModel(replacement);\n\n if (isJoinNode(base) && base.type === \"AND\") {\n return asAdvancedFilterModel({ ...base, conditions: [...base.conditions, replacement] });\n }\n\n return asAdvancedFilterModel({\n conditions: [base, replacement],\n filterType: \"join\",\n type: \"AND\",\n });\n};\n\nconst addUniqueValue = (values: string[], value: string) => {\n if (!values.includes(value)) values.push(value);\n};\n\nconst isTextBooleanCondition = (condition: RegularFilterCondition | AdvancedFilterCondition) => {\n if (condition.filterType !== \"text\" || condition.type !== \"equals\" || condition.filter === undefined) return false;\n const stringValue = String(condition.filter);\n return stringValue === \"true\" || stringValue === \"false\";\n};\n\nconst isRegularBooleanCondition = (condition: RegularFilterCondition) => {\n return condition.filterType === \"boolean\" || isTextBooleanCondition(condition);\n};\n\nconst readRegularConditionIntoEntry = (condition: RegularFilterCondition, entry: PvFilterPanelModelIndexEntry) => {\n if (condition.filterType === \"set\" && Array.isArray(condition.values)) {\n condition.values.forEach((value) => addUniqueValue(entry.values, String(value)));\n return;\n }\n\n if (condition.filterType === \"text\" && condition.type === \"equals\" && condition.filter !== undefined) {\n const stringValue = String(condition.filter);\n if (stringValue === \"true\") entry.booleanValue = true;\n else if (stringValue === \"false\") entry.booleanValue = false;\n addUniqueValue(entry.values, stringValue);\n return;\n }\n\n if (condition.filterType === \"boolean\") {\n if (condition.type === \"true\" || condition.filter === true) entry.booleanValue = true;\n if (condition.type === \"false\" || condition.filter === false) entry.booleanValue = false;\n return;\n }\n\n if (condition.type === \"notBlank\") {\n entry.existsValue = true;\n return;\n }\n\n if (condition.filterType !== \"number\" || typeof condition.filter !== \"number\") return;\n if (condition.type === \"equals\") {\n entry.rangeValue = { max: condition.filter, min: condition.filter };\n }\n if (condition.type === \"inRange\") {\n entry.rangeValue = {\n max: typeof condition.filterTo === \"number\" ? condition.filterTo : null,\n min: condition.filter,\n };\n }\n if (condition.type === \"greaterThan\" || condition.type === \"greaterThanOrEqual\") {\n entry.rangeValue = { ...entry.rangeValue, min: condition.filter };\n }\n if (condition.type === \"lessThan\" || condition.type === \"lessThanOrEqual\") {\n entry.rangeValue = { ...entry.rangeValue, max: condition.filter };\n }\n};\n\nconst readAdvancedConditionIntoEntry = (condition: AdvancedFilterCondition, entry: PvFilterPanelModelIndexEntry) => {\n if (condition.type === \"notBlank\") {\n entry.existsValue = true;\n return;\n }\n\n if (condition.filterType === \"boolean\") {\n if (condition.type === \"true\" || condition.filter === true) entry.booleanValue = true;\n if (condition.type === \"false\" || condition.filter === false) entry.booleanValue = false;\n return;\n }\n\n if (condition.filterType === \"set\" && Array.isArray(condition.values)) {\n condition.values.forEach((value) => addUniqueValue(entry.values, String(value)));\n return;\n }\n\n if (condition.filterType === \"text\" && condition.type === \"equals\" && condition.filter !== undefined) {\n const stringValue = String(condition.filter);\n if (stringValue === \"true\") entry.booleanValue = true;\n else if (stringValue === \"false\") entry.booleanValue = false;\n addUniqueValue(entry.values, stringValue);\n return;\n }\n\n if (condition.filterType !== \"number\" || typeof condition.filter !== \"number\") return;\n if (condition.type === \"equals\") {\n entry.rangeValue = { max: condition.filter, min: condition.filter };\n }\n if (condition.type === \"greaterThan\" || condition.type === \"greaterThanOrEqual\") {\n entry.rangeValue = { ...entry.rangeValue, min: condition.filter };\n }\n if (condition.type === \"lessThan\" || condition.type === \"lessThanOrEqual\") {\n entry.rangeValue = { ...entry.rangeValue, max: condition.filter };\n }\n};\n\nexport const createFilterPanelModelIndex = (\n model: AdvancedFilterModel | null | undefined | unknown,\n modelType: PvFilterPanelFilterModelType = \"advanced\",\n): PvFilterPanelModelIndex => {\n const index: PvFilterPanelModelIndex = new Map();\n\n if (modelType === \"regular\") {\n if (!isRegularFilterModel(model)) return index;\n for (const [colId, condition] of Object.entries(model)) {\n const entry = createIndexEntry();\n getRegularLeafConditions(condition).forEach((leafCondition) =>\n readRegularConditionIntoEntry(leafCondition, entry),\n );\n if (\n entry.values.length ||\n entry.booleanValue !== null ||\n entry.existsValue ||\n entry.rangeValue.min !== null ||\n entry.rangeValue.max !== null\n ) {\n index.set(colId, entry);\n }\n }\n return index;\n }\n\n const normalizedModel = normalizeModel(model);\n if (!normalizedModel) return index;\n const panelOwnedNodes =\n isJoinNode(normalizedModel) && normalizedModel.type === \"AND\" ? normalizedModel.conditions : [normalizedModel];\n\n for (const node of panelOwnedNodes) {\n const colId = getOnlyReferencedColumn(node);\n if (!colId) continue;\n const entry = index.get(colId) ?? createIndexEntry();\n walkConditions(node, (condition) => {\n if (condition.colId === colId) readAdvancedConditionIntoEntry(condition, entry);\n });\n if (\n entry.values.length ||\n entry.booleanValue !== null ||\n entry.existsValue ||\n entry.rangeValue.min !== null ||\n entry.rangeValue.max !== null\n ) {\n index.set(colId, entry);\n }\n }\n\n return index;\n};\n\nexport const advancedFilterHasConditions = (\n model: AdvancedFilterModel | null | undefined | unknown,\n modelType: PvFilterPanelFilterModelType = \"advanced\",\n): boolean => {\n if (modelType === \"regular\") return isRegularFilterModel(model) && Object.keys(model).length > 0;\n return normalizeModel(model) !== null;\n};\n\nexport const getBooleanFilter = (\n model: AdvancedFilterModel | null | unknown,\n colId: string,\n modelType: PvFilterPanelFilterModelType = \"advanced\",\n): boolean | null => {\n return createFilterPanelModelIndex(model, modelType).get(colId)?.booleanValue ?? null;\n};\n\nexport const getExistsFilter = (\n model: AdvancedFilterModel | null | unknown,\n colId: string,\n modelType: PvFilterPanelFilterModelType = \"advanced\",\n): boolean => {\n return createFilterPanelModelIndex(model, modelType).get(colId)?.existsValue ?? false;\n};\n\nexport const getRangeFilter = (\n model: AdvancedFilterModel | null | unknown,\n colId: string,\n modelType: PvFilterPanelFilterModelType = \"advanced\",\n): PvFilterPanelRangeValue => {\n return createFilterPanelModelIndex(model, modelType).get(colId)?.rangeValue ?? { max: null, min: null };\n};\n\nexport const getAdvancedFilterTypeForDataType = (dataType?: string | null): PvAdvancedFilterColumnType => {\n if (\n dataType === \"currency\" ||\n dataType === \"formula\" ||\n dataType === \"integer\" ||\n dataType === \"number\" ||\n dataType === \"percent\"\n ) {\n return \"number\";\n }\n\n if (dataType === \"date\") return \"date\";\n return \"text\";\n};\n\nexport const getValueSelections = (\n model: AdvancedFilterModel | null | unknown,\n colId: string,\n modelType: PvFilterPanelFilterModelType = \"advanced\",\n): string[] => {\n return createFilterPanelModelIndex(model, modelType).get(colId)?.values ?? [];\n};\n\nexport const removeColumnFilter = (\n model: AdvancedFilterModel | null,\n colId: string,\n modelType: PvFilterPanelFilterModelType = \"advanced\",\n): AdvancedFilterModel | null => {\n if (modelType === \"regular\") return removeRegularColumnFilter(model, colId) as AdvancedFilterModel | null;\n return asAdvancedFilterModel(filterOutColumn(normalizeModel(model), colId));\n};\n\nexport const updateBooleanFilter = (\n model: AdvancedFilterModel | null,\n colId: string,\n value: boolean | null,\n modelType: PvFilterPanelFilterModelType = \"advanced\",\n advancedFilterType: \"boolean\" | \"text\" = \"boolean\",\n colDef?: PvFilterPanelColDef,\n): AdvancedFilterModel | null => {\n if (value === null) {\n if (modelType === \"regular\") {\n return updateRegularColumnFilter(model, colId, null, isRegularBooleanCondition, colDef);\n }\n return removeColumnFilter(model, colId, modelType);\n }\n\n if (modelType === \"regular\") {\n return updateRegularColumnFilter(\n model,\n colId,\n advancedFilterType === \"text\"\n ? {\n filter: String(value),\n filterType: \"text\",\n type: \"equals\",\n }\n : {\n filter: value,\n filterType: \"boolean\",\n type: value ? \"true\" : \"false\",\n },\n isRegularBooleanCondition,\n colDef,\n );\n }\n\n if (advancedFilterType === \"text\") {\n return appendColumnFilter(model, colId, {\n colId,\n filter: String(value),\n filterType: \"text\",\n type: \"equals\",\n });\n }\n\n return appendColumnFilter(model, colId, {\n colId,\n filterType: \"boolean\",\n type: value ? \"true\" : \"false\",\n });\n};\n\nexport const updateExistsFilter = (\n model: AdvancedFilterModel | null,\n colId: string,\n value: boolean,\n filterType: PvAdvancedFilterColumnType = \"text\",\n modelType: PvFilterPanelFilterModelType = \"advanced\",\n colDef?: PvFilterPanelColDef,\n): AdvancedFilterModel | null => {\n if (!value) {\n if (modelType === \"regular\") {\n return updateRegularColumnFilter(\n model,\n colId,\n null,\n (condition) => condition.filterType === filterType && condition.type === \"notBlank\",\n colDef,\n );\n }\n return removeColumnFilter(model, colId, modelType);\n }\n\n if (modelType === \"regular\") {\n return updateRegularColumnFilter(\n model,\n colId,\n {\n filterType,\n type: \"notBlank\",\n },\n (condition) => condition.filterType === filterType && condition.type === \"notBlank\",\n colDef,\n );\n }\n\n return appendColumnFilter(model, colId, {\n colId,\n filterType,\n type: \"notBlank\",\n });\n};\n\nexport const updateRangeFilter = (\n model: AdvancedFilterModel | null,\n colId: string,\n minValue: number | null,\n maxValue: number | null,\n modelType: PvFilterPanelFilterModelType = \"advanced\",\n colDef?: PvFilterPanelColDef,\n): AdvancedFilterModel | null => {\n const min = toFiniteNumber(minValue);\n const max = toFiniteNumber(maxValue);\n\n if (modelType === \"regular\") {\n if (min === null && max === null) {\n return updateRegularColumnFilter(model, colId, null, (condition) => condition.filterType === \"number\", colDef);\n }\n if (min !== null && max !== null) {\n return updateRegularColumnFilter(\n model,\n colId,\n {\n filter: min,\n filterTo: max,\n filterType: \"number\",\n type: \"inRange\",\n },\n (condition) => condition.filterType === \"number\",\n colDef,\n );\n }\n return updateRegularColumnFilter(\n model,\n colId,\n {\n filter: min ?? max,\n filterType: \"number\",\n type: min !== null ? \"greaterThanOrEqual\" : \"lessThanOrEqual\",\n },\n (condition) => condition.filterType === \"number\",\n colDef,\n );\n }\n\n const conditions: AdvancedFilterNode[] = [];\n\n if (min !== null) {\n conditions.push({ colId, filter: min, filterType: \"number\", type: \"greaterThanOrEqual\" });\n }\n\n if (max !== null) {\n conditions.push({ colId, filter: max, filterType: \"number\", type: \"lessThanOrEqual\" });\n }\n\n if (!conditions.length) return removeColumnFilter(model, colId);\n\n const replacement =\n conditions.length === 1 ? conditions[0] : ({ conditions, filterType: \"join\", type: \"AND\" } as AdvancedFilterJoin);\n return appendColumnFilter(model, colId, replacement);\n};\n\nexport const updateValueFilter = (\n model: AdvancedFilterModel | null,\n colId: string,\n values: string[],\n modelType: PvFilterPanelFilterModelType = \"advanced\",\n colDef?: PvFilterPanelColDef,\n): AdvancedFilterModel | null => {\n const uniqueValues = Array.from(new Set(values));\n\n if (modelType === \"regular\") {\n if (!uniqueValues.length) {\n return updateRegularColumnFilter(model, colId, null, (condition) => condition.filterType === \"set\", colDef);\n }\n return updateRegularColumnFilter(\n model,\n colId,\n {\n filterType: \"set\",\n values: uniqueValues,\n },\n (condition) => condition.filterType === \"set\",\n colDef,\n );\n }\n\n const conditions: AdvancedFilterNode[] = uniqueValues.map((value) => ({\n colId,\n filter: value,\n filterType: \"text\",\n type: \"equals\",\n }));\n\n if (!conditions.length) return removeColumnFilter(model, colId);\n\n const replacement =\n conditions.length === 1 ? conditions[0] : ({ conditions, filterType: \"join\", type: \"OR\" } as AdvancedFilterJoin);\n return appendColumnFilter(model, colId, replacement);\n};\n","import type { PvFilterPanelOption } from \"./types\";\n\nexport interface PvFilterPanelScopedValue {\n field?: string;\n pairs: Array<{ field: string; value: string }>;\n value: string;\n}\n\nconst FILTER_PANEL_SCOPED_VALUE_PREFIX = \"__pv_filter_panel_scoped_value__\";\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => {\n return typeof value === \"object\" && value !== null;\n};\n\nconst parseScopedPayload = (payload: string): Array<{ field: string; value: string }> => {\n try {\n const parsed = JSON.parse(decodeURIComponent(payload)) as unknown;\n if (!Array.isArray(parsed)) return [];\n return parsed.flatMap((entry) => {\n if (!Array.isArray(entry) || entry.length < 2) return [];\n const [field, fieldValue] = entry;\n return typeof field === \"string\" && typeof fieldValue === \"string\" ? [{ field, value: fieldValue }] : [];\n });\n } catch {\n return [];\n }\n};\n\nconst parseLegacyScopedValue = (value: string): PvFilterPanelScopedValue | null => {\n if (!value.startsWith(\"__\")) return null;\n const parts = value.slice(2).split(\"__\");\n if (parts.length < 2 || !parts[0] || !parts[1]) return null;\n const pairs = [{ field: parts[0], value: parts[1] }];\n return { field: pairs[0].field, pairs, value: pairs[0].value };\n};\n\nexport const parseFilterPanelScopedValue = (value: string | null | undefined): PvFilterPanelScopedValue | null => {\n if (value == null) return null;\n if (!value.startsWith(FILTER_PANEL_SCOPED_VALUE_PREFIX)) return parseLegacyScopedValue(value) ?? { pairs: [], value };\n\n const pairs = parseScopedPayload(value.slice(FILTER_PANEL_SCOPED_VALUE_PREFIX.length));\n\n return {\n field: pairs[0]?.field,\n pairs,\n value: pairs[0]?.value ?? value,\n };\n};\n\nexport const createFilterPanelScopedValue = (field: string, value: string): string =>\n `${FILTER_PANEL_SCOPED_VALUE_PREFIX}${encodeURIComponent(JSON.stringify([[field, value]]))}`;\n\nexport const getFilterPanelOptionRawValue = (option: PvFilterPanelOption | null | undefined): string | null => {\n if (!option) return null;\n if (option.rawValue !== null && option.rawValue !== undefined) return String(option.rawValue);\n if (isRecord(option.metadata) && option.metadata.rawValue !== null && option.metadata.rawValue !== undefined) {\n return String(option.metadata.rawValue);\n }\n if (option.matchedValue !== null && option.matchedValue !== undefined) return String(option.matchedValue);\n return parseFilterPanelScopedValue(option.value)?.value ?? option.value;\n};\n\nexport const getFilterPanelOptionField = (\n option: PvFilterPanelOption | null | undefined,\n fallbackField: string,\n): string => {\n if (option?.field) return option.field;\n if (option?.colField) return option.colField;\n return parseFilterPanelScopedValue(option?.value)?.field ?? fallbackField;\n};\n\nexport const flattenFilterPanelOptions = (options: PvFilterPanelOption[]): PvFilterPanelOption[] => {\n return options.flatMap((option) => [\n option,\n ...(option.children?.length ? flattenFilterPanelOptions(option.children) : []),\n ]);\n};\n\nexport const filterPanelOptionMatchesRawValue = (\n option: PvFilterPanelOption,\n field: string,\n rawValue: string,\n fallbackField: string,\n): boolean => {\n return (\n getFilterPanelOptionField(option, fallbackField) === field && getFilterPanelOptionRawValue(option) === rawValue\n );\n};\n","import type { AdvancedFilterModel } from \"ag-grid-enterprise\";\nimport type { MultiSelectState, SelectionNode } from \"@/types\";\nimport {\n createFilterPanelScopedValue,\n getFilterPanelOptionField,\n getFilterPanelOptionRawValue,\n parseFilterPanelScopedValue,\n} from \"./filterOptionValue\";\nimport type { PvFilterPanelAggregateFieldHierarchy, PvFilterPanelColDef, PvFilterPanelOption } from \"./types\";\n\ninterface LooseAdvancedFilterNode {\n colId?: string;\n conditions?: AdvancedFilterModel[];\n filter?: boolean | number | string | null;\n filterType?: string;\n type?: string;\n}\n\nexport interface PvFilterPanelAggregateSelectionStatus {\n indeterminate: boolean;\n selected: boolean;\n}\n\nexport interface PvFilterPanelAggregateFieldValue {\n field?: string;\n value: string;\n}\n\nconst isAdvancedFilterJoin = (model: AdvancedFilterModel | null | undefined): model is AdvancedFilterModel => {\n const node = model as LooseAdvancedFilterNode | null | undefined;\n return node?.filterType === \"join\" && Array.isArray(node.conditions);\n};\n\nconst cloneAdvancedFilterNode = (model: AdvancedFilterModel): AdvancedFilterModel => {\n const node = model as LooseAdvancedFilterNode;\n if (!isAdvancedFilterJoin(model)) return { ...node } as AdvancedFilterModel;\n\n return {\n ...node,\n conditions: (node.conditions ?? []).map(cloneAdvancedFilterNode),\n } as AdvancedFilterModel;\n};\n\nexport const removeFilterPanelAggregateFieldsFromModel = (\n model: AdvancedFilterModel | null | undefined,\n fields: string[] | Set<string>,\n): AdvancedFilterModel | null => {\n if (!model) return null;\n const fieldSet = fields instanceof Set ? fields : new Set(fields);\n if (!fieldSet.size) return cloneAdvancedFilterNode(model);\n\n if (!isAdvancedFilterJoin(model)) {\n const node = model as LooseAdvancedFilterNode;\n return typeof node.colId === \"string\" && fieldSet.has(node.colId) ? null : cloneAdvancedFilterNode(model);\n }\n\n const node = model as LooseAdvancedFilterNode;\n const conditions = (node.conditions ?? [])\n .map((condition) => removeFilterPanelAggregateFieldsFromModel(condition, fieldSet))\n .filter((condition): condition is AdvancedFilterModel => Boolean(condition));\n\n if (!conditions.length) return null;\n if (conditions.length === 1) return conditions[0];\n\n return {\n ...node,\n conditions,\n } as AdvancedFilterModel;\n};\n\nexport const flattenFilterPanelAggregateFieldHierarchy = (\n hierarchy: PvFilterPanelAggregateFieldHierarchy | undefined,\n): string[] => {\n if (!hierarchy) return [];\n return [hierarchy.field, ...(hierarchy.children ?? []).flatMap(flattenFilterPanelAggregateFieldHierarchy)];\n};\n\nexport const getFilterPanelAggregateLeafFields = (\n hierarchy: PvFilterPanelAggregateFieldHierarchy | undefined,\n): string[] => {\n if (!hierarchy) return [];\n if (!hierarchy.children?.length) return [hierarchy.field];\n return hierarchy.children.flatMap(getFilterPanelAggregateLeafFields);\n};\n\nexport const getFilterPanelAggregateFields = (colDef: PvFilterPanelColDef | null | undefined): string[] => {\n const context = colDef?.context ?? {};\n return context.aggregateFieldHierarchy\n ? flattenFilterPanelAggregateFieldHierarchy(context.aggregateFieldHierarchy)\n : (context.aggregateFields ?? []);\n};\n\nexport const getFilterPanelAggregateRootField = (\n colDef: PvFilterPanelColDef | null | undefined,\n): string | undefined => {\n const context = colDef?.context ?? {};\n if (context.aggregateFieldHierarchy) return context.aggregateFieldHierarchy.field;\n return context.aggregateFields?.[context.aggregateFields.length - 1];\n};\n\nexport const isFilterPanelAggregateColDef = (colDef: PvFilterPanelColDef | null | undefined): boolean => {\n return getFilterPanelAggregateFields(colDef).length > 0;\n};\n\nexport const findFilterPanelOptionByValue = (\n options: (PvFilterPanelOption | null)[] | undefined,\n value: string,\n): PvFilterPanelOption | undefined => {\n for (const option of options ?? []) {\n if (!option) continue;\n if (option.value === value) return option;\n const childMatch = findFilterPanelOptionByValue(option.children, value);\n if (childMatch) return childMatch;\n }\n return undefined;\n};\n\nconst findFilterPanelOptionPathByValue = (\n options: (PvFilterPanelOption | null)[] | undefined,\n value: string,\n path: PvFilterPanelOption[] = [],\n): PvFilterPanelOption[] | undefined => {\n for (const option of options ?? []) {\n if (!option) continue;\n const nextPath = [...path, option];\n if (option.value === value) return nextPath;\n const childPath = findFilterPanelOptionPathByValue(option.children, value, nextPath);\n if (childPath) return childPath;\n }\n return undefined;\n};\n\nexport const getFilterPanelAggregateFieldValue = (\n optionId: string,\n options?: (PvFilterPanelOption | null)[],\n): PvFilterPanelAggregateFieldValue => {\n const option = findFilterPanelOptionByValue(options, optionId);\n const optionField = option ? getFilterPanelOptionField(option, \"\") : undefined;\n const optionRawValue = option ? getFilterPanelOptionRawValue(option) : null;\n if (optionField && optionRawValue !== null) return { field: optionField, value: optionRawValue };\n\n const parsed = parseFilterPanelScopedValue(optionId);\n return {\n field: parsed?.field,\n value: parsed?.value ?? optionId,\n };\n};\n\nexport const findFilterPanelAggregateOptionId = (\n options: (PvFilterPanelOption | null)[] | undefined,\n field: string,\n rawValue: string,\n): string => {\n const matches = (option: PvFilterPanelOption | null): string | undefined => {\n if (!option) return undefined;\n const optionField = getFilterPanelOptionField(option, \"\");\n const optionRawValue = getFilterPanelOptionRawValue(option);\n if (optionField === field && optionRawValue === rawValue) return option.value;\n\n for (const child of option.children ?? []) {\n const childMatch = matches(child);\n if (childMatch) return childMatch;\n }\n return undefined;\n };\n\n for (const option of options ?? []) {\n const match = matches(option);\n if (match) return match;\n }\n\n return `__${field}__${rawValue}`;\n};\n\nconst collectDeselectedSelectionNodes = (nodes: SelectionNode[] | undefined): SelectionNode[] => {\n return (nodes ?? []).flatMap((node) => [\n ...(node.state === \"deselected\" ? [node] : []),\n ...collectDeselectedSelectionNodes(node.children),\n ]);\n};\n\nconst buildFilterPanelAggregateNodeCondition = (\n node: SelectionNode,\n options?: (PvFilterPanelOption | null)[],\n): AdvancedFilterModel | null => {\n if (node.state !== \"selected\") return null;\n\n const { field, value } = getFilterPanelAggregateFieldValue(node.id, options);\n if (!field) return null;\n\n const conditions: AdvancedFilterModel[] = [\n {\n colId: field,\n filter: value,\n filterType: \"text\",\n type: \"equals\",\n } as AdvancedFilterModel,\n ];\n\n for (const child of collectDeselectedSelectionNodes(node.children)) {\n const childValue = getFilterPanelAggregateFieldValue(child.id, options);\n if (!childValue.field) continue;\n conditions.push({\n colId: childValue.field,\n filter: childValue.value,\n filterType: \"text\",\n type: \"notEqual\",\n } as AdvancedFilterModel);\n }\n\n return conditions.length === 1\n ? conditions[0]\n : ({ conditions, filterType: \"join\", type: \"AND\" } as AdvancedFilterModel);\n};\n\nexport const buildFilterPanelAggregateModelFromSelectionState = (params: {\n baseModel: AdvancedFilterModel | null | undefined;\n colDef: PvFilterPanelColDef;\n options?: (PvFilterPanelOption | null)[];\n state: MultiSelectState;\n}): AdvancedFilterModel | null => {\n const aggregateFields = getFilterPanelAggregateFields(params.colDef);\n const baseModel = removeFilterPanelAggregateFieldsFromModel(params.baseModel, aggregateFields);\n if (!aggregateFields.length) return baseModel;\n\n const conditions = params.state\n .map((node) => buildFilterPanelAggregateNodeCondition(node, params.options))\n .filter((condition): condition is AdvancedFilterModel => Boolean(condition));\n\n if (!conditions.length) return baseModel;\n\n const aggregateCondition: AdvancedFilterModel =\n conditions.length === 1 ? conditions[0] : ({ conditions, filterType: \"join\", type: \"OR\" } as AdvancedFilterModel);\n\n if (!baseModel) return aggregateCondition;\n return { conditions: [baseModel, aggregateCondition], filterType: \"join\", type: \"AND\" } as AdvancedFilterModel;\n};\n\nconst getFilterPanelAggregateColumnConditions = (\n model: AdvancedFilterModel | null | undefined,\n fields: Set<string>,\n leafFields: Set<string>,\n): Array<{ colId: string; filter?: string; parentEquals?: { colId: string; filter?: string }; type?: string }> => {\n if (!model) return [];\n const node = model as LooseAdvancedFilterNode;\n\n if (isAdvancedFilterJoin(model)) {\n const conditions = node.conditions ?? [];\n if (node.type === \"AND\") {\n const directEquals = conditions.find((condition) => {\n const conditionNode = condition as LooseAdvancedFilterNode;\n return (\n conditionNode.filterType !== \"join\" &&\n typeof conditionNode.colId === \"string\" &&\n fields.has(conditionNode.colId) &&\n conditionNode.type === \"equals\" &&\n !leafFields.has(conditionNode.colId)\n );\n }) as LooseAdvancedFilterNode | undefined;\n\n return conditions.flatMap((condition) =>\n getFilterPanelAggregateColumnConditions(condition, fields, leafFields).map((childCondition) => ({\n ...childCondition,\n parentEquals:\n childCondition.parentEquals ||\n (directEquals?.colId\n ? {\n colId: directEquals.colId,\n filter: directEquals.filter == null ? undefined : String(directEquals.filter),\n }\n : undefined),\n })),\n );\n }\n\n return conditions.flatMap((condition) => getFilterPanelAggregateColumnConditions(condition, fields, leafFields));\n }\n\n if (node.colId && fields.has(node.colId)) {\n return [\n {\n colId: node.colId,\n filter: node.filter == null ? undefined : String(node.filter),\n type: node.type,\n },\n ];\n }\n\n return [];\n};\n\nexport const seedFilterPanelAggregateSelectionState = (params: {\n colDef: PvFilterPanelColDef;\n model: AdvancedFilterModel | null | undefined;\n options?: (PvFilterPanelOption | null)[];\n}): MultiSelectState => {\n const aggregateFields = getFilterPanelAggregateFields(params.colDef);\n if (!aggregateFields.length) return [];\n\n const leafFields = new Set(getFilterPanelAggregateLeafFields(params.colDef.context?.aggregateFieldHierarchy));\n const rootField = getFilterPanelAggregateRootField(params.colDef);\n const conditions = getFilterPanelAggregateColumnConditions(params.model, new Set(aggregateFields), leafFields);\n const nodeMap = new Map<string, SelectionNode>();\n\n for (const condition of conditions) {\n if (!condition.filter) continue;\n const optionId = findFilterPanelAggregateOptionId(params.options, condition.colId, String(condition.filter));\n\n if (condition.type === \"equals\") {\n const existing = nodeMap.get(optionId);\n nodeMap.set(optionId, { id: optionId, state: \"selected\", children: existing?.children });\n continue;\n }\n\n if (condition.type === \"notEqual\" && condition.parentEquals?.filter && rootField) {\n const parentId = findFilterPanelAggregateOptionId(\n params.options,\n condition.parentEquals.colId,\n String(condition.parentEquals.filter),\n );\n const existing = nodeMap.get(parentId) ?? { children: [], id: parentId, state: \"selected\" as const };\n existing.children = [...(existing.children ?? []), { id: optionId, state: \"deselected\" as const }];\n nodeMap.set(parentId, existing);\n }\n }\n\n return [...nodeMap.values()];\n};\n\nexport const getFilterPanelAggregateSelectedValuesByField = (params: {\n colDef: PvFilterPanelColDef;\n model: AdvancedFilterModel | null | undefined;\n options?: (PvFilterPanelOption | null)[];\n}): Map<string, string[]> => {\n const selectedValuesByField = new Map<string, string[]>();\n const aggregateFields = getFilterPanelAggregateFields(params.colDef);\n if (!aggregateFields.length) return selectedValuesByField;\n\n const conditions = getFilterPanelAggregateColumnConditions(\n params.model,\n new Set(aggregateFields),\n new Set(getFilterPanelAggregateLeafFields(params.colDef.context?.aggregateFieldHierarchy)),\n );\n\n for (const condition of conditions) {\n if (condition.type !== \"equals\" || !condition.filter) continue;\n const values = selectedValuesByField.get(condition.colId) ?? [];\n if (!values.includes(condition.filter)) values.push(condition.filter);\n selectedValuesByField.set(condition.colId, values);\n }\n\n return selectedValuesByField;\n};\n\nconst cloneSelectionState = (state: MultiSelectState): MultiSelectState =>\n state.map((node) => ({\n ...node,\n children: node.children?.map((child) => ({\n ...child,\n children: child.children ? cloneSelectionState(child.children) : undefined,\n })),\n }));\n\nconst removeSelectionNodeById = (state: MultiSelectState, id: string): MultiSelectState => {\n return state.flatMap((node) => {\n if (node.id === id) return [];\n const children = node.children ? removeSelectionNodeById(node.children, id) : undefined;\n return [{ ...node, children: children?.length ? children : undefined }];\n });\n};\n\nconst getSelectionNode = (state: MultiSelectState, id: string): SelectionNode | undefined => {\n for (const node of state) {\n if (node.id === id) return node;\n const childMatch = node.children ? getSelectionNode(node.children, id) : undefined;\n if (childMatch) return childMatch;\n }\n return undefined;\n};\n\nconst hasAggregateChildren = (option: PvFilterPanelOption) => {\n return Boolean(option.children?.length) || (option.totalChildCount ?? 0) > 0;\n};\n\nconst upsertSelectionNode = (state: MultiSelectState, node: SelectionNode): MultiSelectState => {\n const withoutExisting = removeSelectionNodeById(state, node.id);\n return [...withoutExisting, node];\n};\n\nconst collectDescendantOptionIds = (option: PvFilterPanelOption): string[] => {\n return (option.children ?? []).flatMap((child) => [child.value, ...collectDescendantOptionIds(child)]);\n};\n\nconst removeDescendantSelectionNodes = (state: MultiSelectState, option: PvFilterPanelOption): MultiSelectState => {\n return collectDescendantOptionIds(option).reduce(\n (nextState, descendantId) => removeSelectionNodeById(nextState, descendantId),\n state,\n );\n};\n\nconst removeSelectionNodeAndDescendants = (state: MultiSelectState, option: PvFilterPanelOption): MultiSelectState => {\n return [option.value, ...collectDescendantOptionIds(option)].reduce(\n (nextState, descendantId) => removeSelectionNodeById(nextState, descendantId),\n state,\n );\n};\n\nconst getNearestSelectedAncestor = (\n state: MultiSelectState,\n option: PvFilterPanelOption,\n options?: (PvFilterPanelOption | null)[],\n): SelectionNode | undefined => {\n const path = findFilterPanelOptionPathByValue(options, option.value) ?? [];\n const ancestors = path.slice(0, -1).reverse();\n\n for (const ancestor of ancestors) {\n const selectedAncestor = getSelectionNode(state, ancestor.value);\n if (selectedAncestor?.state === \"selected\") return selectedAncestor;\n }\n\n return undefined;\n};\n\nexport const updateFilterPanelAggregateSelectionState = (params: {\n checked: boolean;\n option: PvFilterPanelOption;\n options?: (PvFilterPanelOption | null)[];\n state: MultiSelectState;\n}): MultiSelectState => {\n const nextState = cloneSelectionState(params.state);\n const selectedAncestor = getNearestSelectedAncestor(nextState, params.option, params.options);\n\n if (selectedAncestor) {\n const existingDeselectedChildren = selectedAncestor.children ?? [];\n selectedAncestor.children = params.checked\n ? removeSelectionNodeAndDescendants(existingDeselectedChildren, params.option)\n : [\n ...removeSelectionNodeAndDescendants(existingDeselectedChildren, params.option),\n { id: params.option.value, state: \"deselected\" as const },\n ];\n if (!selectedAncestor.children.length) delete selectedAncestor.children;\n return nextState;\n }\n\n if (hasAggregateChildren(params.option)) {\n return params.checked\n ? upsertSelectionNode(removeDescendantSelectionNodes(nextState, params.option), {\n id: params.option.value,\n state: \"selected\",\n })\n : removeSelectionNodeById(nextState, params.option.value);\n }\n\n return params.checked\n ? upsertSelectionNode(nextState, { id: params.option.value, state: \"selected\" })\n : removeSelectionNodeById(nextState, params.option.value);\n};\n\nconst createSelectionNodeMap = (state: MultiSelectState) => {\n const nodeMap = new Map<string, SelectionNode>();\n\n const addNodes = (nodes: SelectionNode[] | undefined) => {\n for (const node of nodes ?? []) {\n nodeMap.set(node.id, node);\n addNodes(node.children);\n }\n };\n\n addNodes(state);\n return nodeMap;\n};\n\nexport const createFilterPanelAggregateSelectionStatusMap = (params: {\n options?: (PvFilterPanelOption | null)[];\n state: MultiSelectState;\n}): Map<string, PvFilterPanelAggregateSelectionStatus> => {\n const nodeMap = createSelectionNodeMap(params.state);\n const statusMap = new Map<string, PvFilterPanelAggregateSelectionStatus>();\n\n const visitOption = (\n option: PvFilterPanelOption,\n inheritedSelected: boolean,\n ): PvFilterPanelAggregateSelectionStatus => {\n const directNode = nodeMap.get(option.value);\n const selected = directNode?.state === \"selected\" || (inheritedSelected && directNode?.state !== \"deselected\");\n\n const childStatuses: PvFilterPanelAggregateSelectionStatus[] = (option.children ?? []).map((child) =>\n visitOption(child, selected),\n );\n const hasSelectedChild = childStatuses.some((status) => status.selected || status.indeterminate);\n const hasUnselectedChild = childStatuses.some((status) => !status.selected || status.indeterminate);\n const hasDeselectedChildren = collectDeselectedSelectionNodes(directNode?.children).length > 0;\n const status: PvFilterPanelAggregateSelectionStatus = {\n indeterminate: hasDeselectedChildren || (!selected && hasSelectedChild) || (selected && hasUnselectedChild),\n selected,\n };\n\n statusMap.set(option.value, status);\n return status;\n };\n\n for (const option of params.options ?? []) {\n if (option) visitOption(option, false);\n }\n\n return statusMap;\n};\n\nexport const getFilterPanelAggregateOptionSelectionStatus = (params: {\n option: PvFilterPanelOption;\n options?: (PvFilterPanelOption | null)[];\n state: MultiSelectState;\n}): PvFilterPanelAggregateSelectionStatus => {\n return (\n createFilterPanelAggregateSelectionStatusMap(params).get(params.option.value) ??\n createFilterPanelAggregateSelectionStatusMap({ options: [params.option], state: params.state }).get(\n params.option.value,\n ) ?? {\n indeterminate: false,\n selected: false,\n }\n );\n};\n\nexport const getFilterPanelAggregateSelectionOptions = (params: {\n options?: (PvFilterPanelOption | null)[];\n state: MultiSelectState;\n}): PvFilterPanelOption[] => {\n return params.state.flatMap((node) => {\n if (node.state !== \"selected\") return [];\n const option = findFilterPanelOptionByValue(params.options, node.id);\n if (option) return [option];\n\n const { field, value } = getFilterPanelAggregateFieldValue(node.id, params.options);\n return [\n {\n colField: field,\n label: value,\n metadata: { rawValue: value },\n value: field ? createFilterPanelScopedValue(field, value) : node.id,\n },\n ];\n });\n};\n\nexport const getFilterPanelAggregateSelectionCount = (state: MultiSelectState): number => {\n return state.filter((node) => node.state === \"selected\").length;\n};\n","export type PvFilterPanelDisplayResultCount = number | string;\nexport type FilterPanelDisplayResultCount = PvFilterPanelDisplayResultCount;\n\ninterface FilterOptionDisplaySource {\n label?: string;\n metadata?: unknown;\n rawValue?: boolean | number | string | null;\n resultCount?: unknown;\n totalChildCount?: unknown;\n value: string;\n}\n\ninterface FilterOptionColDefLike {\n context?: {\n filterValueFormatter?: ((params: never) => string) | string | null;\n metadataDisplayFields?: string[];\n } | null;\n valueFormatter?: ((params: never) => string) | string | null;\n}\n\nconst RESULT_COUNT_METADATA_KEYS = [\"totalCount\", \"total_count\", \"resultCount\", \"result_count\", \"row_count\", \"count\"];\n\nconst compactNumberFormatter = new Intl.NumberFormat(\"en-US\", {\n maximumFractionDigits: 1,\n notation: \"compact\",\n});\n\nconst isRecord = (value: unknown): value is Record<string, unknown> => {\n return typeof value === \"object\" && value !== null;\n};\n\nconst formatResultCount = (value: unknown): PvFilterPanelDisplayResultCount | undefined => {\n if (typeof value === \"number\" && Number.isFinite(value)) {\n return compactNumberFormatter.format(value);\n }\n\n if (typeof value === \"string\") {\n const trimmedValue = value.trim();\n if (!trimmedValue) return undefined;\n\n const parsed = Number(trimmedValue);\n if (Number.isFinite(parsed)) return compactNumberFormatter.format(parsed);\n return value;\n }\n\n return undefined;\n};\n\nconst getFractionDigits = (dataType?: string | null, valueDecimals?: number | null): number => {\n if (valueDecimals !== null && valueDecimals !== undefined) return valueDecimals;\n if (dataType === \"currency\" || dataType === \"integer\" || dataType === \"percent\") return 0;\n return 2;\n};\n\nexport const formatFilterPanelScalarValue = (\n value: number,\n options: { dataType?: string | null; valueDecimals?: number | null } = {},\n): string => {\n const fractionDigits = getFractionDigits(options.dataType, options.valueDecimals);\n\n if (options.dataType === \"currency\") {\n return new Intl.NumberFormat(\"en-US\", {\n currency: \"USD\",\n maximumFractionDigits: fractionDigits,\n minimumFractionDigits: fractionDigits,\n style: \"currency\",\n }).format(value);\n }\n\n const formattedNumber = new Intl.NumberFormat(\"en-US\", {\n maximumFractionDigits: fractionDigits,\n minimumFractionDigits: fractionDigits,\n }).format(value);\n\n return options.dataType === \"percent\" ? `${formattedNumber}%` : formattedNumber;\n};\n\nexport const formatFilterPanelRangeValue = (\n min: number | null,\n max: number | null,\n options: { dataType?: string | null; valueDecimals?: number | null } = {},\n): string => {\n if (min !== null && max !== null) {\n return `${formatFilterPanelScalarValue(min, options)}–${formatFilterPanelScalarValue(max, options)}`;\n }\n\n if (min !== null) return `${formatFilterPanelScalarValue(min, options)}+`;\n if (max !== null) return `≤ ${formatFilterPanelScalarValue(max, options)}`;\n return \"\";\n};\n\nconst formatWithColDef = (option: FilterOptionDisplaySource, colDef?: FilterOptionColDefLike) => {\n const formatter =\n typeof colDef?.context?.filterValueFormatter === \"function\"\n ? colDef.context.filterValueFormatter\n : typeof colDef?.valueFormatter === \"function\"\n ? colDef.valueFormatter\n : null;\n\n if (!formatter) return null;\n\n try {\n const formatterValue =\n option.rawValue !== null && option.rawValue !== undefined\n ? option.rawValue\n : isRecord(option.metadata) && option.metadata.rawValue !== null && option.metadata.rawValue !== undefined\n ? option.metadata.rawValue\n : option.value;\n return formatter({ context: option.metadata, value: formatterValue } as never);\n } catch {\n return null;\n }\n};\n\nconst getMetadataLabel = (option: FilterOptionDisplaySource, colDef?: FilterOptionColDefLike) => {\n const metadata = option.metadata;\n if (!isRecord(metadata)) return null;\n\n for (const field of colDef?.context?.metadataDisplayFields ?? []) {\n const value = metadata[field];\n if (value !== null && value !== undefined && String(value).trim()) return String(value);\n }\n\n return null;\n};\n\nexport const getFilterOptionLabel = (option: FilterOptionDisplaySource, colDef?: FilterOptionColDefLike) => {\n return option.label || getMetadataLabel(option, colDef) || formatWithColDef(option, colDef) || option.value;\n};\n\nexport const getFilterOptionResultCount = (option: FilterOptionDisplaySource | null | undefined) => {\n const directResultCount = formatResultCount(option?.resultCount);\n if (directResultCount !== undefined) return directResultCount;\n\n const metadata = option?.metadata;\n if (isRecord(metadata)) {\n for (const key of RESULT_COUNT_METADATA_KEYS) {\n const resultCount = formatResultCount(metadata[key]);\n if (resultCount !== undefined) return resultCount;\n }\n }\n\n return formatResultCount(option?.totalChildCount);\n};\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, ref, useAttrs, useId, watch } from \"vue\";\nimport type { PropType } from \"vue\";\n\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport type { PvRangeProps, PvRangeValue } from \"./types\";\n\ntype RangeInputName = \"min\" | \"max\";\n\ndefineOptions({ inheritAttrs: false });\n\nconst DEFAULT_MIN = 0;\nconst DEFAULT_MAX = 100;\n\nconst props = withDefaults(defineProps<PvRangeProps>(), {\n allowMinMaxEqual: true,\n alwaysEditMin: false,\n color: \"single\",\n dataType: null,\n disabled: false,\n label: \"Range\",\n max: null,\n maxLabel: \"Max\",\n min: null,\n minLabel: \"Min\",\n mode: \"single\",\n showBoundLabels: false,\n showClear: true,\n showInputs: true,\n showValueTooltips: true,\n size: \"md\",\n step: null,\n valueDecimals: null,\n});\n\nconst modelValue = defineModel<number>({ default: 0, type: Number });\nconst rangeValue = defineModel<PvRangeValue>(\"rangeValue\", {\n default: () => ({ max: null, min: null }),\n type: Object as PropType<PvRangeValue>,\n});\n\nconst attrs = useAttrs();\nconst id = useId();\nconst maxInputId = `${id}-max`;\nconst minInputId = `${id}-min`;\nconst maxText = ref(\"\");\nconst minText = ref(\"\");\nconst activeHandle = ref<RangeInputName | null>(null);\nconst focusedInput = ref<RangeInputName | null>(null);\nconst isSingleHandleActive = ref(false);\nconst sliderRef = ref<HTMLElement | null>(null);\n\nlet removePointerListeners: (() => void) | null = null;\nlet removeSinglePointerListeners: (() => void) | null = null;\n\nconst isFiniteNumber = (value: unknown): value is number => typeof value === \"number\" && Number.isFinite(value);\nconst toFiniteNumber = (value: unknown): number | null => (isFiniteNumber(value) ? value : null);\n\nconst parseNumber = (value: string): number | null => {\n const textValue = value.trim();\n if (textValue === \"\") return null;\n\n const parsed = Number(textValue.replace(/[^0-9.\\-]/g, \"\"));\n return Number.isFinite(parsed) ? parsed : null;\n};\n\nconst getDefaultDecimals = (dataType?: string | null): number | null => {\n if (dataType === \"currency\" || dataType === \"integer\" || dataType === \"percent\") return 0;\n return null;\n};\n\nconst getFractionDigits = () => {\n if (props.valueDecimals !== null && props.valueDecimals !== undefined) return Math.max(0, props.valueDecimals);\n const defaultDecimals = getDefaultDecimals(props.dataType);\n if (defaultDecimals !== null) return defaultDecimals;\n return 2;\n};\n\nconst formatInputValue = (value: number): string => String(value);\n\nconst formatDisplayValue = (value: number): string => {\n const fractionDigits = getFractionDigits();\n\n const formattedNumber = new Intl.NumberFormat(\"en-US\", {\n maximumFractionDigits: fractionDigits,\n minimumFractionDigits: 0,\n }).format(value);\n\n if (props.dataType === \"currency\") return `$${formattedNumber}`;\n return props.dataType === \"percent\" ? `${formattedNumber}%` : formattedNumber;\n};\n\nconst finiteStep = computed(() => toFiniteNumber(props.step));\nconst dualNumericStep = computed(() => (finiteStep.value !== null && finiteStep.value > 0 ? finiteStep.value : 0));\nconst dualInputStep = computed(() => (dualNumericStep.value > 0 ? String(dualNumericStep.value) : \"any\"));\nconst singleInputStep = computed(() => {\n if (finiteStep.value === null) return \"1\";\n return finiteStep.value > 0 ? String(finiteStep.value) : \"any\";\n});\nconst rangeTrackColor = computed(() =>\n props.color === \"multiple\" ? \"var(--color-data-viz-3, #ff7a4e)\" : \"var(--color-border, #e3e7ea)\",\n);\n\nconst singleBounds = computed(() => {\n const propMin = toFiniteNumber(props.min) ?? DEFAULT_MIN;\n const propMax = toFiniteNumber(props.max) ?? DEFAULT_MAX;\n\n if (propMin > propMax) return { max: propMin, min: propMax };\n if (propMin === propMax) return { max: propMin + 1, min: propMin };\n return { max: propMax, min: propMin };\n});\n\nconst singleValue = computed(() => toFiniteNumber(modelValue.value) ?? singleBounds.value.min);\nconst singlePercent = computed(() => {\n const { max, min } = singleBounds.value;\n const denominator = max - min;\n const percentage = denominator === 0 ? 0 : ((singleValue.value - min) / denominator) * 100;\n return Math.max(0, Math.min(100, percentage));\n});\nconst singleRangeStyle = computed(() => ({\n \"--range-track-color\": rangeTrackColor.value,\n \"--value\": `${singlePercent.value}%`,\n}));\nconst singleTooltipStyle = computed(() => ({ left: `${singlePercent.value}%` }));\n\nconst countFractionDigits = (value: number) => {\n if (!Number.isFinite(value)) return 0;\n\n const valueText = String(value).toLowerCase();\n if (valueText.includes(\"e-\")) {\n const [base, exponent] = valueText.split(\"e-\");\n const baseDecimals = base?.split(\".\")[1]?.length ?? 0;\n return baseDecimals + Number(exponent);\n }\n\n return valueText.split(\".\")[1]?.length ?? 0;\n};\n\nconst dualSliderBounds = computed(() => {\n const propMin = toFiniteNumber(props.min);\n const propMax = toFiniteNumber(props.max);\n const currentMin = toFiniteNumber(rangeValue.value?.min);\n const currentMax = toFiniteNumber(rangeValue.value?.max);\n\n let min = propMin ?? Math.min(DEFAULT_MIN, currentMin ?? DEFAULT_MIN, currentMax ?? DEFAULT_MIN);\n let max = propMax ?? Math.max(DEFAULT_MAX, currentMin ?? DEFAULT_MAX, currentMax ?? DEFAULT_MAX);\n\n if (min > max) [min, max] = [max, min];\n if (min === max) max = min + (dualNumericStep.value > 0 ? dualNumericStep.value : 1);\n\n return { max, min };\n});\n\nconst clampToBounds = (value: number) => {\n return Math.max(dualSliderBounds.value.min, Math.min(dualSliderBounds.value.max, value));\n};\n\nconst stepFractionDigits = computed(() => {\n const boundFractionDigits = Math.max(\n countFractionDigits(dualSliderBounds.value.min),\n countFractionDigits(dualSliderBounds.value.max),\n );\n\n if (dualNumericStep.value <= 0) return Math.max(6, boundFractionDigits);\n return Math.max(boundFractionDigits, countFractionDigits(dualNumericStep.value));\n});\n\nconst normalizePrecision = (value: number) => {\n const fractionDigits = Math.min(20, stepFractionDigits.value);\n return clampToBounds(Number(value.toFixed(fractionDigits)));\n};\n\nconst minimumGap = computed(() => {\n if (props.allowMinMaxEqual) return 0;\n\n const boundsSpan = dualSliderBounds.value.max - dualSliderBounds.value.min;\n if (boundsSpan <= 0) return 0;\n\n const continuousGap = Math.max(boundsSpan / 1_000_000, 10 ** -stepFractionDigits.value);\n const gap = dualNumericStep.value > 0 ? dualNumericStep.value : continuousGap;\n return Math.min(gap, boundsSpan);\n});\n\nconst snapValue = (value: number, direction: \"down\" | \"nearest\" | \"up\" = \"nearest\") => {\n const clampedValue = clampToBounds(value);\n if (dualNumericStep.value <= 0) return normalizePrecision(clampedValue);\n\n const { min } = dualSliderBounds.value;\n const steps = (clampedValue - min) / dualNumericStep.value;\n const roundedSteps =\n direction === \"down\" ? Math.floor(steps) : direction === \"up\" ? Math.ceil(steps) : Math.round(steps);\n const snapped = roundedSteps * dualNumericStep.value + min;\n return normalizePrecision(clampToBounds(snapped));\n};\n\nconst clampMinHandleValue = (value: number, maxValue: number) => {\n const maxAllowed = Math.max(dualSliderBounds.value.min, maxValue - minimumGap.value);\n return snapValue(Math.min(value, maxAllowed), \"down\");\n};\n\nconst clampMaxHandleValue = (value: number, minValue: number) => {\n const minAllowed = Math.min(dualSliderBounds.value.max, minValue + minimumGap.value);\n return snapValue(Math.max(value, minAllowed), \"up\");\n};\n\nconst handleValues = computed(() => {\n const minValue = toFiniteNumber(rangeValue.value?.min) ?? dualSliderBounds.value.min;\n const maxValue = toFiniteNumber(rangeValue.value?.max) ?? dualSliderBounds.value.max;\n const clampedMin = clampToBounds(minValue);\n const clampedMax = clampToBounds(maxValue);\n\n return {\n max: Math.max(clampedMin, clampedMax),\n min: Math.min(clampedMin, clampedMax),\n };\n});\n\nconst percentForValue = (value: number) => {\n const { max, min } = dualSliderBounds.value;\n if (max === min) return 0;\n return ((value - min) / (max - min)) * 100;\n};\n\nconst minPercent = computed(() => percentForValue(handleValues.value.min));\nconst maxPercent = computed(() => percentForValue(handleValues.value.max));\nconst dualRangeStyle = computed(() => ({\n \"--range-track-color\": rangeTrackColor.value,\n \"--value-max\": `${maxPercent.value}%`,\n \"--value-min\": `${minPercent.value}%`,\n}));\nconst minTooltipStyle = computed(() => ({ left: `${minPercent.value}%` }));\nconst maxTooltipStyle = computed(() => ({ left: `${maxPercent.value}%` }));\nconst hasValue = computed(\n () => toFiniteNumber(rangeValue.value?.min) !== null || toFiniteNumber(rangeValue.value?.max) !== null,\n);\n\nconst shouldClearMinAtBoundary = () => toFiniteNumber(props.min) !== null || dualSliderBounds.value.min === DEFAULT_MIN;\nconst shouldClearMaxAtBoundary = () => toFiniteNumber(props.max) !== null || dualSliderBounds.value.max === DEFAULT_MAX;\n\nconst emitHandleValues = (nextMin: number, nextMax: number) => {\n rangeValue.value = {\n max: nextMax >= dualSliderBounds.value.max && shouldClearMaxAtBoundary() ? null : nextMax,\n min: nextMin <= dualSliderBounds.value.min && shouldClearMinAtBoundary() ? null : nextMin,\n };\n};\n\nconst setMinHandleValue = (nextMinValue: number) => {\n emitHandleValues(clampMinHandleValue(nextMinValue, handleValues.value.max), handleValues.value.max);\n};\n\nconst setMaxHandleValue = (nextMaxValue: number) => {\n emitHandleValues(handleValues.value.min, clampMaxHandleValue(nextMaxValue, handleValues.value.min));\n};\n\nconst clearActiveHandle = () => {\n activeHandle.value = null;\n};\n\nconst setActiveHandle = (handle: RangeInputName) => {\n activeHandle.value = handle;\n};\n\nconst handleClear = () => {\n rangeValue.value = { max: null, min: null };\n};\n\nconst removeSingleHandlePointerListeners = () => {\n removeSinglePointerListeners?.();\n removeSinglePointerListeners = null;\n};\n\nconst clearSingleHandle = () => {\n isSingleHandleActive.value = false;\n removeSingleHandlePointerListeners();\n};\n\nconst handleSinglePointerDown = () => {\n if (props.disabled) return;\n\n isSingleHandleActive.value = true;\n removeSingleHandlePointerListeners();\n\n window.addEventListener(\"pointerup\", clearSingleHandle);\n removeSinglePointerListeners = () => window.removeEventListener(\"pointerup\", clearSingleHandle);\n};\n\nconst handleMinSliderInput = (event: Event) => {\n setActiveHandle(\"min\");\n setMinHandleValue(Number((event.target as HTMLInputElement).value));\n};\n\nconst handleMaxSliderInput = (event: Event) => {\n setActiveHandle(\"max\");\n setMaxHandleValue(Number((event.target as HTMLInputElement).value));\n};\n\nconst updateTextFromModel = () => {\n if (focusedInput.value !== \"min\") minText.value = formatInputValue(handleValues.value.min);\n if (focusedInput.value !== \"max\") maxText.value = formatInputValue(handleValues.value.max);\n};\n\nconst commitTextInput = (input: RangeInputName) => {\n const parsed = parseNumber(input === \"min\" ? minText.value : maxText.value);\n const nextValue =\n parsed === null ? (input === \"min\" ? dualSliderBounds.value.min : dualSliderBounds.value.max) : snapValue(parsed);\n\n if (input === \"min\") {\n setMinHandleValue(nextValue);\n } else {\n setMaxHandleValue(nextValue);\n }\n};\n\nconst updateMinText = (event: Event) => {\n minText.value = (event.target as HTMLInputElement).value;\n commitTextInput(\"min\");\n};\n\nconst updateMaxText = (event: Event) => {\n maxText.value = (event.target as HTMLInputElement).value;\n commitTextInput(\"max\");\n};\n\nconst handleInputFocus = (input: RangeInputName) => {\n focusedInput.value = input;\n};\n\nconst handleInputBlur = (input: RangeInputName) => {\n commitTextInput(input);\n focusedInput.value = null;\n updateTextFromModel();\n};\n\nconst handleInputEnter = (event: KeyboardEvent, input: RangeInputName) => {\n event.preventDefault();\n commitTextInput(input);\n (event.target as HTMLInputElement).blur();\n};\n\nconst valueFromPointer = (clientX: number) => {\n const rect = sliderRef.value?.getBoundingClientRect();\n if (!rect || rect.width <= 0) return null;\n\n const percentage = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));\n return snapValue(dualSliderBounds.value.min + percentage * (dualSliderBounds.value.max - dualSliderBounds.value.min));\n};\n\nconst setNearestHandleFromPointer = (clientX: number) => {\n const nextValue = valueFromPointer(clientX);\n if (nextValue === null) return;\n\n if (props.alwaysEditMin) {\n setActiveHandle(\"min\");\n setMinHandleValue(nextValue);\n return;\n }\n\n const distanceToMin = Math.abs(nextValue - handleValues.value.min);\n const distanceToMax = Math.abs(nextValue - handleValues.value.max);\n\n if (distanceToMin <= distanceToMax) {\n setActiveHandle(\"min\");\n setMinHandleValue(nextValue);\n } else {\n setActiveHandle(\"max\");\n setMaxHandleValue(nextValue);\n }\n};\n\nconst removeActivePointerListeners = () => {\n removePointerListeners?.();\n removePointerListeners = null;\n};\n\nconst handleTrackPointerDown = (event: PointerEvent) => {\n if (props.disabled) return;\n\n const target = event.target as HTMLElement | null;\n if (target !== sliderRef.value && !target?.classList.contains(\"pv-range-dual-fill\")) return;\n\n setNearestHandleFromPointer(event.clientX);\n\n const handlePointerMove = (moveEvent: PointerEvent) => setNearestHandleFromPointer(moveEvent.clientX);\n const handlePointerUp = () => {\n clearActiveHandle();\n removeActivePointerListeners();\n };\n\n window.addEventListener(\"pointermove\", handlePointerMove);\n window.addEventListener(\"pointerup\", handlePointerUp);\n removePointerListeners = () => {\n window.removeEventListener(\"pointermove\", handlePointerMove);\n window.removeEventListener(\"pointerup\", handlePointerUp);\n };\n\n event.preventDefault();\n};\n\nwatch([handleValues, dualSliderBounds], updateTextFromModel, { immediate: true });\nonBeforeUnmount(() => {\n removeActivePointerListeners();\n removeSingleHandlePointerListeners();\n});\n</script>\n\n<template>\n <div v-if=\"mode === 'single'\" class=\"pv-range-single-slider\">\n <span v-if=\"showValueTooltips && isSingleHandleActive\" class=\"pv-range-tooltip\" :style=\"singleTooltipStyle\">\n {{ formatDisplayValue(singleValue) }}\n </span>\n <input\n :id=\"id\"\n v-bind=\"attrs\"\n v-model.number=\"modelValue\"\n :aria-label=\"ariaLabel\"\n :class=\"['pv-range', `pv-range-${props.size}`]\"\n :disabled=\"disabled\"\n :max=\"singleBounds.max\"\n :min=\"singleBounds.min\"\n :step=\"singleInputStep\"\n :style=\"singleRangeStyle\"\n type=\"range\"\n @change=\"clearSingleHandle\"\n @pointerdown=\"handleSinglePointerDown\"\n @pointerup=\"clearSingleHandle\"\n />\n </div>\n\n <div\n v-else\n v-bind=\"attrs\"\n class=\"pv-flex-vertical\"\n data-testid=\"pv-range-dual\"\n role=\"group\"\n :aria-label=\"label\"\n style=\"--flex-align: stretch; --flex-gap: 0\"\n >\n <div v-if=\"showBoundLabels\" class=\"pv-space-between pv-text-body-xs pv-text-subdued\" style=\"line-height: 1\">\n <span>{{ formatDisplayValue(dualSliderBounds.min) }}</span>\n <span>{{ formatDisplayValue(dualSliderBounds.max) }}</span>\n </div>\n\n <div\n ref=\"sliderRef\"\n class=\"pv-range-dual-slider\"\n :class=\"[`pv-range-dual-slider-${size}`, { 'pv-range-dual-slider-disabled': disabled }]\"\n :style=\"dualRangeStyle\"\n @pointerdown=\"handleTrackPointerDown\"\n >\n <div class=\"pv-range-dual-fill\" />\n <span v-if=\"showValueTooltips && activeHandle === 'min'\" class=\"pv-range-dual-tooltip\" :style=\"minTooltipStyle\">\n {{ formatDisplayValue(handleValues.min) }}\n </span>\n <span v-if=\"showValueTooltips && activeHandle === 'max'\" class=\"pv-range-dual-tooltip\" :style=\"maxTooltipStyle\">\n {{ formatDisplayValue(handleValues.max) }}\n </span>\n <input\n class=\"pv-range pv-range-dual-native pv-range-dual-native-min\"\n type=\"range\"\n :aria-label=\"`${label} minimum`\"\n :disabled=\"disabled\"\n :max=\"dualSliderBounds.max\"\n :min=\"dualSliderBounds.min\"\n :step=\"dualInputStep\"\n :value=\"handleValues.min\"\n @change=\"clearActiveHandle\"\n @input=\"handleMinSliderInput\"\n @pointerdown=\"setActiveHandle('min')\"\n @pointerup=\"clearActiveHandle\"\n />\n <input\n class=\"pv-range pv-range-dual-native pv-range-dual-native-max\"\n type=\"range\"\n :aria-label=\"`${label} maximum`\"\n :disabled=\"disabled\"\n :max=\"dualSliderBounds.max\"\n :min=\"dualSliderBounds.min\"\n :step=\"dualInputStep\"\n :value=\"handleValues.max\"\n @change=\"clearActiveHandle\"\n @input=\"handleMaxSliderInput\"\n @pointerdown=\"setActiveHandle('max')\"\n @pointerup=\"clearActiveHandle\"\n />\n </div>\n\n <div v-if=\"showInputs\" class=\"pv-flex\" style=\"--flex-align: flex-end; --flex-gap: 0.75rem; --flex-wrap: wrap\">\n <label\n class=\"pv-flex-vertical\"\n :for=\"minInputId\"\n style=\"--flex-align: stretch; --flex-gap: 0; flex: 0 0 75px; max-width: 75px; min-width: 0\"\n >\n <span class=\"pv-text-body-sm\">{{ minLabel }}</span>\n <input\n :id=\"minInputId\"\n class=\"pv-input-text\"\n :disabled=\"disabled\"\n style=\"width: 100%\"\n inputmode=\"decimal\"\n placeholder=\"Min\"\n :step=\"dualInputStep\"\n type=\"text\"\n :value=\"minText\"\n @blur=\"handleInputBlur('min')\"\n @focus=\"handleInputFocus('min')\"\n @input=\"updateMinText\"\n @keydown.enter=\"(event) => handleInputEnter(event, 'min')\"\n />\n </label>\n <label\n class=\"pv-flex-vertical\"\n :for=\"maxInputId\"\n style=\"--flex-align: stretch; --flex-gap: 0; flex: 0 0 75px; max-width: 75px; min-width: 0\"\n >\n <span class=\"pv-text-body-sm\">{{ maxLabel }}</span>\n <input\n :id=\"maxInputId\"\n class=\"pv-input-text\"\n :disabled=\"disabled\"\n style=\"width: 100%\"\n inputmode=\"decimal\"\n placeholder=\"Max\"\n :step=\"dualInputStep\"\n type=\"text\"\n :value=\"maxText\"\n @blur=\"handleInputBlur('max')\"\n @focus=\"handleInputFocus('max')\"\n @input=\"updateMaxText\"\n @keydown.enter=\"(event) => handleInputEnter(event, 'max')\"\n />\n </label>\n <PvButton\n v-if=\"showClear && hasValue\"\n class=\"pv-text-brand\"\n :disabled=\"disabled\"\n label=\"Clear range\"\n variant=\"ghost\"\n @click=\"handleClear\"\n />\n </div>\n\n <PvButton\n v-else-if=\"showClear && hasValue\"\n class=\"pv-text-brand\"\n :disabled=\"disabled\"\n label=\"Clear range\"\n variant=\"ghost\"\n @click=\"handleClear\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, onBeforeUnmount, ref, useAttrs, useId, watch } from \"vue\";\nimport type { PropType } from \"vue\";\n\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport type { PvRangeProps, PvRangeValue } from \"./types\";\n\ntype RangeInputName = \"min\" | \"max\";\n\ndefineOptions({ inheritAttrs: false });\n\nconst DEFAULT_MIN = 0;\nconst DEFAULT_MAX = 100;\n\nconst props = withDefaults(defineProps<PvRangeProps>(), {\n allowMinMaxEqual: true,\n alwaysEditMin: false,\n color: \"single\",\n dataType: null,\n disabled: false,\n label: \"Range\",\n max: null,\n maxLabel: \"Max\",\n min: null,\n minLabel: \"Min\",\n mode: \"single\",\n showBoundLabels: false,\n showClear: true,\n showInputs: true,\n showValueTooltips: true,\n size: \"md\",\n step: null,\n valueDecimals: null,\n});\n\nconst modelValue = defineModel<number>({ default: 0, type: Number });\nconst rangeValue = defineModel<PvRangeValue>(\"rangeValue\", {\n default: () => ({ max: null, min: null }),\n type: Object as PropType<PvRangeValue>,\n});\n\nconst attrs = useAttrs();\nconst id = useId();\nconst maxInputId = `${id}-max`;\nconst minInputId = `${id}-min`;\nconst maxText = ref(\"\");\nconst minText = ref(\"\");\nconst activeHandle = ref<RangeInputName | null>(null);\nconst focusedInput = ref<RangeInputName | null>(null);\nconst isSingleHandleActive = ref(false);\nconst sliderRef = ref<HTMLElement | null>(null);\n\nlet removePointerListeners: (() => void) | null = null;\nlet removeSinglePointerListeners: (() => void) | null = null;\n\nconst isFiniteNumber = (value: unknown): value is number => typeof value === \"number\" && Number.isFinite(value);\nconst toFiniteNumber = (value: unknown): number | null => (isFiniteNumber(value) ? value : null);\n\nconst parseNumber = (value: string): number | null => {\n const textValue = value.trim();\n if (textValue === \"\") return null;\n\n const parsed = Number(textValue.replace(/[^0-9.\\-]/g, \"\"));\n return Number.isFinite(parsed) ? parsed : null;\n};\n\nconst getDefaultDecimals = (dataType?: string | null): number | null => {\n if (dataType === \"currency\" || dataType === \"integer\" || dataType === \"percent\") return 0;\n return null;\n};\n\nconst getFractionDigits = () => {\n if (props.valueDecimals !== null && props.valueDecimals !== undefined) return Math.max(0, props.valueDecimals);\n const defaultDecimals = getDefaultDecimals(props.dataType);\n if (defaultDecimals !== null) return defaultDecimals;\n return 2;\n};\n\nconst formatInputValue = (value: number): string => String(value);\n\nconst formatDisplayValue = (value: number): string => {\n const fractionDigits = getFractionDigits();\n\n const formattedNumber = new Intl.NumberFormat(\"en-US\", {\n maximumFractionDigits: fractionDigits,\n minimumFractionDigits: 0,\n }).format(value);\n\n if (props.dataType === \"currency\") return `$${formattedNumber}`;\n return props.dataType === \"percent\" ? `${formattedNumber}%` : formattedNumber;\n};\n\nconst finiteStep = computed(() => toFiniteNumber(props.step));\nconst dualNumericStep = computed(() => (finiteStep.value !== null && finiteStep.value > 0 ? finiteStep.value : 0));\nconst dualInputStep = computed(() => (dualNumericStep.value > 0 ? String(dualNumericStep.value) : \"any\"));\nconst singleInputStep = computed(() => {\n if (finiteStep.value === null) return \"1\";\n return finiteStep.value > 0 ? String(finiteStep.value) : \"any\";\n});\nconst rangeTrackColor = computed(() =>\n props.color === \"multiple\" ? \"var(--color-data-viz-3, #ff7a4e)\" : \"var(--color-border, #e3e7ea)\",\n);\n\nconst singleBounds = computed(() => {\n const propMin = toFiniteNumber(props.min) ?? DEFAULT_MIN;\n const propMax = toFiniteNumber(props.max) ?? DEFAULT_MAX;\n\n if (propMin > propMax) return { max: propMin, min: propMax };\n if (propMin === propMax) return { max: propMin + 1, min: propMin };\n return { max: propMax, min: propMin };\n});\n\nconst singleValue = computed(() => toFiniteNumber(modelValue.value) ?? singleBounds.value.min);\nconst singlePercent = computed(() => {\n const { max, min } = singleBounds.value;\n const denominator = max - min;\n const percentage = denominator === 0 ? 0 : ((singleValue.value - min) / denominator) * 100;\n return Math.max(0, Math.min(100, percentage));\n});\nconst singleRangeStyle = computed(() => ({\n \"--range-track-color\": rangeTrackColor.value,\n \"--value\": `${singlePercent.value}%`,\n}));\nconst singleTooltipStyle = computed(() => ({ left: `${singlePercent.value}%` }));\n\nconst countFractionDigits = (value: number) => {\n if (!Number.isFinite(value)) return 0;\n\n const valueText = String(value).toLowerCase();\n if (valueText.includes(\"e-\")) {\n const [base, exponent] = valueText.split(\"e-\");\n const baseDecimals = base?.split(\".\")[1]?.length ?? 0;\n return baseDecimals + Number(exponent);\n }\n\n return valueText.split(\".\")[1]?.length ?? 0;\n};\n\nconst dualSliderBounds = computed(() => {\n const propMin = toFiniteNumber(props.min);\n const propMax = toFiniteNumber(props.max);\n const currentMin = toFiniteNumber(rangeValue.value?.min);\n const currentMax = toFiniteNumber(rangeValue.value?.max);\n\n let min = propMin ?? Math.min(DEFAULT_MIN, currentMin ?? DEFAULT_MIN, currentMax ?? DEFAULT_MIN);\n let max = propMax ?? Math.max(DEFAULT_MAX, currentMin ?? DEFAULT_MAX, currentMax ?? DEFAULT_MAX);\n\n if (min > max) [min, max] = [max, min];\n if (min === max) max = min + (dualNumericStep.value > 0 ? dualNumericStep.value : 1);\n\n return { max, min };\n});\n\nconst clampToBounds = (value: number) => {\n return Math.max(dualSliderBounds.value.min, Math.min(dualSliderBounds.value.max, value));\n};\n\nconst stepFractionDigits = computed(() => {\n const boundFractionDigits = Math.max(\n countFractionDigits(dualSliderBounds.value.min),\n countFractionDigits(dualSliderBounds.value.max),\n );\n\n if (dualNumericStep.value <= 0) return Math.max(6, boundFractionDigits);\n return Math.max(boundFractionDigits, countFractionDigits(dualNumericStep.value));\n});\n\nconst normalizePrecision = (value: number) => {\n const fractionDigits = Math.min(20, stepFractionDigits.value);\n return clampToBounds(Number(value.toFixed(fractionDigits)));\n};\n\nconst minimumGap = computed(() => {\n if (props.allowMinMaxEqual) return 0;\n\n const boundsSpan = dualSliderBounds.value.max - dualSliderBounds.value.min;\n if (boundsSpan <= 0) return 0;\n\n const continuousGap = Math.max(boundsSpan / 1_000_000, 10 ** -stepFractionDigits.value);\n const gap = dualNumericStep.value > 0 ? dualNumericStep.value : continuousGap;\n return Math.min(gap, boundsSpan);\n});\n\nconst snapValue = (value: number, direction: \"down\" | \"nearest\" | \"up\" = \"nearest\") => {\n const clampedValue = clampToBounds(value);\n if (dualNumericStep.value <= 0) return normalizePrecision(clampedValue);\n\n const { min } = dualSliderBounds.value;\n const steps = (clampedValue - min) / dualNumericStep.value;\n const roundedSteps =\n direction === \"down\" ? Math.floor(steps) : direction === \"up\" ? Math.ceil(steps) : Math.round(steps);\n const snapped = roundedSteps * dualNumericStep.value + min;\n return normalizePrecision(clampToBounds(snapped));\n};\n\nconst clampMinHandleValue = (value: number, maxValue: number) => {\n const maxAllowed = Math.max(dualSliderBounds.value.min, maxValue - minimumGap.value);\n return snapValue(Math.min(value, maxAllowed), \"down\");\n};\n\nconst clampMaxHandleValue = (value: number, minValue: number) => {\n const minAllowed = Math.min(dualSliderBounds.value.max, minValue + minimumGap.value);\n return snapValue(Math.max(value, minAllowed), \"up\");\n};\n\nconst handleValues = computed(() => {\n const minValue = toFiniteNumber(rangeValue.value?.min) ?? dualSliderBounds.value.min;\n const maxValue = toFiniteNumber(rangeValue.value?.max) ?? dualSliderBounds.value.max;\n const clampedMin = clampToBounds(minValue);\n const clampedMax = clampToBounds(maxValue);\n\n return {\n max: Math.max(clampedMin, clampedMax),\n min: Math.min(clampedMin, clampedMax),\n };\n});\n\nconst percentForValue = (value: number) => {\n const { max, min } = dualSliderBounds.value;\n if (max === min) return 0;\n return ((value - min) / (max - min)) * 100;\n};\n\nconst minPercent = computed(() => percentForValue(handleValues.value.min));\nconst maxPercent = computed(() => percentForValue(handleValues.value.max));\nconst dualRangeStyle = computed(() => ({\n \"--range-track-color\": rangeTrackColor.value,\n \"--value-max\": `${maxPercent.value}%`,\n \"--value-min\": `${minPercent.value}%`,\n}));\nconst minTooltipStyle = computed(() => ({ left: `${minPercent.value}%` }));\nconst maxTooltipStyle = computed(() => ({ left: `${maxPercent.value}%` }));\nconst hasValue = computed(\n () => toFiniteNumber(rangeValue.value?.min) !== null || toFiniteNumber(rangeValue.value?.max) !== null,\n);\n\nconst shouldClearMinAtBoundary = () => toFiniteNumber(props.min) !== null || dualSliderBounds.value.min === DEFAULT_MIN;\nconst shouldClearMaxAtBoundary = () => toFiniteNumber(props.max) !== null || dualSliderBounds.value.max === DEFAULT_MAX;\n\nconst emitHandleValues = (nextMin: number, nextMax: number) => {\n rangeValue.value = {\n max: nextMax >= dualSliderBounds.value.max && shouldClearMaxAtBoundary() ? null : nextMax,\n min: nextMin <= dualSliderBounds.value.min && shouldClearMinAtBoundary() ? null : nextMin,\n };\n};\n\nconst setMinHandleValue = (nextMinValue: number) => {\n emitHandleValues(clampMinHandleValue(nextMinValue, handleValues.value.max), handleValues.value.max);\n};\n\nconst setMaxHandleValue = (nextMaxValue: number) => {\n emitHandleValues(handleValues.value.min, clampMaxHandleValue(nextMaxValue, handleValues.value.min));\n};\n\nconst clearActiveHandle = () => {\n activeHandle.value = null;\n};\n\nconst setActiveHandle = (handle: RangeInputName) => {\n activeHandle.value = handle;\n};\n\nconst handleClear = () => {\n rangeValue.value = { max: null, min: null };\n};\n\nconst removeSingleHandlePointerListeners = () => {\n removeSinglePointerListeners?.();\n removeSinglePointerListeners = null;\n};\n\nconst clearSingleHandle = () => {\n isSingleHandleActive.value = false;\n removeSingleHandlePointerListeners();\n};\n\nconst handleSinglePointerDown = () => {\n if (props.disabled) return;\n\n isSingleHandleActive.value = true;\n removeSingleHandlePointerListeners();\n\n window.addEventListener(\"pointerup\", clearSingleHandle);\n removeSinglePointerListeners = () => window.removeEventListener(\"pointerup\", clearSingleHandle);\n};\n\nconst handleMinSliderInput = (event: Event) => {\n setActiveHandle(\"min\");\n setMinHandleValue(Number((event.target as HTMLInputElement).value));\n};\n\nconst handleMaxSliderInput = (event: Event) => {\n setActiveHandle(\"max\");\n setMaxHandleValue(Number((event.target as HTMLInputElement).value));\n};\n\nconst updateTextFromModel = () => {\n if (focusedInput.value !== \"min\") minText.value = formatInputValue(handleValues.value.min);\n if (focusedInput.value !== \"max\") maxText.value = formatInputValue(handleValues.value.max);\n};\n\nconst commitTextInput = (input: RangeInputName) => {\n const parsed = parseNumber(input === \"min\" ? minText.value : maxText.value);\n const nextValue =\n parsed === null ? (input === \"min\" ? dualSliderBounds.value.min : dualSliderBounds.value.max) : snapValue(parsed);\n\n if (input === \"min\") {\n setMinHandleValue(nextValue);\n } else {\n setMaxHandleValue(nextValue);\n }\n};\n\nconst updateMinText = (event: Event) => {\n minText.value = (event.target as HTMLInputElement).value;\n commitTextInput(\"min\");\n};\n\nconst updateMaxText = (event: Event) => {\n maxText.value = (event.target as HTMLInputElement).value;\n commitTextInput(\"max\");\n};\n\nconst handleInputFocus = (input: RangeInputName) => {\n focusedInput.value = input;\n};\n\nconst handleInputBlur = (input: RangeInputName) => {\n commitTextInput(input);\n focusedInput.value = null;\n updateTextFromModel();\n};\n\nconst handleInputEnter = (event: KeyboardEvent, input: RangeInputName) => {\n event.preventDefault();\n commitTextInput(input);\n (event.target as HTMLInputElement).blur();\n};\n\nconst valueFromPointer = (clientX: number) => {\n const rect = sliderRef.value?.getBoundingClientRect();\n if (!rect || rect.width <= 0) return null;\n\n const percentage = Math.max(0, Math.min(1, (clientX - rect.left) / rect.width));\n return snapValue(dualSliderBounds.value.min + percentage * (dualSliderBounds.value.max - dualSliderBounds.value.min));\n};\n\nconst setNearestHandleFromPointer = (clientX: number) => {\n const nextValue = valueFromPointer(clientX);\n if (nextValue === null) return;\n\n if (props.alwaysEditMin) {\n setActiveHandle(\"min\");\n setMinHandleValue(nextValue);\n return;\n }\n\n const distanceToMin = Math.abs(nextValue - handleValues.value.min);\n const distanceToMax = Math.abs(nextValue - handleValues.value.max);\n\n if (distanceToMin <= distanceToMax) {\n setActiveHandle(\"min\");\n setMinHandleValue(nextValue);\n } else {\n setActiveHandle(\"max\");\n setMaxHandleValue(nextValue);\n }\n};\n\nconst removeActivePointerListeners = () => {\n removePointerListeners?.();\n removePointerListeners = null;\n};\n\nconst handleTrackPointerDown = (event: PointerEvent) => {\n if (props.disabled) return;\n\n const target = event.target as HTMLElement | null;\n if (target !== sliderRef.value && !target?.classList.contains(\"pv-range-dual-fill\")) return;\n\n setNearestHandleFromPointer(event.clientX);\n\n const handlePointerMove = (moveEvent: PointerEvent) => setNearestHandleFromPointer(moveEvent.clientX);\n const handlePointerUp = () => {\n clearActiveHandle();\n removeActivePointerListeners();\n };\n\n window.addEventListener(\"pointermove\", handlePointerMove);\n window.addEventListener(\"pointerup\", handlePointerUp);\n removePointerListeners = () => {\n window.removeEventListener(\"pointermove\", handlePointerMove);\n window.removeEventListener(\"pointerup\", handlePointerUp);\n };\n\n event.preventDefault();\n};\n\nwatch([handleValues, dualSliderBounds], updateTextFromModel, { immediate: true });\nonBeforeUnmount(() => {\n removeActivePointerListeners();\n removeSingleHandlePointerListeners();\n});\n</script>\n\n<template>\n <div v-if=\"mode === 'single'\" class=\"pv-range-single-slider\">\n <span v-if=\"showValueTooltips && isSingleHandleActive\" class=\"pv-range-tooltip\" :style=\"singleTooltipStyle\">\n {{ formatDisplayValue(singleValue) }}\n </span>\n <input\n :id=\"id\"\n v-bind=\"attrs\"\n v-model.number=\"modelValue\"\n :aria-label=\"ariaLabel\"\n :class=\"['pv-range', `pv-range-${props.size}`]\"\n :disabled=\"disabled\"\n :max=\"singleBounds.max\"\n :min=\"singleBounds.min\"\n :step=\"singleInputStep\"\n :style=\"singleRangeStyle\"\n type=\"range\"\n @change=\"clearSingleHandle\"\n @pointerdown=\"handleSinglePointerDown\"\n @pointerup=\"clearSingleHandle\"\n />\n </div>\n\n <div\n v-else\n v-bind=\"attrs\"\n class=\"pv-flex-vertical\"\n data-testid=\"pv-range-dual\"\n role=\"group\"\n :aria-label=\"label\"\n style=\"--flex-align: stretch; --flex-gap: 0\"\n >\n <div v-if=\"showBoundLabels\" class=\"pv-space-between pv-text-body-xs pv-text-subdued\" style=\"line-height: 1\">\n <span>{{ formatDisplayValue(dualSliderBounds.min) }}</span>\n <span>{{ formatDisplayValue(dualSliderBounds.max) }}</span>\n </div>\n\n <div\n ref=\"sliderRef\"\n class=\"pv-range-dual-slider\"\n :class=\"[`pv-range-dual-slider-${size}`, { 'pv-range-dual-slider-disabled': disabled }]\"\n :style=\"dualRangeStyle\"\n @pointerdown=\"handleTrackPointerDown\"\n >\n <div class=\"pv-range-dual-fill\" />\n <span v-if=\"showValueTooltips && activeHandle === 'min'\" class=\"pv-range-dual-tooltip\" :style=\"minTooltipStyle\">\n {{ formatDisplayValue(handleValues.min) }}\n </span>\n <span v-if=\"showValueTooltips && activeHandle === 'max'\" class=\"pv-range-dual-tooltip\" :style=\"maxTooltipStyle\">\n {{ formatDisplayValue(handleValues.max) }}\n </span>\n <input\n class=\"pv-range pv-range-dual-native pv-range-dual-native-min\"\n type=\"range\"\n :aria-label=\"`${label} minimum`\"\n :disabled=\"disabled\"\n :max=\"dualSliderBounds.max\"\n :min=\"dualSliderBounds.min\"\n :step=\"dualInputStep\"\n :value=\"handleValues.min\"\n @change=\"clearActiveHandle\"\n @input=\"handleMinSliderInput\"\n @pointerdown=\"setActiveHandle('min')\"\n @pointerup=\"clearActiveHandle\"\n />\n <input\n class=\"pv-range pv-range-dual-native pv-range-dual-native-max\"\n type=\"range\"\n :aria-label=\"`${label} maximum`\"\n :disabled=\"disabled\"\n :max=\"dualSliderBounds.max\"\n :min=\"dualSliderBounds.min\"\n :step=\"dualInputStep\"\n :value=\"handleValues.max\"\n @change=\"clearActiveHandle\"\n @input=\"handleMaxSliderInput\"\n @pointerdown=\"setActiveHandle('max')\"\n @pointerup=\"clearActiveHandle\"\n />\n </div>\n\n <div v-if=\"showInputs\" class=\"pv-flex\" style=\"--flex-align: flex-end; --flex-gap: 0.75rem; --flex-wrap: wrap\">\n <label\n class=\"pv-flex-vertical\"\n :for=\"minInputId\"\n style=\"--flex-align: stretch; --flex-gap: 0; flex: 0 0 75px; max-width: 75px; min-width: 0\"\n >\n <span class=\"pv-text-body-sm\">{{ minLabel }}</span>\n <input\n :id=\"minInputId\"\n class=\"pv-input-text\"\n :disabled=\"disabled\"\n style=\"width: 100%\"\n inputmode=\"decimal\"\n placeholder=\"Min\"\n :step=\"dualInputStep\"\n type=\"text\"\n :value=\"minText\"\n @blur=\"handleInputBlur('min')\"\n @focus=\"handleInputFocus('min')\"\n @input=\"updateMinText\"\n @keydown.enter=\"(event) => handleInputEnter(event, 'min')\"\n />\n </label>\n <label\n class=\"pv-flex-vertical\"\n :for=\"maxInputId\"\n style=\"--flex-align: stretch; --flex-gap: 0; flex: 0 0 75px; max-width: 75px; min-width: 0\"\n >\n <span class=\"pv-text-body-sm\">{{ maxLabel }}</span>\n <input\n :id=\"maxInputId\"\n class=\"pv-input-text\"\n :disabled=\"disabled\"\n style=\"width: 100%\"\n inputmode=\"decimal\"\n placeholder=\"Max\"\n :step=\"dualInputStep\"\n type=\"text\"\n :value=\"maxText\"\n @blur=\"handleInputBlur('max')\"\n @focus=\"handleInputFocus('max')\"\n @input=\"updateMaxText\"\n @keydown.enter=\"(event) => handleInputEnter(event, 'max')\"\n />\n </label>\n <PvButton\n v-if=\"showClear && hasValue\"\n class=\"pv-text-brand\"\n :disabled=\"disabled\"\n label=\"Clear range\"\n variant=\"ghost\"\n @click=\"handleClear\"\n />\n </div>\n\n <PvButton\n v-else-if=\"showClear && hasValue\"\n class=\"pv-text-brand\"\n :disabled=\"disabled\"\n label=\"Clear range\"\n variant=\"ghost\"\n @click=\"handleClear\"\n />\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, type CSSProperties, useSlots } from \"vue\";\n\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport PvCheckbox from \"@/components/base/PvCheckbox/PvCheckbox.vue\";\nimport type { PvFilterPanelOptionRowProps } from \"./types\";\n\nconst props = withDefaults(defineProps<PvFilterPanelOptionRowProps>(), {\n depth: 0,\n disabled: false,\n focusText: \"Focus\",\n indeterminate: false,\n isFocused: false,\n resultCount: null,\n selected: false,\n showFocusAction: false,\n});\n\nconst emit = defineEmits<{\n \"focus-value\": [value: string];\n \"toggle-value\": [value: string, checked: boolean];\n}>();\n\nconst slots = useSlots();\n\nconst hasResultCount = computed(\n () => props.resultCount !== null && props.resultCount !== undefined && props.resultCount !== \"\",\n);\nconst hasRightContent = computed(() => !props.renderer && (hasResultCount.value || Boolean(slots[\"result-count\"])));\nconst rowStyle = computed<CSSProperties>(() => ({\n \"--pv-filter-panel-option-row-depth\": String(props.depth),\n}));\nconst rendererProps = computed(() => ({\n disabled: props.disabled,\n highlightSearchText: true,\n id: props.value,\n indeterminate: props.indeterminate,\n label: props.label,\n queryText: props.queryText,\n resultCount: props.resultCount ?? undefined,\n secondaryText: props.resultCount ?? undefined,\n selected: props.selected,\n subText: props.subText,\n subduedText: props.subduedText,\n text: props.label,\n value: props.value,\n}));\n\nconst handleToggleValue = (checked: boolean | undefined) => {\n if (props.disabled) return;\n emit(\"toggle-value\", props.value, checked === true);\n};\n\nconst handleFocusValue = () => {\n if (props.disabled) return;\n emit(\"focus-value\", props.value);\n};\n</script>\n\n<template>\n <label\n class=\"pv-filter-panel-option-row pv-flex\"\n :class=\"{ 'pv-filter-panel-option-row-disabled': disabled }\"\n data-testid=\"pv-filter-panel-option-row\"\n :style=\"rowStyle\"\n >\n <PvCheckbox\n :ariaLabel=\"ariaLabel || label\"\n :disabled=\"disabled\"\n :indeterminate=\"indeterminate\"\n :modelValue=\"selected\"\n @update:modelValue=\"handleToggleValue\"\n />\n <component v-if=\"renderer\" :is=\"renderer\" v-bind=\"rendererProps\" />\n <span v-else class=\"pv-filter-panel-option-row-content pv-flex-vertical\">\n <span class=\"pv-filter-panel-option-row-line pv-line-clamp pv-text-body-sm\">{{ label }}</span>\n <span v-if=\"subduedText\" class=\"pv-filter-panel-option-row-line pv-line-clamp pv-text-body-xs pv-text-subdued\">\n {{ subduedText }}\n </span>\n <span v-if=\"subText\" class=\"pv-filter-panel-option-row-line pv-line-clamp pv-text-body-xs pv-text-subdued\">\n {{ subText }}\n </span>\n </span>\n <span v-if=\"hasRightContent\" class=\"pv-filter-panel-option-row-right pv-text-body-xs pv-text-subdued\">\n <slot name=\"result-count\">({{ resultCount }})</slot>\n </span>\n <PvButton\n v-if=\"showFocusAction\"\n :ariaLabel=\"isFocused ? `Remove ${focusText}` : `Select as ${focusText}`\"\n :disabled=\"disabled\"\n leftIcon=\"focus\"\n size=\"md\"\n :variant=\"isFocused ? 'primary' : 'ghost'\"\n @click.stop.prevent=\"handleFocusValue\"\n />\n </label>\n</template>\n\n<style scoped>\n.pv-filter-panel-option-row {\n --flex-align: center;\n --flex-gap: 0.5rem;\n cursor: pointer;\n min-width: 0;\n padding-left: calc(var(--pv-filter-panel-option-row-depth) * 1.25rem);\n}\n\n.pv-filter-panel-option-row-content {\n --flex-align: stretch;\n --flex-gap: 0;\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.pv-filter-panel-option-row-disabled {\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.pv-filter-panel-option-row-line {\n --lines: 1;\n}\n\n.pv-filter-panel-option-row-right {\n flex: 0 0 auto;\n text-align: right;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, type CSSProperties, useSlots } from \"vue\";\n\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport PvCheckbox from \"@/components/base/PvCheckbox/PvCheckbox.vue\";\nimport type { PvFilterPanelOptionRowProps } from \"./types\";\n\nconst props = withDefaults(defineProps<PvFilterPanelOptionRowProps>(), {\n depth: 0,\n disabled: false,\n focusText: \"Focus\",\n indeterminate: false,\n isFocused: false,\n resultCount: null,\n selected: false,\n showFocusAction: false,\n});\n\nconst emit = defineEmits<{\n \"focus-value\": [value: string];\n \"toggle-value\": [value: string, checked: boolean];\n}>();\n\nconst slots = useSlots();\n\nconst hasResultCount = computed(\n () => props.resultCount !== null && props.resultCount !== undefined && props.resultCount !== \"\",\n);\nconst hasRightContent = computed(() => !props.renderer && (hasResultCount.value || Boolean(slots[\"result-count\"])));\nconst rowStyle = computed<CSSProperties>(() => ({\n \"--pv-filter-panel-option-row-depth\": String(props.depth),\n}));\nconst rendererProps = computed(() => ({\n disabled: props.disabled,\n highlightSearchText: true,\n id: props.value,\n indeterminate: props.indeterminate,\n label: props.label,\n queryText: props.queryText,\n resultCount: props.resultCount ?? undefined,\n secondaryText: props.resultCount ?? undefined,\n selected: props.selected,\n subText: props.subText,\n subduedText: props.subduedText,\n text: props.label,\n value: props.value,\n}));\n\nconst handleToggleValue = (checked: boolean | undefined) => {\n if (props.disabled) return;\n emit(\"toggle-value\", props.value, checked === true);\n};\n\nconst handleFocusValue = () => {\n if (props.disabled) return;\n emit(\"focus-value\", props.value);\n};\n</script>\n\n<template>\n <label\n class=\"pv-filter-panel-option-row pv-flex\"\n :class=\"{ 'pv-filter-panel-option-row-disabled': disabled }\"\n data-testid=\"pv-filter-panel-option-row\"\n :style=\"rowStyle\"\n >\n <PvCheckbox\n :ariaLabel=\"ariaLabel || label\"\n :disabled=\"disabled\"\n :indeterminate=\"indeterminate\"\n :modelValue=\"selected\"\n @update:modelValue=\"handleToggleValue\"\n />\n <component v-if=\"renderer\" :is=\"renderer\" v-bind=\"rendererProps\" />\n <span v-else class=\"pv-filter-panel-option-row-content pv-flex-vertical\">\n <span class=\"pv-filter-panel-option-row-line pv-line-clamp pv-text-body-sm\">{{ label }}</span>\n <span v-if=\"subduedText\" class=\"pv-filter-panel-option-row-line pv-line-clamp pv-text-body-xs pv-text-subdued\">\n {{ subduedText }}\n </span>\n <span v-if=\"subText\" class=\"pv-filter-panel-option-row-line pv-line-clamp pv-text-body-xs pv-text-subdued\">\n {{ subText }}\n </span>\n </span>\n <span v-if=\"hasRightContent\" class=\"pv-filter-panel-option-row-right pv-text-body-xs pv-text-subdued\">\n <slot name=\"result-count\">({{ resultCount }})</slot>\n </span>\n <PvButton\n v-if=\"showFocusAction\"\n :ariaLabel=\"isFocused ? `Remove ${focusText}` : `Select as ${focusText}`\"\n :disabled=\"disabled\"\n leftIcon=\"focus\"\n size=\"md\"\n :variant=\"isFocused ? 'primary' : 'ghost'\"\n @click.stop.prevent=\"handleFocusValue\"\n />\n </label>\n</template>\n\n<style scoped>\n.pv-filter-panel-option-row {\n --flex-align: center;\n --flex-gap: 0.5rem;\n cursor: pointer;\n min-width: 0;\n padding-left: calc(var(--pv-filter-panel-option-row-depth) * 1.25rem);\n}\n\n.pv-filter-panel-option-row-content {\n --flex-align: stretch;\n --flex-gap: 0;\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.pv-filter-panel-option-row-disabled {\n cursor: not-allowed;\n opacity: 0.6;\n}\n\n.pv-filter-panel-option-row-line {\n --lines: 1;\n}\n\n.pv-filter-panel-option-row-right {\n flex: 0 0 auto;\n text-align: right;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from \"vue\";\nimport { watchDebounced } from \"@vueuse/core\";\nimport type { MenuOption } from \"@/types\";\n\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport PvCounterBadge from \"@/components/base/PvCounterBadge/PvCounterBadge.vue\";\nimport PvCheckbox from \"@/components/base/PvCheckbox/PvCheckbox.vue\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport PvSearchInput from \"@/components/base/PvSearchInput/PvSearchInput.vue\";\nimport PvSpinner from \"@/components/base/PvSpinner/PvSpinner.vue\";\nimport PvTooltipV2 from \"@/components/base/PvTooltipV2/PvTooltipV2.vue\";\nimport PvRange from \"@/components/base/PvRange/PvRange.vue\";\nimport type { PvRangeValue } from \"@/components/base/PvRange/types\";\nimport PvFilterPanelOptionRow from \"./PvFilterPanelOptionRow.vue\";\nimport { getFilterOptionLabel, getFilterOptionResultCount } from \"./filterOptionDisplay\";\nimport {\n createFilterPanelAggregateSelectionStatusMap,\n getFilterPanelAggregateSelectionCount,\n updateFilterPanelAggregateSelectionState,\n} from \"./aggregateFilterModel\";\nimport {\n flattenFilterPanelOptions,\n getFilterPanelOptionField,\n getFilterPanelOptionRawValue,\n} from \"./filterOptionValue\";\nimport type {\n PvFilterPanelAccordionProps,\n PvFilterPanelControlChange,\n PvFilterPanelFilterType,\n PvFilterPanelOption,\n} from \"./types\";\n\nconst props = defineProps<PvFilterPanelAccordionProps>();\n\nconst emit = defineEmits<{\n \"focus-change\": [field: string, value: string, option: PvFilterPanelOption];\n \"handle-settings-icon\": [field: string, colDef: PvFilterPanelAccordionProps[\"filter\"][\"colDef\"]];\n \"load-more\": [query: string, parentId?: string];\n \"open-change\": [open: boolean];\n \"filter-change\": [change: PvFilterPanelControlChange];\n \"search-change\": [query: string];\n}>();\n\nconst UNSELECTED_PAGE_SIZE = 5;\nconst KNOWN_OPTION_MAP_MAX_SIZE = 500;\n\ninterface DisplayedFilterOptionRow {\n depth: number;\n kind: \"option\";\n option: PvFilterPanelOption;\n}\n\ninterface DisplayedFilterChildLoadMoreRow {\n depth: number;\n kind: \"child-load-more\";\n parent: PvFilterPanelOption;\n}\n\ntype DisplayedFilterOption = DisplayedFilterOptionRow | DisplayedFilterChildLoadMoreRow;\n\nconst knownOptionMap = ref<Record<string, PvFilterPanelOption>>({});\nconst searchText = ref(props.filter.searchQuery ?? \"\");\nconst visibleUnselectedCount = ref(UNSELECTED_PAGE_SIZE);\n\nconst existsLabel = computed(() => props.filter.existsLabel ?? `Has ${props.filter.label}`);\nconst falseLabel = computed(() => props.filter.valueLabels?.[\"false\"] ?? \"No\");\nconst filterOptions = computed(() => props.filter.options ?? []);\nconst knownOptions = computed(() => [...(props.filter.knownOptions ?? []), ...filterOptions.value]);\nconst filterType = computed<PvFilterPanelFilterType>(() => props.filter.type ?? \"value\");\nconst isValueFilter = computed(() => filterType.value === \"value\");\nconst isAggregateFilter = computed(() => isValueFilter.value && props.filter.isAggregate === true);\nconst aggregateSelectionState = computed(() => props.filter.aggregateSelectionState ?? []);\nconst normalizedSearchText = computed(() => searchText.value.trim().toLowerCase());\nconst selectedValues = computed(() => props.filter.selectedValues ?? []);\nconst selectedValueSet = computed(() => new Set(selectedValues.value));\nconst trueLabel = computed(() => props.filter.valueLabels?.[\"true\"] ?? \"Yes\");\nconst optionsSortLabel = computed(() => props.filter.filterOptionsSortDescription || \"Suggested\");\n\nconst getSearchableOptionText = (option: PvFilterPanelOption) => {\n const metadataValues =\n typeof option.metadata === \"object\" && option.metadata !== null ? Object.values(option.metadata) : [];\n return [option.value, option.label, option.subText, option.subduedText, option.matchedValue, option.matchedField]\n .concat(metadataValues.flatMap((value) => (value === null || value === undefined ? [] : [String(value)])))\n .filter((value): value is string => Boolean(value))\n .join(\" \")\n .toLowerCase();\n};\n\nconst counter = computed(() => {\n if (filterType.value === \"range\") {\n return props.filter.rangeValue?.min !== null && props.filter.rangeValue?.min !== undefined\n ? 1\n : props.filter.rangeValue?.max !== null && props.filter.rangeValue?.max !== undefined\n ? 1\n : undefined;\n }\n\n if (filterType.value === \"boolean\") {\n return props.filter.booleanValue !== null && props.filter.booleanValue !== undefined ? 1 : undefined;\n }\n\n if (filterType.value === \"exists\") return props.filter.existsValue ? 1 : undefined;\n if (isAggregateFilter.value) return getFilterPanelAggregateSelectionCount(aggregateSelectionState.value) || undefined;\n return selectedValues.value.length || undefined;\n});\n\nconst optionHasMoreChildren = (option: PvFilterPanelOption) => {\n if (option.totalChildCount === null || option.totalChildCount === undefined) return false;\n return option.totalChildCount > (option.children?.length ?? 0);\n};\n\nconst flattenOptions = (options: PvFilterPanelOption[], depth = 0): DisplayedFilterOption[] => {\n return options.flatMap((option) => [\n { depth, kind: \"option\", option } as DisplayedFilterOptionRow,\n ...(option.children?.length ? flattenOptions(option.children, depth + 1) : []),\n ...(optionHasMoreChildren(option)\n ? ([{ depth: depth + 1, kind: \"child-load-more\", parent: option }] as DisplayedFilterChildLoadMoreRow[])\n : []),\n ]);\n};\n\nconst displayedOptions = computed<DisplayedFilterOption[]>(() => {\n const flattenedOptions = flattenOptions(filterOptions.value);\n const query = normalizedSearchText.value;\n if (!query) return flattenedOptions;\n return flattenedOptions.filter(\n (item): item is DisplayedFilterOptionRow =>\n item.kind === \"option\" && getSearchableOptionText(item.option).includes(query),\n );\n});\nconst selectedOptions = computed(() =>\n isAggregateFilter.value\n ? []\n : selectedValues.value.map((value) => knownOptionMap.value[value] ?? { label: value, value }),\n);\nconst unselectedOptions = computed(() =>\n isAggregateFilter.value\n ? displayedOptions.value\n : displayedOptions.value.filter(\n (item) => item.kind === \"child-load-more\" || !selectedValueSet.value.has(item.option.value),\n ),\n);\nconst hasMoreLocalUnselected = computed(() => unselectedOptions.value.length > visibleUnselectedCount.value);\nconst showSeeMoreButton = computed(() => hasMoreLocalUnselected.value || props.filter.hasMore);\nconst visibleUnselectedOptions = computed(() => unselectedOptions.value.slice(0, visibleUnselectedCount.value));\n\nconst aggregateSelectionStatusMap = computed(() =>\n isAggregateFilter.value\n ? createFilterPanelAggregateSelectionStatusMap({\n options: knownOptions.value,\n state: aggregateSelectionState.value,\n })\n : new Map<string, { indeterminate: boolean; selected: boolean }>(),\n);\n\nconst getOptionDisplayLabel = (option: PvFilterPanelOption) => getFilterOptionLabel(option, props.filter.colDef);\nconst getOptionDisplayResultCount = (option: PvFilterPanelOption) => getFilterOptionResultCount(option);\nconst getOptionSelectionStatus = (option: PvFilterPanelOption) => {\n if (!isAggregateFilter.value) return { indeterminate: false, selected: selectedValueSet.value.has(option.value) };\n return aggregateSelectionStatusMap.value.get(option.value) ?? { indeterminate: false, selected: false };\n};\nconst isOptionSelected = (option: PvFilterPanelOption) => getOptionSelectionStatus(option).selected;\nconst isOptionIndeterminate = (option: PvFilterPanelOption) => getOptionSelectionStatus(option).indeterminate;\n\nconst getOptionFilterValue = (option: PvFilterPanelOption) => getFilterPanelOptionRawValue(option) ?? option.value;\nconst getOptionFilterField = (option: PvFilterPanelOption) => getFilterPanelOptionField(option, props.filter.key);\n\nconst isOptionFocused = (option: PvFilterPanelOption) => {\n const field = getOptionFilterField(option);\n const rawValue = getOptionFilterValue(option);\n return (\n props.filter.focusedValuesByField?.[field]?.includes(rawValue) ||\n (field === props.filter.key && props.filter.focusedValues?.includes(option.value)) ||\n false\n );\n};\n\nconst toMenuOption = (option: PvFilterPanelOption): MenuOption<PvFilterPanelOption> => ({\n ...(option.menuOption ?? {}),\n children: option.children?.map(toMenuOption),\n context: option,\n disabled: props.filter.disabled || option.isSelectable === false || option.menuOption?.disabled,\n id: option.value,\n searchText: getSearchableOptionText(option),\n secondaryText: getOptionDisplayResultCount(option),\n subText: option.subText,\n subduedText: option.subduedText,\n text: getOptionDisplayLabel(option),\n totalChildCount: option.totalChildCount,\n});\n\nconst rendererOptions = computed(() => filterOptions.value.map(toMenuOption));\nconst rendererSelectedItems = computed(() => selectedOptions.value.map(toMenuOption));\nconst rendererSlotProps = computed(() => ({\n colDef: props.filter.colDef,\n disabled: props.filter.disabled,\n filter: props.filter,\n isLoading: props.filter.isLoading,\n isOpen: props.filter.isOpen,\n options: rendererOptions.value,\n searchInput: searchText.value,\n selectedItems: rendererSelectedItems.value,\n slotContext: {\n colDef: props.filter.colDef,\n rowsLoading: props.filter.isLoading,\n },\n}));\n\nconst handleSeeMore = () => {\n if (hasMoreLocalUnselected.value) {\n visibleUnselectedCount.value += UNSELECTED_PAGE_SIZE;\n } else if (props.filter.hasMore) {\n emit(\"load-more\", searchText.value.trim());\n }\n};\n\nconst handleSeeMoreChildren = (parent: PvFilterPanelOption) => {\n emit(\"load-more\", searchText.value.trim(), parent.value);\n};\n\nconst handleToggle = (event: Event) => {\n const detailsElement = event.target as HTMLDetailsElement;\n emit(\"open-change\", detailsElement.open);\n};\n\nconst emitBooleanChange = (value: boolean | null) => {\n emit(\"filter-change\", { type: \"boolean\", value });\n};\n\nconst emitExistsChange = (value: boolean | undefined) => {\n emit(\"filter-change\", { type: \"exists\", value: value === true });\n};\n\nconst emitRangeChange = (value: PvRangeValue) => {\n emit(\"filter-change\", { type: \"range\", value });\n};\n\nconst handleToggleValue = (option: PvFilterPanelOption, checked: boolean) => {\n if (isAggregateFilter.value) {\n emit(\"filter-change\", {\n type: \"aggregate-selection\",\n value: updateFilterPanelAggregateSelectionState({\n checked,\n option,\n options: knownOptions.value,\n state: aggregateSelectionState.value,\n }),\n });\n return;\n }\n\n emit(\"filter-change\", {\n checked,\n field: getOptionFilterField(option),\n type: \"value\",\n value: getOptionFilterValue(option),\n });\n};\n\nconst handleFocusValue = (option: PvFilterPanelOption) => {\n emit(\"focus-change\", getOptionFilterField(option), getOptionFilterValue(option), option);\n};\n\nconst handleGroupToggle = (field: string, isActive: boolean) => {\n emit(\"filter-change\", { field, type: \"boolean\", value: isActive ? null : true });\n};\n\nconst handleSettingsClick = () => {\n emit(\"handle-settings-icon\", props.filter.key, props.filter.colDef);\n};\n\nwatch([searchText, () => props.filter.key], () => {\n visibleUnselectedCount.value = UNSELECTED_PAGE_SIZE;\n});\n\nconst syncKnownOptionMap = () => {\n const flattenedOptions = flattenFilterPanelOptions(knownOptions.value);\n const nextOptionMap = { ...knownOptionMap.value };\n const entries = new Map(Object.entries(nextOptionMap));\n for (const option of flattenedOptions) {\n entries.delete(option.value);\n entries.set(option.value, option);\n }\n\n knownOptionMap.value = Object.fromEntries(\n [...entries.entries()].slice(Math.max(0, entries.size - KNOWN_OPTION_MAP_MAX_SIZE)),\n );\n};\n\nwatch(\n knownOptions,\n () => {\n if (props.filter.isOpen) syncKnownOptionMap();\n },\n { immediate: true },\n);\n\nwatch(\n () => props.filter.isOpen,\n (isOpen) => {\n if (isOpen) syncKnownOptionMap();\n else knownOptionMap.value = {};\n },\n);\n\nwatch(\n () => props.filter.searchQuery,\n (query) => {\n const nextQuery = query ?? \"\";\n if (nextQuery !== searchText.value) {\n searchText.value = nextQuery;\n }\n },\n);\n\nwatchDebounced(\n searchText,\n (query) => {\n if (!isValueFilter.value) return;\n\n const trimmedQuery = query.trim();\n const currentPropQuery = (props.filter.searchQuery ?? \"\").trim();\n if (trimmedQuery !== currentPropQuery) {\n emit(\"search-change\", trimmedQuery);\n }\n },\n { debounce: 300, maxWait: 1000 },\n);\n</script>\n\n<template>\n <details class=\"pv-accordion\" data-testid=\"pv-filter-panel-accordion\" :open=\"filter.isOpen\" @toggle=\"handleToggle\">\n <summary class=\"pv-flex pv-text-body-md\" style=\"--flex-align: center; --flex-gap: 0.5rem\">\n <PvIcon aria-hidden=\"true\" class=\"pv-text-subdued\" :name=\"filter.isOpen ? 'chevron-down' : 'chevron-right'\" />\n <span>{{ filter.label }}</span>\n <PvCounterBadge v-if=\"counter\" :value=\"counter\" size=\"sm\" variant=\"secondary\" />\n </summary>\n\n <div class=\"pv-flex-vertical pv-surface-accent pv-inset-inline-24\" style=\"--flex-align: stretch\">\n <template v-if=\"isValueFilter\">\n <div\n v-if=\"filter.filterGroupOptions?.length || filter.displayPreferencesIcon || filter.filterHeaderRenderer\"\n class=\"pv-flex-vertical\"\n style=\"--flex-align: stretch; --flex-gap: 0.5rem\"\n >\n <div v-if=\"filter.filterGroupOptions?.length\" class=\"pv-flex\" style=\"--flex-gap: 0.5rem; --flex-wrap: wrap\">\n <PvButton\n v-for=\"groupOption in filter.filterGroupOptions\"\n :key=\"groupOption.field\"\n :disabled=\"filter.disabled\"\n :label=\"groupOption.label\"\n size=\"md\"\n :variant=\"groupOption.isActive ? 'primary' : 'secondary'\"\n @click=\"handleGroupToggle(groupOption.field, groupOption.isActive)\"\n />\n </div>\n <div v-if=\"filter.displayPreferencesIcon\" class=\"pv-flex\" style=\"--flex-justify: flex-end\">\n <PvButton\n ariaLabel=\"Open preferences\"\n :disabled=\"filter.disabled\"\n leftIcon=\"sliders-horizontal\"\n size=\"md\"\n variant=\"ghost\"\n @click=\"handleSettingsClick\"\n />\n </div>\n <component v-if=\"filter.filterHeaderRenderer\" :is=\"filter.filterHeaderRenderer\" v-bind=\"rendererSlotProps\" />\n </div>\n\n <PvSearchInput\n v-model=\"searchText\"\n class=\"pv-full-width\"\n :disabled=\"filter.disabled\"\n :placeholder=\"filter.searchPlaceholder ?? 'Search values'\"\n />\n\n <div v-if=\"selectedOptions.length\" class=\"pv-flex-vertical\" style=\"--flex-align: stretch; --flex-gap: 0.5rem\">\n <PvFilterPanelOptionRow\n v-for=\"option in selectedOptions\"\n :key=\"option.value\"\n :disabled=\"filter.disabled || option.isSelectable === false\"\n :focus-text=\"filter.focusText\"\n :is-focused=\"isOptionFocused(option)\"\n :indeterminate=\"isOptionIndeterminate(option)\"\n :label=\"getOptionDisplayLabel(option)\"\n :query-text=\"searchText\"\n :renderer=\"filter.filterOptionsRenderer\"\n :result-count=\"getOptionDisplayResultCount(option)\"\n :selected=\"true\"\n :show-focus-action=\"filter.isFocusable\"\n :sub-text=\"option.subText\"\n :subdued-text=\"option.subduedText\"\n :value=\"option.value\"\n @focus-value=\"() => handleFocusValue(option)\"\n @toggle-value=\"(_, checked) => handleToggleValue(option, checked)\"\n />\n </div>\n\n <div v-if=\"filter.isLoading\">\n <PvSpinner size=\"sm\" />\n </div>\n <template v-else>\n <template v-if=\"!filterOptions.length && !selectedOptions.length && !showSeeMoreButton\">\n <component\n v-if=\"filter.emptyResultsRenderer\"\n :is=\"filter.emptyResultsRenderer\"\n v-bind=\"rendererSlotProps\"\n empty-reason=\"no-values\"\n />\n <p v-else class=\"pv-text-body-xs pv-text-subdued\" style=\"margin: 0\">No values available.</p>\n </template>\n <template v-else-if=\"!displayedOptions.length && !selectedOptions.length && !showSeeMoreButton\">\n <component\n v-if=\"filter.emptyResultsRenderer\"\n :is=\"filter.emptyResultsRenderer\"\n v-bind=\"rendererSlotProps\"\n empty-reason=\"no-matches\"\n />\n <p v-else class=\"pv-text-body-xs pv-text-subdued\" style=\"margin: 0\">No matching values.</p>\n </template>\n\n <div\n v-if=\"unselectedOptions.length || showSeeMoreButton\"\n class=\"pv-flex-vertical\"\n style=\"--flex-align: stretch; --flex-gap: 0.5rem\"\n >\n <div v-if=\"unselectedOptions.length\">\n <PvTooltipV2\n v-if=\"filter.filterOptionsSortTooltip\"\n variant=\"dark\"\n :disableInteractive=\"true\"\n position=\"top-left\"\n size=\"sm\"\n :use-teleport=\"true\"\n style=\"--max-width: 200px\"\n >\n <template #trigger>\n <p class=\"pv-text-title-sm pv-text-subdued suggested-title-label\" style=\"margin: 0\">\n {{ optionsSortLabel }}\n </p>\n </template>\n <template #content>\n {{ filter.filterOptionsSortTooltip }}\n </template>\n </PvTooltipV2>\n <p v-else class=\"pv-text-title-sm pv-text-subdued\" style=\"margin: 0\">{{ optionsSortLabel }}</p>\n </div>\n <template\n v-for=\"item in visibleUnselectedOptions\"\n :key=\"item.kind === 'option' ? item.option.value : `${item.parent.value}-children-more`\"\n >\n <PvFilterPanelOptionRow\n v-if=\"item.kind === 'option'\"\n :depth=\"item.depth\"\n :disabled=\"filter.disabled || item.option.isSelectable === false\"\n :focus-text=\"filter.focusText\"\n :is-focused=\"isOptionFocused(item.option)\"\n :indeterminate=\"isOptionIndeterminate(item.option)\"\n :label=\"getOptionDisplayLabel(item.option)\"\n :query-text=\"searchText\"\n :renderer=\"filter.filterOptionsRenderer\"\n :result-count=\"getOptionDisplayResultCount(item.option)\"\n :selected=\"isOptionSelected(item.option)\"\n :show-focus-action=\"filter.isFocusable\"\n :sub-text=\"item.option.subText\"\n :subdued-text=\"item.option.subduedText\"\n :value=\"item.option.value\"\n @focus-value=\"() => handleFocusValue(item.option)\"\n @toggle-value=\"(_, checked) => handleToggleValue(item.option, checked)\"\n />\n <PvButton\n v-else\n class=\"pv-text-brand\"\n :disabled=\"filter.disabled || filter.isLoadingMore\"\n label=\"See more\"\n :style=\"{ marginLeft: `${item.depth * 1.25}rem`, width: 'fit-content' }\"\n variant=\"ghost\"\n @click=\"handleSeeMoreChildren(item.parent)\"\n />\n </template>\n <PvButton\n v-if=\"showSeeMoreButton\"\n class=\"pv-text-brand\"\n :disabled=\"filter.disabled || filter.isLoadingMore\"\n label=\"See more\"\n style=\"width: fit-content\"\n variant=\"ghost\"\n @click=\"handleSeeMore\"\n />\n </div>\n <component v-if=\"filter.filterFooterRenderer\" :is=\"filter.filterFooterRenderer\" v-bind=\"rendererSlotProps\" />\n </template>\n </template>\n\n <PvRange\n v-else-if=\"filterType === 'range' && filter.rangeMin !== null && filter.rangeMax !== null\"\n mode=\"dual\"\n :rangeValue=\"filter.rangeValue\"\n :data-type=\"filter.dataType\"\n :disabled=\"filter.disabled || filter.isLoading\"\n :label=\"filter.label\"\n :max=\"filter.rangeMax\"\n :min=\"filter.rangeMin\"\n :step=\"filter.rangeStep\"\n :value-decimals=\"filter.valueDecimals\"\n @update:rangeValue=\"emitRangeChange\"\n />\n <p v-else-if=\"filterType === 'range'\" class=\"pv-text-body-xs pv-text-subdued\" style=\"margin: 0\">\n Range filters require minimum and maximum bounds.\n </p>\n <div\n v-else-if=\"filterType === 'boolean'\"\n class=\"pv-flex-vertical\"\n data-testid=\"pv-filter-panel-boolean-control\"\n style=\"--flex-align: stretch; --flex-gap: 0.5rem\"\n >\n <div class=\"pv-flex\" style=\"--flex-align: center; --flex-gap: 0.5rem; --flex-wrap: wrap\">\n <PvButton\n :disabled=\"filter.disabled || filter.isLoading\"\n :label=\"trueLabel\"\n :variant=\"filter.booleanValue === true ? 'primary' : 'secondary'\"\n @click=\"emitBooleanChange(filter.booleanValue === true ? null : true)\"\n />\n <PvButton\n :disabled=\"filter.disabled || filter.isLoading\"\n :label=\"falseLabel\"\n :variant=\"filter.booleanValue === false ? 'primary' : 'secondary'\"\n @click=\"emitBooleanChange(filter.booleanValue === false ? null : false)\"\n />\n </div>\n <PvButton\n v-if=\"filter.booleanValue !== null && filter.booleanValue !== undefined\"\n class=\"pv-text-brand\"\n :disabled=\"filter.disabled || filter.isLoading\"\n label=\"Clear\"\n variant=\"ghost\"\n @click=\"emitBooleanChange(null)\"\n />\n </div>\n <label\n v-else-if=\"filterType === 'exists'\"\n class=\"pv-flex\"\n data-testid=\"pv-filter-panel-exists-control\"\n style=\"--flex-align: center; --flex-gap: 0.5rem; cursor: pointer\"\n >\n <PvCheckbox\n :disabled=\"filter.disabled || filter.isLoading\"\n :modelValue=\"filter.existsValue ?? false\"\n @update:modelValue=\"emitExistsChange\"\n />\n <span class=\"pv-text-body-sm\">{{ existsLabel }}</span>\n </label>\n </div>\n </details>\n</template>\n\n<style scoped>\nsummary {\n background-image: none;\n padding-right: 2px;\n}\n\n:deep(.pv-input-search) {\n background-color: white;\n}\n\n.suggested-title-label {\n text-decoration: underline;\n text-decoration-style: dotted;\n text-underline-offset: 2px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ref, watch } from \"vue\";\nimport { watchDebounced } from \"@vueuse/core\";\nimport type { MenuOption } from \"@/types\";\n\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport PvCounterBadge from \"@/components/base/PvCounterBadge/PvCounterBadge.vue\";\nimport PvCheckbox from \"@/components/base/PvCheckbox/PvCheckbox.vue\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport PvSearchInput from \"@/components/base/PvSearchInput/PvSearchInput.vue\";\nimport PvSpinner from \"@/components/base/PvSpinner/PvSpinner.vue\";\nimport PvTooltipV2 from \"@/components/base/PvTooltipV2/PvTooltipV2.vue\";\nimport PvRange from \"@/components/base/PvRange/PvRange.vue\";\nimport type { PvRangeValue } from \"@/components/base/PvRange/types\";\nimport PvFilterPanelOptionRow from \"./PvFilterPanelOptionRow.vue\";\nimport { getFilterOptionLabel, getFilterOptionResultCount } from \"./filterOptionDisplay\";\nimport {\n createFilterPanelAggregateSelectionStatusMap,\n getFilterPanelAggregateSelectionCount,\n updateFilterPanelAggregateSelectionState,\n} from \"./aggregateFilterModel\";\nimport {\n flattenFilterPanelOptions,\n getFilterPanelOptionField,\n getFilterPanelOptionRawValue,\n} from \"./filterOptionValue\";\nimport type {\n PvFilterPanelAccordionProps,\n PvFilterPanelControlChange,\n PvFilterPanelFilterType,\n PvFilterPanelOption,\n} from \"./types\";\n\nconst props = defineProps<PvFilterPanelAccordionProps>();\n\nconst emit = defineEmits<{\n \"focus-change\": [field: string, value: string, option: PvFilterPanelOption];\n \"handle-settings-icon\": [field: string, colDef: PvFilterPanelAccordionProps[\"filter\"][\"colDef\"]];\n \"load-more\": [query: string, parentId?: string];\n \"open-change\": [open: boolean];\n \"filter-change\": [change: PvFilterPanelControlChange];\n \"search-change\": [query: string];\n}>();\n\nconst UNSELECTED_PAGE_SIZE = 5;\nconst KNOWN_OPTION_MAP_MAX_SIZE = 500;\n\ninterface DisplayedFilterOptionRow {\n depth: number;\n kind: \"option\";\n option: PvFilterPanelOption;\n}\n\ninterface DisplayedFilterChildLoadMoreRow {\n depth: number;\n kind: \"child-load-more\";\n parent: PvFilterPanelOption;\n}\n\ntype DisplayedFilterOption = DisplayedFilterOptionRow | DisplayedFilterChildLoadMoreRow;\n\nconst knownOptionMap = ref<Record<string, PvFilterPanelOption>>({});\nconst searchText = ref(props.filter.searchQuery ?? \"\");\nconst visibleUnselectedCount = ref(UNSELECTED_PAGE_SIZE);\n\nconst existsLabel = computed(() => props.filter.existsLabel ?? `Has ${props.filter.label}`);\nconst falseLabel = computed(() => props.filter.valueLabels?.[\"false\"] ?? \"No\");\nconst filterOptions = computed(() => props.filter.options ?? []);\nconst knownOptions = computed(() => [...(props.filter.knownOptions ?? []), ...filterOptions.value]);\nconst filterType = computed<PvFilterPanelFilterType>(() => props.filter.type ?? \"value\");\nconst isValueFilter = computed(() => filterType.value === \"value\");\nconst isAggregateFilter = computed(() => isValueFilter.value && props.filter.isAggregate === true);\nconst aggregateSelectionState = computed(() => props.filter.aggregateSelectionState ?? []);\nconst normalizedSearchText = computed(() => searchText.value.trim().toLowerCase());\nconst selectedValues = computed(() => props.filter.selectedValues ?? []);\nconst selectedValueSet = computed(() => new Set(selectedValues.value));\nconst trueLabel = computed(() => props.filter.valueLabels?.[\"true\"] ?? \"Yes\");\nconst optionsSortLabel = computed(() => props.filter.filterOptionsSortDescription || \"Suggested\");\n\nconst getSearchableOptionText = (option: PvFilterPanelOption) => {\n const metadataValues =\n typeof option.metadata === \"object\" && option.metadata !== null ? Object.values(option.metadata) : [];\n return [option.value, option.label, option.subText, option.subduedText, option.matchedValue, option.matchedField]\n .concat(metadataValues.flatMap((value) => (value === null || value === undefined ? [] : [String(value)])))\n .filter((value): value is string => Boolean(value))\n .join(\" \")\n .toLowerCase();\n};\n\nconst counter = computed(() => {\n if (filterType.value === \"range\") {\n return props.filter.rangeValue?.min !== null && props.filter.rangeValue?.min !== undefined\n ? 1\n : props.filter.rangeValue?.max !== null && props.filter.rangeValue?.max !== undefined\n ? 1\n : undefined;\n }\n\n if (filterType.value === \"boolean\") {\n return props.filter.booleanValue !== null && props.filter.booleanValue !== undefined ? 1 : undefined;\n }\n\n if (filterType.value === \"exists\") return props.filter.existsValue ? 1 : undefined;\n if (isAggregateFilter.value) return getFilterPanelAggregateSelectionCount(aggregateSelectionState.value) || undefined;\n return selectedValues.value.length || undefined;\n});\n\nconst optionHasMoreChildren = (option: PvFilterPanelOption) => {\n if (option.totalChildCount === null || option.totalChildCount === undefined) return false;\n return option.totalChildCount > (option.children?.length ?? 0);\n};\n\nconst flattenOptions = (options: PvFilterPanelOption[], depth = 0): DisplayedFilterOption[] => {\n return options.flatMap((option) => [\n { depth, kind: \"option\", option } as DisplayedFilterOptionRow,\n ...(option.children?.length ? flattenOptions(option.children, depth + 1) : []),\n ...(optionHasMoreChildren(option)\n ? ([{ depth: depth + 1, kind: \"child-load-more\", parent: option }] as DisplayedFilterChildLoadMoreRow[])\n : []),\n ]);\n};\n\nconst displayedOptions = computed<DisplayedFilterOption[]>(() => {\n const flattenedOptions = flattenOptions(filterOptions.value);\n const query = normalizedSearchText.value;\n if (!query) return flattenedOptions;\n return flattenedOptions.filter(\n (item): item is DisplayedFilterOptionRow =>\n item.kind === \"option\" && getSearchableOptionText(item.option).includes(query),\n );\n});\nconst selectedOptions = computed(() =>\n isAggregateFilter.value\n ? []\n : selectedValues.value.map((value) => knownOptionMap.value[value] ?? { label: value, value }),\n);\nconst unselectedOptions = computed(() =>\n isAggregateFilter.value\n ? displayedOptions.value\n : displayedOptions.value.filter(\n (item) => item.kind === \"child-load-more\" || !selectedValueSet.value.has(item.option.value),\n ),\n);\nconst hasMoreLocalUnselected = computed(() => unselectedOptions.value.length > visibleUnselectedCount.value);\nconst showSeeMoreButton = computed(() => hasMoreLocalUnselected.value || props.filter.hasMore);\nconst visibleUnselectedOptions = computed(() => unselectedOptions.value.slice(0, visibleUnselectedCount.value));\n\nconst aggregateSelectionStatusMap = computed(() =>\n isAggregateFilter.value\n ? createFilterPanelAggregateSelectionStatusMap({\n options: knownOptions.value,\n state: aggregateSelectionState.value,\n })\n : new Map<string, { indeterminate: boolean; selected: boolean }>(),\n);\n\nconst getOptionDisplayLabel = (option: PvFilterPanelOption) => getFilterOptionLabel(option, props.filter.colDef);\nconst getOptionDisplayResultCount = (option: PvFilterPanelOption) => getFilterOptionResultCount(option);\nconst getOptionSelectionStatus = (option: PvFilterPanelOption) => {\n if (!isAggregateFilter.value) return { indeterminate: false, selected: selectedValueSet.value.has(option.value) };\n return aggregateSelectionStatusMap.value.get(option.value) ?? { indeterminate: false, selected: false };\n};\nconst isOptionSelected = (option: PvFilterPanelOption) => getOptionSelectionStatus(option).selected;\nconst isOptionIndeterminate = (option: PvFilterPanelOption) => getOptionSelectionStatus(option).indeterminate;\n\nconst getOptionFilterValue = (option: PvFilterPanelOption) => getFilterPanelOptionRawValue(option) ?? option.value;\nconst getOptionFilterField = (option: PvFilterPanelOption) => getFilterPanelOptionField(option, props.filter.key);\n\nconst isOptionFocused = (option: PvFilterPanelOption) => {\n const field = getOptionFilterField(option);\n const rawValue = getOptionFilterValue(option);\n return (\n props.filter.focusedValuesByField?.[field]?.includes(rawValue) ||\n (field === props.filter.key && props.filter.focusedValues?.includes(option.value)) ||\n false\n );\n};\n\nconst toMenuOption = (option: PvFilterPanelOption): MenuOption<PvFilterPanelOption> => ({\n ...(option.menuOption ?? {}),\n children: option.children?.map(toMenuOption),\n context: option,\n disabled: props.filter.disabled || option.isSelectable === false || option.menuOption?.disabled,\n id: option.value,\n searchText: getSearchableOptionText(option),\n secondaryText: getOptionDisplayResultCount(option),\n subText: option.subText,\n subduedText: option.subduedText,\n text: getOptionDisplayLabel(option),\n totalChildCount: option.totalChildCount,\n});\n\nconst rendererOptions = computed(() => filterOptions.value.map(toMenuOption));\nconst rendererSelectedItems = computed(() => selectedOptions.value.map(toMenuOption));\nconst rendererSlotProps = computed(() => ({\n colDef: props.filter.colDef,\n disabled: props.filter.disabled,\n filter: props.filter,\n isLoading: props.filter.isLoading,\n isOpen: props.filter.isOpen,\n options: rendererOptions.value,\n searchInput: searchText.value,\n selectedItems: rendererSelectedItems.value,\n slotContext: {\n colDef: props.filter.colDef,\n rowsLoading: props.filter.isLoading,\n },\n}));\n\nconst handleSeeMore = () => {\n if (hasMoreLocalUnselected.value) {\n visibleUnselectedCount.value += UNSELECTED_PAGE_SIZE;\n } else if (props.filter.hasMore) {\n emit(\"load-more\", searchText.value.trim());\n }\n};\n\nconst handleSeeMoreChildren = (parent: PvFilterPanelOption) => {\n emit(\"load-more\", searchText.value.trim(), parent.value);\n};\n\nconst handleToggle = (event: Event) => {\n const detailsElement = event.target as HTMLDetailsElement;\n emit(\"open-change\", detailsElement.open);\n};\n\nconst emitBooleanChange = (value: boolean | null) => {\n emit(\"filter-change\", { type: \"boolean\", value });\n};\n\nconst emitExistsChange = (value: boolean | undefined) => {\n emit(\"filter-change\", { type: \"exists\", value: value === true });\n};\n\nconst emitRangeChange = (value: PvRangeValue) => {\n emit(\"filter-change\", { type: \"range\", value });\n};\n\nconst handleToggleValue = (option: PvFilterPanelOption, checked: boolean) => {\n if (isAggregateFilter.value) {\n emit(\"filter-change\", {\n type: \"aggregate-selection\",\n value: updateFilterPanelAggregateSelectionState({\n checked,\n option,\n options: knownOptions.value,\n state: aggregateSelectionState.value,\n }),\n });\n return;\n }\n\n emit(\"filter-change\", {\n checked,\n field: getOptionFilterField(option),\n type: \"value\",\n value: getOptionFilterValue(option),\n });\n};\n\nconst handleFocusValue = (option: PvFilterPanelOption) => {\n emit(\"focus-change\", getOptionFilterField(option), getOptionFilterValue(option), option);\n};\n\nconst handleGroupToggle = (field: string, isActive: boolean) => {\n emit(\"filter-change\", { field, type: \"boolean\", value: isActive ? null : true });\n};\n\nconst handleSettingsClick = () => {\n emit(\"handle-settings-icon\", props.filter.key, props.filter.colDef);\n};\n\nwatch([searchText, () => props.filter.key], () => {\n visibleUnselectedCount.value = UNSELECTED_PAGE_SIZE;\n});\n\nconst syncKnownOptionMap = () => {\n const flattenedOptions = flattenFilterPanelOptions(knownOptions.value);\n const nextOptionMap = { ...knownOptionMap.value };\n const entries = new Map(Object.entries(nextOptionMap));\n for (const option of flattenedOptions) {\n entries.delete(option.value);\n entries.set(option.value, option);\n }\n\n knownOptionMap.value = Object.fromEntries(\n [...entries.entries()].slice(Math.max(0, entries.size - KNOWN_OPTION_MAP_MAX_SIZE)),\n );\n};\n\nwatch(\n knownOptions,\n () => {\n if (props.filter.isOpen) syncKnownOptionMap();\n },\n { immediate: true },\n);\n\nwatch(\n () => props.filter.isOpen,\n (isOpen) => {\n if (isOpen) syncKnownOptionMap();\n else knownOptionMap.value = {};\n },\n);\n\nwatch(\n () => props.filter.searchQuery,\n (query) => {\n const nextQuery = query ?? \"\";\n if (nextQuery !== searchText.value) {\n searchText.value = nextQuery;\n }\n },\n);\n\nwatchDebounced(\n searchText,\n (query) => {\n if (!isValueFilter.value) return;\n\n const trimmedQuery = query.trim();\n const currentPropQuery = (props.filter.searchQuery ?? \"\").trim();\n if (trimmedQuery !== currentPropQuery) {\n emit(\"search-change\", trimmedQuery);\n }\n },\n { debounce: 300, maxWait: 1000 },\n);\n</script>\n\n<template>\n <details class=\"pv-accordion\" data-testid=\"pv-filter-panel-accordion\" :open=\"filter.isOpen\" @toggle=\"handleToggle\">\n <summary class=\"pv-flex pv-text-body-md\" style=\"--flex-align: center; --flex-gap: 0.5rem\">\n <PvIcon aria-hidden=\"true\" class=\"pv-text-subdued\" :name=\"filter.isOpen ? 'chevron-down' : 'chevron-right'\" />\n <span>{{ filter.label }}</span>\n <PvCounterBadge v-if=\"counter\" :value=\"counter\" size=\"sm\" variant=\"secondary\" />\n </summary>\n\n <div class=\"pv-flex-vertical pv-surface-accent pv-inset-inline-24\" style=\"--flex-align: stretch\">\n <template v-if=\"isValueFilter\">\n <div\n v-if=\"filter.filterGroupOptions?.length || filter.displayPreferencesIcon || filter.filterHeaderRenderer\"\n class=\"pv-flex-vertical\"\n style=\"--flex-align: stretch; --flex-gap: 0.5rem\"\n >\n <div v-if=\"filter.filterGroupOptions?.length\" class=\"pv-flex\" style=\"--flex-gap: 0.5rem; --flex-wrap: wrap\">\n <PvButton\n v-for=\"groupOption in filter.filterGroupOptions\"\n :key=\"groupOption.field\"\n :disabled=\"filter.disabled\"\n :label=\"groupOption.label\"\n size=\"md\"\n :variant=\"groupOption.isActive ? 'primary' : 'secondary'\"\n @click=\"handleGroupToggle(groupOption.field, groupOption.isActive)\"\n />\n </div>\n <div v-if=\"filter.displayPreferencesIcon\" class=\"pv-flex\" style=\"--flex-justify: flex-end\">\n <PvButton\n ariaLabel=\"Open preferences\"\n :disabled=\"filter.disabled\"\n leftIcon=\"sliders-horizontal\"\n size=\"md\"\n variant=\"ghost\"\n @click=\"handleSettingsClick\"\n />\n </div>\n <component v-if=\"filter.filterHeaderRenderer\" :is=\"filter.filterHeaderRenderer\" v-bind=\"rendererSlotProps\" />\n </div>\n\n <PvSearchInput\n v-model=\"searchText\"\n class=\"pv-full-width\"\n :disabled=\"filter.disabled\"\n :placeholder=\"filter.searchPlaceholder ?? 'Search values'\"\n />\n\n <div v-if=\"selectedOptions.length\" class=\"pv-flex-vertical\" style=\"--flex-align: stretch; --flex-gap: 0.5rem\">\n <PvFilterPanelOptionRow\n v-for=\"option in selectedOptions\"\n :key=\"option.value\"\n :disabled=\"filter.disabled || option.isSelectable === false\"\n :focus-text=\"filter.focusText\"\n :is-focused=\"isOptionFocused(option)\"\n :indeterminate=\"isOptionIndeterminate(option)\"\n :label=\"getOptionDisplayLabel(option)\"\n :query-text=\"searchText\"\n :renderer=\"filter.filterOptionsRenderer\"\n :result-count=\"getOptionDisplayResultCount(option)\"\n :selected=\"true\"\n :show-focus-action=\"filter.isFocusable\"\n :sub-text=\"option.subText\"\n :subdued-text=\"option.subduedText\"\n :value=\"option.value\"\n @focus-value=\"() => handleFocusValue(option)\"\n @toggle-value=\"(_, checked) => handleToggleValue(option, checked)\"\n />\n </div>\n\n <div v-if=\"filter.isLoading\">\n <PvSpinner size=\"sm\" />\n </div>\n <template v-else>\n <template v-if=\"!filterOptions.length && !selectedOptions.length && !showSeeMoreButton\">\n <component\n v-if=\"filter.emptyResultsRenderer\"\n :is=\"filter.emptyResultsRenderer\"\n v-bind=\"rendererSlotProps\"\n empty-reason=\"no-values\"\n />\n <p v-else class=\"pv-text-body-xs pv-text-subdued\" style=\"margin: 0\">No values available.</p>\n </template>\n <template v-else-if=\"!displayedOptions.length && !selectedOptions.length && !showSeeMoreButton\">\n <component\n v-if=\"filter.emptyResultsRenderer\"\n :is=\"filter.emptyResultsRenderer\"\n v-bind=\"rendererSlotProps\"\n empty-reason=\"no-matches\"\n />\n <p v-else class=\"pv-text-body-xs pv-text-subdued\" style=\"margin: 0\">No matching values.</p>\n </template>\n\n <div\n v-if=\"unselectedOptions.length || showSeeMoreButton\"\n class=\"pv-flex-vertical\"\n style=\"--flex-align: stretch; --flex-gap: 0.5rem\"\n >\n <div v-if=\"unselectedOptions.length\">\n <PvTooltipV2\n v-if=\"filter.filterOptionsSortTooltip\"\n variant=\"dark\"\n :disableInteractive=\"true\"\n position=\"top-left\"\n size=\"sm\"\n :use-teleport=\"true\"\n style=\"--max-width: 200px\"\n >\n <template #trigger>\n <p class=\"pv-text-title-sm pv-text-subdued suggested-title-label\" style=\"margin: 0\">\n {{ optionsSortLabel }}\n </p>\n </template>\n <template #content>\n {{ filter.filterOptionsSortTooltip }}\n </template>\n </PvTooltipV2>\n <p v-else class=\"pv-text-title-sm pv-text-subdued\" style=\"margin: 0\">{{ optionsSortLabel }}</p>\n </div>\n <template\n v-for=\"item in visibleUnselectedOptions\"\n :key=\"item.kind === 'option' ? item.option.value : `${item.parent.value}-children-more`\"\n >\n <PvFilterPanelOptionRow\n v-if=\"item.kind === 'option'\"\n :depth=\"item.depth\"\n :disabled=\"filter.disabled || item.option.isSelectable === false\"\n :focus-text=\"filter.focusText\"\n :is-focused=\"isOptionFocused(item.option)\"\n :indeterminate=\"isOptionIndeterminate(item.option)\"\n :label=\"getOptionDisplayLabel(item.option)\"\n :query-text=\"searchText\"\n :renderer=\"filter.filterOptionsRenderer\"\n :result-count=\"getOptionDisplayResultCount(item.option)\"\n :selected=\"isOptionSelected(item.option)\"\n :show-focus-action=\"filter.isFocusable\"\n :sub-text=\"item.option.subText\"\n :subdued-text=\"item.option.subduedText\"\n :value=\"item.option.value\"\n @focus-value=\"() => handleFocusValue(item.option)\"\n @toggle-value=\"(_, checked) => handleToggleValue(item.option, checked)\"\n />\n <PvButton\n v-else\n class=\"pv-text-brand\"\n :disabled=\"filter.disabled || filter.isLoadingMore\"\n label=\"See more\"\n :style=\"{ marginLeft: `${item.depth * 1.25}rem`, width: 'fit-content' }\"\n variant=\"ghost\"\n @click=\"handleSeeMoreChildren(item.parent)\"\n />\n </template>\n <PvButton\n v-if=\"showSeeMoreButton\"\n class=\"pv-text-brand\"\n :disabled=\"filter.disabled || filter.isLoadingMore\"\n label=\"See more\"\n style=\"width: fit-content\"\n variant=\"ghost\"\n @click=\"handleSeeMore\"\n />\n </div>\n <component v-if=\"filter.filterFooterRenderer\" :is=\"filter.filterFooterRenderer\" v-bind=\"rendererSlotProps\" />\n </template>\n </template>\n\n <PvRange\n v-else-if=\"filterType === 'range' && filter.rangeMin !== null && filter.rangeMax !== null\"\n mode=\"dual\"\n :rangeValue=\"filter.rangeValue\"\n :data-type=\"filter.dataType\"\n :disabled=\"filter.disabled || filter.isLoading\"\n :label=\"filter.label\"\n :max=\"filter.rangeMax\"\n :min=\"filter.rangeMin\"\n :step=\"filter.rangeStep\"\n :value-decimals=\"filter.valueDecimals\"\n @update:rangeValue=\"emitRangeChange\"\n />\n <p v-else-if=\"filterType === 'range'\" class=\"pv-text-body-xs pv-text-subdued\" style=\"margin: 0\">\n Range filters require minimum and maximum bounds.\n </p>\n <div\n v-else-if=\"filterType === 'boolean'\"\n class=\"pv-flex-vertical\"\n data-testid=\"pv-filter-panel-boolean-control\"\n style=\"--flex-align: stretch; --flex-gap: 0.5rem\"\n >\n <div class=\"pv-flex\" style=\"--flex-align: center; --flex-gap: 0.5rem; --flex-wrap: wrap\">\n <PvButton\n :disabled=\"filter.disabled || filter.isLoading\"\n :label=\"trueLabel\"\n :variant=\"filter.booleanValue === true ? 'primary' : 'secondary'\"\n @click=\"emitBooleanChange(filter.booleanValue === true ? null : true)\"\n />\n <PvButton\n :disabled=\"filter.disabled || filter.isLoading\"\n :label=\"falseLabel\"\n :variant=\"filter.booleanValue === false ? 'primary' : 'secondary'\"\n @click=\"emitBooleanChange(filter.booleanValue === false ? null : false)\"\n />\n </div>\n <PvButton\n v-if=\"filter.booleanValue !== null && filter.booleanValue !== undefined\"\n class=\"pv-text-brand\"\n :disabled=\"filter.disabled || filter.isLoading\"\n label=\"Clear\"\n variant=\"ghost\"\n @click=\"emitBooleanChange(null)\"\n />\n </div>\n <label\n v-else-if=\"filterType === 'exists'\"\n class=\"pv-flex\"\n data-testid=\"pv-filter-panel-exists-control\"\n style=\"--flex-align: center; --flex-gap: 0.5rem; cursor: pointer\"\n >\n <PvCheckbox\n :disabled=\"filter.disabled || filter.isLoading\"\n :modelValue=\"filter.existsValue ?? false\"\n @update:modelValue=\"emitExistsChange\"\n />\n <span class=\"pv-text-body-sm\">{{ existsLabel }}</span>\n </label>\n </div>\n </details>\n</template>\n\n<style scoped>\nsummary {\n background-image: none;\n padding-right: 2px;\n}\n\n:deep(.pv-input-search) {\n background-color: white;\n}\n\n.suggested-title-label {\n text-decoration: underline;\n text-decoration-style: dotted;\n text-underline-offset: 2px;\n}\n</style>\n","<script setup lang=\"ts\">\nimport PvTag from \"@/components/base/PvTag/PvTag.vue\";\nimport type {\n PvFilterPanelAppliedFiltersSectionProps,\n PvFilterPanelAppliedValue,\n PvFilterPanelFilterType,\n} from \"./types\";\n\nwithDefaults(defineProps<PvFilterPanelAppliedFiltersSectionProps>(), {\n appliedCount: 0,\n appliedGroups: () => [],\n readOnly: false,\n});\n\nconst emit = defineEmits<{\n \"remove-filter\": [filterKey: string, value: string, type?: PvFilterPanelFilterType];\n}>();\n\nconst handleRemoveFilter = (filterKey: string, item: PvFilterPanelAppliedValue) => {\n emit(\"remove-filter\", item.field ?? filterKey, item.value, item.type);\n};\n</script>\n\n<template>\n <section\n class=\"pv-flex-vertical pv-inset-square-8\"\n data-testid=\"pv-filter-panel-applied-section\"\n style=\"--flex-align: stretch; --flex-gap: 1rem\"\n >\n <div v-if=\"appliedCount\" class=\"pv-flex-vertical\" style=\"--flex-align: stretch; --flex-gap: 1rem\">\n <div\n v-for=\"group in appliedGroups\"\n :key=\"group.key\"\n class=\"pv-flex-vertical pv-border-bottom\"\n style=\"--flex-align: stretch; padding-bottom: 4px\"\n >\n <span class=\"pv-text-title-md pv-stack-8\">{{ group.label }}</span>\n <div class=\"pv-flex\" style=\"--flex-gap: 0.375rem; --flex-wrap: wrap\">\n <PvTag\n v-for=\"item in group.values\"\n :key=\"`${item.field ?? group.key}-${item.type ?? 'value'}-${item.value}`\"\n :label=\"item.label\"\n :showClear=\"!readOnly\"\n @handle-close=\"handleRemoveFilter(group.key, item)\"\n />\n </div>\n </div>\n </div>\n <p v-else class=\"pv-text-body-sm pv-text-subdued\" style=\"margin: 0\">No filters applied yet.</p>\n </section>\n</template>\n","<script setup lang=\"ts\">\nimport PvTag from \"@/components/base/PvTag/PvTag.vue\";\nimport type {\n PvFilterPanelAppliedFiltersSectionProps,\n PvFilterPanelAppliedValue,\n PvFilterPanelFilterType,\n} from \"./types\";\n\nwithDefaults(defineProps<PvFilterPanelAppliedFiltersSectionProps>(), {\n appliedCount: 0,\n appliedGroups: () => [],\n readOnly: false,\n});\n\nconst emit = defineEmits<{\n \"remove-filter\": [filterKey: string, value: string, type?: PvFilterPanelFilterType];\n}>();\n\nconst handleRemoveFilter = (filterKey: string, item: PvFilterPanelAppliedValue) => {\n emit(\"remove-filter\", item.field ?? filterKey, item.value, item.type);\n};\n</script>\n\n<template>\n <section\n class=\"pv-flex-vertical pv-inset-square-8\"\n data-testid=\"pv-filter-panel-applied-section\"\n style=\"--flex-align: stretch; --flex-gap: 1rem\"\n >\n <div v-if=\"appliedCount\" class=\"pv-flex-vertical\" style=\"--flex-align: stretch; --flex-gap: 1rem\">\n <div\n v-for=\"group in appliedGroups\"\n :key=\"group.key\"\n class=\"pv-flex-vertical pv-border-bottom\"\n style=\"--flex-align: stretch; padding-bottom: 4px\"\n >\n <span class=\"pv-text-title-md pv-stack-8\">{{ group.label }}</span>\n <div class=\"pv-flex\" style=\"--flex-gap: 0.375rem; --flex-wrap: wrap\">\n <PvTag\n v-for=\"item in group.values\"\n :key=\"`${item.field ?? group.key}-${item.type ?? 'value'}-${item.value}`\"\n :label=\"item.label\"\n :showClear=\"!readOnly\"\n @handle-close=\"handleRemoveFilter(group.key, item)\"\n />\n </div>\n </div>\n </div>\n <p v-else class=\"pv-text-body-sm pv-text-subdued\" style=\"margin: 0\">No filters applied yet.</p>\n </section>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, nextTick, onBeforeUnmount, onMounted, onUpdated, ref } from \"vue\";\n\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport type { PvHorizontalScrollerProps } from \"./types\";\n\nconst props = withDefaults(defineProps<PvHorizontalScrollerProps>(), {\n ariaLabel: \"Scrollable content\",\n buttonSize: \"md\",\n buttonVariant: \"secondary\",\n hideScrollbar: false,\n leftAriaLabel: \"Scroll left\",\n rightAriaLabel: \"Scroll right\",\n scrollBehavior: \"smooth\",\n scrollFraction: 0.8,\n showFades: false,\n});\n\nconst SCROLL_EPSILON = 1;\n\nconst canScrollLeft = ref(false);\nconst canScrollRight = ref(false);\nconst contentContainer = ref<HTMLElement | null>(null);\nconst scrollContainer = ref<HTMLElement | null>(null);\n\nlet resizeObserver: ResizeObserver | null = null;\nlet usingWindowResizeFallback = false;\n\nconst normalizedScrollFraction = computed(() => Math.max(0, props.scrollFraction));\n\nconst updateScrollState = () => {\n const el = scrollContainer.value;\n if (!el) return;\n\n const maxScrollLeft = Math.max(0, el.scrollWidth - el.clientWidth);\n canScrollLeft.value = el.scrollLeft > SCROLL_EPSILON;\n canScrollRight.value = el.scrollLeft < maxScrollLeft - SCROLL_EPSILON;\n};\n\nconst observeResizeTargets = () => {\n if (!resizeObserver) return;\n\n resizeObserver.disconnect();\n if (scrollContainer.value) resizeObserver.observe(scrollContainer.value);\n if (contentContainer.value) resizeObserver.observe(contentContainer.value);\n};\n\nconst queueScrollStateUpdate = () => {\n void nextTick(updateScrollState);\n};\n\nconst scrollByDirection = (direction: 1 | -1) => {\n const el = scrollContainer.value;\n if (!el) return;\n\n const left = direction * el.clientWidth * normalizedScrollFraction.value;\n if (typeof el.scrollBy === \"function\") {\n el.scrollBy({ behavior: props.scrollBehavior, left });\n } else {\n el.scrollLeft += left;\n }\n\n updateScrollState();\n if (typeof window.requestAnimationFrame === \"function\") {\n window.requestAnimationFrame(updateScrollState);\n }\n};\n\nonMounted(() => {\n scrollContainer.value?.addEventListener(\"scroll\", updateScrollState, { passive: true });\n\n if (typeof ResizeObserver !== \"undefined\") {\n resizeObserver = new ResizeObserver(() => updateScrollState());\n observeResizeTargets();\n } else {\n usingWindowResizeFallback = true;\n window.addEventListener(\"resize\", updateScrollState);\n }\n\n queueScrollStateUpdate();\n});\n\nonUpdated(() => {\n observeResizeTargets();\n queueScrollStateUpdate();\n});\n\nonBeforeUnmount(() => {\n scrollContainer.value?.removeEventListener(\"scroll\", updateScrollState);\n resizeObserver?.disconnect();\n\n if (usingWindowResizeFallback) {\n window.removeEventListener(\"resize\", updateScrollState);\n }\n});\n</script>\n\n<template>\n <div class=\"pv-horizontal-scroller\">\n <div\n ref=\"scrollContainer\"\n class=\"pv-horizontal-scroller-scroll\"\n :class=\"{ 'pv-horizontal-scroller-scroll-hidden-scrollbar': hideScrollbar }\"\n role=\"region\"\n :aria-label=\"ariaLabel\"\n >\n <div ref=\"contentContainer\" class=\"pv-horizontal-scroller-content\">\n <slot />\n </div>\n </div>\n\n <div\n class=\"pv-horizontal-scroller-control pv-horizontal-scroller-control-left\"\n :class=\"{\n 'pv-horizontal-scroller-control-hidden': !canScrollLeft,\n 'pv-horizontal-scroller-control-left-fade': showFades,\n }\"\n >\n <PvButton\n v-if=\"canScrollLeft\"\n :ariaLabel=\"leftAriaLabel\"\n leftIcon=\"chevron-left\"\n :size=\"buttonSize\"\n :variant=\"buttonVariant\"\n @click=\"scrollByDirection(-1)\"\n />\n </div>\n\n <div\n class=\"pv-horizontal-scroller-control pv-horizontal-scroller-control-right\"\n :class=\"{\n 'pv-horizontal-scroller-control-hidden': !canScrollRight,\n 'pv-horizontal-scroller-control-right-fade': showFades,\n }\"\n >\n <PvButton\n v-if=\"canScrollRight\"\n :ariaLabel=\"rightAriaLabel\"\n leftIcon=\"chevron-right\"\n :size=\"buttonSize\"\n :variant=\"buttonVariant\"\n @click=\"scrollByDirection(1)\"\n />\n </div>\n </div>\n</template>\n\n","<script setup lang=\"ts\">\nimport { computed, nextTick, onBeforeUnmount, onMounted, onUpdated, ref } from \"vue\";\n\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport type { PvHorizontalScrollerProps } from \"./types\";\n\nconst props = withDefaults(defineProps<PvHorizontalScrollerProps>(), {\n ariaLabel: \"Scrollable content\",\n buttonSize: \"md\",\n buttonVariant: \"secondary\",\n hideScrollbar: false,\n leftAriaLabel: \"Scroll left\",\n rightAriaLabel: \"Scroll right\",\n scrollBehavior: \"smooth\",\n scrollFraction: 0.8,\n showFades: false,\n});\n\nconst SCROLL_EPSILON = 1;\n\nconst canScrollLeft = ref(false);\nconst canScrollRight = ref(false);\nconst contentContainer = ref<HTMLElement | null>(null);\nconst scrollContainer = ref<HTMLElement | null>(null);\n\nlet resizeObserver: ResizeObserver | null = null;\nlet usingWindowResizeFallback = false;\n\nconst normalizedScrollFraction = computed(() => Math.max(0, props.scrollFraction));\n\nconst updateScrollState = () => {\n const el = scrollContainer.value;\n if (!el) return;\n\n const maxScrollLeft = Math.max(0, el.scrollWidth - el.clientWidth);\n canScrollLeft.value = el.scrollLeft > SCROLL_EPSILON;\n canScrollRight.value = el.scrollLeft < maxScrollLeft - SCROLL_EPSILON;\n};\n\nconst observeResizeTargets = () => {\n if (!resizeObserver) return;\n\n resizeObserver.disconnect();\n if (scrollContainer.value) resizeObserver.observe(scrollContainer.value);\n if (contentContainer.value) resizeObserver.observe(contentContainer.value);\n};\n\nconst queueScrollStateUpdate = () => {\n void nextTick(updateScrollState);\n};\n\nconst scrollByDirection = (direction: 1 | -1) => {\n const el = scrollContainer.value;\n if (!el) return;\n\n const left = direction * el.clientWidth * normalizedScrollFraction.value;\n if (typeof el.scrollBy === \"function\") {\n el.scrollBy({ behavior: props.scrollBehavior, left });\n } else {\n el.scrollLeft += left;\n }\n\n updateScrollState();\n if (typeof window.requestAnimationFrame === \"function\") {\n window.requestAnimationFrame(updateScrollState);\n }\n};\n\nonMounted(() => {\n scrollContainer.value?.addEventListener(\"scroll\", updateScrollState, { passive: true });\n\n if (typeof ResizeObserver !== \"undefined\") {\n resizeObserver = new ResizeObserver(() => updateScrollState());\n observeResizeTargets();\n } else {\n usingWindowResizeFallback = true;\n window.addEventListener(\"resize\", updateScrollState);\n }\n\n queueScrollStateUpdate();\n});\n\nonUpdated(() => {\n observeResizeTargets();\n queueScrollStateUpdate();\n});\n\nonBeforeUnmount(() => {\n scrollContainer.value?.removeEventListener(\"scroll\", updateScrollState);\n resizeObserver?.disconnect();\n\n if (usingWindowResizeFallback) {\n window.removeEventListener(\"resize\", updateScrollState);\n }\n});\n</script>\n\n<template>\n <div class=\"pv-horizontal-scroller\">\n <div\n ref=\"scrollContainer\"\n class=\"pv-horizontal-scroller-scroll\"\n :class=\"{ 'pv-horizontal-scroller-scroll-hidden-scrollbar': hideScrollbar }\"\n role=\"region\"\n :aria-label=\"ariaLabel\"\n >\n <div ref=\"contentContainer\" class=\"pv-horizontal-scroller-content\">\n <slot />\n </div>\n </div>\n\n <div\n class=\"pv-horizontal-scroller-control pv-horizontal-scroller-control-left\"\n :class=\"{\n 'pv-horizontal-scroller-control-hidden': !canScrollLeft,\n 'pv-horizontal-scroller-control-left-fade': showFades,\n }\"\n >\n <PvButton\n v-if=\"canScrollLeft\"\n :ariaLabel=\"leftAriaLabel\"\n leftIcon=\"chevron-left\"\n :size=\"buttonSize\"\n :variant=\"buttonVariant\"\n @click=\"scrollByDirection(-1)\"\n />\n </div>\n\n <div\n class=\"pv-horizontal-scroller-control pv-horizontal-scroller-control-right\"\n :class=\"{\n 'pv-horizontal-scroller-control-hidden': !canScrollRight,\n 'pv-horizontal-scroller-control-right-fade': showFades,\n }\"\n >\n <PvButton\n v-if=\"canScrollRight\"\n :ariaLabel=\"rightAriaLabel\"\n leftIcon=\"chevron-right\"\n :size=\"buttonSize\"\n :variant=\"buttonVariant\"\n @click=\"scrollByDirection(1)\"\n />\n </div>\n </div>\n</template>\n\n","<script setup lang=\"ts\">\nimport { computed, watch } from \"vue\";\n\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport PvHorizontalScroller from \"@/components/base/PvHorizontalScroller/PvHorizontalScroller.vue\";\nimport type { PvFilterPanelCategory, PvFilterPanelCategoryButtonRowProps } from \"./types\";\n\nconst props = withDefaults(defineProps<PvFilterPanelCategoryButtonRowProps>(), {\n filters: () => [],\n});\n\nconst selectedCategory = defineModel<PvFilterPanelCategory | null>({ default: null });\n\nconst availableCategories = computed<PvFilterPanelCategory[]>(() => {\n const present = new Set<PvFilterPanelCategory>();\n const encountered: PvFilterPanelCategory[] = [];\n\n for (const filter of props.filters) {\n if (!filter.category) continue;\n present.add(filter.category);\n if (!encountered.includes(filter.category)) encountered.push(filter.category);\n }\n\n const orderedCategories = (props.categoryOrder ?? []).filter((category) => present.has(category));\n const orderedCategorySet = new Set(orderedCategories);\n const unorderedCategories = encountered.filter((category) => !orderedCategorySet.has(category));\n return [...orderedCategories, ...unorderedCategories];\n});\n\nconst selectCategory = (category: PvFilterPanelCategory | null) => {\n selectedCategory.value = category;\n};\n\nconst variantFor = (category: PvFilterPanelCategory | null) =>\n selectedCategory.value === category ? \"primary\" : \"secondary\";\n\nwatch(\n availableCategories,\n (categories) => {\n if (selectedCategory.value !== null && !categories.includes(selectedCategory.value)) {\n selectedCategory.value = null;\n }\n },\n { immediate: true },\n);\n</script>\n\n<template>\n <div v-if=\"availableCategories.length\" class=\"pv-border-bottom\" data-testid=\"pv-filter-panel-category-row\">\n <PvHorizontalScroller\n ariaLabel=\"Filter categories\"\n buttonSize=\"md\"\n buttonVariant=\"secondary\"\n hideScrollbar\n leftAriaLabel=\"Scroll filter categories left\"\n rightAriaLabel=\"Scroll filter categories right\"\n showFades\n >\n <div class=\"pv-flex\" style=\"--flex-align: center; --flex-gap: 8px; padding: 8px 12px\">\n <PvButton label=\"All\" size=\"md\" :variant=\"variantFor(null)\" @click=\"selectCategory(null)\" />\n <PvButton\n v-for=\"category in availableCategories\"\n :key=\"category\"\n :label=\"category\"\n size=\"md\"\n :variant=\"variantFor(category)\"\n @click=\"selectCategory(category)\"\n />\n </div>\n </PvHorizontalScroller>\n </div>\n</template>\n","<script setup lang=\"ts\">\nimport { computed, watch } from \"vue\";\n\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport PvHorizontalScroller from \"@/components/base/PvHorizontalScroller/PvHorizontalScroller.vue\";\nimport type { PvFilterPanelCategory, PvFilterPanelCategoryButtonRowProps } from \"./types\";\n\nconst props = withDefaults(defineProps<PvFilterPanelCategoryButtonRowProps>(), {\n filters: () => [],\n});\n\nconst selectedCategory = defineModel<PvFilterPanelCategory | null>({ default: null });\n\nconst availableCategories = computed<PvFilterPanelCategory[]>(() => {\n const present = new Set<PvFilterPanelCategory>();\n const encountered: PvFilterPanelCategory[] = [];\n\n for (const filter of props.filters) {\n if (!filter.category) continue;\n present.add(filter.category);\n if (!encountered.includes(filter.category)) encountered.push(filter.category);\n }\n\n const orderedCategories = (props.categoryOrder ?? []).filter((category) => present.has(category));\n const orderedCategorySet = new Set(orderedCategories);\n const unorderedCategories = encountered.filter((category) => !orderedCategorySet.has(category));\n return [...orderedCategories, ...unorderedCategories];\n});\n\nconst selectCategory = (category: PvFilterPanelCategory | null) => {\n selectedCategory.value = category;\n};\n\nconst variantFor = (category: PvFilterPanelCategory | null) =>\n selectedCategory.value === category ? \"primary\" : \"secondary\";\n\nwatch(\n availableCategories,\n (categories) => {\n if (selectedCategory.value !== null && !categories.includes(selectedCategory.value)) {\n selectedCategory.value = null;\n }\n },\n { immediate: true },\n);\n</script>\n\n<template>\n <div v-if=\"availableCategories.length\" class=\"pv-border-bottom\" data-testid=\"pv-filter-panel-category-row\">\n <PvHorizontalScroller\n ariaLabel=\"Filter categories\"\n buttonSize=\"md\"\n buttonVariant=\"secondary\"\n hideScrollbar\n leftAriaLabel=\"Scroll filter categories left\"\n rightAriaLabel=\"Scroll filter categories right\"\n showFades\n >\n <div class=\"pv-flex\" style=\"--flex-align: center; --flex-gap: 8px; padding: 8px 12px\">\n <PvButton label=\"All\" size=\"md\" :variant=\"variantFor(null)\" @click=\"selectCategory(null)\" />\n <PvButton\n v-for=\"category in availableCategories\"\n :key=\"category\"\n :label=\"category\"\n size=\"md\"\n :variant=\"variantFor(category)\"\n @click=\"selectCategory(category)\"\n />\n </div>\n </PvHorizontalScroller>\n </div>\n</template>\n","import { inject, provide, ref, type InjectionKey } from \"vue\";\n\nimport { filterPanelOptionMatchesRawValue, getFilterPanelOptionRawValue } from \"./filterOptionValue\";\nimport type {\n PvFilterPanelOption,\n PvFilterPanelOptionsHandler,\n PvFilterPanelOptionsResponse,\n PvFilterStore,\n PvFilterStoreFetchOptionsParams,\n} from \"./types\";\n\nconst PvFilterStoreKey: InjectionKey<PvFilterStore> = Symbol(\"PvFilterStore\");\n\nconst normalizeOptionsResponse = (\n response: PvFilterPanelOptionsResponse | (PvFilterPanelOption | null)[] | undefined,\n) => {\n if (!response) return { values: [] } satisfies PvFilterPanelOptionsResponse;\n return Array.isArray(response) ? ({ values: response } satisfies PvFilterPanelOptionsResponse) : response;\n};\n\nconst mergeTotalChildCount = (existing?: number, incoming?: number) => incoming ?? existing;\n\nconst cloneOptionMap = <T>(map: Record<string, T[]>) => {\n return Object.fromEntries(Object.entries(map).map(([field, values]) => [field, [...values]]));\n};\n\nconst mergeOptions = (options: (PvFilterPanelOption | null)[]) => {\n const optionsByValue = new Map<string, PvFilterPanelOption>();\n\n for (const option of options) {\n if (!option) continue;\n const existing = optionsByValue.get(option.value);\n if (!existing) {\n optionsByValue.set(option.value, option);\n continue;\n }\n\n optionsByValue.set(option.value, {\n ...existing,\n ...option,\n children: mergeOptions([...(existing.children ?? []), ...(option.children ?? [])]),\n totalChildCount: mergeTotalChildCount(existing.totalChildCount, option.totalChildCount),\n });\n }\n\n return [...optionsByValue.values()];\n};\n\nconst findOptionByValue = (\n options: (PvFilterPanelOption | null)[] | undefined,\n value: string,\n): PvFilterPanelOption | undefined => {\n for (const option of options ?? []) {\n if (!option) continue;\n if (option.value === value) return option;\n const childMatch = findOptionByValue(option.children, value);\n if (childMatch) return childMatch;\n }\n return undefined;\n};\n\nconst optionMatchesSelectedValue = (\n option: PvFilterPanelOption | null | undefined,\n selectedValue: string | null,\n fallbackField: string,\n): boolean => {\n if (!option || selectedValue === null) return false;\n if (option.value === selectedValue) return true;\n const rawValue = getFilterPanelOptionRawValue(option);\n if (rawValue !== null && rawValue === selectedValue) return true;\n if (filterPanelOptionMatchesRawValue(option, option.colField ?? fallbackField, selectedValue, fallbackField))\n return true;\n return option.children?.some((child) => optionMatchesSelectedValue(child, selectedValue, fallbackField)) ?? false;\n};\n\nconst mergeChildOptions = (\n options: (PvFilterPanelOption | null)[],\n parentId: string,\n incomingOptions: (PvFilterPanelOption | null)[],\n): (PvFilterPanelOption | null)[] => {\n const incomingParent = findOptionByValue(incomingOptions, parentId) ?? null;\n const incomingChildren = incomingParent?.children ?? incomingOptions.filter(Boolean);\n\n return options.map((option) => {\n if (!option) return option;\n\n if (option.value === parentId) {\n return {\n ...option,\n children: mergeOptions([...(option.children ?? []), ...incomingChildren]),\n totalChildCount: mergeTotalChildCount(option.totalChildCount, incomingParent?.totalChildCount),\n };\n }\n\n if (!option.children?.length) return option;\n\n return {\n ...option,\n children: mergeChildOptions(option.children, parentId, incomingOptions).filter(\n (child): child is PvFilterPanelOption => Boolean(child),\n ),\n };\n });\n};\n\nconst getChildPaginationKey = (field: string, parentId: string) => `${field}::${parentId}`;\n\nexport const createPvFilterStore = (): PvFilterStore => {\n const filterModel = ref<PvFilterStore[\"filterModel\"][\"value\"]>(null);\n const stagedFilterModel = ref<PvFilterStore[\"stagedFilterModel\"][\"value\"]>(null);\n const filterModelType = ref<PvFilterStore[\"filterModelType\"][\"value\"]>();\n const filterOptionsMap = ref<Record<string, (PvFilterPanelOption | null)[]>>({});\n const filterSelectedValueMap = ref<Record<string, (string | null)[]>>({});\n const filterSelectedMetadataMap = ref<Record<string, (PvFilterPanelOption | null)[]>>({});\n const stagedFilterSelectedValueMap = ref<Record<string, (string | null)[]>>({});\n const stagedFilterSelectedMetadataMap = ref<Record<string, (PvFilterPanelOption | null)[]>>({});\n const filterSearchQueries = ref<Record<string, string | null | undefined>>({});\n const filterLoadingMap = ref<Record<string, boolean | undefined>>({});\n const filterLoadingMoreMap = ref<Record<string, boolean | undefined>>({});\n const filterHasMoreMap = ref<Record<string, boolean | undefined>>({});\n const filterTotalCountMap = ref<Record<string, number | undefined>>({});\n const filterChildHasMoreMap = ref<Record<string, boolean | undefined>>({});\n const filterChildTotalCountMap = ref<Record<string, number | undefined>>({});\n const filterRequestIdMap = ref<Record<string, number | undefined>>({});\n const filterStaleMap = ref<Record<string, boolean | undefined>>({});\n const filterOptionsHandler = ref<PvFilterPanelOptionsHandler | undefined>();\n const loadingRequestCountMap = ref<Record<string, number | undefined>>({});\n\n const setFilterOptionsHandler = (handler?: PvFilterPanelOptionsHandler) => {\n filterOptionsHandler.value = handler;\n };\n\n const getFilterOptions = (field: string) => filterOptionsMap.value[field] ?? [];\n\n const setFilterOptions = (field: string, options: (PvFilterPanelOption | null)[]) => {\n filterOptionsMap.value[field] = options;\n };\n\n const getFilterSelectedValues = (field: string, staged = false) => {\n const selectedValueMap = staged ? stagedFilterSelectedValueMap : filterSelectedValueMap;\n return selectedValueMap.value[field] ?? [];\n };\n\n const setFilterSelectedValues = (field: string, values: (string | null)[], staged = false) => {\n const selectedValueMap = staged ? stagedFilterSelectedValueMap : filterSelectedValueMap;\n selectedValueMap.value[field] = values;\n };\n\n const initStagedFilterSelections = () => {\n stagedFilterSelectedValueMap.value = cloneOptionMap(filterSelectedValueMap.value);\n stagedFilterSelectedMetadataMap.value = cloneOptionMap(filterSelectedMetadataMap.value);\n };\n\n const clearStagedFilterSelections = () => {\n stagedFilterSelectedValueMap.value = {};\n stagedFilterSelectedMetadataMap.value = {};\n };\n\n const commitStagedFilterSelections = () => {\n filterSelectedValueMap.value = cloneOptionMap(stagedFilterSelectedValueMap.value);\n filterSelectedMetadataMap.value = cloneOptionMap(stagedFilterSelectedMetadataMap.value);\n clearStagedFilterSelections();\n };\n\n const setFilterSearchQuery = (field: string, query: string | null | undefined) => {\n filterSearchQueries.value[field] = query;\n };\n\n const getLoadingRequestCountKey = (field: string, isAppend: boolean) =>\n `${isAppend ? \"append\" : \"initial\"}::${field}`;\n\n const startLoading = (field: string, isAppend: boolean) => {\n const loadingMap = isAppend ? filterLoadingMoreMap : filterLoadingMap;\n const loadingKey = getLoadingRequestCountKey(field, isAppend);\n loadingRequestCountMap.value[loadingKey] = (loadingRequestCountMap.value[loadingKey] ?? 0) + 1;\n loadingMap.value[field] = true;\n return loadingKey;\n };\n\n const stopLoading = (field: string, isAppend: boolean, loadingKey: string) => {\n const loadingMap = isAppend ? filterLoadingMoreMap : filterLoadingMap;\n const nextCount = Math.max(0, (loadingRequestCountMap.value[loadingKey] ?? 1) - 1);\n if (nextCount > 0) {\n loadingRequestCountMap.value[loadingKey] = nextCount;\n return;\n }\n\n delete loadingRequestCountMap.value[loadingKey];\n loadingMap.value[field] = false;\n };\n\n const fetchFilterOptions = async (params: PvFilterStoreFetchOptionsParams) => {\n const handler = filterOptionsHandler.value;\n if (!handler) return [];\n\n const query = params.query ?? filterSearchQueries.value[params.field] ?? undefined;\n filterSearchQueries.value[params.field] = query;\n\n const parentOption = params.parentId\n ? findOptionByValue(filterOptionsMap.value[params.field], params.parentId)\n : undefined;\n const offset =\n params.offset ??\n (params.parentId\n ? (parentOption?.children?.length ?? 0)\n : params.reason === \"load-more\"\n ? (filterOptionsMap.value[params.field] ?? []).filter(Boolean).length\n : 0);\n const isAppend = params.reason === \"load-more\" || params.reason === \"child-load-more\";\n const loadingKey = startLoading(params.field, isAppend);\n const requestKey = params.parentId ? getChildPaginationKey(params.field, params.parentId) : params.field;\n const requestId = (filterRequestIdMap.value[requestKey] ?? 0) + 1;\n filterRequestIdMap.value[requestKey] = requestId;\n\n try {\n const rawResponse = await handler({\n ...params,\n filterModel: params.filterModel ?? stagedFilterModel.value ?? filterModel.value,\n offset,\n query,\n selectedValues: params.selectedValues ?? filterSelectedValueMap.value[params.field] ?? [],\n });\n\n if (filterRequestIdMap.value[requestKey] !== requestId) return [];\n\n const response = normalizeOptionsResponse(rawResponse);\n if (params.parentId) {\n const childPaginationKey = getChildPaginationKey(params.field, params.parentId);\n filterChildHasMoreMap.value[childPaginationKey] = response.hasMore;\n filterChildTotalCountMap.value[childPaginationKey] = response.totalCount;\n } else {\n filterHasMoreMap.value[params.field] = response.hasMore;\n filterTotalCountMap.value[params.field] = response.totalCount;\n }\n\n const selectedMetadata = filterSelectedMetadataMap.value[params.field] ?? [];\n let nextOptions: (PvFilterPanelOption | null)[];\n\n if (params.parentId) {\n nextOptions = mergeChildOptions(filterOptionsMap.value[params.field] ?? [], params.parentId, response.values);\n } else if (isAppend) {\n nextOptions = mergeOptions([...(filterOptionsMap.value[params.field] ?? []), ...response.values]);\n } else {\n nextOptions = response.values;\n }\n\n for (const selectedOption of selectedMetadata) {\n if (!selectedOption) continue;\n const selectedValue = getFilterPanelOptionRawValue(selectedOption) ?? selectedOption.value;\n const alreadyPresent = nextOptions.some((option) =>\n optionMatchesSelectedValue(option, selectedValue, params.field),\n );\n if (!alreadyPresent) nextOptions.push(selectedOption);\n }\n\n filterOptionsMap.value[params.field] = nextOptions;\n filterStaleMap.value[params.field] = false;\n return nextOptions\n .filter((option): option is PvFilterPanelOption => Boolean(option))\n .map((option) => option.value);\n } finally {\n stopLoading(params.field, isAppend, loadingKey);\n }\n };\n\n return {\n clearStagedFilterSelections,\n commitStagedFilterSelections,\n fetchFilterOptions,\n filterChildHasMoreMap,\n filterChildTotalCountMap,\n filterHasMoreMap,\n filterLoadingMap,\n filterLoadingMoreMap,\n filterModel,\n filterModelType,\n filterOptionsHandler,\n filterOptionsMap,\n filterRequestIdMap,\n filterSearchQueries,\n filterSelectedMetadataMap,\n filterSelectedValueMap,\n filterStaleMap,\n filterTotalCountMap,\n getFilterOptions,\n getFilterSelectedValues,\n initStagedFilterSelections,\n setFilterOptions,\n setFilterOptionsHandler,\n setFilterSearchQuery,\n setFilterSelectedValues,\n stagedFilterModel,\n stagedFilterSelectedMetadataMap,\n stagedFilterSelectedValueMap,\n };\n};\n\nexport const providePvFilterStore = (filterStore: PvFilterStore) => {\n provide(PvFilterStoreKey, filterStore);\n};\n\nexport const useOptionalPvFilterStore = () => {\n return inject(PvFilterStoreKey, null);\n};\n\nexport const usePvFilterStore = () => {\n return useOptionalPvFilterStore() ?? createPvFilterStore();\n};\n","<script setup lang=\"ts\">\nimport { computed, type CSSProperties, getCurrentInstance, onBeforeUnmount, ref, watch, watchEffect } from \"vue\";\nimport type { AdvancedFilterModel } from \"ag-grid-enterprise\";\n\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport PvModal from \"@/components/base/PvModal/PvModal.vue\";\nimport PvSegmentedControl from \"@/components/base/PvSegmentedControl/PvSegmentedControl.vue\";\nimport PvSuggestionTag from \"@/components/base/PvSuggestionTag/PvSuggestionTag.vue\";\nimport {\n advancedFilterHasConditions,\n createFilterPanelModelIndex,\n getAdvancedFilterTypeForDataType,\n updateBooleanFilter,\n updateExistsFilter,\n updateRangeFilter,\n updateValueFilter,\n} from \"./advancedFilterModel\";\nimport {\n buildFilterPanelAggregateModelFromSelectionState,\n findFilterPanelOptionByValue,\n getFilterPanelAggregateOptionSelectionStatus,\n getFilterPanelAggregateSelectedValuesByField,\n getFilterPanelAggregateSelectionOptions,\n isFilterPanelAggregateColDef,\n seedFilterPanelAggregateSelectionState,\n updateFilterPanelAggregateSelectionState,\n} from \"./aggregateFilterModel\";\nimport { formatFilterPanelRangeValue, getFilterOptionLabel, getFilterOptionResultCount } from \"./filterOptionDisplay\";\nimport {\n createFilterPanelScopedValue,\n filterPanelOptionMatchesRawValue,\n flattenFilterPanelOptions,\n getFilterPanelOptionField,\n getFilterPanelOptionRawValue,\n} from \"./filterOptionValue\";\nimport PvFilterPanelAccordion from \"./PvFilterPanelAccordion.vue\";\nimport PvFilterPanelAppliedFiltersSection from \"./PvFilterPanelAppliedFiltersSection.vue\";\nimport PvFilterPanelCategoryButtonRow from \"./PvFilterPanelCategoryButtonRow.vue\";\nimport { createPvFilterStore, useOptionalPvFilterStore } from \"./usePvFilterStore\";\nimport type {\n PvFilterPanelAppliedGroup,\n PvFilterPanelAppliedValue,\n PvFilterPanelCategory,\n PvFilterPanelColDef,\n PvFilterPanelControlChange,\n PvFilterPanelFilterChangeEvent,\n PvFilterPanelFilterChangeReason,\n PvFilterPanelFilterModel,\n PvFilterPanelFilterType,\n PvFilterPanelOption,\n PvFilterPanelProps,\n PvFilterPanelResolvedFilter,\n PvFilterPanelSuggestion,\n PvFilterStore,\n} from \"./types\";\nimport type { PvRangeValue } from \"@/components/base/PvRange/types\";\n\ntype PvFilterPanelMode = \"filters\" | \"applied\";\n\ntype StoreWithApplyFilterModel = PvFilterStore & {\n applyFilterModel?: (model: PvFilterPanelFilterModel) => void;\n};\n\nconst RANGE_APPLIED_VALUE = \"__range__\";\nconst BOOLEAN_APPLIED_VALUE = \"__boolean__\";\nconst EXISTS_APPLIED_VALUE = \"__exists__\";\nconst FILTER_PANEL_TYPES = new Set<PvFilterPanelFilterType>([\"value\", \"range\", \"boolean\", \"exists\"]);\n\nconst props = withDefaults(defineProps<PvFilterPanelProps>(), {\n applyLabel: \"Apply\",\n ariaLabel: \"Filters\",\n autoHideRelatedFilterFields: undefined,\n cancelLabel: \"Cancel\",\n clearAllBody: \"Are you sure you want to clear all applied filters? This will reset your current filters.\",\n clearAllHeader: \"Clear all filters\",\n clearAllLabel: \"Clear all\",\n colDefs: () => [],\n devMode: false,\n displayPreferencesIcon: false,\n enableFocusView: false,\n filterHasMoreMap: () => ({}),\n filterLoadingMap: () => ({}),\n filterLoadingMoreMap: () => ({}),\n filterOptions: () => ({}),\n filterSearchQueries: () => ({}),\n filterSuggestions: () => [],\n focusableFields: () => [],\n focusedValues: () => ({}),\n focusText: \"Focus\",\n rangeDebounceMs: 250,\n readOnly: false,\n staged: false,\n width: \"320px\",\n});\n\nconst filterModel = defineModel<PvFilterPanelFilterModel>(\"filterModel\", { default: null });\nconst isCollapsed = defineModel<boolean>(\"isCollapsed\", { default: false });\n\nconst emit = defineEmits<{\n apply: [filterModel: PvFilterPanelFilterModel];\n cancel: [];\n \"filter-change\": [event: PvFilterPanelFilterChangeEvent];\n \"focus-change\": [field: string, value: string, option: PvFilterPanelOption];\n \"handle-settings-icon\": [field: string, colDef: PvFilterPanelColDef];\n \"load-more\": [field: string, colDef: PvFilterPanelColDef, query: string, parentId?: string];\n \"open-change\": [field: string, open: boolean, colDef: PvFilterPanelColDef];\n \"search-change\": [field: string, query: string, colDef: PvFilterPanelColDef];\n \"suggestion-click\": [suggestion: PvFilterPanelSuggestion];\n}>();\n\nconst instance = getCurrentInstance();\nconst mode = ref<PvFilterPanelMode>(\"filters\");\nconst openSections = ref<Record<string, boolean>>({});\nconst selectedCategory = ref<PvFilterPanelCategory | null>(null);\nconst showClearAllConfirm = ref(false);\nconst stagedFilterModel = ref<PvFilterPanelFilterModel>(filterModel.value);\nconst internalFilterStore = createPvFilterStore();\nconst injectedFilterStore = useOptionalPvFilterStore();\nconst warnedIgnoredStoreProps = new Set<string>();\nconst warnedFilterModelTypeIssues = new Set<string>();\nconst pendingRangeChanges = new Map<string, { colDef?: PvFilterPanelColDef; timer: number; value: PvRangeValue }>();\n\nconst hasExternalFilterStore = computed(() => Boolean(props.filterStore ?? injectedFilterStore));\nconst isHandlerBackedInternalStore = computed(\n () => !hasExternalFilterStore.value && Boolean(props.filterOptionsHandler),\n);\nconst effectiveFilterStore = computed(() => props.filterStore ?? injectedFilterStore ?? internalFilterStore);\nconst usesInternalFilterStore = computed(() => effectiveFilterStore.value === internalFilterStore);\nconst isStoreMode = computed(() => hasExternalFilterStore.value || isHandlerBackedInternalStore.value);\nconst explicitFilterModelType = computed(\n () => props.filterModelType ?? effectiveFilterStore.value?.filterModelType.value,\n);\nconst effectiveFilterModelType = computed(() => explicitFilterModelType.value ?? \"advanced\");\nconst activeFilterModel = computed(() => {\n const store = effectiveFilterStore.value;\n if (store) return props.staged ? store.stagedFilterModel.value : store.filterModel.value;\n return props.staged ? stagedFilterModel.value : filterModel.value;\n});\nconst filterModelIndex = computed(() =>\n createFilterPanelModelIndex(activeFilterModel.value, effectiveFilterModelType.value),\n);\n\nconst applyCommittedFilterModelToStore = (store: PvFilterStore, nextFilterModel: PvFilterPanelFilterModel) => {\n const applyFilterModel = (store as StoreWithApplyFilterModel).applyFilterModel;\n if (typeof applyFilterModel === \"function\") {\n applyFilterModel(nextFilterModel);\n return;\n }\n\n store.filterModel.value = nextFilterModel;\n};\n\nconst setActiveFilterModelInStore = (store: PvFilterStore, nextFilterModel: PvFilterPanelFilterModel) => {\n if (props.staged) {\n store.stagedFilterModel.value = nextFilterModel;\n return;\n }\n\n applyCommittedFilterModelToStore(store, nextFilterModel);\n};\n\nwatch(\n () => props.filterOptionsHandler,\n (handler) => {\n internalFilterStore.setFilterOptionsHandler(handler);\n },\n { immediate: true },\n);\n\nwatch(\n [() => props.filterOptions, usesInternalFilterStore, () => props.filterOptionsHandler],\n ([filterOptions, usesInternalStore, handler]) => {\n if (!usesInternalStore || handler) return;\n internalFilterStore.filterOptionsMap.value = Object.fromEntries(\n Object.entries(filterOptions).map(([field, options]) => [field, [...options]]),\n );\n },\n { deep: true, immediate: true },\n);\n\nwatch(\n [() => props.filterHasMoreMap, usesInternalFilterStore, () => props.filterOptionsHandler],\n ([filterHasMoreMap, usesInternalStore, handler]) => {\n if (usesInternalStore && !handler) internalFilterStore.filterHasMoreMap.value = { ...filterHasMoreMap };\n },\n { deep: true, immediate: true },\n);\n\nwatch(\n [() => props.filterLoadingMap, usesInternalFilterStore, () => props.filterOptionsHandler],\n ([filterLoadingMap, usesInternalStore, handler]) => {\n if (usesInternalStore && !handler) internalFilterStore.filterLoadingMap.value = { ...filterLoadingMap };\n },\n { deep: true, immediate: true },\n);\n\nwatch(\n [() => props.filterLoadingMoreMap, usesInternalFilterStore, () => props.filterOptionsHandler],\n ([filterLoadingMoreMap, usesInternalStore, handler]) => {\n if (usesInternalStore && !handler) {\n internalFilterStore.filterLoadingMoreMap.value = { ...filterLoadingMoreMap };\n }\n },\n { deep: true, immediate: true },\n);\n\nwatch(\n [() => props.filterSearchQueries, usesInternalFilterStore, () => props.filterOptionsHandler],\n ([filterSearchQueries, usesInternalStore, handler]) => {\n if (usesInternalStore && !handler) internalFilterStore.filterSearchQueries.value = { ...filterSearchQueries };\n },\n { deep: true, immediate: true },\n);\n\nwatch(\n [filterModel, usesInternalFilterStore, () => props.staged],\n ([nextFilterModel, usesInternalStore]) => {\n if (!usesInternalStore) return;\n if (props.staged) stagedFilterModel.value = nextFilterModel;\n internalFilterStore.filterModel.value = nextFilterModel;\n if (props.staged) internalFilterStore.stagedFilterModel.value = nextFilterModel;\n },\n { deep: true, immediate: true },\n);\n\nwatch(\n [() => props.staged, effectiveFilterStore],\n ([isStaged]) => {\n if (isStaged) {\n stagedFilterModel.value = filterModel.value;\n const store = effectiveFilterStore.value;\n if (store) {\n store.stagedFilterModel.value = store.filterModel.value;\n store.initStagedFilterSelections();\n }\n }\n },\n { immediate: true },\n);\n\nconst warnIgnoredStoreProp = (propName: string, shouldWarn: boolean) => {\n if (!isStoreMode.value || !shouldWarn || warnedIgnoredStoreProps.has(propName)) return;\n console.warn(`PvFilterPanel: \"${propName}\" is ignored when filterStore/filterOptionsHandler store mode is active.`);\n warnedIgnoredStoreProps.add(propName);\n};\n\nconst warnFilterModelTypeIssue = (key: string, message: string) => {\n if (warnedFilterModelTypeIssues.has(key)) return;\n console.warn(message);\n warnedFilterModelTypeIssues.add(key);\n};\n\nconst hasProvidedFilterModelProp = () => {\n const vnodeProps = instance?.vnode.props ?? {};\n return (\n Object.prototype.hasOwnProperty.call(vnodeProps, \"filterModel\") ||\n Object.prototype.hasOwnProperty.call(vnodeProps, \"filter-model\")\n );\n};\n\nconst isAdvancedFilterModelShape = (model: PvFilterPanelFilterModel) => {\n return Boolean(model && typeof model === \"object\" && \"filterType\" in model);\n};\n\nconst warnIfModelShapeMismatchesType = (model: PvFilterPanelFilterModel) => {\n if (!model) return;\n const isAdvancedShape = isAdvancedFilterModelShape(model);\n if (effectiveFilterModelType.value === \"advanced\" && !isAdvancedShape) {\n warnFilterModelTypeIssue(\n \"regular-model-in-advanced-mode\",\n 'PvFilterPanel: produced a regular FilterModel while filterModelType is \"advanced\".',\n );\n }\n if (effectiveFilterModelType.value === \"regular\" && isAdvancedShape) {\n warnFilterModelTypeIssue(\n \"advanced-model-in-regular-mode\",\n 'PvFilterPanel: produced an AdvancedFilterModel while filterModelType is \"regular\".',\n );\n }\n};\n\nwatchEffect(() => {\n warnIgnoredStoreProp(\n \"filterModel\",\n Boolean((props.filterStore || injectedFilterStore) && filterModel.value !== null),\n );\n warnIgnoredStoreProp(\"filterOptions\", Object.keys(props.filterOptions).length > 0);\n warnIgnoredStoreProp(\"filterLoadingMap\", Object.keys(props.filterLoadingMap).length > 0);\n warnIgnoredStoreProp(\"filterLoadingMoreMap\", Object.keys(props.filterLoadingMoreMap).length > 0);\n warnIgnoredStoreProp(\"filterHasMoreMap\", Object.keys(props.filterHasMoreMap).length > 0);\n warnIgnoredStoreProp(\"filterSearchQueries\", Object.keys(props.filterSearchQueries).length > 0);\n warnIgnoredStoreProp(\"filterOptionsHandler\", Boolean(props.filterStore && props.filterOptionsHandler));\n\n const hasExternalAmbiguousModel = Boolean(\n (props.filterStore || injectedFilterStore) && activeFilterModel.value !== null,\n );\n if (\n import.meta.env.DEV &&\n !explicitFilterModelType.value &&\n activeFilterModel.value !== null &&\n !isAdvancedFilterModelShape(activeFilterModel.value) &&\n (hasProvidedFilterModelProp() || hasExternalAmbiguousModel)\n ) {\n warnFilterModelTypeIssue(\n \"missing-filter-model-type\",\n 'PvFilterPanel: filterModelType was not provided by props or filterStore; defaulting to \"advanced\".',\n );\n }\n});\n\nconst getColDefContext = (colDef: PvFilterPanelColDef) => colDef.context ?? {};\nconst getColDefKey = (colDef: PvFilterPanelColDef) => colDef.colId || colDef.field || \"\";\nconst getFiniteNumber = (value: unknown) => (typeof value === \"number\" && Number.isFinite(value) ? value : null);\n\nconst inferFilterType = (colDef: PvFilterPanelColDef): PvFilterPanelFilterType | undefined => {\n const context = getColDefContext(colDef);\n const filterType = context.filterPanelType;\n if (filterType && FILTER_PANEL_TYPES.has(filterType)) return filterType;\n if (context.filterPanelRange) return \"range\";\n if (context.dataType === \"boolean\") return \"boolean\";\n if (colDef.filter) return \"value\";\n return undefined;\n};\n\nconst getFilterType = (colDef: PvFilterPanelColDef): PvFilterPanelFilterType => inferFilterType(colDef) ?? \"value\";\n\nconst getFilterCategory = (colDef: PvFilterPanelColDef): PvFilterPanelCategory | null => {\n return getColDefContext(colDef).filterPanelCategory ?? null;\n};\n\nconst getValueLabels = (colDef: PvFilterPanelColDef): Record<string, string> | null => {\n const valueLabels = getColDefContext(colDef).filterPanelValueLabels;\n if (typeof valueLabels !== \"object\" || valueLabels === null || Array.isArray(valueLabels)) return null;\n\n return Object.fromEntries(\n Object.entries(valueLabels).flatMap(([key, value]) => (typeof value === \"string\" ? [[key, value]] : [])),\n );\n};\n\nconst isFilterableColumn = (colDef: PvFilterPanelColDef) => {\n const context = getColDefContext(colDef);\n const key = getColDefKey(colDef);\n if (!key || context.filterPanelHidden === true) return false;\n if (context.devOnly && !props.devMode) return false;\n if (\n props.autoHideRelatedFilterFields !== false &&\n context.filterPanelHidden !== false &&\n autoHiddenFilterFields.value.has(key)\n ) {\n return false;\n }\n return Boolean(inferFilterType(colDef));\n};\n\nconst filterOptionsFor = (field: string) => {\n return (effectiveFilterStore.value.filterOptionsMap.value[field] ?? []).filter(\n (option): option is PvFilterPanelOption => Boolean(option),\n );\n};\n\nconst selectedMetadataOptionsFor = (field: string) => {\n const store = effectiveFilterStore.value;\n const metadataMap = props.staged ? store.stagedFilterSelectedMetadataMap : store.filterSelectedMetadataMap;\n return (metadataMap.value[field] ?? []).filter((option): option is PvFilterPanelOption => Boolean(option));\n};\n\nconst filterHasMoreFor = (field: string) => effectiveFilterStore.value.filterHasMoreMap.value[field] ?? false;\nconst filterLoadingFor = (field: string) => effectiveFilterStore.value.filterLoadingMap.value[field] ?? false;\nconst filterLoadingMoreFor = (field: string) => effectiveFilterStore.value.filterLoadingMoreMap.value[field] ?? false;\nconst filterSearchQueryFor = (field: string) => effectiveFilterStore.value.filterSearchQueries.value[field] ?? \"\";\n\nconst suggestionOptionsFor = (field: string): PvFilterPanelOption[] => {\n return props.filterSuggestions.flatMap((suggestion) => {\n if (suggestion.field !== field || suggestion.filter.type !== \"value\") return [];\n return [suggestion.option ?? { label: suggestion.label, value: suggestion.filter.value }];\n });\n};\n\nconst knownOptionsFor = (field: string) => [\n ...suggestionOptionsFor(field),\n ...filterOptionsFor(field),\n ...selectedMetadataOptionsFor(field),\n];\n\nconst flattenAggregateFieldHierarchy = (hierarchy: unknown): string[] => {\n if (typeof hierarchy !== \"object\" || hierarchy === null || !(\"field\" in hierarchy)) return [];\n const node = hierarchy as { children?: unknown[]; field?: unknown };\n const field = typeof node.field === \"string\" ? node.field : null;\n const children = Array.isArray(node.children) ? node.children.flatMap(flattenAggregateFieldHierarchy) : [];\n return field ? [field, ...children] : children;\n};\n\nconst autoHiddenFilterFields = computed(() => {\n const fields = new Set<string>();\n for (const colDef of props.colDefs) {\n const context = getColDefContext(colDef);\n for (const field of Array.isArray(context.aggregateFields) ? context.aggregateFields : []) {\n if (field) fields.add(field);\n }\n for (const field of flattenAggregateFieldHierarchy(context.aggregateFieldHierarchy)) {\n if (field) fields.add(field);\n }\n for (const field of context.filterGroup?.fields ?? []) {\n if (field) fields.add(field);\n }\n }\n return fields;\n});\n\nconst getRepresentedFields = (colDef: PvFilterPanelColDef) => {\n const field = getColDefKey(colDef);\n const context = getColDefContext(colDef);\n const aggregateFields = Array.isArray(context.aggregateFields) ? context.aggregateFields.filter(Boolean) : [];\n const hierarchyFields = flattenAggregateFieldHierarchy(context.aggregateFieldHierarchy);\n return Array.from(new Set([field, ...aggregateFields, ...hierarchyFields].filter(Boolean)));\n};\n\nconst isAggregateValueFilter = (colDef: PvFilterPanelColDef) => {\n return effectiveFilterModelType.value === \"advanced\" && isFilterPanelAggregateColDef(colDef);\n};\n\nconst getSelectedRawValuesByField = (colDef: PvFilterPanelColDef, options?: (PvFilterPanelOption | null)[]) => {\n if (isAggregateValueFilter(colDef)) {\n return getFilterPanelAggregateSelectedValuesByField({\n colDef,\n model: activeFilterModel.value as AdvancedFilterModel | null,\n options,\n });\n }\n\n return new Map(\n getRepresentedFields(colDef).map((representedField) => [\n representedField,\n filterModelIndex.value.get(representedField)?.values ?? [],\n ]),\n );\n};\n\nconst getSelectedFallbackOptions = (\n field: string,\n colDef: PvFilterPanelColDef,\n selectedRawValuesByField: Map<string, string[]>,\n options: PvFilterPanelOption[],\n): PvFilterPanelOption[] => {\n const matchedSelections = new Set<string>();\n\n for (const option of flattenFilterPanelOptions(options)) {\n for (const [representedField, rawValues] of selectedRawValuesByField) {\n for (const rawValue of rawValues) {\n if (filterPanelOptionMatchesRawValue(option, representedField, rawValue, field)) {\n matchedSelections.add(`${representedField}:${rawValue}`);\n }\n }\n }\n }\n\n return [...selectedRawValuesByField.entries()].flatMap(([representedField, rawValues]) =>\n rawValues.flatMap((rawValue) => {\n if (matchedSelections.has(`${representedField}:${rawValue}`)) return [];\n return [\n {\n colField: representedField === field ? undefined : representedField,\n label: rawValue,\n metadata: { rawValue },\n value: representedField === field ? rawValue : createFilterPanelScopedValue(representedField, rawValue),\n } satisfies PvFilterPanelOption,\n ];\n }),\n );\n};\n\nconst getSelectedValuesForFilter = (\n field: string,\n selectedRawValuesByField: Map<string, string[]>,\n options: PvFilterPanelOption[],\n) => {\n const selectedValues = new Set<string>();\n\n for (const option of flattenFilterPanelOptions(options)) {\n const targetField = getFilterPanelOptionField(option, field);\n const rawValue = getFilterPanelOptionRawValue(option);\n if (rawValue !== null && selectedRawValuesByField.get(targetField)?.includes(rawValue)) {\n selectedValues.add(option.value);\n }\n }\n\n return Array.from(selectedValues);\n};\n\nconst getFocusedValuesByField = (colDef: PvFilterPanelColDef) => {\n return Object.fromEntries(getRepresentedFields(colDef).map((field) => [field, props.focusedValues[field] ?? []]));\n};\n\nconst findColDef = (field: string) => props.colDefs.find((colDef) => getColDefKey(colDef) === field);\n\nconst getFilterGroupOptions = (colDef: PvFilterPanelColDef) => {\n const filterGroup = getColDefContext(colDef).filterGroup;\n if (!filterGroup?.fields.length) return undefined;\n\n return filterGroup.fields.map((field) => ({\n field,\n isActive: filterModelIndex.value.get(field)?.booleanValue === true,\n label: findColDef(field)?.headerName ?? field,\n }));\n};\n\nconst findResolvedFilter = (field: string) =>\n resolvedFilters.value.find((filter) => filter.key === field) ??\n resolvedFilters.value.find((filter) => getRepresentedFields(filter.colDef).includes(field));\n\nconst findKnownOptionForValue = (filterKey: string, field: string, value: string) => {\n const filter = findResolvedFilter(filterKey);\n return flattenFilterPanelOptions(filter?.knownOptions ?? []).find((option) => {\n return option.value === value || filterPanelOptionMatchesRawValue(option, field, value, filterKey);\n });\n};\n\nconst resolvedFilters = computed<PvFilterPanelResolvedFilter[]>(() => {\n return props.colDefs.filter(isFilterableColumn).map((colDef) => {\n const field = getColDefKey(colDef);\n const context = getColDefContext(colDef);\n const type = getFilterType(colDef);\n const baseFilter = {\n category: getFilterCategory(colDef),\n colDef,\n dataType: context.dataType ?? null,\n disabled: props.readOnly,\n displayPreferencesIcon: props.displayPreferencesIcon,\n emptyResultsRenderer: context.emptyFilterResultsRenderer,\n existsLabel: context.filterPanelExistsLabel,\n filterFooterRenderer: context.filterFooterRenderer,\n filterGroupLabel: context.filterGroup?.label,\n filterGroupOptions: getFilterGroupOptions(colDef),\n filterHeaderRenderer: context.filterHeaderRenderer,\n filterOptionsRenderer: context.filterOptionsRenderer,\n filterOptionsSortDescription: context.filterOptionsSortDescription,\n filterOptionsSortTooltip: context.filterOptionsSortTooltip,\n focusText: props.focusText,\n focusedValues: props.focusedValues[field] ?? [],\n focusedValuesByField: getFocusedValuesByField(colDef),\n hasMore: filterHasMoreFor(field),\n isAggregate: isAggregateValueFilter(colDef),\n isFocusable:\n props.enableFocusView &&\n (!props.focusableFields.length ||\n getRepresentedFields(colDef).some((focusField) => props.focusableFields.includes(focusField))),\n isLoading: filterLoadingFor(field),\n isLoadingMore: filterLoadingMoreFor(field),\n isOpen: openSections.value[field] ?? false,\n key: field,\n knownOptions: knownOptionsFor(field),\n label: colDef.headerName || field,\n rangeMax: getFiniteNumber(context.filterPanelRange?.max),\n rangeMin: getFiniteNumber(context.filterPanelRange?.min),\n rangeStep: getFiniteNumber(context.filterPanelRange?.step),\n searchPlaceholder: context.filterPanelSearchPlaceholder,\n searchQuery: filterSearchQueryFor(field) ?? \"\",\n type,\n valueDecimals: context.valueDecimals ?? null,\n valueLabels: getValueLabels(colDef),\n } satisfies PvFilterPanelResolvedFilter;\n\n if (type === \"range\") {\n return {\n ...baseFilter,\n rangeValue: filterModelIndex.value.get(field)?.rangeValue ?? { max: null, min: null },\n };\n }\n\n if (type === \"boolean\") {\n return {\n ...baseFilter,\n booleanValue: filterModelIndex.value.get(field)?.booleanValue ?? null,\n };\n }\n\n if (type === \"exists\") {\n return {\n ...baseFilter,\n existsValue: filterModelIndex.value.get(field)?.existsValue ?? false,\n };\n }\n\n const baseOptions = knownOptionsFor(field);\n const selectedRawValuesByField = getSelectedRawValuesByField(colDef, baseOptions);\n const fallbackOptions = getSelectedFallbackOptions(field, colDef, selectedRawValuesByField, baseOptions);\n const knownOptions = [...baseOptions, ...fallbackOptions];\n const aggregateSelectionState = isAggregateValueFilter(colDef)\n ? seedFilterPanelAggregateSelectionState({\n colDef,\n model: activeFilterModel.value as AdvancedFilterModel | null,\n options: knownOptions,\n })\n : undefined;\n\n return {\n ...baseFilter,\n aggregateSelectionState,\n knownOptions,\n options: filterOptionsFor(field),\n selectedValues: aggregateSelectionState\n ? aggregateSelectionState.flatMap((node) => (node.state === \"selected\" ? [node.id] : []))\n : getSelectedValuesForFilter(field, selectedRawValuesByField, knownOptions),\n };\n });\n});\nconst visibleFilters = computed<PvFilterPanelResolvedFilter[]>(() => {\n if (selectedCategory.value === null) return resolvedFilters.value;\n return resolvedFilters.value.filter((filter) => filter.category === selectedCategory.value);\n});\nconst appliedGroups = computed<PvFilterPanelAppliedGroup[]>(() => {\n return resolvedFilters.value.flatMap((filter) => {\n const values = getAppliedValues(filter);\n if (!values.length) return [];\n return [\n {\n key: filter.key,\n label: filter.label,\n values,\n },\n ];\n });\n});\nconst appliedCount = computed(() => appliedGroups.value.reduce((sum, group) => sum + group.values.length, 0));\nconst filtersWithOpenState = computed<PvFilterPanelResolvedFilter[]>(() => {\n return visibleFilters.value.map((filter) => ({\n ...filter,\n isOpen: openSections.value[filter.key] ?? filter.isOpen ?? false,\n }));\n});\nconst hasActiveFilters = computed(() =>\n advancedFilterHasConditions(activeFilterModel.value, effectiveFilterModelType.value),\n);\nconst modeOptions = computed(() => [\n { label: \"Filters\", value: \"filters\" },\n { label: `Applied (${appliedCount.value})`, value: \"applied\" },\n]);\nconst panelStyle = computed<CSSProperties>(() => ({\n \"--flex-align\": \"stretch\",\n \"--flex-gap\": \"0\",\n flex: `0 0 ${props.width}`,\n minHeight: \"0\",\n width: props.width,\n}));\nconst showClearAll = computed(() => hasActiveFilters.value || appliedCount.value > 0);\n\nconst isSuggestionActive = (suggestion: PvFilterPanelSuggestion) => {\n const filter = findResolvedFilter(suggestion.field);\n if (!filter || filter.type !== suggestion.filter.type) return true;\n\n if (suggestion.filter.type === \"value\") {\n if (filter.isAggregate && suggestion.option) {\n const { selected } = getFilterPanelAggregateOptionSelectionStatus({\n option: suggestion.option,\n options: filter.knownOptions ?? [],\n state: filter.aggregateSelectionState ?? [],\n });\n return suggestion.filter.checked ? selected : !selected;\n }\n\n const selectedValueSet = new Set(filter.selectedValues ?? []);\n const optionValue = suggestion.option?.value ?? suggestion.filter.value;\n const rawValue = suggestion.option ? getFilterPanelOptionRawValue(suggestion.option) : suggestion.filter.value;\n const isSelected = selectedValueSet.has(optionValue) || (rawValue !== null && selectedValueSet.has(rawValue));\n return suggestion.filter.checked ? isSelected : !isSelected;\n }\n\n if (suggestion.filter.type === \"range\") {\n return (\n filter.rangeValue?.min === suggestion.filter.value.min && filter.rangeValue?.max === suggestion.filter.value.max\n );\n }\n\n if (suggestion.filter.type === \"boolean\") {\n return filter.booleanValue === suggestion.filter.value;\n }\n\n return (filter.existsValue ?? false) === suggestion.filter.value;\n};\n\nconst visibleSuggestions = computed(() =>\n props.filterSuggestions.filter((suggestion) => !isSuggestionActive(suggestion)),\n);\n\nconst getSuggestionKey = (suggestion: PvFilterPanelSuggestion) => {\n if (suggestion.key) return suggestion.key;\n\n const filterValue = \"value\" in suggestion.filter ? suggestion.filter.value : \"\";\n return `${suggestion.field}-${suggestion.filter.type}-${JSON.stringify(filterValue)}`;\n};\n\nconst updateStoreSelectedValues = (\n filterKey: string,\n field: string,\n nextValues: string[],\n selectedOption?: PvFilterPanelOption,\n) => {\n const store = effectiveFilterStore.value;\n if (!store) return;\n\n store.setFilterSelectedValues(field, nextValues, props.staged);\n\n const selectedMetadataMap = props.staged ? store.stagedFilterSelectedMetadataMap : store.filterSelectedMetadataMap;\n const selectedMetadata = selectedMetadataMap.value[filterKey] ?? [];\n const nextSelectedValueSet = new Set(nextValues);\n const nextMetadata = selectedMetadata.filter((option): option is PvFilterPanelOption => {\n if (!option) return false;\n const optionField = getFilterPanelOptionField(option, filterKey);\n const optionValue = getFilterPanelOptionRawValue(option) ?? option.value;\n return optionField !== field || nextSelectedValueSet.has(optionValue);\n });\n\n if (selectedOption) {\n const selectedOptionValue = getFilterPanelOptionRawValue(selectedOption) ?? selectedOption.value;\n const selectedOptionField = getFilterPanelOptionField(selectedOption, filterKey);\n const alreadyPresent = nextMetadata.some((option) => {\n const optionValue = getFilterPanelOptionRawValue(option) ?? option.value;\n return (\n getFilterPanelOptionField(option, filterKey) === selectedOptionField && optionValue === selectedOptionValue\n );\n });\n if (!alreadyPresent) nextMetadata.push(selectedOption);\n }\n\n selectedMetadataMap.value[filterKey] = nextMetadata;\n};\n\nconst updateStoreAggregateSelections = (\n filter: PvFilterPanelResolvedFilter,\n state = filter.aggregateSelectionState ?? [],\n) => {\n const store = effectiveFilterStore.value;\n if (!store || !filter.isAggregate) return;\n\n const selectedIds = state.flatMap((node) => (node.state === \"selected\" ? [node.id] : []));\n store.setFilterSelectedValues(filter.key, selectedIds, props.staged);\n\n const selectedMetadataMap = props.staged ? store.stagedFilterSelectedMetadataMap : store.filterSelectedMetadataMap;\n selectedMetadataMap.value[filter.key] = getFilterPanelAggregateSelectionOptions({\n options: filter.knownOptions ?? [],\n state,\n });\n};\n\nconst markStoreValueFiltersStale = (changedField?: string) => {\n if (!isStoreMode.value) return;\n\n const store = effectiveFilterStore.value;\n const changedFields = new Set<string>();\n\n if (changedField) {\n changedFields.add(changedField);\n const changedFilter = findResolvedFilter(changedField);\n if (changedFilter) {\n changedFields.add(changedFilter.key);\n getRepresentedFields(changedFilter.colDef).forEach((field) => changedFields.add(field));\n }\n }\n\n for (const filter of resolvedFilters.value) {\n if (filter.type !== \"value\") continue;\n\n const isChangedFilter = changedField\n ? changedFields.has(filter.key) || getRepresentedFields(filter.colDef).some((field) => changedFields.has(field))\n : false;\n\n if (!isChangedFilter) store.filterStaleMap.value[filter.key] = true;\n }\n};\n\nconst emitFilterChange = (\n nextFilterModel: PvFilterPanelFilterModel,\n reason: PvFilterPanelFilterChangeReason,\n field?: string,\n type?: PvFilterPanelFilterType,\n) => {\n warnIfModelShapeMismatchesType(nextFilterModel);\n\n const previousFilterModel = activeFilterModel.value;\n const store = effectiveFilterStore.value;\n if (store) {\n setActiveFilterModelInStore(store, nextFilterModel);\n if (nextFilterModel === null) {\n if (props.staged) {\n store.stagedFilterSelectedValueMap.value = {};\n store.stagedFilterSelectedMetadataMap.value = {};\n } else {\n store.filterSelectedValueMap.value = {};\n store.filterSelectedMetadataMap.value = {};\n }\n }\n } else if (props.staged) {\n stagedFilterModel.value = nextFilterModel;\n }\n\n if (!props.filterStore && !injectedFilterStore && !props.staged) filterModel.value = nextFilterModel;\n markStoreValueFiltersStale(field);\n const filter = field ? findResolvedFilter(field) : undefined;\n emit(\"filter-change\", {\n colDef: filter?.colDef,\n field,\n filterModel: nextFilterModel,\n previousFilterModel,\n reason,\n type,\n });\n};\n\nconst getAppliedBooleanValue = (filter: PvFilterPanelResolvedFilter): PvFilterPanelAppliedValue[] => {\n const value = filter.booleanValue ?? null;\n if (value === null) return [];\n\n return [\n {\n label: filter.valueLabels?.[String(value)] ?? (value ? \"Yes\" : \"No\"),\n type: \"boolean\",\n value: BOOLEAN_APPLIED_VALUE,\n },\n ];\n};\n\nconst getAppliedExistsValue = (filter: PvFilterPanelResolvedFilter): PvFilterPanelAppliedValue[] => {\n if (!filter.existsValue) return [];\n\n return [\n {\n label: filter.existsLabel ?? `Has ${filter.label}`,\n type: \"exists\",\n value: EXISTS_APPLIED_VALUE,\n },\n ];\n};\n\nconst getAppliedRangeValue = (filter: PvFilterPanelResolvedFilter): PvFilterPanelAppliedValue[] => {\n const rangeValue = filter.rangeValue ?? { max: null, min: null };\n if (rangeValue.min === null && rangeValue.max === null) return [];\n\n return [\n {\n label: formatFilterPanelRangeValue(rangeValue.min, rangeValue.max, {\n dataType: filter.dataType,\n valueDecimals: filter.valueDecimals,\n }),\n type: \"range\",\n value: RANGE_APPLIED_VALUE,\n },\n ];\n};\n\nconst getAppliedValueFilterValue = (\n filter: PvFilterPanelResolvedFilter,\n value: string,\n optionByValue: Map<string, PvFilterPanelOption>,\n): PvFilterPanelAppliedValue => {\n const option = optionByValue.get(value) ?? null;\n\n return {\n field: option ? getFilterPanelOptionField(option, filter.key) : undefined,\n label: option ? getFilterOptionLabel(option, filter.colDef) : value,\n resultCount: getFilterOptionResultCount(option),\n subText: option?.subText,\n subduedText: option?.subduedText,\n type: \"value\",\n value: option ? (getFilterPanelOptionRawValue(option) ?? option.value) : value,\n };\n};\n\nconst getAppliedFilterGroupValues = (filter: PvFilterPanelResolvedFilter): PvFilterPanelAppliedValue[] => {\n return (filter.filterGroupOptions ?? []).flatMap((groupOption) => {\n if (!groupOption.isActive) return [];\n return [\n {\n field: groupOption.field,\n label: groupOption.label,\n type: \"boolean\" as const,\n value: BOOLEAN_APPLIED_VALUE,\n },\n ];\n });\n};\n\nconst getAppliedAggregateValues = (filter: PvFilterPanelResolvedFilter): PvFilterPanelAppliedValue[] => {\n return getFilterPanelAggregateSelectionOptions({\n options: filter.knownOptions ?? [],\n state: filter.aggregateSelectionState ?? [],\n }).map((option) => ({\n field: filter.key,\n label: getFilterOptionLabel(option, filter.colDef),\n resultCount: getFilterOptionResultCount(option),\n subText: option.subText,\n subduedText: option.subduedText,\n type: \"value\" as const,\n value: option.value,\n }));\n};\n\nconst getAppliedValues = (filter: PvFilterPanelResolvedFilter): PvFilterPanelAppliedValue[] => {\n if (filter.type === \"range\") return getAppliedRangeValue(filter);\n if (filter.type === \"boolean\") return getAppliedBooleanValue(filter);\n if (filter.type === \"exists\") return getAppliedExistsValue(filter);\n if (filter.isAggregate) return [...getAppliedAggregateValues(filter), ...getAppliedFilterGroupValues(filter)];\n\n const optionByValue = new Map(\n flattenFilterPanelOptions(filter.knownOptions ?? []).map((option) => [option.value, option]),\n );\n return [\n ...(filter.selectedValues ?? []).map((value) => getAppliedValueFilterValue(filter, value, optionByValue)),\n ...getAppliedFilterGroupValues(filter),\n ];\n};\n\nconst cancelClearAllFilters = () => {\n showClearAllConfirm.value = false;\n};\n\nconst clearAllFilters = () => {\n cancelPendingRangeChanges();\n emitFilterChange(null, \"clear-all\");\n};\n\nconst confirmClearAllFilters = () => {\n clearAllFilters();\n showClearAllConfirm.value = false;\n};\n\nconst applyStagedFilters = () => {\n flushPendingRangeChanges();\n const store = effectiveFilterStore.value;\n const nextFilterModel = store ? store.stagedFilterModel.value : stagedFilterModel.value;\n if (store) {\n applyCommittedFilterModelToStore(store, nextFilterModel);\n store.commitStagedFilterSelections();\n store.initStagedFilterSelections();\n }\n if (!props.filterStore && !injectedFilterStore) filterModel.value = nextFilterModel;\n emit(\"apply\", nextFilterModel);\n};\n\nconst cancelStagedFilters = () => {\n cancelPendingRangeChanges();\n const store = effectiveFilterStore.value;\n if (store) {\n store.stagedFilterModel.value = store.filterModel.value;\n store.initStagedFilterSelections();\n }\n stagedFilterModel.value = filterModel.value;\n emit(\"cancel\");\n};\n\nconst getExistsAdvancedFilterType = (field: string) => {\n return getAdvancedFilterTypeForDataType(findResolvedFilter(field)?.dataType);\n};\n\nconst handleAggregateSelectionChange = (\n filterKey: string,\n state: NonNullable<PvFilterPanelResolvedFilter[\"aggregateSelectionState\"]>,\n reason: PvFilterPanelFilterChangeReason = \"value-toggle\",\n) => {\n const filter = findResolvedFilter(filterKey);\n if (!filter?.isAggregate) return;\n\n updateStoreAggregateSelections(filter, state);\n emitFilterChange(\n buildFilterPanelAggregateModelFromSelectionState({\n baseModel: activeFilterModel.value as AdvancedFilterModel | null,\n colDef: filter.colDef,\n options: filter.knownOptions ?? [],\n state,\n }),\n reason,\n filter.key,\n \"value\",\n );\n};\n\nconst handleAccordionFilterChange = (field: string, change: PvFilterPanelControlChange) => {\n if (change.type === \"aggregate-selection\") {\n handleAggregateSelectionChange(field, change.value);\n return;\n }\n\n const targetField = change.field ?? field;\n const targetColDef = findColDef(targetField) ?? findResolvedFilter(field)?.colDef;\n\n if (change.type === \"value\") {\n const filter = findResolvedFilter(field);\n const option = findKnownOptionForValue(field, targetField, change.value);\n if (filter?.isAggregate && option) {\n handleAggregateSelectionChange(\n field,\n updateFilterPanelAggregateSelectionState({\n checked: change.checked,\n option,\n options: filter.knownOptions ?? [],\n state: filter.aggregateSelectionState ?? [],\n }),\n );\n return;\n }\n\n handleToggleValue(field, targetField, change.value, change.checked, option);\n return;\n }\n\n if (change.type === \"range\") {\n handleRangeChange(targetField, change.value, targetColDef);\n return;\n }\n\n if (change.type === \"boolean\") {\n emitFilterChange(\n updateBooleanFilter(\n activeFilterModel.value as AdvancedFilterModel | null,\n targetField,\n change.value,\n effectiveFilterModelType.value,\n change.field ? \"text\" : \"boolean\",\n targetColDef,\n ),\n \"boolean-change\",\n targetField,\n \"boolean\",\n );\n return;\n }\n\n emitFilterChange(\n updateExistsFilter(\n activeFilterModel.value as AdvancedFilterModel | null,\n targetField,\n change.value,\n getExistsAdvancedFilterType(targetField),\n effectiveFilterModelType.value,\n targetColDef,\n ),\n \"exists-change\",\n targetField,\n \"exists\",\n );\n};\n\nconst shouldFetchStoreOptions = (\n filter: PvFilterPanelResolvedFilter,\n query: string,\n reason: \"open\" | \"search\" | \"load-more\" | \"child-load-more\",\n parentId?: string,\n) => {\n const store = effectiveFilterStore.value;\n if (!store || filter.type !== \"value\") return false;\n if (reason !== \"open\") return true;\n if (parentId) return true;\n if (store.filterLoadingMap.value[filter.key]) return false;\n if (store.filterStaleMap.value[filter.key]) return true;\n\n const loadedOptions = store.filterOptionsMap.value[filter.key] ?? [];\n if (!loadedOptions.length) return true;\n return (store.filterSearchQueries.value[filter.key] ?? \"\") !== query;\n};\n\nconst fetchStoreOptions = (\n filter: PvFilterPanelResolvedFilter,\n query: string,\n reason: \"open\" | \"search\" | \"load-more\" | \"child-load-more\",\n parentId?: string,\n) => {\n const store = effectiveFilterStore.value;\n if (!shouldFetchStoreOptions(filter, query, reason, parentId) || !store) return;\n const selectedValues = Array.from(\n new Set([...getSelectedRawValuesByField(filter.colDef, filter.knownOptions ?? []).values()].flat()),\n );\n void store.fetchFilterOptions({\n colDef: filter.colDef,\n field: filter.key,\n filterModel: activeFilterModel.value,\n parentId,\n query,\n reason,\n selectedValues,\n });\n};\n\nconst handleLoadMore = (filter: PvFilterPanelResolvedFilter, query: string, parentId?: string) => {\n emit(\"load-more\", filter.key, filter.colDef, query, parentId);\n fetchStoreOptions(filter, query, parentId ? \"child-load-more\" : \"load-more\", parentId);\n};\n\nconst handleModeChange = (value: string) => {\n if (value === \"filters\" || value === \"applied\") {\n mode.value = value;\n }\n};\n\nconst applyRangeChange = (field: string, value: PvRangeValue, colDef?: PvFilterPanelColDef) => {\n emitFilterChange(\n updateRangeFilter(\n activeFilterModel.value as AdvancedFilterModel | null,\n field,\n value.min,\n value.max,\n effectiveFilterModelType.value,\n colDef,\n ),\n \"range-change\",\n field,\n \"range\",\n );\n};\n\nconst cancelPendingRangeChanges = () => {\n for (const { timer } of pendingRangeChanges.values()) {\n window.clearTimeout(timer);\n }\n pendingRangeChanges.clear();\n};\n\nconst flushPendingRangeChanges = () => {\n const changes = [...pendingRangeChanges.entries()];\n cancelPendingRangeChanges();\n for (const [field, change] of changes) {\n applyRangeChange(field, change.value, change.colDef);\n }\n};\n\nconst handleRangeChange = (field: string, value: PvRangeValue, colDef?: PvFilterPanelColDef) => {\n if (props.rangeDebounceMs <= 0) {\n applyRangeChange(field, value, colDef);\n return;\n }\n\n const existingChange = pendingRangeChanges.get(field);\n if (existingChange) window.clearTimeout(existingChange.timer);\n\n const timer = window.setTimeout(() => {\n pendingRangeChanges.delete(field);\n applyRangeChange(field, value, colDef);\n }, props.rangeDebounceMs);\n pendingRangeChanges.set(field, { colDef, timer, value });\n};\n\nonBeforeUnmount(cancelPendingRangeChanges);\n\nconst handleSearchChange = (filter: PvFilterPanelResolvedFilter, query: string) => {\n emit(\"search-change\", filter.key, query, filter.colDef);\n fetchStoreOptions(filter, query, \"search\");\n};\n\nconst handleSectionOpenChange = (filter: PvFilterPanelResolvedFilter, open: boolean) => {\n openSections.value[filter.key] = open;\n emit(\"open-change\", filter.key, open, filter.colDef);\n if (open) fetchStoreOptions(filter, filter.searchQuery ?? \"\", \"open\");\n};\n\nconst handleToggleValue = (\n filterKey: string,\n field: string,\n value: string,\n checked: boolean,\n option?: PvFilterPanelOption,\n) => {\n const currentValues = filterModelIndex.value.get(field)?.values ?? [];\n const nextValues = checked\n ? Array.from(new Set([...currentValues, value]))\n : currentValues.filter((selectedValue) => selectedValue !== value);\n\n updateStoreSelectedValues(filterKey, field, nextValues, checked ? option : undefined);\n emitFilterChange(\n updateValueFilter(\n activeFilterModel.value as AdvancedFilterModel | null,\n field,\n nextValues,\n effectiveFilterModelType.value,\n findColDef(field) ?? findResolvedFilter(filterKey)?.colDef,\n ),\n \"value-toggle\",\n field,\n \"value\",\n );\n};\n\nconst handleSuggestionClick = (suggestion: PvFilterPanelSuggestion) => {\n if (suggestion.filter.type === \"value\" && suggestion.option) {\n const filter = findResolvedFilter(suggestion.field);\n const field = getFilterPanelOptionField(suggestion.option, suggestion.field);\n const value = getFilterPanelOptionRawValue(suggestion.option) ?? suggestion.filter.value;\n\n if (filter?.isAggregate) {\n handleAggregateSelectionChange(\n suggestion.field,\n updateFilterPanelAggregateSelectionState({\n checked: suggestion.filter.checked,\n option: suggestion.option,\n options: filter.knownOptions ?? [],\n state: filter.aggregateSelectionState ?? [],\n }),\n );\n } else {\n handleToggleValue(suggestion.field, field, value, suggestion.filter.checked, suggestion.option);\n }\n } else {\n handleAccordionFilterChange(suggestion.field, suggestion.filter);\n }\n emit(\"suggestion-click\", suggestion);\n};\n\nconst removeAppliedFilter = (field: string, value: string, type?: PvFilterPanelFilterType) => {\n const filterType = type ?? findResolvedFilter(field)?.type ?? \"value\";\n\n if (filterType === \"range\" || (!type && value === RANGE_APPLIED_VALUE)) {\n emitFilterChange(\n updateRangeFilter(\n activeFilterModel.value as AdvancedFilterModel | null,\n field,\n null,\n null,\n effectiveFilterModelType.value,\n findColDef(field) ?? findResolvedFilter(field)?.colDef,\n ),\n \"remove-filter\",\n field,\n \"range\",\n );\n return;\n }\n\n if (filterType === \"boolean\" || (!type && value === BOOLEAN_APPLIED_VALUE)) {\n emitFilterChange(\n updateBooleanFilter(\n activeFilterModel.value as AdvancedFilterModel | null,\n field,\n null,\n effectiveFilterModelType.value,\n \"boolean\",\n findColDef(field) ?? findResolvedFilter(field)?.colDef,\n ),\n \"remove-filter\",\n field,\n \"boolean\",\n );\n return;\n }\n\n if (filterType === \"exists\" || (!type && value === EXISTS_APPLIED_VALUE)) {\n emitFilterChange(\n updateExistsFilter(\n activeFilterModel.value as AdvancedFilterModel | null,\n field,\n false,\n \"text\",\n effectiveFilterModelType.value,\n findColDef(field) ?? findResolvedFilter(field)?.colDef,\n ),\n \"remove-filter\",\n field,\n \"exists\",\n );\n return;\n }\n\n const filter = findResolvedFilter(field);\n if (filterType === \"value\" && filter?.isAggregate) {\n const option = findFilterPanelOptionByValue(filter.knownOptions ?? [], value);\n const currentState = filter.aggregateSelectionState ?? [];\n const nextState = option\n ? updateFilterPanelAggregateSelectionState({\n checked: false,\n option,\n options: filter.knownOptions ?? [],\n state: currentState,\n })\n : currentState.filter((node) => node.id !== value);\n handleAggregateSelectionChange(filter.key, nextState, \"remove-filter\");\n return;\n }\n\n const currentValues = filterModelIndex.value.get(field)?.values ?? [];\n const nextValues = currentValues.filter((selectedValue) => selectedValue !== value);\n updateStoreSelectedValues(findResolvedFilter(field)?.key ?? field, field, nextValues);\n emitFilterChange(\n updateValueFilter(\n activeFilterModel.value as AdvancedFilterModel | null,\n field,\n nextValues,\n effectiveFilterModelType.value,\n findColDef(field) ?? findResolvedFilter(field)?.colDef,\n ),\n \"remove-filter\",\n field,\n \"value\",\n );\n};\n\nconst requestClearAllFilters = () => {\n showClearAllConfirm.value = true;\n};\n</script>\n\n<template>\n <aside\n v-if=\"!isCollapsed\"\n class=\"pv-flex-vertical pv-surface pv-border-right\"\n data-testid=\"pv-filter-panel\"\n :aria-label=\"ariaLabel\"\n :style=\"panelStyle\"\n >\n <div class=\"pv-filter-panel-header pv-flex pv-border-bottom\">\n <PvSegmentedControl\n :modelValue=\"mode\"\n :options=\"modeOptions\"\n class=\"pv-filter-panel-mode-control\"\n size=\"xl\"\n @update:modelValue=\"handleModeChange\"\n />\n <PvButton\n ariaLabel=\"Collapse filters\"\n leftIcon=\"chevrons-left\"\n size=\"xl\"\n variant=\"secondary\"\n @click=\"isCollapsed = true\"\n />\n </div>\n\n <div class=\"pv-filter-panel-body pv-flex-vertical\">\n <div\n v-show=\"mode === 'filters'\"\n class=\"pv-filter-panel-filters-view pv-flex-vertical\"\n data-testid=\"pv-filter-panel-filters-view\"\n >\n <section\n v-if=\"!readOnly && visibleSuggestions.length\"\n aria-label=\"Filter suggestions\"\n class=\"pv-filter-panel-suggestions pv-flex-vertical pv-border-bottom\"\n data-testid=\"pv-filter-panel-suggestions\"\n >\n <p class=\"pv-filter-panel-section-title pv-text-title-sm pv-text-subdued\">Suggestions</p>\n <div class=\"pv-filter-panel-suggestion-tags pv-flex\">\n <PvSuggestionTag\n v-for=\"suggestion in visibleSuggestions\"\n :key=\"getSuggestionKey(suggestion)\"\n :icon=\"suggestion.icon\"\n :icon-classes=\"suggestion.iconClasses\"\n :label=\"suggestion.label\"\n @handle-click=\"() => handleSuggestionClick(suggestion)\"\n />\n </div>\n </section>\n <slot name=\"suggestions\" />\n <PvFilterPanelCategoryButtonRow\n v-model=\"selectedCategory\"\n :category-order=\"categoryOrder\"\n :filters=\"resolvedFilters\"\n />\n <div v-if=\"!resolvedFilters.length\" class=\"pv-filter-panel-empty pv-text-body-sm pv-text-subdued\">\n No filters available.\n </div>\n <div v-else-if=\"!visibleFilters.length\" class=\"pv-filter-panel-empty pv-text-body-sm pv-text-subdued\">\n No filters in this category.\n </div>\n <div v-else class=\"pv-filter-panel-filter-list pv-flex-vertical\">\n <PvFilterPanelAccordion\n v-for=\"filter in filtersWithOpenState\"\n :key=\"filter.key\"\n :filter=\"filter\"\n @filter-change=\"(change) => handleAccordionFilterChange(filter.key, change)\"\n @focus-change=\"(field, value, option) => emit('focus-change', field, value, option)\"\n @handle-settings-icon=\"(field, colDef) => emit('handle-settings-icon', field, colDef)\"\n @load-more=\"(query, parentId) => handleLoadMore(filter, query, parentId)\"\n @open-change=\"(open) => handleSectionOpenChange(filter, open)\"\n @search-change=\"(query) => handleSearchChange(filter, query)\"\n />\n </div>\n </div>\n\n <PvFilterPanelAppliedFiltersSection\n v-show=\"mode === 'applied'\"\n :applied-count=\"appliedCount\"\n :applied-groups=\"appliedGroups\"\n :read-only=\"readOnly\"\n @remove-filter=\"removeAppliedFilter\"\n />\n </div>\n\n <div v-if=\"(showClearAll || staged) && !readOnly\" class=\"pv-filter-panel-footer pv-flex pv-border-top\">\n <PvButton\n v-if=\"showClearAll\"\n class=\"pv-text-brand\"\n :label=\"clearAllLabel\"\n variant=\"ghost\"\n @click=\"requestClearAllFilters\"\n />\n <div v-if=\"staged\" class=\"pv-filter-panel-actions pv-flex\">\n <PvButton :label=\"cancelLabel\" variant=\"ghost\" @click=\"cancelStagedFilters\" />\n <PvButton :label=\"applyLabel\" variant=\"primary\" @click=\"applyStagedFilters\" />\n </div>\n </div>\n </aside>\n\n <PvModal v-model=\"showClearAllConfirm\" :header=\"clearAllHeader\" :style=\"{ '--max-width': '440px' }\">\n <template #body>\n <p class=\"pv-text-body-sm\">\n {{ clearAllBody }}\n </p>\n </template>\n <template #footer>\n <div class=\"pv-filter-panel-modal-footer pv-flex\">\n <PvButton :label=\"cancelLabel\" variant=\"ghost\" @click=\"cancelClearAllFilters\" />\n <PvButton :label=\"clearAllLabel\" variant=\"primary\" @click=\"confirmClearAllFilters\" />\n </div>\n </template>\n </PvModal>\n</template>\n\n<style scoped>\n.pv-filter-panel-actions,\n.pv-filter-panel-header,\n.pv-filter-panel-suggestion-tags {\n --flex-gap: 0.5rem;\n}\n\n.pv-filter-panel-body,\n.pv-filter-panel-filters-view {\n --flex-align: stretch;\n --flex-gap: 0;\n}\n\n.pv-filter-panel-body {\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n}\n\n.pv-filter-panel-empty,\n.pv-filter-panel-footer,\n.pv-filter-panel-suggestions {\n padding: 12px;\n}\n\n.pv-filter-panel-filter-list {\n --flex-align: stretch;\n --flex-gap: 8px;\n padding-top: 8px;\n}\n\n.pv-filter-panel-footer {\n --flex-justify: space-between;\n margin-top: auto;\n}\n\n.pv-filter-panel-header {\n --flex-align: center;\n padding: 0 12px 12px;\n}\n\n.pv-filter-panel-mode-control {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.pv-filter-panel-modal-footer {\n --flex-justify: flex-end;\n}\n\n.pv-filter-panel-section-title {\n margin: 0;\n}\n\n.pv-filter-panel-suggestions {\n --flex-align: stretch;\n}\n\n.pv-filter-panel-suggestion-tags {\n --flex-wrap: wrap;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, type CSSProperties, getCurrentInstance, onBeforeUnmount, ref, watch, watchEffect } from \"vue\";\nimport type { AdvancedFilterModel } from \"ag-grid-enterprise\";\n\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport PvModal from \"@/components/base/PvModal/PvModal.vue\";\nimport PvSegmentedControl from \"@/components/base/PvSegmentedControl/PvSegmentedControl.vue\";\nimport PvSuggestionTag from \"@/components/base/PvSuggestionTag/PvSuggestionTag.vue\";\nimport {\n advancedFilterHasConditions,\n createFilterPanelModelIndex,\n getAdvancedFilterTypeForDataType,\n updateBooleanFilter,\n updateExistsFilter,\n updateRangeFilter,\n updateValueFilter,\n} from \"./advancedFilterModel\";\nimport {\n buildFilterPanelAggregateModelFromSelectionState,\n findFilterPanelOptionByValue,\n getFilterPanelAggregateOptionSelectionStatus,\n getFilterPanelAggregateSelectedValuesByField,\n getFilterPanelAggregateSelectionOptions,\n isFilterPanelAggregateColDef,\n seedFilterPanelAggregateSelectionState,\n updateFilterPanelAggregateSelectionState,\n} from \"./aggregateFilterModel\";\nimport { formatFilterPanelRangeValue, getFilterOptionLabel, getFilterOptionResultCount } from \"./filterOptionDisplay\";\nimport {\n createFilterPanelScopedValue,\n filterPanelOptionMatchesRawValue,\n flattenFilterPanelOptions,\n getFilterPanelOptionField,\n getFilterPanelOptionRawValue,\n} from \"./filterOptionValue\";\nimport PvFilterPanelAccordion from \"./PvFilterPanelAccordion.vue\";\nimport PvFilterPanelAppliedFiltersSection from \"./PvFilterPanelAppliedFiltersSection.vue\";\nimport PvFilterPanelCategoryButtonRow from \"./PvFilterPanelCategoryButtonRow.vue\";\nimport { createPvFilterStore, useOptionalPvFilterStore } from \"./usePvFilterStore\";\nimport type {\n PvFilterPanelAppliedGroup,\n PvFilterPanelAppliedValue,\n PvFilterPanelCategory,\n PvFilterPanelColDef,\n PvFilterPanelControlChange,\n PvFilterPanelFilterChangeEvent,\n PvFilterPanelFilterChangeReason,\n PvFilterPanelFilterModel,\n PvFilterPanelFilterType,\n PvFilterPanelOption,\n PvFilterPanelProps,\n PvFilterPanelResolvedFilter,\n PvFilterPanelSuggestion,\n PvFilterStore,\n} from \"./types\";\nimport type { PvRangeValue } from \"@/components/base/PvRange/types\";\n\ntype PvFilterPanelMode = \"filters\" | \"applied\";\n\ntype StoreWithApplyFilterModel = PvFilterStore & {\n applyFilterModel?: (model: PvFilterPanelFilterModel) => void;\n};\n\nconst RANGE_APPLIED_VALUE = \"__range__\";\nconst BOOLEAN_APPLIED_VALUE = \"__boolean__\";\nconst EXISTS_APPLIED_VALUE = \"__exists__\";\nconst FILTER_PANEL_TYPES = new Set<PvFilterPanelFilterType>([\"value\", \"range\", \"boolean\", \"exists\"]);\n\nconst props = withDefaults(defineProps<PvFilterPanelProps>(), {\n applyLabel: \"Apply\",\n ariaLabel: \"Filters\",\n autoHideRelatedFilterFields: undefined,\n cancelLabel: \"Cancel\",\n clearAllBody: \"Are you sure you want to clear all applied filters? This will reset your current filters.\",\n clearAllHeader: \"Clear all filters\",\n clearAllLabel: \"Clear all\",\n colDefs: () => [],\n devMode: false,\n displayPreferencesIcon: false,\n enableFocusView: false,\n filterHasMoreMap: () => ({}),\n filterLoadingMap: () => ({}),\n filterLoadingMoreMap: () => ({}),\n filterOptions: () => ({}),\n filterSearchQueries: () => ({}),\n filterSuggestions: () => [],\n focusableFields: () => [],\n focusedValues: () => ({}),\n focusText: \"Focus\",\n rangeDebounceMs: 250,\n readOnly: false,\n staged: false,\n width: \"320px\",\n});\n\nconst filterModel = defineModel<PvFilterPanelFilterModel>(\"filterModel\", { default: null });\nconst isCollapsed = defineModel<boolean>(\"isCollapsed\", { default: false });\n\nconst emit = defineEmits<{\n apply: [filterModel: PvFilterPanelFilterModel];\n cancel: [];\n \"filter-change\": [event: PvFilterPanelFilterChangeEvent];\n \"focus-change\": [field: string, value: string, option: PvFilterPanelOption];\n \"handle-settings-icon\": [field: string, colDef: PvFilterPanelColDef];\n \"load-more\": [field: string, colDef: PvFilterPanelColDef, query: string, parentId?: string];\n \"open-change\": [field: string, open: boolean, colDef: PvFilterPanelColDef];\n \"search-change\": [field: string, query: string, colDef: PvFilterPanelColDef];\n \"suggestion-click\": [suggestion: PvFilterPanelSuggestion];\n}>();\n\nconst instance = getCurrentInstance();\nconst mode = ref<PvFilterPanelMode>(\"filters\");\nconst openSections = ref<Record<string, boolean>>({});\nconst selectedCategory = ref<PvFilterPanelCategory | null>(null);\nconst showClearAllConfirm = ref(false);\nconst stagedFilterModel = ref<PvFilterPanelFilterModel>(filterModel.value);\nconst internalFilterStore = createPvFilterStore();\nconst injectedFilterStore = useOptionalPvFilterStore();\nconst warnedIgnoredStoreProps = new Set<string>();\nconst warnedFilterModelTypeIssues = new Set<string>();\nconst pendingRangeChanges = new Map<string, { colDef?: PvFilterPanelColDef; timer: number; value: PvRangeValue }>();\n\nconst hasExternalFilterStore = computed(() => Boolean(props.filterStore ?? injectedFilterStore));\nconst isHandlerBackedInternalStore = computed(\n () => !hasExternalFilterStore.value && Boolean(props.filterOptionsHandler),\n);\nconst effectiveFilterStore = computed(() => props.filterStore ?? injectedFilterStore ?? internalFilterStore);\nconst usesInternalFilterStore = computed(() => effectiveFilterStore.value === internalFilterStore);\nconst isStoreMode = computed(() => hasExternalFilterStore.value || isHandlerBackedInternalStore.value);\nconst explicitFilterModelType = computed(\n () => props.filterModelType ?? effectiveFilterStore.value?.filterModelType.value,\n);\nconst effectiveFilterModelType = computed(() => explicitFilterModelType.value ?? \"advanced\");\nconst activeFilterModel = computed(() => {\n const store = effectiveFilterStore.value;\n if (store) return props.staged ? store.stagedFilterModel.value : store.filterModel.value;\n return props.staged ? stagedFilterModel.value : filterModel.value;\n});\nconst filterModelIndex = computed(() =>\n createFilterPanelModelIndex(activeFilterModel.value, effectiveFilterModelType.value),\n);\n\nconst applyCommittedFilterModelToStore = (store: PvFilterStore, nextFilterModel: PvFilterPanelFilterModel) => {\n const applyFilterModel = (store as StoreWithApplyFilterModel).applyFilterModel;\n if (typeof applyFilterModel === \"function\") {\n applyFilterModel(nextFilterModel);\n return;\n }\n\n store.filterModel.value = nextFilterModel;\n};\n\nconst setActiveFilterModelInStore = (store: PvFilterStore, nextFilterModel: PvFilterPanelFilterModel) => {\n if (props.staged) {\n store.stagedFilterModel.value = nextFilterModel;\n return;\n }\n\n applyCommittedFilterModelToStore(store, nextFilterModel);\n};\n\nwatch(\n () => props.filterOptionsHandler,\n (handler) => {\n internalFilterStore.setFilterOptionsHandler(handler);\n },\n { immediate: true },\n);\n\nwatch(\n [() => props.filterOptions, usesInternalFilterStore, () => props.filterOptionsHandler],\n ([filterOptions, usesInternalStore, handler]) => {\n if (!usesInternalStore || handler) return;\n internalFilterStore.filterOptionsMap.value = Object.fromEntries(\n Object.entries(filterOptions).map(([field, options]) => [field, [...options]]),\n );\n },\n { deep: true, immediate: true },\n);\n\nwatch(\n [() => props.filterHasMoreMap, usesInternalFilterStore, () => props.filterOptionsHandler],\n ([filterHasMoreMap, usesInternalStore, handler]) => {\n if (usesInternalStore && !handler) internalFilterStore.filterHasMoreMap.value = { ...filterHasMoreMap };\n },\n { deep: true, immediate: true },\n);\n\nwatch(\n [() => props.filterLoadingMap, usesInternalFilterStore, () => props.filterOptionsHandler],\n ([filterLoadingMap, usesInternalStore, handler]) => {\n if (usesInternalStore && !handler) internalFilterStore.filterLoadingMap.value = { ...filterLoadingMap };\n },\n { deep: true, immediate: true },\n);\n\nwatch(\n [() => props.filterLoadingMoreMap, usesInternalFilterStore, () => props.filterOptionsHandler],\n ([filterLoadingMoreMap, usesInternalStore, handler]) => {\n if (usesInternalStore && !handler) {\n internalFilterStore.filterLoadingMoreMap.value = { ...filterLoadingMoreMap };\n }\n },\n { deep: true, immediate: true },\n);\n\nwatch(\n [() => props.filterSearchQueries, usesInternalFilterStore, () => props.filterOptionsHandler],\n ([filterSearchQueries, usesInternalStore, handler]) => {\n if (usesInternalStore && !handler) internalFilterStore.filterSearchQueries.value = { ...filterSearchQueries };\n },\n { deep: true, immediate: true },\n);\n\nwatch(\n [filterModel, usesInternalFilterStore, () => props.staged],\n ([nextFilterModel, usesInternalStore]) => {\n if (!usesInternalStore) return;\n if (props.staged) stagedFilterModel.value = nextFilterModel;\n internalFilterStore.filterModel.value = nextFilterModel;\n if (props.staged) internalFilterStore.stagedFilterModel.value = nextFilterModel;\n },\n { deep: true, immediate: true },\n);\n\nwatch(\n [() => props.staged, effectiveFilterStore],\n ([isStaged]) => {\n if (isStaged) {\n stagedFilterModel.value = filterModel.value;\n const store = effectiveFilterStore.value;\n if (store) {\n store.stagedFilterModel.value = store.filterModel.value;\n store.initStagedFilterSelections();\n }\n }\n },\n { immediate: true },\n);\n\nconst warnIgnoredStoreProp = (propName: string, shouldWarn: boolean) => {\n if (!isStoreMode.value || !shouldWarn || warnedIgnoredStoreProps.has(propName)) return;\n console.warn(`PvFilterPanel: \"${propName}\" is ignored when filterStore/filterOptionsHandler store mode is active.`);\n warnedIgnoredStoreProps.add(propName);\n};\n\nconst warnFilterModelTypeIssue = (key: string, message: string) => {\n if (warnedFilterModelTypeIssues.has(key)) return;\n console.warn(message);\n warnedFilterModelTypeIssues.add(key);\n};\n\nconst hasProvidedFilterModelProp = () => {\n const vnodeProps = instance?.vnode.props ?? {};\n return (\n Object.prototype.hasOwnProperty.call(vnodeProps, \"filterModel\") ||\n Object.prototype.hasOwnProperty.call(vnodeProps, \"filter-model\")\n );\n};\n\nconst isAdvancedFilterModelShape = (model: PvFilterPanelFilterModel) => {\n return Boolean(model && typeof model === \"object\" && \"filterType\" in model);\n};\n\nconst warnIfModelShapeMismatchesType = (model: PvFilterPanelFilterModel) => {\n if (!model) return;\n const isAdvancedShape = isAdvancedFilterModelShape(model);\n if (effectiveFilterModelType.value === \"advanced\" && !isAdvancedShape) {\n warnFilterModelTypeIssue(\n \"regular-model-in-advanced-mode\",\n 'PvFilterPanel: produced a regular FilterModel while filterModelType is \"advanced\".',\n );\n }\n if (effectiveFilterModelType.value === \"regular\" && isAdvancedShape) {\n warnFilterModelTypeIssue(\n \"advanced-model-in-regular-mode\",\n 'PvFilterPanel: produced an AdvancedFilterModel while filterModelType is \"regular\".',\n );\n }\n};\n\nwatchEffect(() => {\n warnIgnoredStoreProp(\n \"filterModel\",\n Boolean((props.filterStore || injectedFilterStore) && filterModel.value !== null),\n );\n warnIgnoredStoreProp(\"filterOptions\", Object.keys(props.filterOptions).length > 0);\n warnIgnoredStoreProp(\"filterLoadingMap\", Object.keys(props.filterLoadingMap).length > 0);\n warnIgnoredStoreProp(\"filterLoadingMoreMap\", Object.keys(props.filterLoadingMoreMap).length > 0);\n warnIgnoredStoreProp(\"filterHasMoreMap\", Object.keys(props.filterHasMoreMap).length > 0);\n warnIgnoredStoreProp(\"filterSearchQueries\", Object.keys(props.filterSearchQueries).length > 0);\n warnIgnoredStoreProp(\"filterOptionsHandler\", Boolean(props.filterStore && props.filterOptionsHandler));\n\n const hasExternalAmbiguousModel = Boolean(\n (props.filterStore || injectedFilterStore) && activeFilterModel.value !== null,\n );\n if (\n import.meta.env.DEV &&\n !explicitFilterModelType.value &&\n activeFilterModel.value !== null &&\n !isAdvancedFilterModelShape(activeFilterModel.value) &&\n (hasProvidedFilterModelProp() || hasExternalAmbiguousModel)\n ) {\n warnFilterModelTypeIssue(\n \"missing-filter-model-type\",\n 'PvFilterPanel: filterModelType was not provided by props or filterStore; defaulting to \"advanced\".',\n );\n }\n});\n\nconst getColDefContext = (colDef: PvFilterPanelColDef) => colDef.context ?? {};\nconst getColDefKey = (colDef: PvFilterPanelColDef) => colDef.colId || colDef.field || \"\";\nconst getFiniteNumber = (value: unknown) => (typeof value === \"number\" && Number.isFinite(value) ? value : null);\n\nconst inferFilterType = (colDef: PvFilterPanelColDef): PvFilterPanelFilterType | undefined => {\n const context = getColDefContext(colDef);\n const filterType = context.filterPanelType;\n if (filterType && FILTER_PANEL_TYPES.has(filterType)) return filterType;\n if (context.filterPanelRange) return \"range\";\n if (context.dataType === \"boolean\") return \"boolean\";\n if (colDef.filter) return \"value\";\n return undefined;\n};\n\nconst getFilterType = (colDef: PvFilterPanelColDef): PvFilterPanelFilterType => inferFilterType(colDef) ?? \"value\";\n\nconst getFilterCategory = (colDef: PvFilterPanelColDef): PvFilterPanelCategory | null => {\n return getColDefContext(colDef).filterPanelCategory ?? null;\n};\n\nconst getValueLabels = (colDef: PvFilterPanelColDef): Record<string, string> | null => {\n const valueLabels = getColDefContext(colDef).filterPanelValueLabels;\n if (typeof valueLabels !== \"object\" || valueLabels === null || Array.isArray(valueLabels)) return null;\n\n return Object.fromEntries(\n Object.entries(valueLabels).flatMap(([key, value]) => (typeof value === \"string\" ? [[key, value]] : [])),\n );\n};\n\nconst isFilterableColumn = (colDef: PvFilterPanelColDef) => {\n const context = getColDefContext(colDef);\n const key = getColDefKey(colDef);\n if (!key || context.filterPanelHidden === true) return false;\n if (context.devOnly && !props.devMode) return false;\n if (\n props.autoHideRelatedFilterFields !== false &&\n context.filterPanelHidden !== false &&\n autoHiddenFilterFields.value.has(key)\n ) {\n return false;\n }\n return Boolean(inferFilterType(colDef));\n};\n\nconst filterOptionsFor = (field: string) => {\n return (effectiveFilterStore.value.filterOptionsMap.value[field] ?? []).filter(\n (option): option is PvFilterPanelOption => Boolean(option),\n );\n};\n\nconst selectedMetadataOptionsFor = (field: string) => {\n const store = effectiveFilterStore.value;\n const metadataMap = props.staged ? store.stagedFilterSelectedMetadataMap : store.filterSelectedMetadataMap;\n return (metadataMap.value[field] ?? []).filter((option): option is PvFilterPanelOption => Boolean(option));\n};\n\nconst filterHasMoreFor = (field: string) => effectiveFilterStore.value.filterHasMoreMap.value[field] ?? false;\nconst filterLoadingFor = (field: string) => effectiveFilterStore.value.filterLoadingMap.value[field] ?? false;\nconst filterLoadingMoreFor = (field: string) => effectiveFilterStore.value.filterLoadingMoreMap.value[field] ?? false;\nconst filterSearchQueryFor = (field: string) => effectiveFilterStore.value.filterSearchQueries.value[field] ?? \"\";\n\nconst suggestionOptionsFor = (field: string): PvFilterPanelOption[] => {\n return props.filterSuggestions.flatMap((suggestion) => {\n if (suggestion.field !== field || suggestion.filter.type !== \"value\") return [];\n return [suggestion.option ?? { label: suggestion.label, value: suggestion.filter.value }];\n });\n};\n\nconst knownOptionsFor = (field: string) => [\n ...suggestionOptionsFor(field),\n ...filterOptionsFor(field),\n ...selectedMetadataOptionsFor(field),\n];\n\nconst flattenAggregateFieldHierarchy = (hierarchy: unknown): string[] => {\n if (typeof hierarchy !== \"object\" || hierarchy === null || !(\"field\" in hierarchy)) return [];\n const node = hierarchy as { children?: unknown[]; field?: unknown };\n const field = typeof node.field === \"string\" ? node.field : null;\n const children = Array.isArray(node.children) ? node.children.flatMap(flattenAggregateFieldHierarchy) : [];\n return field ? [field, ...children] : children;\n};\n\nconst autoHiddenFilterFields = computed(() => {\n const fields = new Set<string>();\n for (const colDef of props.colDefs) {\n const context = getColDefContext(colDef);\n for (const field of Array.isArray(context.aggregateFields) ? context.aggregateFields : []) {\n if (field) fields.add(field);\n }\n for (const field of flattenAggregateFieldHierarchy(context.aggregateFieldHierarchy)) {\n if (field) fields.add(field);\n }\n for (const field of context.filterGroup?.fields ?? []) {\n if (field) fields.add(field);\n }\n }\n return fields;\n});\n\nconst getRepresentedFields = (colDef: PvFilterPanelColDef) => {\n const field = getColDefKey(colDef);\n const context = getColDefContext(colDef);\n const aggregateFields = Array.isArray(context.aggregateFields) ? context.aggregateFields.filter(Boolean) : [];\n const hierarchyFields = flattenAggregateFieldHierarchy(context.aggregateFieldHierarchy);\n return Array.from(new Set([field, ...aggregateFields, ...hierarchyFields].filter(Boolean)));\n};\n\nconst isAggregateValueFilter = (colDef: PvFilterPanelColDef) => {\n return effectiveFilterModelType.value === \"advanced\" && isFilterPanelAggregateColDef(colDef);\n};\n\nconst getSelectedRawValuesByField = (colDef: PvFilterPanelColDef, options?: (PvFilterPanelOption | null)[]) => {\n if (isAggregateValueFilter(colDef)) {\n return getFilterPanelAggregateSelectedValuesByField({\n colDef,\n model: activeFilterModel.value as AdvancedFilterModel | null,\n options,\n });\n }\n\n return new Map(\n getRepresentedFields(colDef).map((representedField) => [\n representedField,\n filterModelIndex.value.get(representedField)?.values ?? [],\n ]),\n );\n};\n\nconst getSelectedFallbackOptions = (\n field: string,\n colDef: PvFilterPanelColDef,\n selectedRawValuesByField: Map<string, string[]>,\n options: PvFilterPanelOption[],\n): PvFilterPanelOption[] => {\n const matchedSelections = new Set<string>();\n\n for (const option of flattenFilterPanelOptions(options)) {\n for (const [representedField, rawValues] of selectedRawValuesByField) {\n for (const rawValue of rawValues) {\n if (filterPanelOptionMatchesRawValue(option, representedField, rawValue, field)) {\n matchedSelections.add(`${representedField}:${rawValue}`);\n }\n }\n }\n }\n\n return [...selectedRawValuesByField.entries()].flatMap(([representedField, rawValues]) =>\n rawValues.flatMap((rawValue) => {\n if (matchedSelections.has(`${representedField}:${rawValue}`)) return [];\n return [\n {\n colField: representedField === field ? undefined : representedField,\n label: rawValue,\n metadata: { rawValue },\n value: representedField === field ? rawValue : createFilterPanelScopedValue(representedField, rawValue),\n } satisfies PvFilterPanelOption,\n ];\n }),\n );\n};\n\nconst getSelectedValuesForFilter = (\n field: string,\n selectedRawValuesByField: Map<string, string[]>,\n options: PvFilterPanelOption[],\n) => {\n const selectedValues = new Set<string>();\n\n for (const option of flattenFilterPanelOptions(options)) {\n const targetField = getFilterPanelOptionField(option, field);\n const rawValue = getFilterPanelOptionRawValue(option);\n if (rawValue !== null && selectedRawValuesByField.get(targetField)?.includes(rawValue)) {\n selectedValues.add(option.value);\n }\n }\n\n return Array.from(selectedValues);\n};\n\nconst getFocusedValuesByField = (colDef: PvFilterPanelColDef) => {\n return Object.fromEntries(getRepresentedFields(colDef).map((field) => [field, props.focusedValues[field] ?? []]));\n};\n\nconst findColDef = (field: string) => props.colDefs.find((colDef) => getColDefKey(colDef) === field);\n\nconst getFilterGroupOptions = (colDef: PvFilterPanelColDef) => {\n const filterGroup = getColDefContext(colDef).filterGroup;\n if (!filterGroup?.fields.length) return undefined;\n\n return filterGroup.fields.map((field) => ({\n field,\n isActive: filterModelIndex.value.get(field)?.booleanValue === true,\n label: findColDef(field)?.headerName ?? field,\n }));\n};\n\nconst findResolvedFilter = (field: string) =>\n resolvedFilters.value.find((filter) => filter.key === field) ??\n resolvedFilters.value.find((filter) => getRepresentedFields(filter.colDef).includes(field));\n\nconst findKnownOptionForValue = (filterKey: string, field: string, value: string) => {\n const filter = findResolvedFilter(filterKey);\n return flattenFilterPanelOptions(filter?.knownOptions ?? []).find((option) => {\n return option.value === value || filterPanelOptionMatchesRawValue(option, field, value, filterKey);\n });\n};\n\nconst resolvedFilters = computed<PvFilterPanelResolvedFilter[]>(() => {\n return props.colDefs.filter(isFilterableColumn).map((colDef) => {\n const field = getColDefKey(colDef);\n const context = getColDefContext(colDef);\n const type = getFilterType(colDef);\n const baseFilter = {\n category: getFilterCategory(colDef),\n colDef,\n dataType: context.dataType ?? null,\n disabled: props.readOnly,\n displayPreferencesIcon: props.displayPreferencesIcon,\n emptyResultsRenderer: context.emptyFilterResultsRenderer,\n existsLabel: context.filterPanelExistsLabel,\n filterFooterRenderer: context.filterFooterRenderer,\n filterGroupLabel: context.filterGroup?.label,\n filterGroupOptions: getFilterGroupOptions(colDef),\n filterHeaderRenderer: context.filterHeaderRenderer,\n filterOptionsRenderer: context.filterOptionsRenderer,\n filterOptionsSortDescription: context.filterOptionsSortDescription,\n filterOptionsSortTooltip: context.filterOptionsSortTooltip,\n focusText: props.focusText,\n focusedValues: props.focusedValues[field] ?? [],\n focusedValuesByField: getFocusedValuesByField(colDef),\n hasMore: filterHasMoreFor(field),\n isAggregate: isAggregateValueFilter(colDef),\n isFocusable:\n props.enableFocusView &&\n (!props.focusableFields.length ||\n getRepresentedFields(colDef).some((focusField) => props.focusableFields.includes(focusField))),\n isLoading: filterLoadingFor(field),\n isLoadingMore: filterLoadingMoreFor(field),\n isOpen: openSections.value[field] ?? false,\n key: field,\n knownOptions: knownOptionsFor(field),\n label: colDef.headerName || field,\n rangeMax: getFiniteNumber(context.filterPanelRange?.max),\n rangeMin: getFiniteNumber(context.filterPanelRange?.min),\n rangeStep: getFiniteNumber(context.filterPanelRange?.step),\n searchPlaceholder: context.filterPanelSearchPlaceholder,\n searchQuery: filterSearchQueryFor(field) ?? \"\",\n type,\n valueDecimals: context.valueDecimals ?? null,\n valueLabels: getValueLabels(colDef),\n } satisfies PvFilterPanelResolvedFilter;\n\n if (type === \"range\") {\n return {\n ...baseFilter,\n rangeValue: filterModelIndex.value.get(field)?.rangeValue ?? { max: null, min: null },\n };\n }\n\n if (type === \"boolean\") {\n return {\n ...baseFilter,\n booleanValue: filterModelIndex.value.get(field)?.booleanValue ?? null,\n };\n }\n\n if (type === \"exists\") {\n return {\n ...baseFilter,\n existsValue: filterModelIndex.value.get(field)?.existsValue ?? false,\n };\n }\n\n const baseOptions = knownOptionsFor(field);\n const selectedRawValuesByField = getSelectedRawValuesByField(colDef, baseOptions);\n const fallbackOptions = getSelectedFallbackOptions(field, colDef, selectedRawValuesByField, baseOptions);\n const knownOptions = [...baseOptions, ...fallbackOptions];\n const aggregateSelectionState = isAggregateValueFilter(colDef)\n ? seedFilterPanelAggregateSelectionState({\n colDef,\n model: activeFilterModel.value as AdvancedFilterModel | null,\n options: knownOptions,\n })\n : undefined;\n\n return {\n ...baseFilter,\n aggregateSelectionState,\n knownOptions,\n options: filterOptionsFor(field),\n selectedValues: aggregateSelectionState\n ? aggregateSelectionState.flatMap((node) => (node.state === \"selected\" ? [node.id] : []))\n : getSelectedValuesForFilter(field, selectedRawValuesByField, knownOptions),\n };\n });\n});\nconst visibleFilters = computed<PvFilterPanelResolvedFilter[]>(() => {\n if (selectedCategory.value === null) return resolvedFilters.value;\n return resolvedFilters.value.filter((filter) => filter.category === selectedCategory.value);\n});\nconst appliedGroups = computed<PvFilterPanelAppliedGroup[]>(() => {\n return resolvedFilters.value.flatMap((filter) => {\n const values = getAppliedValues(filter);\n if (!values.length) return [];\n return [\n {\n key: filter.key,\n label: filter.label,\n values,\n },\n ];\n });\n});\nconst appliedCount = computed(() => appliedGroups.value.reduce((sum, group) => sum + group.values.length, 0));\nconst filtersWithOpenState = computed<PvFilterPanelResolvedFilter[]>(() => {\n return visibleFilters.value.map((filter) => ({\n ...filter,\n isOpen: openSections.value[filter.key] ?? filter.isOpen ?? false,\n }));\n});\nconst hasActiveFilters = computed(() =>\n advancedFilterHasConditions(activeFilterModel.value, effectiveFilterModelType.value),\n);\nconst modeOptions = computed(() => [\n { label: \"Filters\", value: \"filters\" },\n { label: `Applied (${appliedCount.value})`, value: \"applied\" },\n]);\nconst panelStyle = computed<CSSProperties>(() => ({\n \"--flex-align\": \"stretch\",\n \"--flex-gap\": \"0\",\n flex: `0 0 ${props.width}`,\n minHeight: \"0\",\n width: props.width,\n}));\nconst showClearAll = computed(() => hasActiveFilters.value || appliedCount.value > 0);\n\nconst isSuggestionActive = (suggestion: PvFilterPanelSuggestion) => {\n const filter = findResolvedFilter(suggestion.field);\n if (!filter || filter.type !== suggestion.filter.type) return true;\n\n if (suggestion.filter.type === \"value\") {\n if (filter.isAggregate && suggestion.option) {\n const { selected } = getFilterPanelAggregateOptionSelectionStatus({\n option: suggestion.option,\n options: filter.knownOptions ?? [],\n state: filter.aggregateSelectionState ?? [],\n });\n return suggestion.filter.checked ? selected : !selected;\n }\n\n const selectedValueSet = new Set(filter.selectedValues ?? []);\n const optionValue = suggestion.option?.value ?? suggestion.filter.value;\n const rawValue = suggestion.option ? getFilterPanelOptionRawValue(suggestion.option) : suggestion.filter.value;\n const isSelected = selectedValueSet.has(optionValue) || (rawValue !== null && selectedValueSet.has(rawValue));\n return suggestion.filter.checked ? isSelected : !isSelected;\n }\n\n if (suggestion.filter.type === \"range\") {\n return (\n filter.rangeValue?.min === suggestion.filter.value.min && filter.rangeValue?.max === suggestion.filter.value.max\n );\n }\n\n if (suggestion.filter.type === \"boolean\") {\n return filter.booleanValue === suggestion.filter.value;\n }\n\n return (filter.existsValue ?? false) === suggestion.filter.value;\n};\n\nconst visibleSuggestions = computed(() =>\n props.filterSuggestions.filter((suggestion) => !isSuggestionActive(suggestion)),\n);\n\nconst getSuggestionKey = (suggestion: PvFilterPanelSuggestion) => {\n if (suggestion.key) return suggestion.key;\n\n const filterValue = \"value\" in suggestion.filter ? suggestion.filter.value : \"\";\n return `${suggestion.field}-${suggestion.filter.type}-${JSON.stringify(filterValue)}`;\n};\n\nconst updateStoreSelectedValues = (\n filterKey: string,\n field: string,\n nextValues: string[],\n selectedOption?: PvFilterPanelOption,\n) => {\n const store = effectiveFilterStore.value;\n if (!store) return;\n\n store.setFilterSelectedValues(field, nextValues, props.staged);\n\n const selectedMetadataMap = props.staged ? store.stagedFilterSelectedMetadataMap : store.filterSelectedMetadataMap;\n const selectedMetadata = selectedMetadataMap.value[filterKey] ?? [];\n const nextSelectedValueSet = new Set(nextValues);\n const nextMetadata = selectedMetadata.filter((option): option is PvFilterPanelOption => {\n if (!option) return false;\n const optionField = getFilterPanelOptionField(option, filterKey);\n const optionValue = getFilterPanelOptionRawValue(option) ?? option.value;\n return optionField !== field || nextSelectedValueSet.has(optionValue);\n });\n\n if (selectedOption) {\n const selectedOptionValue = getFilterPanelOptionRawValue(selectedOption) ?? selectedOption.value;\n const selectedOptionField = getFilterPanelOptionField(selectedOption, filterKey);\n const alreadyPresent = nextMetadata.some((option) => {\n const optionValue = getFilterPanelOptionRawValue(option) ?? option.value;\n return (\n getFilterPanelOptionField(option, filterKey) === selectedOptionField && optionValue === selectedOptionValue\n );\n });\n if (!alreadyPresent) nextMetadata.push(selectedOption);\n }\n\n selectedMetadataMap.value[filterKey] = nextMetadata;\n};\n\nconst updateStoreAggregateSelections = (\n filter: PvFilterPanelResolvedFilter,\n state = filter.aggregateSelectionState ?? [],\n) => {\n const store = effectiveFilterStore.value;\n if (!store || !filter.isAggregate) return;\n\n const selectedIds = state.flatMap((node) => (node.state === \"selected\" ? [node.id] : []));\n store.setFilterSelectedValues(filter.key, selectedIds, props.staged);\n\n const selectedMetadataMap = props.staged ? store.stagedFilterSelectedMetadataMap : store.filterSelectedMetadataMap;\n selectedMetadataMap.value[filter.key] = getFilterPanelAggregateSelectionOptions({\n options: filter.knownOptions ?? [],\n state,\n });\n};\n\nconst markStoreValueFiltersStale = (changedField?: string) => {\n if (!isStoreMode.value) return;\n\n const store = effectiveFilterStore.value;\n const changedFields = new Set<string>();\n\n if (changedField) {\n changedFields.add(changedField);\n const changedFilter = findResolvedFilter(changedField);\n if (changedFilter) {\n changedFields.add(changedFilter.key);\n getRepresentedFields(changedFilter.colDef).forEach((field) => changedFields.add(field));\n }\n }\n\n for (const filter of resolvedFilters.value) {\n if (filter.type !== \"value\") continue;\n\n const isChangedFilter = changedField\n ? changedFields.has(filter.key) || getRepresentedFields(filter.colDef).some((field) => changedFields.has(field))\n : false;\n\n if (!isChangedFilter) store.filterStaleMap.value[filter.key] = true;\n }\n};\n\nconst emitFilterChange = (\n nextFilterModel: PvFilterPanelFilterModel,\n reason: PvFilterPanelFilterChangeReason,\n field?: string,\n type?: PvFilterPanelFilterType,\n) => {\n warnIfModelShapeMismatchesType(nextFilterModel);\n\n const previousFilterModel = activeFilterModel.value;\n const store = effectiveFilterStore.value;\n if (store) {\n setActiveFilterModelInStore(store, nextFilterModel);\n if (nextFilterModel === null) {\n if (props.staged) {\n store.stagedFilterSelectedValueMap.value = {};\n store.stagedFilterSelectedMetadataMap.value = {};\n } else {\n store.filterSelectedValueMap.value = {};\n store.filterSelectedMetadataMap.value = {};\n }\n }\n } else if (props.staged) {\n stagedFilterModel.value = nextFilterModel;\n }\n\n if (!props.filterStore && !injectedFilterStore && !props.staged) filterModel.value = nextFilterModel;\n markStoreValueFiltersStale(field);\n const filter = field ? findResolvedFilter(field) : undefined;\n emit(\"filter-change\", {\n colDef: filter?.colDef,\n field,\n filterModel: nextFilterModel,\n previousFilterModel,\n reason,\n type,\n });\n};\n\nconst getAppliedBooleanValue = (filter: PvFilterPanelResolvedFilter): PvFilterPanelAppliedValue[] => {\n const value = filter.booleanValue ?? null;\n if (value === null) return [];\n\n return [\n {\n label: filter.valueLabels?.[String(value)] ?? (value ? \"Yes\" : \"No\"),\n type: \"boolean\",\n value: BOOLEAN_APPLIED_VALUE,\n },\n ];\n};\n\nconst getAppliedExistsValue = (filter: PvFilterPanelResolvedFilter): PvFilterPanelAppliedValue[] => {\n if (!filter.existsValue) return [];\n\n return [\n {\n label: filter.existsLabel ?? `Has ${filter.label}`,\n type: \"exists\",\n value: EXISTS_APPLIED_VALUE,\n },\n ];\n};\n\nconst getAppliedRangeValue = (filter: PvFilterPanelResolvedFilter): PvFilterPanelAppliedValue[] => {\n const rangeValue = filter.rangeValue ?? { max: null, min: null };\n if (rangeValue.min === null && rangeValue.max === null) return [];\n\n return [\n {\n label: formatFilterPanelRangeValue(rangeValue.min, rangeValue.max, {\n dataType: filter.dataType,\n valueDecimals: filter.valueDecimals,\n }),\n type: \"range\",\n value: RANGE_APPLIED_VALUE,\n },\n ];\n};\n\nconst getAppliedValueFilterValue = (\n filter: PvFilterPanelResolvedFilter,\n value: string,\n optionByValue: Map<string, PvFilterPanelOption>,\n): PvFilterPanelAppliedValue => {\n const option = optionByValue.get(value) ?? null;\n\n return {\n field: option ? getFilterPanelOptionField(option, filter.key) : undefined,\n label: option ? getFilterOptionLabel(option, filter.colDef) : value,\n resultCount: getFilterOptionResultCount(option),\n subText: option?.subText,\n subduedText: option?.subduedText,\n type: \"value\",\n value: option ? (getFilterPanelOptionRawValue(option) ?? option.value) : value,\n };\n};\n\nconst getAppliedFilterGroupValues = (filter: PvFilterPanelResolvedFilter): PvFilterPanelAppliedValue[] => {\n return (filter.filterGroupOptions ?? []).flatMap((groupOption) => {\n if (!groupOption.isActive) return [];\n return [\n {\n field: groupOption.field,\n label: groupOption.label,\n type: \"boolean\" as const,\n value: BOOLEAN_APPLIED_VALUE,\n },\n ];\n });\n};\n\nconst getAppliedAggregateValues = (filter: PvFilterPanelResolvedFilter): PvFilterPanelAppliedValue[] => {\n return getFilterPanelAggregateSelectionOptions({\n options: filter.knownOptions ?? [],\n state: filter.aggregateSelectionState ?? [],\n }).map((option) => ({\n field: filter.key,\n label: getFilterOptionLabel(option, filter.colDef),\n resultCount: getFilterOptionResultCount(option),\n subText: option.subText,\n subduedText: option.subduedText,\n type: \"value\" as const,\n value: option.value,\n }));\n};\n\nconst getAppliedValues = (filter: PvFilterPanelResolvedFilter): PvFilterPanelAppliedValue[] => {\n if (filter.type === \"range\") return getAppliedRangeValue(filter);\n if (filter.type === \"boolean\") return getAppliedBooleanValue(filter);\n if (filter.type === \"exists\") return getAppliedExistsValue(filter);\n if (filter.isAggregate) return [...getAppliedAggregateValues(filter), ...getAppliedFilterGroupValues(filter)];\n\n const optionByValue = new Map(\n flattenFilterPanelOptions(filter.knownOptions ?? []).map((option) => [option.value, option]),\n );\n return [\n ...(filter.selectedValues ?? []).map((value) => getAppliedValueFilterValue(filter, value, optionByValue)),\n ...getAppliedFilterGroupValues(filter),\n ];\n};\n\nconst cancelClearAllFilters = () => {\n showClearAllConfirm.value = false;\n};\n\nconst clearAllFilters = () => {\n cancelPendingRangeChanges();\n emitFilterChange(null, \"clear-all\");\n};\n\nconst confirmClearAllFilters = () => {\n clearAllFilters();\n showClearAllConfirm.value = false;\n};\n\nconst applyStagedFilters = () => {\n flushPendingRangeChanges();\n const store = effectiveFilterStore.value;\n const nextFilterModel = store ? store.stagedFilterModel.value : stagedFilterModel.value;\n if (store) {\n applyCommittedFilterModelToStore(store, nextFilterModel);\n store.commitStagedFilterSelections();\n store.initStagedFilterSelections();\n }\n if (!props.filterStore && !injectedFilterStore) filterModel.value = nextFilterModel;\n emit(\"apply\", nextFilterModel);\n};\n\nconst cancelStagedFilters = () => {\n cancelPendingRangeChanges();\n const store = effectiveFilterStore.value;\n if (store) {\n store.stagedFilterModel.value = store.filterModel.value;\n store.initStagedFilterSelections();\n }\n stagedFilterModel.value = filterModel.value;\n emit(\"cancel\");\n};\n\nconst getExistsAdvancedFilterType = (field: string) => {\n return getAdvancedFilterTypeForDataType(findResolvedFilter(field)?.dataType);\n};\n\nconst handleAggregateSelectionChange = (\n filterKey: string,\n state: NonNullable<PvFilterPanelResolvedFilter[\"aggregateSelectionState\"]>,\n reason: PvFilterPanelFilterChangeReason = \"value-toggle\",\n) => {\n const filter = findResolvedFilter(filterKey);\n if (!filter?.isAggregate) return;\n\n updateStoreAggregateSelections(filter, state);\n emitFilterChange(\n buildFilterPanelAggregateModelFromSelectionState({\n baseModel: activeFilterModel.value as AdvancedFilterModel | null,\n colDef: filter.colDef,\n options: filter.knownOptions ?? [],\n state,\n }),\n reason,\n filter.key,\n \"value\",\n );\n};\n\nconst handleAccordionFilterChange = (field: string, change: PvFilterPanelControlChange) => {\n if (change.type === \"aggregate-selection\") {\n handleAggregateSelectionChange(field, change.value);\n return;\n }\n\n const targetField = change.field ?? field;\n const targetColDef = findColDef(targetField) ?? findResolvedFilter(field)?.colDef;\n\n if (change.type === \"value\") {\n const filter = findResolvedFilter(field);\n const option = findKnownOptionForValue(field, targetField, change.value);\n if (filter?.isAggregate && option) {\n handleAggregateSelectionChange(\n field,\n updateFilterPanelAggregateSelectionState({\n checked: change.checked,\n option,\n options: filter.knownOptions ?? [],\n state: filter.aggregateSelectionState ?? [],\n }),\n );\n return;\n }\n\n handleToggleValue(field, targetField, change.value, change.checked, option);\n return;\n }\n\n if (change.type === \"range\") {\n handleRangeChange(targetField, change.value, targetColDef);\n return;\n }\n\n if (change.type === \"boolean\") {\n emitFilterChange(\n updateBooleanFilter(\n activeFilterModel.value as AdvancedFilterModel | null,\n targetField,\n change.value,\n effectiveFilterModelType.value,\n change.field ? \"text\" : \"boolean\",\n targetColDef,\n ),\n \"boolean-change\",\n targetField,\n \"boolean\",\n );\n return;\n }\n\n emitFilterChange(\n updateExistsFilter(\n activeFilterModel.value as AdvancedFilterModel | null,\n targetField,\n change.value,\n getExistsAdvancedFilterType(targetField),\n effectiveFilterModelType.value,\n targetColDef,\n ),\n \"exists-change\",\n targetField,\n \"exists\",\n );\n};\n\nconst shouldFetchStoreOptions = (\n filter: PvFilterPanelResolvedFilter,\n query: string,\n reason: \"open\" | \"search\" | \"load-more\" | \"child-load-more\",\n parentId?: string,\n) => {\n const store = effectiveFilterStore.value;\n if (!store || filter.type !== \"value\") return false;\n if (reason !== \"open\") return true;\n if (parentId) return true;\n if (store.filterLoadingMap.value[filter.key]) return false;\n if (store.filterStaleMap.value[filter.key]) return true;\n\n const loadedOptions = store.filterOptionsMap.value[filter.key] ?? [];\n if (!loadedOptions.length) return true;\n return (store.filterSearchQueries.value[filter.key] ?? \"\") !== query;\n};\n\nconst fetchStoreOptions = (\n filter: PvFilterPanelResolvedFilter,\n query: string,\n reason: \"open\" | \"search\" | \"load-more\" | \"child-load-more\",\n parentId?: string,\n) => {\n const store = effectiveFilterStore.value;\n if (!shouldFetchStoreOptions(filter, query, reason, parentId) || !store) return;\n const selectedValues = Array.from(\n new Set([...getSelectedRawValuesByField(filter.colDef, filter.knownOptions ?? []).values()].flat()),\n );\n void store.fetchFilterOptions({\n colDef: filter.colDef,\n field: filter.key,\n filterModel: activeFilterModel.value,\n parentId,\n query,\n reason,\n selectedValues,\n });\n};\n\nconst handleLoadMore = (filter: PvFilterPanelResolvedFilter, query: string, parentId?: string) => {\n emit(\"load-more\", filter.key, filter.colDef, query, parentId);\n fetchStoreOptions(filter, query, parentId ? \"child-load-more\" : \"load-more\", parentId);\n};\n\nconst handleModeChange = (value: string) => {\n if (value === \"filters\" || value === \"applied\") {\n mode.value = value;\n }\n};\n\nconst applyRangeChange = (field: string, value: PvRangeValue, colDef?: PvFilterPanelColDef) => {\n emitFilterChange(\n updateRangeFilter(\n activeFilterModel.value as AdvancedFilterModel | null,\n field,\n value.min,\n value.max,\n effectiveFilterModelType.value,\n colDef,\n ),\n \"range-change\",\n field,\n \"range\",\n );\n};\n\nconst cancelPendingRangeChanges = () => {\n for (const { timer } of pendingRangeChanges.values()) {\n window.clearTimeout(timer);\n }\n pendingRangeChanges.clear();\n};\n\nconst flushPendingRangeChanges = () => {\n const changes = [...pendingRangeChanges.entries()];\n cancelPendingRangeChanges();\n for (const [field, change] of changes) {\n applyRangeChange(field, change.value, change.colDef);\n }\n};\n\nconst handleRangeChange = (field: string, value: PvRangeValue, colDef?: PvFilterPanelColDef) => {\n if (props.rangeDebounceMs <= 0) {\n applyRangeChange(field, value, colDef);\n return;\n }\n\n const existingChange = pendingRangeChanges.get(field);\n if (existingChange) window.clearTimeout(existingChange.timer);\n\n const timer = window.setTimeout(() => {\n pendingRangeChanges.delete(field);\n applyRangeChange(field, value, colDef);\n }, props.rangeDebounceMs);\n pendingRangeChanges.set(field, { colDef, timer, value });\n};\n\nonBeforeUnmount(cancelPendingRangeChanges);\n\nconst handleSearchChange = (filter: PvFilterPanelResolvedFilter, query: string) => {\n emit(\"search-change\", filter.key, query, filter.colDef);\n fetchStoreOptions(filter, query, \"search\");\n};\n\nconst handleSectionOpenChange = (filter: PvFilterPanelResolvedFilter, open: boolean) => {\n openSections.value[filter.key] = open;\n emit(\"open-change\", filter.key, open, filter.colDef);\n if (open) fetchStoreOptions(filter, filter.searchQuery ?? \"\", \"open\");\n};\n\nconst handleToggleValue = (\n filterKey: string,\n field: string,\n value: string,\n checked: boolean,\n option?: PvFilterPanelOption,\n) => {\n const currentValues = filterModelIndex.value.get(field)?.values ?? [];\n const nextValues = checked\n ? Array.from(new Set([...currentValues, value]))\n : currentValues.filter((selectedValue) => selectedValue !== value);\n\n updateStoreSelectedValues(filterKey, field, nextValues, checked ? option : undefined);\n emitFilterChange(\n updateValueFilter(\n activeFilterModel.value as AdvancedFilterModel | null,\n field,\n nextValues,\n effectiveFilterModelType.value,\n findColDef(field) ?? findResolvedFilter(filterKey)?.colDef,\n ),\n \"value-toggle\",\n field,\n \"value\",\n );\n};\n\nconst handleSuggestionClick = (suggestion: PvFilterPanelSuggestion) => {\n if (suggestion.filter.type === \"value\" && suggestion.option) {\n const filter = findResolvedFilter(suggestion.field);\n const field = getFilterPanelOptionField(suggestion.option, suggestion.field);\n const value = getFilterPanelOptionRawValue(suggestion.option) ?? suggestion.filter.value;\n\n if (filter?.isAggregate) {\n handleAggregateSelectionChange(\n suggestion.field,\n updateFilterPanelAggregateSelectionState({\n checked: suggestion.filter.checked,\n option: suggestion.option,\n options: filter.knownOptions ?? [],\n state: filter.aggregateSelectionState ?? [],\n }),\n );\n } else {\n handleToggleValue(suggestion.field, field, value, suggestion.filter.checked, suggestion.option);\n }\n } else {\n handleAccordionFilterChange(suggestion.field, suggestion.filter);\n }\n emit(\"suggestion-click\", suggestion);\n};\n\nconst removeAppliedFilter = (field: string, value: string, type?: PvFilterPanelFilterType) => {\n const filterType = type ?? findResolvedFilter(field)?.type ?? \"value\";\n\n if (filterType === \"range\" || (!type && value === RANGE_APPLIED_VALUE)) {\n emitFilterChange(\n updateRangeFilter(\n activeFilterModel.value as AdvancedFilterModel | null,\n field,\n null,\n null,\n effectiveFilterModelType.value,\n findColDef(field) ?? findResolvedFilter(field)?.colDef,\n ),\n \"remove-filter\",\n field,\n \"range\",\n );\n return;\n }\n\n if (filterType === \"boolean\" || (!type && value === BOOLEAN_APPLIED_VALUE)) {\n emitFilterChange(\n updateBooleanFilter(\n activeFilterModel.value as AdvancedFilterModel | null,\n field,\n null,\n effectiveFilterModelType.value,\n \"boolean\",\n findColDef(field) ?? findResolvedFilter(field)?.colDef,\n ),\n \"remove-filter\",\n field,\n \"boolean\",\n );\n return;\n }\n\n if (filterType === \"exists\" || (!type && value === EXISTS_APPLIED_VALUE)) {\n emitFilterChange(\n updateExistsFilter(\n activeFilterModel.value as AdvancedFilterModel | null,\n field,\n false,\n \"text\",\n effectiveFilterModelType.value,\n findColDef(field) ?? findResolvedFilter(field)?.colDef,\n ),\n \"remove-filter\",\n field,\n \"exists\",\n );\n return;\n }\n\n const filter = findResolvedFilter(field);\n if (filterType === \"value\" && filter?.isAggregate) {\n const option = findFilterPanelOptionByValue(filter.knownOptions ?? [], value);\n const currentState = filter.aggregateSelectionState ?? [];\n const nextState = option\n ? updateFilterPanelAggregateSelectionState({\n checked: false,\n option,\n options: filter.knownOptions ?? [],\n state: currentState,\n })\n : currentState.filter((node) => node.id !== value);\n handleAggregateSelectionChange(filter.key, nextState, \"remove-filter\");\n return;\n }\n\n const currentValues = filterModelIndex.value.get(field)?.values ?? [];\n const nextValues = currentValues.filter((selectedValue) => selectedValue !== value);\n updateStoreSelectedValues(findResolvedFilter(field)?.key ?? field, field, nextValues);\n emitFilterChange(\n updateValueFilter(\n activeFilterModel.value as AdvancedFilterModel | null,\n field,\n nextValues,\n effectiveFilterModelType.value,\n findColDef(field) ?? findResolvedFilter(field)?.colDef,\n ),\n \"remove-filter\",\n field,\n \"value\",\n );\n};\n\nconst requestClearAllFilters = () => {\n showClearAllConfirm.value = true;\n};\n</script>\n\n<template>\n <aside\n v-if=\"!isCollapsed\"\n class=\"pv-flex-vertical pv-surface pv-border-right\"\n data-testid=\"pv-filter-panel\"\n :aria-label=\"ariaLabel\"\n :style=\"panelStyle\"\n >\n <div class=\"pv-filter-panel-header pv-flex pv-border-bottom\">\n <PvSegmentedControl\n :modelValue=\"mode\"\n :options=\"modeOptions\"\n class=\"pv-filter-panel-mode-control\"\n size=\"xl\"\n @update:modelValue=\"handleModeChange\"\n />\n <PvButton\n ariaLabel=\"Collapse filters\"\n leftIcon=\"chevrons-left\"\n size=\"xl\"\n variant=\"secondary\"\n @click=\"isCollapsed = true\"\n />\n </div>\n\n <div class=\"pv-filter-panel-body pv-flex-vertical\">\n <div\n v-show=\"mode === 'filters'\"\n class=\"pv-filter-panel-filters-view pv-flex-vertical\"\n data-testid=\"pv-filter-panel-filters-view\"\n >\n <section\n v-if=\"!readOnly && visibleSuggestions.length\"\n aria-label=\"Filter suggestions\"\n class=\"pv-filter-panel-suggestions pv-flex-vertical pv-border-bottom\"\n data-testid=\"pv-filter-panel-suggestions\"\n >\n <p class=\"pv-filter-panel-section-title pv-text-title-sm pv-text-subdued\">Suggestions</p>\n <div class=\"pv-filter-panel-suggestion-tags pv-flex\">\n <PvSuggestionTag\n v-for=\"suggestion in visibleSuggestions\"\n :key=\"getSuggestionKey(suggestion)\"\n :icon=\"suggestion.icon\"\n :icon-classes=\"suggestion.iconClasses\"\n :label=\"suggestion.label\"\n @handle-click=\"() => handleSuggestionClick(suggestion)\"\n />\n </div>\n </section>\n <slot name=\"suggestions\" />\n <PvFilterPanelCategoryButtonRow\n v-model=\"selectedCategory\"\n :category-order=\"categoryOrder\"\n :filters=\"resolvedFilters\"\n />\n <div v-if=\"!resolvedFilters.length\" class=\"pv-filter-panel-empty pv-text-body-sm pv-text-subdued\">\n No filters available.\n </div>\n <div v-else-if=\"!visibleFilters.length\" class=\"pv-filter-panel-empty pv-text-body-sm pv-text-subdued\">\n No filters in this category.\n </div>\n <div v-else class=\"pv-filter-panel-filter-list pv-flex-vertical\">\n <PvFilterPanelAccordion\n v-for=\"filter in filtersWithOpenState\"\n :key=\"filter.key\"\n :filter=\"filter\"\n @filter-change=\"(change) => handleAccordionFilterChange(filter.key, change)\"\n @focus-change=\"(field, value, option) => emit('focus-change', field, value, option)\"\n @handle-settings-icon=\"(field, colDef) => emit('handle-settings-icon', field, colDef)\"\n @load-more=\"(query, parentId) => handleLoadMore(filter, query, parentId)\"\n @open-change=\"(open) => handleSectionOpenChange(filter, open)\"\n @search-change=\"(query) => handleSearchChange(filter, query)\"\n />\n </div>\n </div>\n\n <PvFilterPanelAppliedFiltersSection\n v-show=\"mode === 'applied'\"\n :applied-count=\"appliedCount\"\n :applied-groups=\"appliedGroups\"\n :read-only=\"readOnly\"\n @remove-filter=\"removeAppliedFilter\"\n />\n </div>\n\n <div v-if=\"(showClearAll || staged) && !readOnly\" class=\"pv-filter-panel-footer pv-flex pv-border-top\">\n <PvButton\n v-if=\"showClearAll\"\n class=\"pv-text-brand\"\n :label=\"clearAllLabel\"\n variant=\"ghost\"\n @click=\"requestClearAllFilters\"\n />\n <div v-if=\"staged\" class=\"pv-filter-panel-actions pv-flex\">\n <PvButton :label=\"cancelLabel\" variant=\"ghost\" @click=\"cancelStagedFilters\" />\n <PvButton :label=\"applyLabel\" variant=\"primary\" @click=\"applyStagedFilters\" />\n </div>\n </div>\n </aside>\n\n <PvModal v-model=\"showClearAllConfirm\" :header=\"clearAllHeader\" :style=\"{ '--max-width': '440px' }\">\n <template #body>\n <p class=\"pv-text-body-sm\">\n {{ clearAllBody }}\n </p>\n </template>\n <template #footer>\n <div class=\"pv-filter-panel-modal-footer pv-flex\">\n <PvButton :label=\"cancelLabel\" variant=\"ghost\" @click=\"cancelClearAllFilters\" />\n <PvButton :label=\"clearAllLabel\" variant=\"primary\" @click=\"confirmClearAllFilters\" />\n </div>\n </template>\n </PvModal>\n</template>\n\n<style scoped>\n.pv-filter-panel-actions,\n.pv-filter-panel-header,\n.pv-filter-panel-suggestion-tags {\n --flex-gap: 0.5rem;\n}\n\n.pv-filter-panel-body,\n.pv-filter-panel-filters-view {\n --flex-align: stretch;\n --flex-gap: 0;\n}\n\n.pv-filter-panel-body {\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n}\n\n.pv-filter-panel-empty,\n.pv-filter-panel-footer,\n.pv-filter-panel-suggestions {\n padding: 12px;\n}\n\n.pv-filter-panel-filter-list {\n --flex-align: stretch;\n --flex-gap: 8px;\n padding-top: 8px;\n}\n\n.pv-filter-panel-footer {\n --flex-justify: space-between;\n margin-top: auto;\n}\n\n.pv-filter-panel-header {\n --flex-align: center;\n padding: 0 12px 12px;\n}\n\n.pv-filter-panel-mode-control {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.pv-filter-panel-modal-footer {\n --flex-justify: flex-end;\n}\n\n.pv-filter-panel-section-title {\n margin: 0;\n}\n\n.pv-filter-panel-suggestions {\n --flex-align: stretch;\n}\n\n.pv-filter-panel-suggestion-tags {\n --flex-wrap: wrap;\n}\n</style>\n","import { MenuOption } from \"@/types\";\n\n// The query builder can be used in two modes:\n// 1. Full - the query is parsed and populates both the filter model and free text terms.\n// 2. Field-only - the query is parsed to extract only the filter model, treating free-text terms as invalid\nexport type QueryBuilderProcessor = \"full\" | \"field-only\";\n\nexport interface QueryBuilderOutput {\n queryTerms: QueryTerm[];\n freeTextTerms?: string[];\n}\n\nexport interface QueryTerm {\n queryField?: string;\n queryDisplayField?: string;\n exactMatch?: boolean;\n queryText?: string;\n}\n\nexport interface QueryBuilderSuggestionMenuOption extends MenuOption {\n queryTerm?: QueryTerm;\n}\n\n/**\n * The filter model is structured as follows:\n * For single conditions\n * {\n * [field]: {\n * filterType: \"text\",\n * type: \"equals\" | \"contains\",\n * filter: string,\n * },\n * }\n * For multiple conditions on the same field, it will be structured as:\n * {\n * [field]: {\n * filterType: \"text\",\n * operator: 'OR',\n * conditions: [\n * {\n * type: \"equals\" | \"contains\",\n * filter: string,\n * }\n * ]\n * },\n * }\n */\n\nexport const useQueryBuilder = () => {\n const addQueryOption = (\n query: QueryBuilderOutput | null,\n option: QueryBuilderSuggestionMenuOption,\n ): QueryBuilderOutput | null => {\n const updatedQuery = query || { queryTerms: [] };\n const newQueryTerm = option.queryTerm || {};\n if (isValidQueryTerm(option) && !containsQueryOption(query, option)) {\n updatedQuery.queryTerms.push(newQueryTerm);\n }\n return updatedQuery;\n };\n const isValidQueryTerm = (option: QueryBuilderSuggestionMenuOption): boolean => {\n // don't allow blank query terms\n if (!option.queryTerm) return false;\n return option.queryTerm.queryText !== undefined && option.queryTerm.queryText.trim() !== \"\";\n };\n const queryTermEquals = (a: QueryTerm, b: QueryTerm): boolean => {\n return (\n a.queryField === b.queryField &&\n a.exactMatch === b.exactMatch &&\n a.queryText === b.queryText &&\n a.queryDisplayField === b.queryDisplayField\n );\n };\n const containsQueryOption = (query: QueryBuilderOutput | null, option: QueryBuilderSuggestionMenuOption): boolean => {\n return !!query && query.queryTerms.some((term) => queryTermEquals(term, option.queryTerm || {}));\n };\n const removeQueryOption = (\n query: QueryBuilderOutput | null,\n option: QueryBuilderSuggestionMenuOption,\n ): QueryBuilderOutput | null => {\n // find and remove the option from the query\n if (!query) return null;\n const index = query.queryTerms.findIndex((term) => queryTermEquals(term, option.queryTerm || {}));\n if (index !== -1) {\n query.queryTerms.splice(index, 1);\n }\n return query;\n };\n return {\n addQueryOption,\n containsQueryOption,\n removeQueryOption,\n };\n};\n","<script setup lang=\"ts\">\nimport { QueryTerm } from \"@/components/base/PvQueryBuilderInput/useQueryBuilder\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport { computed, onMounted, ref } from \"vue\";\nimport { MenuOption } from \"@/types\";\n\nconst props = defineProps<MenuOption<QueryTerm>>();\nconst queryBuilderProps = computed(() => {\n return props.context;\n});\n\nconst queryOptionText = ref<HTMLElement | null>(null);\n\nconst exactMatch = computed(() => {\n return queryBuilderProps.value?.exactMatch || false;\n});\nconst displayText = computed(() => {\n return props.text;\n});\n\nconst currentSearchText = computed(() => {\n return props.searchText || \"\";\n});\n\nconst searchField = computed(() => {\n return queryBuilderProps.value?.queryDisplayField;\n});\nconst primaryIcon = computed(() => {\n const optionIcon = props.icon || \"search\";\n return exactMatch.value ? optionIcon : \"search\";\n});\n\nonMounted(() => {\n if (queryOptionText.value && currentSearchText.value) {\n const regex = new RegExp(`(${currentSearchText.value})`, \"gi\");\n queryOptionText.value.innerHTML = displayText.value.replace(regex, '<span style=\"font-weight: bold;\">$1</span>');\n }\n});\n</script>\n\n<template>\n <div>\n <div class=\"pv-flex\">\n <PvIcon :name=\"primaryIcon\"></PvIcon>\n <div>\n <p ref=\"queryOptionText\" class=\"pv-text-body-md\">{{ displayText }}</p>\n <p v-if=\"searchField\" class=\"pv-text-body-xs\">\n <span v-if=\"!exactMatch\">Search in </span>\n <span class=\"pv-text-subdued pv-text-body-xs\" style=\"font-weight: 500\">{{ searchField }}</span>\n </p>\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.pv-text-tertiary {\n color: #6e8081;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { QueryTerm } from \"@/components/base/PvQueryBuilderInput/useQueryBuilder\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport { computed, onMounted, ref } from \"vue\";\nimport { MenuOption } from \"@/types\";\n\nconst props = defineProps<MenuOption<QueryTerm>>();\nconst queryBuilderProps = computed(() => {\n return props.context;\n});\n\nconst queryOptionText = ref<HTMLElement | null>(null);\n\nconst exactMatch = computed(() => {\n return queryBuilderProps.value?.exactMatch || false;\n});\nconst displayText = computed(() => {\n return props.text;\n});\n\nconst currentSearchText = computed(() => {\n return props.searchText || \"\";\n});\n\nconst searchField = computed(() => {\n return queryBuilderProps.value?.queryDisplayField;\n});\nconst primaryIcon = computed(() => {\n const optionIcon = props.icon || \"search\";\n return exactMatch.value ? optionIcon : \"search\";\n});\n\nonMounted(() => {\n if (queryOptionText.value && currentSearchText.value) {\n const regex = new RegExp(`(${currentSearchText.value})`, \"gi\");\n queryOptionText.value.innerHTML = displayText.value.replace(regex, '<span style=\"font-weight: bold;\">$1</span>');\n }\n});\n</script>\n\n<template>\n <div>\n <div class=\"pv-flex\">\n <PvIcon :name=\"primaryIcon\"></PvIcon>\n <div>\n <p ref=\"queryOptionText\" class=\"pv-text-body-md\">{{ displayText }}</p>\n <p v-if=\"searchField\" class=\"pv-text-body-xs\">\n <span v-if=\"!exactMatch\">Search in </span>\n <span class=\"pv-text-subdued pv-text-body-xs\" style=\"font-weight: 500\">{{ searchField }}</span>\n </p>\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.pv-text-tertiary {\n color: #6e8081;\n}\n</style>\n","<script setup lang=\"ts\">\nimport {\n QueryBuilderOutput,\n QueryBuilderSuggestionMenuOption,\n QueryTerm,\n useQueryBuilder,\n} from \"@/components/base/PvQueryBuilderInput/useQueryBuilder\";\nimport PvTag from \"@/components/base/PvTag/PvTag.vue\";\nimport { computed } from \"vue\";\nimport { TagVariant } from \"@/components/base/PvTag/types\";\n\ninterface QueryFormatterProps {\n queryTermDisplayLimit?: number;\n}\n\nconst props = withDefaults(defineProps<QueryFormatterProps>(), {\n queryTermDisplayLimit: 3,\n});\n\nconst parsedQuery = defineModel<QueryBuilderOutput | null>({ required: true });\nconst wrapContent = defineModel<boolean>(\"wrap-content\", { required: false, default: false });\nconst { removeQueryOption } = useQueryBuilder();\n\nconst displayedQueryTerms = computed(() => {\n // extract filter terms from parsedQuery\n // if enableItemWrap is true, show all terms\n const terms = parsedQuery.value?.queryTerms || [];\n return wrapContent.value ? terms : terms.slice(0, props.queryTermDisplayLimit);\n});\n\nconst overflowQueryTermCount = computed(() => {\n const availableQueryTermCount = parsedQuery.value?.queryTerms.length || 0;\n const currentDisplayCount = displayedQueryTerms.value.length;\n return availableQueryTermCount - currentDisplayCount;\n});\n\nconst tagLabelForQueryTerm = (term: QueryTerm) => {\n // if exact match, don't show field\n if (term.queryField && !term.exactMatch) {\n const displayField = term.queryDisplayField || term.queryField;\n return `${displayField}: '${term.queryText}'`;\n }\n return term.queryText || \"\";\n};\n\nconst tagVariantForQueryTerm = (term: QueryTerm): TagVariant => {\n // return variant based on term type\n return term.exactMatch ? \"primary\" : \"tertiary\";\n};\n\nconst handleTagClick = (term: QueryTerm) => {\n const queryOption: QueryBuilderSuggestionMenuOption = {\n id: \"id\",\n text: term.queryText || \"\",\n queryTerm: {\n queryText: term.queryText,\n queryDisplayField: term.queryDisplayField,\n queryField: term.queryField || \"\",\n exactMatch: term.exactMatch,\n },\n };\n removeQueryOption(parsedQuery.value, queryOption);\n};\n</script>\n\n<template>\n <PvTag\n v-for=\"(queryTerm, index) in displayedQueryTerms\"\n :key=\"`${index}-${queryTerm.queryText}`\"\n :variant=\"tagVariantForQueryTerm(queryTerm)\"\n :label=\"tagLabelForQueryTerm(queryTerm)\"\n :show-clear=\"true\"\n @handle-close=\"handleTagClick(queryTerm)\"\n />\n <PvTag v-if=\"overflowQueryTermCount > 0\" :label=\"`+${overflowQueryTermCount}`\" @handle-click=\"wrapContent = true\" />\n</template>\n\n<style scoped></style>\n","<script setup lang=\"ts\">\nimport {\n QueryBuilderOutput,\n QueryBuilderSuggestionMenuOption,\n QueryTerm,\n useQueryBuilder,\n} from \"@/components/base/PvQueryBuilderInput/useQueryBuilder\";\nimport PvTag from \"@/components/base/PvTag/PvTag.vue\";\nimport { computed } from \"vue\";\nimport { TagVariant } from \"@/components/base/PvTag/types\";\n\ninterface QueryFormatterProps {\n queryTermDisplayLimit?: number;\n}\n\nconst props = withDefaults(defineProps<QueryFormatterProps>(), {\n queryTermDisplayLimit: 3,\n});\n\nconst parsedQuery = defineModel<QueryBuilderOutput | null>({ required: true });\nconst wrapContent = defineModel<boolean>(\"wrap-content\", { required: false, default: false });\nconst { removeQueryOption } = useQueryBuilder();\n\nconst displayedQueryTerms = computed(() => {\n // extract filter terms from parsedQuery\n // if enableItemWrap is true, show all terms\n const terms = parsedQuery.value?.queryTerms || [];\n return wrapContent.value ? terms : terms.slice(0, props.queryTermDisplayLimit);\n});\n\nconst overflowQueryTermCount = computed(() => {\n const availableQueryTermCount = parsedQuery.value?.queryTerms.length || 0;\n const currentDisplayCount = displayedQueryTerms.value.length;\n return availableQueryTermCount - currentDisplayCount;\n});\n\nconst tagLabelForQueryTerm = (term: QueryTerm) => {\n // if exact match, don't show field\n if (term.queryField && !term.exactMatch) {\n const displayField = term.queryDisplayField || term.queryField;\n return `${displayField}: '${term.queryText}'`;\n }\n return term.queryText || \"\";\n};\n\nconst tagVariantForQueryTerm = (term: QueryTerm): TagVariant => {\n // return variant based on term type\n return term.exactMatch ? \"primary\" : \"tertiary\";\n};\n\nconst handleTagClick = (term: QueryTerm) => {\n const queryOption: QueryBuilderSuggestionMenuOption = {\n id: \"id\",\n text: term.queryText || \"\",\n queryTerm: {\n queryText: term.queryText,\n queryDisplayField: term.queryDisplayField,\n queryField: term.queryField || \"\",\n exactMatch: term.exactMatch,\n },\n };\n removeQueryOption(parsedQuery.value, queryOption);\n};\n</script>\n\n<template>\n <PvTag\n v-for=\"(queryTerm, index) in displayedQueryTerms\"\n :key=\"`${index}-${queryTerm.queryText}`\"\n :variant=\"tagVariantForQueryTerm(queryTerm)\"\n :label=\"tagLabelForQueryTerm(queryTerm)\"\n :show-clear=\"true\"\n @handle-close=\"handleTagClick(queryTerm)\"\n />\n <PvTag v-if=\"overflowQueryTermCount > 0\" :label=\"`+${overflowQueryTermCount}`\" @handle-click=\"wrapContent = true\" />\n</template>\n\n<style scoped></style>\n","<script setup lang=\"ts\">\nimport { computed, ComputedRef, ref, useTemplateRef, watch } from \"vue\";\nimport {\n QueryBuilderOutput,\n QueryBuilderProcessor,\n QueryBuilderSuggestionMenuOption,\n QueryTerm,\n useQueryBuilder,\n} from \"@/components/base/PvQueryBuilderInput/useQueryBuilder\";\nimport PvPopover from \"@/components/base/PvPopover/PvPopover.vue\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport PvMenuItem from \"@/components/base/PvMenu/items/PvMenuItem.vue\";\nimport { vOnClickOutside } from \"@vueuse/components\";\nimport QueryBuilderMenuOptionRenderer from \"@/components/base/PvQueryBuilderInput/QueryBuilderMenuOptionRenderer.vue\";\nimport QueryFormatter from \"@/components/base/PvQueryBuilderInput/QueryFormatter.vue\";\nimport type { MenuOption } from \"@/types\";\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport PvSpinner from \"@/components/base/PvSpinner/PvSpinner.vue\";\nimport { onKeyStroke } from \"@vueuse/core\";\n\nexport interface PvQueryBuilderInputProps {\n /**\n * Placeholder text shown in the input when no query is active.\n */\n placeholder?: string;\n /**\n * When true, the input is non-interactive and visually dimmed.\n */\n disabled?: boolean;\n /** When true, displays a keyboard shortcut badge next to the input. */\n displayShortcut?: boolean;\n /**\n * Determines how user input is parsed into structured query terms.\n * - `'full'`: free-text and field-based queries.\n * - `'field-only'`: only options with a queryField are shown.\n */\n processor?: QueryBuilderProcessor;\n /**\n * When true, shows a loading spinner in the suggestion dropdown.\n */\n optionsLoading?: boolean;\n /**\n * When true, users can press Enter to add free-text terms without selecting a suggestion.\n */\n enableCustomOptionsInput?: boolean;\n /**\n * When true, hides the search icon on the left side of the input.\n */\n hideSearchIcon?: boolean;\n /**\n * When true, hides the clear button that resets the query.\n */\n hideClearButton?: boolean;\n /**\n * Maximum number of query term pills to display before collapsing.\n */\n queryTermDisplayLimit?: number;\n /**\n * When true, query term pills wrap to the next line instead of scrolling horizontally.\n */\n enableWrapQueryTerms?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvQueryBuilderInputProps>(), {\n placeholder: \"Search\",\n disabled: false,\n processor: \"full\",\n optionsLoading: false,\n enableCustomOptionsInput: false,\n hideSearchIcon: false,\n hideClearButton: false,\n queryTermDisplayLimit: 3,\n enableWrapQueryTerms: false,\n});\n\nconst menuOptionConfig = {\n renderer: QueryBuilderMenuOptionRenderer,\n};\n\n// const wrapper = useTemplateRef<HTMLDivElement | null>(\"query-builder-input\");\nconst input = useTemplateRef<HTMLInputElement | null>(\"search-input\");\nconst inputText = defineModel<string>(\"searchText\", { required: false, default: \"\" });\nconst parsedQuery = defineModel<QueryBuilderOutput | null>(\"query\", { required: true });\nconst queryOptions = defineModel<QueryBuilderSuggestionMenuOption[]>(\"options\", {\n required: false,\n});\nconst { addQueryOption, containsQueryOption } = useQueryBuilder();\nconst displayOptions = ref(false);\nconst isCurrentInputFocused = ref(false);\nconst wrapContent = ref(false);\n\nconst computedPlaceholder = computed(() => {\n return parsedQuery.value !== null ? \"\" : props.placeholder;\n});\n\nconst invalidQueryReason = ref<string | null>(null);\nconst displayInvalidQuery = computed(() => {\n return invalidQueryReason.value !== null && invalidQueryReason.value !== \"\" && !isCurrentInputFocused.value;\n});\n\nconst clearQuery = () => {\n parsedQuery.value = null;\n inputText.value = \"\";\n invalidQueryReason.value = null;\n wrapContent.value = false;\n};\n\nif (props.enableCustomOptionsInput) {\n onKeyStroke(\n \"Enter\",\n () => {\n if (inputText.value.trim()) {\n handleAddSelfAddedOption();\n }\n },\n { target: input },\n );\n}\n\nconst handleAddSelfAddedOption = () => {\n if (inputText.value.trim()) {\n parsedQuery.value = addQueryOption(parsedQuery.value, {\n id: inputText.value.trim(),\n text: inputText.value,\n queryTerm: {\n queryText: inputText.value,\n },\n });\n clearInputText();\n }\n};\n\nconst availableOptions: ComputedRef<MenuOption<QueryTerm>[]> = computed(() => {\n if (!queryOptions.value || queryOptions.value.length === 0) {\n return [];\n }\n let filteredOptions = queryOptions.value;\n // if the processor is field-only, filter out options without a queryField\n if (props.processor === \"field-only\") {\n filteredOptions = queryOptions.value.filter((option) => option.queryTerm?.queryField);\n }\n // filter out options that are already present in the current query\n if (parsedQuery.value) {\n filteredOptions = filteredOptions.filter((option) => !containsQueryOption(parsedQuery.value, option));\n }\n // append the input text to the option text for highlighting in the menu item\n return filteredOptions.map((option) => {\n const menuOption: MenuOption<QueryTerm> = {\n id: option.id,\n text: option.text,\n icon: option.icon,\n disabled: option.disabled,\n searchText: inputText.value,\n context: option.queryTerm,\n };\n return menuOption;\n });\n});\n\n// Watch for changes in available options, input text, or loading state to ensure menu is displayed when typing.\nwatch(\n [availableOptions, inputText, () => props.optionsLoading],\n ([newOptions, newInputText, isLoading]) => {\n // If user is typing and there are options to show OR loading, display the menu\n if (newInputText && newInputText.length > 0 && (newOptions.length > 0 || isLoading)) {\n displayOptions.value = true;\n } else if (!newInputText || newInputText.length === 0) {\n // Clear the menu if no input text\n displayOptions.value = false;\n }\n },\n { immediate: true },\n);\n\nconst handleClickOutside = () => {\n if (props.enableCustomOptionsInput) {\n handleAddSelfAddedOption();\n }\n\n displayOptions.value = false;\n isCurrentInputFocused.value = false;\n wrapContent.value = false;\n};\n\nconst handleOptionSelected = (option: MenuOption<QueryTerm>) => {\n try {\n const queryOption: QueryBuilderSuggestionMenuOption = {\n id: option.id,\n text: option.text,\n queryTerm: option.context,\n icon: option.icon,\n };\n parsedQuery.value = addQueryOption(parsedQuery.value, queryOption);\n //clear input text after adding option\n clearInputText();\n } catch (error) {\n console.error(\"Error adding query option:\", error);\n } finally {\n displayOptions.value = false;\n isCurrentInputFocused.value = false;\n }\n};\n\nfunction handleWrapperClick(event: MouseEvent) {\n const target = event.target as HTMLElement;\n\n // Don't interfere if clicking on a contenteditable element (QueryTerm)\n if (target.isContentEditable || target.closest('[contenteditable=\"true\"]')) {\n return;\n }\n\n // Don't interfere if clicking on buttons or other interactive elements\n if (target.tagName === \"BUTTON\" || target.tagName === \"SVG\" || target.closest(\"button\")) {\n return;\n }\n\n // Focus the main input for everything else\n input.value?.focus();\n}\n\nfunction checkWrapperFocus(event: FocusEvent) {\n if (event.type === \"focus\") {\n isCurrentInputFocused.value = true;\n displayOptions.value = true;\n } else if (event.type === \"blur\") {\n // Use setTimeout to allow other focus events to fire first\n // setTimeout(() => {\n // // Check if any element inside the wrapper is currently focused\n // const wrapperEl = wrapper.value;\n // const activeElement = document.activeElement;\n // if (!wrapperEl || !wrapperEl.contains(activeElement)) {\n // isCurrentInputFocused.value = false;\n // displayOptions.value = false;\n // }\n // }, 100);\n }\n}\n\nconst clearInputText = () => {\n inputText.value = \"\";\n};\n</script>\n\n<template>\n <div\n ref=\"query-builder-input\"\n class=\"pv-relative pv-query-builder-input-wrapper\"\n @focus=\"checkWrapperFocus\"\n @click=\"handleWrapperClick\"\n v-on-click-outside=\"handleClickOutside\"\n >\n <PvIcon v-if=\"!hideSearchIcon\" name=\"search\" />\n <div\n class=\"pv-flex pv-full-width pv-inset-inline pv-query-builder-input\"\n style=\"--inset-size: 4px; --flex-gap: 4px\"\n :style=\"enableWrapQueryTerms || wrapContent ? 'flex-wrap: wrap;' : 'flex-wrap: nowrap;'\"\n >\n <QueryFormatter\n v-model=\"parsedQuery\"\n v-model:wrap-content=\"wrapContent\"\n :query-term-display-limit=\"queryTermDisplayLimit\"\n ></QueryFormatter>\n <input\n v-model=\"inputText\"\n ref=\"search-input\"\n data-testid=\"pv-search-input\"\n type=\"text\"\n :disabled=\"disabled\"\n :placeholder=\"computedPlaceholder\"\n :data-invalid=\"displayInvalidQuery ? 'true' : undefined\"\n @focus=\"checkWrapperFocus\"\n @blur=\"checkWrapperFocus\"\n />\n </div>\n <PvButton v-if=\"parsedQuery && !hideClearButton\" variant=\"ghost\" leftIcon=\"close\" size=\"md\" @click=\"clearQuery\" />\n <p v-if=\"displayInvalidQuery\" class=\"pv-text-red pv-text-body-xs\">\n {{ invalidQueryReason }}\n </p>\n <PvPopover\n v-if=\"availableOptions.length > 0 || optionsLoading\"\n :class=\"{ 'pv-hide': !displayOptions }\"\n :css-custom-properties=\"{ width: '100%', maxWidth: '100%' }\"\n :isList=\"true\"\n >\n <template v-if=\"!optionsLoading\">\n <template v-for=\"(option, index) in availableOptions\" :key=\"`${index}-${option.searchText}`\">\n <PvMenuItem v-bind=\"option\" @handleSelected=\"handleOptionSelected(option)\" :config=\"menuOptionConfig\" />\n </template>\n </template>\n <template v-else>\n <div class=\"pv-text-center\">\n <PvSpinner variant=\"dark\" />\n </div>\n </template>\n </PvPopover>\n </div>\n</template>\n\n<style scoped>\n.pv-query-builder-input-wrapper {\n display: flex;\n align-items: center;\n position: relative;\n width: 100%;\n background: rgb(247, 248, 248);\n padding: 0.25rem;\n border-radius: 0.5rem;\n border: 2px solid transparent;\n font-size: 0.75rem;\n min-height: 2.25rem;\n cursor: text;\n}\n\n.pv-query-builder-input {\n justify-content: start;\n overflow-x: hidden;\n}\n\n.pv-query-builder-input-wrapper input {\n border: none;\n background: transparent;\n outline: none;\n font-size: 0.75rem;\n}\n\n.pv-query-builder-input-wrapper:focus-within {\n border: 2px solid #36c5ba;\n}\n</style>\n","<script setup lang=\"ts\">\nimport { computed, ComputedRef, ref, useTemplateRef, watch } from \"vue\";\nimport {\n QueryBuilderOutput,\n QueryBuilderProcessor,\n QueryBuilderSuggestionMenuOption,\n QueryTerm,\n useQueryBuilder,\n} from \"@/components/base/PvQueryBuilderInput/useQueryBuilder\";\nimport PvPopover from \"@/components/base/PvPopover/PvPopover.vue\";\nimport PvIcon from \"@/components/base/PvIcon/PvIcon.vue\";\nimport PvMenuItem from \"@/components/base/PvMenu/items/PvMenuItem.vue\";\nimport { vOnClickOutside } from \"@vueuse/components\";\nimport QueryBuilderMenuOptionRenderer from \"@/components/base/PvQueryBuilderInput/QueryBuilderMenuOptionRenderer.vue\";\nimport QueryFormatter from \"@/components/base/PvQueryBuilderInput/QueryFormatter.vue\";\nimport type { MenuOption } from \"@/types\";\nimport PvButton from \"@/components/base/PvButton/PvButton.vue\";\nimport PvSpinner from \"@/components/base/PvSpinner/PvSpinner.vue\";\nimport { onKeyStroke } from \"@vueuse/core\";\n\nexport interface PvQueryBuilderInputProps {\n /**\n * Placeholder text shown in the input when no query is active.\n */\n placeholder?: string;\n /**\n * When true, the input is non-interactive and visually dimmed.\n */\n disabled?: boolean;\n /** When true, displays a keyboard shortcut badge next to the input. */\n displayShortcut?: boolean;\n /**\n * Determines how user input is parsed into structured query terms.\n * - `'full'`: free-text and field-based queries.\n * - `'field-only'`: only options with a queryField are shown.\n */\n processor?: QueryBuilderProcessor;\n /**\n * When true, shows a loading spinner in the suggestion dropdown.\n */\n optionsLoading?: boolean;\n /**\n * When true, users can press Enter to add free-text terms without selecting a suggestion.\n */\n enableCustomOptionsInput?: boolean;\n /**\n * When true, hides the search icon on the left side of the input.\n */\n hideSearchIcon?: boolean;\n /**\n * When true, hides the clear button that resets the query.\n */\n hideClearButton?: boolean;\n /**\n * Maximum number of query term pills to display before collapsing.\n */\n queryTermDisplayLimit?: number;\n /**\n * When true, query term pills wrap to the next line instead of scrolling horizontally.\n */\n enableWrapQueryTerms?: boolean;\n}\n\nconst props = withDefaults(defineProps<PvQueryBuilderInputProps>(), {\n placeholder: \"Search\",\n disabled: false,\n processor: \"full\",\n optionsLoading: false,\n enableCustomOptionsInput: false,\n hideSearchIcon: false,\n hideClearButton: false,\n queryTermDisplayLimit: 3,\n enableWrapQueryTerms: false,\n});\n\nconst menuOptionConfig = {\n renderer: QueryBuilderMenuOptionRenderer,\n};\n\n// const wrapper = useTemplateRef<HTMLDivElement | null>(\"query-builder-input\");\nconst input = useTemplateRef<HTMLInputElement | null>(\"search-input\");\nconst inputText = defineModel<string>(\"searchText\", { required: false, default: \"\" });\nconst parsedQuery = defineModel<QueryBuilderOutput | null>(\"query\", { required: true });\nconst queryOptions = defineModel<QueryBuilderSuggestionMenuOption[]>(\"options\", {\n required: false,\n});\nconst { addQueryOption, containsQueryOption } = useQueryBuilder();\nconst displayOptions = ref(false);\nconst isCurrentInputFocused = ref(false);\nconst wrapContent = ref(false);\n\nconst computedPlaceholder = computed(() => {\n return parsedQuery.value !== null ? \"\" : props.placeholder;\n});\n\nconst invalidQueryReason = ref<string | null>(null);\nconst displayInvalidQuery = computed(() => {\n return invalidQueryReason.value !== null && invalidQueryReason.value !== \"\" && !isCurrentInputFocused.value;\n});\n\nconst clearQuery = () => {\n parsedQuery.value = null;\n inputText.value = \"\";\n invalidQueryReason.value = null;\n wrapContent.value = false;\n};\n\nif (props.enableCustomOptionsInput) {\n onKeyStroke(\n \"Enter\",\n () => {\n if (inputText.value.trim()) {\n handleAddSelfAddedOption();\n }\n },\n { target: input },\n );\n}\n\nconst handleAddSelfAddedOption = () => {\n if (inputText.value.trim()) {\n parsedQuery.value = addQueryOption(parsedQuery.value, {\n id: inputText.value.trim(),\n text: inputText.value,\n queryTerm: {\n queryText: inputText.value,\n },\n });\n clearInputText();\n }\n};\n\nconst availableOptions: ComputedRef<MenuOption<QueryTerm>[]> = computed(() => {\n if (!queryOptions.value || queryOptions.value.length === 0) {\n return [];\n }\n let filteredOptions = queryOptions.value;\n // if the processor is field-only, filter out options without a queryField\n if (props.processor === \"field-only\") {\n filteredOptions = queryOptions.value.filter((option) => option.queryTerm?.queryField);\n }\n // filter out options that are already present in the current query\n if (parsedQuery.value) {\n filteredOptions = filteredOptions.filter((option) => !containsQueryOption(parsedQuery.value, option));\n }\n // append the input text to the option text for highlighting in the menu item\n return filteredOptions.map((option) => {\n const menuOption: MenuOption<QueryTerm> = {\n id: option.id,\n text: option.text,\n icon: option.icon,\n disabled: option.disabled,\n searchText: inputText.value,\n context: option.queryTerm,\n };\n return menuOption;\n });\n});\n\n// Watch for changes in available options, input text, or loading state to ensure menu is displayed when typing.\nwatch(\n [availableOptions, inputText, () => props.optionsLoading],\n ([newOptions, newInputText, isLoading]) => {\n // If user is typing and there are options to show OR loading, display the menu\n if (newInputText && newInputText.length > 0 && (newOptions.length > 0 || isLoading)) {\n displayOptions.value = true;\n } else if (!newInputText || newInputText.length === 0) {\n // Clear the menu if no input text\n displayOptions.value = false;\n }\n },\n { immediate: true },\n);\n\nconst handleClickOutside = () => {\n if (props.enableCustomOptionsInput) {\n handleAddSelfAddedOption();\n }\n\n displayOptions.value = false;\n isCurrentInputFocused.value = false;\n wrapContent.value = false;\n};\n\nconst handleOptionSelected = (option: MenuOption<QueryTerm>) => {\n try {\n const queryOption: QueryBuilderSuggestionMenuOption = {\n id: option.id,\n text: option.text,\n queryTerm: option.context,\n icon: option.icon,\n };\n parsedQuery.value = addQueryOption(parsedQuery.value, queryOption);\n //clear input text after adding option\n clearInputText();\n } catch (error) {\n console.error(\"Error adding query option:\", error);\n } finally {\n displayOptions.value = false;\n isCurrentInputFocused.value = false;\n }\n};\n\nfunction handleWrapperClick(event: MouseEvent) {\n const target = event.target as HTMLElement;\n\n // Don't interfere if clicking on a contenteditable element (QueryTerm)\n if (target.isContentEditable || target.closest('[contenteditable=\"true\"]')) {\n return;\n }\n\n // Don't interfere if clicking on buttons or other interactive elements\n if (target.tagName === \"BUTTON\" || target.tagName === \"SVG\" || target.closest(\"button\")) {\n return;\n }\n\n // Focus the main input for everything else\n input.value?.focus();\n}\n\nfunction checkWrapperFocus(event: FocusEvent) {\n if (event.type === \"focus\") {\n isCurrentInputFocused.value = true;\n displayOptions.value = true;\n } else if (event.type === \"blur\") {\n // Use setTimeout to allow other focus events to fire first\n // setTimeout(() => {\n // // Check if any element inside the wrapper is currently focused\n // const wrapperEl = wrapper.value;\n // const activeElement = document.activeElement;\n // if (!wrapperEl || !wrapperEl.contains(activeElement)) {\n // isCurrentInputFocused.value = false;\n // displayOptions.value = false;\n // }\n // }, 100);\n }\n}\n\nconst clearInputText = () => {\n inputText.value = \"\";\n};\n</script>\n\n<template>\n <div\n ref=\"query-builder-input\"\n class=\"pv-relative pv-query-builder-input-wrapper\"\n @focus=\"checkWrapperFocus\"\n @click=\"handleWrapperClick\"\n v-on-click-outside=\"handleClickOutside\"\n >\n <PvIcon v-if=\"!hideSearchIcon\" name=\"search\" />\n <div\n class=\"pv-flex pv-full-width pv-inset-inline pv-query-builder-input\"\n style=\"--inset-size: 4px; --flex-gap: 4px\"\n :style=\"enableWrapQueryTerms || wrapContent ? 'flex-wrap: wrap;' : 'flex-wrap: nowrap;'\"\n >\n <QueryFormatter\n v-model=\"parsedQuery\"\n v-model:wrap-content=\"wrapContent\"\n :query-term-display-limit=\"queryTermDisplayLimit\"\n ></QueryFormatter>\n <input\n v-model=\"inputText\"\n ref=\"search-input\"\n data-testid=\"pv-search-input\"\n type=\"text\"\n :disabled=\"disabled\"\n :placeholder=\"computedPlaceholder\"\n :data-invalid=\"displayInvalidQuery ? 'true' : undefined\"\n @focus=\"checkWrapperFocus\"\n @blur=\"checkWrapperFocus\"\n />\n </div>\n <PvButton v-if=\"parsedQuery && !hideClearButton\" variant=\"ghost\" leftIcon=\"close\" size=\"md\" @click=\"clearQuery\" />\n <p v-if=\"displayInvalidQuery\" class=\"pv-text-red pv-text-body-xs\">\n {{ invalidQueryReason }}\n </p>\n <PvPopover\n v-if=\"availableOptions.length > 0 || optionsLoading\"\n :class=\"{ 'pv-hide': !displayOptions }\"\n :css-custom-properties=\"{ width: '100%', maxWidth: '100%' }\"\n :isList=\"true\"\n >\n <template v-if=\"!optionsLoading\">\n <template v-for=\"(option, index) in availableOptions\" :key=\"`${index}-${option.searchText}`\">\n <PvMenuItem v-bind=\"option\" @handleSelected=\"handleOptionSelected(option)\" :config=\"menuOptionConfig\" />\n </template>\n </template>\n <template v-else>\n <div class=\"pv-text-center\">\n <PvSpinner variant=\"dark\" />\n </div>\n </template>\n </PvPopover>\n </div>\n</template>\n\n<style scoped>\n.pv-query-builder-input-wrapper {\n display: flex;\n align-items: center;\n position: relative;\n width: 100%;\n background: rgb(247, 248, 248);\n padding: 0.25rem;\n border-radius: 0.5rem;\n border: 2px solid transparent;\n font-size: 0.75rem;\n min-height: 2.25rem;\n cursor: text;\n}\n\n.pv-query-builder-input {\n justify-content: start;\n overflow-x: hidden;\n}\n\n.pv-query-builder-input-wrapper input {\n border: none;\n background: transparent;\n outline: none;\n font-size: 0.75rem;\n}\n\n.pv-query-builder-input-wrapper:focus-within {\n border: 2px solid #36c5ba;\n}\n</style>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport type { PvTableOfContentsItem } from \"./types\";\n\ninterface PvTableOfContentsProps {\n /** Items to display in the table of contents */\n items: PvTableOfContentsItem[];\n}\n\ndefineProps<PvTableOfContentsProps>();\n\nconst modelValue = defineModel<string>({ required: false });\nconst emit = defineEmits<{\n (e: \"handle-select\", item: PvTableOfContentsItem): void;\n}>();\n\nconst handleSelect = (event: MouseEvent, item: PvTableOfContentsItem) => {\n if (!item.href) {\n event.preventDefault();\n }\n modelValue.value = item.id;\n emit(\"handle-select\", item);\n};\n</script>\n\n<template>\n <ul class=\"pv-toc\" role=\"list\" style=\"min-width: 160px\">\n <li v-for=\"item in items\" :key=\"item.id\" :aria-current=\"modelValue === item.id ? 'true' : undefined\">\n <a :href=\"item.href ?? '#'\" @click=\"handleSelect($event, item)\">\n <PvIcon v-if=\"item.icon\" :name=\"item.icon\" />\n {{ item.label }}\n </a>\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\">\nimport PvIcon from \"../PvIcon/PvIcon.vue\";\nimport type { PvTableOfContentsItem } from \"./types\";\n\ninterface PvTableOfContentsProps {\n /** Items to display in the table of contents */\n items: PvTableOfContentsItem[];\n}\n\ndefineProps<PvTableOfContentsProps>();\n\nconst modelValue = defineModel<string>({ required: false });\nconst emit = defineEmits<{\n (e: \"handle-select\", item: PvTableOfContentsItem): void;\n}>();\n\nconst handleSelect = (event: MouseEvent, item: PvTableOfContentsItem) => {\n if (!item.href) {\n event.preventDefault();\n }\n modelValue.value = item.id;\n emit(\"handle-select\", item);\n};\n</script>\n\n<template>\n <ul class=\"pv-toc\" role=\"list\" style=\"min-width: 160px\">\n <li v-for=\"item in items\" :key=\"item.id\" :aria-current=\"modelValue === item.id ? 'true' : undefined\">\n <a :href=\"item.href ?? '#'\" @click=\"handleSelect($event, item)\">\n <PvIcon v-if=\"item.icon\" :name=\"item.icon\" />\n {{ item.label }}\n </a>\n </li>\n </ul>\n</template>\n","<script setup lang=\"ts\">\ninterface StepperProps {\n count?: number;\n active?: number;\n clickable?: boolean;\n}\n\ndefineEmits<{\n (e: \"update:active\", index: number): void;\n}>();\n\nconst props = withDefaults(defineProps<StepperProps>(), {\n count: 5,\n active: 0,\n clickable: false,\n});\n\nif (props.active < 0 || props.active >= props.count) {\n console.warn(`PvStepper: \"active\" (${props.active}) is out of range for \"count\" (${props.count}).`);\n}\n</script>\n\n<template>\n <div class=\"pv-flex\">\n <div\n v-for=\"(_, index) in count\"\n :key=\"index\"\n :data-clickable=\"clickable\"\n :class=\"index === active ? 'pv-stepper-active' : 'pv-stepper-inactive'\"\n @click=\"clickable && $emit('update:active', index)\"\n ></div>\n </div>\n</template>\n","<script setup lang=\"ts\">\ninterface StepperProps {\n count?: number;\n active?: number;\n clickable?: boolean;\n}\n\ndefineEmits<{\n (e: \"update:active\", index: number): void;\n}>();\n\nconst props = withDefaults(defineProps<StepperProps>(), {\n count: 5,\n active: 0,\n clickable: false,\n});\n\nif (props.active < 0 || props.active >= props.count) {\n console.warn(`PvStepper: \"active\" (${props.active}) is out of range for \"count\" (${props.count}).`);\n}\n</script>\n\n<template>\n <div class=\"pv-flex\">\n <div\n v-for=\"(_, index) in count\"\n :key=\"index\"\n :data-clickable=\"clickable\"\n :class=\"index === active ? 'pv-stepper-active' : 'pv-stepper-inactive'\"\n @click=\"clickable && $emit('update:active', index)\"\n ></div>\n </div>\n</template>\n","import Aura from \"@primeuix/themes/aura\";\n\nexport const PvComponentsConfig = {\n theme: {\n preset: Aura,\n options: {\n darkModeSelector: false || \"none\",\n cssLayer: {\n name: \"primevue\",\n order: \"pit-viper-v2, primevue\",\n },\n },\n },\n};\n","import { PrimeVue } from \"@primevue/core\";\nimport { App } from \"vue\";\nimport { PvComponentsConfig } from \"./primeVue.config.ts\";\n\nexport const usePvComponents = (app: App<Element>) => {\n app.use(PrimeVue, PvComponentsConfig);\n};\n"],"x_google_ignoreList":[30,31,32,33,34,35],"mappings":"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"}