@verbb/plugin-kit-web 2.0.19 → 2.0.21
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/CHANGELOG.md +10 -0
- package/dist/base/pk-form-associated-element.d.ts.map +1 -1
- package/dist/chunks/{pk-autocomplete-IFL-u-RF.js → pk-autocomplete-qy2Psvqm.js} +2 -2
- package/dist/chunks/{pk-autocomplete-IFL-u-RF.js.map → pk-autocomplete-qy2Psvqm.js.map} +1 -1
- package/dist/chunks/{pk-checkbox-CfV1uDdC.js → pk-checkbox-13ArHSmt.js} +3 -2
- package/dist/chunks/{pk-checkbox-CfV1uDdC.js.map → pk-checkbox-13ArHSmt.js.map} +1 -1
- package/dist/chunks/{pk-checkbox-select-DeCaI3a0.js → pk-checkbox-select-Ckvfbu83.js} +2 -2
- package/dist/chunks/{pk-checkbox-select-DeCaI3a0.js.map → pk-checkbox-select-Ckvfbu83.js.map} +1 -1
- package/dist/chunks/{pk-code-editor-BG9sG_Fy.js → pk-code-editor-BlG6O5qB.js} +2 -2
- package/dist/chunks/{pk-code-editor-BG9sG_Fy.js.map → pk-code-editor-BlG6O5qB.js.map} +1 -1
- package/dist/chunks/{pk-color-input-CncNce1C.js → pk-color-input-BRgQ5-vB.js} +2 -2
- package/dist/chunks/{pk-color-input-CncNce1C.js.map → pk-color-input-BRgQ5-vB.js.map} +1 -1
- package/dist/chunks/{pk-combobox-CL9En0J-.js → pk-combobox-ag89QEX2.js} +3 -2
- package/dist/chunks/pk-combobox-ag89QEX2.js.map +1 -0
- package/dist/chunks/{pk-date-picker-BEAd4Ngl.js → pk-date-picker-C2YvDPNm.js} +2 -2
- package/dist/chunks/{pk-date-picker-BEAd4Ngl.js.map → pk-date-picker-C2YvDPNm.js.map} +1 -1
- package/dist/chunks/{pk-editable-table-BubcKCBn.js → pk-editable-table-DDnu1I8Y.js} +11 -11
- package/dist/chunks/{pk-editable-table-BubcKCBn.js.map → pk-editable-table-DDnu1I8Y.js.map} +1 -1
- package/dist/chunks/{pk-form-associated-element-CCQALRGB.js → pk-form-associated-element-GxX5lbnk.js} +2 -2
- package/dist/chunks/pk-form-associated-element-GxX5lbnk.js.map +1 -0
- package/dist/chunks/{pk-image-browser-DwiCFOIG.js → pk-image-browser-Bj8LhWfk.js} +3 -4
- package/dist/chunks/pk-image-browser-Bj8LhWfk.js.map +1 -0
- package/dist/chunks/{pk-input-CF_icEtR.js → pk-input-BywmK5n2.js} +2 -2
- package/dist/chunks/{pk-input-CF_icEtR.js.map → pk-input-BywmK5n2.js.map} +1 -1
- package/dist/chunks/{pk-lightswitch-D1qEFRxK.js → pk-lightswitch-VHfJizBW.js} +2 -2
- package/dist/chunks/{pk-lightswitch-D1qEFRxK.js.map → pk-lightswitch-VHfJizBW.js.map} +1 -1
- package/dist/chunks/{pk-radio-group-ByrxGLdX.js → pk-radio-group-Dzd-3HaQ.js} +3 -2
- package/dist/chunks/pk-radio-group-Dzd-3HaQ.js.map +1 -0
- package/dist/chunks/{pk-select-CdQdhnZN.js → pk-select-b5S5WKc-.js} +3 -2
- package/dist/chunks/pk-select-b5S5WKc-.js.map +1 -0
- package/dist/chunks/{pk-textarea-CYM2tK88.js → pk-textarea-Dhj1WFLH.js} +2 -2
- package/dist/chunks/{pk-textarea-CYM2tK88.js.map → pk-textarea-Dhj1WFLH.js.map} +1 -1
- package/dist/chunks/{pk-time-picker-CebRqydV.js → pk-time-picker-ChRbKHNB.js} +2 -2
- package/dist/chunks/{pk-time-picker-CebRqydV.js.map → pk-time-picker-ChRbKHNB.js.map} +1 -1
- package/dist/chunks/{pk-tiptap-editor-CTz-yfHL.js → pk-tiptap-editor-BzZ-J2sl.js} +4 -4
- package/dist/chunks/{pk-tiptap-editor-CTz-yfHL.js.map → pk-tiptap-editor-BzZ-J2sl.js.map} +1 -1
- package/dist/chunks/{pk-tiptap-input-Y9eog9Zn.js → pk-tiptap-input-YKg4VLp_.js} +2 -2
- package/dist/chunks/{pk-tiptap-input-Y9eog9Zn.js.map → pk-tiptap-input-YKg4VLp_.js.map} +1 -1
- package/dist/chunks/{register-Bw9kG690.js → register-C6_F-VwU.js} +16 -16
- package/dist/chunks/{register-Bw9kG690.js.map → register-C6_F-VwU.js.map} +1 -1
- package/dist/components/autocomplete/pk-autocomplete.js +1 -1
- package/dist/components/autocomplete.js +1 -1
- package/dist/components/checkbox/pk-checkbox.d.ts.map +1 -1
- package/dist/components/checkbox/pk-checkbox.js +1 -1
- package/dist/components/checkbox-select/pk-checkbox-select.js +1 -1
- package/dist/components/checkbox-select.js +1 -1
- package/dist/components/checkbox.js +1 -1
- package/dist/components/code-editor/pk-code-editor.js +1 -1
- package/dist/components/code-editor.js +1 -1
- package/dist/components/color-input/pk-color-input.js +1 -1
- package/dist/components/color-input.js +1 -1
- package/dist/components/combobox/pk-combobox.d.ts.map +1 -1
- package/dist/components/combobox/pk-combobox.js +1 -1
- package/dist/components/combobox.js +1 -1
- package/dist/components/date-picker/pk-date-picker.js +1 -1
- package/dist/components/date-picker.js +1 -1
- package/dist/components/editable-table/pk-editable-table.js +1 -1
- package/dist/components/editable-table.js +1 -1
- package/dist/components/image-browser/pk-image-browser.d.ts.map +1 -1
- package/dist/components/image-browser/pk-image-browser.js +1 -1
- package/dist/components/image-browser.js +1 -1
- package/dist/components/input/pk-input.js +1 -1
- package/dist/components/input.js +1 -1
- package/dist/components/lightswitch/pk-lightswitch.js +1 -1
- package/dist/components/lightswitch.js +1 -1
- package/dist/components/radio-group/pk-radio-group.d.ts.map +1 -1
- package/dist/components/radio-group/pk-radio-group.js +1 -1
- package/dist/components/radio-group.js +1 -1
- package/dist/components/select/pk-select.d.ts.map +1 -1
- package/dist/components/select/pk-select.js +1 -1
- package/dist/components/select.js +1 -1
- package/dist/components/textarea/pk-textarea.js +1 -1
- package/dist/components/textarea.js +1 -1
- package/dist/components/time-picker/pk-time-picker.js +1 -1
- package/dist/components/time-picker.js +1 -1
- package/dist/components/tiptap/pk-tiptap-editor.js +1 -1
- package/dist/components/tiptap/pk-tiptap-input.js +1 -1
- package/dist/components/tiptap-editor.js +1 -1
- package/dist/components/tiptap-input.js +1 -1
- package/dist/index.js +17 -17
- package/dist/register.js +16 -16
- package/dist-loader/chunks/{pk-base-CyzwylQ7.js → pk-base-B2MqxErC.js} +1 -1
- package/dist-loader/chunks/{pk-button-saBDszJV.js → pk-button-Dfm23jEC.js} +2 -2
- package/dist-loader/chunks/{pk-calendar-BrF8i3dW.js → pk-calendar-BuSULJCU.js} +1 -1
- package/dist-loader/chunks/{pk-checkbox-B3d4nkBx.js → pk-checkbox-BDoq3xg0.js} +2 -1
- package/dist-loader/chunks/{pk-color-input-CD-r_sfG.js → pk-color-input-eLjO9zfn.js} +1 -1
- package/dist-loader/chunks/{pk-combobox-Cpx0w1KV.js → pk-combobox-DBvcyxRC.js} +3 -2
- package/dist-loader/chunks/{pk-date-picker-DEoiTOxN.js → pk-date-picker-CYLpYIji.js} +3 -3
- package/dist-loader/chunks/{pk-dialog-C6aaPokv.js → pk-dialog-BtrH5Ke0.js} +1 -1
- package/dist-loader/chunks/{pk-dropdown-item-D8RrwjxL.js → pk-dropdown-item-D8tfEU-k.js} +1 -1
- package/dist-loader/chunks/{pk-dropdown-label-Cg32UgRe.js → pk-dropdown-label-TbLj4bHK.js} +1 -1
- package/dist-loader/chunks/{pk-dropdown-menu-CAHCltlX.js → pk-dropdown-menu-C4GDW5pE.js} +3 -3
- package/dist-loader/chunks/{pk-field-V7JOy26T.js → pk-field-BM0XD9Ij.js} +1 -1
- package/dist-loader/chunks/{pk-icon-Bph-EBqp.js → pk-icon-_1F1aL74.js} +1 -1
- package/dist-loader/chunks/{pk-input-BhU0PiCk.js → pk-input-DvBrD7Md.js} +1 -1
- package/dist-loader/chunks/{pk-lightswitch-m23Cy3_D.js → pk-lightswitch-CcwlLQ9f.js} +1 -1
- package/dist-loader/chunks/{pk-option-BrDMERSl.js → pk-option-DATPm0Bo.js} +1 -1
- package/dist-loader/chunks/{pk-popup-CrxxR-Hb.js → pk-popup-CUuGs8r_.js} +1 -1
- package/dist-loader/chunks/{pk-select-Dok-JdSe.js → pk-select-DpcvbzUL.js} +3 -2
- package/dist-loader/chunks/{pk-spinner-BKU9Rf2R.js → pk-spinner-Dk_LbvHW.js} +1 -1
- package/dist-loader/chunks/{pk-status-D2g_77m_.js → pk-status-B8UvjIp2.js} +1 -1
- package/dist-loader/chunks/{pk-textarea-CC7rA5A7.js → pk-textarea-DeSuxufJ.js} +1 -1
- package/dist-loader/chunks/{pk-time-picker-h5Wgd4a_.js → pk-time-picker-DpJt8biN.js} +3 -3
- package/dist-loader/chunks/{pk-tooltip-Dd_Q0Bn5.js → pk-tooltip-DcF9J5GT.js} +2 -2
- package/dist-loader/components/autocomplete/autocomplete.js +2 -2
- package/dist-loader/components/button/button.js +1 -1
- package/dist-loader/components/button-group/button-group-separator.js +1 -1
- package/dist-loader/components/button-group/button-group-text.js +1 -1
- package/dist-loader/components/button-group/button-group.js +1 -1
- package/dist-loader/components/calendar/calendar.js +1 -1
- package/dist-loader/components/checkbox/checkbox.js +1 -1
- package/dist-loader/components/checkbox-select/checkbox-select.js +2 -2
- package/dist-loader/components/code-editor/code-editor.js +1 -1
- package/dist-loader/components/color-input/color-input.js +1 -1
- package/dist-loader/components/combobox/combobox.js +1 -1
- package/dist-loader/components/connect/connect-oauth.js +3 -3
- package/dist-loader/components/connect/connect.js +5 -5
- package/dist-loader/components/copy-button/copy-button.js +2 -2
- package/dist-loader/components/date-picker/date-picker.js +1 -1
- package/dist-loader/components/dialog/dialog.js +1 -1
- package/dist-loader/components/dropdown-menu/dropdown-item.js +1 -1
- package/dist-loader/components/dropdown-menu/dropdown-label.js +1 -1
- package/dist-loader/components/dropdown-menu/dropdown-menu.js +1 -1
- package/dist-loader/components/dropdown-menu/dropdown-separator.js +1 -1
- package/dist-loader/components/editable-table/editable-table.js +14 -14
- package/dist-loader/components/field/field.js +1 -1
- package/dist-loader/components/icon/icon.js +1 -1
- package/dist-loader/components/image-browser/image-browser.js +5 -6
- package/dist-loader/components/input/input.js +1 -1
- package/dist-loader/components/input-group/input-group-addon.js +1 -1
- package/dist-loader/components/input-group/input-group-button.js +1 -1
- package/dist-loader/components/input-group/input-group-input.js +1 -1
- package/dist-loader/components/input-group/input-group-text.js +1 -1
- package/dist-loader/components/input-group/input-group-textarea.js +1 -1
- package/dist-loader/components/input-group/input-group.js +1 -1
- package/dist-loader/components/lightswitch/lightswitch.js +1 -1
- package/dist-loader/components/popover/popover.js +2 -2
- package/dist-loader/components/popup/popup.js +1 -1
- package/dist-loader/components/radio-group/radio-group.js +2 -1
- package/dist-loader/components/radio-group/radio.js +1 -1
- package/dist-loader/components/scroll-area/scroll-area.js +1 -1
- package/dist-loader/components/select/option-group.js +1 -1
- package/dist-loader/components/select/option.js +1 -1
- package/dist-loader/components/select/select.js +1 -1
- package/dist-loader/components/separator/separator.js +1 -1
- package/dist-loader/components/spinner/spinner.js +1 -1
- package/dist-loader/components/status/status.js +1 -1
- package/dist-loader/components/tabs/tab-heading.js +1 -1
- package/dist-loader/components/tabs/tab-panel.js +1 -1
- package/dist-loader/components/tabs/tab.js +1 -1
- package/dist-loader/components/tabs/tabs.js +1 -1
- package/dist-loader/components/textarea/textarea.js +1 -1
- package/dist-loader/components/time-picker/time-picker.js +1 -1
- package/dist-loader/components/tiptap/tiptap-content.js +1 -1
- package/dist-loader/components/tiptap/tiptap-editor.js +10 -10
- package/dist-loader/components/tiptap/tiptap-input.js +1 -1
- package/dist-loader/components/toggle/toggle.js +1 -1
- package/dist-loader/components/toggle-group/toggle-group.js +1 -1
- package/dist-loader/components/tooltip/tooltip.js +1 -1
- package/package.json +7 -7
- package/dist/chunks/pk-combobox-CL9En0J-.js.map +0 -1
- package/dist/chunks/pk-form-associated-element-CCQALRGB.js.map +0 -1
- package/dist/chunks/pk-image-browser-DwiCFOIG.js.map +0 -1
- package/dist/chunks/pk-radio-group-ByrxGLdX.js.map +0 -1
- package/dist/chunks/pk-select-CdQdhnZN.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pk-image-browser-DwiCFOIG.js","names":[],"sources":["../../src/components/image-browser/pk-image-browser.styles.ts","../../src/components/image-browser/pk-image-browser.ts"],"sourcesContent":["import { css } from 'lit';\n\nimport { iconStyles } from '../../base/icon.styles.js';\nimport { popupContentAnimationStyles } from '../../styles/popup-content-animation.styles.js';\n\n/**\n * Presentational static image / icon browser.\n * Trigger chrome mirrors combobox popup-mode; panel grid mirrors Vizy icon picker.\n */\nexport const pkImageBrowserStyles = [\n popupContentAnimationStyles,\n css`\n ${iconStyles}\n @layer pk-component {\n :host {\n display: inline-block;\n position: relative;\n width: fit-content;\n max-width: 100%;\n vertical-align: top;\n color: var(--pk-color-gray-700);\n font-family: var(--pk-font-family);\n font-size: var(--pk-font-size-base);\n line-height: var(--pk-line-height);\n --pk-image-browser-trigger-min-height: var(--pk-btn-height-default);\n --pk-image-browser-padding-block: 6px;\n --pk-image-browser-padding-inline: 10px;\n --pk-image-browser-font-size: var(--pk-font-size-base);\n --pk-image-browser-line-height: var(--pk-input-control-line-height, 1.25rem);\n --pk-image-browser-glyph-size: 1rem;\n --pk-image-browser-panel-width: 26.25rem;\n /* Hit target larger than the glyph so the select ring has breathing room. */\n --pk-image-browser-cell-min: 2.25rem;\n --pk-image-browser-glyph-tile: 1.375rem;\n --pk-image-browser-fill: var(--pk-color-slate-250);\n --pk-image-browser-fill-hover: var(--pk-color-slate-300);\n }\n\n /* Caption under each cell — wider tracks; glyph size stays put. */\n :host([label-mode='inline']) {\n --pk-image-browser-cell-min: 3.75rem;\n }\n\n :host([size='xs']) {\n --pk-image-browser-trigger-min-height: var(--pk-btn-height-xs);\n --pk-image-browser-padding-block: 2px;\n --pk-image-browser-padding-inline: 6px;\n --pk-image-browser-font-size: var(--pk-font-size-xs, 0.75rem);\n --pk-image-browser-glyph-size: 0.875rem;\n }\n\n :host([size='sm']) {\n --pk-image-browser-trigger-min-height: var(--pk-btn-height-sm);\n --pk-image-browser-padding-block: 4px;\n --pk-image-browser-padding-inline: 8px;\n --pk-image-browser-font-size: var(--pk-font-size-sm, 0.8125rem);\n --pk-image-browser-glyph-size: 0.875rem;\n }\n\n :host([size='lg']),\n :host([size='xl']) {\n --pk-image-browser-trigger-min-height: var(--pk-btn-height-lg);\n --pk-image-browser-padding-block: 8px;\n --pk-image-browser-padding-inline: 12px;\n --pk-image-browser-font-size: var(--pk-font-size-lg, 1rem);\n --pk-image-browser-glyph-size: 1.125rem;\n }\n\n /* Image mode — roomier photo tiles; captions still opt-in via label-mode=\"inline\". */\n :host([mode='image']) {\n --pk-image-browser-panel-width: 34rem;\n --pk-image-browser-cell-min: 7.5rem;\n }\n\n :host([mode='image'][label-mode='inline']) {\n /* Captions reclaim a little width; preview stays the hero. */\n --pk-image-browser-cell-min: 6.5rem;\n }\n\n :host([width='full']) {\n display: block;\n width: 100%;\n }\n\n :host([width='full']) .control {\n width: 100%;\n }\n\n .value-input {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n opacity: 0;\n pointer-events: none;\n }\n\n /* Combobox-style chrome: label + clear + chevron share one filled control.\n * 0.5rem gap keeps ellipsized filenames from kissing the clear glyph. */\n .control {\n display: inline-flex;\n align-items: stretch;\n gap: 0.5rem;\n min-width: 12.5rem;\n max-width: 100%;\n height: var(--pk-image-browser-trigger-min-height);\n min-height: var(--pk-image-browser-trigger-min-height);\n margin: 0;\n padding: 0 0 0 var(--pk-image-browser-padding-inline);\n border: 1px solid transparent;\n border-radius: var(--pk-input-border-radius, var(--pk-radius-lg));\n background: var(--pk-image-browser-fill);\n color: inherit;\n box-sizing: border-box;\n overflow: hidden;\n transition: border-color 0.12s ease, box-shadow 0.12s ease, background 0.12s ease;\n }\n\n .control:hover:not(.is-disabled) {\n background: var(--pk-image-browser-fill-hover);\n }\n\n .control.is-open:not(.is-disabled) {\n background: var(--pk-image-browser-fill-hover);\n }\n\n .control:focus-within:not(.is-disabled) {\n border-color: var(--pk-color-sky-600);\n box-shadow: var(--pk-input-focus-shadow);\n background: var(--pk-color-white);\n }\n\n :host([invalid]) .control,\n :host(:state(user-invalid)) .control {\n border-color: var(--pk-color-rose-500, #f43f5e);\n }\n\n .control.is-disabled {\n cursor: not-allowed;\n opacity: 0.5;\n }\n\n .trigger {\n display: inline-flex;\n align-items: center;\n flex: 1 1 auto;\n min-width: 0;\n margin: 0;\n padding: var(--pk-image-browser-padding-block) 0;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n font-size: var(--pk-image-browser-font-size);\n font-weight: 400;\n line-height: var(--pk-image-browser-line-height);\n text-align: left;\n white-space: nowrap;\n cursor: pointer;\n outline: none;\n box-sizing: border-box;\n }\n\n .trigger:disabled {\n cursor: not-allowed;\n }\n\n .trigger-main {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n }\n\n .trigger-preview {\n display: inline-flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n width: var(--pk-image-browser-glyph-size);\n height: var(--pk-image-browser-glyph-size);\n overflow: hidden;\n }\n\n .trigger-preview svg,\n .trigger-preview img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n }\n\n .trigger-preview svg {\n fill: currentColor;\n }\n\n .trigger-label {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .trigger-label.is-placeholder {\n color: var(--pk-color-gray-500);\n }\n\n .clear-button,\n .expand-button {\n display: inline-flex;\n flex-shrink: 0;\n align-items: center;\n justify-content: center;\n align-self: stretch;\n box-sizing: border-box;\n width: calc(0.75rem + 0.5rem);\n margin: 0;\n padding: 0;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: var(--pk-color-gray-600);\n cursor: pointer;\n outline: none;\n }\n\n .expand-button {\n width: calc(0.75rem + 0.5rem + var(--pk-image-browser-padding-inline));\n padding-inline-end: var(--pk-image-browser-padding-inline);\n }\n\n .clear-button:hover:not(:disabled),\n .expand-button:hover:not(:disabled) {\n color: var(--pk-color-gray-800);\n }\n\n .clear-button:disabled,\n .expand-button:disabled {\n cursor: not-allowed;\n }\n\n .clear-button-icon,\n .expand-button-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n line-height: 0;\n pointer-events: none;\n }\n\n .clear-button-icon svg,\n .expand-button-icon svg {\n display: block;\n width: 0.75rem;\n height: 0.75rem;\n }\n\n .panel {\n position: relative;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n width: var(--pk-image-browser-panel-width);\n max-width: min(100vw - 1.5rem, var(--pk-image-browser-panel-width));\n max-height: min(28.75rem, 60vh);\n border-radius: var(--pk-radius-lg);\n background: var(--pk-color-white);\n box-shadow:\n 0 0 0 1px rgba(31, 41, 51, 0.1),\n 0 5px 20px rgba(31, 41, 51, 0.25);\n overflow: hidden;\n }\n\n .panel[hidden] {\n display: none !important;\n }\n\n .panel-search {\n flex: none;\n /* Same inline inset as panel-body so search + grid share one vertical edge. */\n padding: 0.625rem 0.625rem 0.5rem;\n border-bottom: 1px solid var(--pk-color-gray-150, rgba(51, 64, 77, 0.1));\n }\n\n .panel-input {\n display: block;\n width: 100%;\n box-sizing: border-box;\n margin: 0;\n padding: 0.375rem 0.625rem;\n border: 1px solid var(--pk-color-gray-200, #d4dce4);\n border-radius: var(--pk-input-border-radius, var(--pk-radius-md));\n background: var(--pk-color-white);\n color: var(--pk-color-gray-700);\n font: inherit;\n font-size: var(--pk-font-size-sm, 0.8125rem);\n line-height: 1.25rem;\n outline: none;\n }\n\n .panel-input:focus {\n border-color: var(--pk-color-sky-600);\n box-shadow: var(--pk-input-focus-shadow);\n }\n\n .panel-body {\n flex: 1 1 auto;\n min-height: 0;\n overflow-y: auto;\n /* Match search field inset so the grid lines up with the input. */\n padding: 0.5rem 0.625rem 0.625rem;\n }\n\n :host([mode='image']) .panel-body {\n padding: 0.5rem 0.625rem 0.625rem;\n }\n\n .group + .group {\n margin-top: 0.875rem;\n }\n\n .group-heading {\n display: flex;\n justify-content: space-between;\n gap: 0.5rem;\n margin: 0 0 0.375rem;\n color: var(--pk-color-gray-500);\n font-size: 0.6875rem;\n font-weight: 600;\n letter-spacing: 0.04em;\n line-height: 1.25;\n text-transform: uppercase;\n }\n\n .group-heading-count {\n font-weight: 400;\n letter-spacing: 0;\n text-transform: none;\n }\n\n /* Fixed column width (not 1fr) so sparse catalogs stay dense instead of stretching. */\n .grid {\n display: grid;\n grid-template-columns: repeat(auto-fill, var(--pk-image-browser-cell-min));\n gap: 0.375rem;\n justify-content: start;\n /* Don’t stretch short single-line cells to match taller wrapped neighbors in the row. */\n align-items: start;\n }\n\n :host([mode='image']) .grid {\n grid-template-columns: repeat(auto-fill, minmax(var(--pk-image-browser-cell-min), 1fr));\n gap: 0.375rem;\n }\n\n .option {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 0;\n width: var(--pk-image-browser-cell-min);\n height: var(--pk-image-browser-cell-min);\n margin: 0;\n /* Square hit target; glyph is smaller so the ring doesn’t clip tips. */\n padding: 0;\n border: 1px solid transparent;\n border-radius: var(--pk-radius-sm);\n background: none;\n color: inherit;\n cursor: pointer;\n outline: none;\n overflow: hidden;\n }\n\n /* With captions, height hugs glyph + label instead of a fixed square. */\n :host([label-mode='inline']) .option {\n justify-content: flex-start;\n gap: 0.125rem;\n height: auto;\n /* Keep glyph + caption inside the inset highlight ring. */\n padding: 0.25rem 0.125rem 0.3125rem;\n }\n\n :host([mode='image']) .option {\n position: relative;\n width: auto;\n height: auto;\n min-height: 0;\n gap: 0;\n padding: 0;\n overflow: hidden;\n border-radius: var(--pk-radius-md);\n }\n\n :host([mode='image'][label-mode='inline']) .option {\n gap: 0.375rem;\n padding: 0.375rem 0.375rem 0.5rem;\n overflow: visible;\n }\n\n .option:hover,\n .option:focus-visible,\n .option.is-highlighted {\n background: var(--pk-color-gray-050, #f3f7fc);\n }\n\n /* Selected is the durable chrome; highlight/hover share the same ring for keyboard parity. */\n .option.is-selected,\n .option.is-highlighted,\n .option:hover {\n box-shadow: inset 0 0 0 2px var(--pk-color-sky-600);\n }\n\n /*\n * Flush photo tiles paint over inset box-shadow (descendants sit above it).\n * Overlay the same ring so tooltip/none match inline chrome.\n */\n :host([mode='image']) .option.is-selected,\n :host([mode='image']) .option.is-highlighted,\n :host([mode='image']) .option:hover {\n box-shadow: none;\n }\n\n :host([mode='image']) .option.is-selected::after,\n :host([mode='image']) .option.is-highlighted::after,\n :host([mode='image']) .option:hover::after {\n content: '';\n position: absolute;\n inset: 0;\n z-index: 1;\n border-radius: inherit;\n box-shadow: inset 0 0 0 2px var(--pk-color-sky-600);\n pointer-events: none;\n }\n\n .option:focus-visible {\n outline: none;\n }\n\n .option-preview {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n width: var(--pk-image-browser-glyph-tile);\n height: var(--pk-image-browser-glyph-tile);\n margin: 0;\n overflow: hidden;\n }\n\n :host([mode='image']) .option-preview {\n width: 100%;\n height: auto;\n aspect-ratio: 4 / 3;\n margin: 0;\n border-radius: inherit;\n }\n\n .option-preview svg,\n .option-preview img {\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n }\n\n /* Photo tiles crop to fill — previews, not faithful aspect viewers. */\n :host([mode='image']) .option-preview svg,\n :host([mode='image']) .option-preview img {\n object-fit: cover;\n }\n\n .option-preview svg {\n fill: currentColor;\n }\n\n .option-label {\n display: -webkit-box;\n box-sizing: border-box;\n width: 100%;\n max-width: 100%;\n padding-inline: 2px;\n overflow: hidden;\n color: var(--pk-color-gray-700);\n font-size: 0.625rem;\n line-height: 0.75rem;\n text-align: center;\n overflow-wrap: anywhere;\n word-break: break-word;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 3;\n line-clamp: 3;\n }\n\n :host([mode='image']) .option-label {\n display: block;\n color: var(--pk-color-gray-600);\n font-size: 0.6875rem;\n line-height: 1.2;\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow-wrap: normal;\n word-break: normal;\n -webkit-line-clamp: unset;\n line-clamp: unset;\n }\n\n .notice {\n margin: 0.375rem 0;\n color: var(--pk-color-gray-500);\n font-size: var(--pk-font-size-sm, 0.8125rem);\n }\n\n .notice.is-error {\n color: var(--pk-color-rose-600, #e11d48);\n }\n\n /* Host-driven catalog warm — spinner only (no loading copy). */\n .loading {\n display: flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n min-height: 6rem;\n padding: 1.25rem 0.75rem;\n color: var(--pk-color-gray-500);\n }\n\n .panel-input:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n }\n\n /* Host is inert layout chrome; the floating tip lives in pk-popup. */\n .option-tooltip {\n position: absolute;\n width: 0;\n height: 0;\n margin: 0;\n padding: 0;\n overflow: hidden;\n pointer-events: none;\n }\n }\n `,\n];\n","import { html, nothing } from 'lit';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js';\nimport { customElement, property, query, state } from '../../decorators.js';\nimport type { PropertyValues } from 'lit';\n\nimport { chevronDown, xmark, renderIconHtml } from '../../icons/index.js';\nimport { LiveRegion, uniqueId } from '../../a11y/focus.js';\nimport { isTopDismissible, registerDismissible, unregisterDismissible } from '../../a11y/dismissible-stack.js';\nimport { scrollIntoView } from '../../a11y/scroll-lock.js';\nimport { PkFormAssociatedElement } from '../../base/pk-form-associated-element.js';\nimport { PkClearEvent } from '../../events/pk-clear.js';\nimport {\n PkAfterHideEvent,\n PkAfterShowEvent,\n PkHideEvent,\n PkShowEvent,\n type PkOverlaySource,\n} from '../../events/overlay-lifecycle.js';\nimport { MirrorValidator, RequiredValidator } from '../../validators/index.js';\nimport { isPointerInsideOverlay } from '../../utils/popup-pointer.js';\nimport {\n syncPopupPlacementAnimation,\n waitForPopupReposition,\n} from '../../utils/popup-placement-animation.js';\n// Keep the internal element registered when production builds erase type-only imports.\nimport '../popup/pk-popup.js';\nimport type { PkPopup, PkPopupPlacement } from '../popup/pk-popup.js';\nimport '../spinner/pk-spinner.js';\nimport '../tooltip/pk-tooltip.js';\nimport type { PkTooltip } from '../tooltip/pk-tooltip.js';\nimport { pkImageBrowserStyles } from './pk-image-browser.styles.js';\n\nexport type PkImageBrowserSize = 'xs' | 'sm' | 'default' | 'lg' | 'xl';\n\n/** Grid preview kind — compact glyphs vs larger photo tiles. */\nexport type PkImageBrowserMode = 'icon' | 'image';\n\n/**\n * How option names appear in the grid.\n * - `tooltip` (default) — shared `pk-tooltip` on hover; `aria-label` always\n * - `inline` — caption under each cell\n * - `none` — `aria-label` only (no tooltip, no caption)\n *\n * Named `labelMode` (not `labels`) to avoid clashing with the native\n * form-associated `HTMLElement.labels` NodeList getter.\n */\nexport type PkImageBrowserLabelMode = 'tooltip' | 'inline' | 'none';\n\nexport type PkImageBrowserWidth = 'auto' | 'full';\n\n/**\n * One browsable entry. Plugins own filtering / filesystem scanning and pass\n * already-resolved preview URLs or inline SVG markup.\n */\nexport type PkImageBrowserItem = {\n value: string;\n label: string;\n /** Public URL for `<img>`, or inline `<svg>…</svg>` markup. */\n preview?: string;\n};\n\nexport type PkImageBrowserGroup = {\n name: string;\n items: PkImageBrowserItem[];\n};\n\nconst CHEVRON_ICON = renderIconHtml(chevronDown);\nconst XMARK_ICON = renderIconHtml(xmark);\n\n/** How many matched items per group are painted before scroll reveals more. */\nconst DEFAULT_PAGE_SIZE = 96;\n\nfunction isInlineSvg(preview: string): boolean {\n return /^\\s*<svg[\\s>]/i.test(preview);\n}\n\n/**\n * Image browser — presentational picker for static filesystem icons/images.\n *\n * Plugins supply `items` / `groups` (and optional `selected-label` /\n * `selected-preview` for the closed trigger before the catalog is ready). The\n * kit does not scan disks or filter extensions.\n *\n * Keyboard: trigger opens with Enter / Space / ArrowDown; search owns focus with\n * `aria-activedescendant`; arrows move the highlight (2D in the grid); Enter\n * selects; Escape closes.\n *\n * @csspart root - Filled control surface (trigger + clear + chevron)\n * @csspart trigger - Opens the panel (preview + label)\n * @csspart clear-button - Clear selection button (inside the control)\n * @csspart panel - Popup panel shell\n * @csspart panel-search - Search field container\n * @csspart panel-input - Search input\n * @csspart panel-body - Scrollable results region\n * @csspart loading - Catalog-loading status region (spinner)\n * @csspart option - Grid cell button\n *\n * @dependency pk-popup - Positioned panel host.\n * @dependency pk-spinner - Shown in the panel while `loading` is set.\n * @dependency pk-tooltip - Hover label when `label-mode=\"tooltip\"`.\n */\n@customElement('pk-image-browser')\nexport class PkImageBrowser extends PkFormAssociatedElement {\n static override styles = pkImageBrowserStyles;\n\n static override get validators() {\n return [...super.validators, MirrorValidator(), RequiredValidator()];\n }\n\n override assumeInteractionOn = ['pk-change'];\n\n @property({ reflect: true })\n size: PkImageBrowserSize = 'default';\n\n /** `icon` = compact glyph tiles; `image` = larger photo tiles. */\n @property({ reflect: true })\n mode: PkImageBrowserMode = 'icon';\n\n @property({ reflect: true })\n width: PkImageBrowserWidth = 'auto';\n\n /**\n * How option names appear in the grid: `tooltip` (default), `inline` under\n * each cell, or `none` (`aria-label` only).\n */\n @property({ reflect: true, attribute: 'label-mode' })\n labelMode: PkImageBrowserLabelMode = 'tooltip';\n\n @property({ type: Boolean, reflect: true })\n invalid = false;\n\n @property({ type: Boolean, reflect: true })\n readonly = false;\n\n @property()\n value = '';\n\n @property({ attribute: 'default-value' })\n defaultValue = '';\n\n @property()\n placeholder = 'Choose…';\n\n @property({ attribute: 'search-placeholder' })\n searchPlaceholder = 'Search…';\n\n @property({ attribute: 'empty-message' })\n emptyMessage = 'No items match your query.';\n\n @property({ attribute: 'aria-label' })\n ariaLabel: string | null = null;\n\n /**\n * Host-driven catalog warm / refresh. Shows a centered `pk-spinner` in the\n * panel (no loading copy). Prefer this over inferring from empty `items` /\n * `groups` — empty can also mean a filter miss or a genuinely empty catalog.\n */\n @property({ type: Boolean, reflect: true })\n loading = false;\n\n /** Show a clear control when a value is selected. */\n @property({ type: Boolean, reflect: true, attribute: 'with-clear' })\n withClear = true;\n\n @property({ attribute: false })\n items: PkImageBrowserItem[] = [];\n\n @property({ attribute: false })\n groups: PkImageBrowserGroup[] = [];\n\n /**\n * Closed-trigger label when `value` is set but not yet found in `items` /\n * `groups` (e.g. catalog still loading).\n */\n @property({ attribute: 'selected-label' })\n selectedLabel = '';\n\n /** Closed-trigger preview for the same pre-catalog case as `selected-label`. */\n @property({ attribute: 'selected-preview' })\n selectedPreview = '';\n\n @property({ reflect: true })\n placement: PkPopupPlacement = 'bottom-start';\n\n @property({ type: Number, attribute: 'side-offset' })\n sideOffset = 4;\n\n /** Items drawn per group before scroll reveals the next page. */\n @property({ type: Number, attribute: 'page-size' })\n pageSize = DEFAULT_PAGE_SIZE;\n\n @property({ type: Boolean, reflect: true })\n open = false;\n\n @state()\n private query = '';\n\n /** Render budget shared across groups — raised by scrolling, reset on query/open. */\n @state()\n private limit = DEFAULT_PAGE_SIZE;\n\n @state()\n private closing = false;\n\n @state()\n private panelAnimated = false;\n\n /** Flat index into `flatVisibleItems()` for aria-activedescendant navigation. */\n @state()\n private highlightedIndex = -1;\n\n /** Shared hover tooltip target when `labelMode=\"tooltip\"`. */\n @state()\n private tooltipFor = '';\n\n @state()\n private tooltipContent = '';\n\n @query('.value-input')\n override input!: HTMLInputElement;\n\n @query('.trigger')\n private triggerElement!: HTMLButtonElement;\n\n @query('.control')\n private controlElement!: HTMLDivElement;\n\n @query('pk-popup')\n private popupElement!: PkPopup;\n\n @query('.panel')\n private panelElement!: HTMLDivElement;\n\n @query('.panel-input')\n private searchInput!: HTMLInputElement | null;\n\n @query('.panel-body')\n private panelBody!: HTMLDivElement | null;\n\n @query('.option-tooltip')\n private optionTooltip!: PkTooltip | null;\n\n private readonly listboxId = uniqueId('pk-image-browser-listbox');\n private readonly searchId = uniqueId('pk-image-browser-search');\n private closeTimer: number | null = null;\n private tooltipOpenTimer: number | null = null;\n private liveRegion: LiveRegion | null = null;\n\n override connectedCallback(): void {\n super.connectedCallback();\n this.limit = this.normalizedPageSize();\n }\n\n override disconnectedCallback(): void {\n this.teardownDismissListeners();\n this.clearCloseTimer();\n this.clearTooltipOpenTimer();\n this.liveRegion?.destroy();\n this.liveRegion = null;\n super.disconnectedCallback();\n }\n\n protected override willUpdate(changed: PropertyValues): void {\n if (changed.has('pageSize') && !this.open) {\n this.limit = this.normalizedPageSize();\n }\n\n super.willUpdate(changed);\n }\n\n override updated(changed: PropertyValues): void {\n super.updated(changed);\n\n if (changed.has('open')) {\n if (this.open) {\n this.attachDismissListeners();\n } else if (!this.closing) {\n this.teardownDismissListeners();\n }\n }\n\n if ((changed.has('open') || changed.has('closing')) && (this.open || this.closing)) {\n void this.syncPanelPlacement();\n }\n\n if (this.open && (changed.has('highlightedIndex') || changed.has('query') || changed.has('limit'))) {\n this.scrollHighlightedIntoView();\n }\n\n // Catalog arrived while the panel is open — seat highlight on selection / first cell.\n if (this.open && changed.has('loading') && !this.loading) {\n this.resetHighlightForOpenCatalog();\n }\n }\n\n protected override get validationTarget(): HTMLElement {\n return this.triggerElement ?? this;\n }\n\n protected override syncFormValue(): void {\n this.setFormValue(this.value, this.value);\n }\n\n protected override resetToDefaultValue(): void {\n this.value = this.defaultValue;\n }\n\n protected override restoreFormState(state: string | File | FormData | null): void {\n if (typeof state === 'string') {\n this.value = state;\n }\n }\n\n async show(): Promise<void> {\n if (this.open || this.closing || this.disabled || this.readonly) {\n return;\n }\n\n await this.openPanel();\n }\n\n async hide(source: PkOverlaySource = 'api'): Promise<void> {\n if (!this.open || this.closing) {\n return;\n }\n\n await this.closePanel(source);\n }\n\n private optionId(index: number): string {\n return `${this.listboxId}-opt-${index}`;\n }\n\n private groupHeadingId(groupIndex: number): string {\n return `${this.listboxId}-group-${groupIndex}`;\n }\n\n private normalizedPageSize(): number {\n return this.pageSize > 0 ? this.pageSize : DEFAULT_PAGE_SIZE;\n }\n\n private resolveGroups(): PkImageBrowserGroup[] {\n if (this.groups.length > 0) {\n return this.groups;\n }\n\n if (this.items.length > 0) {\n return [{ name: '', items: this.items }];\n }\n\n return [];\n }\n\n private findItem(value: string): PkImageBrowserItem | null {\n if (value === '') {\n return null;\n }\n\n for (const group of this.resolveGroups()) {\n const found = group.items.find((item) => item.value === value);\n if (found) {\n return found;\n }\n }\n\n return null;\n }\n\n private selectedItem(): PkImageBrowserItem | null {\n return this.findItem(this.value);\n }\n\n private triggerDisplay(): { label: string; preview?: string; isPlaceholder: boolean } {\n const selected = this.selectedItem();\n if (selected) {\n return {\n label: selected.label,\n preview: selected.preview,\n isPlaceholder: false,\n };\n }\n\n if (this.value !== '') {\n return {\n label: this.selectedLabel || this.value,\n preview: this.selectedPreview || undefined,\n isPlaceholder: false,\n };\n }\n\n return {\n label: this.placeholder,\n isPlaceholder: true,\n };\n }\n\n /** Groups matching the query, each truncated to the current render budget. */\n private visibleGroups(): Array<PkImageBrowserGroup & { total: number }> {\n const query = this.query.trim().toLowerCase();\n\n return this.resolveGroups().reduce<Array<PkImageBrowserGroup & { total: number }>>((acc, group) => {\n const matched = query === ''\n ? group.items\n : group.items.filter((item) => (\n item.label.toLowerCase().includes(query)\n || item.value.toLowerCase().includes(query)\n ));\n\n if (matched.length === 0) {\n return acc;\n }\n\n acc.push({\n name: group.name,\n total: matched.length,\n items: matched.slice(0, this.limit),\n });\n return acc;\n }, []);\n }\n\n private flatVisibleItems(): PkImageBrowserItem[] {\n return this.visibleGroups().flatMap((group) => group.items);\n }\n\n private isTruncated(): boolean {\n return this.visibleGroups().some((group) => group.items.length < group.total);\n }\n\n private activeDescendantId(): string | null {\n if (!this.open || this.highlightedIndex < 0) {\n return null;\n }\n\n return this.optionId(this.highlightedIndex);\n }\n\n private triggerAccessibleName(): string {\n if (this.ariaLabel) {\n const display = this.triggerDisplay();\n if (display.isPlaceholder) {\n return this.ariaLabel;\n }\n return `${this.ariaLabel}, ${display.label}`;\n }\n\n return this.triggerDisplay().label;\n }\n\n private announceResults(): void {\n // Skip while the host is still warming — empty would read as \"no matches\".\n if (this.loading) {\n return;\n }\n\n const items = this.flatVisibleItems();\n const filter = this.query.trim();\n\n if (!filter) {\n return;\n }\n\n if (!this.liveRegion) {\n this.liveRegion = new LiveRegion('polite');\n }\n\n this.liveRegion.announce(\n items.length === 0\n ? this.emptyMessage\n : `${items.length} ${items.length === 1 ? 'result' : 'results'} available`,\n );\n }\n\n private resetHighlightForOpenCatalog(): void {\n const items = this.flatVisibleItems();\n if (items.length === 0) {\n this.highlightedIndex = -1;\n return;\n }\n\n const selectedIdx = items.findIndex((item) => item.value === this.value);\n this.highlightedIndex = selectedIdx >= 0 ? selectedIdx : 0;\n }\n\n private setHighlightedIndex(index: number): void {\n const items = this.flatVisibleItems();\n if (items.length === 0) {\n this.highlightedIndex = -1;\n return;\n }\n\n const next = Math.max(0, Math.min(index, items.length - 1));\n this.highlightedIndex = next;\n\n // Navigating near the end of a truncated catalog should reveal more, same as scroll.\n if (next >= items.length - 4 && this.isTruncated()) {\n this.limit += this.normalizedPageSize();\n }\n }\n\n private scrollHighlightedIntoView(): void {\n if (this.highlightedIndex < 0 || !this.panelBody) {\n return;\n }\n\n const option = this.renderRoot.querySelector<HTMLElement>(\n `#${CSS.escape(this.optionId(this.highlightedIndex))}`,\n );\n if (!option) {\n return;\n }\n\n scrollIntoView(option, this.panelBody, 'vertical', 'auto');\n }\n\n /** Column count of the CSS grid that owns the highlighted option (for 2D arrows). */\n private columnCountNear(index: number): number {\n const option = this.renderRoot.querySelector<HTMLElement>(\n `#${CSS.escape(this.optionId(index))}`,\n );\n const grid = option?.closest('.grid');\n if (!grid) {\n return 1;\n }\n\n const options = [...grid.querySelectorAll<HTMLElement>('.option')];\n if (options.length === 0) {\n return 1;\n }\n\n const firstTop = options[0]!.offsetTop;\n let cols = 0;\n for (const candidate of options) {\n if (candidate.offsetTop !== firstTop) {\n break;\n }\n cols += 1;\n }\n\n return Math.max(1, cols);\n }\n\n private moveHighlight(key: string): void {\n const items = this.flatVisibleItems();\n if (items.length === 0) {\n this.highlightedIndex = -1;\n return;\n }\n\n let next = this.highlightedIndex;\n\n if (next < 0) {\n next = (key === 'ArrowUp' || key === 'ArrowLeft' || key === 'End')\n ? items.length - 1\n : 0;\n this.setHighlightedIndex(next);\n return;\n }\n\n const cols = this.columnCountNear(next);\n\n switch (key) {\n case 'ArrowRight':\n next = Math.min(next + 1, items.length - 1);\n break;\n case 'ArrowLeft':\n next = Math.max(next - 1, 0);\n break;\n case 'ArrowDown':\n next = Math.min(next + cols, items.length - 1);\n break;\n case 'ArrowUp':\n next = Math.max(next - cols, 0);\n break;\n case 'Home':\n next = 0;\n break;\n case 'End':\n next = items.length - 1;\n break;\n default:\n return;\n }\n\n this.setHighlightedIndex(next);\n }\n\n private emitChange(next: string): void {\n this.value = next;\n this.syncFormValue();\n this.updateValidity();\n\n this.dispatchEvent(new CustomEvent('pk-change', {\n detail: { value: next },\n bubbles: true,\n composed: true,\n }));\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));\n }\n\n private selectValue(next: string): void {\n if (this.disabled || this.readonly) {\n return;\n }\n\n const previous = this.value;\n void this.closePanel('api');\n this.query = '';\n this.limit = this.normalizedPageSize();\n this.highlightedIndex = -1;\n\n // Re-clicking the active option clears it (same as the trigger clear control).\n if (previous === next) {\n if (this.withClear && previous !== '') {\n this.emitChange('');\n this.dispatchEvent(new PkClearEvent());\n }\n return;\n }\n\n this.emitChange(next);\n }\n\n private handleClear = (event: Event): void => {\n event.preventDefault();\n event.stopPropagation();\n\n if (this.disabled || this.readonly || this.value === '') {\n return;\n }\n\n this.emitChange('');\n this.dispatchEvent(new PkClearEvent());\n this.triggerElement?.focus({ preventScroll: true });\n };\n\n private togglePanel = (event?: Event): void => {\n event?.preventDefault();\n event?.stopPropagation();\n\n if (this.disabled || this.readonly) {\n return;\n }\n\n if (this.open || this.closing) {\n void this.closePanel('api');\n } else {\n void this.openPanel();\n }\n };\n\n private handleTriggerKeyDown = (event: KeyboardEvent): void => {\n if (this.disabled || this.readonly) {\n return;\n }\n\n if (\n event.key === 'ArrowDown'\n || event.key === 'ArrowUp'\n || event.key === 'Enter'\n || event.key === ' '\n ) {\n event.preventDefault();\n if (!this.open && !this.closing) {\n void this.openPanel();\n }\n }\n };\n\n private async openPanel(): Promise<void> {\n if (this.open || this.closing || this.disabled || this.readonly) {\n return;\n }\n\n this.dispatchEvent(new PkShowEvent());\n this.closing = false;\n this.panelAnimated = false;\n this.query = '';\n this.limit = this.normalizedPageSize();\n this.open = true;\n this.resetHighlightForOpenCatalog();\n\n await this.updateComplete;\n await this.syncPanelPlacement();\n this.panelAnimated = true;\n this.dispatchEvent(new PkAfterShowEvent());\n await this.focusSearchWhenReady();\n this.scrollHighlightedIntoView();\n }\n\n private async closePanel(source: PkOverlaySource): Promise<void> {\n if (!this.open || this.closing) {\n return;\n }\n\n const hideEvent = new PkHideEvent(source);\n this.dispatchEvent(hideEvent);\n if (hideEvent.defaultPrevented) {\n return;\n }\n\n this.closing = true;\n this.open = false;\n this.highlightedIndex = -1;\n this.clearOptionTooltip();\n this.teardownDismissListeners();\n this.triggerElement?.focus({ preventScroll: true });\n\n this.clearCloseTimer();\n this.closeTimer = window.setTimeout(() => {\n this.closing = false;\n this.panelAnimated = false;\n this.query = '';\n this.limit = this.normalizedPageSize();\n this.closeTimer = null;\n this.dispatchEvent(new PkAfterHideEvent());\n }, 100);\n }\n\n private clearCloseTimer(): void {\n if (this.closeTimer != null) {\n window.clearTimeout(this.closeTimer);\n this.closeTimer = null;\n }\n }\n\n private async syncPanelPlacement(): Promise<void> {\n if (!this.popupElement || !this.panelElement) {\n return;\n }\n\n syncPopupPlacementAnimation(this.panelElement, this.placement);\n const placement = await waitForPopupReposition(this.popupElement, this.placement, 300, {\n requireEvent: true,\n });\n syncPopupPlacementAnimation(this.panelElement, placement);\n }\n\n private attachDismissListeners(): void {\n registerDismissible(this);\n document.addEventListener('pointerdown', this.onDocumentPointerDown, true);\n document.addEventListener('keydown', this.onDocumentKeyDown, true);\n }\n\n private teardownDismissListeners(): void {\n unregisterDismissible(this);\n document.removeEventListener('pointerdown', this.onDocumentPointerDown, true);\n document.removeEventListener('keydown', this.onDocumentKeyDown, true);\n }\n\n private onDocumentPointerDown = (event: PointerEvent): void => {\n if (!this.open || this.closing || !isTopDismissible(this)) {\n return;\n }\n\n if (isPointerInsideOverlay(event, {\n host: this,\n anchor: this.controlElement ?? this.triggerElement,\n panel: this.panelElement,\n })) {\n return;\n }\n\n void this.closePanel('pointer-dismiss');\n };\n\n private onDocumentKeyDown = (event: KeyboardEvent): void => {\n if (!this.open || this.closing || !isTopDismissible(this)) {\n return;\n }\n\n if (event.key === 'Escape') {\n event.preventDefault();\n event.stopPropagation();\n void this.closePanel('escape');\n }\n };\n\n private handleSearchInput = (event: Event): void => {\n if (this.loading) {\n return;\n }\n\n this.query = (event.target as HTMLInputElement).value;\n // New query = new set; don't keep a tall scroll budget from the previous browse.\n this.limit = this.normalizedPageSize();\n this.resetHighlightForOpenCatalog();\n this.announceResults();\n };\n\n private handleSearchKeyDown = (event: KeyboardEvent): void => {\n if (!this.open || this.closing || this.loading) {\n return;\n }\n\n switch (event.key) {\n case 'ArrowDown':\n case 'ArrowUp':\n case 'ArrowLeft':\n case 'ArrowRight':\n case 'Home':\n case 'End':\n event.preventDefault();\n event.stopPropagation();\n this.moveHighlight(event.key);\n return;\n case 'Enter': {\n event.preventDefault();\n event.stopPropagation();\n const items = this.flatVisibleItems();\n const item = items[this.highlightedIndex];\n if (item) {\n this.selectValue(item.value);\n }\n return;\n }\n default:\n break;\n }\n };\n\n private handleResultsScroll = (): void => {\n // Tip can trail a scrolled-away cell; drop it and let hover re-open.\n this.clearOptionTooltip();\n\n const results = this.panelBody;\n if (!results || !this.isTruncated()) {\n return;\n }\n\n if (results.scrollTop + results.clientHeight < results.scrollHeight - 200) {\n return;\n }\n\n const anchor = results.scrollTop;\n this.limit += this.normalizedPageSize();\n void this.updateComplete.then(() => {\n if (this.panelBody) {\n this.panelBody.scrollTop = anchor;\n }\n });\n };\n\n private async focusSearchWhenReady(): Promise<void> {\n const started = performance.now();\n while (this.open && performance.now() - started < 2000) {\n const input = this.searchInput;\n if (input && getComputedStyle(input).visibility !== 'hidden') {\n input.focus({ preventScroll: true });\n if (document.activeElement === input) {\n return;\n }\n }\n await new Promise<void>((resolve) => requestAnimationFrame(() => resolve()));\n }\n }\n\n private renderPreview(preview: string | undefined, className: string) {\n if (!preview) {\n return nothing;\n }\n\n if (isInlineSvg(preview)) {\n return html`<span class=${className} aria-hidden=\"true\">${unsafeSVG(preview)}</span>`;\n }\n\n return html`<img class=${className} src=${preview} alt=\"\" />`;\n }\n\n private usesInlineLabels(): boolean {\n return this.labelMode === 'inline';\n }\n\n private usesTooltipLabels(): boolean {\n return this.labelMode === 'tooltip';\n }\n\n /** Hover caption via one shared tooltip — avoids N×pk-tooltip in large catalogs. */\n private showOptionTooltip(optionId: string, label: string): void {\n if (!this.usesTooltipLabels()) {\n return;\n }\n\n // Already tracking a cell → re-anchor immediately; first hover waits so scans don’t flash.\n const alreadyTracking = this.tooltipFor !== '';\n this.tooltipFor = optionId;\n this.tooltipContent = label;\n this.clearTooltipOpenTimer();\n\n const openNow = (): void => {\n this.tooltipOpenTimer = null;\n void this.updateComplete.then(() => {\n void this.optionTooltip?.show();\n });\n };\n\n if (alreadyTracking) {\n openNow();\n return;\n }\n\n this.tooltipOpenTimer = window.setTimeout(openNow, 280);\n }\n\n private clearOptionTooltip(): void {\n this.clearTooltipOpenTimer();\n this.tooltipFor = '';\n this.tooltipContent = '';\n void this.optionTooltip?.hide();\n }\n\n private clearTooltipOpenTimer(): void {\n if (this.tooltipOpenTimer != null) {\n window.clearTimeout(this.tooltipOpenTimer);\n this.tooltipOpenTimer = null;\n }\n }\n\n private handleOptionPointerEnter(index: number, label: string): void {\n this.highlightedIndex = index;\n this.showOptionTooltip(this.optionId(index), label);\n }\n\n private handleOptionPointerLeave = (event: MouseEvent): void => {\n const next = event.relatedTarget;\n const movingToNeighbor = next instanceof Node\n && this.panelBody?.contains(next)\n && Boolean(\n next instanceof Element\n ? next.closest('.option')\n : next.parentElement?.closest('.option'),\n );\n\n if (movingToNeighbor) {\n return;\n }\n\n // Leave the grid — drop sticky hover chrome back onto the selected cell (or none).\n this.resetHighlightToSelected();\n this.clearOptionTooltip();\n };\n\n private resetHighlightToSelected(): void {\n const items = this.flatVisibleItems();\n if (items.length === 0) {\n this.highlightedIndex = -1;\n return;\n }\n\n const selectedIdx = items.findIndex((item) => item.value === this.value);\n this.highlightedIndex = selectedIdx;\n }\n\n private renderTriggerContents() {\n const display = this.triggerDisplay();\n\n return html`\n <span class=\"trigger-main\">\n ${this.renderPreview(display.preview, 'trigger-preview')}\n <span\n class=${classMap({\n 'trigger-label': true,\n 'is-placeholder': display.isPlaceholder,\n })}\n aria-hidden=\"true\"\n >${display.label}</span>\n </span>\n `;\n }\n\n private renderResults() {\n if (this.loading) {\n return html`\n <div\n id=${this.listboxId}\n role=\"listbox\"\n aria-label=${this.ariaLabel || 'Options'}\n aria-busy=\"true\"\n >\n <div part=\"loading\" class=\"loading\" role=\"status\" aria-label=\"Loading\">\n <pk-spinner size=\"sm\" centered></pk-spinner>\n </div>\n </div>\n `;\n }\n\n const groups = this.visibleGroups();\n\n if (groups.length === 0) {\n return html`\n <div\n id=${this.listboxId}\n role=\"listbox\"\n aria-label=${this.ariaLabel || 'Options'}\n >\n <p class=\"notice\" part=\"empty\" role=\"status\">${this.emptyMessage}</p>\n </div>\n `;\n }\n\n let flatIndex = 0;\n\n return html`\n <div\n id=${this.listboxId}\n role=\"listbox\"\n aria-label=${this.ariaLabel || 'Options'}\n >\n ${groups.map((group, groupIndex) => {\n const headingId = this.groupHeadingId(groupIndex);\n const groupStart = flatIndex;\n\n const options = group.items.map((item, itemIndex) => {\n const index = groupStart + itemIndex;\n flatIndex = index + 1;\n const selected = item.value === this.value;\n const highlighted = index === this.highlightedIndex;\n\n return html`\n <button\n type=\"button\"\n part=\"option\"\n id=${this.optionId(index)}\n class=${classMap({\n option: true,\n 'is-highlighted': highlighted,\n 'is-selected': selected,\n })}\n role=\"option\"\n tabindex=\"-1\"\n aria-label=${item.label}\n aria-selected=${selected ? 'true' : 'false'}\n @click=${() => this.selectValue(item.value)}\n @mouseenter=${() => this.handleOptionPointerEnter(index, item.label)}\n @mouseleave=${this.handleOptionPointerLeave}\n >\n ${this.renderPreview(item.preview, 'option-preview')}\n ${this.usesInlineLabels()\n ? html`<span class=\"option-label\" aria-hidden=\"true\">${item.label}</span>`\n : nothing}\n </button>\n `;\n });\n\n return html`\n <div\n class=\"group\"\n role=${group.name ? 'group' : nothing}\n aria-labelledby=${group.name ? headingId : nothing}\n >\n ${group.name\n ? html`\n <h6 class=\"group-heading\" id=${headingId}>\n <span>${group.name}</span>\n ${group.items.length < group.total\n ? html`\n <span class=\"group-heading-count\">\n Showing ${group.items.length} of ${group.total}\n </span>\n `\n : nothing}\n </h6>\n `\n : nothing}\n <div class=\"grid\">\n ${options}\n </div>\n </div>\n `;\n })}\n </div>\n `;\n }\n\n override render() {\n const showClear = this.withClear && this.value !== '' && !this.disabled && !this.readonly;\n const panelActive = this.open || this.closing;\n const activeDescendant = this.activeDescendantId();\n\n return html`\n <input\n class=\"value-input\"\n part=\"value-input\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n .value=${this.value}\n ?required=${this.required}\n @input=${() => this.updateValidity()}\n />\n <div\n part=\"root\"\n class=${classMap({\n control: true,\n 'is-disabled': this.disabled || this.readonly,\n 'is-open': this.open,\n })}\n >\n <button\n type=\"button\"\n part=\"trigger\"\n class=\"trigger\"\n ?disabled=${this.disabled || this.readonly}\n aria-label=${this.triggerAccessibleName()}\n aria-haspopup=\"listbox\"\n aria-expanded=${this.open ? 'true' : 'false'}\n aria-controls=${this.listboxId}\n @click=${this.togglePanel}\n @keydown=${this.handleTriggerKeyDown}\n >\n ${this.renderTriggerContents()}\n </button>\n ${showClear\n ? html`\n <button\n type=\"button\"\n part=\"clear-button\"\n class=\"clear-button\"\n aria-label=\"Clear selection\"\n ?disabled=${this.disabled}\n @click=${this.handleClear}\n >\n <span class=\"clear-button-icon\" aria-hidden=\"true\">${unsafeSVG(XMARK_ICON)}</span>\n </button>\n `\n : nothing}\n <button\n type=\"button\"\n class=\"expand-button\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n ?disabled=${this.disabled || this.readonly}\n @click=${this.togglePanel}\n >\n <span class=\"expand-button-icon\">${unsafeSVG(CHEVRON_ICON)}</span>\n </button>\n </div>\n <pk-popup\n .active=${panelActive}\n .anchor=${this.controlElement ?? this.triggerElement ?? ''}\n .placement=${this.placement}\n .distance=${this.sideOffset}\n flip\n shift\n >\n <div\n part=\"panel\"\n class=${classMap({\n panel: true,\n 'pk-popup-content': true,\n closing: this.closing,\n })}\n tabindex=\"-1\"\n ?hidden=${!panelActive}\n data-open=${this.panelAnimated && !this.closing ? '' : nothing}\n >\n <div part=\"panel-search\" class=\"panel-search\">\n <input\n part=\"panel-input\"\n class=\"panel-input\"\n id=${this.searchId}\n type=\"text\"\n role=\"combobox\"\n .value=${this.query}\n placeholder=${this.searchPlaceholder}\n aria-label=${this.searchPlaceholder}\n aria-autocomplete=\"list\"\n aria-expanded=${this.open ? 'true' : 'false'}\n aria-controls=${this.listboxId}\n aria-activedescendant=${activeDescendant ?? nothing}\n ?disabled=${this.loading}\n @input=${this.handleSearchInput}\n @keydown=${this.handleSearchKeyDown}\n />\n </div>\n <div\n part=\"panel-body\"\n class=\"panel-body\"\n @scroll=${this.handleResultsScroll}\n >\n ${this.renderResults()}\n </div>\n ${this.usesTooltipLabels() && panelActive\n ? html`\n <pk-tooltip\n class=\"option-tooltip\"\n for=${this.tooltipFor}\n content=${this.tooltipContent}\n placement=\"top\"\n trigger=\"manual\"\n ></pk-tooltip>\n `\n : nothing}\n </div>\n </pk-popup>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'pk-image-browser': PkImageBrowser;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pk-radio-group-ByrxGLdX.js","names":[],"sources":["../../src/components/radio-group/pk-radio-group.styles.ts","../../src/components/radio-group/pk-radio-group.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const pkRadioGroupStyles = css`\n @layer pk-component {\n :host {\n display: block;\n font-family: var(--pk-font-family);\n font-size: var(--pk-font-size-base);\n line-height: var(--pk-line-height);\n }\n\n .group {\n display: grid;\n gap: 0.375rem;\n }\n\n .group--horizontal {\n grid-auto-flow: column;\n grid-auto-columns: max-content;\n align-items: center;\n }\n }\n`;\n","import { html, nothing } from 'lit';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { customElement, property, query, state } from '../../decorators.js';\nimport type { PropertyValues } from 'lit';\n\nimport { formControlStyles } from '../../base/form-control.styles.js';\nimport { PkFormAssociatedElement } from '../../base/pk-form-associated-element.js';\nimport { HasSlotController } from '../../internal/has-slot.js';\nimport { hasInstructionContent, readLegacyInstructions } from '../../internal/field-labels.js';\nimport { RequiredValidator } from '../../validators/index.js';\nimport type { PkRadio } from './pk-radio.js';\nimport { pkRadioGroupStyles } from './pk-radio-group.styles.js';\n\nexport type PkRadioGroupOrientation = 'horizontal' | 'vertical';\n\n/**\n * Radio group — pattern: light-DOM `pk-radio` children, shared value + validation.\n *\n * @slot label - Group label\n * @slot instructions - Instructions text\n * @slot hint - Alias for `instructions`\n * @slot - `pk-radio` items\n *\n * @csspart form-control - Form control wrapper\n * @csspart label - Label text\n * @csspart radios - Radio items container\n * @csspart instructions - Instructions text\n */\n@customElement('pk-radio-group')\nexport class PkRadioGroup extends PkFormAssociatedElement {\n static override shadowRootOptions: ShadowRootInit = {\n mode: 'open',\n delegatesFocus: true,\n };\n\n static override styles = [formControlStyles, pkRadioGroupStyles];\n\n static override get validators() {\n return [...super.validators, RequiredValidator()];\n }\n\n override assumeInteractionOn = ['change'];\n\n private readonly hasSlotController = new HasSlotController(this, 'instructions', 'hint', 'label');\n\n private _value: string | null = null;\n\n get value(): string {\n if (this.valueHasChanged) {\n return this._value ?? '';\n }\n\n return this._value ?? this.defaultValue ?? '';\n }\n\n set value(val: string | null) {\n this._value = val == null ? null : String(val);\n this.valueHasChanged = true;\n }\n\n /** Default value — reflected as the `value` attribute. */\n @property({ attribute: 'value', reflect: true })\n defaultValue = '';\n\n @property({ reflect: true })\n orientation: PkRadioGroupOrientation = 'vertical';\n\n @property({ type: Boolean, reflect: true })\n invalid = false;\n\n @property()\n label = '';\n\n @property()\n instructions = '';\n\n @property({ attribute: 'aria-label' })\n override ariaLabel: string | null = null;\n\n @query('slot:not([name])')\n private defaultSlot!: HTMLSlotElement;\n\n @state()\n private items: PkRadio[] = [];\n\n protected override syncFormValue(): void {\n this.setFormValue(this.value || null);\n }\n\n protected override resetToDefaultValue(): void {\n this._value = null;\n this.applySelection();\n }\n\n protected override restoreFormState(state: string | File | FormData | null): void {\n if (typeof state === 'string') {\n this.value = state;\n this.applySelection();\n }\n }\n\n protected override get validationTarget(): HTMLElement | undefined {\n return this.getAllRadios().find((item) => !item.disabled) ?? this.getAllRadios()[0];\n }\n\n override connectedCallback(): void {\n this.instructions = readLegacyInstructions(this, this.instructions);\n super.connectedCallback();\n this.addEventListener('keydown', this.handleKeyDown);\n this.addEventListener('click', this.handleRadioClick);\n }\n\n override disconnectedCallback(): void {\n this.removeEventListener('keydown', this.handleKeyDown);\n this.removeEventListener('click', this.handleRadioClick);\n super.disconnectedCallback();\n }\n\n override updated(changed: PropertyValues): void {\n if (changed.has('value') || changed.has('disabled') || changed.has('invalid') || changed.has('name')) {\n this.applySelection();\n }\n\n super.updated(changed);\n }\n\n override formResetCallback(): void {\n this._value = null;\n super.formResetCallback();\n this.applySelection();\n }\n\n override focus(options?: FocusOptions): void {\n if (this.disabled) {\n return;\n }\n\n const radios = this.getEnabledItems();\n const checked = radios.find((radio) => radio.checked);\n const target = checked ?? radios[0];\n target?.focusControl(options);\n }\n\n private getAllRadios(): PkRadio[] {\n return [...this.querySelectorAll('pk-radio')];\n }\n\n private syncItems = (): void => {\n this.items = this.getAllRadios();\n this.applySelection();\n };\n\n private getEnabledItems(): PkRadio[] {\n return this.items.filter((item) => !item.disabled && !this.disabled);\n }\n\n private applySelection(): void {\n const radios = this.getAllRadios();\n this.items = radios;\n\n const enabled = this.getEnabledItems();\n const checkedRadio = enabled.find((item) => item.value === this.value);\n\n for (const item of radios) {\n const checked = item.value === this.value;\n // React sets CE booleans as properties, while hand-written HTML uses attributes.\n // Preserve item-level disabled state from either source, but do not let a prior\n // group-level disabled pass permanently mark every child disabled.\n const itemDisabled = item.hasAttribute('disabled') || (item.disabled && !item.forceDisabled);\n item.checked = checked;\n item.disabled = this.disabled || itemDisabled;\n item.invalid = this.invalid;\n item.required = this.required;\n item.forceDisabled = this.disabled;\n }\n\n if (this.disabled) {\n for (const item of radios) {\n item.tabIndex = -1;\n }\n return;\n }\n\n if (checkedRadio) {\n for (const item of enabled) {\n item.tabIndex = item.checked ? 0 : -1;\n }\n } else if (enabled.length > 0) {\n enabled.forEach((item, index) => {\n item.tabIndex = index === 0 ? 0 : -1;\n });\n }\n\n for (const item of radios.filter((radio) => radio.disabled)) {\n item.tabIndex = -1;\n }\n }\n\n private handleRadioClick = (event: Event): void => {\n const clickedRadio = (event.target as HTMLElement).closest('pk-radio') as PkRadio | null;\n\n if (!clickedRadio || clickedRadio.disabled || clickedRadio.forceDisabled || this.disabled) {\n return;\n }\n\n const oldValue = this.value;\n this.value = clickedRadio.value;\n this.applySelection();\n\n if (this.value !== oldValue) {\n this.emitValueChange();\n }\n };\n\n private handleKeyDown = (event: KeyboardEvent): void => {\n if (!['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', ' ', 'Home', 'End'].includes(event.key) || this.disabled) {\n return;\n }\n\n const radios = this.getEnabledItems();\n\n if (radios.length === 0) {\n return;\n }\n\n event.preventDefault();\n\n const oldValue = this.value;\n const checkedRadio = radios.find((radio) => radio.checked) ?? radios[0]!;\n let index = radios.indexOf(checkedRadio);\n\n if (event.key === ' ') {\n // Space selects focused radio without moving\n } else if (event.key === 'Home') {\n index = 0;\n } else if (event.key === 'End') {\n index = radios.length - 1;\n } else {\n const increment = ['ArrowUp', 'ArrowLeft'].includes(event.key) ? -1 : 1;\n index += increment;\n\n if (index < 0) {\n index = radios.length - 1;\n }\n\n if (index >= radios.length) {\n index = 0;\n }\n }\n\n this.value = radios[index]!.value;\n this.applySelection();\n radios[index]!.focusControl();\n\n if (this.value !== oldValue) {\n this.emitValueChange();\n }\n };\n\n private emitValueChange(): void {\n this.dispatchEvent(new CustomEvent('pk-change', {\n detail: { value: this.value },\n bubbles: true,\n composed: true,\n }));\n\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));\n }\n\n override render() {\n const hasLabelSlot = this.hasSlotController.test('label');\n const hasInstructions = hasInstructionContent(\n (name, flag) => this.hasSlotController.test(name, flag),\n this.instructions,\n );\n const hasLabel = Boolean(this.label) || hasLabelSlot;\n\n return html`\n <div part=\"form-control\" class=\"form-control\">\n ${hasLabel\n ? html`\n <div part=\"label\" class=\"form-control__label\" id=\"label\">\n <slot name=\"label\">${this.label}</slot>\n </div>\n `\n : nothing}\n\n ${hasInstructions\n ? html`\n <div part=\"instructions\" class=\"form-control__instructions\" id=\"instructions\">\n <slot name=\"instructions\">${this.instructions}</slot>\n <slot name=\"hint\"></slot>\n </div>\n `\n : nothing}\n\n <div\n part=\"radios\"\n class=${classMap({\n group: true,\n 'pk-radio-group': true,\n 'group--horizontal': this.orientation === 'horizontal',\n 'pk-radio-group--horizontal': this.orientation === 'horizontal',\n })}\n role=\"radiogroup\"\n aria-labelledby=${hasLabel ? 'label' : nothing}\n aria-label=${!hasLabel ? (this.ariaLabel ?? nothing) : nothing}\n aria-describedby=${hasInstructions ? 'instructions' : nothing}\n aria-invalid=${this.invalid ? 'true' : nothing}\n aria-required=${this.required ? 'true' : nothing}\n >\n <slot @slotchange=${this.syncItems}></slot>\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'pk-radio-group': PkRadioGroup;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pk-select-CdQdhnZN.js","names":[],"sources":["../../src/components/select/pk-select.styles.ts","../../src/components/select/pk-select.ts"],"sourcesContent":["import { css } from 'lit';\n\nimport { iconStyles } from '../../base/icon.styles.js';\nimport { popupContentAnimationStyles } from '../../styles/popup-content-animation.styles.js';\n\nexport const pkSelectStyles = [\n popupContentAnimationStyles,\n css`\n ${iconStyles}\n @layer pk-component {\n :host {\n display: inline-block;\n position: relative;\n width: fit-content;\n max-width: 100%;\n align-self: flex-start;\n flex: none;\n color: var(--pk-color-gray-700);\n font-family: var(--pk-font-family);\n font-size: var(--pk-font-size-base);\n line-height: var(--pk-line-height);\n --pk-select-trigger-border-width: 1px;\n --pk-select-item-min-height: var(--pk-input-height);\n --pk-select-item-padding-block: 6px;\n --pk-select-item-padding-inline: 10px;\n --pk-select-item-padding-inline-end: 2rem;\n --pk-select-item-font-size: var(--pk-font-size-base);\n --pk-select-item-line-height: var(--pk-input-control-line-height, 1.25rem);\n --pk-select-item-indicator-size: 0.75rem;\n --pk-select-item-indicator-inset: 0.5rem;\n /* v1 SelectLabel default: text-xs → 12px */\n --pk-select-group-label-font-size: 12px;\n --pk-select-decoration-size: 0.875rem;\n }\n\n :host([width='full']) {\n display: block;\n width: 100%;\n }\n\n :host([width='full']) .control {\n width: 100%;\n }\n\n :host([width='full']) button.control .icon {\n margin-inline-start: auto;\n }\n\n .control {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n /* Fill the host when consumers set min-width/width on :host. */\n width: 100%;\n max-width: 100%;\n min-width: 0;\n margin: 0;\n padding: var(--pk-select-item-padding-block) var(--pk-select-item-padding-inline);\n border: var(--pk-select-trigger-border-width) solid transparent;\n border-radius: var(--pk-radius-lg);\n --pk-select-fill: var(--pk-color-slate-250);\n --pk-select-fill-hover: var(--pk-color-slate-300);\n background: var(--pk-select-fill);\n color: var(--pk-color-gray-700);\n font: inherit;\n font-size: var(--pk-select-item-font-size);\n line-height: var(--pk-input-control-line-height, 1.25rem);\n white-space: nowrap;\n cursor: pointer;\n outline: none;\n box-sizing: border-box;\n transition: border-color 0.12s ease, box-shadow 0.12s ease, background 0.12s ease;\n }\n\n button.control {\n appearance: none;\n -webkit-appearance: none;\n text-align: left;\n background-color: var(--pk-select-fill);\n border: var(--pk-select-trigger-border-width) solid transparent;\n }\n\n :host(:not([disabled])) .control:hover:not(.is-disabled):not(:disabled),\n :host(:not([disabled])) button.control:hover:not(.is-disabled):not(:disabled) {\n background: var(--pk-select-fill-hover);\n }\n\n :host(:not([disabled])) button.control:hover:not(.is-disabled):not(:disabled) {\n background-color: var(--pk-select-fill-hover);\n }\n\n :host(:not([invalid]):not(:state(user-invalid))) button.control:focus-visible,\n :host(:not([invalid]):not(:state(user-invalid))[data-state='focus-visible']) button.control {\n border-color: var(--pk-color-sky-600);\n box-shadow: var(--pk-input-focus-shadow);\n }\n\n .control.is-disabled {\n cursor: not-allowed;\n opacity: 0.5;\n }\n\n .trigger {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: 0 0 auto;\n min-width: 0;\n padding: 0;\n border: 0;\n background: transparent;\n color: inherit;\n font: inherit;\n cursor: inherit;\n outline: none;\n }\n\n .control > .trigger:not(.trigger--icon) {\n flex: 0 1 auto;\n justify-content: flex-start;\n }\n\n .trigger--icon {\n width: 1.25rem;\n }\n\n .trigger-start {\n display: none;\n flex: 0 0 auto;\n align-items: center;\n }\n\n .trigger-start.has-decoration {\n display: inline-flex;\n }\n\n .control-start,\n .control-end {\n display: inline-flex;\n align-items: center;\n flex-shrink: 0;\n line-height: 0;\n color: var(--pk-color-gray-600);\n }\n\n slot[name='start']::slotted(svg),\n slot[name='end']::slotted(svg) {\n width: var(--pk-select-decoration-size);\n height: var(--pk-select-decoration-size);\n }\n\n .value {\n flex: 1 1 auto;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n text-align: left;\n }\n\n .icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n line-height: 0;\n pointer-events: none;\n color: var(--pk-color-gray-600);\n }\n\n /* Extra space before the expand chevron (control gap stays for start icon ↔ label). */\n .control > .icon,\n .control > .trigger--icon {\n margin-inline-start: 0.25rem;\n }\n\n .icon svg {\n display: block;\n width: 0.75rem;\n height: 0.75rem;\n }\n\n .tags {\n display: flex;\n flex: 0 1 auto;\n flex-wrap: wrap;\n gap: 0.25rem;\n min-width: 0;\n }\n\n .tag {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n max-width: 10ch;\n padding: 0.125rem 0.375rem;\n border-radius: var(--pk-radius-sm);\n background: var(--pk-color-gray-200);\n color: var(--pk-color-gray-800);\n font-size: 12px;\n line-height: 1.3;\n }\n\n .tag-label {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n .tag-remove {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 0.875rem;\n height: 0.875rem;\n padding: 0;\n border: 0;\n border-radius: var(--pk-radius-sm);\n background: transparent;\n color: var(--pk-color-gray-600);\n cursor: pointer;\n }\n\n .tag-remove:hover {\n background: rgb(0 0 0 / 8%);\n }\n\n .clear-button {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 1.25rem;\n height: 1.25rem;\n padding: 0;\n border: 0;\n border-radius: var(--pk-radius-sm);\n background: transparent;\n color: var(--pk-color-gray-600);\n cursor: pointer;\n flex-shrink: 0;\n }\n\n .clear-button:hover {\n background: rgb(0 0 0 / 6%);\n color: var(--pk-color-gray-800);\n }\n\n .value-input {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n }\n\n .panel ::slotted(pk-separator) {\n margin: 4px 0;\n }\n\n .panel {\n width: max-content;\n min-width: var(--pk-select-anchor-width, 8rem);\n max-height: 16rem;\n overflow: auto;\n padding: 0;\n border: 0;\n border-radius: var(--pk-radius-md);\n background: var(--pk-color-white);\n box-shadow: var(--pk-shadow-popup);\n color: var(--pk-color-gray-700);\n outline: none;\n }\n\n .panel[hidden] {\n display: none !important;\n }\n\n :host([invalid]) .control,\n :host(:state(user-invalid)) .control {\n border-color: var(--pk-color-rose-600);\n }\n\n :host([invalid]) button.control:focus-visible,\n :host([invalid][data-state='focus-visible']) button.control,\n :host(:state(user-invalid)) button.control:focus-visible,\n :host(:state(user-invalid)[data-state='focus-visible']) button.control {\n border-color: var(--pk-color-rose-600);\n box-shadow: var(--pk-input-invalid-focus-shadow);\n }\n\n :host([size='xs']) {\n --pk-select-item-min-height: 0;\n --pk-select-item-padding-block: 4px;\n --pk-select-item-padding-inline: 8px;\n --pk-select-item-padding-inline-end: 1.75rem;\n --pk-select-item-font-size: 11px;\n --pk-select-item-line-height: 1.25;\n /* v1 SelectLabel xs: text-[11px] */\n --pk-select-group-label-font-size: 11px;\n --pk-select-decoration-size: 0.625rem;\n }\n\n :host([size='xs']) .control {\n border-radius: var(--pk-radius-sm);\n /* Match trigger line-height to the compact item token (default is 1.25rem). */\n line-height: var(--pk-select-item-line-height, 1.25);\n }\n\n :host([size='xs']) .icon svg {\n width: 0.625rem;\n height: 0.625rem;\n }\n\n /* Options live in light DOM; ::slotted pushes size tokens onto each pk-option\n * host so the open listbox matches the trigger (inheritance alone is flaky when\n * the panel is promoted to the popover top layer). */\n :host([size='xs']) ::slotted(pk-option) {\n --pk-select-item-min-height: 0;\n --pk-select-item-padding-block: 4px;\n --pk-select-item-padding-inline: 8px;\n --pk-select-item-padding-inline-end: 1.75rem;\n --pk-select-item-font-size: 11px;\n --pk-select-item-line-height: 1.25;\n --pk-select-item-indicator-size: 0.625rem;\n }\n\n :host([size='xs']) .panel {\n max-height: 12rem;\n }\n\n /* Editable-table cells only (class set by pk-editable-table) — compact chip + menu. */\n :host(.cell-pk-control) {\n --pk-select-item-min-height: 0;\n --pk-select-item-padding-block: 5px;\n --pk-select-item-padding-inline: 8px;\n --pk-select-item-padding-inline-end: 1.5rem;\n --pk-select-item-font-size: 11px;\n --pk-select-item-line-height: 1.2;\n /* Compact table chip — match xs label size. */\n --pk-select-group-label-font-size: 11px;\n --pk-select-decoration-size: 0.625rem;\n --pk-select-item-indicator-size: 0.625rem;\n }\n\n :host(.cell-pk-control) .control {\n border-radius: var(--pk-radius-sm);\n line-height: var(--pk-select-item-line-height, 1.2);\n }\n\n :host(.cell-pk-control) ::slotted(pk-option) {\n --pk-select-item-min-height: 0;\n --pk-select-item-padding-block: 5px;\n --pk-select-item-padding-inline: 8px;\n --pk-select-item-padding-inline-end: 1.5rem;\n --pk-select-item-font-size: 11px;\n --pk-select-item-line-height: 1.2;\n --pk-select-item-indicator-size: 0.625rem;\n }\n\n :host(.cell-pk-control) .panel {\n max-height: 11rem;\n }\n\n :host([size='sm']) {\n --pk-select-item-min-height: 0;\n --pk-select-item-padding-block: 6px;\n --pk-select-item-padding-inline: 10px;\n --pk-select-item-padding-inline-end: 1.75rem;\n --pk-select-item-font-size: 12px;\n --pk-select-item-indicator-inset: 0.625rem;\n /* v1 SelectLabel sm: text-[12px] */\n --pk-select-group-label-font-size: 12px;\n --pk-select-decoration-size: 0.6875rem;\n }\n\n :host([size='sm']) .control {\n border-radius: var(--pk-radius-md);\n }\n\n :host([size='sm']) .icon svg {\n width: 0.6875rem;\n height: 0.6875rem;\n }\n\n :host([size='lg']) {\n --pk-select-item-padding-block: 8px;\n --pk-select-item-padding-inline: 12px;\n --pk-select-item-font-size: var(--pk-font-size-base);\n --pk-select-item-indicator-inset: 0.75rem;\n /* v1 SelectLabel lg: text-sm → 14px */\n --pk-select-group-label-font-size: 14px;\n --pk-select-decoration-size: 1rem;\n }\n\n :host([size='xl']) {\n --pk-select-item-padding-block: 10px;\n --pk-select-item-padding-inline: 14px;\n --pk-select-item-padding-inline-end: 2.25rem;\n --pk-select-item-font-size: var(--pk-font-size-base);\n --pk-select-item-indicator-inset: 0.875rem;\n /* v1 SelectLabel xl: text-base → 16px */\n --pk-select-group-label-font-size: 16px;\n --pk-select-decoration-size: 1.125rem;\n }\n\n :host([size='xl']) .icon svg {\n width: 0.875rem;\n height: 0.875rem;\n }\n }\n`,\n];\n","import { html, nothing } from 'lit';\nimport { classMap } from 'lit/directives/class-map.js';\nimport { customElement, property, query, state } from '../../decorators.js';\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js';\nimport type { PropertyValues } from 'lit';\n\nimport { chevronDown, renderIconHtml } from '../../icons/index.js';\n\nimport { isTopDismissible, registerDismissible, unregisterDismissible } from '../../a11y/dismissible-stack.js';\nimport { scrollIntoView } from '../../a11y/scroll-lock.js';\nimport { uniqueId } from '../../a11y/focus.js';\nimport { PkFormAssociatedElement } from '../../base/pk-form-associated-element.js';\nimport { HasSlotController } from '../../internal/has-slot.js';\nimport { PkClearEvent } from '../../events/pk-clear.js';\nimport {\n PkAfterHideEvent,\n PkAfterShowEvent,\n PkHideEvent,\n PkShowEvent,\n type PkOverlaySource,\n} from '../../events/overlay-lifecycle.js';\nimport type { PkValidator } from '../../validators/types.js';\nimport { MirrorValidator } from '../../validators/mirror-validator.js';\n// Keep the internal element registered when production builds erase type-only imports.\nimport '../popup/pk-popup.js';\nimport type { PkPopup, PkPopupPlacement } from '../popup/pk-popup.js';\nimport {\n createTypeToSelectHandler,\n handleListboxKeyDown,\n isListboxTypeToSelectKey,\n LISTBOX_NAVIGATION_KEYS,\n} from '../../utils/listbox-keyboard.js';\nimport {\n syncPopupPlacementAnimation,\n waitForPopupReposition,\n} from '../../utils/popup-placement-animation.js';\nimport { isEventInsideOverlay, isPointerInsideOverlay } from '../../utils/popup-pointer.js';\nimport { syncListboxSeparators } from '../../internal/sync-listbox-separators.js';\nimport type { PkOption } from './pk-option.js';\nimport type { PkOptionGroup } from './pk-option-group.js';\nimport { pkSelectStyles } from './pk-select.styles.js';\n\nexport type PkSelectSize = 'xs' | 'sm' | 'default' | 'lg' | 'xl';\n\nconst CHEVRON_ICON = renderIconHtml(chevronDown);\n\n/**\n * Select — slotted `pk-option` children, form-associated, clearable, multiselect tags.\n *\n * @slot start - Presentational decoration before the trigger label (e.g. icons)\n * @slot end - Presentational decoration before the expand chevron\n * @slot - `pk-option` and `pk-option-group` items\n *\n * @csspart control - Trigger control wrapper\n * @csspart start - Host start decoration container\n * @csspart end - Host end decoration container\n * @csspart trigger-start - Mirrored start decoration from the selected option\n * @csspart trigger - Select trigger button\n * @csspart panel - Listbox panel\n *\n * @cssproperty [--pk-select-fill=var(--pk-color-slate-250)] - Closed trigger background.\n * @cssproperty [--pk-select-fill-hover=var(--pk-color-slate-300)] - Closed trigger hover background.\n * @cssproperty [--pk-select-anchor-width] - Panel min-width; set from the trigger width while open.\n * @cssproperty [--pk-select-decoration-size=0.875rem] - Start/end decoration glyph size.\n *\n * @event pk-show - Emitted when the listbox begins to open.\n * @event pk-after-show - Emitted after the listbox opens and enter motion finishes.\n * @event {{ source: string }} pk-hide - Emitted when the listbox begins to close (cancelable).\n * @event pk-after-hide - Emitted after the listbox closes and exit motion finishes.\n * @event {{ open: boolean }} pk-open-change - Emitted when `open` changes after show/hide settles.\n * @event {{ value: string, values: string[] }} pk-change - Emitted when the selection changes.\n * @event pk-clear - Emitted when the value is cleared via the clear control.\n * @event pk-invalid - Emitted when constraint validation fails.\n * @event input - Native input event when the selection changes.\n * @event change - Native change event when the selection changes.\n *\n * @method show - Opens the listbox.\n * @method hide - Closes the listbox.\n * @method checkValidity - Runs constraint validation without showing the browser UI.\n * @method reportValidity - Runs constraint validation and shows the browser UI when invalid.\n * @method setCustomValidity - Sets or clears a custom validation message.\n * @method resetValidity - Clears custom errors and re-syncs validity state.\n *\n * @dependency pk-popup - Positioned listbox panel host.\n */\n@customElement('pk-select')\nexport class PkSelect extends PkFormAssociatedElement {\n static override styles = pkSelectStyles;\n\n static override get validators(): PkValidator[] {\n return [\n ...super.validators,\n MirrorValidator(),\n {\n observedAttributes: ['required'],\n checkValidity: (element) => {\n const select = element as PkSelect;\n const result = {\n message: 'Please select an item in the list.',\n isValid: true,\n invalidKeys: [] as ReturnType<PkValidator['checkValidity']>['invalidKeys'],\n };\n\n if (!select.required) {\n return result;\n }\n\n const missing = select.multiple ? select.values.length === 0 : !select.value;\n\n if (!missing) {\n return result;\n }\n\n result.isValid = false;\n result.invalidKeys.push('valueMissing');\n return result;\n },\n },\n ];\n }\n\n override assumeInteractionOn = ['blur', 'input'];\n\n /** Whether the listbox is open. Prefer `show()` / `hide()` for animated transitions. */\n @property({ type: Boolean, reflect: true })\n open = false;\n\n /** Allow more than one option to be selected (tag display). */\n @property({ type: Boolean, reflect: true })\n multiple = false;\n\n /** Preferred listbox placement; may flip to stay in viewport. */\n @property({ reflect: true })\n placement: PkPopupPlacement = 'bottom-start';\n\n /** Gap between the trigger and listbox panel in px. */\n @property({ attribute: 'side-offset', type: Number })\n sideOffset = 4;\n\n /** Alias of `with-clear` — shows a clear control when the value is non-empty. */\n @property({ type: Boolean, reflect: true })\n clearable = false;\n\n /** Shows a clear control when the value is non-empty. */\n @property({ attribute: 'with-clear', type: Boolean })\n withClear = false;\n\n /** Marks the control invalid (visual + ARIA). */\n @property({ type: Boolean, reflect: true })\n invalid = false;\n\n /** Shared CP size scale for the closed trigger and list items. */\n @property({ reflect: true })\n size: PkSelectSize = 'default';\n\n /** When `full`, the trigger stretches to the host width. */\n @property({ reflect: true })\n width?: 'full';\n\n /** Prompt shown when nothing is selected. Empty by default. */\n @property()\n placeholder = '';\n\n /** Selected value (single-select). Empty string when cleared. */\n @property()\n value = '';\n\n /** Initial value before user interaction (form reset baseline). */\n @property({ attribute: 'default-value' })\n defaultValue = '';\n\n /** Selected values when `multiple` is set. Property-only (not an attribute). */\n @property({ type: Array, attribute: false })\n values: string[] = [];\n\n /** Initial multi values before user interaction. Property-only. */\n @property({ attribute: false })\n defaultValues: string[] = [];\n\n /** Accessible name for the trigger when no visible label is present. */\n @property({ attribute: 'aria-label' })\n ariaLabel: string | null = null;\n\n /**\n * Whether arrow-key focus loops from the last option back to the first (and vice versa).\n * Base UI `Select` has no equivalent; default: `false`.\n */\n @property({ attribute: 'loop-focus', type: Boolean })\n loopFocus = false;\n\n private readonly hasSlotController = new HasSlotController(this, 'start', 'end');\n\n private readonly listboxId = uniqueId('pk-select-listbox');\n private readonly triggerId = uniqueId('pk-select-trigger');\n\n @query('.trigger-start')\n private triggerStartElement?: HTMLSpanElement;\n\n @query('pk-popup')\n private popupElement!: PkPopup;\n\n @query('.control')\n private controlElement!: HTMLElement;\n\n @query('button.control, .control > button.trigger')\n private triggerButton?: HTMLButtonElement;\n\n @query('.value-input')\n override input!: HTMLInputElement;\n\n private get panelElement(): HTMLDivElement | null {\n return this.popupElement?.getContentElement() as HTMLDivElement | null ?? null;\n }\n\n private options: PkOption[] = [];\n\n @state()\n private highlightedIndex = 0;\n\n private dismissRegistered = false;\n private panelEventTarget: HTMLElement | null = null;\n private typeToSelect = createTypeToSelectHandler([], () => {});\n private optionsObserver?: MutationObserver;\n\n /** True while the shared popup-content exit animation is running. */\n @state()\n private closing = false;\n\n /** Gates `data-open` so enter motion starts after Floating UI places the panel. */\n @state()\n private panelAnimated = false;\n\n override connectedCallback(): void {\n this.refreshOptions();\n super.connectedCallback();\n this.addEventListener('pk-listbox-keydown', this.handleListboxKeyDownEvent as EventListener);\n this.addEventListener('keydown', this.onKeyDown);\n this.optionsObserver = new MutationObserver(() => {\n this.handleOptionsMutation({ render: true });\n });\n this.optionsObserver.observe(this, { childList: true, subtree: true });\n }\n\n override disconnectedCallback(): void {\n this.unbindPanelEvents();\n this.removeEventListener('pk-listbox-keydown', this.handleListboxKeyDownEvent as EventListener);\n this.removeEventListener('keydown', this.onKeyDown);\n this.optionsObserver?.disconnect();\n void this.closePanel('api');\n super.disconnectedCallback();\n }\n\n override updated(changed: PropertyValues): void {\n if (changed.has('value') || changed.has('values') || changed.has('multiple')) {\n this.applySelection();\n }\n\n super.updated(changed);\n }\n\n private getOptionElements(): PkOption[] {\n const portaled = this.popupElement?.getContentElement()?.querySelectorAll('pk-option');\n\n if (portaled && portaled.length > 0) {\n return [...portaled];\n }\n\n return [...this.querySelectorAll('pk-option')];\n }\n\n private handleOptionsMutation = (options: { render?: boolean } = {}): void => {\n const next = this.getOptionElements();\n const changed = next.length !== this.options.length\n || next.some((option, index) => option !== this.options[index]);\n\n this.options = next;\n this.applySelection();\n this.updateTypeToSelect();\n\n if (options.render !== false && changed) {\n this.requestUpdate();\n }\n };\n\n private refreshOptions(): void {\n this.handleOptionsMutation({ render: false });\n }\n\n private syncOptions = (): void => {\n this.handleOptionsMutation({ render: true });\n };\n\n /** Portaled listbox options are outside the host tree — listen on the panel instead. */\n private bindPanelEvents(): void {\n const panel = this.panelElement;\n\n if (!panel || panel === this.panelEventTarget) {\n return;\n }\n\n this.unbindPanelEvents();\n this.panelEventTarget = panel;\n panel.addEventListener('pk-option-select', this.handleOptionSelect as EventListener);\n panel.addEventListener('pk-option-highlight', this.handleOptionHighlight as EventListener);\n panel.addEventListener('pk-listbox-keydown', this.handleListboxKeyDownEvent as EventListener);\n }\n\n private unbindPanelEvents(): void {\n if (!this.panelEventTarget) {\n return;\n }\n\n this.panelEventTarget.removeEventListener('pk-option-select', this.handleOptionSelect as EventListener);\n this.panelEventTarget.removeEventListener('pk-option-highlight', this.handleOptionHighlight as EventListener);\n this.panelEventTarget.removeEventListener('pk-listbox-keydown', this.handleListboxKeyDownEvent as EventListener);\n this.panelEventTarget = null;\n }\n\n protected override get validationTarget(): HTMLElement | undefined {\n return this.input ?? this.triggerButton ?? this.controlElement;\n }\n\n protected override getAriaMirrorTarget(): HTMLElement | null {\n return this.triggerButton ?? this.controlElement ?? null;\n }\n\n protected override syncFormValue(): void {\n if (!this.name) {\n this.setFormValue(null);\n return;\n }\n\n if (this.multiple) {\n const formData = new FormData();\n\n for (const item of this.values) {\n formData.append(this.name, item);\n }\n\n this.setFormValue(formData);\n return;\n }\n\n this.setFormValue(this.value || '');\n }\n\n protected override resetToDefaultValue(): void {\n if (this.multiple) {\n this.values = [...this.defaultValues];\n } else {\n this.value = this.defaultValue;\n }\n\n this.applySelection();\n }\n\n protected override restoreFormState(state: string | File | FormData | null): void {\n if (state instanceof FormData && this.name) {\n this.values = state.getAll(this.name).map(String);\n return;\n }\n\n if (typeof state === 'string') {\n this.value = state;\n }\n }\n\n private isOptionInHiddenGroup(option: PkOption): boolean {\n const group = option.closest('pk-option-group') as PkOptionGroup | null;\n\n return Boolean(group?.hidden);\n }\n\n private getVisibleOptions(): PkOption[] {\n return this.options.filter((option) => !this.isOptionInHiddenGroup(option));\n }\n\n private getEnabledVisibleOptions(): PkOption[] {\n return this.getVisibleOptions().filter((option) => !option.disabled);\n }\n\n private isSelected(value: string): boolean {\n if (this.multiple) {\n return this.values.includes(value);\n }\n\n return this.value === value;\n }\n\n private applySelection(): void {\n const visible = this.getVisibleOptions();\n\n for (const option of this.options) {\n option.selected = this.isSelected(option.value);\n option.hidden = !visible.includes(option);\n option.optionId = `${this.listboxId}-option-${option.value}`;\n }\n\n for (const group of this.querySelectorAll('pk-option-group')) {\n const groupOptions = [...group.querySelectorAll('pk-option')];\n group.hidden = groupOptions.length > 0 && groupOptions.every((option) => option.hidden);\n }\n\n syncListboxSeparators(this);\n\n this.syncValueInput();\n this.syncTriggerDecorations();\n\n if (this.open) {\n this.syncHighlight();\n }\n }\n\n private syncValueInput(): void {\n if (!this.input) {\n return;\n }\n\n if (this.multiple) {\n this.input.value = this.values.join(',');\n this.input.required = this.required;\n return;\n }\n\n this.input.value = this.value;\n this.input.required = this.required;\n }\n\n private getDisplayValue(): string {\n if (this.multiple) {\n const labels = this.getSelectedOptions()\n .map((option) => option.getLabel());\n\n return labels.length > 0 ? labels.join(', ') : this.placeholder;\n }\n\n const selected = this.options.find((option) => option.value === this.value);\n\n return selected?.getLabel() || this.placeholder;\n }\n\n private getSelectedOptions(): PkOption[] {\n return this.options.filter((option) => this.isSelected(option.value));\n }\n\n /**\n * Mirror the selected option's `slot=\"start\"` decorations into the trigger —\n * `pk-select` start/end decoration pattern.\n */\n private syncTriggerDecorations(): void {\n const container = this.triggerStartElement;\n\n if (!container || this.multiple) {\n return;\n }\n\n container.replaceChildren();\n container.classList.remove('has-decoration');\n\n const selected = this.options.find((option) => option.value === this.value);\n\n if (!selected) {\n return;\n }\n\n for (const element of selected.getStartElements()) {\n container.append(element.cloneNode(true));\n }\n\n container.classList.toggle('has-decoration', container.childElementCount > 0);\n }\n\n private hasSelection(): boolean {\n if (this.multiple) {\n return this.values.length > 0;\n }\n\n // Empty-string values are valid when an option declares them (e.g. \"Default\").\n return this.options.some((option) => option.value === this.value) || Boolean(this.value);\n }\n\n private syncHighlightedIndexToSelection(): void {\n if (this.multiple) {\n return;\n }\n\n const enabled = this.getEnabledVisibleOptions();\n\n if (enabled.length === 0) {\n return;\n }\n\n const selectedIndex = enabled.findIndex((option) => option.value === this.value);\n\n if (selectedIndex >= 0) {\n this.highlightedIndex = selectedIndex;\n }\n }\n\n private syncHighlight(): void {\n const enabled = this.getEnabledVisibleOptions();\n\n for (const option of this.options) {\n option.highlighted = false;\n option.focusIndex = -1;\n }\n\n if (enabled.length === 0) {\n this.highlightedIndex = 0;\n return;\n }\n\n if (this.highlightedIndex >= enabled.length) {\n this.highlightedIndex = 0;\n }\n\n const highlighted = enabled[this.highlightedIndex];\n\n if (highlighted && this.panelElement) {\n highlighted.highlighted = true;\n highlighted.focusIndex = 0;\n scrollIntoView(highlighted, this.panelElement, 'vertical', 'auto');\n }\n }\n\n private updateTypeToSelect(): void {\n this.typeToSelect = createTypeToSelectHandler(\n this.getEnabledVisibleOptions() as unknown as HTMLElement[],\n (index) => {\n this.highlightedIndex = index;\n this.syncHighlight();\n this.getEnabledVisibleOptions()[index]?.focusControl();\n },\n );\n }\n\n private togglePanel = (event?: Event): void => {\n event?.preventDefault();\n event?.stopPropagation();\n\n if (this.disabled || this.closing) {\n return;\n }\n\n if (this.open) {\n void this.closePanel('api');\n } else {\n void this.openPanel();\n }\n };\n\n private getPopupAnchor(): HTMLElement | null {\n return this.controlElement ?? null;\n }\n\n private getActiveDescendantId(): string | null {\n const enabled = this.getEnabledVisibleOptions();\n const highlighted = enabled[this.highlightedIndex];\n return highlighted?.optionId || null;\n }\n\n /** Opens the listbox. */\n async show(): Promise<void> {\n if (this.open || this.closing || this.disabled) {\n return;\n }\n\n await this.openPanel();\n }\n\n /** Closes the listbox. */\n async hide(source: PkOverlaySource = 'api'): Promise<void> {\n if (!this.open || this.closing) {\n return;\n }\n\n await this.closePanel(source);\n }\n\n private openPanel(): Promise<void> {\n const anchor = this.getPopupAnchor();\n\n if (!anchor || this.closing) {\n return Promise.resolve();\n }\n\n this.dispatchEvent(new PkShowEvent());\n this.closing = false;\n this.panelAnimated = false;\n this.open = true;\n this.popupElement.active = true;\n this.applySelection();\n this.syncHighlightedIndexToSelection();\n\n if (this.panelElement) {\n this.panelElement.hidden = false;\n // Seed side before first paint so enter keyframes pick a direction.\n syncPopupPlacementAnimation(this.panelElement, this.placement);\n }\n\n const anchorWidth = anchor.getBoundingClientRect().width;\n this.style.setProperty('--pk-select-anchor-width', `${anchorWidth}px`);\n this.registerDismissHandlers();\n this.syncHighlight();\n this.updateTypeToSelect();\n\n return this.updateComplete.then(async () => {\n const placement = await waitForPopupReposition(this.popupElement, this.placement, 300, {\n requireEvent: true,\n });\n\n if (this.panelElement) {\n syncPopupPlacementAnimation(this.panelElement, placement);\n }\n\n // Flip data-open after placement so the shared enter animation can run.\n this.panelAnimated = true;\n this.bindPanelEvents();\n this.refreshOptions();\n this.getEnabledVisibleOptions()[this.highlightedIndex]?.focusControl();\n\n this.dispatchEvent(new PkAfterShowEvent());\n this.dispatchEvent(new CustomEvent('pk-open-change', {\n detail: { open: true },\n bubbles: true,\n composed: true,\n }));\n });\n }\n\n private async closePanel(source: PkOverlaySource = 'unknown'): Promise<void> {\n if (!this.open || this.closing) {\n return;\n }\n\n const hideEvent = new PkHideEvent(source);\n\n if (!this.dispatchEvent(hideEvent)) {\n return;\n }\n\n this.typeToSelect.reset();\n this.unbindPanelEvents();\n this.unregisterDismissHandlers();\n\n this.closing = true;\n this.panelAnimated = false;\n await this.waitForExitAnimation();\n\n this.open = false;\n this.closing = false;\n this.panelAnimated = false;\n\n if (this.panelElement) {\n this.panelElement.hidden = true;\n this.panelElement.removeAttribute('data-side');\n }\n\n this.popupElement.active = false;\n\n this.dispatchEvent(new PkAfterHideEvent());\n this.dispatchEvent(new CustomEvent('pk-open-change', {\n detail: { open: false },\n bubbles: true,\n composed: true,\n }));\n\n if (this.shouldReturnFocusToTrigger(source)) {\n this.triggerButton?.focus({ preventScroll: true });\n } else {\n this.triggerButton?.blur();\n }\n }\n\n private waitForExitAnimation(): Promise<void> {\n const panel = this.panelElement;\n\n if (!panel) {\n return Promise.resolve();\n }\n\n return new Promise((resolve) => {\n let settled = false;\n\n const finish = (): void => {\n if (settled) {\n return;\n }\n\n settled = true;\n panel.removeEventListener('animationend', onAnimationEnd);\n window.clearTimeout(fallback);\n panel.classList.remove('closing');\n resolve();\n };\n\n const onAnimationEnd = (event: AnimationEvent): void => {\n if (event.target === panel && event.animationName.startsWith('pk-popup-content-out')) {\n finish();\n }\n };\n\n panel.classList.add('closing');\n panel.addEventListener('animationend', onAnimationEnd);\n const fallback = window.setTimeout(finish, 150);\n });\n }\n\n /** Base UI skips return focus on outside press — avoids an unwanted focus ring after light dismiss. */\n private shouldReturnFocusToTrigger(source: PkOverlaySource): boolean {\n return source !== 'light-dismiss' && source !== 'pointer-dismiss';\n }\n\n private registerDismissHandlers(): void {\n registerDismissible(this);\n this.dismissRegistered = true;\n document.addEventListener('pointerdown', this.onDocumentPointerDown, true);\n document.addEventListener('keydown', this.onDocumentKeyDown, true);\n }\n\n private unregisterDismissHandlers(): void {\n if (this.dismissRegistered) {\n unregisterDismissible(this);\n this.dismissRegistered = false;\n }\n\n document.removeEventListener('pointerdown', this.onDocumentPointerDown, true);\n document.removeEventListener('keydown', this.onDocumentKeyDown, true);\n }\n\n private onDocumentPointerDown = (event: PointerEvent): void => {\n if (this.isPointerInside(event)) {\n return;\n }\n\n void this.closePanel('light-dismiss');\n };\n\n private isPointerInside(event: PointerEvent): boolean {\n return isPointerInsideOverlay(event, {\n anchor: this.getPopupAnchor(),\n panel: this.panelElement,\n });\n };\n\n private onDocumentKeyDown = (event: KeyboardEvent): void => {\n if (!this.open) {\n return;\n }\n\n if (event.key === 'Escape') {\n if (!isTopDismissible(this)) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n void this.closePanel('escape');\n return;\n }\n\n const isListboxKey = LISTBOX_NAVIGATION_KEYS.has(event.key) || isListboxTypeToSelectKey(event);\n\n if (!isListboxKey) {\n return;\n }\n\n if (!isEventInsideOverlay(event, {\n anchor: this.getPopupAnchor(),\n panel: this.panelElement,\n })) {\n return;\n }\n\n event.preventDefault();\n event.stopPropagation();\n this.onListboxKeyDown(event);\n };\n\n private handleOptionSelect = (event: CustomEvent<{ value: string }>): void => {\n const { value } = event.detail;\n\n if (this.multiple) {\n this.values = this.values.includes(value)\n ? this.values.filter((v) => v !== value)\n : [...this.values, value];\n } else {\n this.value = value;\n void this.closePanel('api');\n }\n\n this.applySelection();\n this.emitValueChange();\n };\n\n private handleOptionHighlight = (event: CustomEvent<{ value: string }>): void => {\n if (!this.open) {\n return;\n }\n\n const enabled = this.getEnabledVisibleOptions();\n const index = enabled.findIndex((option) => option.value === event.detail.value);\n\n if (index === -1 || index === this.highlightedIndex) {\n return;\n }\n\n this.highlightedIndex = index;\n this.syncHighlight();\n };\n\n private removeTag(value: string, event: Event): void {\n event.preventDefault();\n event.stopPropagation();\n this.values = this.values.filter((item) => item !== value);\n this.applySelection();\n this.emitValueChange();\n }\n\n private handleClear(event: Event): void {\n event.preventDefault();\n event.stopPropagation();\n\n if (this.multiple) {\n this.values = [];\n } else {\n this.value = '';\n }\n\n this.applySelection();\n this.dispatchEvent(new PkClearEvent());\n this.emitValueChange();\n this.triggerButton?.focus();\n }\n\n private emitValueChange(): void {\n this.dispatchEvent(new CustomEvent('pk-change', {\n detail: {\n value: this.multiple ? [...this.values] : this.value,\n },\n bubbles: true,\n composed: true,\n }));\n\n this.dispatchEvent(new Event('input', { bubbles: true, composed: true }));\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));\n }\n\n private onKeyDown = (event: KeyboardEvent): void => {\n if (!this.open) {\n if (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n void this.openPanel();\n }\n\n return;\n }\n\n this.onListboxKeyDown(event);\n };\n\n private onListboxKeyDown(event: KeyboardEvent): void {\n const enabled = this.getEnabledVisibleOptions();\n\n this.highlightedIndex = handleListboxKeyDown(event, {\n items: enabled as unknown as HTMLElement[],\n currentIndex: this.highlightedIndex,\n multiselect: this.multiple,\n loop: this.loopFocus,\n onSelect: (index) => {\n this.highlightedIndex = index;\n this.syncHighlight();\n },\n focusItem: (index) => {\n enabled[index]?.focusControl();\n },\n onClose: () => { void this.closePanel('escape'); },\n });\n\n if (event.key.length === 1 && !event.ctrlKey && !event.metaKey && !event.altKey) {\n this.typeToSelect.handleKey(event);\n }\n }\n\n private handleListboxKeyDownEvent = (event: CustomEvent<{ keyboardEvent: KeyboardEvent }>): void => {\n if (!this.open) {\n return;\n }\n\n this.onListboxKeyDown(event.detail.keyboardEvent);\n };\n\n private renderTags() {\n return this.getSelectedOptions().map((option) => html`\n <span class=\"tag\" part=\"tag\">\n <span class=\"tag-label\">${option.getLabel()}</span>\n <button\n type=\"button\"\n class=\"tag-remove\"\n part=\"tag-remove\"\n aria-label=${`Remove ${option.getLabel()}`}\n @click=${(event: Event) => this.removeTag(option.value, event)}\n >\n ×\n </button>\n </span>\n `);\n }\n\n private renderChevronIcon() {\n return html`\n <span class=\"icon\" aria-hidden=\"true\">${unsafeSVG(CHEVRON_ICON)}</span>\n `;\n }\n\n private renderHostDecorationSlot(name: 'start' | 'end') {\n if (!this.hasSlotController.test(name)) {\n return html`<slot name=${name} hidden></slot>`;\n }\n\n const className = name === 'start' ? 'control-start' : 'control-end';\n\n return html`\n <span part=${name} class=${className}>\n <slot name=${name}></slot>\n </span>\n `;\n }\n\n override render() {\n const displayValue = this.getDisplayValue();\n const isPlaceholder = !this.hasSelection();\n const showClear = (this.clearable || this.withClear) && this.hasSelection() && !this.disabled;\n\n return html`\n <input\n class=\"value-input\"\n part=\"value-input\"\n tabindex=\"-1\"\n aria-hidden=\"true\"\n .value=${this.multiple ? this.values.join(',') : this.value}\n ?required=${this.required}\n @input=${() => this.updateValidity()}\n />\n ${this.multiple\n ? html`\n <div\n part=\"control\"\n class=${classMap({\n control: true,\n 'is-disabled': this.disabled,\n })}\n >\n ${this.renderHostDecorationSlot('start')}\n ${this.hasSelection()\n ? html`\n <div class=\"tags\" part=\"tags\">${this.renderTags()}</div>\n ${showClear\n ? html`\n <button\n type=\"button\"\n class=\"clear-button\"\n part=\"clear-button\"\n aria-label=\"Clear selection\"\n @click=${this.handleClear}\n >\n ×\n </button>\n `\n : nothing}\n `\n : html`\n <button\n part=\"trigger\"\n type=\"button\"\n class=\"trigger\"\n id=${this.triggerId}\n ?disabled=${this.disabled}\n aria-label=${this.ariaLabel ?? nothing}\n aria-haspopup=\"listbox\"\n aria-expanded=${this.open ? 'true' : 'false'}\n aria-controls=${this.listboxId}\n @click=${this.togglePanel}\n >\n <span class=\"value is-placeholder\">${this.placeholder}</span>\n </button>\n `}\n ${this.renderHostDecorationSlot('end')}\n <button\n type=\"button\"\n class=\"trigger trigger--icon\"\n part=\"trigger expand-button\"\n aria-label=\"Toggle options\"\n ?disabled=${this.disabled}\n @click=${this.togglePanel}\n >\n ${this.renderChevronIcon()}\n </button>\n </div>\n `\n : html`\n <button\n part=\"control\"\n type=\"button\"\n class=${classMap({\n control: true,\n 'is-disabled': this.disabled,\n })}\n id=${this.triggerId}\n ?disabled=${this.disabled}\n aria-label=${this.ariaLabel ?? nothing}\n aria-haspopup=\"listbox\"\n aria-expanded=${this.open ? 'true' : 'false'}\n aria-controls=${this.listboxId}\n @click=${this.togglePanel}\n >\n ${this.renderHostDecorationSlot('start')}\n <span part=\"trigger-start\" class=\"trigger-start\"></span>\n <span\n class=${classMap({\n value: true,\n 'is-placeholder': isPlaceholder,\n })}\n >${displayValue}</span>\n ${showClear\n ? html`\n <span\n class=\"clear-button\"\n part=\"clear-button\"\n role=\"button\"\n tabindex=\"-1\"\n aria-label=\"Clear selection\"\n @click=${this.handleClear}\n >\n ×\n </span>\n `\n : nothing}\n ${this.renderHostDecorationSlot('end')}\n ${this.renderChevronIcon()}\n </button>\n `}\n <pk-popup\n .anchor=${this.getPopupAnchor() ?? ''}\n .placement=${this.placement}\n .distance=${this.sideOffset}\n .sync=${'width'}\n flip\n shift\n >\n <div\n part=\"panel\"\n class=${classMap({\n panel: true,\n 'pk-popup-content': true,\n closing: this.closing,\n })}\n id=${this.listboxId}\n role=\"listbox\"\n aria-multiselectable=${this.multiple ? 'true' : 'false'}\n tabindex=\"-1\"\n ?hidden=${!this.open && !this.closing}\n data-open=${this.panelAnimated && !this.closing ? '' : nothing}\n @slotchange=${this.syncOptions}\n >\n <slot></slot>\n </div>\n </pk-popup>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'pk-select': PkSelect;\n }\n}\n"],"mappings":"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"}
|