@pine-ds/core 4.3.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.
- package/components/closest.js +1 -1
- package/components/floating-ui.dom.js +1 -1
- package/components/i18n-format.js +1 -1
- package/components/index.d.ts +2 -0
- package/components/index.js +1 -1
- package/components/index2.js +1 -1
- package/components/mock-pds-modal.js +1 -1
- package/components/pds-button2.js +1 -1
- package/components/pds-checkbox2.js +1 -1
- package/components/pds-chip2.js +1 -1
- package/components/pds-combobox.js +2 -2
- package/components/pds-container.js +1 -1
- package/components/pds-copytext.js +1 -1
- package/components/pds-datepicker.d.ts +11 -0
- package/components/pds-datepicker.js +1 -0
- package/components/pds-divider.js +1 -1
- package/components/pds-drawer-content.js +1 -1
- package/components/pds-drawer-footer.js +1 -1
- package/components/pds-drawer-header.js +1 -1
- package/components/pds-drawer.js +1 -1
- package/components/pds-dropdown-menu-item.js +1 -1
- package/components/pds-dropdown-menu-separator.js +1 -1
- package/components/pds-dropdown-menu.js +1 -1
- package/components/pds-filter.js +1 -1
- package/components/pds-filters.js +1 -1
- package/components/pds-image.js +1 -1
- package/components/pds-input.js +1 -1
- package/components/pds-input2.js +1 -0
- package/components/pds-link2.js +1 -1
- package/components/pds-loader2.js +1 -1
- package/components/pds-modal-content.js +1 -1
- package/components/pds-modal-footer.js +1 -1
- package/components/pds-modal-header.js +1 -1
- package/components/pds-modal2.js +1 -1
- package/components/pds-multiselect.js +1 -1
- package/components/pds-popover.js +1 -1
- package/components/pds-progress.js +1 -1
- package/components/pds-property.js +1 -1
- package/components/pds-radio-group.js +1 -1
- package/components/pds-radio.js +1 -1
- package/components/pds-row.js +1 -1
- package/components/pds-select.js +1 -1
- package/components/pds-sortable-item.js +1 -1
- package/components/pds-sortable.js +2 -2
- package/components/pds-switch.js +1 -1
- package/components/pds-table-body.js +1 -1
- package/components/pds-table-cell2.js +1 -1
- package/components/pds-table-head-cell2.js +1 -1
- package/components/pds-table-head.js +1 -1
- package/components/pds-table-row.js +1 -1
- package/components/pds-tabpanel.js +1 -1
- package/components/pds-tabs.js +1 -1
- package/components/pds-text2.js +1 -1
- package/components/pds-textarea.js +1 -1
- package/components/pds-toast.js +1 -1
- package/components/pds-tooltip.js +1 -1
- package/components/utils.js +1 -1
- package/dist/cjs/closest-D0qyYtJ3.js +20 -0
- package/dist/cjs/{floating-ui.dom-BZk7Blsu.js → floating-ui.dom-Dc8Anyel.js} +79 -0
- package/dist/cjs/{i18n-format-CrpIhahc.js → i18n-format-BD0PmYzT.js} +1 -0
- package/dist/cjs/{index-CaLa1zy9.js → index-Bl5KnQay.js} +4 -1
- package/dist/cjs/{index-DYvijwA6.js → index-D-QQKB0y.js} +8 -0
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/mock-pds-modal.cjs.entry.js +3 -3
- package/dist/cjs/pds-accordion.cjs.entry.js +2 -2
- package/dist/cjs/pds-alert.cjs.entry.js +1 -1
- package/dist/cjs/pds-avatar.cjs.entry.js +2 -2
- package/dist/cjs/pds-box.cjs.entry.js +2 -2
- package/dist/cjs/pds-button.cjs.entry.js +53 -4
- package/dist/cjs/pds-checkbox.cjs.entry.js +14 -6
- package/dist/cjs/pds-chip.cjs.entry.js +6 -6
- package/dist/cjs/pds-combobox.cjs.entry.js +1225 -117
- package/dist/cjs/pds-container.cjs.entry.js +2 -2
- package/dist/cjs/pds-copytext.cjs.entry.js +5 -5
- package/dist/cjs/pds-datepicker.cjs.entry.js +1962 -0
- package/dist/cjs/pds-divider.cjs.entry.js +2 -2
- package/dist/cjs/pds-drawer-content.cjs.entry.js +2 -2
- package/dist/cjs/pds-drawer-footer.cjs.entry.js +2 -2
- package/dist/cjs/pds-drawer-header.cjs.entry.js +2 -2
- package/dist/cjs/pds-drawer.cjs.entry.js +11 -4
- package/dist/cjs/pds-dropdown-menu-item.cjs.entry.js +2 -2
- package/dist/cjs/pds-dropdown-menu-separator.cjs.entry.js +2 -2
- package/dist/cjs/pds-dropdown-menu.cjs.entry.js +11 -4
- package/dist/cjs/pds-filter.cjs.entry.js +3 -3
- package/dist/cjs/pds-filters.cjs.entry.js +2 -2
- package/dist/cjs/pds-icon.cjs.entry.js +1 -1
- package/dist/cjs/pds-image.cjs.entry.js +3 -3
- package/dist/cjs/pds-input.cjs.entry.js +8 -5
- package/dist/cjs/pds-link.cjs.entry.js +5 -5
- package/dist/cjs/pds-loader.cjs.entry.js +2 -2
- package/dist/cjs/pds-modal-content.cjs.entry.js +3 -3
- package/dist/cjs/pds-modal-footer.cjs.entry.js +2 -2
- package/dist/cjs/pds-modal-header.cjs.entry.js +2 -2
- package/dist/cjs/pds-modal.cjs.entry.js +12 -6
- package/dist/cjs/pds-multiselect.cjs.entry.js +264 -51
- package/dist/cjs/pds-popover.cjs.entry.js +30 -12
- package/dist/cjs/pds-progress.cjs.entry.js +3 -3
- package/dist/cjs/pds-property.cjs.entry.js +2 -2
- package/dist/cjs/pds-radio-group.cjs.entry.js +5 -5
- package/dist/cjs/pds-radio.cjs.entry.js +5 -5
- package/dist/cjs/pds-row.cjs.entry.js +2 -2
- package/dist/cjs/pds-select.cjs.entry.js +3 -3
- package/dist/cjs/pds-sortable-item.cjs.entry.js +3 -3
- package/dist/cjs/pds-sortable.cjs.entry.js +2 -2
- package/dist/cjs/pds-switch.cjs.entry.js +14 -6
- package/dist/cjs/pds-tab.cjs.entry.js +1 -1
- package/dist/cjs/pds-table-body.cjs.entry.js +2 -2
- package/dist/cjs/pds-table-cell.cjs.entry.js +5 -5
- package/dist/cjs/pds-table-head-cell.cjs.entry.js +4 -4
- package/dist/cjs/pds-table-head.cjs.entry.js +3 -3
- package/dist/cjs/pds-table-row.cjs.entry.js +3 -3
- package/dist/cjs/pds-table.cjs.entry.js +1 -1
- package/dist/cjs/pds-tabpanel.cjs.entry.js +2 -2
- package/dist/cjs/pds-tabs.cjs.entry.js +2 -2
- package/dist/cjs/pds-text.cjs.entry.js +5 -5
- package/dist/cjs/pds-textarea.cjs.entry.js +14 -9
- package/dist/cjs/pds-toast.cjs.entry.js +4 -4
- package/dist/cjs/pds-tooltip.cjs.entry.js +4 -4
- package/dist/cjs/pine-core.cjs.js +2 -2
- package/dist/cjs/{truncation-tooltip-Bps7_rUy.js → truncation-tooltip-CYgQfBLt.js} +1 -1
- package/dist/cjs/{utils-KWALOgy9.js → utils-BhRmyxT8.js} +35 -4
- package/dist/collection/collection-manifest.json +1 -0
- package/dist/collection/components/pds-button/pds-button.js +53 -2
- package/dist/collection/components/pds-checkbox/pds-checkbox.css +7 -0
- package/dist/collection/components/pds-checkbox/pds-checkbox.js +19 -3
- package/dist/collection/components/pds-chip/pds-chip.js +1 -1
- package/dist/collection/components/pds-combobox/grouped-options-panel.js +262 -0
- package/dist/collection/components/pds-combobox/pds-combobox.css +242 -13
- package/dist/collection/components/pds-combobox/pds-combobox.js +1128 -114
- package/dist/collection/components/pds-combobox/stories/pds-combobox.stories.js +240 -0
- package/dist/collection/components/pds-container/pds-container.js +1 -1
- package/dist/collection/components/pds-copytext/pds-copytext.js +1 -1
- package/dist/collection/components/pds-datepicker/calendar-portal.js +136 -0
- package/dist/collection/components/pds-datepicker/date-utils.js +132 -0
- package/dist/collection/components/pds-datepicker/datepicker-interface.js +1 -0
- package/dist/collection/components/pds-datepicker/pds-datepicker.css +545 -0
- package/dist/collection/components/pds-datepicker/pds-datepicker.js +2406 -0
- package/dist/collection/components/pds-datepicker/presets.js +96 -0
- package/dist/collection/components/pds-datepicker/stories/pds-datepicker.stories.js +195 -0
- package/dist/collection/components/pds-datepicker/value.js +238 -0
- package/dist/collection/components/pds-divider/pds-divider.js +1 -1
- package/dist/collection/components/pds-drawer/pds-drawer-content/pds-drawer-content.js +1 -1
- package/dist/collection/components/pds-drawer/pds-drawer-footer/pds-drawer-footer.js +1 -1
- package/dist/collection/components/pds-drawer/pds-drawer-header/pds-drawer-header.js +1 -1
- package/dist/collection/components/pds-drawer/pds-drawer.css +4 -0
- package/dist/collection/components/pds-drawer/pds-drawer.js +9 -2
- package/dist/collection/components/pds-dropdown-menu/pds-dropdown-menu-item/pds-dropdown-menu-item.js +1 -1
- package/dist/collection/components/pds-dropdown-menu/pds-dropdown-menu-separator/pds-dropdown-menu-separator.js +1 -1
- package/dist/collection/components/pds-dropdown-menu/pds-dropdown-menu.js +9 -2
- package/dist/collection/components/pds-filters/pds-filter/pds-filter.js +1 -1
- package/dist/collection/components/pds-filters/pds-filters.js +1 -1
- package/dist/collection/components/pds-image/pds-image.js +2 -2
- package/dist/collection/components/pds-input/pds-input.js +6 -3
- package/dist/collection/components/pds-link/pds-link.js +2 -2
- package/dist/collection/components/pds-loader/pds-loader.js +1 -1
- package/dist/collection/components/pds-modal/pds-modal-content/pds-modal-content.js +2 -2
- package/dist/collection/components/pds-modal/pds-modal-footer/pds-modal-footer.js +1 -1
- package/dist/collection/components/pds-modal/pds-modal-header/pds-modal-header.js +1 -1
- package/dist/collection/components/pds-modal/pds-modal.css +16 -0
- package/dist/collection/components/pds-modal/pds-modal.js +10 -4
- package/dist/collection/components/pds-modal/test/mock-pds-modal.js +1 -1
- package/dist/collection/components/pds-multiselect/pds-multiselect.css +19 -1
- package/dist/collection/components/pds-multiselect/pds-multiselect.js +390 -47
- package/dist/collection/components/pds-multiselect/stories/pds-multiselect.stories.js +136 -1
- package/dist/collection/components/pds-popover/pds-popover.js +29 -11
- package/dist/collection/components/pds-progress/pds-progress.js +1 -1
- package/dist/collection/components/pds-property/pds-property.js +1 -1
- package/dist/collection/components/pds-radio/pds-radio.js +3 -3
- package/dist/collection/components/pds-radio-group/pds-radio-group.js +3 -3
- package/dist/collection/components/pds-row/pds-row.js +1 -1
- package/dist/collection/components/pds-select/pds-select.js +1 -1
- package/dist/collection/components/pds-sortable/pds-sortable-item/pds-sortable-item.js +1 -1
- package/dist/collection/components/pds-sortable/pds-sortable.js +1 -1
- package/dist/collection/components/pds-switch/pds-switch.css +3 -0
- package/dist/collection/components/pds-switch/pds-switch.js +20 -4
- package/dist/collection/components/pds-table/pds-table-body/pds-table-body.js +1 -1
- package/dist/collection/components/pds-table/pds-table-cell/pds-table-cell.js +2 -2
- package/dist/collection/components/pds-table/pds-table-head/pds-table-head.js +1 -1
- package/dist/collection/components/pds-table/pds-table-head-cell/pds-table-head-cell.js +2 -2
- package/dist/collection/components/pds-table/pds-table-row/pds-table-row.js +1 -1
- package/dist/collection/components/pds-tabs/pds-tabpanel/pds-tabpanel.js +1 -1
- package/dist/collection/components/pds-tabs/pds-tabs.js +1 -1
- package/dist/collection/components/pds-text/pds-text.js +1 -1
- package/dist/collection/components/pds-textarea/pds-textarea.js +11 -6
- package/dist/collection/components/pds-toast/pds-toast.js +3 -3
- package/dist/collection/components/pds-tooltip/pds-tooltip.js +2 -2
- package/dist/collection/utils/closest.js +8 -0
- package/dist/collection/utils/utils.js +33 -4
- package/dist/docs.json +1933 -59
- package/dist/esm/closest-DHPzKMVS.js +17 -0
- package/dist/esm/{floating-ui.dom-DDtwbwIl.js → floating-ui.dom-BPqJgIq6.js} +79 -1
- package/dist/esm/{i18n-format-BKsJZTyn.js → i18n-format-BJgZHCWe.js} +1 -1
- package/dist/esm/{index-DcT8--Dn.js → index-CB8Yh0Nt.js} +4 -1
- package/dist/esm/{index-BU1hN5Vy.js → index-DxI-61GK.js} +5 -1
- package/dist/esm/loader.js +3 -3
- package/dist/esm/mock-pds-modal.entry.js +3 -3
- package/dist/esm/pds-accordion.entry.js +2 -2
- package/dist/esm/pds-alert.entry.js +1 -1
- package/dist/esm/pds-avatar.entry.js +2 -2
- package/dist/esm/pds-box.entry.js +2 -2
- package/dist/esm/pds-button.entry.js +53 -4
- package/dist/esm/pds-checkbox.entry.js +14 -6
- package/dist/esm/pds-chip.entry.js +6 -6
- package/dist/esm/pds-combobox.entry.js +1225 -117
- package/dist/esm/pds-container.entry.js +2 -2
- package/dist/esm/pds-copytext.entry.js +5 -5
- package/dist/esm/pds-datepicker.entry.js +1960 -0
- package/dist/esm/pds-divider.entry.js +2 -2
- package/dist/esm/pds-drawer-content.entry.js +2 -2
- package/dist/esm/pds-drawer-footer.entry.js +2 -2
- package/dist/esm/pds-drawer-header.entry.js +2 -2
- package/dist/esm/pds-drawer.entry.js +11 -4
- package/dist/esm/pds-dropdown-menu-item.entry.js +2 -2
- package/dist/esm/pds-dropdown-menu-separator.entry.js +2 -2
- package/dist/esm/pds-dropdown-menu.entry.js +11 -4
- package/dist/esm/pds-filter.entry.js +3 -3
- package/dist/esm/pds-filters.entry.js +2 -2
- package/dist/esm/pds-icon.entry.js +1 -1
- package/dist/esm/pds-image.entry.js +3 -3
- package/dist/esm/pds-input.entry.js +8 -5
- package/dist/esm/pds-link.entry.js +5 -5
- package/dist/esm/pds-loader.entry.js +2 -2
- package/dist/esm/pds-modal-content.entry.js +3 -3
- package/dist/esm/pds-modal-footer.entry.js +2 -2
- package/dist/esm/pds-modal-header.entry.js +2 -2
- package/dist/esm/pds-modal.entry.js +12 -6
- package/dist/esm/pds-multiselect.entry.js +264 -51
- package/dist/esm/pds-popover.entry.js +30 -12
- package/dist/esm/pds-progress.entry.js +3 -3
- package/dist/esm/pds-property.entry.js +2 -2
- package/dist/esm/pds-radio-group.entry.js +5 -5
- package/dist/esm/pds-radio.entry.js +5 -5
- package/dist/esm/pds-row.entry.js +2 -2
- package/dist/esm/pds-select.entry.js +3 -3
- package/dist/esm/pds-sortable-item.entry.js +3 -3
- package/dist/esm/pds-sortable.entry.js +2 -2
- package/dist/esm/pds-switch.entry.js +14 -6
- package/dist/esm/pds-tab.entry.js +1 -1
- package/dist/esm/pds-table-body.entry.js +2 -2
- package/dist/esm/pds-table-cell.entry.js +5 -5
- package/dist/esm/pds-table-head-cell.entry.js +4 -4
- package/dist/esm/pds-table-head.entry.js +3 -3
- package/dist/esm/pds-table-row.entry.js +3 -3
- package/dist/esm/pds-table.entry.js +1 -1
- package/dist/esm/pds-tabpanel.entry.js +2 -2
- package/dist/esm/pds-tabs.entry.js +2 -2
- package/dist/esm/pds-text.entry.js +5 -5
- package/dist/esm/pds-textarea.entry.js +14 -9
- package/dist/esm/pds-toast.entry.js +4 -4
- package/dist/esm/pds-tooltip.entry.js +4 -4
- package/dist/esm/pine-core.js +3 -3
- package/dist/esm/{truncation-tooltip-CdtEBn_5.js → truncation-tooltip-_902ENWC.js} +1 -1
- package/dist/esm/{utils-u_0lxWnH.js → utils-OYK5-nwe.js} +34 -5
- package/dist/esm-es5/closest-DHPzKMVS.js +1 -0
- package/dist/esm-es5/floating-ui.dom-BPqJgIq6.js +1 -0
- package/dist/esm-es5/{i18n-format-BKsJZTyn.js → i18n-format-BJgZHCWe.js} +1 -1
- package/dist/esm-es5/index-CB8Yh0Nt.js +2 -0
- package/dist/esm-es5/index-DxI-61GK.js +1 -0
- package/dist/esm-es5/loader.js +1 -1
- package/dist/esm-es5/mock-pds-modal.entry.js +1 -1
- package/dist/esm-es5/pds-accordion.entry.js +1 -1
- package/dist/esm-es5/pds-alert.entry.js +1 -1
- package/dist/esm-es5/pds-avatar.entry.js +1 -1
- package/dist/esm-es5/pds-box.entry.js +1 -1
- package/dist/esm-es5/pds-button.entry.js +1 -1
- package/dist/esm-es5/pds-checkbox.entry.js +1 -1
- package/dist/esm-es5/pds-chip.entry.js +1 -1
- package/dist/esm-es5/pds-combobox.entry.js +2 -2
- package/dist/esm-es5/pds-container.entry.js +1 -1
- package/dist/esm-es5/pds-copytext.entry.js +1 -1
- package/dist/esm-es5/pds-datepicker.entry.js +1 -0
- package/dist/esm-es5/pds-divider.entry.js +1 -1
- package/dist/esm-es5/pds-drawer-content.entry.js +1 -1
- package/dist/esm-es5/pds-drawer-footer.entry.js +1 -1
- package/dist/esm-es5/pds-drawer-header.entry.js +1 -1
- package/dist/esm-es5/pds-drawer.entry.js +1 -1
- package/dist/esm-es5/pds-dropdown-menu-item.entry.js +1 -1
- package/dist/esm-es5/pds-dropdown-menu-separator.entry.js +1 -1
- package/dist/esm-es5/pds-dropdown-menu.entry.js +1 -1
- package/dist/esm-es5/pds-filter.entry.js +1 -1
- package/dist/esm-es5/pds-filters.entry.js +1 -1
- package/dist/esm-es5/pds-icon.entry.js +1 -1
- package/dist/esm-es5/pds-image.entry.js +1 -1
- package/dist/esm-es5/pds-input.entry.js +1 -1
- package/dist/esm-es5/pds-link.entry.js +1 -1
- package/dist/esm-es5/pds-loader.entry.js +1 -1
- package/dist/esm-es5/pds-modal-content.entry.js +1 -1
- package/dist/esm-es5/pds-modal-footer.entry.js +1 -1
- package/dist/esm-es5/pds-modal-header.entry.js +1 -1
- package/dist/esm-es5/pds-modal.entry.js +1 -1
- package/dist/esm-es5/pds-multiselect.entry.js +1 -1
- package/dist/esm-es5/pds-popover.entry.js +1 -1
- package/dist/esm-es5/pds-progress.entry.js +1 -1
- package/dist/esm-es5/pds-property.entry.js +1 -1
- package/dist/esm-es5/pds-radio-group.entry.js +1 -1
- package/dist/esm-es5/pds-radio.entry.js +1 -1
- package/dist/esm-es5/pds-row.entry.js +1 -1
- package/dist/esm-es5/pds-select.entry.js +1 -1
- package/dist/esm-es5/pds-sortable-item.entry.js +1 -1
- package/dist/esm-es5/pds-sortable.entry.js +2 -2
- package/dist/esm-es5/pds-switch.entry.js +1 -1
- package/dist/esm-es5/pds-tab.entry.js +1 -1
- package/dist/esm-es5/pds-table-body.entry.js +1 -1
- package/dist/esm-es5/pds-table-cell.entry.js +1 -1
- package/dist/esm-es5/pds-table-head-cell.entry.js +1 -1
- package/dist/esm-es5/pds-table-head.entry.js +1 -1
- package/dist/esm-es5/pds-table-row.entry.js +1 -1
- package/dist/esm-es5/pds-table.entry.js +1 -1
- package/dist/esm-es5/pds-tabpanel.entry.js +1 -1
- package/dist/esm-es5/pds-tabs.entry.js +1 -1
- package/dist/esm-es5/pds-text.entry.js +1 -1
- package/dist/esm-es5/pds-textarea.entry.js +1 -1
- package/dist/esm-es5/pds-toast.entry.js +1 -1
- package/dist/esm-es5/pds-tooltip.entry.js +1 -1
- package/dist/esm-es5/pine-core.js +1 -1
- package/dist/esm-es5/{truncation-tooltip-CdtEBn_5.js → truncation-tooltip-_902ENWC.js} +1 -1
- package/dist/esm-es5/utils-OYK5-nwe.js +1 -0
- package/dist/pine-core/p-0414092a.system.entry.js +1 -0
- package/dist/pine-core/p-04807201.entry.js +1 -0
- package/dist/pine-core/{p-cfcb89d1.system.entry.js → p-07f0d168.system.entry.js} +1 -1
- package/dist/pine-core/p-08f5d19c.entry.js +1 -0
- package/dist/pine-core/{p-d70aa0c7.system.entry.js → p-0aaf8faa.system.entry.js} +1 -1
- package/dist/pine-core/p-0bad5955.entry.js +1 -0
- package/dist/pine-core/{p-99f300ef.system.entry.js → p-0c3bf377.system.entry.js} +1 -1
- package/dist/pine-core/p-0ce79cd0.entry.js +1 -0
- package/dist/pine-core/{p-f682f08a.system.entry.js → p-1057b8c3.system.entry.js} +1 -1
- package/dist/pine-core/{p-089606b8.system.entry.js → p-108c910a.system.entry.js} +1 -1
- package/dist/pine-core/{p-ea986474.system.entry.js → p-166f61a6.system.entry.js} +1 -1
- package/dist/pine-core/{p-95defb53.entry.js → p-16c8f5e3.entry.js} +1 -1
- package/dist/pine-core/p-16e258d1.entry.js +1 -0
- package/dist/pine-core/{p-a8f1a48d.entry.js → p-1be33c95.entry.js} +1 -1
- package/dist/pine-core/{p-70fb83d4.entry.js → p-1e3a31da.entry.js} +1 -1
- package/dist/pine-core/{p-12941e0d.entry.js → p-1f228db9.entry.js} +1 -1
- package/dist/pine-core/p-257c6ef9.entry.js +1 -0
- package/dist/pine-core/p-26415245.system.entry.js +1 -0
- package/dist/pine-core/p-26e1e5bb.entry.js +1 -0
- package/dist/pine-core/p-27c06bf8.entry.js +2 -0
- package/dist/pine-core/p-31aee437.entry.js +1 -0
- package/dist/pine-core/p-330a76f6.system.entry.js +1 -0
- package/dist/pine-core/{p-4ebdb90b.system.entry.js → p-33c63be6.system.entry.js} +1 -1
- package/dist/pine-core/{p-c5b6b545.entry.js → p-344609f9.entry.js} +2 -2
- package/dist/pine-core/{p-2dbc90ba.entry.js → p-3a1711c1.entry.js} +1 -1
- package/dist/pine-core/p-3a9c58bd.system.entry.js +1 -0
- package/dist/pine-core/{p-32fc82c2.entry.js → p-3ebd543f.entry.js} +1 -1
- package/dist/pine-core/p-3fbcb0c8.system.entry.js +1 -0
- package/dist/pine-core/{p-e08e4ca7.entry.js → p-427b4aeb.entry.js} +1 -1
- package/dist/pine-core/{p-f5cf98be.system.entry.js → p-42bd87ea.system.entry.js} +1 -1
- package/dist/pine-core/{p-8d1e7b3c.system.entry.js → p-43c691bf.system.entry.js} +1 -1
- package/dist/pine-core/p-4566d659.system.entry.js +1 -0
- package/dist/pine-core/{p-b9a857fc.system.entry.js → p-4b8cf04a.system.entry.js} +1 -1
- package/dist/pine-core/p-4d6f471c.entry.js +1 -0
- package/dist/pine-core/{p-ec04d4c3.entry.js → p-4e7580c4.entry.js} +1 -1
- package/dist/pine-core/{p-fbb72e66.system.entry.js → p-4f4a2d2a.system.entry.js} +1 -1
- package/dist/pine-core/{p-b8a5597d.entry.js → p-5211aba7.entry.js} +1 -1
- package/dist/pine-core/{p-7e4729e0.entry.js → p-524b7d3f.entry.js} +1 -1
- package/dist/pine-core/{p-c08b1697.entry.js → p-5613c64c.entry.js} +1 -1
- package/dist/pine-core/{p-5a8345e2.entry.js → p-5bb24cb4.entry.js} +1 -1
- package/dist/pine-core/{p-73c3a73f.entry.js → p-5bb80b3c.entry.js} +1 -1
- package/dist/pine-core/{p-e039ebb6.system.entry.js → p-5c6e0a26.system.entry.js} +1 -1
- package/dist/pine-core/{p-b53d9620.system.entry.js → p-5db57551.system.entry.js} +1 -1
- package/dist/pine-core/{p-6b260a97.entry.js → p-5eb00ba5.entry.js} +1 -1
- package/dist/pine-core/p-61756414.system.entry.js +1 -0
- package/dist/pine-core/{p-08196d6c.entry.js → p-682e9e8f.entry.js} +1 -1
- package/dist/pine-core/p-6965db1d.entry.js +1 -0
- package/dist/pine-core/{p-317337e4.entry.js → p-6b180ee2.entry.js} +1 -1
- package/dist/pine-core/{p-d33d65f6.entry.js → p-6c53962f.entry.js} +1 -1
- package/dist/pine-core/p-6da6520b.system.entry.js +3 -0
- package/dist/pine-core/{p-bd9b2931.system.entry.js → p-6e3bf862.system.entry.js} +1 -1
- package/dist/pine-core/{p-9d77f2f8.system.entry.js → p-71c9f866.system.entry.js} +1 -1
- package/dist/pine-core/{p-a616385b.system.entry.js → p-7265b94c.system.entry.js} +1 -1
- package/dist/pine-core/{p-55532d56.system.entry.js → p-74229b5e.system.entry.js} +1 -1
- package/dist/pine-core/p-7512c2d4.system.entry.js +1 -0
- package/dist/pine-core/p-76db406d.system.entry.js +1 -0
- package/dist/pine-core/{p-3b555f06.system.entry.js → p-79aa5f43.system.entry.js} +1 -1
- package/dist/pine-core/{p-77082557.system.entry.js → p-7bbcda0f.system.entry.js} +1 -1
- package/dist/pine-core/p-7c8946e6.entry.js +1 -0
- package/dist/pine-core/p-7c98c90a.system.entry.js +1 -0
- package/dist/pine-core/p-81292c03.system.entry.js +1 -0
- package/dist/pine-core/p-81300046.system.entry.js +1 -0
- package/dist/pine-core/{p-93c52e2b.system.entry.js → p-8252cd84.system.entry.js} +1 -1
- package/dist/pine-core/p-84ba0e6a.system.entry.js +1 -0
- package/dist/pine-core/{p-45d55983.entry.js → p-86fc0bfa.entry.js} +1 -1
- package/dist/pine-core/p-90692bb6.entry.js +1 -0
- package/dist/pine-core/{p-67fc26e5.system.entry.js → p-90ea812c.system.entry.js} +1 -1
- package/dist/pine-core/p-948826db.entry.js +1 -0
- package/dist/pine-core/{p-35edd8b0.entry.js → p-9b66642d.entry.js} +1 -1
- package/dist/pine-core/p-BJgZHCWe.js +1 -0
- package/dist/pine-core/p-BPqJgIq6.js +1 -0
- package/dist/pine-core/p-BSRFZB4I.system.js +1 -0
- package/dist/pine-core/p-BZsj6eAn.system.js +1 -0
- package/dist/pine-core/p-CB8Yh0Nt.js +2 -0
- package/dist/pine-core/{p-B2qvvB3q.system.js → p-CBu9UrXr.system.js} +1 -1
- package/dist/pine-core/p-COtCa1Md.system.js +1 -0
- package/dist/pine-core/p-CTQZ2fkv.system.js +1 -0
- package/dist/pine-core/{p-B2nn1gSd.js → p-CnM3cCof.js} +1 -1
- package/dist/pine-core/p-CnO10OxH.system.js +1 -0
- package/dist/pine-core/p-D-akEPIU.system.js +2 -0
- package/dist/pine-core/p-DHPzKMVS.js +1 -0
- package/dist/pine-core/p-Dx8tEj0U.system.js +1 -0
- package/dist/pine-core/p-DxI-61GK.js +1 -0
- package/dist/pine-core/p-OYK5-nwe.js +1 -0
- package/dist/pine-core/p-a10af84b.system.entry.js +1 -0
- package/dist/pine-core/p-a21b530a.system.entry.js +1 -0
- package/dist/pine-core/{p-b0becff3.system.entry.js → p-a85535a4.system.entry.js} +1 -1
- package/dist/pine-core/p-abc0fe2f.system.entry.js +1 -0
- package/dist/pine-core/p-ac6a5bf0.entry.js +1 -0
- package/dist/pine-core/{p-5f5339ab.entry.js → p-b0526f98.entry.js} +1 -1
- package/dist/pine-core/p-b130b716.entry.js +1 -0
- package/dist/pine-core/{p-4cbb691f.entry.js → p-b195d345.entry.js} +1 -1
- package/dist/pine-core/{p-5c5bd609.entry.js → p-b4923acf.entry.js} +1 -1
- package/dist/pine-core/{p-15a0fa0a.system.entry.js → p-b4e440e3.system.entry.js} +1 -1
- package/dist/pine-core/p-b8693a87.entry.js +1 -0
- package/dist/pine-core/{p-bf025e38.entry.js → p-b8ada1eb.entry.js} +1 -1
- package/dist/pine-core/{p-a6a269da.system.entry.js → p-bb85bbb5.system.entry.js} +1 -1
- package/dist/pine-core/{p-fa8d3155.system.entry.js → p-bbc539bc.system.entry.js} +2 -2
- package/dist/pine-core/{p-f26dcbc2.system.entry.js → p-bf833976.system.entry.js} +1 -1
- package/dist/pine-core/{p-e055c543.entry.js → p-c23097af.entry.js} +1 -1
- package/dist/pine-core/p-c2dd84bd.system.entry.js +1 -0
- package/dist/pine-core/{p-441682f4.system.entry.js → p-c4520b04.system.entry.js} +1 -1
- package/dist/pine-core/{p-f1365550.entry.js → p-c4f68dfc.entry.js} +1 -1
- package/dist/pine-core/{p-fa2a786d.system.entry.js → p-c6fa6744.system.entry.js} +1 -1
- package/dist/pine-core/p-c7dba815.entry.js +1 -0
- package/dist/pine-core/p-cb6f55ff.entry.js +1 -0
- package/dist/pine-core/p-cfb8fa7c.system.entry.js +1 -0
- package/dist/pine-core/{p-2bb101c2.entry.js → p-d0d7d1d4.entry.js} +1 -1
- package/dist/pine-core/{p-4f5aacd9.entry.js → p-d1112c8a.entry.js} +1 -1
- package/dist/pine-core/{p-5f3d0c86.system.entry.js → p-d4e91ad9.system.entry.js} +1 -1
- package/dist/pine-core/{p-44222439.entry.js → p-da018dcb.entry.js} +1 -1
- package/dist/pine-core/{p-57784f2f.system.entry.js → p-dc27abe6.system.entry.js} +1 -1
- package/dist/pine-core/{p-f9f7101e.entry.js → p-dc343b6d.entry.js} +1 -1
- package/dist/pine-core/{p-fb774f89.system.entry.js → p-dde753e7.system.entry.js} +1 -1
- package/dist/pine-core/{p-558ac401.entry.js → p-dea3a582.entry.js} +1 -1
- package/dist/pine-core/p-df29fd41.entry.js +1 -0
- package/dist/pine-core/{p-c6426e16.system.entry.js → p-e4e2eae2.system.entry.js} +1 -1
- package/dist/pine-core/{p-1abae35f.entry.js → p-e8668178.entry.js} +1 -1
- package/dist/pine-core/{p-20753e42.system.entry.js → p-eb28d21d.system.entry.js} +1 -1
- package/dist/pine-core/p-eb71a82d.system.entry.js +1 -0
- package/dist/pine-core/{p-13bb89ff.entry.js → p-ed63873c.entry.js} +1 -1
- package/dist/pine-core/{p-5d2f95bd.entry.js → p-f4f6dc36.entry.js} +1 -1
- package/dist/pine-core/{p-6b3d8c2b.system.entry.js → p-f67a0ca8.system.entry.js} +1 -1
- package/dist/pine-core/{p-003df3b3.entry.js → p-fc455968.entry.js} +1 -1
- package/dist/pine-core/{p-02452806.system.entry.js → p-fe3e2ebd.system.entry.js} +1 -1
- package/dist/pine-core/pine-core.css +1 -1
- package/dist/pine-core/pine-core.esm.js +1 -1
- package/dist/pine-core/pine-core.js +1 -1
- package/dist/types/components/pds-button/pds-button.d.ts +10 -0
- package/dist/types/components/pds-checkbox/pds-checkbox.d.ts +5 -0
- package/dist/types/components/pds-combobox/combobox-interface.d.ts +17 -0
- package/dist/types/components/pds-combobox/grouped-options-panel.d.ts +105 -0
- package/dist/types/components/pds-combobox/pds-combobox.d.ts +235 -3
- package/dist/types/components/pds-datepicker/calendar-portal.d.ts +43 -0
- package/dist/types/components/pds-datepicker/date-utils.d.ts +48 -0
- package/dist/types/components/pds-datepicker/datepicker-interface.d.ts +30 -0
- package/dist/types/components/pds-datepicker/pds-datepicker.d.ts +489 -0
- package/dist/types/components/pds-datepicker/presets.d.ts +23 -0
- package/dist/types/components/pds-datepicker/value.d.ts +47 -0
- package/dist/types/components/pds-dropdown-menu/pds-dropdown-menu.d.ts +1 -0
- package/dist/types/components/pds-multiselect/multiselect-interface.d.ts +19 -0
- package/dist/types/components/pds-multiselect/pds-multiselect.d.ts +56 -1
- package/dist/types/components/pds-popover/pds-popover.d.ts +1 -0
- package/dist/types/components/pds-switch/pds-switch.d.ts +5 -0
- package/dist/types/components.d.ts +677 -4
- package/dist/types/utils/closest.d.ts +2 -0
- package/dist/types/utils/utils.d.ts +9 -1
- package/dist/vscode.html-data.json +467 -3
- package/hydrate/index.js +3973 -362
- package/hydrate/index.mjs +3973 -362
- package/package.json +2 -2
- package/dist/cjs/closest-BZXvuB_Y.js +0 -11
- package/dist/esm/closest-DnUJodVd.js +0 -9
- package/dist/esm-es5/closest-DnUJodVd.js +0 -1
- package/dist/esm-es5/floating-ui.dom-DDtwbwIl.js +0 -1
- package/dist/esm-es5/index-BU1hN5Vy.js +0 -1
- package/dist/esm-es5/index-DcT8--Dn.js +0 -2
- package/dist/esm-es5/utils-u_0lxWnH.js +0 -1
- package/dist/pine-core/p-026ee6de.entry.js +0 -1
- package/dist/pine-core/p-03f3fc92.system.entry.js +0 -1
- package/dist/pine-core/p-06375326.system.entry.js +0 -1
- package/dist/pine-core/p-1df5e088.entry.js +0 -1
- package/dist/pine-core/p-24214ab9.system.entry.js +0 -1
- package/dist/pine-core/p-250011ba.entry.js +0 -1
- package/dist/pine-core/p-2b420257.entry.js +0 -1
- package/dist/pine-core/p-375eb7f4.entry.js +0 -1
- package/dist/pine-core/p-3b796898.entry.js +0 -1
- package/dist/pine-core/p-3c5489ce.entry.js +0 -1
- package/dist/pine-core/p-3e868906.system.entry.js +0 -1
- package/dist/pine-core/p-464f23e6.entry.js +0 -1
- package/dist/pine-core/p-49c6112a.entry.js +0 -1
- package/dist/pine-core/p-4bd57896.system.entry.js +0 -1
- package/dist/pine-core/p-6a6a767b.system.entry.js +0 -1
- package/dist/pine-core/p-6dabeebc.system.entry.js +0 -3
- package/dist/pine-core/p-70891202.entry.js +0 -1
- package/dist/pine-core/p-73fa955a.system.entry.js +0 -1
- package/dist/pine-core/p-755e0b3c.system.entry.js +0 -1
- package/dist/pine-core/p-8b051229.entry.js +0 -1
- package/dist/pine-core/p-8d8a8550.system.entry.js +0 -1
- package/dist/pine-core/p-93486f2e.entry.js +0 -1
- package/dist/pine-core/p-93ae562d.entry.js +0 -1
- package/dist/pine-core/p-95b8bece.system.entry.js +0 -1
- package/dist/pine-core/p-9d902000.system.entry.js +0 -1
- package/dist/pine-core/p-9ef355b7.entry.js +0 -1
- package/dist/pine-core/p-BI7Ml0VF.system.js +0 -1
- package/dist/pine-core/p-BKsJZTyn.js +0 -1
- package/dist/pine-core/p-BU1hN5Vy.js +0 -1
- package/dist/pine-core/p-BrLs99ML.system.js +0 -1
- package/dist/pine-core/p-CJ8t3EBJ.system.js +0 -2
- package/dist/pine-core/p-Cr7-rJtJ.system.js +0 -1
- package/dist/pine-core/p-DDtwbwIl.js +0 -1
- package/dist/pine-core/p-D_I-k33A.system.js +0 -1
- package/dist/pine-core/p-DcT8--Dn.js +0 -2
- package/dist/pine-core/p-DnUJodVd.js +0 -1
- package/dist/pine-core/p-a009ab10.system.entry.js +0 -1
- package/dist/pine-core/p-a8cd2ab5.entry.js +0 -1
- package/dist/pine-core/p-b45b8f8b.system.entry.js +0 -1
- package/dist/pine-core/p-b85bb61d.system.entry.js +0 -1
- package/dist/pine-core/p-bdded57a.system.entry.js +0 -1
- package/dist/pine-core/p-c1a65082.entry.js +0 -1
- package/dist/pine-core/p-c1d1befb.system.entry.js +0 -1
- package/dist/pine-core/p-ctdGub9B.system.js +0 -1
- package/dist/pine-core/p-d9c1ee36.system.entry.js +0 -1
- package/dist/pine-core/p-df285ece.system.entry.js +0 -1
- package/dist/pine-core/p-ee114aef.entry.js +0 -1
- package/dist/pine-core/p-ee997fbf.entry.js +0 -2
- package/dist/pine-core/p-f89197c9.entry.js +0 -1
- package/dist/pine-core/p-kYMYDfJY.system.js +0 -1
- package/dist/pine-core/p-u_0lxWnH.js +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var index = require('./index-
|
|
3
|
+
var index = require('./index-Bl5KnQay.js');
|
|
4
4
|
var form = require('./form-MhwfKTuo.js');
|
|
5
|
-
var floatingUi_dom = require('./floating-ui.dom-
|
|
6
|
-
var utils = require('./utils-
|
|
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-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)}.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
|
|
1624
|
-
|
|
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
|
|
1635
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
2199
|
+
query: this.activeQuery,
|
|
1817
2200
|
page: this.currentPage + 1,
|
|
1818
2201
|
});
|
|
1819
|
-
this.debouncedFetchAsyncOptions(this.
|
|
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
|
-
|
|
2091
|
-
|
|
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
|
-
//
|
|
2094
|
-
//
|
|
2095
|
-
|
|
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
|
-
|
|
2150
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
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
|
-
|
|
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
|
-
//
|
|
2465
|
-
|
|
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
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
*
|
|
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
|
-
|
|
2547
|
-
|
|
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
|
|
2550
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2717
|
-
|
|
3652
|
+
closeGroup();
|
|
3653
|
+
group = { optgroup: item, key: `optgroup-${itemIdx}`, options: [], members: [] };
|
|
2718
3654
|
}
|
|
2719
3655
|
else if (item.tagName === 'PDS-TEXT') {
|
|
2720
|
-
|
|
2721
|
-
|
|
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
|
-
|
|
2726
|
-
|
|
2727
|
-
const
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
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
|
-
|
|
2738
|
-
|
|
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: '
|
|
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.
|
|
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
|
}],
|