@pine-ds/core 4.2.0 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (545) hide show
  1. package/components/closest.js +1 -1
  2. package/components/floating-ui.dom.js +1 -1
  3. package/components/i18n-format.js +1 -1
  4. package/components/index.d.ts +2 -0
  5. package/components/index.js +1 -1
  6. package/components/index2.js +1 -1
  7. package/components/mock-pds-modal.js +1 -1
  8. package/components/pds-button2.js +1 -1
  9. package/components/pds-checkbox2.js +1 -1
  10. package/components/pds-chip2.js +1 -1
  11. package/components/pds-combobox.js +2 -2
  12. package/components/pds-container.js +1 -1
  13. package/components/pds-copytext.js +1 -1
  14. package/components/pds-datepicker.d.ts +11 -0
  15. package/components/pds-datepicker.js +1 -0
  16. package/components/pds-divider.js +1 -1
  17. package/components/pds-drawer-content.js +1 -1
  18. package/components/pds-drawer-footer.js +1 -1
  19. package/components/pds-drawer-header.js +1 -1
  20. package/components/pds-drawer.js +1 -1
  21. package/components/pds-dropdown-menu-item.js +1 -1
  22. package/components/pds-dropdown-menu-separator.js +1 -1
  23. package/components/pds-dropdown-menu.js +1 -1
  24. package/components/pds-filter.js +1 -1
  25. package/components/pds-filters.js +1 -1
  26. package/components/pds-icon2.js +1 -1
  27. package/components/pds-image.js +1 -1
  28. package/components/pds-input.js +1 -1
  29. package/components/pds-input2.js +1 -0
  30. package/components/pds-link2.js +1 -1
  31. package/components/pds-loader2.js +1 -1
  32. package/components/pds-modal-content.js +1 -1
  33. package/components/pds-modal-footer.js +1 -1
  34. package/components/pds-modal-header.js +1 -1
  35. package/components/pds-modal2.js +1 -1
  36. package/components/pds-multiselect.js +1 -1
  37. package/components/pds-popover.js +1 -1
  38. package/components/pds-progress.js +1 -1
  39. package/components/pds-property.js +1 -1
  40. package/components/pds-radio-group.js +1 -1
  41. package/components/pds-radio.js +1 -1
  42. package/components/pds-row.js +1 -1
  43. package/components/pds-select.js +1 -1
  44. package/components/pds-sortable-item.js +1 -1
  45. package/components/pds-sortable.js +2 -2
  46. package/components/pds-switch.js +1 -1
  47. package/components/pds-table-body.js +1 -1
  48. package/components/pds-table-cell2.js +1 -1
  49. package/components/pds-table-head-cell2.js +1 -1
  50. package/components/pds-table-head.js +1 -1
  51. package/components/pds-table-row.js +1 -1
  52. package/components/pds-tabpanel.js +1 -1
  53. package/components/pds-tabs.js +1 -1
  54. package/components/pds-text2.js +1 -1
  55. package/components/pds-textarea.js +1 -1
  56. package/components/pds-toast.js +1 -1
  57. package/components/pds-tooltip.js +1 -1
  58. package/components/utils.js +1 -1
  59. package/dist/cjs/closest-D0qyYtJ3.js +20 -0
  60. package/dist/cjs/{floating-ui.dom-BZk7Blsu.js → floating-ui.dom-Dc8Anyel.js} +79 -0
  61. package/dist/cjs/{i18n-format-CrpIhahc.js → i18n-format-BD0PmYzT.js} +1 -0
  62. package/dist/cjs/{index-CuQil7H0.js → index-Bl5KnQay.js} +4 -1
  63. package/dist/cjs/{index-Bu3NXpbK.js → index-D-QQKB0y.js} +9 -1
  64. package/dist/cjs/loader.cjs.js +2 -2
  65. package/dist/cjs/mock-pds-modal.cjs.entry.js +3 -3
  66. package/dist/cjs/pds-accordion.cjs.entry.js +2 -2
  67. package/dist/cjs/pds-alert.cjs.entry.js +1 -1
  68. package/dist/cjs/pds-avatar.cjs.entry.js +2 -2
  69. package/dist/cjs/pds-box.cjs.entry.js +2 -2
  70. package/dist/cjs/pds-button.cjs.entry.js +54 -5
  71. package/dist/cjs/pds-checkbox.cjs.entry.js +14 -6
  72. package/dist/cjs/pds-chip.cjs.entry.js +34 -9
  73. package/dist/cjs/pds-combobox.cjs.entry.js +1225 -117
  74. package/dist/cjs/pds-container.cjs.entry.js +2 -2
  75. package/dist/cjs/pds-copytext.cjs.entry.js +5 -5
  76. package/dist/cjs/pds-datepicker.cjs.entry.js +1962 -0
  77. package/dist/cjs/pds-divider.cjs.entry.js +2 -2
  78. package/dist/cjs/pds-drawer-content.cjs.entry.js +2 -2
  79. package/dist/cjs/pds-drawer-footer.cjs.entry.js +2 -2
  80. package/dist/cjs/pds-drawer-header.cjs.entry.js +2 -2
  81. package/dist/cjs/pds-drawer.cjs.entry.js +11 -4
  82. package/dist/cjs/pds-dropdown-menu-item.cjs.entry.js +2 -2
  83. package/dist/cjs/pds-dropdown-menu-separator.cjs.entry.js +2 -2
  84. package/dist/cjs/pds-dropdown-menu.cjs.entry.js +11 -4
  85. package/dist/cjs/pds-filter.cjs.entry.js +3 -3
  86. package/dist/cjs/pds-filters.cjs.entry.js +2 -2
  87. package/dist/cjs/pds-icon.cjs.entry.js +2 -2
  88. package/dist/cjs/pds-image.cjs.entry.js +3 -3
  89. package/dist/cjs/pds-input.cjs.entry.js +8 -5
  90. package/dist/cjs/pds-link.cjs.entry.js +5 -5
  91. package/dist/cjs/pds-loader.cjs.entry.js +2 -2
  92. package/dist/cjs/pds-modal-content.cjs.entry.js +3 -3
  93. package/dist/cjs/pds-modal-footer.cjs.entry.js +2 -2
  94. package/dist/cjs/pds-modal-header.cjs.entry.js +2 -2
  95. package/dist/cjs/pds-modal.cjs.entry.js +42 -8
  96. package/dist/cjs/pds-multiselect.cjs.entry.js +264 -51
  97. package/dist/cjs/pds-popover.cjs.entry.js +30 -12
  98. package/dist/cjs/pds-progress.cjs.entry.js +4 -2
  99. package/dist/cjs/pds-property.cjs.entry.js +2 -2
  100. package/dist/cjs/pds-radio-group.cjs.entry.js +5 -5
  101. package/dist/cjs/pds-radio.cjs.entry.js +6 -6
  102. package/dist/cjs/pds-row.cjs.entry.js +2 -2
  103. package/dist/cjs/pds-select.cjs.entry.js +3 -3
  104. package/dist/cjs/pds-sortable-item.cjs.entry.js +3 -3
  105. package/dist/cjs/pds-sortable.cjs.entry.js +2 -2
  106. package/dist/cjs/pds-switch.cjs.entry.js +14 -6
  107. package/dist/cjs/pds-tab.cjs.entry.js +1 -1
  108. package/dist/cjs/pds-table-body.cjs.entry.js +2 -2
  109. package/dist/cjs/pds-table-cell.cjs.entry.js +5 -5
  110. package/dist/cjs/pds-table-head-cell.cjs.entry.js +4 -4
  111. package/dist/cjs/pds-table-head.cjs.entry.js +3 -3
  112. package/dist/cjs/pds-table-row.cjs.entry.js +3 -3
  113. package/dist/cjs/pds-table.cjs.entry.js +1 -1
  114. package/dist/cjs/pds-tabpanel.cjs.entry.js +2 -2
  115. package/dist/cjs/pds-tabs.cjs.entry.js +2 -2
  116. package/dist/cjs/pds-text.cjs.entry.js +5 -5
  117. package/dist/cjs/pds-textarea.cjs.entry.js +14 -9
  118. package/dist/cjs/pds-toast.cjs.entry.js +4 -4
  119. package/dist/cjs/pds-tooltip.cjs.entry.js +4 -4
  120. package/dist/cjs/pine-core.cjs.js +2 -2
  121. package/dist/cjs/{truncation-tooltip-Bps7_rUy.js → truncation-tooltip-CYgQfBLt.js} +1 -1
  122. package/dist/cjs/{utils-7jx8T2mW.js → utils-BhRmyxT8.js} +51 -6
  123. package/dist/collection/collection-manifest.json +1 -0
  124. package/dist/collection/components/pds-button/pds-button.css +1 -2
  125. package/dist/collection/components/pds-button/pds-button.js +53 -2
  126. package/dist/collection/components/pds-checkbox/pds-checkbox.css +13 -4
  127. package/dist/collection/components/pds-checkbox/pds-checkbox.js +19 -3
  128. package/dist/collection/components/pds-chip/pds-chip.css +60 -6
  129. package/dist/collection/components/pds-chip/pds-chip.js +69 -4
  130. package/dist/collection/components/pds-chip/pds-chip.tokens.css +16 -0
  131. package/dist/collection/components/pds-chip/stories/pds-chip.stories.js +39 -1
  132. package/dist/collection/components/pds-combobox/grouped-options-panel.js +262 -0
  133. package/dist/collection/components/pds-combobox/pds-combobox.css +243 -15
  134. package/dist/collection/components/pds-combobox/pds-combobox.js +1129 -115
  135. package/dist/collection/components/pds-combobox/stories/pds-combobox.stories.js +240 -0
  136. package/dist/collection/components/pds-container/pds-container.js +1 -1
  137. package/dist/collection/components/pds-copytext/pds-copytext.js +1 -1
  138. package/dist/collection/components/pds-datepicker/calendar-portal.js +136 -0
  139. package/dist/collection/components/pds-datepicker/date-utils.js +132 -0
  140. package/dist/collection/components/pds-datepicker/datepicker-interface.js +1 -0
  141. package/dist/collection/components/pds-datepicker/pds-datepicker.css +545 -0
  142. package/dist/collection/components/pds-datepicker/pds-datepicker.js +2406 -0
  143. package/dist/collection/components/pds-datepicker/presets.js +96 -0
  144. package/dist/collection/components/pds-datepicker/stories/pds-datepicker.stories.js +195 -0
  145. package/dist/collection/components/pds-datepicker/value.js +238 -0
  146. package/dist/collection/components/pds-divider/pds-divider.js +1 -1
  147. package/dist/collection/components/pds-drawer/pds-drawer-content/pds-drawer-content.js +1 -1
  148. package/dist/collection/components/pds-drawer/pds-drawer-footer/pds-drawer-footer.js +1 -1
  149. package/dist/collection/components/pds-drawer/pds-drawer-header/pds-drawer-header.js +1 -1
  150. package/dist/collection/components/pds-drawer/pds-drawer.css +4 -0
  151. package/dist/collection/components/pds-drawer/pds-drawer.js +9 -2
  152. package/dist/collection/components/pds-dropdown-menu/pds-dropdown-menu-item/pds-dropdown-menu-item.js +1 -1
  153. package/dist/collection/components/pds-dropdown-menu/pds-dropdown-menu-separator/pds-dropdown-menu-separator.js +1 -1
  154. package/dist/collection/components/pds-dropdown-menu/pds-dropdown-menu.js +9 -2
  155. package/dist/collection/components/pds-filters/pds-filter/pds-filter.js +1 -1
  156. package/dist/collection/components/pds-filters/pds-filters.js +1 -1
  157. package/dist/collection/components/pds-image/pds-image.js +2 -2
  158. package/dist/collection/components/pds-input/pds-input.js +6 -3
  159. package/dist/collection/components/pds-link/pds-link.js +2 -2
  160. package/dist/collection/components/pds-loader/pds-loader.js +1 -1
  161. package/dist/collection/components/pds-modal/pds-modal-content/pds-modal-content.js +2 -2
  162. package/dist/collection/components/pds-modal/pds-modal-footer/pds-modal-footer.js +1 -1
  163. package/dist/collection/components/pds-modal/pds-modal-header/pds-modal-header.js +1 -1
  164. package/dist/collection/components/pds-modal/pds-modal.css +20 -0
  165. package/dist/collection/components/pds-modal/pds-modal.js +55 -10
  166. package/dist/collection/components/pds-modal/stories/pds-modal.stories.js +14 -0
  167. package/dist/collection/components/pds-modal/test/mock-pds-modal.js +1 -1
  168. package/dist/collection/components/pds-multiselect/pds-multiselect.css +19 -1
  169. package/dist/collection/components/pds-multiselect/pds-multiselect.js +390 -47
  170. package/dist/collection/components/pds-multiselect/stories/pds-multiselect.stories.js +136 -1
  171. package/dist/collection/components/pds-popover/pds-popover.js +29 -11
  172. package/dist/collection/components/pds-progress/pds-progress.js +3 -1
  173. package/dist/collection/components/pds-property/pds-property.js +1 -1
  174. package/dist/collection/components/pds-radio/pds-radio.css +1 -2
  175. package/dist/collection/components/pds-radio/pds-radio.js +3 -3
  176. package/dist/collection/components/pds-radio-group/pds-radio-group.js +3 -3
  177. package/dist/collection/components/pds-row/pds-row.js +1 -1
  178. package/dist/collection/components/pds-select/pds-select.js +1 -1
  179. package/dist/collection/components/pds-sortable/pds-sortable-item/pds-sortable-item.js +1 -1
  180. package/dist/collection/components/pds-sortable/pds-sortable.js +1 -1
  181. package/dist/collection/components/pds-switch/pds-switch.css +3 -0
  182. package/dist/collection/components/pds-switch/pds-switch.js +20 -4
  183. package/dist/collection/components/pds-table/pds-table-body/pds-table-body.js +1 -1
  184. package/dist/collection/components/pds-table/pds-table-cell/pds-table-cell.js +2 -2
  185. package/dist/collection/components/pds-table/pds-table-head/pds-table-head.js +1 -1
  186. package/dist/collection/components/pds-table/pds-table-head-cell/pds-table-head-cell.js +2 -2
  187. package/dist/collection/components/pds-table/pds-table-row/pds-table-row.js +1 -1
  188. package/dist/collection/components/pds-tabs/pds-tabpanel/pds-tabpanel.js +1 -1
  189. package/dist/collection/components/pds-tabs/pds-tabs.js +1 -1
  190. package/dist/collection/components/pds-text/pds-text.js +1 -1
  191. package/dist/collection/components/pds-textarea/pds-textarea.js +11 -6
  192. package/dist/collection/components/pds-toast/pds-toast.js +3 -3
  193. package/dist/collection/components/pds-tooltip/pds-tooltip.js +2 -2
  194. package/dist/collection/utils/closest.js +8 -0
  195. package/dist/collection/utils/utils.js +49 -6
  196. package/dist/docs.json +2055 -84
  197. package/dist/esm/closest-DHPzKMVS.js +17 -0
  198. package/dist/esm/{floating-ui.dom-DDtwbwIl.js → floating-ui.dom-BPqJgIq6.js} +79 -1
  199. package/dist/esm/{i18n-format-BKsJZTyn.js → i18n-format-BJgZHCWe.js} +1 -1
  200. package/dist/esm/{index-CTLu1TM4.js → index-CB8Yh0Nt.js} +4 -1
  201. package/dist/esm/{index-DdPaBxPo.js → index-DxI-61GK.js} +6 -2
  202. package/dist/esm/loader.js +3 -3
  203. package/dist/esm/mock-pds-modal.entry.js +3 -3
  204. package/dist/esm/pds-accordion.entry.js +2 -2
  205. package/dist/esm/pds-alert.entry.js +1 -1
  206. package/dist/esm/pds-avatar.entry.js +2 -2
  207. package/dist/esm/pds-box.entry.js +2 -2
  208. package/dist/esm/pds-button.entry.js +54 -5
  209. package/dist/esm/pds-checkbox.entry.js +14 -6
  210. package/dist/esm/pds-chip.entry.js +34 -9
  211. package/dist/esm/pds-combobox.entry.js +1225 -117
  212. package/dist/esm/pds-container.entry.js +2 -2
  213. package/dist/esm/pds-copytext.entry.js +5 -5
  214. package/dist/esm/pds-datepicker.entry.js +1960 -0
  215. package/dist/esm/pds-divider.entry.js +2 -2
  216. package/dist/esm/pds-drawer-content.entry.js +2 -2
  217. package/dist/esm/pds-drawer-footer.entry.js +2 -2
  218. package/dist/esm/pds-drawer-header.entry.js +2 -2
  219. package/dist/esm/pds-drawer.entry.js +11 -4
  220. package/dist/esm/pds-dropdown-menu-item.entry.js +2 -2
  221. package/dist/esm/pds-dropdown-menu-separator.entry.js +2 -2
  222. package/dist/esm/pds-dropdown-menu.entry.js +11 -4
  223. package/dist/esm/pds-filter.entry.js +3 -3
  224. package/dist/esm/pds-filters.entry.js +2 -2
  225. package/dist/esm/pds-icon.entry.js +2 -2
  226. package/dist/esm/pds-image.entry.js +3 -3
  227. package/dist/esm/pds-input.entry.js +8 -5
  228. package/dist/esm/pds-link.entry.js +5 -5
  229. package/dist/esm/pds-loader.entry.js +2 -2
  230. package/dist/esm/pds-modal-content.entry.js +3 -3
  231. package/dist/esm/pds-modal-footer.entry.js +2 -2
  232. package/dist/esm/pds-modal-header.entry.js +2 -2
  233. package/dist/esm/pds-modal.entry.js +42 -8
  234. package/dist/esm/pds-multiselect.entry.js +264 -51
  235. package/dist/esm/pds-popover.entry.js +30 -12
  236. package/dist/esm/pds-progress.entry.js +4 -2
  237. package/dist/esm/pds-property.entry.js +2 -2
  238. package/dist/esm/pds-radio-group.entry.js +5 -5
  239. package/dist/esm/pds-radio.entry.js +6 -6
  240. package/dist/esm/pds-row.entry.js +2 -2
  241. package/dist/esm/pds-select.entry.js +3 -3
  242. package/dist/esm/pds-sortable-item.entry.js +3 -3
  243. package/dist/esm/pds-sortable.entry.js +2 -2
  244. package/dist/esm/pds-switch.entry.js +14 -6
  245. package/dist/esm/pds-tab.entry.js +1 -1
  246. package/dist/esm/pds-table-body.entry.js +2 -2
  247. package/dist/esm/pds-table-cell.entry.js +5 -5
  248. package/dist/esm/pds-table-head-cell.entry.js +4 -4
  249. package/dist/esm/pds-table-head.entry.js +3 -3
  250. package/dist/esm/pds-table-row.entry.js +3 -3
  251. package/dist/esm/pds-table.entry.js +1 -1
  252. package/dist/esm/pds-tabpanel.entry.js +2 -2
  253. package/dist/esm/pds-tabs.entry.js +2 -2
  254. package/dist/esm/pds-text.entry.js +5 -5
  255. package/dist/esm/pds-textarea.entry.js +14 -9
  256. package/dist/esm/pds-toast.entry.js +4 -4
  257. package/dist/esm/pds-tooltip.entry.js +4 -4
  258. package/dist/esm/pine-core.js +3 -3
  259. package/dist/esm/{truncation-tooltip-CdtEBn_5.js → truncation-tooltip-_902ENWC.js} +1 -1
  260. package/dist/esm/{utils-tJa4KYNO.js → utils-OYK5-nwe.js} +50 -7
  261. package/dist/esm-es5/closest-DHPzKMVS.js +1 -0
  262. package/dist/esm-es5/floating-ui.dom-BPqJgIq6.js +1 -0
  263. package/dist/esm-es5/{i18n-format-BKsJZTyn.js → i18n-format-BJgZHCWe.js} +1 -1
  264. package/dist/esm-es5/index-CB8Yh0Nt.js +2 -0
  265. package/dist/esm-es5/index-DxI-61GK.js +1 -0
  266. package/dist/esm-es5/loader.js +1 -1
  267. package/dist/esm-es5/mock-pds-modal.entry.js +1 -1
  268. package/dist/esm-es5/pds-accordion.entry.js +1 -1
  269. package/dist/esm-es5/pds-alert.entry.js +1 -1
  270. package/dist/esm-es5/pds-avatar.entry.js +1 -1
  271. package/dist/esm-es5/pds-box.entry.js +1 -1
  272. package/dist/esm-es5/pds-button.entry.js +1 -1
  273. package/dist/esm-es5/pds-checkbox.entry.js +1 -1
  274. package/dist/esm-es5/pds-chip.entry.js +1 -1
  275. package/dist/esm-es5/pds-combobox.entry.js +2 -2
  276. package/dist/esm-es5/pds-container.entry.js +1 -1
  277. package/dist/esm-es5/pds-copytext.entry.js +1 -1
  278. package/dist/esm-es5/pds-datepicker.entry.js +1 -0
  279. package/dist/esm-es5/pds-divider.entry.js +1 -1
  280. package/dist/esm-es5/pds-drawer-content.entry.js +1 -1
  281. package/dist/esm-es5/pds-drawer-footer.entry.js +1 -1
  282. package/dist/esm-es5/pds-drawer-header.entry.js +1 -1
  283. package/dist/esm-es5/pds-drawer.entry.js +1 -1
  284. package/dist/esm-es5/pds-dropdown-menu-item.entry.js +1 -1
  285. package/dist/esm-es5/pds-dropdown-menu-separator.entry.js +1 -1
  286. package/dist/esm-es5/pds-dropdown-menu.entry.js +1 -1
  287. package/dist/esm-es5/pds-filter.entry.js +1 -1
  288. package/dist/esm-es5/pds-filters.entry.js +1 -1
  289. package/dist/esm-es5/pds-icon.entry.js +1 -1
  290. package/dist/esm-es5/pds-image.entry.js +1 -1
  291. package/dist/esm-es5/pds-input.entry.js +1 -1
  292. package/dist/esm-es5/pds-link.entry.js +1 -1
  293. package/dist/esm-es5/pds-loader.entry.js +1 -1
  294. package/dist/esm-es5/pds-modal-content.entry.js +1 -1
  295. package/dist/esm-es5/pds-modal-footer.entry.js +1 -1
  296. package/dist/esm-es5/pds-modal-header.entry.js +1 -1
  297. package/dist/esm-es5/pds-modal.entry.js +1 -1
  298. package/dist/esm-es5/pds-multiselect.entry.js +1 -1
  299. package/dist/esm-es5/pds-popover.entry.js +1 -1
  300. package/dist/esm-es5/pds-progress.entry.js +1 -1
  301. package/dist/esm-es5/pds-property.entry.js +1 -1
  302. package/dist/esm-es5/pds-radio-group.entry.js +1 -1
  303. package/dist/esm-es5/pds-radio.entry.js +1 -1
  304. package/dist/esm-es5/pds-row.entry.js +1 -1
  305. package/dist/esm-es5/pds-select.entry.js +1 -1
  306. package/dist/esm-es5/pds-sortable-item.entry.js +1 -1
  307. package/dist/esm-es5/pds-sortable.entry.js +2 -2
  308. package/dist/esm-es5/pds-switch.entry.js +1 -1
  309. package/dist/esm-es5/pds-tab.entry.js +1 -1
  310. package/dist/esm-es5/pds-table-body.entry.js +1 -1
  311. package/dist/esm-es5/pds-table-cell.entry.js +1 -1
  312. package/dist/esm-es5/pds-table-head-cell.entry.js +1 -1
  313. package/dist/esm-es5/pds-table-head.entry.js +1 -1
  314. package/dist/esm-es5/pds-table-row.entry.js +1 -1
  315. package/dist/esm-es5/pds-table.entry.js +1 -1
  316. package/dist/esm-es5/pds-tabpanel.entry.js +1 -1
  317. package/dist/esm-es5/pds-tabs.entry.js +1 -1
  318. package/dist/esm-es5/pds-text.entry.js +1 -1
  319. package/dist/esm-es5/pds-textarea.entry.js +1 -1
  320. package/dist/esm-es5/pds-toast.entry.js +1 -1
  321. package/dist/esm-es5/pds-tooltip.entry.js +1 -1
  322. package/dist/esm-es5/pine-core.js +1 -1
  323. package/dist/esm-es5/{truncation-tooltip-CdtEBn_5.js → truncation-tooltip-_902ENWC.js} +1 -1
  324. package/dist/esm-es5/utils-OYK5-nwe.js +1 -0
  325. package/dist/pine-core/p-0414092a.system.entry.js +1 -0
  326. package/dist/pine-core/p-04807201.entry.js +1 -0
  327. package/dist/pine-core/{p-56b34569.system.entry.js → p-07f0d168.system.entry.js} +1 -1
  328. package/dist/pine-core/p-08f5d19c.entry.js +1 -0
  329. package/dist/pine-core/{p-15d3a4bc.system.entry.js → p-0aaf8faa.system.entry.js} +1 -1
  330. package/dist/pine-core/p-0bad5955.entry.js +1 -0
  331. package/dist/pine-core/{p-4d388957.system.entry.js → p-0c3bf377.system.entry.js} +1 -1
  332. package/dist/pine-core/p-0ce79cd0.entry.js +1 -0
  333. package/dist/pine-core/{p-3464b456.system.entry.js → p-1057b8c3.system.entry.js} +1 -1
  334. package/dist/pine-core/{p-bf3afa16.system.entry.js → p-108c910a.system.entry.js} +1 -1
  335. package/dist/pine-core/{p-53a4852e.system.entry.js → p-166f61a6.system.entry.js} +1 -1
  336. package/dist/pine-core/{p-31e1722e.entry.js → p-16c8f5e3.entry.js} +1 -1
  337. package/dist/pine-core/p-16e258d1.entry.js +1 -0
  338. package/dist/pine-core/{p-591fbff5.entry.js → p-1be33c95.entry.js} +1 -1
  339. package/dist/pine-core/p-1e3a31da.entry.js +1 -0
  340. package/dist/pine-core/p-1f228db9.entry.js +1 -0
  341. package/dist/pine-core/p-257c6ef9.entry.js +1 -0
  342. package/dist/pine-core/p-26415245.system.entry.js +1 -0
  343. package/dist/pine-core/p-26e1e5bb.entry.js +1 -0
  344. package/dist/pine-core/p-27c06bf8.entry.js +2 -0
  345. package/dist/pine-core/p-31aee437.entry.js +1 -0
  346. package/dist/pine-core/p-330a76f6.system.entry.js +1 -0
  347. package/dist/pine-core/{p-3c4236a8.system.entry.js → p-33c63be6.system.entry.js} +1 -1
  348. package/dist/pine-core/{p-d46adf7d.entry.js → p-344609f9.entry.js} +2 -2
  349. package/dist/pine-core/{p-049681fc.entry.js → p-3a1711c1.entry.js} +1 -1
  350. package/dist/pine-core/p-3a9c58bd.system.entry.js +1 -0
  351. package/dist/pine-core/{p-e3a7d2db.entry.js → p-3ebd543f.entry.js} +1 -1
  352. package/dist/pine-core/p-3fbcb0c8.system.entry.js +1 -0
  353. package/dist/pine-core/{p-b923a70b.entry.js → p-427b4aeb.entry.js} +1 -1
  354. package/dist/pine-core/{p-5772f260.system.entry.js → p-42bd87ea.system.entry.js} +1 -1
  355. package/dist/pine-core/{p-1e2a9b5d.system.entry.js → p-43c691bf.system.entry.js} +1 -1
  356. package/dist/pine-core/p-4566d659.system.entry.js +1 -0
  357. package/dist/pine-core/p-4b8cf04a.system.entry.js +1 -0
  358. package/dist/pine-core/p-4d6f471c.entry.js +1 -0
  359. package/dist/pine-core/{p-3e0c6384.entry.js → p-4e7580c4.entry.js} +1 -1
  360. package/dist/pine-core/{p-0ab735aa.system.entry.js → p-4f4a2d2a.system.entry.js} +1 -1
  361. package/dist/pine-core/{p-7e2b934d.entry.js → p-5211aba7.entry.js} +1 -1
  362. package/dist/pine-core/{p-376f8286.entry.js → p-524b7d3f.entry.js} +1 -1
  363. package/dist/pine-core/{p-3f12afb1.entry.js → p-5613c64c.entry.js} +1 -1
  364. package/dist/pine-core/p-5bb24cb4.entry.js +1 -0
  365. package/dist/pine-core/{p-d7865297.entry.js → p-5bb80b3c.entry.js} +1 -1
  366. package/dist/pine-core/{p-e3cd4627.system.entry.js → p-5c6e0a26.system.entry.js} +1 -1
  367. package/dist/pine-core/{p-51dff5af.system.entry.js → p-5db57551.system.entry.js} +1 -1
  368. package/dist/pine-core/{p-f94667b5.entry.js → p-5eb00ba5.entry.js} +1 -1
  369. package/dist/pine-core/p-61756414.system.entry.js +1 -0
  370. package/dist/pine-core/{p-e5bbe8cc.entry.js → p-682e9e8f.entry.js} +1 -1
  371. package/dist/pine-core/p-6965db1d.entry.js +1 -0
  372. package/dist/pine-core/{p-5aea1082.entry.js → p-6b180ee2.entry.js} +1 -1
  373. package/dist/pine-core/{p-d21739eb.entry.js → p-6c53962f.entry.js} +1 -1
  374. package/dist/pine-core/p-6da6520b.system.entry.js +3 -0
  375. package/dist/pine-core/p-6e3bf862.system.entry.js +1 -0
  376. package/dist/pine-core/{p-053b0898.system.entry.js → p-71c9f866.system.entry.js} +1 -1
  377. package/dist/pine-core/{p-78fd593d.system.entry.js → p-7265b94c.system.entry.js} +1 -1
  378. package/dist/pine-core/{p-9187c26c.system.entry.js → p-74229b5e.system.entry.js} +1 -1
  379. package/dist/pine-core/p-7512c2d4.system.entry.js +1 -0
  380. package/dist/pine-core/p-76db406d.system.entry.js +1 -0
  381. package/dist/pine-core/{p-e1653d75.system.entry.js → p-79aa5f43.system.entry.js} +1 -1
  382. package/dist/pine-core/p-7bbcda0f.system.entry.js +1 -0
  383. package/dist/pine-core/p-7c8946e6.entry.js +1 -0
  384. package/dist/pine-core/p-7c98c90a.system.entry.js +1 -0
  385. package/dist/pine-core/p-81292c03.system.entry.js +1 -0
  386. package/dist/pine-core/p-81300046.system.entry.js +1 -0
  387. package/dist/pine-core/{p-a11a9c40.system.entry.js → p-8252cd84.system.entry.js} +1 -1
  388. package/dist/pine-core/{p-d0d2a886.system.entry.js → p-84ba0e6a.system.entry.js} +1 -1
  389. package/dist/pine-core/{p-c1f8a187.entry.js → p-86fc0bfa.entry.js} +1 -1
  390. package/dist/pine-core/p-90692bb6.entry.js +1 -0
  391. package/dist/pine-core/{p-2eb8d697.system.entry.js → p-90ea812c.system.entry.js} +1 -1
  392. package/dist/pine-core/p-948826db.entry.js +1 -0
  393. package/dist/pine-core/{p-714bfdbd.entry.js → p-9b66642d.entry.js} +1 -1
  394. package/dist/pine-core/p-BJgZHCWe.js +1 -0
  395. package/dist/pine-core/p-BPqJgIq6.js +1 -0
  396. package/dist/pine-core/p-BSRFZB4I.system.js +1 -0
  397. package/dist/pine-core/p-BZsj6eAn.system.js +1 -0
  398. package/dist/pine-core/p-CB8Yh0Nt.js +2 -0
  399. package/dist/pine-core/{p-B2qvvB3q.system.js → p-CBu9UrXr.system.js} +1 -1
  400. package/dist/pine-core/p-COtCa1Md.system.js +1 -0
  401. package/dist/pine-core/p-CTQZ2fkv.system.js +1 -0
  402. package/dist/pine-core/{p-B2nn1gSd.js → p-CnM3cCof.js} +1 -1
  403. package/dist/pine-core/p-CnO10OxH.system.js +1 -0
  404. package/dist/pine-core/p-D-akEPIU.system.js +2 -0
  405. package/dist/pine-core/p-DHPzKMVS.js +1 -0
  406. package/dist/pine-core/p-Dx8tEj0U.system.js +1 -0
  407. package/dist/pine-core/p-DxI-61GK.js +1 -0
  408. package/dist/pine-core/p-OYK5-nwe.js +1 -0
  409. package/dist/pine-core/p-a10af84b.system.entry.js +1 -0
  410. package/dist/pine-core/p-a21b530a.system.entry.js +1 -0
  411. package/dist/pine-core/p-a85535a4.system.entry.js +1 -0
  412. package/dist/pine-core/p-abc0fe2f.system.entry.js +1 -0
  413. package/dist/pine-core/p-ac6a5bf0.entry.js +1 -0
  414. package/dist/pine-core/{p-f7a5062f.entry.js → p-b0526f98.entry.js} +1 -1
  415. package/dist/pine-core/p-b130b716.entry.js +1 -0
  416. package/dist/pine-core/{p-09413b07.entry.js → p-b195d345.entry.js} +1 -1
  417. package/dist/pine-core/{p-e3600c53.entry.js → p-b4923acf.entry.js} +1 -1
  418. package/dist/pine-core/{p-e410b0d8.system.entry.js → p-b4e440e3.system.entry.js} +1 -1
  419. package/dist/pine-core/p-b8693a87.entry.js +1 -0
  420. package/dist/pine-core/{p-e95225cf.entry.js → p-b8ada1eb.entry.js} +1 -1
  421. package/dist/pine-core/{p-1614c000.system.entry.js → p-bb85bbb5.system.entry.js} +1 -1
  422. package/dist/pine-core/{p-fec298bb.system.entry.js → p-bbc539bc.system.entry.js} +2 -2
  423. package/dist/pine-core/{p-f21aea90.system.entry.js → p-bf833976.system.entry.js} +1 -1
  424. package/dist/pine-core/{p-c5ce6dea.entry.js → p-c23097af.entry.js} +1 -1
  425. package/dist/pine-core/p-c2dd84bd.system.entry.js +1 -0
  426. package/dist/pine-core/{p-869ed1c0.system.entry.js → p-c4520b04.system.entry.js} +1 -1
  427. package/dist/pine-core/{p-3605a5f5.entry.js → p-c4f68dfc.entry.js} +1 -1
  428. package/dist/pine-core/{p-d9ffb2d9.system.entry.js → p-c6fa6744.system.entry.js} +1 -1
  429. package/dist/pine-core/p-c7dba815.entry.js +1 -0
  430. package/dist/pine-core/p-cb6f55ff.entry.js +1 -0
  431. package/dist/pine-core/p-cfb8fa7c.system.entry.js +1 -0
  432. package/dist/pine-core/{p-86bc2a0c.entry.js → p-d0d7d1d4.entry.js} +1 -1
  433. package/dist/pine-core/{p-b109de2e.entry.js → p-d1112c8a.entry.js} +1 -1
  434. package/dist/pine-core/p-d4e91ad9.system.entry.js +1 -0
  435. package/dist/pine-core/{p-7b1e3e91.entry.js → p-da018dcb.entry.js} +1 -1
  436. package/dist/pine-core/{p-c09dab1a.system.entry.js → p-dc27abe6.system.entry.js} +1 -1
  437. package/dist/pine-core/{p-3eca0b00.entry.js → p-dc343b6d.entry.js} +1 -1
  438. package/dist/pine-core/p-dde753e7.system.entry.js +1 -0
  439. package/dist/pine-core/{p-f35596cd.entry.js → p-dea3a582.entry.js} +1 -1
  440. package/dist/pine-core/p-df29fd41.entry.js +1 -0
  441. package/dist/pine-core/{p-1f307e59.system.entry.js → p-e4e2eae2.system.entry.js} +1 -1
  442. package/dist/pine-core/{p-51b8490d.entry.js → p-e8668178.entry.js} +1 -1
  443. package/dist/pine-core/{p-5dd393cd.system.entry.js → p-eb28d21d.system.entry.js} +1 -1
  444. package/dist/pine-core/p-eb71a82d.system.entry.js +1 -0
  445. package/dist/pine-core/{p-8eef80d5.entry.js → p-ed63873c.entry.js} +1 -1
  446. package/dist/pine-core/{p-12182cab.entry.js → p-f4f6dc36.entry.js} +1 -1
  447. package/dist/pine-core/{p-be819bff.system.entry.js → p-f67a0ca8.system.entry.js} +1 -1
  448. package/dist/pine-core/p-fc455968.entry.js +1 -0
  449. package/dist/pine-core/{p-92ef1608.system.entry.js → p-fe3e2ebd.system.entry.js} +1 -1
  450. package/dist/pine-core/pine-core.css +1 -1
  451. package/dist/pine-core/pine-core.esm.js +1 -1
  452. package/dist/pine-core/pine-core.js +1 -1
  453. package/dist/types/components/pds-button/pds-button.d.ts +10 -0
  454. package/dist/types/components/pds-checkbox/pds-checkbox.d.ts +5 -0
  455. package/dist/types/components/pds-chip/pds-chip.d.ts +12 -0
  456. package/dist/types/components/pds-combobox/combobox-interface.d.ts +17 -0
  457. package/dist/types/components/pds-combobox/grouped-options-panel.d.ts +105 -0
  458. package/dist/types/components/pds-combobox/pds-combobox.d.ts +235 -3
  459. package/dist/types/components/pds-datepicker/calendar-portal.d.ts +43 -0
  460. package/dist/types/components/pds-datepicker/date-utils.d.ts +48 -0
  461. package/dist/types/components/pds-datepicker/datepicker-interface.d.ts +30 -0
  462. package/dist/types/components/pds-datepicker/pds-datepicker.d.ts +489 -0
  463. package/dist/types/components/pds-datepicker/presets.d.ts +23 -0
  464. package/dist/types/components/pds-datepicker/value.d.ts +47 -0
  465. package/dist/types/components/pds-dropdown-menu/pds-dropdown-menu.d.ts +1 -0
  466. package/dist/types/components/pds-modal/pds-modal.d.ts +9 -2
  467. package/dist/types/components/pds-multiselect/multiselect-interface.d.ts +19 -0
  468. package/dist/types/components/pds-multiselect/pds-multiselect.d.ts +56 -1
  469. package/dist/types/components/pds-popover/pds-popover.d.ts +1 -0
  470. package/dist/types/components/pds-switch/pds-switch.d.ts +5 -0
  471. package/dist/types/components.d.ts +702 -11
  472. package/dist/types/utils/closest.d.ts +2 -0
  473. package/dist/types/utils/types.d.ts +2 -1
  474. package/dist/types/utils/utils.d.ts +25 -2
  475. package/dist/vscode.html-data.json +497 -7
  476. package/hydrate/index.js +4059 -377
  477. package/hydrate/index.mjs +4059 -377
  478. package/package.json +2 -2
  479. package/dist/cjs/closest-BZXvuB_Y.js +0 -11
  480. package/dist/esm/closest-DnUJodVd.js +0 -9
  481. package/dist/esm-es5/closest-DnUJodVd.js +0 -1
  482. package/dist/esm-es5/floating-ui.dom-DDtwbwIl.js +0 -1
  483. package/dist/esm-es5/index-CTLu1TM4.js +0 -2
  484. package/dist/esm-es5/index-DdPaBxPo.js +0 -1
  485. package/dist/esm-es5/utils-tJa4KYNO.js +0 -1
  486. package/dist/pine-core/p--Llh7wKm.system.js +0 -1
  487. package/dist/pine-core/p-02a47ebb.entry.js +0 -1
  488. package/dist/pine-core/p-12ec8186.system.entry.js +0 -1
  489. package/dist/pine-core/p-17dc3f87.entry.js +0 -1
  490. package/dist/pine-core/p-18a59cdd.system.entry.js +0 -1
  491. package/dist/pine-core/p-2016c878.entry.js +0 -1
  492. package/dist/pine-core/p-222ff58e.system.entry.js +0 -1
  493. package/dist/pine-core/p-324a7ae4.system.entry.js +0 -1
  494. package/dist/pine-core/p-32f10aa9.entry.js +0 -1
  495. package/dist/pine-core/p-33c0f3c9.system.entry.js +0 -1
  496. package/dist/pine-core/p-34e38037.system.entry.js +0 -1
  497. package/dist/pine-core/p-3873f55b.entry.js +0 -1
  498. package/dist/pine-core/p-3aec9079.entry.js +0 -1
  499. package/dist/pine-core/p-3c229a00.system.entry.js +0 -1
  500. package/dist/pine-core/p-43338f77.system.entry.js +0 -1
  501. package/dist/pine-core/p-4661259e.system.entry.js +0 -1
  502. package/dist/pine-core/p-585ad368.system.entry.js +0 -1
  503. package/dist/pine-core/p-5d585aa8.entry.js +0 -1
  504. package/dist/pine-core/p-613a64f1.entry.js +0 -1
  505. package/dist/pine-core/p-630f33d6.system.entry.js +0 -1
  506. package/dist/pine-core/p-63686e2a.system.entry.js +0 -1
  507. package/dist/pine-core/p-6f7a7d55.entry.js +0 -1
  508. package/dist/pine-core/p-6fd863e5.system.entry.js +0 -1
  509. package/dist/pine-core/p-76286a68.system.entry.js +0 -1
  510. package/dist/pine-core/p-7691a875.system.entry.js +0 -3
  511. package/dist/pine-core/p-7e44106e.entry.js +0 -1
  512. package/dist/pine-core/p-84ade640.entry.js +0 -1
  513. package/dist/pine-core/p-8be301b6.entry.js +0 -1
  514. package/dist/pine-core/p-8cc270f0.system.entry.js +0 -1
  515. package/dist/pine-core/p-8cea0d7a.system.entry.js +0 -1
  516. package/dist/pine-core/p-957dbb0c.entry.js +0 -1
  517. package/dist/pine-core/p-BG6uGRQj.system.js +0 -1
  518. package/dist/pine-core/p-BKsJZTyn.js +0 -1
  519. package/dist/pine-core/p-BrLs99ML.system.js +0 -1
  520. package/dist/pine-core/p-CTLu1TM4.js +0 -2
  521. package/dist/pine-core/p-Cr7-rJtJ.system.js +0 -1
  522. package/dist/pine-core/p-DAIsVNlL.system.js +0 -2
  523. package/dist/pine-core/p-DDtwbwIl.js +0 -1
  524. package/dist/pine-core/p-DdPaBxPo.js +0 -1
  525. package/dist/pine-core/p-DnUJodVd.js +0 -1
  526. package/dist/pine-core/p-Dr-FzkdE.system.js +0 -1
  527. package/dist/pine-core/p-a4a58477.entry.js +0 -1
  528. package/dist/pine-core/p-a98bf89f.system.entry.js +0 -1
  529. package/dist/pine-core/p-ac0098fd.entry.js +0 -1
  530. package/dist/pine-core/p-b32e3174.system.entry.js +0 -1
  531. package/dist/pine-core/p-be4a6cc2.entry.js +0 -1
  532. package/dist/pine-core/p-c0b3f2c1.system.entry.js +0 -1
  533. package/dist/pine-core/p-c8bffb08.system.entry.js +0 -1
  534. package/dist/pine-core/p-cf24ed1e.system.entry.js +0 -1
  535. package/dist/pine-core/p-d12ef40d.entry.js +0 -1
  536. package/dist/pine-core/p-d280741f.entry.js +0 -1
  537. package/dist/pine-core/p-d415bb01.entry.js +0 -2
  538. package/dist/pine-core/p-d43db3ba.entry.js +0 -1
  539. package/dist/pine-core/p-db5703f2.entry.js +0 -1
  540. package/dist/pine-core/p-dd6d9807.system.entry.js +0 -1
  541. package/dist/pine-core/p-e0da17aa.system.entry.js +0 -1
  542. package/dist/pine-core/p-ed297f3e.entry.js +0 -1
  543. package/dist/pine-core/p-fbf5f315.entry.js +0 -1
  544. package/dist/pine-core/p-kYMYDfJY.system.js +0 -1
  545. package/dist/pine-core/p-tJa4KYNO.js +0 -1
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-CuQil7H0.js');
3
+ var index = require('./index-Bl5KnQay.js');
4
4
  var form = require('./form-MhwfKTuo.js');
5
- var floatingUi_dom = require('./floating-ui.dom-BZk7Blsu.js');
6
- var utils = require('./utils-7jx8T2mW.js');
5
+ var floatingUi_dom = require('./floating-ui.dom-Dc8Anyel.js');
6
+ var utils = require('./utils-BhRmyxT8.js');
7
7
 
8
8
  /*! @license DOMPurify 3.3.3 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.3.3/LICENSE */
9
9
 
@@ -1391,7 +1391,269 @@ function createDOMPurify() {
1391
1391
  }
1392
1392
  var purify = createDOMPurify();
1393
1393
 
1394
- const pdsComboboxCss = () => `:host{display:block}:host([aria-disabled=true]) .pds-combobox__input-icon{color:var(--pine-color-text-disabled);pointer-events:none}.pds-combobox{position:relative}.pds-combobox__label{color:var(--pine-color-text-label);display:block;font:var(--pine-typography-body-medium);letter-spacing:var(--pine-letter-spacing);-webkit-margin-after:var(--pine-dimension-2xs);margin-block-end:var(--pine-dimension-2xs)}.pds-combobox__input-wrapper{-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;position:relative;width:100%}.pds-combobox__input{background:var(--pine-color-background-container);border:var(--pine-border);border-radius:var(--pine-dimension-125);-webkit-box-sizing:border-box;box-sizing:border-box;color:var(--pine-color-text-strong);-ms-flex:1;flex:1;font:var(--pine-typography-body-medium);padding:var(--pine-dimension-xs) var(--pine-dimension-450) var(--pine-dimension-xs) var(--pine-dimension-150);-webkit-transition:border-color var(--pine-motion-duration-base) ease;transition:border-color var(--pine-motion-duration-base) ease;width:100%}.pds-combobox__input:hover:not(:disabled){border-color:var(--pine-color-border-hover)}.pds-combobox__input:disabled{background:var(--pine-color-background-container-disabled);border-color:var(--pine-color-border-disabled);color:var(--pine-color-text-disabled);cursor:not-allowed}.pds-combobox__input:disabled::-webkit-input-placeholder{color:var(--pine-color-text-placeholder-disabled)}.pds-combobox__input:disabled::-moz-placeholder{color:var(--pine-color-text-placeholder-disabled)}.pds-combobox__input:disabled:-ms-input-placeholder{color:var(--pine-color-text-placeholder-disabled)}.pds-combobox__input:disabled::-ms-input-placeholder{color:var(--pine-color-text-placeholder-disabled)}.pds-combobox__input:disabled::placeholder{color:var(--pine-color-text-placeholder-disabled)}.pds-combobox__input:focus-visible{border-color:var(--pine-color-border-active);outline:var(--pine-outline-focus);outline-offset:var(--pine-border-width)}.pds-combobox__input::-webkit-input-placeholder{color:var(--pine-color-text-placeholder)}.pds-combobox__input::-moz-placeholder{color:var(--pine-color-text-placeholder)}.pds-combobox__input:-ms-input-placeholder{color:var(--pine-color-text-placeholder)}.pds-combobox__input::-ms-input-placeholder{color:var(--pine-color-text-placeholder)}.pds-combobox__input::placeholder{color:var(--pine-color-text-placeholder)}.pds-combobox__input.pds-combobox__input--invalid{background:var(--pine-color-red-050);border-color:var(--pine-color-border-danger)}:host-context([data-theme=dark]) .pds-combobox__input.pds-combobox__input--invalid{background:var(--pine-color-red-950)}.pds-combobox__input.pds-combobox__input--invalid:hover:not(:disabled){border-color:var(--pine-color-border-danger)}.pds-combobox__input.pds-combobox__input--invalid:focus-visible{outline-color:var(--pine-color-focus-ring-danger)}.pds-combobox__input-icon{color:var(--pine-color-text-secondary);inset-inline-end:var(--pine-dimension-150);pointer-events:none;position:absolute;z-index:calc(var(--pine-z-index-raised) - 1)}.pds-combobox__helper{color:var(--pine-color-text-message);font:var(--pine-typography-body-sm-medium);-webkit-margin-before:var(--pine-dimension-2xs);margin-block-start:var(--pine-dimension-2xs)}.pds-combobox__error{-ms-flex-align:start;align-items:flex-start;color:var(--pine-color-text-message-danger);display:-ms-flexbox;display:flex;font:var(--pine-typography-body-sm-medium);gap:var(--pine-dimension-2xs);-webkit-margin-before:var(--pine-dimension-2xs);margin-block-start:var(--pine-dimension-2xs)}.pds-combobox__error pds-icon{-ms-flex-negative:0;flex-shrink:0;-webkit-margin-before:var(--pine-dimension-025);margin-block-start:var(--pine-dimension-025)}.pds-combobox__listbox{background:var(--pine-color-background-overlay);border:0;border-radius:var(--pine-dimension-125);-webkit-box-shadow:var(--pine-box-shadow);box-shadow:var(--pine-box-shadow);list-style:none;margin:0;min-width:220px;overflow-y:auto;padding:var(--pine-dimension-xs);position:absolute;z-index:var(--pine-z-index-raised)}.pds-combobox__option{-ms-flex-align:center;align-items:center;background:transparent;border-radius:var(--pine-dimension-125);color:var(--pine-color-text-secondary);cursor:pointer;display:-ms-flexbox;display:flex;font:var(--pine-typography-body-medium);-ms-flex-pack:justify;justify-content:space-between;padding:var(--pine-dimension-xs) var(--pine-dimension-sm);position:relative;-webkit-transition:background 0.15s;transition:background 0.15s}.pds-combobox__option[aria-selected=true]{background:var(--pine-color-background-muted)}.pds-combobox__option:focus-visible{outline:0}.pds-combobox__option.pds-combobox__option--layout .pds-combobox__option-layout-wrapper{-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;width:100%}.pds-combobox__option.pds-combobox__option--chip .pds-combobox__option-chip{-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;width:100%}.pds-combobox__option:last-child{-webkit-margin-after:0;margin-block-end:0}.pds-combobox__option--highlighted,.pds-combobox__option[selected],.pds-combobox__option--selected{background:var(--pine-color-background-muted)}.pds-combobox__option-check{color:currentColor;font-size:var(--pine-dimension-150);-webkit-margin-start:var(--pine-dimension-150);margin-inline-start:var(--pine-dimension-150)}.pds-combobox__group-label{color:var(--pine-color-text-tertiary);cursor:default;font:var(--pine-typography-heading-caption);-webkit-margin-after:var(--pine-dimension-2xs);margin-block-end:var(--pine-dimension-2xs);-webkit-margin-before:var(--pine-dimension-150);margin-block-start:var(--pine-dimension-150);padding:var(--pine-dimension-2xs) var(--pine-dimension-sm);text-transform:uppercase}.pds-combobox__group-label:first-child{-webkit-margin-before:0;margin-block-start:0}.pds-combobox__loading{-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding:var(--pine-dimension-150)}.pds-combobox__empty{color:var(--pine-color-text-tertiary);padding:var(--pine-dimension-150) var(--pine-dimension-sm);text-align:center}.pds-combobox__load-more{-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding:var(--pine-dimension-150)}.pds-combobox__button-trigger{-ms-flex-align:center;align-items:center;background:var(--color-background-default, var(--pine-color-secondary));border:var(--pine-border);border-radius:var(--pine-border-radius-full);color:var(--color-text-default, var(--pine-color-text-inverse-emphasis));cursor:pointer;display:-ms-flexbox;display:flex;font:var(--pine-typography-body-medium);-ms-flex-pack:justify;justify-content:space-between;min-height:var(--pine-dimension-450);outline:none;padding:0 var(--pine-dimension-sm);-webkit-transition:border-color 0.15s, background 0.15s, -webkit-box-shadow 0.15s;transition:border-color 0.15s, background 0.15s, -webkit-box-shadow 0.15s;transition:border-color 0.15s, box-shadow 0.15s, background 0.15s;transition:border-color 0.15s, box-shadow 0.15s, background 0.15s, -webkit-box-shadow 0.15s;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.pds-combobox__button-trigger .pds-combobox__button-trigger-layout-wrapper{-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;-ms-flex:1;flex:1}.pds-combobox__button-trigger .trigger-content{-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;width:100%}.pds-combobox__button-trigger:focus-visible{border-color:var(--color-border-focus, var(--pine-color-border));-webkit-box-shadow:0 0 0 2px var(--color-outline, var(--pine-color-focus-ring));box-shadow:0 0 0 2px var(--color-outline, var(--pine-color-focus-ring))}.pds-combobox__button-trigger:hover{background:var(--color-background-hover, var(--pine-color-secondary-hover));border-color:var(--color-border-hover, var(--pine-color-border-hover))}.pds-combobox__button-trigger[aria-disabled=true],.pds-combobox__button-trigger:disabled{background:var(--color-background-disabled, var(--pine-color-secondary-disabled));border-color:var(--color-border-disabled, var(--pine-color-border-disabled));color:var(--color-text-disabled, var(--pine-color-text-secondary-disabled));cursor:not-allowed;opacity:0.6}.pds-combobox__button-trigger-label{color:inherit;-ms-flex:1 1 auto;flex:1 1 auto;text-align:start}.pds-combobox__button-trigger--input-shape{border-radius:var(--pine-dimension-125);min-height:var(--pine-dimension-500)}.pds-combobox__button-trigger-chevron{color:currentColor;-webkit-margin-start:var(--pine-dimension-150);margin-inline-start:var(--pine-dimension-150)}.pds-combobox__button-trigger--primary{--color-background-default:var(--pine-color-primary);--color-background-hover:var(--pine-color-primary-hover);--color-background-disabled:var(--pine-color-primary-disabled);--color-border-default:var(--pine-color-primary);--color-border-hover:var(--pine-color-primary-hover);--color-border-disabled:var(--pine-color-primary-disabled);--color-border-focus:var(--pine-color-primary);--color-text-default:var(--pine-color-text-primary);--color-text-disabled:var(--pine-color-text-primary-disabled);--color-outline:var(--pine-color-focus-ring)}.pds-combobox__button-trigger--accent{--color-background-default:var(--pine-color-accent);--color-background-hover:var(--pine-color-accent-hover);--color-background-disabled:var(--pine-color-accent-disabled);--color-border-default:var(--pine-color-accent);--color-border-hover:var(--pine-color-accent-hover);--color-border-disabled:var(--pine-color-accent-disabled);--color-border-focus:var(--pine-color-accent);--color-text-default:var(--pine-color-white);--color-text-disabled:var(--pine-color-text-accent-disabled);--color-outline:var(--pine-color-focus-ring)}.pds-combobox__button-trigger--secondary{--color-background-default:var(--pine-color-secondary);--color-background-hover:var(--pine-color-secondary-hover);--color-background-disabled:var(--pine-color-secondary-disabled);--color-border-default:var(--pine-color-border);--color-border-hover:var(--pine-color-border-hover);--color-border-disabled:var(--pine-color-border-disabled);--color-border-focus:var(--pine-color-border);--color-text-default:var(--pine-color-text-secondary);--color-text-disabled:var(--pine-color-text-secondary-disabled);--color-outline:var(--pine-color-focus-ring)}.pds-combobox__button-trigger--destructive{--color-background-default:var(--pine-color-danger);--color-background-hover:var(--pine-color-danger-hover);--color-background-disabled:var(--pine-color-danger-disabled);--color-border-default:var(--pine-color-danger);--color-border-hover:var(--pine-color-danger-hover);--color-border-disabled:var(--pine-color-danger-disabled);--color-border-focus:var(--pine-color-danger);--color-text-default:var(--pine-color-white);--color-text-disabled:var(--pine-color-text-danger-disabled);--color-outline:var(--pine-color-focus-ring-danger)}.visually-hidden{border:0;clip:rect(0 0 0 0);-webkit-clip-path:polygon(0 0, 0 0, 0 0);clip-path:polygon(0 0, 0 0, 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;white-space:nowrap;width:1px}[data-layout]{border-radius:var(--pine-dimension-125);padding-block:var(--pine-dimension-xs)}.pds-combobox__chip-trigger{-ms-flex-align:center;align-items:center;border-radius:var(--pine-dimension-sm);cursor:pointer;display:-ms-inline-flexbox;display:inline-flex;font:var(--pine-typography-body-medium);-ms-flex-pack:justify;justify-content:space-between;outline:none;padding-block:var(--pine-dimension-025);padding-inline:var(--pine-dimension-150);-webkit-transition:all 0.15s ease;transition:all 0.15s ease;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.pds-combobox__chip-trigger .pds-combobox__chip-trigger-layout-wrapper{-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;-ms-flex:1;flex:1}.pds-combobox__chip-trigger .trigger-content{-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;width:100%}.pds-combobox__chip-trigger:focus-visible{outline:var(--pine-outline-focus);outline-offset:var(--pine-border-width)}.pds-combobox__chip-trigger[aria-disabled=true]{cursor:not-allowed;opacity:0.6}.pds-combobox__chip-trigger-label{color:inherit;-ms-flex:1 1 auto;flex:1 1 auto;text-align:start}.pds-combobox__chip-trigger-chevron{color:currentColor;-webkit-margin-start:var(--pine-dimension-150);margin-inline-start:var(--pine-dimension-150)}.pds-combobox__chip-trigger-icon{-webkit-margin-end:var(--pine-dimension-2xs);margin-inline-end:var(--pine-dimension-2xs)}.pds-combobox__chip-trigger--neutral,.pds-combobox__chip-trigger--accent,.pds-combobox__chip-trigger--success,.pds-combobox__chip-trigger--warning,.pds-combobox__chip-trigger--danger,.pds-combobox__chip-trigger--info{background:var(--chip-bg);border:var(--pine-border-width) solid var(--chip-border);color:var(--chip-text)}.pds-combobox__chip-trigger--neutral:hover:not([aria-disabled=true]),.pds-combobox__chip-trigger--accent:hover:not([aria-disabled=true]),.pds-combobox__chip-trigger--success:hover:not([aria-disabled=true]),.pds-combobox__chip-trigger--warning:hover:not([aria-disabled=true]),.pds-combobox__chip-trigger--danger:hover:not([aria-disabled=true]),.pds-combobox__chip-trigger--info:hover:not([aria-disabled=true]){background:var(--chip-bg-hover)}.pds-combobox__chip-trigger--neutral:focus-visible,.pds-combobox__chip-trigger--accent:focus-visible,.pds-combobox__chip-trigger--success:focus-visible,.pds-combobox__chip-trigger--warning:focus-visible,.pds-combobox__chip-trigger--danger:focus-visible,.pds-combobox__chip-trigger--info:focus-visible{border-color:var(--chip-border)}.pds-combobox__chip-trigger--neutral{--chip-bg:var(--pine-chip-color-neutral);--chip-bg-hover:var(--pine-chip-color-neutral-hover);--chip-border:var(--pine-chip-color-neutral-hover);--chip-text:var(--pine-color-text-neutral)}.pds-combobox__chip-trigger--accent{--chip-bg:var(--pine-chip-color-accent);--chip-bg-hover:var(--pine-chip-color-accent-hover);--chip-border:var(--pine-chip-color-accent-hover);--chip-text:var(--pine-color-text-accent)}.pds-combobox__chip-trigger--success{--chip-bg:var(--pine-chip-color-success);--chip-bg-hover:var(--pine-chip-color-success-hover);--chip-border:var(--pine-chip-color-success-hover);--chip-text:var(--pine-color-text-success)}.pds-combobox__chip-trigger--warning{--chip-bg:var(--pine-chip-color-warning);--chip-bg-hover:var(--pine-chip-color-warning-hover);--chip-border:var(--pine-chip-color-warning-hover);--chip-text:var(--pine-color-text-warning)}.pds-combobox__chip-trigger--danger{--chip-bg:var(--pine-chip-color-danger);--chip-bg-hover:var(--pine-chip-color-danger-hover);--chip-border:var(--pine-chip-color-danger-hover);--chip-text:var(--pine-color-text-danger)}.pds-combobox__chip-trigger--info{--chip-bg:var(--pine-chip-color-info);--chip-bg-hover:var(--pine-chip-color-info-hover);--chip-border:var(--pine-chip-color-info-hover);--chip-text:var(--pine-color-text-info)}.pds-combobox__chip-trigger--brand{background:-webkit-gradient(linear, left top, right top, from(#FF3E14), to(#6B62F2));background:linear-gradient(90deg, #FF3E14 0%, #6B62F2 100%);border:0;color:var(--pine-color-text-neutral);padding:1px;position:relative}.pds-combobox__chip-trigger--brand .pds-combobox__chip-trigger-label{background:rgba(255, 255, 255, 0.9);border-radius:calc(var(--pine-dimension-sm) - 1px);color:var(--pine-color-text-neutral);font-weight:var(--pine-font-weight-medium);padding:var(--pine-dimension-025) var(--pine-dimension-150);position:relative;z-index:1}.pds-combobox__chip-trigger--brand .pds-combobox__chip-trigger-chevron{position:relative;z-index:1}.pds-combobox__chip-trigger--brand:hover:not([aria-disabled=true]) .pds-combobox__chip-trigger-label{background:rgba(255, 255, 255, 0.8)}.pds-combobox__chip-trigger--dropdown:not(.pds-combobox__chip-trigger--brand){padding:var(--pine-dimension-none)}.pds-combobox__chip-trigger--dropdown:not(.pds-combobox__chip-trigger--brand) .pds-combobox__chip-trigger-label{padding:var(--pine-dimension-025) var(--pine-dimension-150)}.pds-combobox__chip-trigger--large .pds-combobox__chip-trigger-label{font-family:var(--pine-font-family-heading);font-size:var(--pine-font-size-heading-6);font-weight:var(--pine-font-weight-medium);letter-spacing:var(--pine-letter-spacing-heading-6)}.pds-combobox__chip-trigger--dot .pds-combobox__chip-trigger-label::before{border:var(--pine-border-width) solid transparent;border-radius:var(--pine-border-radius-full);content:"";display:inline-block;height:var(--pine-dimension-2xs);-webkit-margin-end:var(--pine-dimension-2xs);margin-inline-end:var(--pine-dimension-2xs);width:var(--pine-dimension-2xs)}`;
1394
+ /** The optgroup an option sits in, or null for an ungrouped option. */
1395
+ function parentOptgroupOf(option) {
1396
+ const parent = option === null || option === void 0 ? void 0 : option.parentElement;
1397
+ return parent !== null && parent !== undefined && parent.tagName === 'OPTGROUP' ? parent : null;
1398
+ }
1399
+ /** A Pine icon name: letters, digits and hyphens, such as `hashtag`. Never a URL or file path. */
1400
+ const PINE_ICON_NAME = /^[a-z0-9-]+$/i;
1401
+ /**
1402
+ * An optgroup's `data-icon` when it's a Pine icon name, or null. One definition of a usable group
1403
+ * icon for every mode, checked here rather than trusting `pds-icon` to reject anything else; it is
1404
+ * only ever passed to `pds-icon` as `name`.
1405
+ */
1406
+ function groupIconOf(optgroup) {
1407
+ const icon = optgroup.getAttribute('data-icon');
1408
+ return icon !== null && PINE_ICON_NAME.test(icon) ? icon : null;
1409
+ }
1410
+ /** An option is disabled by its own `disabled` or its optgroup's, as in a native select. */
1411
+ function isOptionDisabled(option) {
1412
+ var _a;
1413
+ if (option === null || option === undefined)
1414
+ return false;
1415
+ return option.hasAttribute('disabled') || ((_a = parentOptgroupOf(option)) === null || _a === void 0 ? void 0 : _a.hasAttribute('disabled')) === true;
1416
+ }
1417
+ /** A group with no option left to choose. It still opens, so its options can be seen. */
1418
+ function isGroupDisabled(group) {
1419
+ return group.options.every(({ option }) => isOptionDisabled(option));
1420
+ }
1421
+ /**
1422
+ * Groups the combobox's filtered items for the panel: each optgroup becomes one entry holding its
1423
+ * options, and ungrouped options stay where they are. Indexes count options in list order, the
1424
+ * same as the inline listbox, so `data-option-index` means the same thing in every mode.
1425
+ */
1426
+ function buildPanelEntries(items) {
1427
+ const entries = [];
1428
+ const groups = new Map();
1429
+ let index = 0;
1430
+ items.forEach(item => {
1431
+ if (item.tagName !== 'OPTION')
1432
+ return;
1433
+ const option = item;
1434
+ const optgroup = parentOptgroupOf(option);
1435
+ if (optgroup !== null) {
1436
+ let group = groups.get(optgroup);
1437
+ if (!group) {
1438
+ group = { optgroup, label: optgroup.label, icon: groupIconOf(optgroup), options: [] };
1439
+ groups.set(optgroup, group);
1440
+ entries.push({ kind: 'group', group });
1441
+ }
1442
+ group.options.push({ option, index: index++ });
1443
+ }
1444
+ else {
1445
+ entries.push({ kind: 'option', option, index: index++ });
1446
+ }
1447
+ });
1448
+ return entries;
1449
+ }
1450
+ /** The label of the optgroup an option sits in, or null for an ungrouped option. */
1451
+ function groupLabelOf(option) {
1452
+ var _a, _b;
1453
+ return (_b = (_a = parentOptgroupOf(option)) === null || _a === void 0 ? void 0 : _a.label) !== null && _b !== void 0 ? _b : null;
1454
+ }
1455
+ /**
1456
+ * The items Up and Down move through from `current`, one tree level at a time: the panel's rows
1457
+ * (groups and ungrouped options), or the open group's options. Drilled into a group, its row
1458
+ * (drawn as the row back) comes first, above its options, as a tree draws a parent above its children.
1459
+ * Disabled options and groups stay in it, as the APG listbox and tree patterns advise, so they're
1460
+ * announced as unavailable rather than hidden from the keyboard.
1461
+ */
1462
+ function panelColumn(entries, openGroup, current, drilledIn) {
1463
+ const open = openGroup === null ? undefined : findGroup(entries, openGroup);
1464
+ if (open !== undefined) {
1465
+ const options = open.options.map(({ index }) => index);
1466
+ if (drilledIn)
1467
+ return [open.optgroup, ...options];
1468
+ if (typeof current === 'number' && options.includes(current))
1469
+ return options;
1470
+ }
1471
+ return entries.map(entry => (entry.kind === 'group' ? entry.group.optgroup : entry.index));
1472
+ }
1473
+ /** The panel's group for an optgroup, if it's showing. */
1474
+ function findGroup(entries, optgroup) {
1475
+ for (const entry of entries) {
1476
+ if (entry.kind === 'group' && entry.group.optgroup === optgroup)
1477
+ return entry.group;
1478
+ }
1479
+ return undefined;
1480
+ }
1481
+ /** Moving from one group row to another waits this long, so a diagonal trip into the flyout doesn't switch groups. */
1482
+ const SWITCH_DELAY_MS = 120;
1483
+ /** Leaving a group (into the gap beside its flyout, say) waits this long before closing it. */
1484
+ const CLOSE_DELAY_MS = 200;
1485
+ /** Space between the panel's edge and the flyout: --pine-dimension-050 (4px), per the Figma frames. */
1486
+ const FLYOUT_GAP_PX = 4;
1487
+ /** How close the flyout may come to the viewport edge: --pine-dimension-100 (8px). */
1488
+ const VIEWPORT_PADDING_PX = 8;
1489
+ /** A flyout never shrinks below roughly three rows, even when little space is left. */
1490
+ const MIN_FLYOUT_HEIGHT_PX = 120;
1491
+ /**
1492
+ * Opens and closes a group's flyout with hover intent, and keeps the open flyout positioned beside
1493
+ * its group row. The flyout renders inside the row, so moving the pointer into it never leaves
1494
+ * the row; the delays cover the gap between panel and flyout and diagonal moves across rows.
1495
+ */
1496
+ /**
1497
+ * Scrolls `el` into view inside `container` only. A flyout option needs this: the flyout is `fixed`
1498
+ * beside the panel but sits inside it in the DOM, so `scrollIntoView` would also scroll the panel
1499
+ * and the page, moving the flyout's row out from under it.
1500
+ */
1501
+ function scrollIntoViewWithin(container, el) {
1502
+ const bounds = container.getBoundingClientRect();
1503
+ const rect = el.getBoundingClientRect();
1504
+ if (rect.top < bounds.top) {
1505
+ container.scrollTop -= bounds.top - rect.top;
1506
+ }
1507
+ else if (rect.bottom > bounds.bottom) {
1508
+ container.scrollTop += rect.bottom - bounds.bottom;
1509
+ }
1510
+ }
1511
+ class FlyoutController {
1512
+ constructor(getOpenGroup, setOpenGroup) {
1513
+ this.getOpenGroup = getOpenGroup;
1514
+ this.setOpenGroup = setOpenGroup;
1515
+ }
1516
+ /** Pointer entered a group row (or its flyout, which sits inside it). */
1517
+ enter(label) {
1518
+ this.clearClose();
1519
+ const open = this.getOpenGroup();
1520
+ if (open === label) {
1521
+ this.clearSwitch();
1522
+ return;
1523
+ }
1524
+ if (open === null) {
1525
+ this.setOpenGroup(label);
1526
+ return;
1527
+ }
1528
+ this.clearSwitch();
1529
+ this.switchTimer = setTimeout(() => {
1530
+ this.switchTimer = undefined;
1531
+ this.setOpenGroup(label);
1532
+ }, SWITCH_DELAY_MS);
1533
+ }
1534
+ /** Pointer left a group row and its flyout. */
1535
+ leave(label) {
1536
+ this.clearSwitch();
1537
+ if (this.getOpenGroup() !== label)
1538
+ return;
1539
+ this.clearClose();
1540
+ this.closeTimer = setTimeout(() => {
1541
+ this.closeTimer = undefined;
1542
+ if (this.getOpenGroup() === label)
1543
+ this.setOpenGroup(null);
1544
+ }, CLOSE_DELAY_MS);
1545
+ }
1546
+ /**
1547
+ * A click or tap on a group row opens it. It never closes it: on desktop the hover that preceded
1548
+ * the click has already opened it, and touch browsers fire an emulated mouseenter and then click
1549
+ * in the same tap. Closing happens on leaving the row or closing the panel.
1550
+ */
1551
+ open(label) {
1552
+ this.clearTimers();
1553
+ this.setOpenGroup(label);
1554
+ }
1555
+ /**
1556
+ * Keeps `flyout` beside `row`: horizontally against the panel's edge, vertically so its first
1557
+ * option lines up with the row. `fixed` positioning so the panel's scrolling can't clip it,
1558
+ * including when the panel is portaled into a dialog.
1559
+ */
1560
+ position(row, panel, flyout) {
1561
+ if (this.positionedFlyout === flyout && this.stopAutoUpdate)
1562
+ return;
1563
+ this.stopPositioning();
1564
+ this.positionedFlyout = flyout;
1565
+ const reference = {
1566
+ getBoundingClientRect: () => {
1567
+ const panelRect = panel.getBoundingClientRect();
1568
+ const rowRect = row.getBoundingClientRect();
1569
+ return {
1570
+ x: panelRect.x,
1571
+ y: rowRect.y,
1572
+ left: panelRect.left,
1573
+ right: panelRect.right,
1574
+ top: rowRect.top,
1575
+ bottom: rowRect.bottom,
1576
+ width: panelRect.width,
1577
+ height: rowRect.height,
1578
+ };
1579
+ },
1580
+ contextElement: row,
1581
+ };
1582
+ // The flyout's own top padding, so its first option, not its edge, lines up with the row.
1583
+ const flyoutPaddingTop = parseFloat(getComputedStyle(flyout).paddingTop) || 0;
1584
+ const update = () => floatingUi_dom.computePosition(reference, flyout, {
1585
+ placement: 'right-start',
1586
+ strategy: 'fixed',
1587
+ middleware: [
1588
+ floatingUi_dom.offset({ mainAxis: FLYOUT_GAP_PX, crossAxis: -flyoutPaddingTop }),
1589
+ floatingUi_dom.flip({ fallbackPlacements: ['left-start'] }),
1590
+ floatingUi_dom.shift({ padding: VIEWPORT_PADDING_PX }),
1591
+ // A long group scrolls inside the flyout instead of running off the viewport.
1592
+ floatingUi_dom.size({
1593
+ padding: VIEWPORT_PADDING_PX,
1594
+ apply({ availableHeight }) {
1595
+ flyout.style.maxHeight = `${Math.max(availableHeight, MIN_FLYOUT_HEIGHT_PX)}px`;
1596
+ },
1597
+ }),
1598
+ // Hidden with its row when the panel scrolls the row out of view.
1599
+ floatingUi_dom.hide({ strategy: 'referenceHidden' }),
1600
+ ],
1601
+ }).then(({ x, y, middlewareData }) => {
1602
+ var _a;
1603
+ // It starts hidden (see the stylesheet) so it never flashes in the row before it's placed.
1604
+ Object.assign(flyout.style, {
1605
+ position: 'fixed',
1606
+ left: `${x}px`,
1607
+ top: `${y}px`,
1608
+ visibility: ((_a = middlewareData.hide) === null || _a === void 0 ? void 0 : _a.referenceHidden) === true ? 'hidden' : 'visible',
1609
+ });
1610
+ const reveal = this.pendingReveal;
1611
+ this.pendingReveal = undefined;
1612
+ if (reveal !== undefined && flyout.contains(reveal))
1613
+ scrollIntoViewWithin(flyout, reveal);
1614
+ });
1615
+ this.stopAutoUpdate = floatingUi_dom.autoUpdate(reference, flyout, () => {
1616
+ void update();
1617
+ });
1618
+ }
1619
+ /**
1620
+ * Scrolls `option` into view inside its flyout. Before the flyout's first placement its height
1621
+ * isn't capped yet, so the option looks visible; it's revealed again once the placement lands.
1622
+ */
1623
+ reveal(flyout, option) {
1624
+ scrollIntoViewWithin(flyout, option);
1625
+ if (flyout.style.maxHeight === '')
1626
+ this.pendingReveal = option;
1627
+ }
1628
+ stopPositioning() {
1629
+ var _a;
1630
+ (_a = this.stopAutoUpdate) === null || _a === void 0 ? void 0 : _a.call(this);
1631
+ this.stopAutoUpdate = undefined;
1632
+ this.positionedFlyout = undefined;
1633
+ this.pendingReveal = undefined;
1634
+ }
1635
+ /** The panel closed or the component left the page. */
1636
+ reset() {
1637
+ this.clearTimers();
1638
+ this.stopPositioning();
1639
+ }
1640
+ clearTimers() {
1641
+ this.clearSwitch();
1642
+ this.clearClose();
1643
+ }
1644
+ clearSwitch() {
1645
+ if (this.switchTimer !== undefined)
1646
+ clearTimeout(this.switchTimer);
1647
+ this.switchTimer = undefined;
1648
+ }
1649
+ clearClose() {
1650
+ if (this.closeTimer !== undefined)
1651
+ clearTimeout(this.closeTimer);
1652
+ this.closeTimer = undefined;
1653
+ }
1654
+ }
1655
+
1656
+ const pdsComboboxCss = () => `:host{display:block}:host([aria-disabled=true]) .pds-combobox__input-icon{color:var(--pine-color-text-disabled);pointer-events:none}.pds-combobox{position:relative}.pds-combobox__label{color:var(--pine-color-text-label);display:block;font:var(--pine-typography-body-medium);letter-spacing:var(--pine-letter-spacing);-webkit-margin-after:var(--pine-dimension-2xs);margin-block-end:var(--pine-dimension-2xs)}.pds-combobox__input-wrapper{-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;position:relative;width:100%}.pds-combobox__input{background:var(--pine-color-background-container);border:var(--pine-border);border-radius:var(--pine-dimension-125);-webkit-box-sizing:border-box;box-sizing:border-box;color:var(--pine-color-text-strong);-ms-flex:1;flex:1;font:var(--pine-typography-body-medium);padding:var(--pine-dimension-xs) var(--pine-dimension-450) var(--pine-dimension-xs) var(--pine-dimension-150);-webkit-transition:border-color var(--pine-motion-duration-base) ease;transition:border-color var(--pine-motion-duration-base) ease;width:100%}.pds-combobox__input:hover:not(:disabled){border-color:var(--pine-color-border-hover)}.pds-combobox__input:disabled{background:var(--pine-color-background-container-disabled);border-color:var(--pine-color-border-disabled);color:var(--pine-color-text-disabled);cursor:not-allowed}.pds-combobox__input:disabled::-webkit-input-placeholder{color:var(--pine-color-text-placeholder-disabled)}.pds-combobox__input:disabled::-moz-placeholder{color:var(--pine-color-text-placeholder-disabled)}.pds-combobox__input:disabled:-ms-input-placeholder{color:var(--pine-color-text-placeholder-disabled)}.pds-combobox__input:disabled::-ms-input-placeholder{color:var(--pine-color-text-placeholder-disabled)}.pds-combobox__input:disabled::placeholder{color:var(--pine-color-text-placeholder-disabled)}.pds-combobox__input:focus-visible{border-color:var(--pine-color-border-active);outline:var(--pine-outline-focus);outline-offset:var(--pine-border-width)}.pds-combobox__input::-webkit-input-placeholder{color:var(--pine-color-text-placeholder)}.pds-combobox__input::-moz-placeholder{color:var(--pine-color-text-placeholder)}.pds-combobox__input:-ms-input-placeholder{color:var(--pine-color-text-placeholder)}.pds-combobox__input::-ms-input-placeholder{color:var(--pine-color-text-placeholder)}.pds-combobox__input::placeholder{color:var(--pine-color-text-placeholder)}.pds-combobox__input.pds-combobox__input--invalid{background:var(--pine-color-red-050);border-color:var(--pine-color-border-danger)}:host-context([data-theme=dark]) .pds-combobox__input.pds-combobox__input--invalid{background:var(--pine-color-red-950)}.pds-combobox__input.pds-combobox__input--invalid:hover:not(:disabled){border-color:var(--pine-color-border-danger)}.pds-combobox__input.pds-combobox__input--invalid:focus-visible{outline-color:var(--pine-color-focus-ring-danger)}.pds-combobox__input-icon{color:var(--pine-color-text-secondary);inset-inline-end:var(--pine-dimension-150);pointer-events:none;position:absolute;z-index:calc(var(--pine-z-index-raised) - 1)}.pds-combobox__helper{color:var(--pine-color-text-message);font:var(--pine-typography-body-sm-medium);-webkit-margin-before:var(--pine-dimension-2xs);margin-block-start:var(--pine-dimension-2xs)}.pds-combobox__error{-ms-flex-align:start;align-items:flex-start;color:var(--pine-color-text-message-danger);display:-ms-flexbox;display:flex;font:var(--pine-typography-body-sm-medium);gap:var(--pine-dimension-2xs);-webkit-margin-before:var(--pine-dimension-2xs);margin-block-start:var(--pine-dimension-2xs)}.pds-combobox__error pds-icon{-ms-flex-negative:0;flex-shrink:0;-webkit-margin-before:var(--pine-dimension-025);margin-block-start:var(--pine-dimension-025)}.pds-combobox__listbox{background:var(--pine-color-background-overlay);border:0;border-radius:var(--pine-dimension-125);-webkit-box-shadow:var(--pine-box-shadow);box-shadow:var(--pine-box-shadow);list-style:none;margin:0;min-width:220px;overflow-y:auto;padding:var(--pine-dimension-xs);position:absolute;z-index:var(--pine-z-index-raised)}.pds-combobox__option{-ms-flex-align:center;align-items:center;background:transparent;border-radius:var(--pine-dimension-125);color:var(--pine-color-text-secondary);cursor:pointer;display:-ms-flexbox;display:flex;font:var(--pine-typography-body-medium);-ms-flex-pack:justify;justify-content:space-between;padding:var(--pine-dimension-xs) var(--pine-dimension-sm);position:relative;-webkit-transition:background 0.15s;transition:background 0.15s}.pds-combobox__option[aria-selected=true]{background:var(--pine-color-background-muted)}.pds-combobox__option:focus-visible{outline:0}.pds-combobox__option.pds-combobox__option--layout .pds-combobox__option-layout-wrapper{-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;width:100%}.pds-combobox__option.pds-combobox__option--chip .pds-combobox__option-chip{-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;width:100%}.pds-combobox__option:last-child{-webkit-margin-after:0;margin-block-end:0}.pds-combobox__option--highlighted,.pds-combobox__option[selected],.pds-combobox__option--selected{background:var(--pine-color-background-muted)}.pds-combobox__option--disabled,.pds-combobox__group-row--disabled>.pds-combobox__group-row-trigger,.pds-combobox__group-back--disabled>.pds-combobox__group-back-trigger,.pds-combobox__group--disabled>.pds-combobox__group-label{color:var(--pine-color-text-disabled)}.pds-combobox__option--disabled{cursor:not-allowed}.pds-combobox__option--disabled .pds-combobox__option-chip,.pds-combobox__option--disabled .pds-combobox__option-layout-wrapper{opacity:0.5}.pds-combobox__option-check{color:currentColor;font-size:var(--pine-dimension-150);-webkit-margin-start:var(--pine-dimension-150);margin-inline-start:var(--pine-dimension-150)}.pds-combobox__group-label{color:var(--pine-color-text-tertiary);cursor:default;font:var(--pine-typography-heading-caption);-webkit-margin-after:var(--pine-dimension-2xs);margin-block-end:var(--pine-dimension-2xs);-webkit-margin-before:var(--pine-dimension-150);margin-block-start:var(--pine-dimension-150);padding:var(--pine-dimension-2xs) var(--pine-dimension-sm);text-transform:uppercase}.pds-combobox__group-label:first-child{-webkit-margin-before:0;margin-block-start:0}.pds-combobox__group{list-style:none;-webkit-margin-before:var(--pine-dimension-150);margin-block-start:var(--pine-dimension-150)}.pds-combobox__group:first-child{-webkit-margin-before:0;margin-block-start:0}.pds-combobox__group-list{list-style:none;margin:0;padding:0}.pds-combobox__listbox--grouped .pds-combobox__group-list{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;gap:var(--pine-dimension-2xs)}.pds-combobox__group-label--with-icon{-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;gap:var(--pine-dimension-xs)}.pds-combobox__group-icon{-ms-flex-negative:0;flex-shrink:0}.pds-combobox__group-row{list-style:none;position:relative}.pds-combobox__group-row-trigger{-ms-flex-align:center;align-items:center;border-radius:var(--pine-dimension-125);color:var(--pine-color-text-secondary);cursor:pointer;display:-ms-flexbox;display:flex;font:var(--pine-typography-body-medium);gap:var(--pine-dimension-xs);-ms-flex-pack:justify;justify-content:space-between;padding:var(--pine-dimension-xs) var(--pine-dimension-sm);-webkit-transition:background 0.15s;transition:background 0.15s}.pds-combobox__group-row--open>.pds-combobox__group-row-trigger,.pds-combobox__group-row--has-selection>.pds-combobox__group-row-trigger,.pds-combobox__group-row--highlighted>.pds-combobox__group-row-trigger,.pds-combobox__group-back--highlighted>.pds-combobox__group-row-trigger,.pds-combobox__group-row-trigger:hover{background:var(--pine-color-background-muted)}.pds-combobox__listbox--drill-in,.pds-combobox__listbox--drill-out{overflow-x:hidden}.pds-combobox__listbox--drill-in>.pds-combobox__group-back{-webkit-animation:pds-combobox-drill-from-end var(--pine-motion-duration-base) var(--pine-motion-easing-out);animation:pds-combobox-drill-from-end var(--pine-motion-duration-base) var(--pine-motion-easing-out)}.pds-combobox__listbox--drill-out>li{-webkit-animation:pds-combobox-drill-from-start var(--pine-motion-duration-base) var(--pine-motion-easing-out);animation:pds-combobox-drill-from-start var(--pine-motion-duration-base) var(--pine-motion-easing-out)}@-webkit-keyframes pds-combobox-drill-from-end{from{opacity:0;-webkit-transform:translateX(var(--pine-dimension-sm));transform:translateX(var(--pine-dimension-sm))}}@keyframes pds-combobox-drill-from-end{from{opacity:0;-webkit-transform:translateX(var(--pine-dimension-sm));transform:translateX(var(--pine-dimension-sm))}}@-webkit-keyframes pds-combobox-drill-from-start{from{opacity:0;-webkit-transform:translateX(calc(var(--pine-dimension-sm) * -1));transform:translateX(calc(var(--pine-dimension-sm) * -1))}}@keyframes pds-combobox-drill-from-start{from{opacity:0;-webkit-transform:translateX(calc(var(--pine-dimension-sm) * -1));transform:translateX(calc(var(--pine-dimension-sm) * -1))}}.pds-combobox__group-row--keyboard>.pds-combobox__group-row-trigger,.pds-combobox__group-back--keyboard>.pds-combobox__group-row-trigger{outline:var(--pine-outline-focus);outline-offset:calc(var(--pine-border-width) * -2)}.pds-combobox__group-row-label{-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;gap:var(--pine-dimension-xs);min-width:0}.pds-combobox__group-row-caret{-ms-flex-negative:0;flex-shrink:0}.pds-combobox__listbox--grouped,.pds-combobox__flyout{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;gap:var(--pine-dimension-2xs);padding:var(--pine-dimension-2xs)}.pds-combobox__flyout{background:var(--pine-color-background-overlay);border-radius:var(--pine-dimension-125);-webkit-box-shadow:var(--pine-box-shadow);box-shadow:var(--pine-box-shadow);list-style:none;margin:0;overflow-y:auto;position:fixed;visibility:hidden;width:-webkit-max-content;width:-moz-max-content;width:max-content;z-index:1}.pds-combobox__listbox--with-search{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;overflow:hidden;padding:0}.pds-combobox__listbox-options{-ms-flex:1;flex:1;list-style:none;margin:0;min-height:0;overflow-y:auto;padding:var(--pine-dimension-xs)}.pds-combobox__listbox-options.pds-combobox__listbox--grouped{padding:var(--pine-dimension-2xs)}.pds-combobox__panel-search{-ms-flex-align:center;align-items:center;-webkit-border-after:var(--pine-border);border-block-end:var(--pine-border);border-block-end-color:var(--pine-color-border-subtle);display:-ms-flexbox;display:flex;-ms-flex-negative:0;flex-shrink:0;gap:var(--pine-dimension-xs);padding:var(--pine-dimension-xs) var(--pine-dimension-sm)}.pds-combobox__panel-search pds-icon{color:var(--pine-color-text-muted);-ms-flex-negative:0;flex-shrink:0}.pds-combobox__panel-search:focus-within{border-block-end-color:var(--pine-color-border-active)}.pds-combobox__panel-search-input{background:transparent;border:0;color:var(--pine-color-text-strong);-ms-flex:1;flex:1;font:var(--pine-typography-body);letter-spacing:var(--pine-letter-spacing);min-width:0;outline:none}.pds-combobox__panel-search-input::-webkit-input-placeholder{color:var(--pine-color-text-placeholder)}.pds-combobox__panel-search-input::-moz-placeholder{color:var(--pine-color-text-placeholder)}.pds-combobox__panel-search-input:-ms-input-placeholder{color:var(--pine-color-text-placeholder)}.pds-combobox__panel-search-input::-ms-input-placeholder{color:var(--pine-color-text-placeholder)}.pds-combobox__panel-search-input::placeholder{color:var(--pine-color-text-placeholder)}.pds-combobox__group-back{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;gap:var(--pine-dimension-2xs);list-style:none}.pds-combobox__group-back-trigger{-ms-flex-pack:start;justify-content:flex-start}.pds-combobox__listbox-options--drilled-in.pds-combobox__listbox--grouped{-webkit-padding-before:0;padding-block-start:0}.pds-combobox__listbox-options--drilled-in:focus{outline:none}.pds-combobox__listbox-options--drilled-in:focus .pds-combobox__group-back-trigger{border-block-end-color:var(--pine-color-border-active)}:where(.pds-combobox__listbox-options--drilled-in) .pds-combobox__group-back-trigger{background-color:var(--pine-color-background-overlay);-webkit-border-after:var(--pine-border);border-block-end:var(--pine-border);border-block-end-color:var(--pine-color-border-subtle);border-radius:0;inset-block-start:0;margin-inline:calc(var(--pine-dimension-2xs) * -1);position:-webkit-sticky;position:sticky;z-index:1}.pds-combobox__drill-in-options{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;gap:var(--pine-dimension-2xs);list-style:none;margin:0;padding:0}.visually-hidden{border:0;clip:rect(0 0 0 0);-webkit-clip-path:polygon(0 0, 0 0, 0 0);clip-path:polygon(0 0, 0 0, 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;white-space:nowrap;width:1px}.pds-combobox__loading{-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding:var(--pine-dimension-150)}.pds-combobox__empty{color:var(--pine-color-text-tertiary);padding:var(--pine-dimension-150) var(--pine-dimension-sm);text-align:center}.pds-combobox__load-more{-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding:var(--pine-dimension-150)}.pds-combobox__button-trigger{-ms-flex-align:center;align-items:center;background:var(--color-background-default, var(--pine-color-secondary));border:var(--pine-border);border-radius:var(--pine-border-radius-full);color:var(--color-text-default, var(--pine-color-text-inverse-emphasis));cursor:pointer;display:-ms-flexbox;display:flex;font:var(--pine-typography-body-medium);-ms-flex-pack:justify;justify-content:space-between;min-height:var(--pine-dimension-450);outline:none;padding:0 var(--pine-dimension-sm);-webkit-transition:border-color 0.15s, background 0.15s, -webkit-box-shadow 0.15s;transition:border-color 0.15s, background 0.15s, -webkit-box-shadow 0.15s;transition:border-color 0.15s, box-shadow 0.15s, background 0.15s;transition:border-color 0.15s, box-shadow 0.15s, background 0.15s, -webkit-box-shadow 0.15s;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.pds-combobox__button-trigger .pds-combobox__button-trigger-layout-wrapper{-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;-ms-flex:1;flex:1}.pds-combobox__button-trigger .trigger-content{-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;width:100%}.pds-combobox__button-trigger:focus-visible{border-color:var(--color-border-focus, var(--pine-color-border));-webkit-box-shadow:0 0 0 2px var(--color-outline, var(--pine-color-focus-ring));box-shadow:0 0 0 2px var(--color-outline, var(--pine-color-focus-ring))}.pds-combobox__button-trigger:hover{background:var(--color-background-hover, var(--pine-color-secondary-hover));border-color:var(--color-border-hover, var(--pine-color-border-hover))}.pds-combobox__button-trigger[aria-disabled=true],.pds-combobox__button-trigger:disabled{background:var(--color-background-disabled, var(--pine-color-secondary-disabled));border-color:var(--color-border-disabled, var(--pine-color-border-disabled));color:var(--color-text-disabled, var(--pine-color-text-secondary-disabled));cursor:not-allowed;opacity:0.6}.pds-combobox__button-trigger-label{color:inherit;-ms-flex:1 1 auto;flex:1 1 auto;text-align:start}.pds-combobox__button-trigger--input-shape{border-radius:var(--pine-dimension-125);min-height:var(--pine-dimension-500)}.pds-combobox__button-trigger-chevron{color:currentColor;-webkit-margin-start:var(--pine-dimension-150);margin-inline-start:var(--pine-dimension-150)}.pds-combobox__button-trigger--primary{--color-background-default:var(--pine-color-primary);--color-background-hover:var(--pine-color-primary-hover);--color-background-disabled:var(--pine-color-primary-disabled);--color-border-default:var(--pine-color-primary);--color-border-hover:var(--pine-color-primary-hover);--color-border-disabled:var(--pine-color-primary-disabled);--color-border-focus:var(--pine-color-primary);--color-text-default:var(--pine-color-text-primary);--color-text-disabled:var(--pine-color-text-primary-disabled);--color-outline:var(--pine-color-focus-ring)}.pds-combobox__button-trigger--accent{--color-background-default:var(--pine-color-accent);--color-background-hover:var(--pine-color-accent-hover);--color-background-disabled:var(--pine-color-accent-disabled);--color-border-default:var(--pine-color-accent);--color-border-hover:var(--pine-color-accent-hover);--color-border-disabled:var(--pine-color-accent-disabled);--color-border-focus:var(--pine-color-accent);--color-text-default:var(--pine-color-text-primary);--color-text-disabled:var(--pine-color-text-accent-disabled);--color-outline:var(--pine-color-focus-ring)}.pds-combobox__button-trigger--secondary{--color-background-default:var(--pine-color-secondary);--color-background-hover:var(--pine-color-secondary-hover);--color-background-disabled:var(--pine-color-secondary-disabled);--color-border-default:var(--pine-color-border);--color-border-hover:var(--pine-color-border-hover);--color-border-disabled:var(--pine-color-border-disabled);--color-border-focus:var(--pine-color-border);--color-text-default:var(--pine-color-text-secondary);--color-text-disabled:var(--pine-color-text-secondary-disabled);--color-outline:var(--pine-color-focus-ring)}.pds-combobox__button-trigger--destructive{--color-background-default:var(--pine-color-danger);--color-background-hover:var(--pine-color-danger-hover);--color-background-disabled:var(--pine-color-danger-disabled);--color-border-default:var(--pine-color-danger);--color-border-hover:var(--pine-color-danger-hover);--color-border-disabled:var(--pine-color-danger-disabled);--color-border-focus:var(--pine-color-danger);--color-text-default:var(--pine-color-white);--color-text-disabled:var(--pine-color-text-danger-disabled);--color-outline:var(--pine-color-focus-ring-danger)}[data-layout]{border-radius:var(--pine-dimension-125);padding-block:var(--pine-dimension-xs)}.pds-combobox__chip-trigger{-ms-flex-align:center;align-items:center;border-radius:var(--pine-dimension-sm);cursor:pointer;display:-ms-inline-flexbox;display:inline-flex;font:var(--pine-typography-body-medium);-ms-flex-pack:justify;justify-content:space-between;outline:none;padding-block:var(--pine-dimension-025);padding-inline:var(--pine-dimension-150);-webkit-transition:all 0.15s ease;transition:all 0.15s ease;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.pds-combobox__chip-trigger .pds-combobox__chip-trigger-layout-wrapper{-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;-ms-flex:1;flex:1}.pds-combobox__chip-trigger .trigger-content{-ms-flex-align:center;align-items:center;display:-ms-flexbox;display:flex;width:100%}.pds-combobox__chip-trigger:focus-visible{outline:var(--pine-outline-focus);outline-offset:var(--pine-border-width)}.pds-combobox__chip-trigger[aria-disabled=true]{cursor:not-allowed;opacity:0.6}.pds-combobox__chip-trigger-label{color:inherit;-ms-flex:1 1 auto;flex:1 1 auto;text-align:start}.pds-combobox__chip-trigger-chevron{color:currentColor;-webkit-margin-start:var(--pine-dimension-150);margin-inline-start:var(--pine-dimension-150)}.pds-combobox__chip-trigger-icon{-webkit-margin-end:var(--pine-dimension-2xs);margin-inline-end:var(--pine-dimension-2xs)}.pds-combobox__chip-trigger--neutral,.pds-combobox__chip-trigger--accent,.pds-combobox__chip-trigger--success,.pds-combobox__chip-trigger--warning,.pds-combobox__chip-trigger--danger,.pds-combobox__chip-trigger--info{background:var(--chip-bg);border:var(--pine-border-width) solid var(--chip-border);color:var(--chip-text)}.pds-combobox__chip-trigger--neutral:hover:not([aria-disabled=true]),.pds-combobox__chip-trigger--accent:hover:not([aria-disabled=true]),.pds-combobox__chip-trigger--success:hover:not([aria-disabled=true]),.pds-combobox__chip-trigger--warning:hover:not([aria-disabled=true]),.pds-combobox__chip-trigger--danger:hover:not([aria-disabled=true]),.pds-combobox__chip-trigger--info:hover:not([aria-disabled=true]){background:var(--chip-bg-hover)}.pds-combobox__chip-trigger--neutral:focus-visible,.pds-combobox__chip-trigger--accent:focus-visible,.pds-combobox__chip-trigger--success:focus-visible,.pds-combobox__chip-trigger--warning:focus-visible,.pds-combobox__chip-trigger--danger:focus-visible,.pds-combobox__chip-trigger--info:focus-visible{border-color:var(--chip-border)}.pds-combobox__chip-trigger--neutral{--chip-bg:var(--pine-chip-color-neutral);--chip-bg-hover:var(--pine-chip-color-neutral-hover);--chip-border:var(--pine-chip-color-neutral-hover);--chip-text:var(--pine-color-text-neutral)}.pds-combobox__chip-trigger--accent{--chip-bg:var(--pine-chip-color-accent);--chip-bg-hover:var(--pine-chip-color-accent-hover);--chip-border:var(--pine-chip-color-accent-hover);--chip-text:var(--pine-color-text-accent)}.pds-combobox__chip-trigger--success{--chip-bg:var(--pine-chip-color-success);--chip-bg-hover:var(--pine-chip-color-success-hover);--chip-border:var(--pine-chip-color-success-hover);--chip-text:var(--pine-color-text-success)}.pds-combobox__chip-trigger--warning{--chip-bg:var(--pine-chip-color-warning);--chip-bg-hover:var(--pine-chip-color-warning-hover);--chip-border:var(--pine-chip-color-warning-hover);--chip-text:var(--pine-color-text-warning)}.pds-combobox__chip-trigger--danger{--chip-bg:var(--pine-chip-color-danger);--chip-bg-hover:var(--pine-chip-color-danger-hover);--chip-border:var(--pine-chip-color-danger-hover);--chip-text:var(--pine-color-text-danger)}.pds-combobox__chip-trigger--info{--chip-bg:var(--pine-chip-color-info);--chip-bg-hover:var(--pine-chip-color-info-hover);--chip-border:var(--pine-chip-color-info-hover);--chip-text:var(--pine-color-text-info)}.pds-combobox__chip-trigger--brand{background:-webkit-gradient(linear, left top, right top, from(#FF3E14), to(#6B62F2));background:linear-gradient(90deg, #FF3E14 0%, #6B62F2 100%);border:0;color:var(--pine-color-text-neutral);padding:1px;position:relative}.pds-combobox__chip-trigger--brand .pds-combobox__chip-trigger-label{background:rgba(255, 255, 255, 0.9);border-radius:calc(var(--pine-dimension-sm) - 1px);color:var(--pine-color-text-neutral);font-weight:var(--pine-font-weight-medium);padding:var(--pine-dimension-025) var(--pine-dimension-150);position:relative;z-index:1}.pds-combobox__chip-trigger--brand .pds-combobox__chip-trigger-chevron{position:relative;z-index:1}.pds-combobox__chip-trigger--brand:hover:not([aria-disabled=true]) .pds-combobox__chip-trigger-label{background:rgba(255, 255, 255, 0.8)}.pds-combobox__chip-trigger--dropdown:not(.pds-combobox__chip-trigger--brand){padding:var(--pine-dimension-none)}.pds-combobox__chip-trigger--dropdown:not(.pds-combobox__chip-trigger--brand) .pds-combobox__chip-trigger-label{padding:var(--pine-dimension-025) var(--pine-dimension-150)}.pds-combobox__chip-trigger--large .pds-combobox__chip-trigger-label{font-family:var(--pine-font-family-heading);font-size:var(--pine-font-size-heading-6);font-weight:var(--pine-font-weight-medium);letter-spacing:var(--pine-letter-spacing-heading-6)}.pds-combobox__chip-trigger--dot .pds-combobox__chip-trigger-label::before{border:var(--pine-border-width) solid transparent;border-radius:var(--pine-border-radius-full);content:"";display:inline-block;height:var(--pine-dimension-2xs);-webkit-margin-end:var(--pine-dimension-2xs);margin-inline-end:var(--pine-dimension-2xs);width:var(--pine-dimension-2xs)}`;
1395
1657
 
1396
1658
  const PdsCombobox = class {
1397
1659
  constructor(hostRef) {
@@ -1438,6 +1700,35 @@ const PdsCombobox = class {
1438
1700
  * @default 'host'
1439
1701
  */
1440
1702
  this.dropdownMount = 'host';
1703
+ /**
1704
+ * Accessible prefix for the row that returns to the group list when `group-display` is
1705
+ * `drill-in`, read before the open group's label. Pass a translated string to localize it; defaults to English.
1706
+ * @defaultValue 'Back'
1707
+ */
1708
+ this.drillInBackLabel = 'Back';
1709
+ /**
1710
+ * Maximum width of a group's flyout when `group-display` is `flyout`. Any valid CSS width value.
1711
+ * @default '380px'
1712
+ */
1713
+ this.flyoutMaxWidth = '380px';
1714
+ /**
1715
+ * Minimum width of a group's flyout when `group-display` is `flyout`. Any valid CSS width value.
1716
+ * The flyout is as wide as its options, between this and `flyout-max-width`.
1717
+ * @default '280px'
1718
+ */
1719
+ this.flyoutMinWidth = '280px';
1720
+ /**
1721
+ * How option groups (`<optgroup>`, or the `group` field of `options`) are shown in the dropdown.
1722
+ * `inline` lists each group's label above its options. `flyout` lists the groups, and opens a
1723
+ * group's options in a panel beside it on hover or click; while searching, the matching options
1724
+ * are listed under their group labels, and search also matches group labels. `flyout` groups
1725
+ * by `<optgroup>` (or `group`) only: options under a `<pds-text>` heading are listed ungrouped.
1726
+ * `drill-in` lists the groups too, but a click replaces the list with that group's options and a
1727
+ * row back to the groups; use it where nothing can open beside the dropdown, such as a side
1728
+ * panel. `flyout` falls back to `drill-in` when there is no room for a flyout on either side.
1729
+ * @default 'inline'
1730
+ */
1731
+ this.groupDisplay = 'inline';
1441
1732
  /**
1442
1733
  * Visually hides the label text for instances where only the combobox should be displayed.
1443
1734
  * The visible `<label>` is omitted (same pattern as `pds-select`) so label spacing does not reserve layout;
@@ -1451,6 +1742,23 @@ const PdsCombobox = class {
1451
1742
  * @default 'filter'
1452
1743
  */
1453
1744
  this.mode = 'filter';
1745
+ /**
1746
+ * Shows a search field at the top of the dropdown for the `button` and `chip` triggers, which
1747
+ * can't be typed into. Search filters the options the same way typing in the `input` trigger
1748
+ * does; in a grouped display it also matches group labels.
1749
+ * @default false
1750
+ */
1751
+ this.panelSearch = false;
1752
+ /**
1753
+ * Accessible label for the search input inside the dropdown panel (`panel-search`). Pass a translated string to localize it; defaults to English.
1754
+ * @defaultValue 'Search options'
1755
+ */
1756
+ this.searchOptionsLabel = 'Search options';
1757
+ /**
1758
+ * Placeholder text for the search input inside the dropdown panel (`panel-search`). Pass a translated string to localize it; defaults to English.
1759
+ * @defaultValue 'Find...'
1760
+ */
1761
+ this.searchPlaceholder = 'Find...';
1454
1762
  /**
1455
1763
  * Determines the combobox trigger: 'input' (editable input), 'button' (button-like, non-editable), or 'chip' (chip-like, non-editable).
1456
1764
  * @default 'input'
@@ -1523,6 +1831,30 @@ const PdsCombobox = class {
1523
1831
  * Internal state for dropdown open/close
1524
1832
  */
1525
1833
  this.isOpen = false;
1834
+ /**
1835
+ * The optgroup whose flyout is open, when `groupDisplay` is `flyout`.
1836
+ */
1837
+ this.openGroup = null;
1838
+ /**
1839
+ * Which way drill-in just moved, so the list slides that way: `in` to a group, `out` back to the
1840
+ * groups. Cleared once the slide ends, so later renders don't animate.
1841
+ */
1842
+ this.drillDirection = null;
1843
+ /**
1844
+ * The group row highlighted in the grouped panel. It counts only while no option is
1845
+ * highlighted (`highlightedIndex` is -1); see `highlightedGroupRow`.
1846
+ */
1847
+ this.highlightedGroup = null;
1848
+ /** The keys, not the pointer, moved the highlight last; the focus ring shows only then. */
1849
+ this.keyboardNavigating = false;
1850
+ /**
1851
+ * What's typed in the dropdown's own search field (`panelSearch`).
1852
+ */
1853
+ this.panelQuery = '';
1854
+ /**
1855
+ * `groupDisplay` is `flyout` but there's no room beside the dropdown, so groups drill in instead.
1856
+ */
1857
+ this.flyoutFallback = false;
1526
1858
  /**
1527
1859
  * Internal state for the currently selected option
1528
1860
  */
@@ -1552,12 +1884,39 @@ const PdsCombobox = class {
1552
1884
  this.portalEl = null;
1553
1885
  this.bodyPortalAutoUpdateActive = false;
1554
1886
  this.isUpdatingFromSelection = false;
1887
+ this.flyout = new FlyoutController(() => this.openGroup, group => {
1888
+ this.openGroup = group;
1889
+ });
1890
+ /** The groups in the flyout panel's last render, so a row's index finds its optgroup. */
1891
+ this.renderedGroups = [];
1892
+ /** Room for a flyout was checked for this open. */
1893
+ this.flyoutRoomChecked = false;
1894
+ /** The highlighted option sits in a flyout that hasn't rendered yet; focus it after the next render. */
1895
+ this.pendingOptionFocus = false;
1896
+ /** Group rows' DOM ids, stable across renders so `aria-activedescendant` can point at a row. */
1897
+ this.groupIds = new WeakMap();
1898
+ this.groupIdCount = 0;
1555
1899
  /**
1556
1900
  * In filter mode, after choosing an option the input still shows the label and would
1557
1901
  * otherwise filter the list to matching substrings only. While this flag is true,
1558
1902
  * the list shows every option until the user types (then normal filtering applies).
1559
1903
  */
1560
1904
  this.expandFilterListWhileOpen = false;
1905
+ this.onDrillAnimationEnd = (event) => {
1906
+ var _a;
1907
+ // Only the slide's own end: slotted consumer content can animate inside the list too.
1908
+ if ((_a = event.animationName) === null || _a === void 0 ? void 0 : _a.startsWith('pds-combobox-drill'))
1909
+ this.drillDirection = null;
1910
+ };
1911
+ /** `<label for>` only works on the input trigger; for a div trigger a click on the label focuses it. */
1912
+ this.onLabelClick = () => {
1913
+ var _a;
1914
+ if (this.trigger !== 'input' && !this.disabled) {
1915
+ (_a = this.triggerEl) === null || _a === void 0 ? void 0 : _a.focus();
1916
+ }
1917
+ };
1918
+ /** The query behind the options loaded from `async-url`. */
1919
+ this.lastFetchedQuery = '';
1561
1920
  this.handleInput = (e) => {
1562
1921
  const target = e.target;
1563
1922
  this.clearExpandFilterList();
@@ -1594,6 +1953,7 @@ const PdsCombobox = class {
1594
1953
  this.handleKeyDown = (e) => {
1595
1954
  if (!this.isOpen && (e.key === 'ArrowDown' || e.key === 'ArrowUp' || (e.altKey && e.key === 'ArrowDown'))) {
1596
1955
  e.preventDefault();
1956
+ this.keyboardNavigating = true;
1597
1957
  this.isOpen = true;
1598
1958
  this.prepareExpandFilterListOnOpen();
1599
1959
  this.filterOptions();
@@ -1615,75 +1975,53 @@ const PdsCombobox = class {
1615
1975
  if (!this.isOpen) {
1616
1976
  return;
1617
1977
  }
1978
+ if (this.handleGroupedPanelKey(e))
1979
+ return;
1980
+ // The input trigger's text keeps Space, Home and End while the grouped panel shows.
1981
+ if (this.showsGroupedPanel && this.trigger === 'input' && (e.key === ' ' || e.key === 'Home' || e.key === 'End'))
1982
+ return;
1618
1983
  // Get only the option elements (skip group labels) for navigation
1619
1984
  const selectableOptions = this.filteredItems.filter(item => item.tagName === 'OPTION');
1620
1985
  switch (e.key) {
1621
1986
  case 'ArrowDown':
1622
1987
  e.preventDefault();
1623
- // If no option is highlighted and we have options, start at 0
1624
- if (this.highlightedIndex < 0 && selectableOptions.length > 0) {
1625
- this.highlightedIndex = 0;
1626
- }
1627
- else {
1628
- this.highlightedIndex = Math.min(this.highlightedIndex + 1, selectableOptions.length - 1);
1629
- }
1630
- this.updateOptionFocus();
1988
+ // If no option is highlighted, start at the first
1989
+ this.highlightOptionAt(selectableOptions, this.highlightedIndex < 0 ? 0 : this.highlightedIndex + 1);
1631
1990
  break;
1632
1991
  case 'ArrowUp':
1633
1992
  e.preventDefault();
1634
- // If no option is highlighted and we have options, start at last option
1635
- if (this.highlightedIndex < 0 && selectableOptions.length > 0) {
1636
- this.highlightedIndex = selectableOptions.length - 1;
1637
- }
1638
- else {
1639
- this.highlightedIndex = Math.max(this.highlightedIndex - 1, 0);
1640
- }
1641
- this.updateOptionFocus();
1993
+ // If no option is highlighted, start at the last
1994
+ this.highlightOptionAt(selectableOptions, this.highlightedIndex < 0 ? selectableOptions.length - 1 : this.highlightedIndex - 1);
1642
1995
  break;
1643
1996
  case 'Home':
1644
1997
  e.preventDefault();
1645
- if (selectableOptions.length > 0) {
1646
- this.highlightedIndex = 0;
1647
- this.updateOptionFocus();
1648
- }
1998
+ this.highlightOptionAt(selectableOptions, 0);
1649
1999
  break;
1650
2000
  case 'End':
1651
2001
  e.preventDefault();
1652
- if (selectableOptions.length > 0) {
1653
- this.highlightedIndex = selectableOptions.length - 1;
1654
- this.updateOptionFocus();
1655
- }
2002
+ this.highlightOptionAt(selectableOptions, selectableOptions.length - 1);
1656
2003
  break;
1657
2004
  case 'PageDown':
1658
2005
  e.preventDefault();
1659
- if (selectableOptions.length > 0) {
1660
- const nextIndex = Math.min(this.highlightedIndex + 10, selectableOptions.length - 1);
1661
- this.highlightedIndex = nextIndex;
1662
- this.updateOptionFocus();
1663
- }
2006
+ this.highlightOptionAt(selectableOptions, this.highlightedIndex + 10);
1664
2007
  break;
1665
2008
  case 'PageUp':
1666
2009
  e.preventDefault();
1667
- if (selectableOptions.length > 0) {
1668
- const prevIndex = Math.max(this.highlightedIndex - 10, 0);
1669
- this.highlightedIndex = prevIndex;
1670
- this.updateOptionFocus();
1671
- }
2010
+ this.highlightOptionAt(selectableOptions, this.highlightedIndex - 10);
1672
2011
  break;
1673
2012
  case 'Enter':
2013
+ case ' ': {
1674
2014
  e.preventDefault();
1675
- if (this.highlightedIndex >= 0 && this.highlightedIndex < selectableOptions.length) {
1676
- this.handleOptionClick(selectableOptions[this.highlightedIndex]);
1677
- this.restoreFocusToTrigger();
1678
- }
1679
- break;
1680
- case ' ':
1681
- e.preventDefault();
1682
- if (this.highlightedIndex >= 0 && this.highlightedIndex < selectableOptions.length) {
1683
- this.handleOptionClick(selectableOptions[this.highlightedIndex]);
2015
+ // An option in a flyout the pointer has since closed isn't on screen; don't choose it.
2016
+ if (this.showsGroupedPanel && this.activeDescendantId === undefined)
2017
+ break;
2018
+ const option = selectableOptions[this.highlightedIndex];
2019
+ if (option !== undefined && !isOptionDisabled(option)) {
2020
+ this.handleOptionClick(option);
1684
2021
  this.restoreFocusToTrigger();
1685
2022
  }
1686
2023
  break;
2024
+ }
1687
2025
  case 'Escape':
1688
2026
  e.preventDefault();
1689
2027
  this.isOpen = false;
@@ -1708,12 +2046,53 @@ const PdsCombobox = class {
1708
2046
  const idx = Number(event.currentTarget.getAttribute('data-option-index'));
1709
2047
  const selectableOptions = this.filteredItems.filter(item => item.tagName === 'OPTION');
1710
2048
  const option = selectableOptions[idx];
2049
+ if (isOptionDisabled(option))
2050
+ return;
1711
2051
  this.handleOptionClick(option);
2052
+ // The search field closes with the panel; send focus back to the trigger instead of losing it.
2053
+ // (Enter and Space already restore focus in the key handler.)
2054
+ if (this.usesPanelSearch)
2055
+ this.restoreFocusToTrigger();
1712
2056
  };
1713
2057
  // Event handler for mouse enter on option
1714
2058
  this.onOptionMouseEnter = (event) => {
1715
2059
  const idx = Number(event.currentTarget.getAttribute('data-option-index'));
1716
2060
  this.highlightedIndex = idx;
2061
+ this.keyboardNavigating = false;
2062
+ };
2063
+ this.onGroupRowMouseEnter = (event) => {
2064
+ const group = this.groupFromEvent(event);
2065
+ if (group !== null)
2066
+ this.flyout.enter(group);
2067
+ };
2068
+ this.onGroupRowMouseLeave = (event) => {
2069
+ const group = this.groupFromEvent(event);
2070
+ if (group !== null)
2071
+ this.flyout.leave(group);
2072
+ };
2073
+ // The pointer highlights a group's row as it does an option, so the keys carry on from there.
2074
+ this.onGroupRowTriggerMouseEnter = (event) => {
2075
+ const group = this.groupFromEvent(event);
2076
+ if (group !== null)
2077
+ this.highlightGroupRowByPointer(group);
2078
+ };
2079
+ this.onGroupBackMouseEnter = () => {
2080
+ if (this.openGroup !== null)
2081
+ this.highlightGroupRowByPointer(this.openGroup);
2082
+ };
2083
+ this.onGroupRowClick = (event) => {
2084
+ var _a;
2085
+ const group = this.groupFromEvent(event);
2086
+ if (group === null)
2087
+ return;
2088
+ this.flyout.open(group);
2089
+ // Highlight the group's first option, so the arrow keys carry on from the group just opened
2090
+ // rather than from wherever the highlight was before.
2091
+ const first = (_a = this.renderedGroups.find(entry => entry.optgroup === group)) === null || _a === void 0 ? void 0 : _a.options[0];
2092
+ if (first !== undefined) {
2093
+ this.highlightedIndex = first.index;
2094
+ this.updateAriaActiveDescendant();
2095
+ }
1717
2096
  };
1718
2097
  // Prevent blur on mousedown
1719
2098
  this.onOptionMouseDown = (event) => {
@@ -1730,10 +2109,7 @@ const PdsCombobox = class {
1730
2109
  if (this.isOpen) {
1731
2110
  this.prepareExpandFilterListOnOpen();
1732
2111
  this.filterOptions();
1733
- // Trigger initial fetch if async and no options loaded yet
1734
- if (this.asyncUrl && this.internalOptions.length === 0) {
1735
- this.debouncedFetchAsyncOptions(this.displayText, 1);
1736
- }
2112
+ this.fetchAsyncOptionsOnOpen();
1737
2113
  // Set highlighted index and prepare for keyboard navigation
1738
2114
  this.setInitialHighlightedIndex();
1739
2115
  // For button trigger, prepare for arrow-key navigation mode
@@ -1748,12 +2124,17 @@ const PdsCombobox = class {
1748
2124
  };
1749
2125
  // Handler for button trigger keyboard events
1750
2126
  this.onButtonTriggerKeyDown = (e) => {
2127
+ // Escape closes an open group before the dropdown. Other keys reach the tree through handleKeyDown.
2128
+ if (this.isOpen && e.key === 'Escape' && this.handleGroupedPanelKey(e))
2129
+ return;
1751
2130
  if ((e.key === 'Enter' || e.key === ' ' || e.key === 'ArrowDown' || e.key === 'ArrowUp') && !this.isOpen) {
1752
2131
  e.preventDefault();
1753
2132
  e.stopPropagation(); // Prevent the event from bubbling and triggering click
2133
+ this.keyboardNavigating = true;
1754
2134
  this.isOpen = true;
1755
2135
  this.prepareExpandFilterListOnOpen();
1756
2136
  this.filterOptions();
2137
+ this.fetchAsyncOptionsOnOpen();
1757
2138
  // Set highlighted index immediately
1758
2139
  this.setInitialHighlightedIndex();
1759
2140
  setTimeout(() => {
@@ -1786,11 +2167,13 @@ const PdsCombobox = class {
1786
2167
  };
1787
2168
  // Close dropdown when focus leaves the combobox
1788
2169
  this.onComboboxFocusOut = (event) => {
1789
- var _a, _b;
2170
+ var _a, _b, _c;
1790
2171
  const relatedTarget = event.relatedTarget;
1791
2172
  const isRelatedTargetInListbox = relatedTarget &&
1792
2173
  (((_a = this.listboxEl) === null || _a === void 0 ? void 0 : _a.contains(relatedTarget)) || ((_b = this.portalEl) === null || _b === void 0 ? void 0 : _b.contains(relatedTarget)));
1793
- const isRelatedTargetInCombobox = this.el.contains(relatedTarget);
2174
+ // `contains` doesn't cross into the shadow root, where the trigger lives; with panel search,
2175
+ // focus leaves the search field for the trigger whenever it's clicked to close.
2176
+ const isRelatedTargetInCombobox = relatedTarget !== null && (this.el.contains(relatedTarget) || !!((_c = this.el.shadowRoot) === null || _c === void 0 ? void 0 : _c.contains(relatedTarget)));
1794
2177
  // Don't close if focus is moving to an option in the listbox or staying within the combobox
1795
2178
  if (!isRelatedTargetInCombobox && !isRelatedTargetInListbox) {
1796
2179
  this.isOpen = false;
@@ -1813,11 +2196,58 @@ const PdsCombobox = class {
1813
2196
  // Load more when near bottom (within 50px)
1814
2197
  if (scrollBottom < 50) {
1815
2198
  this.pdsComboboxLoadOptions.emit({
1816
- query: this.displayText,
2199
+ query: this.activeQuery,
1817
2200
  page: this.currentPage + 1,
1818
2201
  });
1819
- this.debouncedFetchAsyncOptions(this.displayText, this.currentPage + 1);
2202
+ this.debouncedFetchAsyncOptions(this.activeQuery, this.currentPage + 1);
2203
+ }
2204
+ };
2205
+ // A press on the panel's padding, captions or status rows keeps focus in the search field;
2206
+ // otherwise it would blur the field, closing a portaled panel or stranding the keys.
2207
+ this.onPanelMouseDown = (event) => {
2208
+ if (event.target !== this.panelSearchEl)
2209
+ event.preventDefault();
2210
+ };
2211
+ this.onPanelSearchInput = (event) => {
2212
+ this.setPanelQuery(event.target.value);
2213
+ };
2214
+ // Space, Home and End edit the search text rather than moving through the options.
2215
+ this.onPanelSearchKeyDown = (event) => {
2216
+ if (event.key === ' ' || event.key === 'Home' || event.key === 'End')
2217
+ return;
2218
+ if (this.handlePanelTab(event))
2219
+ return;
2220
+ this.handleKeyDown(event);
2221
+ };
2222
+ /**
2223
+ * Keys in the list while a drilled-in group hides the search field. Backspace, like ArrowLeft,
2224
+ * steps back to the groups; a character starts a search of the whole list. Characters typed
2225
+ * before the search field renders and takes focus still land on the list, so they add to the
2226
+ * query rather than starting it again.
2227
+ */
2228
+ this.onPanelTreeKeyDown = (event) => {
2229
+ if (this.handlePanelTab(event))
2230
+ return;
2231
+ if (event.key === 'Backspace') {
2232
+ event.preventDefault();
2233
+ if (!this.leaveDrilledInGroup() && this.panelQuery !== '')
2234
+ this.setPanelQuery(this.panelQuery.slice(0, -1));
2235
+ return;
1820
2236
  }
2237
+ // AltGr (Ctrl+Alt on Windows) and Option on macOS type characters too; Meta and Ctrl alone are
2238
+ // shortcuts.
2239
+ if (event.key.length === 1 && event.key !== ' ' && !event.metaKey && (!event.ctrlKey || event.altKey)) {
2240
+ event.preventDefault();
2241
+ this.flyout.reset();
2242
+ // The query first, so leaving the group reads as search results, not a slide back.
2243
+ this.setPanelQuery(this.panelQuery + event.key);
2244
+ this.openGroup = null;
2245
+ return;
2246
+ }
2247
+ this.handleKeyDown(event);
2248
+ };
2249
+ this.onGroupBackClick = () => {
2250
+ this.leaveDrilledInGroup();
1821
2251
  };
1822
2252
  }
1823
2253
  connectedCallback() {
@@ -1854,15 +2284,106 @@ const PdsCombobox = class {
1854
2284
  this.deferredPortalTeardownId = undefined;
1855
2285
  }
1856
2286
  (_a = this.observer) === null || _a === void 0 ? void 0 : _a.disconnect();
2287
+ utils.cancelDebouncedEvent(this.pdsComboboxSearch);
1857
2288
  this.clearAsyncFetchState();
1858
2289
  this.removeBodyPortal();
2290
+ this.flyout.reset();
1859
2291
  }
1860
2292
  componentDidRender() {
2293
+ var _a;
1861
2294
  if (this.usesBodyPortal && this.isOpen) {
1862
2295
  this.syncBodyPortal();
1863
2296
  }
2297
+ const row = (_a = this.listboxEl) === null || _a === void 0 ? void 0 : _a.querySelector('.pds-combobox__group-row--open');
2298
+ const flyoutEl = row === null || row === void 0 ? void 0 : row.querySelector('.pds-combobox__flyout');
2299
+ if (this.isOpen && this.listboxEl && row && flyoutEl) {
2300
+ this.flyout.position(row, this.listboxEl, flyoutEl);
2301
+ }
2302
+ else {
2303
+ this.flyout.stopPositioning();
2304
+ }
2305
+ // The row back is sticky over the group's options; scrolling an option into view stops below
2306
+ // it. Set before any scroll below, and when it first applies, scroll the highlighted option
2307
+ // again: the list keeps its offset on drilling in, and an earlier scroll had no padding.
2308
+ if (this.panelTreeEl) {
2309
+ const header = this.hidesPanelSearch ? this.panelTreeEl.querySelector('.pds-combobox__group-back-trigger') : null;
2310
+ const padding = header ? `${header.offsetHeight}px` : '';
2311
+ if (this.panelTreeEl.style.scrollPaddingBlockStart !== padding) {
2312
+ this.panelTreeEl.style.scrollPaddingBlockStart = padding;
2313
+ if (padding !== '' && this.highlightedIndex >= 0)
2314
+ this.pendingOptionFocus = true;
2315
+ }
2316
+ }
2317
+ if (this.pendingOptionFocus) {
2318
+ this.pendingOptionFocus = false;
2319
+ this.updateOptionFocus();
2320
+ }
2321
+ // Panel search keeps focus in the search field, or in the list while a group hides the field.
2322
+ const panelFocusEl = this.hidesPanelSearch ? this.panelTreeEl : this.panelSearchEl;
2323
+ if (this.isOpen && this.usesPanelSearch && panelFocusEl && panelFocusEl !== this.panelFocusEl) {
2324
+ this.focusPanel(panelFocusEl);
2325
+ }
2326
+ }
2327
+ focusPanel(el) {
2328
+ var _a, _b;
2329
+ this.panelFocusEl = el;
2330
+ // Before the dropdown is positioned it sits in the page's flow; don't scroll to it.
2331
+ el.focus({ preventScroll: true });
2332
+ // A search started by typing in the list carries its first character; type on after it.
2333
+ if (el === this.panelSearchEl && this.panelQuery !== '') {
2334
+ (_b = (_a = this.panelSearchEl).setSelectionRange) === null || _b === void 0 ? void 0 : _b.call(_a, this.panelQuery.length, this.panelQuery.length);
2335
+ }
2336
+ this.updateAriaActiveDescendant();
2337
+ }
2338
+ /** Switching display mode leaves no flyout or hover timer from the last one. */
2339
+ groupDisplayChanged() {
2340
+ this.flyout.reset();
2341
+ this.openGroup = null;
2342
+ // The reset isn't a drill-out, so it doesn't slide either.
2343
+ this.drillDirection = null;
2344
+ }
2345
+ openGroupChanged(next, previous) {
2346
+ this.handPanelFocusToList();
2347
+ // Only moves between the drill-in panel's views slide; search results don't.
2348
+ if (!this.isOpen || this.effectiveGroupDisplay !== 'drill-in' || !this.showsGroupedPanel)
2349
+ return;
2350
+ if (next !== null && previous === null)
2351
+ this.drillDirection = 'in';
2352
+ else if (next === null && previous !== null)
2353
+ this.drillDirection = 'out';
2354
+ }
2355
+ /** A flyout with no room beside the dropdown drills in, which can hide the focused search field too. */
2356
+ flyoutFallbackChanged() {
2357
+ this.handPanelFocusToList();
2358
+ }
2359
+ /**
2360
+ * Drilling into a group hides the search field, so focus moves to the list before the field
2361
+ * unmounts: focus lost with it would leave the combobox and close the dropdown.
2362
+ */
2363
+ handPanelFocusToList() {
2364
+ if (this.isOpen && this.hidesPanelSearch && this.panelTreeEl)
2365
+ this.focusPanel(this.panelTreeEl);
1864
2366
  }
1865
2367
  isOpenChanged(isOpen) {
2368
+ if (!isOpen) {
2369
+ this.drillDirection = null;
2370
+ this.openGroup = null;
2371
+ this.highlightedGroup = null;
2372
+ this.keyboardNavigating = false;
2373
+ this.flyout.reset();
2374
+ if (this.panelQuery !== '') {
2375
+ // The field reopens empty, so tell consumers who filter `options` from this event.
2376
+ this.panelQuery = '';
2377
+ this.pdsComboboxSearch.emit({ query: '' });
2378
+ }
2379
+ // And with `async-url`, start loading the unsearched list now, so it's ready by the reopen.
2380
+ if (this.usesPanelSearch && this.asyncUrl && this.lastFetchedQuery !== '') {
2381
+ this.debouncedFetchAsyncOptions('', 1);
2382
+ }
2383
+ this.panelFocusEl = undefined;
2384
+ this.flyoutRoomChecked = false;
2385
+ this.flyoutFallback = false;
2386
+ }
1866
2387
  if (isOpen && this.deferredPortalTeardownId !== undefined) {
1867
2388
  clearTimeout(this.deferredPortalTeardownId);
1868
2389
  this.deferredPortalTeardownId = undefined;
@@ -1895,17 +2416,52 @@ const PdsCombobox = class {
1895
2416
  get usesBodyPortal() {
1896
2417
  return this.dropdownMount === 'body';
1897
2418
  }
2419
+ get labelId() {
2420
+ return `${this.componentId}-label`;
2421
+ }
2422
+ /** One check for "the `<label>` is rendered", so the label and the reference to it can't disagree. */
2423
+ get hasVisibleLabel() {
2424
+ return Boolean(this.label) && !this.hideLabel;
2425
+ }
2426
+ /**
2427
+ * The button and chip triggers are `div`s, which `<label for>` can't name, so they point at the
2428
+ * visible label instead. With `hide-label` there is no visible label and `aria-label` names them.
2429
+ * With panel search the trigger is a button, which has no value, so its own text (the selection
2430
+ * or placeholder) joins the label in its name.
2431
+ */
2432
+ get triggerLabelledBy() {
2433
+ if (!this.hasVisibleLabel)
2434
+ return undefined;
2435
+ return this.usesPanelSearch ? `${this.labelId} ${this.componentId}` : this.labelId;
2436
+ }
2437
+ /** The div triggers' `aria-label` when the label is hidden; with panel search it names the selection too. */
2438
+ get triggerAriaLabel() {
2439
+ if (!this.hideLabel)
2440
+ return undefined;
2441
+ const shown = this.selectedLabel || this.placeholder;
2442
+ return this.usesPanelSearch && shown ? `${this.label}, ${shown}` : this.label;
2443
+ }
1898
2444
  get listboxId() {
1899
2445
  return `${this.componentId}-listbox`;
1900
2446
  }
1901
2447
  optionDomId(optionIndex) {
1902
2448
  return `${this.componentId}-option-${optionIndex}`;
1903
2449
  }
2450
+ groupDomId(optgroup) {
2451
+ let id = this.groupIds.get(optgroup);
2452
+ if (id === undefined) {
2453
+ id = `${this.componentId}-group-${this.groupIdCount++}`;
2454
+ this.groupIds.set(optgroup, id);
2455
+ }
2456
+ return id;
2457
+ }
1904
2458
  setupDebounce() {
1905
2459
  const { pdsComboboxSearch, debounce, originalSearchEmitter } = this;
1906
2460
  this.pdsComboboxSearch = debounce === undefined
1907
2461
  ? originalSearchEmitter !== null && originalSearchEmitter !== void 0 ? originalSearchEmitter : pdsComboboxSearch
1908
2462
  : utils.debounceEvent(pdsComboboxSearch, debounce);
2463
+ // After the swap, so an emit made while flushing goes to the new emitter, not the old one.
2464
+ utils.flushDebouncedEvent(pdsComboboxSearch);
1909
2465
  }
1910
2466
  optionsChanged() {
1911
2467
  if (this.options) {
@@ -2052,6 +2608,8 @@ const PdsCombobox = class {
2052
2608
  });
2053
2609
  if (page === 1) {
2054
2610
  this.internalOptions = formattedResults;
2611
+ // Only once its results have loaded: a failed or aborted fetch leaves the last query's.
2612
+ this.lastFetchedQuery = query;
2055
2613
  }
2056
2614
  else {
2057
2615
  this.internalOptions = [...this.internalOptions, ...formattedResults];
@@ -2076,26 +2634,76 @@ const PdsCombobox = class {
2076
2634
  }
2077
2635
  }
2078
2636
  updateOptionsFromAsync() {
2637
+ var _a;
2079
2638
  if (!this.asyncUrl && !this.options)
2080
2639
  return;
2081
2640
  // Clear existing slot-based options when using async
2082
2641
  this.optionEls = [];
2083
2642
  this.allItems = [];
2084
- // Create option elements from async data
2643
+ // Create option elements from async data. Grouped options are nested in an optgroup, as
2644
+ // slotted markup would be, so grouping, filtering and labels work the same either way. Each
2645
+ // group is listed where it first appears with all of its options, even when the data
2646
+ // interleaves groups, so an option never renders under another group's label. Ungrouped
2647
+ // options come first, so none reads as part of the group above it.
2085
2648
  const asyncOptions = this.options || this.internalOptions;
2649
+ const groups = new Map();
2650
+ const ungrouped = [];
2651
+ const groupEntries = [];
2086
2652
  asyncOptions.forEach(opt => {
2087
2653
  const optionEl = document.createElement('option');
2088
2654
  optionEl.value = String(opt.id);
2089
2655
  optionEl.textContent = opt.text;
2090
- this.optionEls.push(optionEl);
2091
- this.allItems.push(optionEl);
2656
+ if (opt.disabled === true)
2657
+ optionEl.setAttribute('disabled', '');
2658
+ // Only strings group an option or name an icon; anything else from JS is ignored, not coerced.
2659
+ if (typeof opt.group !== 'string' || opt.group === '') {
2660
+ ungrouped.push(optionEl);
2661
+ return;
2662
+ }
2663
+ let optgroup = groups.get(opt.group);
2664
+ if (!optgroup) {
2665
+ optgroup = document.createElement('optgroup');
2666
+ optgroup.label = opt.group;
2667
+ groups.set(opt.group, optgroup);
2668
+ groupEntries.push(optgroup);
2669
+ }
2670
+ if (!optgroup.hasAttribute('data-icon') && typeof opt.groupIcon === 'string' && opt.groupIcon !== '') {
2671
+ optgroup.setAttribute('data-icon', opt.groupIcon);
2672
+ }
2673
+ optgroup.appendChild(optionEl);
2674
+ });
2675
+ [...ungrouped, ...groupEntries].forEach(entry => {
2676
+ if (entry.tagName === 'OPTGROUP') {
2677
+ this.allItems.push(entry);
2678
+ Array.from(entry.children).forEach(child => {
2679
+ this.optionEls.push(child);
2680
+ this.allItems.push(child);
2681
+ });
2682
+ }
2683
+ else {
2684
+ this.optionEls.push(entry);
2685
+ this.allItems.push(entry);
2686
+ }
2092
2687
  });
2093
- // Re-apply preselection if a value is set but no option has been selected yet.
2094
- // This handles the case where `value` is set before async options have loaded.
2095
- if (this.value && !this.selectedOption) {
2688
+ // A rebuild replaces every optgroup. Follow the open group to its new element by label, so the
2689
+ // flyout stays open across reloads and pagination, or close it if the group is gone. The hover
2690
+ // timers still hold the old element, so they're cleared either way. filterOptions, below,
2691
+ // resets the highlight.
2692
+ if (this.openGroup !== null && !groupEntries.includes(this.openGroup)) {
2693
+ this.flyout.reset();
2694
+ this.openGroup = (_a = groups.get(this.openGroup.label)) !== null && _a !== void 0 ? _a : null;
2695
+ }
2696
+ // Re-apply the selection to the rebuilt options: when `value` is set before async options have
2697
+ // loaded, and after any rebuild, which detaches the previously selected option element.
2698
+ if (this.value && (!this.selectedOption || !this.optionEls.includes(this.selectedOption))) {
2096
2699
  const matchingOption = this.optionEls.find(opt => opt.value === this.value);
2097
2700
  if (matchingOption) {
2701
+ // Relinking a selection keeps the same value, so it keeps any text being typed too, which
2702
+ // the selectedOption watcher would otherwise reset to the label.
2703
+ const typed = this.selectedOption ? this.displayText : undefined;
2098
2704
  this.setSelectedOption(matchingOption);
2705
+ if (typed !== undefined)
2706
+ this.displayText = typed;
2099
2707
  }
2100
2708
  }
2101
2709
  this.filterOptions();
@@ -2146,11 +2754,12 @@ const PdsCombobox = class {
2146
2754
  }
2147
2755
  }
2148
2756
  // For chip triggers, ensure we always have a selected option
2149
- if (!initialSelected && this.trigger === 'chip' && this.optionEls.length > 0) {
2150
- initialSelected = this.optionEls[0]; // Select first option as default
2757
+ const firstEnabled = this.optionEls.find(opt => !isOptionDisabled(opt));
2758
+ if (initialSelected === null && this.trigger === 'chip' && firstEnabled !== undefined) {
2759
+ initialSelected = firstEnabled;
2151
2760
  this.value = initialSelected.value;
2152
2761
  this.displayText = this.getOptionLabel(initialSelected);
2153
- console.warn('PDS Combobox: Chip triggers should always have a selected option. Automatically selected the first option.');
2762
+ console.warn('PDS Combobox: Chip triggers should always have a selected option. Automatically selected the first enabled option.');
2154
2763
  }
2155
2764
  // Update selection if we found a different selected option or if we don't have one
2156
2765
  if (initialSelected && initialSelected !== this.selectedOption) {
@@ -2238,16 +2847,26 @@ const PdsCombobox = class {
2238
2847
  }
2239
2848
  }
2240
2849
  filterOptions() {
2850
+ // A new list replaces the rows a slide was animating, so its end event may never come.
2851
+ this.drillDirection = null;
2241
2852
  // Ensure allItems includes optionEls if not already populated (for edge cases)
2242
2853
  if (this.allItems.length === 0 && this.optionEls.length > 0) {
2243
2854
  this.allItems = [...this.optionEls];
2244
2855
  }
2245
- if (this.mode === 'select-only' || this.expandFilterListWhileOpen) {
2856
+ const searchesPanel = this.usesPanelSearch;
2857
+ if ((this.mode === 'select-only' && !searchesPanel) || this.expandFilterListWhileOpen || (searchesPanel && this.panelQuery === '')) {
2246
2858
  this.filteredItems = [...this.allItems];
2247
2859
  }
2248
2860
  else {
2249
- const val = this.displayText.toLowerCase();
2861
+ const val = (searchesPanel ? this.panelQuery : this.displayText).toLowerCase();
2250
2862
  const filteredOptions = this.optionEls.filter(option => {
2863
+ // Outside inline mode a group's label is part of what search matches, so "tag" finds
2864
+ // every option in the Tag group.
2865
+ if (this.groupDisplay !== 'inline') {
2866
+ const groupLabel = groupLabelOf(option);
2867
+ if (groupLabel !== null && groupLabel.toLowerCase().includes(val))
2868
+ return true;
2869
+ }
2251
2870
  // For layout options, search both text content and data-search-text attribute
2252
2871
  if (this.isOptionLayout(option)) {
2253
2872
  const searchText = option.getAttribute('data-search-text') || option.textContent || '';
@@ -2282,6 +2901,7 @@ const PdsCombobox = class {
2282
2901
  });
2283
2902
  }
2284
2903
  this.highlightedIndex = -1;
2904
+ this.highlightedGroup = null;
2285
2905
  }
2286
2906
  clearExpandFilterList() {
2287
2907
  this.expandFilterListWhileOpen = false;
@@ -2311,7 +2931,8 @@ const PdsCombobox = class {
2311
2931
  this.listboxEl.style.width = this.dropdownWidth;
2312
2932
  if (this.maxHeight) {
2313
2933
  this.listboxEl.style.maxHeight = this.maxHeight;
2314
- this.listboxEl.style.overflowY = 'auto';
2934
+ // With panel search, the options list scrolls under a fixed search field.
2935
+ this.listboxEl.style.overflowY = this.usesPanelSearch ? 'hidden' : 'auto';
2315
2936
  }
2316
2937
  return floatingUi_dom.computePosition(this.triggerEl, this.listboxEl, {
2317
2938
  placement: this.dropdownPlacement,
@@ -2327,8 +2948,30 @@ const PdsCombobox = class {
2327
2948
  position: strategy,
2328
2949
  zIndex,
2329
2950
  });
2951
+ this.checkFlyoutRoom();
2330
2952
  });
2331
2953
  }
2954
+ /**
2955
+ * Once per open, after the dropdown is placed: with no room for a flyout on either side of it,
2956
+ * `flyout` drills in instead. `flyout-min-width` is resolved through CSS, so any length works.
2957
+ */
2958
+ checkFlyoutRoom() {
2959
+ if (!this.isOpen || this.groupDisplay !== 'flyout' || this.flyoutRoomChecked || !this.listboxEl)
2960
+ return;
2961
+ this.flyoutRoomChecked = true;
2962
+ const probe = document.createElement('div');
2963
+ // Fixed, like the flyout, so a percentage resolves against the viewport as the flyout's does.
2964
+ probe.style.cssText = 'position:fixed;visibility:hidden;width:0;';
2965
+ probe.style.minWidth = this.flyoutMinWidth;
2966
+ this.listboxEl.appendChild(probe);
2967
+ const needed = parseFloat(getComputedStyle(probe).minWidth);
2968
+ probe.remove();
2969
+ const rect = this.listboxEl.getBoundingClientRect();
2970
+ const room = Math.max(window.innerWidth - rect.right, rect.left);
2971
+ const fallback = Number.isFinite(needed) && needed > 0 && rect.width > 0 && room < needed;
2972
+ if (fallback !== this.flyoutFallback)
2973
+ this.flyoutFallback = fallback;
2974
+ }
2332
2975
  openDropdownPositioning() {
2333
2976
  if (!this.triggerEl || !this.listboxEl) {
2334
2977
  return;
@@ -2431,6 +3074,130 @@ const PdsCombobox = class {
2431
3074
  this.listboxEl = undefined;
2432
3075
  }
2433
3076
  }
3077
+ /**
3078
+ * The tree keys in the grouped panel. Up, Down, Home, End, PageUp and PageDown move within one
3079
+ * level; Right, Enter or Space opens a group at its first option; Left, or Escape, closes the
3080
+ * open group back to its row. Returns false for keys the listbox handling covers, such as
3081
+ * Enter on an option.
3082
+ */
3083
+ handleGroupedPanelKey(e) {
3084
+ if (!this.showsGroupedPanel)
3085
+ return false;
3086
+ this.keyboardNavigating = true;
3087
+ // In the input trigger, Left and Right still move the caret through typed text, and Space,
3088
+ // Home and End edit it, as they do in the panel's search field.
3089
+ if (this.trigger === 'input') {
3090
+ if ((e.key === 'ArrowLeft' || e.key === 'ArrowRight') && this.displayText !== '')
3091
+ return false;
3092
+ if (e.key === ' ' || e.key === 'Home' || e.key === 'End')
3093
+ return false;
3094
+ }
3095
+ const entries = buildPanelEntries(this.filteredItems);
3096
+ const drilledIn = this.effectiveGroupDisplay === 'drill-in' && this.openGroup !== null;
3097
+ const current = this.currentPanelItem();
3098
+ const column = panelColumn(entries, this.openGroup, current, drilledIn);
3099
+ if (column.length === 0)
3100
+ return false;
3101
+ const position = current === null ? -1 : column.indexOf(current);
3102
+ const moveTo = (to) => {
3103
+ e.preventDefault();
3104
+ this.highlightPanelItem(column[Math.max(0, Math.min(column.length - 1, to))]);
3105
+ return true;
3106
+ };
3107
+ switch (e.key) {
3108
+ case 'ArrowDown':
3109
+ return moveTo(position < 0 ? 0 : position + 1);
3110
+ case 'ArrowUp':
3111
+ return moveTo(position < 0 ? column.length - 1 : position - 1);
3112
+ case 'Home':
3113
+ return moveTo(0);
3114
+ case 'End':
3115
+ return moveTo(column.length - 1);
3116
+ case 'PageDown':
3117
+ return moveTo(position < 0 ? 0 : position + 10);
3118
+ case 'PageUp':
3119
+ return moveTo(position < 0 ? column.length - 1 : position - 10);
3120
+ case 'ArrowRight':
3121
+ case 'Enter':
3122
+ case ' ': {
3123
+ if (current === null || typeof current === 'number')
3124
+ return false;
3125
+ e.preventDefault();
3126
+ if (!drilledIn || current !== this.openGroup) {
3127
+ this.expandGroup(entries, current);
3128
+ }
3129
+ else if (e.key === 'ArrowRight') {
3130
+ // On the row back of a drilled-in group: down into its options.
3131
+ if (column.length > 1)
3132
+ this.highlightPanelItem(column[1]);
3133
+ }
3134
+ else {
3135
+ this.leaveDrilledInGroup();
3136
+ }
3137
+ return true;
3138
+ }
3139
+ case 'ArrowLeft':
3140
+ case 'Escape': {
3141
+ // Escape with no group open closes the panel, through the listbox handling.
3142
+ if (this.openGroup === null)
3143
+ return false;
3144
+ e.preventDefault();
3145
+ this.collapseToGroup(this.openGroup);
3146
+ return true;
3147
+ }
3148
+ }
3149
+ return false;
3150
+ }
3151
+ /**
3152
+ * Where the keyboard is in the grouped panel. An option highlighted in a group that has since
3153
+ * closed (the pointer left its flyout) counts as its group's row, so the keys carry on from
3154
+ * what's showing rather than from an option that isn't.
3155
+ */
3156
+ currentPanelItem() {
3157
+ if (this.highlightedIndex < 0)
3158
+ return this.highlightedGroup;
3159
+ const selectable = this.filteredItems.filter(item => item.tagName === 'OPTION');
3160
+ const group = parentOptgroupOf(selectable[this.highlightedIndex]);
3161
+ return group !== null && group !== this.openGroup ? group : this.highlightedIndex;
3162
+ }
3163
+ /**
3164
+ * Highlights the option at `index`, kept within the list. Disabled options can be highlighted,
3165
+ * so assistive tech announces them as unavailable, but not chosen.
3166
+ */
3167
+ highlightOptionAt(options, index) {
3168
+ if (options.length === 0)
3169
+ return;
3170
+ this.highlightedIndex = Math.max(0, Math.min(options.length - 1, index));
3171
+ this.updateOptionFocus();
3172
+ }
3173
+ /** Highlights a group row or an option, opening or closing flyouts to match. */
3174
+ highlightPanelItem(item) {
3175
+ if (typeof item === 'number') {
3176
+ this.highlightedIndex = item;
3177
+ }
3178
+ else {
3179
+ this.highlightedIndex = -1;
3180
+ this.highlightedGroup = item;
3181
+ }
3182
+ this.updateOptionFocus();
3183
+ }
3184
+ expandGroup(entries, optgroup) {
3185
+ var _a;
3186
+ this.flyout.open(optgroup);
3187
+ const first = (_a = findGroup(entries, optgroup)) === null || _a === void 0 ? void 0 : _a.options[0];
3188
+ if (first !== undefined)
3189
+ this.highlightPanelItem(first.index);
3190
+ // Its options render after this change; scroll to the first one then.
3191
+ this.pendingOptionFocus = true;
3192
+ }
3193
+ /** Closes the open group and highlights its row, as a tree's Left does from a child. */
3194
+ collapseToGroup(optgroup) {
3195
+ this.flyout.reset();
3196
+ this.openGroup = null;
3197
+ this.highlightPanelItem(optgroup);
3198
+ // The row renders after this change (in drill-in it replaces the row back); scroll to it then.
3199
+ this.pendingOptionFocus = true;
3200
+ }
2434
3201
  /**
2435
3202
  * Sets focus on the native input element.
2436
3203
  */
@@ -2444,8 +3211,9 @@ const PdsCombobox = class {
2444
3211
  }
2445
3212
  }
2446
3213
  /**
2447
- * Sets the initial highlighted index when dropdown opens.
2448
- * If there's a selected option, highlight it. Otherwise, highlight the first option.
3214
+ * Sets the initial highlighted index when dropdown opens. Highlights the selected option unless
3215
+ * it's disabled. Otherwise highlights the first enabled option, or, in the grouped panel, the
3216
+ * first row with something to choose, or nothing when every option is disabled.
2449
3217
  */
2450
3218
  setInitialHighlightedIndex() {
2451
3219
  const selectableOptions = this.filteredItems.filter(item => item.tagName === 'OPTION');
@@ -2453,16 +3221,33 @@ const PdsCombobox = class {
2453
3221
  this.highlightedIndex = -1;
2454
3222
  return;
2455
3223
  }
2456
- // If there's a selected option, find its index in the filtered options
2457
- if (this.selectedOption) {
3224
+ // If there's a selected option, find its index in the filtered options. A disabled one can be
3225
+ // the value, as in a native select, but it isn't highlighted.
3226
+ if (this.selectedOption && !isOptionDisabled(this.selectedOption)) {
2458
3227
  const selectedIndex = selectableOptions.findIndex(option => option === this.selectedOption);
2459
3228
  if (selectedIndex >= 0) {
2460
3229
  this.highlightedIndex = selectedIndex;
3230
+ // In the grouped panel, open on the selection's group, however the dropdown was opened, and
3231
+ // scroll the selection into view once its group has rendered.
3232
+ if (this.showsGroupedPanel) {
3233
+ this.openGroup = parentOptgroupOf(this.selectedOption);
3234
+ // Opening on the selection isn't drilling in, so it doesn't slide.
3235
+ this.drillDirection = null;
3236
+ this.pendingOptionFocus = true;
3237
+ }
2461
3238
  return;
2462
3239
  }
2463
3240
  }
2464
- // No selected option or selected option not in filtered results, highlight first option
2465
- this.highlightedIndex = 0;
3241
+ // In the grouped panel, the first row with something to choose: a group stays closed until
3242
+ // it's opened.
3243
+ if (this.showsGroupedPanel) {
3244
+ const first = buildPanelEntries(this.filteredItems).find(entry => entry.kind === 'group' ? !isGroupDisabled(entry.group) : !isOptionDisabled(entry.option));
3245
+ this.highlightedIndex = (first === null || first === void 0 ? void 0 : first.kind) === 'option' ? first.index : -1;
3246
+ this.highlightedGroup = (first === null || first === void 0 ? void 0 : first.kind) === 'group' ? first.group.optgroup : null;
3247
+ return;
3248
+ }
3249
+ // No selected option or selected option not in filtered results, highlight the first enabled option
3250
+ this.highlightedIndex = selectableOptions.findIndex(option => !isOptionDisabled(option));
2466
3251
  }
2467
3252
  /**
2468
3253
  * Focus management helper - moves focus to the first option when dropdown opens
@@ -2498,19 +3283,9 @@ const PdsCombobox = class {
2498
3283
  const selectableOptions = this.filteredItems.filter(item => item.tagName === 'OPTION');
2499
3284
  if (selectableOptions.length > 0) {
2500
3285
  this.setInitialHighlightedIndex();
2501
- if (this.listboxEl) {
2502
- const optionElements = this.listboxEl.querySelectorAll('[role="option"]');
2503
- const highlightedOption = optionElements[this.highlightedIndex];
2504
- if (highlightedOption) {
2505
- optionElements.forEach(option => {
2506
- option.setAttribute('tabindex', '-1');
2507
- });
2508
- highlightedOption.setAttribute('tabindex', '0');
2509
- highlightedOption.focus();
2510
- highlightedOption.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
2511
- }
2512
- }
2513
- this.updateAriaActiveDescendant();
3286
+ // By index, through the same path as arrowing: it opens the option's flyout group first
3287
+ // when it isn't rendered, and highlights it once it is.
3288
+ this.updateOptionFocus();
2514
3289
  }
2515
3290
  }
2516
3291
  /**
@@ -2518,14 +3293,58 @@ const PdsCombobox = class {
2518
3293
  * Note: We don't actually focus the option to prevent focusout events that close the dropdown
2519
3294
  */
2520
3295
  updateOptionFocus() {
2521
- if (!this.listboxEl || this.highlightedIndex < 0)
3296
+ var _a;
3297
+ if (this.listboxEl === undefined || this.listboxEl === null)
3298
+ return;
3299
+ // A row highlighted outright; an option highlighted in a closed group opens it below instead.
3300
+ const groupRow = this.showsGroupedPanel && this.highlightedIndex < 0 ? this.highlightedGroup : null;
3301
+ if (groupRow !== null) {
3302
+ // Arrowing onto another row closes a flyout that hover left open.
3303
+ if (this.effectiveGroupDisplay === 'flyout' && this.openGroup !== null && this.openGroup !== groupRow) {
3304
+ this.flyout.reset();
3305
+ this.openGroup = null;
3306
+ }
3307
+ // Matched by id, not a selector: componentId is consumer text and may not be selector-safe.
3308
+ const id = this.groupDomId(groupRow);
3309
+ (_a = Array.from(this.listboxEl.querySelectorAll('[role="treeitem"]'))
3310
+ .find(row => row.id === id)) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ block: 'nearest' });
3311
+ this.updateAriaActiveDescendant();
2522
3312
  return;
3313
+ }
3314
+ if (this.highlightedIndex < 0)
3315
+ return;
3316
+ // In the flyout panel only the open group's options are rendered: open the highlighted
3317
+ // option's group, and finish once it has rendered. Through the controller, so a hover timer
3318
+ // left running by the pointer can't close or switch the group the keys just moved into.
3319
+ if (this.showsGroupedPanel) {
3320
+ const selectable = this.filteredItems.filter(item => item.tagName === 'OPTION');
3321
+ const group = parentOptgroupOf(selectable[this.highlightedIndex]);
3322
+ const changed = group !== this.openGroup;
3323
+ if (group !== null) {
3324
+ this.flyout.open(group);
3325
+ }
3326
+ else {
3327
+ this.flyout.reset();
3328
+ this.openGroup = null;
3329
+ }
3330
+ if (changed) {
3331
+ this.pendingOptionFocus = true;
3332
+ return;
3333
+ }
3334
+ }
2523
3335
  const optionElements = this.listboxEl.querySelectorAll('[role="option"]');
2524
- const currentOption = optionElements[this.highlightedIndex];
3336
+ // By index, not position: the flyout panel renders only some options.
3337
+ const currentOption = this.listboxEl.querySelector(`[data-option-index="${this.highlightedIndex}"]`);
2525
3338
  if (currentOption) {
2526
3339
  // Check if any option currently has focus OR if we're in arrow-key navigation mode
2527
3340
  const hasOptionFocus = Array.from(optionElements).some(el => el === document.activeElement);
2528
- const shouldFocusOption = !this.usesBodyPortal && (hasOptionFocus || this.isArrowKeyNavigationMode);
3341
+ // The panel's search field keeps focus and points at the option with aria-activedescendant,
3342
+ // and so does the trigger over the grouped panel, whose group rows can't take focus and
3343
+ // whose options are hidden while a flyout is placed.
3344
+ const shouldFocusOption = !this.usesBodyPortal &&
3345
+ !this.usesPanelSearch &&
3346
+ !this.showsGroupedPanel &&
3347
+ (hasOptionFocus || this.isArrowKeyNavigationMode);
2529
3348
  if (shouldFocusOption) {
2530
3349
  optionElements.forEach(option => {
2531
3350
  option.setAttribute('tabindex', '-1');
@@ -2533,21 +3352,64 @@ const PdsCombobox = class {
2533
3352
  currentOption.setAttribute('tabindex', '0');
2534
3353
  currentOption.focus();
2535
3354
  }
2536
- // Always scroll the option into view
2537
- currentOption.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
3355
+ // Always scroll the option into view; in a flyout, by scrolling the flyout alone.
3356
+ const flyout = currentOption.closest('.pds-combobox__flyout');
3357
+ if (flyout) {
3358
+ this.flyout.reveal(flyout, currentOption);
3359
+ }
3360
+ else {
3361
+ currentOption.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
3362
+ }
2538
3363
  }
2539
3364
  // Always update aria-activedescendant on the trigger element
2540
3365
  this.updateAriaActiveDescendant();
2541
3366
  }
3367
+ /** The highlighted group row in the grouped panel, or null while an option is highlighted. */
3368
+ get highlightedGroupRow() {
3369
+ if (!this.showsGroupedPanel)
3370
+ return null;
3371
+ if (this.highlightedIndex < 0)
3372
+ return this.highlightedGroup;
3373
+ // An option left highlighted in a flyout that has since closed shows as its group's row.
3374
+ const current = this.currentPanelItem();
3375
+ return typeof current === 'number' ? null : current;
3376
+ }
2542
3377
  /**
2543
- * Updates aria-activedescendant on the trigger element
3378
+ * The id of the highlighted option or group row, only while it's rendered. In the flyout panel
3379
+ * an option in a closed group isn't in the DOM, and drilled into a group the other groups' rows
3380
+ * aren't; `aria-activedescendant` must not point at a missing element.
2544
3381
  */
3382
+ get activeDescendantId() {
3383
+ if (!this.isOpen)
3384
+ return undefined;
3385
+ const groupRow = this.highlightedGroupRow;
3386
+ if (groupRow !== null) {
3387
+ const drilledIntoAnother = this.effectiveGroupDisplay === 'drill-in' && this.openGroup !== null && this.openGroup !== groupRow;
3388
+ return drilledIntoAnother ? undefined : this.groupDomId(groupRow);
3389
+ }
3390
+ if (this.highlightedIndex < 0)
3391
+ return undefined;
3392
+ if (this.showsGroupedPanel) {
3393
+ const selectable = this.filteredItems.filter(item => item.tagName === 'OPTION');
3394
+ const group = parentOptgroupOf(selectable[this.highlightedIndex]);
3395
+ if (group !== null && group !== this.openGroup)
3396
+ return undefined;
3397
+ }
3398
+ return this.optionDomId(this.highlightedIndex);
3399
+ }
3400
+ /** Points the focused element's aria-activedescendant at the highlighted option, or clears it. */
2545
3401
  updateAriaActiveDescendant() {
2546
- if (this.triggerEl && this.highlightedIndex >= 0) {
2547
- this.triggerEl.setAttribute('aria-activedescendant', this.optionDomId(this.highlightedIndex));
3402
+ // With panel search, the element with focus owns it, not the trigger: the search field, or
3403
+ // the list while a drilled-in group hides the field.
3404
+ const target = this.usesPanelSearch ? (this.hidesPanelSearch ? this.panelTreeEl : this.panelSearchEl) : this.triggerEl;
3405
+ if (!target)
3406
+ return;
3407
+ const id = this.activeDescendantId;
3408
+ if (id !== undefined) {
3409
+ target.setAttribute('aria-activedescendant', id);
2548
3410
  }
2549
- else if (this.triggerEl) {
2550
- this.triggerEl.removeAttribute('aria-activedescendant');
3411
+ else {
3412
+ target.removeAttribute('aria-activedescendant');
2551
3413
  }
2552
3414
  }
2553
3415
  /**
@@ -2583,6 +3445,17 @@ const PdsCombobox = class {
2583
3445
  this.pdsComboboxChange.emit({ value: '' });
2584
3446
  }
2585
3447
  }
3448
+ // Group rows in the flyout panel carry their group's index, as options carry theirs.
3449
+ groupFromEvent(event) {
3450
+ var _a, _b;
3451
+ const index = Number(event.currentTarget.getAttribute('data-group-index'));
3452
+ return (_b = (_a = this.renderedGroups[index]) === null || _a === void 0 ? void 0 : _a.optgroup) !== null && _b !== void 0 ? _b : null;
3453
+ }
3454
+ highlightGroupRowByPointer(group) {
3455
+ this.highlightedIndex = -1;
3456
+ this.highlightedGroup = group;
3457
+ this.keyboardNavigating = false;
3458
+ }
2586
3459
  // Get the label of the selected option
2587
3460
  get selectedLabel() {
2588
3461
  return this.displayText || '';
@@ -2695,7 +3568,24 @@ const PdsCombobox = class {
2695
3568
  // Fallback: Use component props
2696
3569
  return this.chipDot;
2697
3570
  }
3571
+ /**
3572
+ * With `async-url`, fetches when the button trigger opens: the first page if nothing has loaded.
3573
+ * The panel's search field opens empty, so results left from the last search are refetched for
3574
+ * an empty query.
3575
+ */
3576
+ fetchAsyncOptionsOnOpen() {
3577
+ if (!this.asyncUrl)
3578
+ return;
3579
+ if (this.usesPanelSearch && (this.internalOptions.length === 0 || this.lastFetchedQuery !== '')) {
3580
+ this.debouncedFetchAsyncOptions('', 1);
3581
+ }
3582
+ else if (this.internalOptions.length === 0) {
3583
+ this.debouncedFetchAsyncOptions(this.displayText, 1);
3584
+ }
3585
+ }
2698
3586
  handleOptionClick(option) {
3587
+ if (isOptionDisabled(option))
3588
+ return;
2699
3589
  // Update reactive state - single source of truth
2700
3590
  // The @Watch('selectedOption') will handle displayText, value, and form internals
2701
3591
  this.setSelectedOption(option);
@@ -2709,33 +3599,242 @@ const PdsCombobox = class {
2709
3599
  }
2710
3600
  const hasSlottedEmpty = !this.usesBodyPortal && !!this.el.querySelector('[slot="empty"]');
2711
3601
  const hasSlottedLoading = !this.usesBodyPortal && !!this.el.querySelector('[slot="loading"]');
2712
- let optionIndex = 0;
2713
3602
  const selectableOptions = this.filteredItems.filter(item => item.tagName === 'OPTION');
2714
- return (index.h("ul", { class: "pds-combobox__listbox", role: "listbox", id: this.listboxId, "aria-label": this.label || 'Options', "aria-multiselectable": "false", ref: el => (this.listboxEl = el), onScroll: this.handleScroll }, this.loading && (index.h("li", { class: "pds-combobox__loading", role: "presentation" }, hasSlottedLoading ? (index.h("slot", { name: "loading" })) : (index.h("pds-loader", { size: "small" })))), !this.loading && this.filteredItems.length === 0 && (index.h("li", { class: "pds-combobox__empty", role: "presentation" }, hasSlottedEmpty ? (index.h("slot", { name: "empty" })) : (index.h("span", null, "No options found")))), this.filteredItems.map((item, itemIdx) => {
3603
+ const withSearch = this.usesPanelSearch;
3604
+ // While a drilled-in group hides the search field, the list takes focus in its place.
3605
+ const listTakesFocus = this.hidesPanelSearch;
3606
+ const list = (index.h("ul", { key: "panel-list", class: {
3607
+ 'pds-combobox__listbox': !withSearch,
3608
+ 'pds-combobox__listbox-options': withSearch,
3609
+ 'pds-combobox__listbox-options--drilled-in': listTakesFocus,
3610
+ 'pds-combobox__listbox--grouped': this.groupDisplay !== 'inline',
3611
+ 'pds-combobox__listbox--drill-in': this.drillDirection === 'in',
3612
+ 'pds-combobox__listbox--drill-out': this.drillDirection === 'out',
3613
+ }, onAnimationEnd: this.onDrillAnimationEnd, role: this.showsGroupedPanel ? 'tree' : 'listbox', id: this.listboxId, "aria-label": this.label || 'Options', "aria-multiselectable": "false",
3614
+ // Focusable but out of the tab order with panel search, so it can take focus when a
3615
+ // drilled-in group hides the field. Dropping it while focused would blur the list and close.
3616
+ tabIndex: withSearch ? -1 : undefined, "aria-activedescendant": listTakesFocus ? this.activeDescendantId : undefined, onKeyDown: withSearch ? this.onPanelTreeKeyDown : undefined, ref: el => {
3617
+ if (withSearch)
3618
+ this.panelTreeEl = el;
3619
+ else
3620
+ this.listboxEl = el;
3621
+ }, onScroll: this.handleScroll }, this.loading && (index.h("li", { class: "pds-combobox__loading", role: "presentation" }, hasSlottedLoading ? (index.h("slot", { name: "loading" })) : (index.h("pds-loader", { size: "small" })))), !this.loading && this.filteredItems.length === 0 && (index.h("li", { class: "pds-combobox__empty", role: "presentation" }, hasSlottedEmpty ? (index.h("slot", { name: "empty" })) : (index.h("span", null, "No options found")))), this.showsGroupedPanel ? this.renderGroupedPanel() : this.renderListboxItems(selectableOptions.length), this.hasMore && !this.loading && (index.h("li", { class: "pds-combobox__load-more", role: "presentation" }, index.h("pds-loader", { size: "small" })))));
3622
+ if (!withSearch)
3623
+ return list;
3624
+ // The search field sits above the list; the wrapper is what's positioned and portaled.
3625
+ return (index.h("div", { class: "pds-combobox__listbox pds-combobox__listbox--with-search", ref: el => (this.listboxEl = el), onMouseDown: this.onPanelMouseDown,
3626
+ // Portaled, the panel sits outside .pds-combobox, so its focusout wouldn't reach that handler.
3627
+ onFocusout: this.usesBodyPortal ? this.onComboboxFocusOut : undefined }, !listTakesFocus && this.renderPanelSearch(), list));
3628
+ }
3629
+ /**
3630
+ * The listbox's items. Each optgroup's options sit in a `group` named for it, as in
3631
+ * `pds-multiselect`, so assistive tech announces the group on entering it; a `pds-text` label
3632
+ * stays a caption above the options that follow it.
3633
+ */
3634
+ renderListboxItems(setSize) {
3635
+ const rendered = [];
3636
+ let optionIndex = 0;
3637
+ let group = null;
3638
+ const closeGroup = () => {
3639
+ if (group === null)
3640
+ return;
3641
+ const { optgroup, key, options, members } = group;
3642
+ const groupIcon = groupIconOf(optgroup);
3643
+ // As in the grouped displays: disabled when there's nothing left in it to choose.
3644
+ const disabled = members.length > 0 && members.every(member => isOptionDisabled(member));
3645
+ rendered.push(index.h("li", { key: key, class: { 'pds-combobox__group': true, 'pds-combobox__group--disabled': disabled }, role: "group", "aria-label": optgroup.label, "aria-disabled": disabled ? 'true' : undefined }, index.h("div", { class: { 'pds-combobox__group-label': true, 'pds-combobox__group-label--with-icon': groupIcon !== null }, "aria-hidden": "true" }, groupIcon !== null && (
3646
+ // `name`, not `icon`: `icon` also loads URLs and data: SVGs, unsanitized.
3647
+ index.h("pds-icon", { name: groupIcon, size: "small", "aria-hidden": "true", class: "pds-combobox__group-icon" })), optgroup.label), index.h("ul", { class: "pds-combobox__group-list", role: "presentation" }, options)));
3648
+ group = null;
3649
+ };
3650
+ this.filteredItems.forEach((item, itemIdx) => {
2715
3651
  if (item.tagName === 'OPTGROUP') {
2716
- const optgroup = item;
2717
- return (index.h("li", { key: `optgroup-${itemIdx}`, class: "pds-combobox__group-label", role: "presentation", "aria-label": optgroup.label }, optgroup.label));
3652
+ closeGroup();
3653
+ group = { optgroup: item, key: `optgroup-${itemIdx}`, options: [], members: [] };
2718
3654
  }
2719
3655
  else if (item.tagName === 'PDS-TEXT') {
2720
- const pdsText = item;
2721
- return (index.h("li", { key: `pds-text-${itemIdx}`, class: "pds-combobox__group-label", role: "presentation" }, pdsText.textContent));
3656
+ closeGroup();
3657
+ rendered.push(index.h("li", { key: `pds-text-${itemIdx}`, class: "pds-combobox__group-label", role: "presentation" }, item.textContent));
2722
3658
  }
2723
3659
  else if (item.tagName === 'OPTION') {
2724
3660
  const option = item;
2725
- const isSelected = this.isOptionSelected(option);
2726
- const isHighlighted = this.highlightedIndex === optionIndex;
2727
- const isLayout = this.isOptionLayout(option);
2728
- const isChip = this.isOptionChip(option);
2729
- const currentOptionIndex = optionIndex++;
2730
- return (index.h("li", { key: option.value, id: this.optionDomId(currentOptionIndex), role: "option", "aria-selected": isSelected ? 'true' : 'false', "aria-setsize": selectableOptions.length, "aria-posinset": currentOptionIndex + 1, "aria-label": isLayout || isChip ? option.getAttribute('aria-label') || this.getOptionLabel(option) : undefined, tabindex: this.usesBodyPortal ? '-1' : isHighlighted ? '0' : '-1', class: {
2731
- 'pds-combobox__option': true,
2732
- 'pds-combobox__option--highlighted': isHighlighted,
2733
- 'pds-combobox__option--layout': isLayout,
2734
- 'pds-combobox__option--chip': isChip,
2735
- }, "data-option-index": currentOptionIndex, onMouseDown: this.onOptionMouseDown, onClick: this.onOptionClick, onMouseEnter: this.onOptionMouseEnter, onKeyDown: this.onOptionKeyDown }, isLayout ? (index.h("pds-box", { class: "pds-combobox__option-layout-wrapper", innerHTML: this.getOptionLayoutContent(option) })) : isChip ? (this.renderOptionChip(option)) : (this.getOptionLabel(option)), isSelected && index.h("pds-icon", { icon: "check", size: "regular", class: "pds-combobox__option-check" })));
3661
+ if (group !== null && parentOptgroupOf(option) !== group.optgroup)
3662
+ closeGroup();
3663
+ const rendering = this.renderOption(option, optionIndex, { posinset: optionIndex + 1, setsize: setSize });
3664
+ optionIndex++;
3665
+ if (group !== null) {
3666
+ group.options.push(rendering);
3667
+ group.members.push(option);
3668
+ }
3669
+ else {
3670
+ rendered.push(rendering);
3671
+ }
2736
3672
  }
2737
- return null;
2738
- }), this.hasMore && !this.loading && (index.h("li", { class: "pds-combobox__load-more", role: "presentation" }, index.h("pds-loader", { size: "small" })))));
3673
+ });
3674
+ closeGroup();
3675
+ return rendered;
3676
+ }
3677
+ /** `panelSearch` applies to the triggers that can't be typed into. */
3678
+ get usesPanelSearch() {
3679
+ return this.panelSearch && this.trigger !== 'input';
3680
+ }
3681
+ /** `groupDisplay`, with `flyout` drilling in when there's no room beside the dropdown. */
3682
+ get effectiveGroupDisplay() {
3683
+ return this.groupDisplay === 'flyout' && this.flyoutFallback ? 'drill-in' : this.groupDisplay;
3684
+ }
3685
+ /**
3686
+ * The popup's role, for the triggers' `aria-haspopup`: a `tree` while the grouped panel shows
3687
+ * groups, and a `listbox` of options otherwise, search results included.
3688
+ */
3689
+ get popupRole() {
3690
+ return this.showsGroupedPanel ? 'tree' : 'listbox';
3691
+ }
3692
+ /**
3693
+ * The input trigger's `aria-haspopup`. While closed it names what opening shows: the full list,
3694
+ * so the grouped panel in a grouped display, even though the input still holds the selection's
3695
+ * label.
3696
+ */
3697
+ get inputPopupRole() {
3698
+ if (this.isOpen)
3699
+ return this.popupRole;
3700
+ return this.effectiveGroupDisplay === 'inline' ? 'listbox' : 'tree';
3701
+ }
3702
+ /**
3703
+ * The button and chip triggers' `aria-haspopup`. With panel search the trigger opens the panel,
3704
+ * which starts as a tree in a grouped display, so typing in the panel doesn't change it.
3705
+ */
3706
+ get triggerPopupRole() {
3707
+ if (!this.usesPanelSearch)
3708
+ return this.popupRole;
3709
+ return this.groupDisplay === 'inline' ? 'listbox' : 'tree';
3710
+ }
3711
+ /**
3712
+ * Drilled into a group with panel search: the group's row back takes the search field's place,
3713
+ * since one group's options don't need searching. Typing searches the whole list again.
3714
+ */
3715
+ get hidesPanelSearch() {
3716
+ return this.usesPanelSearch && this.showsGroupedPanel && this.effectiveGroupDisplay === 'drill-in' && this.openGroup !== null;
3717
+ }
3718
+ /** The grouped panel is showing groups rather than search results. */
3719
+ get showsGroupedPanel() {
3720
+ if (this.effectiveGroupDisplay === 'inline')
3721
+ return false;
3722
+ const searching = this.usesPanelSearch
3723
+ ? this.panelQuery !== ''
3724
+ : this.mode === 'filter' && !this.expandFilterListWhileOpen && this.displayText !== '';
3725
+ return !searching;
3726
+ }
3727
+ setPanelQuery(query) {
3728
+ this.panelQuery = query;
3729
+ this.clearExpandFilterList();
3730
+ this.filterOptions();
3731
+ this.pdsComboboxSearch.emit({ query: this.panelQuery });
3732
+ if (this.asyncUrl !== undefined && this.asyncUrl !== '') {
3733
+ this.debouncedFetchAsyncOptions(this.panelQuery, 1);
3734
+ }
3735
+ // The list changes size, so place the dropdown again, as typing in the input trigger does.
3736
+ setTimeout(() => this.openDropdownPositioning(), 0);
3737
+ }
3738
+ /** What's being searched: the panel's field, or the input trigger's text. */
3739
+ get activeQuery() {
3740
+ return this.usesPanelSearch ? this.panelQuery : this.displayText;
3741
+ }
3742
+ // Tab closes the dropdown and lands on the trigger, as Escape does: the focused field or list is
3743
+ // about to unmount, so the browser can't tab on from it. The next Tab continues from the trigger.
3744
+ handlePanelTab(event) {
3745
+ if (event.key !== 'Tab')
3746
+ return false;
3747
+ event.preventDefault();
3748
+ this.handleKeyDown(event);
3749
+ this.restoreFocusToTrigger();
3750
+ return true;
3751
+ }
3752
+ /** Returns from a drilled-in group to the group list; false when not drilled in. */
3753
+ leaveDrilledInGroup() {
3754
+ if (!this.showsGroupedPanel || this.effectiveGroupDisplay !== 'drill-in' || this.openGroup === null)
3755
+ return false;
3756
+ this.collapseToGroup(this.openGroup);
3757
+ return true;
3758
+ }
3759
+ renderPanelSearch() {
3760
+ return (index.h("div", { key: "panel-search", class: "pds-combobox__panel-search" }, index.h("pds-icon", { name: "search", size: "small", "aria-hidden": "true" }), index.h("input", { ref: el => (this.panelSearchEl = el), type: "text", class: "pds-combobox__panel-search-input", placeholder: this.searchPlaceholder, value: this.panelQuery, role: "combobox", "aria-label": this.searchOptionsLabel, "aria-haspopup": this.popupRole, "aria-controls": this.listboxId, "aria-autocomplete": "list", "aria-expanded": "true", "aria-activedescendant": this.activeDescendantId, autocomplete: "off", onInput: this.onPanelSearchInput, onKeyDown: this.onPanelSearchKeyDown })));
3761
+ }
3762
+ /**
3763
+ * An option, as a listbox `option` or, given a tree `level`, a `treeitem`. `posinset` and
3764
+ * `setsize` place it among its siblings.
3765
+ */
3766
+ renderOption(option, index$1, { posinset, setsize, level }) {
3767
+ const isSelected = this.isOptionSelected(option);
3768
+ const isHighlighted = this.highlightedIndex === index$1;
3769
+ const isLayout = this.isOptionLayout(option);
3770
+ const isChip = this.isOptionChip(option);
3771
+ const isDisabled = isOptionDisabled(option);
3772
+ const tree = level !== undefined;
3773
+ return (index.h("li", { key: option.value, id: this.optionDomId(index$1), role: tree ? 'treeitem' : 'option', "aria-selected": isSelected ? 'true' : tree ? undefined : 'false', "aria-disabled": isDisabled ? 'true' : undefined, "aria-level": level, "aria-setsize": setsize, "aria-posinset": posinset, "aria-label": isLayout || isChip ? option.getAttribute('aria-label') || this.getOptionLabel(option) : undefined, tabindex: this.usesBodyPortal || this.usesPanelSearch || tree ? '-1' : isHighlighted ? '0' : '-1', class: {
3774
+ 'pds-combobox__option': true,
3775
+ 'pds-combobox__option--highlighted': isHighlighted,
3776
+ 'pds-combobox__option--layout': isLayout,
3777
+ 'pds-combobox__option--chip': isChip,
3778
+ 'pds-combobox__option--disabled': isDisabled,
3779
+ }, "data-option-index": index$1, onMouseDown: this.onOptionMouseDown, onClick: this.onOptionClick, onMouseEnter: this.onOptionMouseEnter, onKeyDown: this.onOptionKeyDown }, isLayout ? (index.h("pds-box", { class: "pds-combobox__option-layout-wrapper", innerHTML: this.getOptionLayoutContent(option) })) : isChip ? (this.renderOptionChip(option)) : (this.getOptionLabel(option)), isSelected && index.h("pds-icon", { icon: "check", size: "regular", class: "pds-combobox__option-check" })));
3780
+ }
3781
+ /**
3782
+ * `flyout`: one row per group, its options in a flyout beside it. `drill-in`: the same rows, and
3783
+ * an opened group replaces them with its row, drawn as a row back, above its options. Either way
3784
+ * it's a tree: the rows and ungrouped options are level 1, a group's options level 2.
3785
+ */
3786
+ renderGroupedPanel() {
3787
+ const entries = buildPanelEntries(this.filteredItems);
3788
+ const setsize = entries.length;
3789
+ if (this.effectiveGroupDisplay === 'drill-in' && this.openGroup !== null) {
3790
+ const position = entries.findIndex(entry => entry.kind === 'group' && entry.group.optgroup === this.openGroup);
3791
+ const open = entries[position];
3792
+ if ((open === null || open === void 0 ? void 0 : open.kind) === 'group')
3793
+ return this.renderGroupBackRow(open.group, { posinset: position + 1, setsize });
3794
+ }
3795
+ this.renderedGroups = [];
3796
+ return entries.map((entry, position) => {
3797
+ const placement = { posinset: position + 1, setsize };
3798
+ if (entry.kind === 'option')
3799
+ return this.renderOption(entry.option, entry.index, Object.assign(Object.assign({}, placement), { level: 1 }));
3800
+ this.renderedGroups.push(entry.group);
3801
+ return this.renderGroupRow(entry.group, this.renderedGroups.length - 1, placement);
3802
+ });
3803
+ }
3804
+ /** A group's options, as its children in the tree. */
3805
+ renderGroupOptions(group) {
3806
+ return group.options.map(({ option, index }, position) => this.renderOption(option, index, { posinset: position + 1, setsize: group.options.length, level: 2 }));
3807
+ }
3808
+ /**
3809
+ * Drilled into a group: its treeitem, expanded. Its row reads as a way back ("Back: Tag") and
3810
+ * leads its options.
3811
+ */
3812
+ renderGroupBackRow(group, { posinset, setsize }) {
3813
+ const id = this.groupDomId(group.optgroup);
3814
+ const disabled = isGroupDisabled(group);
3815
+ return (index.h("li", { key: "group-back", id: id, class: {
3816
+ 'pds-combobox__group-back': true,
3817
+ 'pds-combobox__group-back--disabled': disabled,
3818
+ 'pds-combobox__group-back--highlighted': this.highlightedGroupRow === group.optgroup,
3819
+ 'pds-combobox__group-back--keyboard': this.keyboardNavigating && this.highlightedGroupRow === group.optgroup,
3820
+ }, role: "treeitem", "aria-expanded": "true", "aria-disabled": disabled ? 'true' : undefined, "aria-level": 1, "aria-posinset": posinset, "aria-setsize": setsize, "aria-labelledby": `${id}-label` }, index.h("div", { class: "pds-combobox__group-row-trigger pds-combobox__group-back-trigger", onMouseDown: this.onOptionMouseDown, onMouseEnter: this.onGroupBackMouseEnter, onClick: this.onGroupBackClick }, index.h("span", { class: "pds-combobox__group-row-label", id: `${id}-label` }, index.h("pds-icon", { name: "caret-left", size: "regular", "aria-hidden": "true", class: "pds-combobox__group-row-caret" }), index.h("span", { class: "visually-hidden" }, this.drillInBackLabel, ": "), group.label)), index.h("ul", { class: "pds-combobox__drill-in-options", role: "group", "aria-label": group.label }, this.renderGroupOptions(group))));
3821
+ }
3822
+ renderGroupRow(group, groupIndex, { posinset, setsize }) {
3823
+ const flyout = this.effectiveGroupDisplay === 'flyout';
3824
+ const isOpen = flyout && this.openGroup === group.optgroup;
3825
+ const hasSelection = group.options.some(({ option }) => this.isOptionSelected(option));
3826
+ const disabled = isGroupDisabled(group);
3827
+ const id = this.groupDomId(group.optgroup);
3828
+ return (index.h("li", { key: `group-${groupIndex}`, id: id, class: {
3829
+ 'pds-combobox__group-row': true,
3830
+ 'pds-combobox__group-row--open': isOpen,
3831
+ 'pds-combobox__group-row--has-selection': hasSelection,
3832
+ 'pds-combobox__group-row--highlighted': this.highlightedGroupRow === group.optgroup,
3833
+ 'pds-combobox__group-row--keyboard': this.keyboardNavigating && this.highlightedGroupRow === group.optgroup,
3834
+ 'pds-combobox__group-row--disabled': disabled,
3835
+ }, role: "treeitem", "aria-expanded": isOpen ? 'true' : 'false', "aria-disabled": disabled ? 'true' : undefined, "aria-level": 1, "aria-posinset": posinset, "aria-setsize": setsize, "aria-labelledby": `${id}-label`, "data-group-index": groupIndex, onMouseEnter: flyout ? this.onGroupRowMouseEnter : undefined, onMouseLeave: flyout ? this.onGroupRowMouseLeave : undefined }, index.h("div", { class: "pds-combobox__group-row-trigger", "data-group-index": groupIndex, onMouseDown: this.onOptionMouseDown, onMouseEnter: this.onGroupRowTriggerMouseEnter, onClick: this.onGroupRowClick }, index.h("span", { class: "pds-combobox__group-row-label", id: `${id}-label` }, group.icon !== null && (
3836
+ // `name`, not `icon`: `icon` also loads URLs and data: SVGs, unsanitized.
3837
+ index.h("pds-icon", { name: group.icon, size: "regular", "aria-hidden": "true", class: "pds-combobox__group-icon" })), group.label), index.h("pds-icon", { name: "caret-right", size: "regular", "aria-hidden": "true", class: "pds-combobox__group-row-caret" })), isOpen && (index.h("ul", { class: "pds-combobox__flyout", role: "group", "aria-label": group.label, style: { minWidth: this.flyoutMinWidth, maxWidth: this.flyoutMaxWidth } }, this.renderGroupOptions(group)))));
2739
3838
  }
2740
3839
  // Helper method to render the caret icon
2741
3840
  renderCaretIcon() {
@@ -2872,17 +3971,26 @@ const PdsCombobox = class {
2872
3971
  ]
2873
3972
  .filter(Boolean)
2874
3973
  .join(' ');
2875
- return (index.h(index.Host, { key: 'a39df3c86a29028344943bd3a2828d5e99106d77', "aria-disabled": this.disabled ? 'true' : null }, index.h("div", { key: '32cdb8ce31f9d7c9eac8f995cd233fe6f4d9dfc3', class: "pds-combobox", tabIndex: -1, onFocusout: this.onComboboxFocusOut, part: "combobox" }, this.label && !this.hideLabel && (index.h("label", { key: '64ed7fe37082e2f895daae0090ae3dfac472e3c3', htmlFor: this.componentId, class: "pds-combobox__label" }, this.label)), this.trigger === 'input' ? (index.h("div", { class: "pds-combobox__input-wrapper", style: { width: this.triggerWidth } }, index.h("input", { ref: el => {
3974
+ return (index.h(index.Host, { key: 'd709320411c4d1706133376ea716756c3e1c1471', "aria-disabled": this.disabled ? 'true' : null }, index.h("div", { key: '455a02fa764524c95fe0bbfd024eba7134b3ac34', class: "pds-combobox", tabIndex: -1, onFocusout: this.onComboboxFocusOut, part: "combobox" }, this.hasVisibleLabel && (index.h("label", { key: '0d243157491934d823156841e97bfd369e12c2d5', htmlFor: this.trigger === 'input' ? this.componentId : undefined, id: this.labelId, class: "pds-combobox__label", onClick: this.onLabelClick }, this.label)), this.trigger === 'input' ? (index.h("div", { class: "pds-combobox__input-wrapper", style: { width: this.triggerWidth } }, index.h("input", { ref: el => {
2876
3975
  this.inputEl = el;
2877
3976
  this.triggerEl = el;
2878
3977
  }, class: {
2879
3978
  'pds-combobox__input': true,
2880
3979
  'pds-combobox__input--invalid': this.isInvalid(),
2881
- }, type: "text", role: "combobox", "aria-autocomplete": "list", "aria-controls": this.listboxId, "aria-describedby": form.assignDescription(this.componentId, this.isInvalid(), this.helperMessage, this.errorMessage), "aria-invalid": this.isInvalid() ? 'true' : undefined, "aria-activedescendant": this.isOpen && this.highlightedIndex >= 0 ? this.optionDomId(this.highlightedIndex) : undefined, "aria-expanded": this.isOpen ? 'true' : 'false', "aria-disabled": this.disabled ? 'true' : 'false', "aria-label": this.hideLabel ? this.label : undefined, id: this.componentId, value: this.displayText, placeholder: this.placeholder, disabled: this.disabled, onInput: this.handleInput, onClick: this.handleInputClick, onKeyDown: this.handleKeyDown, autocomplete: "off", part: "input" }), index.h("pds-icon", { icon: "enlarge", "aria-hidden": "true", class: "pds-combobox__input-icon" }))) : this.trigger === 'chip' ? (index.h("div", { class: this.getChipTriggerClass(), style: { width: this.triggerWidth }, role: "combobox", "aria-haspopup": "listbox", "aria-controls": this.listboxId, "aria-describedby": form.assignDescription(this.componentId, this.isInvalid(), this.helperMessage, this.errorMessage), "aria-invalid": this.isInvalid() ? 'true' : undefined, "aria-activedescendant": this.isOpen && this.highlightedIndex >= 0 ? this.optionDomId(this.highlightedIndex) : undefined, "aria-expanded": this.isOpen ? 'true' : 'false', "aria-disabled": this.disabled ? 'true' : 'false', "aria-label": this.hideLabel ? this.label : undefined, id: this.componentId, tabIndex: this.disabled ? -1 : 0, onClick: this.onButtonTriggerClick, "data-layout": this.customTriggerContent, onKeyDown: this.onButtonTriggerKeyDown, onKeyUp: this.onButtonTriggerKeyUp, ref: el => (this.triggerEl = el), part: "chip-trigger" }, this.renderChipTriggerContent())) : (index.h("div", { class: triggerClass, style: { width: this.triggerWidth }, role: "combobox", "aria-haspopup": "listbox", "aria-controls": this.listboxId, "aria-describedby": form.assignDescription(this.componentId, this.isInvalid(), this.helperMessage, this.errorMessage), "aria-invalid": this.isInvalid() ? 'true' : undefined, "aria-activedescendant": this.isOpen && this.highlightedIndex >= 0 ? this.optionDomId(this.highlightedIndex) : undefined, "aria-expanded": this.isOpen ? 'true' : 'false', "aria-disabled": this.disabled ? 'true' : 'false', "aria-label": this.hideLabel ? this.label : undefined, id: this.componentId, tabIndex: this.disabled ? -1 : 0, onClick: this.onButtonTriggerClick, "data-layout": this.customTriggerContent, onKeyDown: this.onButtonTriggerKeyDown, onKeyUp: this.onButtonTriggerKeyUp, ref: el => (this.triggerEl = el), part: "button-trigger" }, this.renderButtonTriggerContent())), this.renderMessages(), index.h("div", { key: '48041c41a39987f2f4093bd048d6c495ea69514b', style: { display: 'none' } }, index.h("slot", { key: '5f4d95fefbd3dbdb33ecb25af593c9429df0e10b', onSlotchange: () => this.updateOptions() })), this.renderDropdown())));
3980
+ }, type: "text", role: "combobox", "aria-autocomplete": "list", "aria-haspopup": this.inputPopupRole === 'tree' ? 'tree' : undefined, "aria-controls": this.listboxId, "aria-describedby": form.assignDescription(this.componentId, this.isInvalid(), this.helperMessage, this.errorMessage), "aria-invalid": this.isInvalid() ? 'true' : undefined, "aria-activedescendant": this.usesPanelSearch ? undefined : this.activeDescendantId, "aria-expanded": this.isOpen ? 'true' : 'false', "aria-disabled": this.disabled ? 'true' : 'false', "aria-label": this.hideLabel ? this.label : undefined, id: this.componentId, value: this.displayText, placeholder: this.placeholder, disabled: this.disabled, onInput: this.handleInput, onClick: this.handleInputClick, onKeyDown: this.handleKeyDown, autocomplete: "off", part: "input" }), index.h("pds-icon", { icon: "enlarge", "aria-hidden": "true", class: "pds-combobox__input-icon" }))) : this.trigger === 'chip' ? (index.h("div", { class: this.getChipTriggerClass(), style: { width: this.triggerWidth }, role: this.usesPanelSearch ? 'button' : 'combobox', "aria-haspopup": this.triggerPopupRole, "aria-controls": this.listboxId, "aria-describedby": form.assignDescription(this.componentId, this.isInvalid(), this.helperMessage, this.errorMessage), "aria-invalid": this.isInvalid() ? 'true' : undefined, "aria-activedescendant": this.usesPanelSearch ? undefined : this.activeDescendantId, "aria-expanded": this.isOpen ? 'true' : 'false', "aria-disabled": this.disabled ? 'true' : 'false', "aria-label": this.triggerAriaLabel, "aria-labelledby": this.triggerLabelledBy, id: this.componentId, tabIndex: this.disabled ? -1 : 0, onClick: this.onButtonTriggerClick, "data-layout": this.customTriggerContent, onKeyDown: this.onButtonTriggerKeyDown, onKeyUp: this.onButtonTriggerKeyUp, ref: el => (this.triggerEl = el), part: "chip-trigger" }, this.renderChipTriggerContent())) : (index.h("div", { class: triggerClass, style: { width: this.triggerWidth }, role: this.usesPanelSearch ? 'button' : 'combobox', "aria-haspopup": this.triggerPopupRole, "aria-controls": this.listboxId, "aria-describedby": form.assignDescription(this.componentId, this.isInvalid(), this.helperMessage, this.errorMessage), "aria-invalid": this.isInvalid() ? 'true' : undefined, "aria-activedescendant": this.usesPanelSearch ? undefined : this.activeDescendantId, "aria-expanded": this.isOpen ? 'true' : 'false', "aria-disabled": this.disabled ? 'true' : 'false', "aria-label": this.triggerAriaLabel, "aria-labelledby": this.triggerLabelledBy, id: this.componentId, tabIndex: this.disabled ? -1 : 0, onClick: this.onButtonTriggerClick, "data-layout": this.customTriggerContent, onKeyDown: this.onButtonTriggerKeyDown, onKeyUp: this.onButtonTriggerKeyUp, ref: el => (this.triggerEl = el), part: "button-trigger" }, this.renderButtonTriggerContent())), this.renderMessages(), index.h("div", { key: 'fd1eb34561f56df05e2f44c7acecde0e56b5e714', style: { display: 'none' } }, index.h("slot", { key: '68e11626a00175d0926c54086ae815be157e6bf0', onSlotchange: () => this.updateOptions() })), this.renderDropdown(), this.groupDisplay !== 'inline' && (index.h("span", { key: '6f3c60c3400d411abbed08ddc6e596db097bb097', class: "visually-hidden", role: "status", "aria-live": "polite" }, this.isOpen && this.effectiveGroupDisplay === 'drill-in' && this.openGroup !== null ? this.openGroup.label : '')))));
2882
3981
  }
2883
3982
  static get formAssociated() { return true; }
2884
3983
  get el() { return index.getElement(this); }
2885
3984
  static get watchers() { return {
3985
+ "groupDisplay": [{
3986
+ "groupDisplayChanged": 0
3987
+ }],
3988
+ "openGroup": [{
3989
+ "openGroupChanged": 0
3990
+ }],
3991
+ "flyoutFallback": [{
3992
+ "flyoutFallbackChanged": 0
3993
+ }],
2886
3994
  "isOpen": [{
2887
3995
  "isOpenChanged": 0
2888
3996
  }],