@xplor-education/core-stencil-components 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/index.js +1 -1
- package/components/index.js.map +1 -1
- package/components/{p-B1W2qj2l.js → p-B3zR7peH.js} +4 -4
- package/components/p-B3zR7peH.js.map +1 -0
- package/components/{p-Ddr35stE.js → p-BRWe4TXp.js} +65 -5
- package/components/p-BRWe4TXp.js.map +1 -0
- package/components/{p-CBSi5kQB.js → p-Bs_ocvfe.js} +7 -3
- package/components/p-Bs_ocvfe.js.map +1 -0
- package/components/{p-CTD6SyTD.js → p-D4jVa8dE.js} +20 -4
- package/components/p-D4jVa8dE.js.map +1 -0
- package/components/{p-x30CgLRv.js → p-DURNLP66.js} +71 -6
- package/components/p-DURNLP66.js.map +1 -0
- package/components/{p-BK_ATKuB.js → p-DxxjL3sU.js} +3 -3
- package/components/{p-BK_ATKuB.js.map → p-DxxjL3sU.js.map} +1 -1
- package/components/xplor-alert-dialog.js +60 -3
- package/components/xplor-alert-dialog.js.map +1 -1
- package/components/xplor-assistant.js +3 -3
- package/components/xplor-assistant.js.map +1 -1
- package/components/xplor-autocomplete.js +15 -9
- package/components/xplor-autocomplete.js.map +1 -1
- package/components/xplor-avatar-and-name.js +1 -1
- package/components/xplor-avatar.js +1 -1
- package/components/xplor-btn-back-to-parent.js +7 -2
- package/components/xplor-btn-back-to-parent.js.map +1 -1
- package/components/xplor-btn-icon.js +3 -2
- package/components/xplor-btn-icon.js.map +1 -1
- package/components/xplor-btn-menu.js +103 -6
- package/components/xplor-btn-menu.js.map +1 -1
- package/components/xplor-btn-tooltip.js +2 -2
- package/components/xplor-button.js +1 -1
- package/components/xplor-chat-widget.js +2 -2
- package/components/xplor-checkbox.js +3 -1
- package/components/xplor-checkbox.js.map +1 -1
- package/components/xplor-combobox.js +20 -10
- package/components/xplor-combobox.js.map +1 -1
- package/components/xplor-datatable.js +10 -4
- package/components/xplor-datatable.js.map +1 -1
- package/components/xplor-date-picker.js +9 -5
- package/components/xplor-date-picker.js.map +1 -1
- package/components/xplor-drag-and-drop-input.js +43 -5
- package/components/xplor-drag-and-drop-input.js.map +1 -1
- package/components/xplor-dropdown.js +1 -1
- package/components/xplor-expansion-panel.js +4 -4
- package/components/xplor-expansion-panel.js.map +1 -1
- package/components/xplor-expansion-panels.js +1 -1
- package/components/xplor-expansion-panels.js.map +1 -1
- package/components/xplor-file-upload.js +2 -2
- package/components/xplor-file-upload.js.map +1 -1
- package/components/xplor-inline-checkbox.js +2 -2
- package/components/xplor-inline-date-picker.js +1 -1
- package/components/xplor-inline-switch.js +1 -1
- package/components/xplor-input-file.js +3 -1
- package/components/xplor-input-file.js.map +1 -1
- package/components/xplor-input-search.js +4 -2
- package/components/xplor-input-search.js.map +1 -1
- package/components/xplor-input-select.js +127 -7
- package/components/xplor-input-select.js.map +1 -1
- package/components/xplor-input-send.js +3 -3
- package/components/xplor-input-send.js.map +1 -1
- package/components/xplor-input-text-area.js +6 -2
- package/components/xplor-input-text-area.js.map +1 -1
- package/components/xplor-input-text-secondary.js +6 -2
- package/components/xplor-input-text-secondary.js.map +1 -1
- package/components/xplor-input-text.js +6 -2
- package/components/xplor-input-text.js.map +1 -1
- package/components/xplor-input-title.js +7 -2
- package/components/xplor-input-title.js.map +1 -1
- package/components/xplor-links.js +5 -2
- package/components/xplor-links.js.map +1 -1
- package/components/xplor-modal-persistent.js +2 -2
- package/components/xplor-modal.js +1 -1
- package/components/xplor-nav-tabs.js +41 -3
- package/components/xplor-nav-tabs.js.map +1 -1
- package/components/xplor-radio-btn.d.ts +11 -0
- package/components/xplor-radio-btn.js +131 -0
- package/components/xplor-radio-btn.js.map +1 -0
- package/components/xplor-section-card.js +2 -2
- package/components/xplor-section-card.js.map +1 -1
- package/components/xplor-section-heading.js +9 -3
- package/components/xplor-section-heading.js.map +1 -1
- package/components/xplor-table.js +14 -9
- package/components/xplor-table.js.map +1 -1
- package/components/xplor-text-bubble.js +2 -2
- package/components/xplor-text-field.js +2 -2
- package/components/xplor-time-picker.js +6 -6
- package/components/xplor-tooltip.js +1 -1
- package/dist/cjs/{index-Bc5o_4vY.js → index-BjAapk2n.js} +5 -5
- package/dist/cjs/index-BjAapk2n.js.map +1 -0
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/{xplor-alert-dialog_57.cjs.entry.js → xplor-alert-dialog_58.cjs.entry.js} +747 -108
- package/dist/cjs/xplor-alert-dialog_58.cjs.entry.js.map +1 -0
- package/dist/cjs/xplor-component-library.cjs.js +2 -2
- package/dist/collection/collection-manifest.json +1 -0
- package/dist/collection/components/xplor-alert-dialog/xplor-alert-dialog.js +85 -1
- package/dist/collection/components/xplor-alert-dialog/xplor-alert-dialog.js.map +1 -1
- package/dist/collection/components/xplor-assistant/internal/AssistantInput.js +1 -1
- package/dist/collection/components/xplor-assistant/internal/AssistantInput.js.map +1 -1
- package/dist/collection/components/xplor-assistant/xplor-assistant.js +1 -1
- package/dist/collection/components/xplor-assistant/xplor-assistant.js.map +1 -1
- package/dist/collection/components/xplor-autocomplete/xplor-autocomplete.js +33 -9
- package/dist/collection/components/xplor-autocomplete/xplor-autocomplete.js.map +1 -1
- package/dist/collection/components/xplor-avatar/xplor-avatar.js +2 -2
- package/dist/collection/components/xplor-avatar/xplor-avatar.js.map +1 -1
- package/dist/collection/components/xplor-btn-back-to-parent/xplor-btn-back-to-parent.js +25 -1
- package/dist/collection/components/xplor-btn-back-to-parent/xplor-btn-back-to-parent.js.map +1 -1
- package/dist/collection/components/xplor-btn-icon/xplor-btn-icon.js +20 -1
- package/dist/collection/components/xplor-btn-icon/xplor-btn-icon.js.map +1 -1
- package/dist/collection/components/xplor-btn-menu/xplor-btn-menu.js +129 -5
- package/dist/collection/components/xplor-btn-menu/xplor-btn-menu.js.map +1 -1
- package/dist/collection/components/xplor-button/xplor-button.js +42 -1
- package/dist/collection/components/xplor-button/xplor-button.js.map +1 -1
- package/dist/collection/components/xplor-checkbox/xplor-checkbox.js +3 -1
- package/dist/collection/components/xplor-checkbox/xplor-checkbox.js.map +1 -1
- package/dist/collection/components/xplor-combobox/xplor-combobox.js +38 -10
- package/dist/collection/components/xplor-combobox/xplor-combobox.js.map +1 -1
- package/dist/collection/components/xplor-datatable/xplor-datatable.js +10 -4
- package/dist/collection/components/xplor-datatable/xplor-datatable.js.map +1 -1
- package/dist/collection/components/xplor-date-picker/xplor-date-picker.js +8 -4
- package/dist/collection/components/xplor-date-picker/xplor-date-picker.js.map +1 -1
- package/dist/collection/components/xplor-drag-and-drop-input/xplor-drag-and-drop-input.css +125 -21
- package/dist/collection/components/xplor-drag-and-drop-input/xplor-drag-and-drop-input.js +79 -4
- package/dist/collection/components/xplor-drag-and-drop-input/xplor-drag-and-drop-input.js.map +1 -1
- package/dist/collection/components/xplor-dropdown/xplor-dropdown.js +1 -1
- package/dist/collection/components/xplor-expansion-panel/xplor-expansion-panel.js +4 -4
- package/dist/collection/components/xplor-expansion-panel/xplor-expansion-panel.js.map +1 -1
- package/dist/collection/components/xplor-expansion-panels/xplor-expansion-panels.js +1 -1
- package/dist/collection/components/xplor-expansion-panels/xplor-expansion-panels.js.map +1 -1
- package/dist/collection/components/xplor-file-upload/xplor-file-upload.js +2 -2
- package/dist/collection/components/xplor-file-upload/xplor-file-upload.js.map +1 -1
- package/dist/collection/components/xplor-inline-checkbox/xplor-inline-checkbox.js +2 -2
- package/dist/collection/components/xplor-inline-date-picker/xplor-inline-date-picker.js +77 -3
- package/dist/collection/components/xplor-inline-date-picker/xplor-inline-date-picker.js.map +1 -1
- package/dist/collection/components/xplor-inline-switch/xplor-inline-switch.js +1 -1
- package/dist/collection/components/xplor-input-file/xplor-input-file.js +3 -1
- package/dist/collection/components/xplor-input-file/xplor-input-file.js.map +1 -1
- package/dist/collection/components/xplor-input-search/xplor-input-search.js +4 -2
- package/dist/collection/components/xplor-input-search/xplor-input-search.js.map +1 -1
- package/dist/collection/components/xplor-input-select/xplor-input-select.css +1 -6
- package/dist/collection/components/xplor-input-select/xplor-input-select.js +152 -5
- package/dist/collection/components/xplor-input-select/xplor-input-select.js.map +1 -1
- package/dist/collection/components/xplor-input-send/xplor-input-send.js +2 -2
- package/dist/collection/components/xplor-input-send/xplor-input-send.js.map +1 -1
- package/dist/collection/components/xplor-input-text/xplor-input-text.js +6 -2
- package/dist/collection/components/xplor-input-text/xplor-input-text.js.map +1 -1
- package/dist/collection/components/xplor-input-text-area/xplor-input-text-area.js +6 -2
- package/dist/collection/components/xplor-input-text-area/xplor-input-text-area.js.map +1 -1
- package/dist/collection/components/xplor-input-text-secondary/xplor-input-text-secondary.js +6 -2
- package/dist/collection/components/xplor-input-text-secondary/xplor-input-text-secondary.js.map +1 -1
- package/dist/collection/components/xplor-input-title/xplor-input-title.js +25 -1
- package/dist/collection/components/xplor-input-title/xplor-input-title.js.map +1 -1
- package/dist/collection/components/xplor-links/xplor-links.js +25 -1
- package/dist/collection/components/xplor-links/xplor-links.js.map +1 -1
- package/dist/collection/components/xplor-modal/xplor-modal.js +88 -1
- package/dist/collection/components/xplor-modal/xplor-modal.js.map +1 -1
- package/dist/collection/components/xplor-modal-persistent/xplor-modal-persistent.js +1 -1
- package/dist/collection/components/xplor-nav-tabs/xplor-nav-tabs.js +49 -2
- package/dist/collection/components/xplor-nav-tabs/xplor-nav-tabs.js.map +1 -1
- package/dist/collection/components/xplor-radio-btn/xplor-radio-btn.css +386 -0
- package/dist/collection/components/xplor-radio-btn/xplor-radio-btn.js +275 -0
- package/dist/collection/components/xplor-radio-btn/xplor-radio-btn.js.map +1 -0
- package/dist/collection/components/xplor-section-card/xplor-section-card.js +2 -2
- package/dist/collection/components/xplor-section-card/xplor-section-card.js.map +1 -1
- package/dist/collection/components/xplor-section-heading/xplor-section-heading.js +27 -2
- package/dist/collection/components/xplor-section-heading/xplor-section-heading.js.map +1 -1
- package/dist/collection/components/xplor-table/xplor-table.js +14 -9
- package/dist/collection/components/xplor-table/xplor-table.js.map +1 -1
- package/dist/collection/components/xplor-text-bubble/xplor-text-bubble.js +2 -2
- package/dist/collection/components/xplor-text-field/xplor-text-field.js +2 -2
- package/dist/collection/components/xplor-time-picker/xplor-time-picker.js +6 -6
- package/dist/collection/components/xplor-tooltip/xplor-tooltip.js +18 -2
- package/dist/collection/components/xplor-tooltip/xplor-tooltip.js.map +1 -1
- package/dist/components/index.js +1 -1
- package/dist/components/index.js.map +1 -1
- package/dist/components/{p-BHdeGt6k.js → p--zhT6rvJ.js} +4 -4
- package/dist/components/p--zhT6rvJ.js.map +1 -0
- package/dist/components/{p-DKh6y3GY.js → p-04oMLTZR.js} +65 -5
- package/dist/components/p-04oMLTZR.js.map +1 -0
- package/dist/components/{p-DIv_A5Gj.js → p-B5rS_jjI.js} +7 -3
- package/dist/components/p-B5rS_jjI.js.map +1 -0
- package/dist/components/{p-4l9DAhAo.js → p-DbQ6ZNvh.js} +20 -4
- package/dist/components/p-DbQ6ZNvh.js.map +1 -0
- package/dist/components/{p-BIFlTsO8.js → p-Dh0wQJt6.js} +71 -6
- package/dist/components/p-Dh0wQJt6.js.map +1 -0
- package/dist/components/{p-CJGP2_5k.js → p-oOSnPjGy.js} +3 -3
- package/dist/components/{p-CJGP2_5k.js.map → p-oOSnPjGy.js.map} +1 -1
- package/dist/components/xplor-alert-dialog.js +60 -3
- package/dist/components/xplor-alert-dialog.js.map +1 -1
- package/dist/components/xplor-assistant.js +3 -3
- package/dist/components/xplor-assistant.js.map +1 -1
- package/dist/components/xplor-autocomplete.js +15 -9
- package/dist/components/xplor-autocomplete.js.map +1 -1
- package/dist/components/xplor-avatar-and-name.js +1 -1
- package/dist/components/xplor-avatar.js +1 -1
- package/dist/components/xplor-btn-back-to-parent.js +7 -2
- package/dist/components/xplor-btn-back-to-parent.js.map +1 -1
- package/dist/components/xplor-btn-icon.js +3 -2
- package/dist/components/xplor-btn-icon.js.map +1 -1
- package/dist/components/xplor-btn-menu.js +103 -6
- package/dist/components/xplor-btn-menu.js.map +1 -1
- package/dist/components/xplor-btn-tooltip.js +2 -2
- package/dist/components/xplor-button.js +1 -1
- package/dist/components/xplor-chat-widget.js +2 -2
- package/dist/components/xplor-checkbox.js +3 -1
- package/dist/components/xplor-checkbox.js.map +1 -1
- package/dist/components/xplor-combobox.js +20 -10
- package/dist/components/xplor-combobox.js.map +1 -1
- package/dist/components/xplor-datatable.js +10 -4
- package/dist/components/xplor-datatable.js.map +1 -1
- package/dist/components/xplor-date-picker.js +9 -5
- package/dist/components/xplor-date-picker.js.map +1 -1
- package/dist/components/xplor-drag-and-drop-input.js +43 -5
- package/dist/components/xplor-drag-and-drop-input.js.map +1 -1
- package/dist/components/xplor-dropdown.js +1 -1
- package/dist/components/xplor-expansion-panel.js +4 -4
- package/dist/components/xplor-expansion-panel.js.map +1 -1
- package/dist/components/xplor-expansion-panels.js +1 -1
- package/dist/components/xplor-expansion-panels.js.map +1 -1
- package/dist/components/xplor-file-upload.js +2 -2
- package/dist/components/xplor-file-upload.js.map +1 -1
- package/dist/components/xplor-inline-checkbox.js +2 -2
- package/dist/components/xplor-inline-date-picker.js +1 -1
- package/dist/components/xplor-inline-switch.js +1 -1
- package/dist/components/xplor-input-file.js +3 -1
- package/dist/components/xplor-input-file.js.map +1 -1
- package/dist/components/xplor-input-search.js +4 -2
- package/dist/components/xplor-input-search.js.map +1 -1
- package/dist/components/xplor-input-select.js +127 -7
- package/dist/components/xplor-input-select.js.map +1 -1
- package/dist/components/xplor-input-send.js +3 -3
- package/dist/components/xplor-input-send.js.map +1 -1
- package/dist/components/xplor-input-text-area.js +6 -2
- package/dist/components/xplor-input-text-area.js.map +1 -1
- package/dist/components/xplor-input-text-secondary.js +6 -2
- package/dist/components/xplor-input-text-secondary.js.map +1 -1
- package/dist/components/xplor-input-text.js +6 -2
- package/dist/components/xplor-input-text.js.map +1 -1
- package/dist/components/xplor-input-title.js +7 -2
- package/dist/components/xplor-input-title.js.map +1 -1
- package/dist/components/xplor-links.js +5 -2
- package/dist/components/xplor-links.js.map +1 -1
- package/dist/components/xplor-modal-persistent.js +2 -2
- package/dist/components/xplor-modal.js +1 -1
- package/dist/components/xplor-nav-tabs.js +41 -3
- package/dist/components/xplor-nav-tabs.js.map +1 -1
- package/dist/components/xplor-radio-btn.d.ts +11 -0
- package/dist/components/xplor-radio-btn.js +132 -0
- package/dist/components/xplor-radio-btn.js.map +1 -0
- package/dist/components/xplor-section-card.js +2 -2
- package/dist/components/xplor-section-card.js.map +1 -1
- package/dist/components/xplor-section-heading.js +9 -3
- package/dist/components/xplor-section-heading.js.map +1 -1
- package/dist/components/xplor-table.js +14 -9
- package/dist/components/xplor-table.js.map +1 -1
- package/dist/components/xplor-text-bubble.js +2 -2
- package/dist/components/xplor-text-field.js +2 -2
- package/dist/components/xplor-time-picker.js +6 -6
- package/dist/components/xplor-tooltip.js +1 -1
- package/dist/esm/{index-Zkk2NJif.js → index-KRfMjDC2.js} +5 -5
- package/dist/esm/index-KRfMjDC2.js.map +1 -0
- package/dist/esm/loader.js +3 -3
- package/dist/esm/{xplor-alert-dialog_57.entry.js → xplor-alert-dialog_58.entry.js} +747 -109
- package/dist/esm/xplor-alert-dialog_58.entry.js.map +1 -0
- package/dist/esm/xplor-component-library.js +3 -3
- package/dist/hydrate/index.js +798 -120
- package/dist/hydrate/index.mjs +798 -120
- package/dist/types/components/xplor-alert-dialog/xplor-alert-dialog.d.ts +11 -0
- package/dist/types/components/xplor-autocomplete/xplor-autocomplete.d.ts +4 -0
- package/dist/types/components/xplor-btn-back-to-parent/xplor-btn-back-to-parent.d.ts +4 -0
- package/dist/types/components/xplor-btn-icon/xplor-btn-icon.d.ts +4 -0
- package/dist/types/components/xplor-btn-menu/xplor-btn-menu.d.ts +19 -0
- package/dist/types/components/xplor-button/xplor-button.d.ts +4 -0
- package/dist/types/components/xplor-checkbox/xplor-checkbox.d.ts +1 -0
- package/dist/types/components/xplor-combobox/xplor-combobox.d.ts +4 -0
- package/dist/types/components/xplor-date-picker/xplor-date-picker.d.ts +3 -0
- package/dist/types/components/xplor-drag-and-drop-input/xplor-drag-and-drop-input.d.ts +11 -0
- package/dist/types/components/xplor-inline-date-picker/xplor-inline-date-picker.d.ts +3 -0
- package/dist/types/components/xplor-input-file/xplor-input-file.d.ts +1 -0
- package/dist/types/components/xplor-input-search/xplor-input-search.d.ts +1 -0
- package/dist/types/components/xplor-input-select/xplor-input-select.d.ts +15 -0
- package/dist/types/components/xplor-input-text/xplor-input-text.d.ts +3 -0
- package/dist/types/components/xplor-input-text-area/xplor-input-text-area.d.ts +3 -0
- package/dist/types/components/xplor-input-text-secondary/xplor-input-text-secondary.d.ts +3 -0
- package/dist/types/components/xplor-input-title/xplor-input-title.d.ts +4 -0
- package/dist/types/components/xplor-links/xplor-links.d.ts +2 -0
- package/dist/types/components/xplor-modal/xplor-modal.d.ts +11 -0
- package/dist/types/components/xplor-nav-tabs/xplor-nav-tabs.d.ts +2 -0
- package/dist/types/components/xplor-radio-btn/xplor-radio-btn.d.ts +35 -0
- package/dist/types/components/xplor-section-heading/xplor-section-heading.d.ts +4 -0
- package/dist/types/components/xplor-tooltip/xplor-tooltip.d.ts +3 -0
- package/dist/types/components.d.ts +230 -2
- package/dist/xplor-component-library/p-0df9ea5d.entry.js +2 -0
- package/dist/xplor-component-library/p-0df9ea5d.entry.js.map +1 -0
- package/dist/xplor-component-library/{p-Zkk2NJif.js → p-KRfMjDC2.js} +3 -3
- package/dist/xplor-component-library/p-KRfMjDC2.js.map +1 -0
- package/dist/xplor-component-library/xplor-component-library.css +1 -1
- package/dist/xplor-component-library/xplor-component-library.esm.js +1 -1
- package/package.json +1 -1
- package/components/p-B1W2qj2l.js.map +0 -1
- package/components/p-CBSi5kQB.js.map +0 -1
- package/components/p-CTD6SyTD.js.map +0 -1
- package/components/p-Ddr35stE.js.map +0 -1
- package/components/p-x30CgLRv.js.map +0 -1
- package/dist/cjs/index-Bc5o_4vY.js.map +0 -1
- package/dist/cjs/xplor-alert-dialog_57.cjs.entry.js.map +0 -1
- package/dist/components/p-4l9DAhAo.js.map +0 -1
- package/dist/components/p-BHdeGt6k.js.map +0 -1
- package/dist/components/p-BIFlTsO8.js.map +0 -1
- package/dist/components/p-DIv_A5Gj.js.map +0 -1
- package/dist/components/p-DKh6y3GY.js.map +0 -1
- package/dist/esm/index-Zkk2NJif.js.map +0 -1
- package/dist/esm/xplor-alert-dialog_57.entry.js.map +0 -1
- package/dist/xplor-component-library/p-25fa8553.entry.js +0 -2
- package/dist/xplor-component-library/p-25fa8553.entry.js.map +0 -1
- package/dist/xplor-component-library/p-Zkk2NJif.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["xplorAlertDialogCss","XplorAlertDialog","constructor","hostRef","this","open","width","persistent","previouslyFocusedElement","handleBackdropClick","closeDialog","handleCardClick","event","stopPropagation","xplorClose","emit","xplorDialogChange","handleOpenChange","newValue","document","body","style","overflow","activeElement","requestAnimationFrame","setInitialFocus","focus","disconnectedCallback","handleKeyDown","key","preventDefault","trapFocus","getFocusableElements","dialogEl","selectors","Array","from","querySelectorAll","focusableElements","length","firstElement","lastElement","shiftKey","render","h","Host","class","onClick","role","ariaLabel","undefined","tabindex","ref","el","type","id","name","xplorAlertMessageCss","XplorAlertMessage","dismissible","handleDismiss","xplorDismiss","alertTitle","generateSessionId","timestamp","Date","now","random","Math","toString","substring","getCurrentDate","year","getFullYear","month","String","getMonth","padStart","day","getDate","getCurrentTime","hours","getHours","minutes","getMinutes","seconds","getSeconds","async","sendMessageToAPI","endpoint","message","sessionId","userId","userEmail","userName","Error","trim","payload","currentDate","currentTime","response","fetch","method","headers","JSON","stringify","ok","errorText","text","catch","statusText","status","data","json","error","includes","detectBrowserCapabilities","window","voiceInput","textToSpeech","hasVoiceInput","hasTTS","SpeechRecognitionManager","recognition","onResultCallback","onErrorCallback","onStartCallback","onEndCallback","SpeechRecognition","webkitSpeechRecognition","continuous","interimResults","lang","maxAlternatives","onstart","onresult","transcript","results","onerror","errorMessage","getErrorMessage","onend","start","console","stop","onResult","callback","onError","onStart","onEnd","isAvailable","SpeechSynthesisManager","currentUtterance","speak","SpeechSynthesisUtterance","rate","pitch","volume","speechSynthesis","speaking","cancel","isSpeaking","microphoneIcon","sendIcon","speakerIcon","stopIcon","AssistantMessage","props","enableTextToSpeech","onSpeak","onStopSpeaking","messageClasses","handleSpeakClick","content","formatTime","ampm","displayHours","displayMinutes","title","innerHTML","AssistantInput","placeholder","disabled","isLoading","enableVoiceInput","isListening","inputValue","onSendMessage","onStartListening","onStopListening","setInputValue","handleSubmit","e","log","handleInputChange","target","value","handleVoiceClick","isSendDisabled","onSubmit","onInput","QuickReplies","replies","onReplyClick","map","reply","TypingIndicator","xplorAssistantCss","XplorAssistant","autoSpeak","maxHeight","messages","internalSessionId","hasVoiceSupport","hasTTSSupport","handleSendMessage","messageText","userMessage","assistantMessageSent","apiEndpoint","assistantMessage","assistantMessageReceived","handleError","handleVoiceInput","assistantError","handleStartListening","speechRecognition","handleStopListening","handleSpeak","handleStopSpeaking","handleQuickReply","componentWillLoad","assistantSessionCreated","capabilities","handleSessionIdChange","newSessionId","componentDidUpdate","scrollToBottom","sendMessage","clearHistory","stopSpeaking","messagesContainerRef","setTimeout","scrollTop","scrollHeight","quickReplies","xplorAutocompleteCss","XplorAutocomplete","items","readonly","clearable","multiple","minSearchLength","itemValue","itemText","menuMaxWidth","isOpen","searchQuery","filteredItems","selectedItems","highlightedIndex","handleInputFocus","input","filterItems","xplorSearch","xplorChange","handleInputKeyDown","min","scrollToHighlighted","max","selectItem","_a","inputEl","blur","removeItem","handleClear","xplorClear","getItemValue","item","getItemText","label","isArray","selectedItem","find","handleDocumentClick","contains","query","toLowerCase","filter","dropdownEl","highlightedEl","querySelector","scrollIntoView","block","itemVal","xplorSelect","v","getSelectedItemLabel","i","findItemByValue","hasValue","listboxId","labelId","activeDescendantId","autocomplete","chipLabel","renderSelection","onFocus","onKeyDown","maxWidth","index","isSelected","autocomplete__item","renderItem","xplorAvatarCss","XplorAvatar","className","size","color","inner","src","alt","href","xplorAvatarAndNameCss","XplorAvatarAndName","charAt","toUpperCase","xplorBadgeCss","XplorBadge","backgroundColor","threshold","variant","datatable","calculateLuminance","r","g","b","rs","gs","bs","c","pow","parseColor","startsWith","hex","replace","parseInt","rgbMatch","match","calculateContrastingColor","bgColor","rgb","luminance","cssVars","vars","computedClasses","xplorBadgeActiveCss","XplorBadgeActive","xplorBadgeArchivedCss","XplorBadgeArchived","xplorBadgeDeletedCss","XplorBadgeDeleted","xplorBadgeExpiredCss","XplorBadgeExpired","xplorBadgeInactiveCss","XplorBadgeInactive","xplorBadgeRecalledCss","XplorBadgeRecalled","xplorBadgeSessionBookingCss","XplorBadgeSessionBooking","getBookingTypeClass","classes","booking","push","_b","ccs_gap_fee_is_waived","join","xplorBadgeUpcomingCss","XplorBadgeUpcoming","xplorBadgeWaitlistCss","XplorBadgeWaitlist","xplorBtnBackCss","XplorBtnBack","minWidth","minHeight","gap","handleClick","xplorClick","buttonClasses","buttonStyles","xplorBtnBackToParentCss","XplorBtnBackToParent","inline","back","xplorBtnIconCss","XplorBtnIcon","iconSize","xplorBtnMenuCss","XplorBtnMenu","options","hiddenKeys","disabledKeys","density","show","focusedIndex","handleOutsideClick","menuRef","toggleMenu","handleClickOption","option","triggerBtnRef","isHidden","isDisabled","componentDidLoad","addEventListener","removeEventListener","getVisibleOptions","focusMenuItem","visibleOptions","totalVisible","menuId","visibleIndex","currentVisibleIndex","xplorBtnToggleCss","XplorBtnToggle","active","inactiveOutlined","xplorToggle","xplorBtnToggleGroupCss","XplorBtnToggleGroup","xplorBtnToggleSecondaryCss","XplorBtnToggleSecondary","xplorBtnTooltipCss","XplorBtnTooltip","tooltipPosition","position","tooltipText","trigger","arrow","slot","mode","iconPosition","xplorButtonCss","XplorButton","icon","renderIcon","iconSvg","isIconOnly","hasIcon","Object","assign","shadow","styles","clickAction","xplorChatWidgetCss","XplorChatWidget","languageOptions","textId","selectedLanguage","apiKey","service","action","language","textValue","then","handleChange","selectElement","element","host","shadowRoot","getElementById","textContent","selected","xplorCheckboxCss","checkboxIdCounter","XplorCheckbox","initialChecked","initialIndeterminate","checked","indeterminate","isHovered","isFocused","isPressed","checkboxChange","handleKeyUp","getCheckboxClass","watchCheckedProp","watchIndeterminateProp","onMouseEnter","onMouseLeave","onMouseDown","onMouseUp","onBlur","onKeyUp","tabIndex","viewBox","fill","d","stroke","xplorComboboxCss","XplorCombobox","allowCustom","createMessage","customItems","totalItems","canCreateNew","createNewItem","allItems","exactMatch","some","newItem","xplorCreate","showCreateOption","combobox","combobox__item","xplorDatatableCss","XplorDatatable","loading","pagination","page","perpage","total","canSelect","horizontalLines","striped","skeletonLoader","hover","perPageOptions","sortBy","sortDirection","internalSelected","Set","allSelected","handleSort","column","sortable","sortChange","direction","handleSelectAll","forEach","add","clear","xplorSelectionChange","handleSelectOne","delete","updateAllSelectedState","handleRowClick","tagName","closest","rowClick","handlePageChange","newPage","updatedPagination","paginationChange","handlePerPageChange","isNaN","watchSelected","newSelected","watchItems","every","has","getSortIcon","height","opacity","renderSkeletonLoader","renderPagination","totalPages","ceil","currentPage","end","tableHeight","hasHeight","onChange","header","sorted","fixed","align","colSpan","clickable","xplorDatePickerCss","datePickerIdCounter","XplorDatePicker","monthType","display","dateFormat","closeOnSelect","startWeekOnSunday","hideDetails","required","inputText","dropdownPosition","inputId","errorId","toggleDropdown","updateDropdownPosition","xplorFocus","handleInputBlur","xplorBlur","parsed","parseInputText","isDateInRange","formatDateForDisplay","dateChange","handleDateSelected","iso","detail","parseISODate","finalDate","finalIso","toISO","handleTextClick","getTime","date","Intl","DateTimeFormat","format","trimmed","slashMatch","isoMatch","rect","getBoundingClientRect","spaceBelow","innerHeight","bottom","showDetails","calendarIcon","x","y","rx","ry","x1","y1","x2","y2","htmlFor","selectedDate","onDateSelected","xplorDragAndDropInputCss","DEFAULT_ACCEPT_ALL","XplorDragAndDropInput","accepts","browseLabel","progress","dragover","currentFile","onDrop","file","dataTransfer","files","fileSelect","onDragOver","onDragEnter","onDragLeave","onFileSelect","openFileDialog","fileInputEl","click","getAcceptsLabel","formatFileSize","bytes","k","sizes","floor","parseFloat","toFixed","formatDate","months","suffix","showProgress","clearCurrentFile","fileClear","progressValue","dropZoneLabel","xmlns","lastModified","round","accept","xplorDropdownCss","XplorDropdown","xplorExpansionPanelCss","nextId","XplorExpansionPanel","contentHeight","handleToggle","xplorPanelToggle","panelId","updateContentHeight","contentEl","xplorExpansionPanelsCss","XplorExpansionPanels","accordion","openPanels","handlePanelToggle","newPanels","xplorFileUploadCss","XplorFileUpload","maxSize","showPreview","isDragging","handleFileSelect","processFiles","handleDragOver","handleDragLeave","handleDrop","handleRemoveFile","fileToRemove","f","xplorFileRemove","handleButtonClick","fileList","validFiles","maxSizeMB","xplorError","acceptedTypes","split","t","fileExtension","pop","isAccepted","endsWith","uploadedFile","substr","reader","FileReader","onload","dataUrl","result","readAsDataURL","xplorFileAdd","xplorInlineCheckboxCss","XplorInlineCheckbox","containerClasses","accentColor","xplorInlineDatePickerCss","XplorInlineDatePicker","focusedDay","monthNames","dayNames","dayNamesStartMonday","previousMonth","currentMonth","currentYear","viewDate","monthChanged","nextMonth","selectDate","dateString","isDateDisabled","dateSelected","minDate","maxDate","isToday","today","getDaysInMonth","getFirstDayOfMonth","firstDay","getDay","renderCalendarDays","daysInMonth","days","getSidebarDate","remainder","dayEl","sidebarDate","dayHeaders","xplorInlineSwitchCss","XplorInlineSwitch","xplorInputFileCss","inputFileIdCounter","XplorInputFile","maxChips","counter","showSize","prependInnerIcon","selectedFiles","handleFileChange","attach","fileInputRef","visibleFiles","slice","additionalCount","xplorInputSearchCss","inputSearchIdCounter","XplorInputSearch","handleInput","handleSearch","search","xplorInputSelectCss","XplorInputSelect","helperText","menuPosition","updateMenuPosition","fieldRef","top","left","selectRef","handleOptionClick","currentValue","findIndex","_","getDisplayValue","selectedOptions","opt","selectedOption","totalOptions","scrollToHighlightedOption","helperId","describedByParts","ariaDescribedBy","readOnly","subtitle","xplorInputSendCss","XplorInputSend","buttonText","buttonType","internalValue","xplorValueChange","handleSend","xplorSend","maxLength","xplorInputTextCss","inputTextIdCounter","XplorInputText","xplorInput","handleFocus","handleBlur","xplorInputTextAreaCss","inputTextAreaIdCounter","XplorInputTextArea","rows","showClearButton","xplorInputTextSecondaryCss","inputTextSecondaryIdCounter","XplorInputTextSecondary","isDirty","xplorInputTitleCss","XplorInputTitle","xplorLinksCss","XplorLinks","imageAlt","brand","xplorModalCss","XplorModal","scrollable","showTitle","closeModal","cardClasses","bodyClasses","XplorModalPersistent","onXplorClose","xplorNavTabsCss","XplorNavTabs","grow","handleTabClick","enabledItems","currentIndex","newIndex","buttons","allItemIndex","indexOf","targetButton","xplorRadioBtnCss","XplorRadioBtn","getSiblingRadios","radio","deselect","radioChange","getRadioClass","parent","parentElement","all","xplorSectionCardCss","XplorSectionCard","outlined","rounded","padding","xplorSectionHeadingCss","XplorSectionHeading","level","HeadingTag","getIconType","sortType","XplorTable","selectedValues","isSortable","sortableColumns","areAllSelected","hasScrolled","sortTypeArray","selectedDateRange","handlePagination","handleDateRangeChange","handleFilterReports","handleDownloadAll","selectAllValue","selectAll","HTMLInputElement","selectOne","checkboxIdx","selectedIdx","tableSelect","onScroll","container","scrollLeft","col","val","idx","a","toLocaleLowerCase","rowData","sort","setData","getPaginatedData","startIndex","endIndex","watchData","columns","freeze","paginatedData","iconType","isColumnSortable","multiselect","row","rowNum","cell","xplorTextBubbleCss","XplorTextBubble","xplorTextFieldCss","XplorTextField","errorMessages","customClass","valueChange","inputFocus","inputBlur","clearClick","inputElement","handleValueChange","hasError","labelFloating","maxlength","xplorTimePickerCss","XplorTimePicker","prefill","showSeconds","period","lastGoodValue","emitChange","timeChange","incrementHours","decrementHours","incrementMinutes","decrementMinutes","incrementSeconds","decrementSeconds","togglePeriod","parseValueToState","formatDisplayTime","parts","m","s","stateToValue","hStr","mStr","sStr","raw","sanitised","withColons","splits","hour","minute","second","num","renderChevronUp","points","renderChevronDown","clockIcon","cx","cy","xplorTooltipCss","tooltipIdCounter","XplorTooltip","tooltipStyle","arrowStyle","tooltipId","handleMouseEnter","hideTimeout","clearTimeout","showTooltip","handleMouseLeave","hideTooltip","handleFocusIn","handleFocusOut","updatePosition","setupHoverListeners","cleanupListeners","triggerEl","tooltipEl","triggerRect","tooltipRect","arrowSize","arrowTop","arrowLeft","arrowTransform","right","viewportPadding","innerWidth","transform","tooltip"],"sources":["src/components/xplor-alert-dialog/xplor-alert-dialog.scss?tag=xplor-alert-dialog&encapsulation=scoped","src/components/xplor-alert-dialog/xplor-alert-dialog.tsx","src/components/xplor-alert-message/xplor-alert-message.scss?tag=xplor-alert-message&encapsulation=scoped","src/components/xplor-alert-message/xplor-alert-message.tsx","src/components/xplor-assistant/utils/api.ts","src/components/xplor-assistant/utils/speech.ts","src/components/xplor-assistant/utils/icons.ts","src/components/xplor-assistant/internal/AssistantMessage.tsx","src/components/xplor-assistant/internal/AssistantInput.tsx","src/components/xplor-assistant/internal/QuickReplies.tsx","src/components/xplor-assistant/internal/TypingIndicator.tsx","src/components/xplor-assistant/xplor-assistant.scss?tag=xplor-assistant&encapsulation=scoped","src/components/xplor-assistant/xplor-assistant.tsx","src/components/xplor-autocomplete/xplor-autocomplete.scss?tag=xplor-autocomplete&encapsulation=scoped","src/components/xplor-autocomplete/xplor-autocomplete.tsx","src/components/xplor-avatar/xplor-avatar.scss?tag=xplor-avatar&encapsulation=shadow","src/components/xplor-avatar/xplor-avatar.tsx","src/components/xplor-avatar-and-name/xplor-avatar-and-name.scss?tag=xplor-avatar-and-name&encapsulation=scoped","src/components/xplor-avatar-and-name/xplor-avatar-and-name.tsx","src/components/xplor-badge/xplor-badge.scss?tag=xplor-badge&encapsulation=scoped","src/components/xplor-badge/xplor-badge.tsx","src/components/xplor-badge-active/xplor-badge-active.scss?tag=xplor-badge-active&encapsulation=scoped","src/components/xplor-badge-active/xplor-badge-active.tsx","src/components/xplor-badge-archived/xplor-badge-archived.scss?tag=xplor-badge-archived&encapsulation=scoped","src/components/xplor-badge-archived/xplor-badge-archived.tsx","src/components/xplor-badge-deleted/xplor-badge-deleted.scss?tag=xplor-badge-deleted&encapsulation=scoped","src/components/xplor-badge-deleted/xplor-badge-deleted.tsx","src/components/xplor-badge-expired/xplor-badge-expired.scss?tag=xplor-badge-expired&encapsulation=scoped","src/components/xplor-badge-expired/xplor-badge-expired.tsx","src/components/xplor-badge-inactive/xplor-badge-inactive.scss?tag=xplor-badge-inactive&encapsulation=scoped","src/components/xplor-badge-inactive/xplor-badge-inactive.tsx","src/components/xplor-badge-recalled/xplor-badge-recalled.scss?tag=xplor-badge-recalled&encapsulation=scoped","src/components/xplor-badge-recalled/xplor-badge-recalled.tsx","src/components/xplor-badge-session-booking/xplor-badge-session-booking.scss?tag=xplor-badge-session-booking&encapsulation=scoped","src/components/xplor-badge-session-booking/xplor-badge-session-booking.tsx","src/components/xplor-badge-upcoming/xplor-badge-upcoming.scss?tag=xplor-badge-upcoming&encapsulation=scoped","src/components/xplor-badge-upcoming/xplor-badge-upcoming.tsx","src/components/xplor-badge-waitlist/xplor-badge-waitlist.scss?tag=xplor-badge-waitlist&encapsulation=scoped","src/components/xplor-badge-waitlist/xplor-badge-waitlist.tsx","src/components/xplor-btn-back/xplor-btn-back.scss?tag=xplor-btn-back&encapsulation=scoped","src/components/xplor-btn-back/xplor-btn-back.tsx","src/components/xplor-btn-back-to-parent/xplor-btn-back-to-parent.scss?tag=xplor-btn-back-to-parent&encapsulation=scoped","src/components/xplor-btn-back-to-parent/xplor-btn-back-to-parent.tsx","src/components/xplor-btn-icon/xplor-btn-icon.scss?tag=xplor-btn-icon&encapsulation=scoped","src/components/xplor-btn-icon/xplor-btn-icon.tsx","src/components/xplor-btn-menu/xplor-btn-menu.scss?tag=xplor-btn-menu&encapsulation=scoped","src/components/xplor-btn-menu/xplor-btn-menu.tsx","src/components/xplor-btn-toggle/xplor-btn-toggle.scss?tag=xplor-btn-toggle&encapsulation=scoped","src/components/xplor-btn-toggle/xplor-btn-toggle.tsx","src/components/xplor-btn-toggle-group/xplor-btn-toggle-group.scss?tag=xplor-btn-toggle-group&encapsulation=scoped","src/components/xplor-btn-toggle-group/xplor-btn-toggle-group.tsx","src/components/xplor-btn-toggle-secondary/xplor-btn-toggle-secondary.scss?tag=xplor-btn-toggle-secondary&encapsulation=scoped","src/components/xplor-btn-toggle-secondary/xplor-btn-toggle-secondary.tsx","src/components/xplor-btn-tooltip/xplor-btn-tooltip.scss?tag=xplor-btn-tooltip&encapsulation=scoped","src/components/xplor-btn-tooltip/xplor-btn-tooltip.tsx","src/components/xplor-button/xplor-button.scss?tag=xplor-button&encapsulation=scoped","src/components/xplor-button/xplor-button.tsx","src/components/xplor-chat-widget/xplor-chat-widget.scss?tag=xplor-chat-widget&encapsulation=shadow","src/components/xplor-chat-widget/xplor-chat-widget.tsx","src/components/xplor-checkbox/xplor-checkbox.scss?tag=xplor-checkbox&encapsulation=shadow","src/components/xplor-checkbox/xplor-checkbox.tsx","src/components/xplor-combobox/xplor-combobox.scss?tag=xplor-combobox&encapsulation=scoped","src/components/xplor-combobox/xplor-combobox.tsx","src/components/xplor-datatable/xplor-datatable.scss?tag=xplor-datatable&encapsulation=shadow","src/components/xplor-datatable/xplor-datatable.tsx","src/components/xplor-date-picker/xplor-date-picker.scss?tag=xplor-date-picker&encapsulation=scoped","src/components/xplor-date-picker/xplor-date-picker.tsx","src/components/xplor-drag-and-drop-input/xplor-drag-and-drop-input.scss?tag=xplor-drag-and-drop-input&encapsulation=scoped","src/components/xplor-drag-and-drop-input/xplor-drag-and-drop-input.tsx","src/components/xplor-dropdown/xplor-dropdown.scss?tag=xplor-dropdown&encapsulation=shadow","src/components/xplor-dropdown/xplor-dropdown.tsx","src/components/xplor-expansion-panel/xplor-expansion-panel.scss?tag=xplor-expansion-panel&encapsulation=scoped","src/components/xplor-expansion-panel/xplor-expansion-panel.tsx","src/components/xplor-expansion-panels/xplor-expansion-panels.scss?tag=xplor-expansion-panels&encapsulation=scoped","src/components/xplor-expansion-panels/xplor-expansion-panels.tsx","src/components/xplor-file-upload/xplor-file-upload.scss?tag=xplor-file-upload&encapsulation=scoped","src/components/xplor-file-upload/xplor-file-upload.tsx","src/components/xplor-inline-checkbox/xplor-inline-checkbox.scss?tag=xplor-inline-checkbox&encapsulation=scoped","src/components/xplor-inline-checkbox/xplor-inline-checkbox.tsx","src/components/xplor-inline-date-picker/xplor-inline-date-picker.scss?tag=xplor-inline-date-picker&encapsulation=scoped","src/components/xplor-inline-date-picker/xplor-inline-date-picker.tsx","src/components/xplor-inline-switch/xplor-inline-switch.scss?tag=xplor-inline-switch&encapsulation=scoped","src/components/xplor-inline-switch/xplor-inline-switch.tsx","src/components/xplor-input-file/xplor-input-file.scss?tag=xplor-input-file&encapsulation=scoped","src/components/xplor-input-file/xplor-input-file.tsx","src/components/xplor-input-search/xplor-input-search.scss?tag=xplor-input-search&encapsulation=scoped","src/components/xplor-input-search/xplor-input-search.tsx","src/components/xplor-input-select/xplor-input-select.scss?tag=xplor-input-select&encapsulation=scoped","src/components/xplor-input-select/xplor-input-select.tsx","src/components/xplor-input-send/xplor-input-send.scss?tag=xplor-input-send&encapsulation=scoped","src/components/xplor-input-send/xplor-input-send.tsx","src/components/xplor-input-text/xplor-input-text.scss?tag=xplor-input-text&encapsulation=scoped","src/components/xplor-input-text/xplor-input-text.tsx","src/components/xplor-input-text-area/xplor-input-text-area.scss?tag=xplor-input-text-area&encapsulation=scoped","src/components/xplor-input-text-area/xplor-input-text-area.tsx","src/components/xplor-input-text-secondary/xplor-input-text-secondary.scss?tag=xplor-input-text-secondary&encapsulation=scoped","src/components/xplor-input-text-secondary/xplor-input-text-secondary.tsx","src/components/xplor-input-title/xplor-input-title.scss?tag=xplor-input-title&encapsulation=scoped","src/components/xplor-input-title/xplor-input-title.tsx","src/components/xplor-links/xplor-links.css?tag=xplor-links&encapsulation=shadow","src/components/xplor-links/xplor-links.tsx","src/components/xplor-modal/xplor-modal.scss?tag=xplor-modal&encapsulation=scoped","src/components/xplor-modal/xplor-modal.tsx","src/components/xplor-modal-persistent/xplor-modal-persistent.tsx","src/components/xplor-nav-tabs/xplor-nav-tabs.scss?tag=xplor-nav-tabs&encapsulation=scoped","src/components/xplor-nav-tabs/xplor-nav-tabs.tsx","src/components/xplor-radio-btn/xplor-radio-btn.scss?tag=xplor-radio-btn&encapsulation=shadow","src/components/xplor-radio-btn/xplor-radio-btn.tsx","src/components/xplor-section-card/xplor-section-card.scss?tag=xplor-section-card&encapsulation=scoped","src/components/xplor-section-card/xplor-section-card.tsx","src/components/xplor-section-heading/xplor-section-heading.scss?tag=xplor-section-heading&encapsulation=scoped","src/components/xplor-section-heading/xplor-section-heading.tsx","src/components/xplor-table/xplor-table.tsx","src/components/xplor-text-bubble/xplor-text-bubble.scss?tag=xplor-text-bubble&encapsulation=scoped","src/components/xplor-text-bubble/xplor-text-bubble.tsx","src/components/xplor-text-field/xplor-text-field.scss?tag=xplor-text-field&encapsulation=scoped","src/components/xplor-text-field/xplor-text-field.tsx","src/components/xplor-time-picker/xplor-time-picker.scss?tag=xplor-time-picker&encapsulation=scoped","src/components/xplor-time-picker/xplor-time-picker.tsx","src/components/xplor-tooltip/xplor-tooltip.scss?tag=xplor-tooltip&encapsulation=scoped","src/components/xplor-tooltip/xplor-tooltip.tsx"],"sourcesContent":[":host {\n display: contents;\n}\n\n.xplor-alert-dialog {\n &__backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 2000;\n padding: 1rem;\n }\n\n &__card {\n position: relative;\n background-color: white;\n border-radius: 0.5rem;\n padding: 3.75rem 1.25rem;\n min-height: 320px;\n max-width: 90vw;\n max-height: 90vh;\n overflow: auto;\n box-shadow: 0px 11px 15px -7px rgba(0, 0, 0, 0.2),\n 0px 24px 38px 3px rgba(0, 0, 0, 0.14),\n 0px 9px 46px 8px rgba(0, 0, 0, 0.12);\n animation: xplor-dialog-fade-in 0.2s ease-out;\n }\n\n &__close-btn {\n position: absolute;\n top: 1rem;\n right: 1rem;\n width: 2rem;\n height: 2rem;\n border: none;\n background: transparent;\n color: rgba(0, 0, 0, 0.54);\n font-size: 1.5rem;\n cursor: pointer;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s ease;\n z-index: 1;\n\n &:hover {\n background-color: rgba(0, 0, 0, 0.04);\n }\n\n &:active {\n background-color: rgba(0, 0, 0, 0.08);\n }\n }\n\n &__title {\n padding-top: 0;\n margin-bottom: 1rem;\n font-size: 1.25rem;\n font-weight: 500;\n color: rgba(0, 0, 0, 0.87);\n }\n\n &__text {\n margin-bottom: 1.5rem;\n color: rgba(0, 0, 0, 0.87);\n }\n\n &__actions {\n display: flex;\n gap: 0.5rem;\n justify-content: flex-end;\n }\n}\n\n@keyframes xplor-dialog-fade-in {\n from {\n opacity: 0;\n transform: scale(0.95);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n}\n","import { Component, Host, h, Prop, Event, EventEmitter, Watch, Element, Listen } from '@stencil/core';\n\n@Component({\n tag: 'xplor-alert-dialog',\n styleUrl: 'xplor-alert-dialog.scss',\n scoped: true,\n})\nexport class XplorAlertDialog {\n /**\n * Whether the dialog is open\n */\n @Prop({ mutable: true }) open: boolean = false;\n\n /**\n * Dialog width (can be pixel value or percentage)\n */\n @Prop() width: string = '408px';\n\n /**\n * Persistent mode - prevents closing on backdrop click\n */\n @Prop() persistent: boolean = true;\n\n /**\n * Accessible label for the dialog (used if no title slot)\n */\n @Prop() ariaLabel: string;\n\n /**\n * Close event\n */\n @Event() xplorClose: EventEmitter<void>;\n\n /**\n * Dialog state change event\n */\n @Event() xplorDialogChange: EventEmitter<boolean>;\n\n @Element() el: HTMLElement;\n\n private previouslyFocusedElement: HTMLElement | null = null;\n private dialogEl: HTMLElement;\n\n @Watch('open')\n handleOpenChange(newValue: boolean) {\n if (newValue) {\n document.body.style.overflow = 'hidden';\n this.previouslyFocusedElement = document.activeElement as HTMLElement;\n requestAnimationFrame(() => {\n this.setInitialFocus();\n });\n } else {\n document.body.style.overflow = '';\n if (this.previouslyFocusedElement) {\n this.previouslyFocusedElement.focus();\n this.previouslyFocusedElement = null;\n }\n }\n }\n\n disconnectedCallback() {\n document.body.style.overflow = '';\n }\n\n @Listen('keydown')\n handleKeyDown(event: KeyboardEvent) {\n if (!this.open) return;\n\n if (event.key === 'Escape' && !this.persistent) {\n event.preventDefault();\n this.closeDialog();\n return;\n }\n\n if (event.key === 'Tab') {\n this.trapFocus(event);\n }\n }\n\n private getFocusableElements(): HTMLElement[] {\n if (!this.dialogEl) return [];\n const selectors = 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n return Array.from(this.dialogEl.querySelectorAll(selectors)) as HTMLElement[];\n }\n\n private trapFocus(event: KeyboardEvent) {\n const focusableElements = this.getFocusableElements();\n if (focusableElements.length === 0) return;\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n\n if (event.shiftKey) {\n if (document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n }\n } else {\n if (document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n }\n }\n\n private setInitialFocus() {\n const focusableElements = this.getFocusableElements();\n if (focusableElements.length > 0) {\n focusableElements[0].focus();\n } else if (this.dialogEl) {\n this.dialogEl.focus();\n }\n }\n\n private handleBackdropClick = () => {\n if (!this.persistent) {\n this.closeDialog();\n }\n };\n\n private handleCardClick = (event: Event) => {\n event.stopPropagation();\n };\n\n private closeDialog = () => {\n this.open = false;\n this.xplorClose.emit();\n this.xplorDialogChange.emit(false);\n };\n\n render() {\n if (!this.open) {\n return null;\n }\n\n return (\n <Host>\n <div class=\"xplor-alert-dialog__backdrop\" onClick={this.handleBackdropClick}>\n <div\n class=\"xplor-alert-dialog__card\"\n style={{ width: this.width }}\n onClick={this.handleCardClick}\n role=\"alertdialog\"\n aria-modal=\"true\"\n aria-labelledby={this.ariaLabel ? undefined : 'xplor-alert-dialog-title'}\n aria-label={this.ariaLabel}\n aria-describedby=\"xplor-alert-dialog-text\"\n tabindex=\"-1\"\n ref={(el) => (this.dialogEl = el)}\n >\n <button\n type=\"button\"\n class=\"xplor-alert-dialog__close-btn\"\n onClick={this.closeDialog}\n aria-label=\"Close dialog\"\n >\n ✕\n </button>\n\n <div class=\"xplor-alert-dialog__title\" id=\"xplor-alert-dialog-title\">\n <slot name=\"title\" />\n </div>\n\n <div class=\"xplor-alert-dialog__text\" id=\"xplor-alert-dialog-text\">\n <slot name=\"text\" />\n </div>\n\n <div class=\"xplor-alert-dialog__actions\">\n <slot name=\"actions\" />\n </div>\n </div>\n </div>\n </Host>\n );\n }\n}\n",":host {\n display: block;\n}\n\n.alert-message {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n padding: 1rem 1.5rem;\n border-radius: 4px;\n border-left: 4px solid;\n gap: 1rem;\n\n &--info {\n background-color: #ede7f6;\n border-left-color: #673ab7;\n color: #4a148c;\n }\n\n &--warning {\n background-color: #fff3e0;\n border-left-color: #ff9800;\n color: #e65100;\n }\n\n &--success {\n background-color: #e8f5e9;\n border-left-color: #4caf50;\n color: #1b5e20;\n }\n\n &--error {\n background-color: #ffebee;\n border-left-color: #f44336;\n color: #b71c1c;\n }\n}\n\n.alert-message__content {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.alert-message__title {\n font-weight: 600;\n font-size: 1rem;\n line-height: 1.5;\n}\n\n.alert-message__body {\n font-size: 0.875rem;\n line-height: 1.5;\n}\n\n.alert-message__actions {\n margin-top: 0.5rem;\n\n &:empty {\n display: none;\n }\n}\n\n.alert-message__dismiss {\n background: none;\n border: none;\n font-size: 1.5rem;\n line-height: 1;\n cursor: pointer;\n padding: 0;\n width: 1.5rem;\n height: 1.5rem;\n display: flex;\n align-items: center;\n justify-content: center;\n color: currentColor;\n opacity: 0.7;\n transition: opacity 0.2s;\n flex-shrink: 0;\n\n &:hover {\n opacity: 1;\n }\n\n &:focus {\n outline: 2px solid currentColor;\n outline-offset: 2px;\n border-radius: 2px;\n }\n}","import { Component, Host, h, Prop, Event, EventEmitter } from '@stencil/core';\n\n@Component({\n tag: 'xplor-alert-message',\n styleUrl: 'xplor-alert-message.scss',\n scoped: true,\n})\nexport class XplorAlertMessage {\n @Prop() type: 'info' | 'warning' | 'success' | 'error' = 'info';\n @Prop() alertTitle: string;\n @Prop() dismissible: boolean = false;\n\n @Event() xplorDismiss: EventEmitter<void>;\n\n private handleDismiss = () => {\n this.xplorDismiss.emit();\n };\n\n render() {\n return (\n <Host>\n <div\n class={{\n 'alert-message': true,\n [`alert-message--${this.type}`]: true,\n }}\n role=\"alert\"\n >\n <div class=\"alert-message__content\">\n {this.alertTitle && (\n <div class=\"alert-message__title\">\n <slot name=\"title\">{this.alertTitle}</slot>\n </div>\n )}\n <div class=\"alert-message__body\">\n <slot />\n </div>\n <div class=\"alert-message__actions\">\n <slot name=\"actions\" />\n </div>\n </div>\n {this.dismissible && (\n <button\n class=\"alert-message__dismiss\"\n onClick={this.handleDismiss}\n aria-label=\"Dismiss alert\"\n type=\"button\"\n >\n ×\n </button>\n )}\n </div>\n </Host>\n );\n }\n}\n","/**\n * API integration utilities for the xplor-assistant component\n */\n\nimport { AssistantAPIRequest, AssistantAPIResponse } from '../internal/types';\n\n/**\n * Generates a unique session ID\n * Format: session_${timestamp}_${random}\n */\nexport function generateSessionId(): string {\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 11);\n return `session_${timestamp}_${random}`;\n}\n\n/**\n * Formats the current date as YYYY-MM-DD\n */\nexport function getCurrentDate(): string {\n const now = new Date();\n const year = now.getFullYear();\n const month = String(now.getMonth() + 1).padStart(2, '0');\n const day = String(now.getDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n}\n\n/**\n * Formats the current time as HH:MM:SS\n */\nexport function getCurrentTime(): string {\n const now = new Date();\n const hours = String(now.getHours()).padStart(2, '0');\n const minutes = String(now.getMinutes()).padStart(2, '0');\n const seconds = String(now.getSeconds()).padStart(2, '0');\n return `${hours}:${minutes}:${seconds}`;\n}\n\n/**\n * Sends a message to the assistant API\n *\n * @param endpoint - The API endpoint URL\n * @param message - The user's message\n * @param sessionId - The current session ID\n * @param userId - The user's ID\n * @param userEmail - The user's email\n * @param userName - The user's name\n * @returns Promise with the API response\n * @throws Error if the API call fails\n */\nexport async function sendMessageToAPI(\n endpoint: string,\n message: string,\n sessionId: string,\n userId: string,\n userEmail: string,\n userName: string\n): Promise<AssistantAPIResponse> {\n if (!endpoint) {\n throw new Error('API endpoint is required');\n }\n\n if (!message || !message.trim()) {\n throw new Error('Message cannot be empty');\n }\n\n const payload: AssistantAPIRequest = {\n message: message.trim(),\n sessionId,\n userId,\n userEmail,\n userName,\n currentDate: getCurrentDate(),\n currentTime: getCurrentTime(),\n };\n\n try {\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n throw new Error(`API error: ${response.status} - ${errorText}`);\n }\n\n const data: AssistantAPIResponse = await response.json();\n\n // Validate response structure\n if (!data.message || !data.sessionId) {\n throw new Error('Invalid API response: missing required fields');\n }\n\n return data;\n } catch (error) {\n if (error instanceof Error) {\n // Re-throw with more context if it's a fetch error\n if (error.name === 'TypeError' && error.message.includes('fetch')) {\n throw new Error('Network error: Unable to reach the API. Please check your connection.');\n }\n throw error;\n }\n throw new Error('Unknown error occurred while calling the API');\n }\n}\n\n/**\n * Creates an AbortController for cancelling requests\n * Useful for cleanup when component unmounts\n */\nexport function createRequestController(): AbortController {\n return new AbortController();\n}\n\n/**\n * Sends a message to the API with abort support\n *\n * @param endpoint - The API endpoint URL\n * @param message - The user's message\n * @param sessionId - The current session ID\n * @param userId - The user's ID\n * @param userEmail - The user's email\n * @param userName - The user's name\n * @param signal - AbortSignal for cancelling the request\n * @returns Promise with the API response\n */\nexport async function sendMessageWithAbort(\n endpoint: string,\n message: string,\n sessionId: string,\n userId: string,\n userEmail: string,\n userName: string,\n signal?: AbortSignal\n): Promise<AssistantAPIResponse> {\n const payload: AssistantAPIRequest = {\n message: message.trim(),\n sessionId,\n userId,\n userEmail,\n userName,\n currentDate: getCurrentDate(),\n currentTime: getCurrentTime(),\n };\n\n const response = await fetch(endpoint, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(payload),\n signal,\n });\n\n if (!response.ok) {\n const errorText = await response.text().catch(() => response.statusText);\n throw new Error(`API error: ${response.status} - ${errorText}`);\n }\n\n const data: AssistantAPIResponse = await response.json();\n\n if (!data.message || !data.sessionId) {\n throw new Error('Invalid API response: missing required fields');\n }\n\n return data;\n}\n","/**\n * Web Speech API helpers for the xplor-assistant component\n * Handles both Speech Recognition (voice input) and Speech Synthesis (text-to-speech)\n */\n\nimport { BrowserCapabilities } from '../internal/types';\n\n/**\n * Detects browser capabilities for speech features\n */\nexport function detectBrowserCapabilities(): BrowserCapabilities {\n if (typeof window === 'undefined') {\n return {\n voiceInput: false,\n textToSpeech: false,\n };\n }\n\n const hasVoiceInput =\n 'SpeechRecognition' in window ||\n 'webkitSpeechRecognition' in window;\n\n const hasTTS = 'speechSynthesis' in window;\n\n return {\n voiceInput: hasVoiceInput,\n textToSpeech: hasTTS,\n };\n}\n\n/**\n * Speech Recognition Manager\n * Handles voice-to-text functionality\n */\nexport class SpeechRecognitionManager {\n private recognition: any = null;\n private onResultCallback: ((transcript: string) => void) | null = null;\n private onErrorCallback: ((error: string) => void) | null = null;\n private onStartCallback: (() => void) | null = null;\n private onEndCallback: (() => void) | null = null;\n\n constructor() {\n if (typeof window === 'undefined') return;\n\n const SpeechRecognition =\n (window as any).SpeechRecognition ||\n (window as any).webkitSpeechRecognition;\n\n if (SpeechRecognition) {\n this.recognition = new SpeechRecognition();\n this.recognition.continuous = false;\n this.recognition.interimResults = false;\n this.recognition.lang = 'en-US';\n this.recognition.maxAlternatives = 1;\n\n this.recognition.onstart = () => {\n if (this.onStartCallback) {\n this.onStartCallback();\n }\n };\n\n this.recognition.onresult = (event: any) => {\n const transcript = event.results[0][0].transcript;\n if (this.onResultCallback) {\n this.onResultCallback(transcript);\n }\n };\n\n this.recognition.onerror = (event: any) => {\n const errorMessage = this.getErrorMessage(event.error);\n if (this.onErrorCallback) {\n this.onErrorCallback(errorMessage);\n }\n };\n\n this.recognition.onend = () => {\n if (this.onEndCallback) {\n this.onEndCallback();\n }\n };\n }\n }\n\n /**\n * Converts speech recognition error codes to user-friendly messages\n */\n private getErrorMessage(error: string): string {\n switch (error) {\n case 'no-speech':\n return 'No speech detected. Please try again.';\n case 'audio-capture':\n return 'No microphone found. Please ensure a microphone is connected.';\n case 'not-allowed':\n return 'Microphone permission denied. Please allow microphone access.';\n case 'network':\n return 'Network error. Please check your connection.';\n default:\n return `Speech recognition error: ${error}`;\n }\n }\n\n /**\n * Starts listening for voice input\n */\n start(): void {\n if (!this.recognition) {\n console.error('Speech recognition not supported');\n return;\n }\n\n try {\n this.recognition.start();\n } catch (error) {\n console.error('Failed to start speech recognition:', error);\n if (this.onErrorCallback) {\n this.onErrorCallback('Failed to start voice recognition');\n }\n }\n }\n\n /**\n * Stops listening for voice input\n */\n stop(): void {\n if (this.recognition) {\n this.recognition.stop();\n }\n }\n\n /**\n * Sets the callback for when a result is received\n */\n onResult(callback: (transcript: string) => void): void {\n this.onResultCallback = callback;\n }\n\n /**\n * Sets the callback for when an error occurs\n */\n onError(callback: (error: string) => void): void {\n this.onErrorCallback = callback;\n }\n\n /**\n * Sets the callback for when recognition starts\n */\n onStart(callback: () => void): void {\n this.onStartCallback = callback;\n }\n\n /**\n * Sets the callback for when recognition ends\n */\n onEnd(callback: () => void): void {\n this.onEndCallback = callback;\n }\n\n /**\n * Checks if speech recognition is available\n */\n isAvailable(): boolean {\n return this.recognition !== null;\n }\n}\n\n/**\n * Speech Synthesis Manager\n * Handles text-to-speech functionality\n */\nexport class SpeechSynthesisManager {\n private currentUtterance: SpeechSynthesisUtterance | null = null;\n private onStartCallback: (() => void) | null = null;\n private onEndCallback: (() => void) | null = null;\n\n /**\n * Speaks the given text\n */\n speak(text: string): void {\n if (typeof window === 'undefined' || !('speechSynthesis' in window)) {\n console.error('Speech synthesis not supported');\n return;\n }\n\n // Stop any ongoing speech first\n this.stop();\n\n this.currentUtterance = new SpeechSynthesisUtterance(text);\n this.currentUtterance.lang = 'en-US';\n this.currentUtterance.rate = 1.0;\n this.currentUtterance.pitch = 1.0;\n this.currentUtterance.volume = 1.0;\n\n this.currentUtterance.onstart = () => {\n if (this.onStartCallback) {\n this.onStartCallback();\n }\n };\n\n this.currentUtterance.onend = () => {\n if (this.onEndCallback) {\n this.onEndCallback();\n }\n this.currentUtterance = null;\n };\n\n this.currentUtterance.onerror = (event) => {\n console.error('Speech synthesis error:', event);\n if (this.onEndCallback) {\n this.onEndCallback();\n }\n this.currentUtterance = null;\n };\n\n window.speechSynthesis.speak(this.currentUtterance);\n }\n\n /**\n * Stops any ongoing speech\n */\n stop(): void {\n if (typeof window === 'undefined' || !('speechSynthesis' in window)) {\n return;\n }\n\n if (window.speechSynthesis.speaking) {\n window.speechSynthesis.cancel();\n if (this.onEndCallback) {\n this.onEndCallback();\n }\n }\n this.currentUtterance = null;\n }\n\n /**\n * Checks if currently speaking\n */\n isSpeaking(): boolean {\n if (typeof window === 'undefined' || !('speechSynthesis' in window)) {\n return false;\n }\n return window.speechSynthesis.speaking;\n }\n\n /**\n * Sets the callback for when speech starts\n */\n onStart(callback: () => void): void {\n this.onStartCallback = callback;\n }\n\n /**\n * Sets the callback for when speech ends\n */\n onEnd(callback: () => void): void {\n this.onEndCallback = callback;\n }\n\n /**\n * Checks if speech synthesis is available\n */\n isAvailable(): boolean {\n return typeof window !== 'undefined' && 'speechSynthesis' in window;\n }\n}\n","/**\n * SVG icon definitions for the xplor-assistant component\n * Following the pattern used in xplor-button component\n */\n\n/**\n * Microphone icon for voice input button\n */\nexport const microphoneIcon = `\n<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z\"></path>\n <path d=\"M19 10v2a7 7 0 0 1-14 0v-2\"></path>\n <line x1=\"12\" y1=\"19\" x2=\"12\" y2=\"23\"></line>\n <line x1=\"8\" y1=\"23\" x2=\"16\" y2=\"23\"></line>\n</svg>\n`;\n\n/**\n * Send arrow icon for send message button\n */\nexport const sendIcon = `\n<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"></line>\n <polygon points=\"22 2 15 22 11 13 2 9 22 2\"></polygon>\n</svg>\n`;\n\n/**\n * Speaker icon for text-to-speech button\n */\nexport const speakerIcon = `\n<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\"></polygon>\n <path d=\"M15.54 8.46a5 5 0 0 1 0 7.07\"></path>\n <path d=\"M19.07 4.93a10 10 0 0 1 0 14.14\"></path>\n</svg>\n`;\n\n/**\n * Stop square icon for stopping speech\n */\nexport const stopIcon = `\n<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" stroke=\"none\">\n <rect x=\"6\" y=\"6\" width=\"12\" height=\"12\" rx=\"2\"></rect>\n</svg>\n`;\n\n/**\n * Muted speaker icon for when TTS is disabled\n */\nexport const speakerMutedIcon = `\n<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polygon points=\"11 5 6 9 2 9 2 15 6 15 11 19 11 5\"></polygon>\n <line x1=\"23\" y1=\"9\" x2=\"17\" y2=\"15\"></line>\n <line x1=\"17\" y1=\"9\" x2=\"23\" y2=\"15\"></line>\n</svg>\n`;\n","/**\n * AssistantMessage - Internal component\n * Renders a single message bubble with optional text-to-speech functionality\n */\n\nimport { h } from '@stencil/core';\nimport { AssistantMessageProps } from './types';\nimport { speakerIcon, stopIcon } from '../utils/icons';\n\nexport const AssistantMessage = (props: AssistantMessageProps) => {\n const { message, enableTextToSpeech, isSpeaking, onSpeak, onStopSpeaking } = props;\n\n const messageClasses = {\n 'xplor-assistant__message': true,\n 'xplor-assistant__message--user': message.role === 'user',\n 'xplor-assistant__message--assistant': message.role === 'assistant',\n };\n\n const handleSpeakClick = () => {\n if (isSpeaking) {\n onStopSpeaking?.();\n } else {\n onSpeak?.(message.content);\n }\n };\n\n const formatTime = (timestamp: Date) => {\n const hours = timestamp.getHours();\n const minutes = timestamp.getMinutes();\n const ampm = hours >= 12 ? 'PM' : 'AM';\n const displayHours = hours % 12 || 12;\n const displayMinutes = minutes < 10 ? `0${minutes}` : minutes;\n return `${displayHours}:${displayMinutes} ${ampm}`;\n };\n\n return (\n <div class={messageClasses}>\n <div class=\"xplor-assistant__message-content\">\n {message.content}\n </div>\n <div class=\"xplor-assistant__message-footer\">\n <span class=\"xplor-assistant__message-timestamp\">\n {formatTime(message.timestamp)}\n </span>\n {message.role === 'assistant' && enableTextToSpeech && (\n <button\n class={{\n 'xplor-assistant__speak-button': true,\n 'xplor-assistant__speak-button--active': isSpeaking,\n }}\n onClick={handleSpeakClick}\n title={isSpeaking ? 'Stop speaking' : 'Listen to message'}\n type=\"button\"\n >\n <span\n class=\"xplor-assistant__speak-icon\"\n innerHTML={isSpeaking ? stopIcon : speakerIcon}\n ></span>\n </button>\n )}\n </div>\n </div>\n );\n};\n","/**\n * AssistantInput - Internal component\n * Renders the input field with voice and send buttons\n */\n\nimport { h } from '@stencil/core';\nimport { microphoneIcon, sendIcon } from '../utils/icons';\n\nexport interface AssistantInputInternalProps {\n placeholder: string;\n disabled: boolean;\n isLoading: boolean;\n enableVoiceInput: boolean;\n isListening: boolean;\n inputValue: string;\n onSendMessage: (message: string) => void;\n onStartListening: () => void;\n onStopListening: () => void;\n setInputValue: (value: string) => void;\n}\n\nexport const AssistantInput = (props: AssistantInputInternalProps) => {\n const {\n placeholder,\n disabled,\n isLoading,\n enableVoiceInput,\n isListening,\n inputValue,\n onSendMessage,\n onStartListening,\n onStopListening,\n setInputValue,\n } = props;\n\n const handleSubmit = (e: Event) => {\n e.preventDefault();\n console.log('[AssistantInput] Submit triggered, inputValue:', inputValue);\n if (inputValue.trim() && !disabled && !isLoading) {\n console.log('[AssistantInput] Calling onSendMessage with:', inputValue);\n onSendMessage(inputValue);\n setInputValue('');\n } else {\n console.log('[AssistantInput] Submit blocked - disabled:', disabled, 'isLoading:', isLoading, 'hasValue:', !!inputValue.trim());\n }\n };\n\n const handleInputChange = (e: Event) => {\n const target = e.target as HTMLInputElement;\n setInputValue(target.value);\n };\n\n const handleVoiceClick = () => {\n if (isListening) {\n onStopListening();\n } else {\n onStartListening();\n }\n };\n\n const isSendDisabled = !inputValue.trim() || disabled || isLoading;\n\n return (\n <div class=\"xplor-assistant__input-container\">\n <form onSubmit={handleSubmit} class=\"xplor-assistant__input-form\">\n {enableVoiceInput && (\n <button\n type=\"button\"\n class={{\n 'xplor-assistant__voice-button': true,\n 'xplor-assistant__voice-button--listening': isListening,\n }}\n onClick={handleVoiceClick}\n disabled={disabled || isLoading}\n title={isListening ? 'Stop listening' : 'Start voice input'}\n aria-label=\"Voice input\"\n >\n <span class=\"xplor-assistant__voice-icon\" innerHTML={microphoneIcon}></span>\n </button>\n )}\n\n <input\n type=\"text\"\n class=\"xplor-assistant__input\"\n placeholder={placeholder}\n value={inputValue}\n onInput={handleInputChange}\n disabled={disabled || isLoading}\n />\n\n <button\n type=\"submit\"\n class=\"xplor-assistant__send-button\"\n disabled={isSendDisabled}\n title=\"Send message\"\n aria-label=\"Send message\"\n >\n <span class=\"xplor-assistant__send-icon\" innerHTML={sendIcon}></span>\n </button>\n </form>\n </div>\n );\n};\n","/**\n * QuickReplies - Internal component\n * Renders quick reply suggestion buttons\n */\n\nimport { h } from '@stencil/core';\nimport { QuickRepliesProps } from './types';\n\nexport const QuickReplies = (props: QuickRepliesProps) => {\n const { replies, disabled, onReplyClick } = props;\n\n if (!replies || replies.length === 0) {\n return null;\n }\n\n return (\n <div class=\"xplor-assistant__quick-replies\">\n {replies.map((reply) => (\n <button\n class=\"xplor-assistant__quick-reply\"\n onClick={() => onReplyClick(reply)}\n disabled={disabled}\n type=\"button\"\n >\n {reply}\n </button>\n ))}\n </div>\n );\n};\n","/**\n * TypingIndicator - Internal component\n * Displays animated dots to indicate the assistant is processing/typing\n */\n\nimport { h } from '@stencil/core';\n\nexport const TypingIndicator = () => {\n return (\n <div class=\"xplor-assistant__typing-indicator\">\n <span class=\"xplor-assistant__typing-dot\"></span>\n <span class=\"xplor-assistant__typing-dot\"></span>\n <span class=\"xplor-assistant__typing-dot\"></span>\n </div>\n );\n};\n","@use '../../styles/colours.scss' as colours;\n@use '../../styles/spacing.scss' as spacing;\n@use '../../styles/mixins.scss' as mixins;\n\n:host {\n display: block;\n\n // CSS custom properties for theming\n --assistant-bot-bg: #{colours.$secondary}; // Purple for bot messages\n --assistant-user-bg: #{colours.$gray-200}; // Light gray for user messages\n --assistant-accent: #{colours.$warning}; // Orange accents\n --assistant-border: #{colours.$gray-300};\n --assistant-text: #{colours.$gray-900};\n --assistant-text-light: #{colours.$gray-600};\n}\n\n.xplor-assistant {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n background-color: colours.$white;\n border-radius: 0.75rem;\n border: 1px solid var(--assistant-border);\n overflow: hidden;\n\n &--disabled {\n opacity: 0.6;\n pointer-events: none;\n }\n\n &--error {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: spacing.$spacing-24;\n }\n}\n\n// Messages Area\n.xplor-assistant__messages {\n flex: 1;\n overflow-y: auto;\n padding: spacing.$spacing-16;\n display: flex;\n flex-direction: column;\n gap: spacing.$spacing-12;\n scroll-behavior: smooth;\n\n // Scrollbar styling\n &::-webkit-scrollbar {\n width: 6px;\n }\n\n &::-webkit-scrollbar-track {\n background: colours.$gray-100;\n border-radius: 3px;\n }\n\n &::-webkit-scrollbar-thumb {\n background: colours.$gray-400;\n border-radius: 3px;\n\n &:hover {\n background: colours.$gray-500;\n }\n }\n}\n\n// Individual Message\n.xplor-assistant__message {\n display: flex;\n flex-direction: column;\n max-width: 80%;\n animation: slideIn 0.3s ease-out;\n\n &--bot {\n align-self: flex-start;\n\n .xplor-assistant__message-content {\n background-color: var(--assistant-bot-bg);\n color: colours.$white;\n border-radius: 1rem 1rem 1rem 0.25rem;\n }\n }\n\n &--user {\n align-self: flex-end;\n\n .xplor-assistant__message-content {\n background-color: var(--assistant-user-bg);\n color: var(--assistant-text);\n border-radius: 1rem 1rem 0.25rem 1rem;\n }\n }\n}\n\n.xplor-assistant__message-content {\n padding: spacing.$spacing-12 spacing.$spacing-16;\n font-size: 0.9375rem;\n line-height: 1.5;\n word-wrap: break-word;\n overflow-wrap: break-word;\n}\n\n.xplor-assistant__message-footer {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-top: spacing.$spacing-4;\n padding: 0 spacing.$spacing-8;\n}\n\n.xplor-assistant__message-timestamp {\n font-size: 0.75rem;\n color: var(--assistant-text-light);\n}\n\n.xplor-assistant__speak-button {\n background: transparent;\n border: none;\n cursor: pointer;\n padding: spacing.$spacing-4;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: 50%;\n transition: background-color 0.2s;\n\n &:hover {\n background-color: colours.$gray-200;\n }\n\n &--active {\n background-color: colours.$gray-300;\n }\n}\n\n.xplor-assistant__speak-icon {\n width: 16px;\n height: 16px;\n display: flex;\n align-items: center;\n justify-content: center;\n\n svg {\n width: 16px;\n height: 16px;\n stroke: var(--assistant-text-light);\n }\n}\n\n// Typing Indicator\n.xplor-assistant__typing-indicator {\n display: flex;\n gap: spacing.$spacing-4;\n padding: spacing.$spacing-12 spacing.$spacing-16;\n}\n\n.xplor-assistant__typing-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background-color: colours.$gray-400;\n animation: typingBounce 1.4s infinite ease-in-out;\n\n &:nth-child(1) {\n animation-delay: 0s;\n }\n\n &:nth-child(2) {\n animation-delay: 0.2s;\n }\n\n &:nth-child(3) {\n animation-delay: 0.4s;\n }\n}\n\n// Error Banner\n.xplor-assistant__error-banner {\n background-color: colours.$error-50;\n color: colours.$error-700;\n padding: spacing.$spacing-12 spacing.$spacing-16;\n border-radius: 0.5rem;\n font-size: 0.875rem;\n margin: spacing.$spacing-8 0;\n}\n\n.xplor-assistant__error-message {\n color: colours.$error-700;\n font-size: 0.9375rem;\n text-align: center;\n}\n\n// Quick Replies\n.xplor-assistant__quick-replies {\n display: flex;\n flex-wrap: wrap;\n gap: spacing.$spacing-8;\n padding: spacing.$spacing-12 spacing.$spacing-16;\n border-top: 1px solid var(--assistant-border);\n background-color: colours.$gray-50;\n}\n\n.xplor-assistant__quick-reply {\n padding: spacing.$spacing-8 spacing.$spacing-16;\n background-color: colours.$white;\n border: 2px solid var(--assistant-accent);\n color: var(--assistant-accent);\n border-radius: 1rem;\n font-size: 0.875rem;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.2s;\n white-space: nowrap;\n\n &:hover:not(:disabled) {\n background-color: var(--assistant-accent);\n color: colours.$white;\n transform: translateY(-1px);\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n}\n\n// Input Container\n.xplor-assistant__input-container {\n border-top: 1px solid var(--assistant-border);\n padding: spacing.$spacing-12;\n background-color: colours.$white;\n}\n\n.xplor-assistant__input-form {\n display: flex;\n gap: spacing.$spacing-8;\n align-items: center;\n}\n\n.xplor-assistant__input {\n flex: 1;\n padding: spacing.$spacing-12 spacing.$spacing-16;\n border: 1px solid var(--assistant-border);\n border-radius: 1.5rem;\n font-size: 0.9375rem;\n outline: none;\n transition: border-color 0.2s;\n\n &:focus {\n border-color: var(--assistant-bot-bg);\n }\n\n &:disabled {\n background-color: colours.$gray-100;\n cursor: not-allowed;\n }\n\n &::placeholder {\n color: colours.$gray-500;\n }\n}\n\n.xplor-assistant__voice-button {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n border: none;\n background-color: colours.$gray-200;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s;\n flex-shrink: 0;\n\n &:hover:not(:disabled) {\n background-color: colours.$gray-300;\n transform: scale(1.05);\n }\n\n &--listening {\n background-color: colours.$error;\n animation: pulse 1.5s ease-in-out infinite;\n\n .xplor-assistant__voice-icon svg {\n stroke: colours.$white;\n }\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n}\n\n.xplor-assistant__voice-icon {\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n\n svg {\n width: 20px;\n height: 20px;\n stroke: var(--assistant-text);\n }\n}\n\n.xplor-assistant__send-button {\n width: 40px;\n height: 40px;\n border-radius: 50%;\n border: none;\n background-color: var(--assistant-bot-bg);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: all 0.2s;\n flex-shrink: 0;\n\n &:hover:not(:disabled) {\n background-color: colours.$secondary-700;\n transform: scale(1.05);\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n}\n\n.xplor-assistant__send-icon {\n width: 20px;\n height: 20px;\n display: flex;\n align-items: center;\n justify-content: center;\n\n svg {\n width: 20px;\n height: 20px;\n stroke: colours.$white;\n }\n}\n\n// Animations\n@keyframes slideIn {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes typingBounce {\n 0%, 60%, 100% {\n transform: translateY(0);\n }\n 30% {\n transform: translateY(-8px);\n }\n}\n\n@keyframes pulse {\n 0%, 100% {\n transform: scale(1);\n opacity: 1;\n }\n 50% {\n transform: scale(1.05);\n opacity: 0.9;\n }\n}\n","import { Component, Host, h, Prop, State, Event, EventEmitter, Method, Element, Watch } from '@stencil/core';\nimport {\n AssistantMessage as MessageType,\n AssistantMessageSentEvent,\n AssistantMessageReceivedEvent,\n AssistantErrorEvent,\n AssistantSessionEvent,\n} from './internal/types';\nimport { sendMessageToAPI, generateSessionId } from './utils/api';\nimport { SpeechRecognitionManager, SpeechSynthesisManager, detectBrowserCapabilities } from './utils/speech';\nimport { AssistantMessage } from './internal/AssistantMessage';\nimport { AssistantInput } from './internal/AssistantInput';\nimport { QuickReplies } from './internal/QuickReplies';\nimport { TypingIndicator } from './internal/TypingIndicator';\n\n@Component({\n tag: 'xplor-assistant',\n styleUrl: 'xplor-assistant.scss',\n scoped: true,\n})\nexport class XplorAssistant {\n @Element() el: HTMLElement;\n\n // Required Props\n @Prop() apiEndpoint!: string;\n @Prop() userId!: string;\n @Prop() userEmail!: string;\n @Prop() userName!: string;\n\n // Optional Props\n @Prop() sessionId?: string;\n @Prop() quickReplies?: string[];\n @Prop() placeholder: string = 'Type your message...';\n @Prop() enableVoiceInput: boolean = true;\n @Prop() enableTextToSpeech: boolean = true;\n @Prop() autoSpeak: boolean = false;\n @Prop() maxHeight: string = '600px';\n @Prop() disabled: boolean = false;\n\n // State\n @State() messages: MessageType[] = [];\n @State() internalSessionId: string = '';\n @State() isLoading: boolean = false;\n @State() isListening: boolean = false;\n @State() isSpeaking: boolean = false;\n @State() error: string = '';\n @State() inputValue: string = '';\n @State() hasVoiceSupport: boolean = false;\n @State() hasTTSSupport: boolean = false;\n\n // Events\n @Event() assistantMessageSent: EventEmitter<AssistantMessageSentEvent>;\n @Event() assistantMessageReceived: EventEmitter<AssistantMessageReceivedEvent>;\n @Event() assistantError: EventEmitter<AssistantErrorEvent>;\n @Event() assistantSessionCreated: EventEmitter<AssistantSessionEvent>;\n\n // Private members\n private speechRecognition: SpeechRecognitionManager;\n private speechSynthesis: SpeechSynthesisManager;\n private messagesContainerRef: HTMLDivElement;\n\n componentWillLoad() {\n // Validate required props\n if (!this.apiEndpoint) {\n console.error('xplor-assistant: apiEndpoint prop is required');\n this.error = 'Configuration error: API endpoint not provided';\n return;\n }\n\n if (!this.userId || !this.userEmail || !this.userName) {\n console.error('xplor-assistant: userId, userEmail, and userName props are required');\n this.error = 'Configuration error: User information not provided';\n return;\n }\n\n // Initialize session\n if (this.sessionId) {\n this.internalSessionId = this.sessionId;\n } else {\n this.internalSessionId = generateSessionId();\n this.assistantSessionCreated.emit({\n sessionId: this.internalSessionId,\n timestamp: new Date(),\n });\n }\n\n // Detect browser capabilities\n const capabilities = detectBrowserCapabilities();\n this.hasVoiceSupport = capabilities.voiceInput;\n this.hasTTSSupport = capabilities.textToSpeech;\n\n // Disable features if not supported\n if (!this.hasVoiceSupport) {\n this.enableVoiceInput = false;\n }\n if (!this.hasTTSSupport) {\n this.enableTextToSpeech = false;\n }\n\n // Initialize speech managers\n this.speechRecognition = new SpeechRecognitionManager();\n this.speechSynthesis = new SpeechSynthesisManager();\n\n // Setup speech recognition callbacks\n this.speechRecognition.onStart(() => {\n this.isListening = true;\n });\n\n this.speechRecognition.onEnd(() => {\n this.isListening = false;\n });\n\n this.speechRecognition.onResult((transcript) => {\n this.handleVoiceInput(transcript);\n });\n\n this.speechRecognition.onError((error) => {\n this.isListening = false;\n this.handleError(error, 'voice');\n });\n\n // Setup speech synthesis callbacks\n this.speechSynthesis.onStart(() => {\n this.isSpeaking = true;\n });\n\n this.speechSynthesis.onEnd(() => {\n this.isSpeaking = false;\n });\n }\n\n @Watch('sessionId')\n handleSessionIdChange(newSessionId: string) {\n if (newSessionId && newSessionId !== this.internalSessionId) {\n this.internalSessionId = newSessionId;\n }\n }\n\n componentDidUpdate() {\n // Auto-scroll to bottom when new messages arrive\n this.scrollToBottom();\n }\n\n disconnectedCallback() {\n // Cleanup speech synthesis\n if (this.speechSynthesis) {\n this.speechSynthesis.stop();\n }\n }\n\n // Public Methods\n\n @Method()\n async sendMessage(message: string): Promise<void> {\n if (!message || !message.trim()) {\n return;\n }\n await this.handleSendMessage(message);\n }\n\n @Method()\n async clearHistory(): Promise<void> {\n this.messages = [];\n this.error = '';\n }\n\n @Method()\n async speak(text: string): Promise<void> {\n if (this.enableTextToSpeech && this.speechSynthesis) {\n this.speechSynthesis.speak(text);\n }\n }\n\n @Method()\n async stopSpeaking(): Promise<void> {\n if (this.speechSynthesis) {\n this.speechSynthesis.stop();\n }\n }\n\n // Private Methods\n\n private scrollToBottom() {\n if (this.messagesContainerRef) {\n setTimeout(() => {\n this.messagesContainerRef.scrollTop = this.messagesContainerRef.scrollHeight;\n }, 100);\n }\n }\n\n private handleSendMessage = async (messageText: string) => {\n console.log('[XplorAssistant] handleSendMessage called with:', messageText);\n\n if (this.disabled || this.isLoading || !messageText.trim()) {\n console.log('[XplorAssistant] Message blocked - disabled:', this.disabled, 'isLoading:', this.isLoading, 'hasValue:', !!messageText.trim());\n return;\n }\n\n // Clear the input immediately\n this.inputValue = '';\n console.log('[XplorAssistant] Input cleared, proceeding with message');\n\n const userMessage: MessageType = {\n id: `user-${Date.now()}`,\n role: 'user',\n content: messageText.trim(),\n timestamp: new Date(),\n };\n\n // Add user message to the conversation\n this.messages = [...this.messages, userMessage];\n this.error = '';\n this.isLoading = true;\n\n // Emit message sent event\n this.assistantMessageSent.emit({\n message: userMessage.content,\n sessionId: this.internalSessionId,\n timestamp: userMessage.timestamp,\n });\n\n try {\n // Call the API\n const response = await sendMessageToAPI(\n this.apiEndpoint,\n userMessage.content,\n this.internalSessionId,\n this.userId,\n this.userEmail,\n this.userName\n );\n\n // Update session ID if changed\n if (response.sessionId && response.sessionId !== this.internalSessionId) {\n this.internalSessionId = response.sessionId;\n }\n\n // Add assistant response to conversation\n const assistantMessage: MessageType = {\n id: `assistant-${Date.now()}`,\n role: 'assistant',\n content: response.message,\n timestamp: new Date(),\n };\n\n this.messages = [...this.messages, assistantMessage];\n\n // Emit message received event\n this.assistantMessageReceived.emit({\n message: assistantMessage.content,\n sessionId: this.internalSessionId,\n timestamp: assistantMessage.timestamp,\n });\n\n // Auto-speak if enabled\n if (this.autoSpeak && this.enableTextToSpeech) {\n this.speechSynthesis.speak(assistantMessage.content);\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Failed to send message';\n this.handleError(errorMessage, 'api');\n } finally {\n this.isLoading = false;\n }\n };\n\n private handleVoiceInput = (transcript: string) => {\n if (transcript && transcript.trim()) {\n this.handleSendMessage(transcript);\n }\n };\n\n private handleError = (error: string, type: 'api' | 'voice' | 'tts' | 'network' | 'validation') => {\n this.error = error;\n this.assistantError.emit({\n error,\n type,\n timestamp: new Date(),\n });\n };\n\n private handleStartListening = () => {\n if (this.speechRecognition && this.enableVoiceInput && !this.disabled && !this.isLoading) {\n this.speechRecognition.start();\n }\n };\n\n private handleStopListening = () => {\n if (this.speechRecognition) {\n this.speechRecognition.stop();\n }\n };\n\n private handleSpeak = (text: string) => {\n if (this.speechSynthesis && this.enableTextToSpeech) {\n this.speechSynthesis.speak(text);\n }\n };\n\n private handleStopSpeaking = () => {\n if (this.speechSynthesis) {\n this.speechSynthesis.stop();\n }\n };\n\n private handleQuickReply = (reply: string) => {\n this.handleSendMessage(reply);\n };\n\n private setInputValue = (value: string) => {\n this.inputValue = value;\n };\n\n render() {\n // Show error state if critical error\n if (this.error && !this.apiEndpoint) {\n return (\n <Host>\n <div class=\"xplor-assistant xplor-assistant--error\">\n <div class=\"xplor-assistant__error-message\">\n {this.error}\n </div>\n </div>\n </Host>\n );\n }\n\n return (\n <Host>\n <div\n class={{\n 'xplor-assistant': true,\n 'xplor-assistant--disabled': this.disabled,\n }}\n style={{ maxHeight: this.maxHeight }}\n >\n {/* Messages Area */}\n <div\n class=\"xplor-assistant__messages\"\n ref={(el) => (this.messagesContainerRef = el)}\n role=\"log\"\n aria-live=\"polite\"\n aria-busy={this.isLoading ? 'true' : 'false'}\n >\n {this.messages.map((message) => (\n <AssistantMessage\n message={message}\n enableTextToSpeech={this.enableTextToSpeech}\n autoSpeak={false}\n isSpeaking={this.isSpeaking}\n onSpeak={this.handleSpeak}\n onStopSpeaking={this.handleStopSpeaking}\n />\n ))}\n\n {/* Loading Indicator */}\n {this.isLoading && (\n <div class=\"xplor-assistant__message xplor-assistant__message--assistant\">\n <TypingIndicator />\n </div>\n )}\n\n {/* Error Message */}\n {this.error && this.apiEndpoint && (\n <div class=\"xplor-assistant__error-banner\">\n {this.error}\n </div>\n )}\n </div>\n\n {/* Quick Replies */}\n {this.quickReplies && this.quickReplies.length > 0 && (\n <QuickReplies\n replies={this.quickReplies}\n disabled={this.disabled || this.isLoading}\n onReplyClick={this.handleQuickReply}\n />\n )}\n\n {/* Input Area */}\n <AssistantInput\n placeholder={this.placeholder}\n disabled={this.disabled}\n isLoading={this.isLoading}\n enableVoiceInput={this.enableVoiceInput && this.hasVoiceSupport}\n isListening={this.isListening}\n onSendMessage={this.handleSendMessage}\n onStartListening={this.handleStartListening}\n onStopListening={this.handleStopListening}\n inputValue={this.inputValue}\n setInputValue={this.setInputValue}\n />\n </div>\n </Host>\n );\n }\n}\n",":host {\n display: block;\n width: 100%;\n}\n\n.autocomplete {\n position: relative;\n width: 100%;\n\n &--disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n &--readonly {\n .autocomplete__input {\n background-color: #f5f5f5;\n }\n }\n}\n\n.autocomplete__label {\n display: block;\n font-size: 0.875rem;\n font-weight: 500;\n color: #424242;\n margin-bottom: 0.5rem;\n}\n\n.autocomplete__input-wrapper {\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0.5rem;\n border: 1px solid #bdbdbd;\n border-radius: 4px;\n padding: 0.5rem;\n background-color: #fff;\n transition: border-color 0.2s, box-shadow 0.2s;\n\n &:focus-within {\n border-color: #1976d2;\n box-shadow: 0 0 0 3px rgba(25, 118, 210, 0.1);\n }\n}\n\n.autocomplete__chips {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n}\n\n.autocomplete__chip {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0.25rem 0.5rem;\n background-color: #e3f2fd;\n border-radius: 16px;\n font-size: 0.875rem;\n color: #1976d2;\n}\n\n.autocomplete__chip-label {\n line-height: 1;\n}\n\n.autocomplete__chip-remove {\n background: none;\n border: none;\n font-size: 1.25rem;\n line-height: 1;\n cursor: pointer;\n padding: 0;\n width: 1rem;\n height: 1rem;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #1976d2;\n border-radius: 50%;\n transition: background-color 0.2s;\n\n &:hover:not(:disabled) {\n background-color: rgba(25, 118, 210, 0.1);\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n}\n\n.autocomplete__input {\n flex: 1;\n min-width: 120px;\n border: none;\n outline: none;\n font-family: inherit;\n font-size: 1rem;\n padding: 0.25rem;\n background: transparent;\n color: #212121;\n\n &::placeholder {\n color: #9e9e9e;\n }\n\n &:disabled {\n cursor: not-allowed;\n }\n\n &[readonly] {\n cursor: default;\n }\n}\n\n.autocomplete__actions {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n flex-shrink: 0;\n}\n\n.autocomplete__clear {\n background: none;\n border: none;\n font-size: 1.25rem;\n line-height: 1;\n cursor: pointer;\n padding: 0;\n width: 1.5rem;\n height: 1.5rem;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #757575;\n border-radius: 50%;\n transition: background-color 0.2s;\n\n &:hover {\n background-color: #f5f5f5;\n color: #212121;\n }\n}\n\n.autocomplete__icon {\n font-size: 0.75rem;\n color: #757575;\n pointer-events: none;\n transition: transform 0.2s;\n\n .autocomplete--open & {\n transform: rotate(180deg);\n }\n}\n\n.autocomplete__dropdown {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n right: 0;\n max-height: 300px;\n overflow-y: auto;\n background-color: #fff;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);\n z-index: 1000;\n}\n\n.autocomplete__item {\n padding: 0.75rem 1rem;\n cursor: pointer;\n transition: background-color 0.2s;\n color: #212121;\n\n &:hover:not(&--disabled) {\n background-color: #f5f5f5;\n }\n\n &--highlighted {\n background-color: #e3f2fd;\n }\n\n &--selected {\n background-color: #1976d2;\n color: #fff;\n\n &:hover {\n background-color: #1565c0;\n }\n }\n\n &--disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n}\n\n.autocomplete__no-results {\n padding: 1rem;\n text-align: center;\n color: #757575;\n font-size: 0.875rem;\n}","import { Component, Host, h, Prop, State, Event, EventEmitter, Element, Listen } from '@stencil/core';\n\nexport interface AutocompleteItem {\n label: string;\n value: any;\n disabled?: boolean;\n [key: string]: any;\n}\n\n@Component({\n tag: 'xplor-autocomplete',\n styleUrl: 'xplor-autocomplete.scss',\n scoped: true,\n})\nexport class XplorAutocomplete {\n @Element() el: HTMLElement;\n\n /**\n * Array of items to display in the dropdown\n */\n @Prop() items: AutocompleteItem[] = [];\n\n /**\n * Selected value\n */\n @Prop({ mutable: true }) value: any = null;\n\n /**\n * Placeholder text\n */\n @Prop() placeholder: string = 'Search...';\n\n /**\n * Label for the input\n */\n @Prop() label: string;\n\n /**\n * Accessible label for the input when no visible label is provided\n */\n @Prop() ariaLabel: string;\n\n /**\n * Disable the autocomplete\n */\n @Prop() disabled: boolean = false;\n\n /**\n * Make the autocomplete readonly\n */\n @Prop() readonly: boolean = false;\n\n /**\n * Clear button\n */\n @Prop() clearable: boolean = false;\n\n /**\n * Allow multiple selection\n */\n @Prop() multiple: boolean = false;\n\n /**\n * Minimum characters to trigger search\n */\n @Prop() minSearchLength: number = 0;\n\n /**\n * Key to extract value from item objects\n */\n @Prop() itemValue: string = 'value';\n\n /**\n * Key to extract display text from item objects\n */\n @Prop() itemText: string = 'label';\n\n /**\n * Max width of the dropdown menu\n */\n @Prop() menuMaxWidth: string = '100%';\n\n /**\n * Custom render function for dropdown items\n */\n @Prop() renderItem: (item: AutocompleteItem) => any;\n\n /**\n * Custom render function for selected items (chips)\n */\n @Prop() renderSelection: (item: AutocompleteItem) => any;\n\n @State() isOpen: boolean = false;\n @State() searchQuery: string = '';\n @State() filteredItems: AutocompleteItem[] = [];\n @State() selectedItems: any[] = [];\n @State() highlightedIndex: number = -1;\n\n @Event() xplorChange: EventEmitter<any>;\n @Event() xplorSelect: EventEmitter<AutocompleteItem>;\n @Event() xplorClear: EventEmitter<void>;\n @Event() xplorSearch: EventEmitter<string>;\n\n private inputEl: HTMLInputElement;\n private dropdownEl: HTMLDivElement;\n\n private getItemValue(item: AutocompleteItem): any {\n return item[this.itemValue] !== undefined ? item[this.itemValue] : item.value;\n }\n\n private getItemText(item: AutocompleteItem): string {\n return item[this.itemText] !== undefined ? String(item[this.itemText]) : String(item.label);\n }\n\n componentWillLoad() {\n this.filterItems();\n if (this.value !== null) {\n if (this.multiple && Array.isArray(this.value)) {\n this.selectedItems = this.value;\n } else if (!this.multiple) {\n const selectedItem = this.items.find(item => this.getItemValue(item) === this.value);\n if (selectedItem) {\n this.searchQuery = this.getItemText(selectedItem);\n }\n }\n }\n }\n\n @Listen('click', { target: 'document' })\n handleDocumentClick(event: MouseEvent) {\n const target = event.target as Node;\n if (!this.el.contains(target)) {\n this.isOpen = false;\n }\n }\n\n private filterItems() {\n if (this.searchQuery.length < this.minSearchLength) {\n this.filteredItems = this.items;\n return;\n }\n\n const query = this.searchQuery.toLowerCase();\n this.filteredItems = this.items.filter(item =>\n this.getItemText(item).toLowerCase().includes(query)\n );\n }\n\n private handleInputFocus = () => {\n if (this.disabled || this.readonly) return;\n this.isOpen = true;\n this.highlightedIndex = -1;\n };\n\n private handleInputChange = (event: Event) => {\n const input = event.target as HTMLInputElement;\n this.searchQuery = input.value;\n this.filterItems();\n this.isOpen = true;\n this.highlightedIndex = -1;\n this.xplorSearch.emit(this.searchQuery);\n\n if (!this.multiple && this.searchQuery === '') {\n this.value = null;\n this.xplorChange.emit(null);\n }\n };\n\n private handleInputKeyDown = (event: KeyboardEvent) => {\n if (this.disabled || this.readonly) return;\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n this.isOpen = true;\n this.highlightedIndex = Math.min(this.highlightedIndex + 1, this.filteredItems.length - 1);\n this.scrollToHighlighted();\n break;\n\n case 'ArrowUp':\n event.preventDefault();\n this.highlightedIndex = Math.max(this.highlightedIndex - 1, -1);\n this.scrollToHighlighted();\n break;\n\n case 'Enter':\n event.preventDefault();\n if (this.highlightedIndex >= 0 && this.highlightedIndex < this.filteredItems.length) {\n this.selectItem(this.filteredItems[this.highlightedIndex]);\n }\n break;\n\n case 'Escape':\n event.preventDefault();\n this.isOpen = false;\n this.inputEl?.blur();\n break;\n\n case 'Backspace':\n if (this.multiple && this.searchQuery === '' && this.selectedItems.length > 0) {\n event.preventDefault();\n this.removeItem(this.selectedItems[this.selectedItems.length - 1]);\n }\n break;\n }\n };\n\n private scrollToHighlighted() {\n if (this.dropdownEl && this.highlightedIndex >= 0) {\n const highlightedEl = this.dropdownEl.querySelector(`[data-index=\"${this.highlightedIndex}\"]`) as HTMLElement;\n if (highlightedEl) {\n highlightedEl.scrollIntoView({ block: 'nearest' });\n }\n }\n }\n\n private selectItem(item: AutocompleteItem) {\n if (item.disabled) return;\n\n const itemVal = this.getItemValue(item);\n\n if (this.multiple) {\n if (!this.selectedItems.includes(itemVal)) {\n this.selectedItems = [...this.selectedItems, itemVal];\n this.value = this.selectedItems;\n this.xplorChange.emit(this.value);\n }\n this.searchQuery = '';\n this.filterItems();\n } else {\n this.value = itemVal;\n this.searchQuery = this.getItemText(item);\n this.isOpen = false;\n this.xplorChange.emit(this.value);\n }\n\n this.xplorSelect.emit(item);\n this.inputEl?.focus();\n }\n\n private removeItem(value: any) {\n this.selectedItems = this.selectedItems.filter(v => v !== value);\n this.value = this.selectedItems;\n this.xplorChange.emit(this.value);\n }\n\n private handleClear = () => {\n this.value = this.multiple ? [] : null;\n this.selectedItems = [];\n this.searchQuery = '';\n this.filterItems();\n this.xplorChange.emit(this.value);\n this.xplorClear.emit();\n this.inputEl?.focus();\n };\n\n private getSelectedItemLabel(value: any): string {\n const item = this.items.find(i => this.getItemValue(i) === value);\n return item ? this.getItemText(item) : value;\n }\n\n private findItemByValue(value: any): AutocompleteItem | undefined {\n return this.items.find(i => this.getItemValue(i) === value);\n }\n\n render() {\n const hasValue = this.multiple ? this.selectedItems.length > 0 : this.value !== null && this.searchQuery !== '';\n const listboxId = 'autocomplete-listbox';\n const labelId = 'autocomplete-label';\n const activeDescendantId = this.highlightedIndex >= 0 ? `autocomplete-option-${this.highlightedIndex}` : undefined;\n\n return (\n <Host>\n <div\n class={{\n 'autocomplete': true,\n 'autocomplete--disabled': this.disabled,\n 'autocomplete--readonly': this.readonly,\n 'autocomplete--open': this.isOpen,\n }}\n >\n {this.label && (\n <label class=\"autocomplete__label\" id={labelId}>{this.label}</label>\n )}\n\n <div class=\"autocomplete__input-wrapper\">\n {this.multiple && this.selectedItems.length > 0 && (\n <div class=\"autocomplete__chips\">\n {this.selectedItems.map(value => {\n const item = this.findItemByValue(value);\n const chipLabel = this.getSelectedItemLabel(value);\n return (\n <div class=\"autocomplete__chip\">\n <span class=\"autocomplete__chip-label\">\n {this.renderSelection && item ? this.renderSelection(item) : chipLabel}\n </span>\n <button\n type=\"button\"\n class=\"autocomplete__chip-remove\"\n onClick={() => this.removeItem(value)}\n disabled={this.disabled || this.readonly}\n aria-label={`Remove ${chipLabel}`}\n >\n ×\n </button>\n </div>\n );\n })}\n </div>\n )}\n\n <input\n ref={(el) => (this.inputEl = el)}\n type=\"text\"\n class=\"autocomplete__input\"\n placeholder={this.placeholder}\n value={this.searchQuery}\n onFocus={this.handleInputFocus}\n onInput={this.handleInputChange}\n onKeyDown={this.handleInputKeyDown}\n disabled={this.disabled}\n readonly={this.readonly}\n autocomplete=\"off\"\n role=\"combobox\"\n aria-expanded={this.isOpen ? 'true' : 'false'}\n aria-haspopup=\"listbox\"\n aria-controls={this.isOpen ? listboxId : undefined}\n aria-activedescendant={activeDescendantId}\n aria-labelledby={this.label ? labelId : undefined}\n aria-label={!this.label ? (this.ariaLabel || this.placeholder) : undefined}\n aria-autocomplete=\"list\"\n />\n\n <div class=\"autocomplete__actions\">\n {this.clearable && hasValue && !this.disabled && !this.readonly && (\n <button\n type=\"button\"\n class=\"autocomplete__clear\"\n onClick={this.handleClear}\n aria-label=\"Clear selection\"\n >\n ×\n </button>\n )}\n <span class=\"autocomplete__icon\" aria-hidden=\"true\">▼</span>\n </div>\n </div>\n\n {this.isOpen && this.filteredItems.length > 0 && (\n <div\n class=\"autocomplete__dropdown\"\n ref={(el) => (this.dropdownEl = el)}\n style={{ maxWidth: this.menuMaxWidth }}\n role=\"listbox\"\n id={listboxId}\n aria-label={this.label || this.ariaLabel || 'Suggestions'}\n >\n {this.filteredItems.map((item, index) => {\n const itemVal = this.getItemValue(item);\n const isSelected = this.multiple\n ? this.selectedItems.includes(itemVal)\n : this.value === itemVal;\n return (\n <div\n key={itemVal}\n id={`autocomplete-option-${index}`}\n data-index={index}\n role=\"option\"\n aria-selected={isSelected ? 'true' : 'false'}\n aria-disabled={item.disabled ? 'true' : undefined}\n class={{\n 'autocomplete__item': true,\n 'autocomplete__item--highlighted': index === this.highlightedIndex,\n 'autocomplete__item--selected': isSelected,\n 'autocomplete__item--disabled': item.disabled,\n }}\n onClick={() => this.selectItem(item)}\n >\n {this.renderItem ? this.renderItem(item) : this.getItemText(item)}\n </div>\n );\n })}\n </div>\n )}\n\n {this.isOpen && this.filteredItems.length === 0 && (\n <div class=\"autocomplete__dropdown\" style={{ maxWidth: this.menuMaxWidth }} role=\"listbox\" id={listboxId}>\n <div class=\"autocomplete__no-results\" role=\"option\" aria-disabled=\"true\">No results found</div>\n </div>\n )}\n </div>\n </Host>\n );\n }\n}\n",":host {\n display: block;\n}\n","import { Component, Host, h, Prop } from '@stencil/core';\n\n@Component({\n tag: 'xplor-avatar',\n styleUrl: 'xplor-avatar.scss',\n shadow: true,\n})\nexport class XplorAvatar {\n /** Background color when there is no image src */\n @Prop() color?: 'green' | 'yellow' | 'pink' | 'primary' | 'secondary';\n // eslint-disable-next-line @stencil/required-jsdoc\n @Prop() disabled?: boolean = false;\n /** The URL if the avatar should be hyperlinked */\n @Prop() href?: string;\n /** Alt text for the image if there is an image src */\n @Prop() name?: string;\n /** Size of the avatar */\n @Prop() size?: 'md' | 'sm';\n /** The image URL */\n @Prop() src?: string;\n /** Color styles for the dot indicator to indicate varied states */\n @Prop() status?: 'active' | 'warning' | 'inactive';\n /**\n * Where to open the URL chosen for the `href` prop:\n * `_self` (default), `_blank`, `_parent`, or `_top`\n */\n @Prop() target?: string;\n\n render() {\n let className = 'xpl-avatar';\n if (this.size) className += ` xpl-avatar--${this.size}`;\n if (this.color) className += ` xpl-avatar--${this.color}`;\n\n const inner = (\n <div>\n {this.src ? (\n <img alt={this.name} src={this.src} />\n ) : (\n <div class=\"xpl-avatar__placeholder\">\n <slot></slot>\n </div>\n )}\n {this.status && <div class={`xpl-avatar__dot--${this.status}`} aria-label={`Status: ${this.status}`} role=\"img\"></div>}\n </div>\n );\n\n return (\n <Host>\n {this.href && !this.disabled ? (\n <a href={this.href} class={className} target={this.target}>\n {inner}\n </a>\n ) : this.href && this.disabled ? (\n <div class={className + ' xpl-avatar--disabled'}>{inner}</div>\n ) : (\n <div class={className}>{inner}</div>\n )}\n </Host>\n );\n }\n}\n",":host {\n display: inline-block;\n}\n\n.avatar-and-name {\n display: inline-flex;\n align-items: center;\n gap: 0.75rem;\n}\n\n.avatar-and-name__text {\n font-size: 0.875rem;\n font-weight: 500;\n color: #212121;\n line-height: 1.5;\n}","import { Component, Host, h, Prop } from '@stencil/core';\n\n@Component({\n tag: 'xplor-avatar-and-name',\n styleUrl: 'xplor-avatar-and-name.scss',\n scoped: true,\n})\nexport class XplorAvatarAndName {\n @Prop() name: string;\n @Prop() src: string;\n @Prop() size: 'sm' | 'md' = 'md';\n @Prop() color?: 'green' | 'yellow' | 'pink' | 'primary' | 'secondary';\n @Prop() status?: 'active' | 'warning' | 'inactive';\n\n render() {\n return (\n <Host>\n <div class=\"avatar-and-name\">\n <xplor-avatar\n name={this.name}\n src={this.src}\n size={this.size}\n color={this.color}\n status={this.status}\n >\n {!this.src && this.name && this.name.charAt(0).toUpperCase()}\n </xplor-avatar>\n <span class=\"avatar-and-name__text\">\n <slot>{this.name}</slot>\n </span>\n </div>\n </Host>\n );\n }\n}\n","@use '../../styles/colours.scss' as colours;\n@use '../../styles/spacing.scss' as spacing;\n@use '../../styles/mixins.scss' as mixins;\n\n:host {\n display: inline-block;\n}\n\n.xplor-badge {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-weight: 400;\n font-size: 0.875rem;\n line-height: 1.25rem;\n padding: 4px 12px;\n border-radius: 16px;\n background-color: var(--xplor-badge-bg, colours.$primary-50);\n color: var(--xplor-badge-color, colours.$primary);\n transition: all 0.2s ease;\n white-space: nowrap;\n max-width: 100%;\n overflow: hidden;\n text-overflow: ellipsis;\n\n // Size variants\n &--small {\n font-size: 0.75rem;\n padding: 2px 8px;\n border-radius: 12px;\n }\n\n &--medium {\n font-size: 0.875rem;\n padding: 4px 12px;\n border-radius: 16px;\n }\n\n &--large {\n font-size: 1rem;\n padding: 6px 16px;\n border-radius: 20px;\n }\n\n // Style variants\n &--flat {\n border: none;\n }\n\n &--outlined {\n background-color: transparent;\n border: 1px solid var(--xplor-badge-bg, colours.$primary);\n color: var(--xplor-badge-bg, colours.$primary);\n }\n\n &--tonal {\n background-color: var(--xplor-badge-bg, colours.$primary-50);\n color: var(--xplor-badge-color, colours.$primary);\n }\n\n // Datatable variant (slightly larger padding)\n &--datatable {\n padding: 8px 12px;\n border-radius: 14px;\n }\n}\n","import { Component, Host, h, Prop } from '@stencil/core';\n\n@Component({\n tag: 'xplor-badge',\n styleUrl: 'xplor-badge.scss',\n scoped: true,\n})\nexport class XplorBadge {\n /**\n * Background color (can be CSS color or theme color name)\n */\n @Prop() backgroundColor: string = '#e3f2fd';\n\n /**\n * Text color - 'auto' will calculate contrasting color\n */\n @Prop() color: string = 'auto';\n\n /**\n * Luminance threshold for auto contrast calculation (0-255)\n */\n @Prop() threshold: number = 130;\n\n /**\n * Visual variant\n */\n @Prop() variant: 'flat' | 'outlined' | 'tonal' = 'flat';\n\n /**\n * Size variant\n */\n @Prop() size: 'small' | 'medium' | 'large' = 'medium';\n\n /**\n * Whether to use datatable styling (slightly larger padding)\n */\n @Prop() datatable: boolean = false;\n\n /**\n * Optional text content (can also use slot)\n */\n @Prop() text: string = '';\n\n /**\n * Calculates relative luminance of a color\n * Based on WCAG 2.0 formula\n */\n private calculateLuminance(r: number, g: number, b: number): number {\n const [rs, gs, bs] = [r, g, b].map(c => {\n c = c / 255;\n return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);\n });\n return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;\n }\n\n /**\n * Parses hex/rgb/rgba color to RGB values\n */\n private parseColor(color: string): { r: number; g: number; b: number } | null {\n // Handle hex colors\n if (color.startsWith('#')) {\n const hex = color.replace('#', '');\n if (hex.length === 3) {\n const r = parseInt(hex[0] + hex[0], 16);\n const g = parseInt(hex[1] + hex[1], 16);\n const b = parseInt(hex[2] + hex[2], 16);\n return { r, g, b };\n } else if (hex.length === 6) {\n const r = parseInt(hex.substring(0, 2), 16);\n const g = parseInt(hex.substring(2, 4), 16);\n const b = parseInt(hex.substring(4, 6), 16);\n return { r, g, b };\n }\n }\n\n // Handle rgb/rgba\n const rgbMatch = color.match(/rgba?\\((\\d+),\\s*(\\d+),\\s*(\\d+)/);\n if (rgbMatch) {\n return {\n r: parseInt(rgbMatch[1]),\n g: parseInt(rgbMatch[2]),\n b: parseInt(rgbMatch[3]),\n };\n }\n\n return null;\n }\n\n /**\n * Calculates contrasting color (black or white) based on background\n */\n private calculateContrastingColor(bgColor: string): string {\n const rgb = this.parseColor(bgColor);\n if (!rgb) return '#000000';\n\n const luminance = this.calculateLuminance(rgb.r, rgb.g, rgb.b);\n // Using threshold to determine light vs dark background\n return luminance > 0.5 ? '#000000' : '#ffffff';\n }\n\n /**\n * Gets the computed CSS variables for the badge\n */\n private get cssVars(): { [key: string]: string } {\n const vars: { [key: string]: string } = {};\n\n // Set background color\n vars['--xplor-badge-bg'] = this.backgroundColor;\n\n // Set text color (auto-calculate if needed)\n if (this.color === 'auto') {\n vars['--xplor-badge-color'] = this.calculateContrastingColor(this.backgroundColor);\n } else {\n vars['--xplor-badge-color'] = this.color;\n }\n\n return vars;\n }\n\n /**\n * Gets the computed CSS classes\n */\n private get computedClasses(): { [key: string]: boolean } {\n return {\n 'xplor-badge': true,\n [`xplor-badge--${this.variant}`]: true,\n [`xplor-badge--${this.size}`]: true,\n 'xplor-badge--datatable': this.datatable,\n };\n }\n\n render() {\n return (\n <Host>\n <span class={this.computedClasses} style={this.cssVars}>\n <slot>{this.text}</slot>\n </span>\n </Host>\n );\n }\n}\n",":host {\n display: inline-block;\n}\n\n.xplor-badge-active {\n background-color: #E6F7F7;\n color: #00605C;\n font-weight: 400;\n padding: 4px 12px;\n border-radius: 16px;\n display: inline-block;\n}\n","import { Component, Host, h } from '@stencil/core';\n\n@Component({\n tag: 'xplor-badge-active',\n styleUrl: 'xplor-badge-active.scss',\n scoped: true,\n})\nexport class XplorBadgeActive {\n render() {\n return (\n <Host>\n <span class=\"xplor-badge-active\">\n Active\n </span>\n </Host>\n );\n }\n}\n",":host {\n display: inline-block;\n}\n\n.xplor-badge-archived {\n background-color: #E8E0F0;\n color: #60479A;\n font-weight: 400;\n padding: 4px 12px;\n border-radius: 16px;\n display: inline-block;\n}\n","import { Component, Host, h } from '@stencil/core';\n\n@Component({\n tag: 'xplor-badge-archived',\n styleUrl: 'xplor-badge-archived.scss',\n scoped: true,\n})\nexport class XplorBadgeArchived {\n render() {\n return (\n <Host>\n <span class=\"xplor-badge-archived\">\n Archived\n </span>\n </Host>\n );\n }\n}\n",":host {\n display: inline-block;\n}\n\n.xplor-badge-deleted {\n background-color: #FFF3E6;\n color: #B35A00;\n font-weight: 400;\n padding: 4px 12px;\n border-radius: 16px;\n display: inline-block;\n}\n","import { Component, Host, h } from '@stencil/core';\n\n@Component({\n tag: 'xplor-badge-deleted',\n styleUrl: 'xplor-badge-deleted.scss',\n scoped: true,\n})\nexport class XplorBadgeDeleted {\n render() {\n return (\n <Host>\n <span class=\"xplor-badge-deleted\">\n Deleted\n </span>\n </Host>\n );\n }\n}\n",":host {\n display: inline-block;\n}\n\n.xplor-badge-expired {\n background-color: #FEE;\n color: #C62828;\n font-weight: 400;\n padding: 4px 12px;\n border-radius: 16px;\n display: inline-block;\n}\n","import { Component, Host, h } from '@stencil/core';\n\n@Component({\n tag: 'xplor-badge-expired',\n styleUrl: 'xplor-badge-expired.scss',\n scoped: true,\n})\nexport class XplorBadgeExpired {\n render() {\n return (\n <Host>\n <span class=\"xplor-badge-expired\">\n Expired\n </span>\n </Host>\n );\n }\n}\n",":host {\n display: inline-block;\n}\n\n.xplor-badge-inactive {\n background-color: #FAFAFA;\n color: #424242;\n font-weight: 400;\n padding: 4px 12px;\n border-radius: 16px;\n display: inline-block;\n}\n","import { Component, Host, h } from '@stencil/core';\n\n@Component({\n tag: 'xplor-badge-inactive',\n styleUrl: 'xplor-badge-inactive.scss',\n scoped: true,\n})\nexport class XplorBadgeInactive {\n render() {\n return (\n <Host>\n <span class=\"xplor-badge-inactive\">\n Inactive\n </span>\n </Host>\n );\n }\n}\n",":host {\n display: inline-block;\n}\n\n.xplor-badge-recalled {\n background-color: #FFF9E6;\n color: #F9A825;\n font-weight: 400;\n padding: 4px 12px;\n border-radius: 16px;\n display: inline-block;\n}\n","import { Component, Host, h } from '@stencil/core';\n\n@Component({\n tag: 'xplor-badge-recalled',\n styleUrl: 'xplor-badge-recalled.scss',\n scoped: true,\n})\nexport class XplorBadgeRecalled {\n render() {\n return (\n <Host>\n <span class=\"xplor-badge-recalled\">\n Recalled\n </span>\n </Host>\n );\n }\n}\n",":host {\n display: inline-block;\n}\n\n.xplor-badge-session-booking {\n border-radius: 0.25rem;\n color: #000;\n width: 200px;\n display: inline-flex;\n justify-content: center;\n align-items: center;\n padding: 4px 12px;\n\n &--default {\n background-color: #fef2e0;\n border: solid 2px #f69202;\n }\n\n &--absent {\n background-color: #f0f0f0;\n border: solid 2px #7b7b7b;\n }\n\n &--attend {\n background-color: #dff6f6;\n border: solid 2px #00b2a8;\n }\n\n &--holiday {\n background-color: #f0f0f0;\n border: solid 2px #7b7b7b;\n }\n\n &--waived {\n opacity: 0.5;\n }\n}\n","import { Component, Host, h, Prop } from '@stencil/core';\n\nexport interface Booking {\n type: 'absence' | 'attendance' | 'holiday' | string;\n [key: string]: any;\n}\n\nexport interface BookingItem {\n ccs_gap_fee_is_waived?: boolean;\n [key: string]: any;\n}\n\n@Component({\n tag: 'xplor-badge-session-booking',\n styleUrl: 'xplor-badge-session-booking.scss',\n scoped: true,\n})\nexport class XplorBadgeSessionBooking {\n /**\n * Booking object\n */\n @Prop() booking!: Booking;\n\n /**\n * Item object\n */\n @Prop() item!: BookingItem;\n\n private getBookingTypeClass(): string {\n const classes = ['xplor-badge-session-booking'];\n\n switch (this.booking?.type) {\n case 'absence':\n classes.push('xplor-badge-session-booking--absent');\n break;\n case 'attendance':\n classes.push('xplor-badge-session-booking--attend');\n break;\n case 'holiday':\n classes.push('xplor-badge-session-booking--holiday');\n break;\n default:\n classes.push('xplor-badge-session-booking--default');\n break;\n }\n\n if (this.item?.ccs_gap_fee_is_waived) {\n classes.push('xplor-badge-session-booking--waived');\n }\n\n return classes.join(' ');\n }\n\n render() {\n return (\n <Host>\n <span class={this.getBookingTypeClass()}>\n <slot />\n </span>\n </Host>\n );\n }\n}\n",":host {\n display: inline-block;\n}\n\n.xplor-badge-upcoming {\n background-color: #E3F2FD;\n color: #1976D2;\n font-weight: 400;\n padding: 4px 12px;\n border-radius: 16px;\n display: inline-block;\n}\n","import { Component, Host, h } from '@stencil/core';\n\n@Component({\n tag: 'xplor-badge-upcoming',\n styleUrl: 'xplor-badge-upcoming.scss',\n scoped: true,\n})\nexport class XplorBadgeUpcoming {\n render() {\n return (\n <Host>\n <span class=\"xplor-badge-upcoming\">\n Upcoming\n </span>\n </Host>\n );\n }\n}\n",":host {\n display: inline-block;\n}\n\n.xplor-badge-waitlist {\n background-color: #FFF3E6;\n color: #B35A00;\n font-weight: 400;\n padding: 4px 12px;\n border-radius: 16px;\n display: inline-block;\n}\n","import { Component, Host, h } from '@stencil/core';\n\n@Component({\n tag: 'xplor-badge-waitlist',\n styleUrl: 'xplor-badge-waitlist.scss',\n scoped: true,\n})\nexport class XplorBadgeWaitlist {\n render() {\n return (\n <Host>\n <span class=\"xplor-badge-waitlist\">\n Waitlist\n </span>\n </Host>\n );\n }\n}\n",":host {\n display: inline-block;\n}\n\n.xplor-btn-back {\n display: inline-flex;\n align-items: center;\n gap: var(--gap, 0.625rem);\n min-width: var(--min-width, 6.375rem);\n min-height: var(--min-height, 3rem);\n padding-left: 0;\n padding-right: 1rem;\n border: none;\n background: transparent;\n color: inherit;\n cursor: pointer;\n font-size: inherit;\n font-family: inherit;\n transition: opacity 0.2s ease;\n\n &__icon {\n font-size: 1.5rem;\n line-height: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n &__text {\n line-height: 1;\n }\n\n &:hover:not(.xplor-btn-back--disabled) {\n opacity: 0.8;\n }\n\n &--disabled {\n opacity: 0.38;\n cursor: not-allowed;\n pointer-events: none;\n }\n}\n","import { Component, Host, h, Prop, Event, EventEmitter } from '@stencil/core';\n\n@Component({\n tag: 'xplor-btn-back',\n styleUrl: 'xplor-btn-back.scss',\n scoped: true,\n})\nexport class XplorBtnBack {\n /**\n * Button color\n */\n @Prop() color: string = 'secondary';\n\n /**\n * Minimum width\n */\n @Prop() minWidth: string = '6.375rem';\n\n /**\n * Minimum height\n */\n @Prop() minHeight: string = '3rem';\n\n /**\n * Gap between icon and text\n */\n @Prop() gap: string = '0.625rem';\n\n /**\n * Whether the button is disabled\n */\n @Prop() disabled: boolean = false;\n\n /**\n * Click event\n */\n @Event() xplorClick: EventEmitter<MouseEvent>;\n\n private handleClick = (event: MouseEvent) => {\n if (!this.disabled) {\n this.xplorClick.emit(event);\n }\n };\n\n render() {\n const buttonClasses = {\n 'xplor-btn-back': true,\n 'xplor-btn-back--disabled': this.disabled,\n };\n\n const buttonStyles = {\n '--min-width': this.minWidth,\n '--min-height': this.minHeight,\n '--gap': this.gap,\n };\n\n return (\n <Host>\n <button\n class={buttonClasses}\n style={buttonStyles}\n disabled={this.disabled}\n onClick={this.handleClick}\n >\n <span class=\"xplor-btn-back__icon\">‹</span>\n <span class=\"xplor-btn-back__text\">\n <slot>Back</slot>\n </span>\n </button>\n </Host>\n );\n }\n}\n",":host {\n display: inline-block;\n}\n\n.xplor-btn-back-to-parent {\n position: absolute;\n right: 1rem;\n top: 1rem;\n font-size: 1rem;\n z-index: 1;\n padding: 0;\n width: var(--btn-size, 2.25rem);\n height: var(--btn-size, 2.25rem);\n border: none;\n border-radius: 4px;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n background-color: white;\n color: #008480;\n transition: background-color 0.2s ease;\n\n &__icon {\n font-size: 1rem;\n line-height: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n &:hover {\n background-color: #E6F7F7;\n }\n\n &--inline {\n position: relative;\n top: 0;\n right: 0;\n }\n}\n","import { Component, Host, h, Prop, Event, EventEmitter } from '@stencil/core';\n\n@Component({\n tag: 'xplor-btn-back-to-parent',\n styleUrl: 'xplor-btn-back-to-parent.scss',\n scoped: true,\n})\nexport class XplorBtnBackToParent {\n /**\n * Button size\n */\n @Prop() size: string = '2.25rem';\n\n /**\n * Whether to use inline (relative) positioning instead of absolute\n */\n @Prop() inline: boolean = false;\n\n /**\n * Background color\n */\n @Prop() bgColor: string = 'white';\n\n /**\n * Text/icon color\n */\n @Prop() color: string = 'secondary';\n\n /**\n * Visual variant\n */\n @Prop() variant: 'text' | 'outlined' | 'elevated' | 'tonal' = 'tonal';\n\n /**\n * Accessible label for the button\n */\n @Prop() ariaLabel: string = 'Back to parent';\n\n /**\n * Back event (emitted on click)\n */\n @Event() back: EventEmitter<void>;\n\n private handleClick = () => {\n this.back.emit();\n };\n\n render() {\n const buttonClasses = {\n 'xplor-btn-back-to-parent': true,\n 'xplor-btn-back-to-parent--inline': this.inline,\n };\n\n const buttonStyles = {\n '--btn-size': this.size,\n };\n\n return (\n <Host>\n <button\n class={buttonClasses}\n style={buttonStyles}\n onClick={this.handleClick}\n aria-label={this.ariaLabel}\n >\n <span class=\"xplor-btn-back-to-parent__icon\">✕</span>\n </button>\n </Host>\n );\n }\n}\n",":host {\n display: inline-block;\n}\n\n.xplor-btn-icon {\n min-width: 0;\n min-height: 0;\n width: var(--btn-size, 32px);\n height: var(--btn-size, 32px);\n padding: 0;\n border: none;\n border-radius: 50%;\n cursor: pointer;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s ease;\n position: relative;\n\n &__content {\n font-size: var(--icon-size, 18px);\n line-height: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n // Elevated variant (default)\n &--elevated {\n box-shadow: 0px 3px 1px -2px rgba(0, 0, 0, 0.2),\n 0px 2px 2px 0px rgba(0, 0, 0, 0.14),\n 0px 1px 5px 0px rgba(0, 0, 0, 0.12);\n }\n\n // Text variant\n &--text {\n box-shadow: none;\n }\n\n // Outlined variant\n &--outlined {\n border: 1px solid currentColor;\n box-shadow: none;\n }\n\n // Tonal variant\n &--tonal {\n box-shadow: none;\n }\n\n // Color variants\n &--primary {\n &.xplor-btn-icon--elevated,\n &.xplor-btn-icon--text {\n background-color: #EC7702;\n color: white;\n }\n\n &.xplor-btn-icon--outlined {\n background-color: transparent;\n color: #EC7702;\n border-color: #EC7702;\n }\n\n &.xplor-btn-icon--tonal {\n background-color: #FFF3E6;\n color: #EC7702;\n }\n\n &:hover:not(.xplor-btn-icon--disabled) {\n &.xplor-btn-icon--elevated,\n &.xplor-btn-icon--text {\n background-color: #D66A02;\n }\n\n &.xplor-btn-icon--tonal {\n background-color: #FFE7CC;\n }\n }\n }\n\n &--secondary {\n &.xplor-btn-icon--elevated,\n &.xplor-btn-icon--text {\n background-color: #008480;\n color: white;\n }\n\n &.xplor-btn-icon--outlined {\n background-color: transparent;\n color: #008480;\n border-color: #008480;\n }\n\n &.xplor-btn-icon--tonal {\n background-color: #E6F7F7;\n color: #008480;\n }\n\n &:hover:not(.xplor-btn-icon--disabled) {\n &.xplor-btn-icon--elevated,\n &.xplor-btn-icon--text {\n background-color: #006D6A;\n }\n\n &.xplor-btn-icon--tonal {\n background-color: #008480;\n color: white;\n }\n }\n }\n\n &--success {\n &.xplor-btn-icon--elevated,\n &.xplor-btn-icon--text {\n background-color: #489951;\n color: white;\n }\n\n &.xplor-btn-icon--outlined {\n background-color: transparent;\n color: #489951;\n border-color: #489951;\n }\n\n &.xplor-btn-icon--tonal {\n background-color: #E8F5E9;\n color: #489951;\n }\n\n &:hover:not(.xplor-btn-icon--disabled) {\n &.xplor-btn-icon--elevated,\n &.xplor-btn-icon--text {\n background-color: #3D8044;\n }\n\n &.xplor-btn-icon--tonal {\n background-color: #D0EBD2;\n }\n }\n }\n\n &--disabled {\n opacity: 0.38;\n cursor: not-allowed;\n pointer-events: none;\n }\n}\n","import { Component, Host, h, Prop, Event, EventEmitter } from '@stencil/core';\n\n@Component({\n tag: 'xplor-btn-icon',\n styleUrl: 'xplor-btn-icon.scss',\n scoped: true,\n})\nexport class XplorBtnIcon {\n /**\n * Button color variant\n */\n @Prop() color: 'primary' | 'secondary' | 'success' | string = 'secondary';\n\n /**\n * Button size (can be pixel value like '32' or '48')\n */\n @Prop() size: string | number = '32';\n\n /**\n * Icon size\n */\n @Prop() iconSize: string | number = '18';\n\n /**\n * Visual variant\n */\n @Prop() variant: 'text' | 'outlined' | 'elevated' | 'tonal' = 'elevated';\n\n /**\n * Whether the button is disabled\n */\n @Prop() disabled: boolean = false;\n\n /**\n * Accessible label for the icon button (required for screen readers)\n */\n @Prop() ariaLabel: string;\n\n /**\n * Click event\n */\n @Event() xplorClick: EventEmitter<MouseEvent>;\n\n private handleClick = (event: MouseEvent) => {\n if (!this.disabled) {\n this.xplorClick.emit(event);\n }\n };\n\n render() {\n const buttonClasses = {\n 'xplor-btn-icon': true,\n [`xplor-btn-icon--${this.color}`]: true,\n [`xplor-btn-icon--${this.variant}`]: true,\n 'xplor-btn-icon--disabled': this.disabled,\n };\n\n const buttonStyles = {\n '--btn-size': typeof this.size === 'number' ? `${this.size}px` : this.size,\n '--icon-size': typeof this.iconSize === 'number' ? `${this.iconSize}px` : this.iconSize,\n };\n\n return (\n <Host>\n <button\n class={buttonClasses}\n style={buttonStyles}\n disabled={this.disabled}\n onClick={this.handleClick}\n aria-label={this.ariaLabel}\n >\n <span class=\"xplor-btn-icon__content\">\n <slot />\n </span>\n </button>\n </Host>\n );\n }\n}\n",":host {\n display: inline-block;\n position: relative;\n}\n\n.xplor-btn-menu {\n position: relative;\n display: inline-block;\n\n &__button {\n display: inline-flex;\n align-items: center;\n gap: 0.625rem;\n padding: 0.5rem 1rem;\n border: 1px solid #008480;\n border-radius: 4px;\n background-color: transparent;\n color: #008480;\n cursor: pointer;\n font-size: inherit;\n font-family: inherit;\n transition: background-color 0.2s ease;\n\n &:hover {\n background-color: rgba(0, 132, 128, 0.04);\n }\n }\n\n &__icon {\n font-size: 0.75rem;\n line-height: 1;\n }\n\n &__list {\n position: absolute;\n top: calc(100% + 0.25rem);\n left: 0;\n min-width: 200px;\n background: white;\n border-radius: 4px;\n box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.2),\n 0px 8px 10px 1px rgba(0, 0, 0, 0.14),\n 0px 3px 14px 2px rgba(0, 0, 0, 0.12);\n z-index: 1000;\n overflow: hidden;\n }\n\n &__item {\n padding: 0.75rem 1rem;\n border-bottom: 1px solid #e0e0e0;\n text-align: center;\n cursor: pointer;\n transition: background-color 0.2s ease;\n\n &:hover:not(&--disabled) {\n background-color: #f5f5f5;\n }\n\n &:last-child {\n border-bottom: none;\n }\n\n &--disabled {\n opacity: 0.38;\n cursor: not-allowed;\n pointer-events: none;\n }\n }\n}\n","import { Component, Host, h, Prop, State, Event, EventEmitter, Element, Listen } from '@stencil/core';\n\nexport interface MenuOption {\n key?: string;\n label: string;\n [key: string]: any;\n}\n\n@Component({\n tag: 'xplor-btn-menu',\n styleUrl: 'xplor-btn-menu.scss',\n scoped: true,\n})\nexport class XplorBtnMenu {\n @Element() el: HTMLElement;\n\n /**\n * Accessible label for the menu trigger button when no visible label is provided\n */\n @Prop() ariaLabel: string;\n\n /**\n * Button label\n */\n @Prop() label: string = '';\n\n /**\n * Menu options\n */\n @Prop() options: MenuOption[] = [];\n\n /**\n * Hidden option keys\n */\n @Prop() hiddenKeys: string[] = [];\n\n /**\n * Disabled option keys\n */\n @Prop() disabledKeys: string[] = [];\n\n /**\n * Button color\n */\n @Prop() color: string = 'secondary';\n\n /**\n * Button density (compact, default, comfortable)\n */\n @Prop() density: string = 'default';\n\n /**\n * Whether the menu is open\n */\n @State() show: boolean = false;\n\n /**\n * Index of the currently focused menu item for keyboard navigation\n */\n @State() focusedIndex: number = -1;\n\n /**\n * Click event - emits the clicked option\n */\n @Event() xplorClick: EventEmitter<MenuOption>;\n\n private menuRef: HTMLDivElement;\n private triggerBtnRef: HTMLButtonElement;\n\n componentDidLoad() {\n document.addEventListener('click', this.handleOutsideClick);\n }\n\n disconnectedCallback() {\n document.removeEventListener('click', this.handleOutsideClick);\n }\n\n private handleOutsideClick = (event: MouseEvent) => {\n if (this.menuRef && !this.menuRef.contains(event.target as Node)) {\n this.show = false;\n }\n };\n\n private toggleMenu = () => {\n this.show = !this.show;\n if (!this.show) {\n this.focusedIndex = -1;\n }\n };\n\n private handleClickOption = (option: MenuOption) => {\n this.xplorClick.emit(option);\n this.show = false;\n this.focusedIndex = -1;\n this.triggerBtnRef?.focus();\n };\n\n /**\n * Returns the list of visible (non-hidden) options for keyboard navigation\n */\n private getVisibleOptions(): { option: MenuOption; key: string }[] {\n return this.options\n .map((option, index) => ({ option, key: option.key || String(index) }))\n .filter(({ key }) => !this.isHidden(key));\n }\n\n /**\n * Focuses the menu item at the given index in the visible options list\n */\n private focusMenuItem(index: number) {\n if (this.menuRef) {\n const items = this.menuRef.querySelectorAll('[role=\"menuitem\"]');\n if (items[index]) {\n (items[index] as HTMLElement).focus();\n }\n }\n }\n\n @Listen('keydown')\n handleKeyDown(event: KeyboardEvent) {\n if (!this.show && (event.key === 'ArrowDown' || event.key === 'Enter' || event.key === ' ')) {\n const target = event.target as HTMLElement;\n if (target === this.triggerBtnRef || this.el.querySelector('[slot=\"activator\"]')?.contains(target)) {\n if (event.key === 'ArrowDown') {\n event.preventDefault();\n this.show = true;\n this.focusedIndex = 0;\n requestAnimationFrame(() => this.focusMenuItem(0));\n }\n }\n return;\n }\n\n if (!this.show) return;\n\n const visibleOptions = this.getVisibleOptions();\n const totalVisible = visibleOptions.length;\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n this.focusedIndex = this.focusedIndex < totalVisible - 1 ? this.focusedIndex + 1 : 0;\n this.focusMenuItem(this.focusedIndex);\n break;\n\n case 'ArrowUp':\n event.preventDefault();\n this.focusedIndex = this.focusedIndex > 0 ? this.focusedIndex - 1 : totalVisible - 1;\n this.focusMenuItem(this.focusedIndex);\n break;\n\n case 'Escape':\n event.preventDefault();\n this.show = false;\n this.focusedIndex = -1;\n this.triggerBtnRef?.focus();\n break;\n\n case 'Enter':\n case ' ':\n event.preventDefault();\n if (this.focusedIndex >= 0 && this.focusedIndex < totalVisible) {\n const { option, key } = visibleOptions[this.focusedIndex];\n if (!this.isDisabled(key)) {\n this.handleClickOption(option);\n }\n }\n break;\n\n case 'Home':\n event.preventDefault();\n this.focusedIndex = 0;\n this.focusMenuItem(this.focusedIndex);\n break;\n\n case 'End':\n event.preventDefault();\n this.focusedIndex = totalVisible - 1;\n this.focusMenuItem(this.focusedIndex);\n break;\n\n case 'Tab':\n this.show = false;\n this.focusedIndex = -1;\n break;\n }\n }\n\n private isHidden = (key: string | null): boolean => {\n return key !== null && this.hiddenKeys.includes(key);\n };\n\n private isDisabled = (key: string | null): boolean => {\n return key !== null && this.disabledKeys.includes(key);\n };\n\n render() {\n const menuId = 'xplor-btn-menu-list';\n let visibleIndex = 0;\n\n return (\n <Host>\n <div class=\"xplor-btn-menu\" ref={(el) => (this.menuRef = el)}>\n <slot name=\"activator\">\n <button\n ref={(el) => (this.triggerBtnRef = el)}\n class=\"xplor-btn-menu__button\"\n onClick={this.toggleMenu}\n aria-haspopup=\"menu\"\n aria-expanded={this.show ? 'true' : 'false'}\n aria-controls={this.show ? menuId : undefined}\n aria-label={this.ariaLabel || this.label || 'Menu'}\n >\n <span>{this.label}</span>\n <span class=\"xplor-btn-menu__icon\" aria-hidden=\"true\">▼</span>\n </button>\n </slot>\n\n {this.show && (\n <div class=\"xplor-btn-menu__list\" role=\"menu\" id={menuId} aria-label={this.ariaLabel || this.label || 'Menu'}>\n {this.options.map((option, index) => {\n const key = option.key || String(index);\n if (this.isHidden(key)) {\n return null;\n }\n\n const disabled = this.isDisabled(key);\n const currentVisibleIndex = visibleIndex++;\n\n return (\n <div\n key={key}\n role=\"menuitem\"\n tabindex={currentVisibleIndex === this.focusedIndex ? 0 : -1}\n aria-disabled={disabled ? 'true' : undefined}\n class={{\n 'xplor-btn-menu__item': true,\n 'xplor-btn-menu__item--disabled': disabled,\n }}\n onClick={() => !disabled && this.handleClickOption(option)}\n >\n <slot name={key}>{option.label || ''}</slot>\n </div>\n );\n })}\n </div>\n )}\n </div>\n </Host>\n );\n }\n}\n",":host {\n display: inline-block;\n}\n\n.xplor-btn-toggle {\n border: 1px solid #E0E0E0;\n border-radius: 1rem;\n min-width: 4rem;\n padding: 0.5rem 1rem;\n background-color: white;\n color: #757575;\n cursor: pointer;\n font-size: inherit;\n font-family: inherit;\n transition: all 0.2s ease;\n margin-right: 0.5rem;\n\n &:first-of-type {\n margin-left: 0;\n }\n\n &--active {\n background-color: #E6F7F7;\n color: #008480;\n border-color: #008480;\n }\n\n &--disabled {\n background-color: #FAFAFA;\n color: rgba(0, 0, 0, 0.38);\n border-color: rgba(0, 0, 0, 0.12);\n cursor: not-allowed;\n pointer-events: none;\n\n &.xplor-btn-toggle--active {\n background-color: rgba(0, 0, 0, 0.05);\n }\n }\n\n &--inactive-outlined {\n border-color: #757575;\n }\n\n &:hover:not(.xplor-btn-toggle--disabled) {\n background-color: #F5F5F5;\n\n &.xplor-btn-toggle--active {\n background-color: #D0EBD2;\n }\n }\n}\n","import { Component, Host, h, Prop, Event, EventEmitter } from '@stencil/core';\n\n@Component({\n tag: 'xplor-btn-toggle',\n styleUrl: 'xplor-btn-toggle.scss',\n scoped: true,\n})\nexport class XplorBtnToggle {\n /**\n * Whether the button is active/selected\n */\n @Prop({ mutable: true }) active: boolean = false;\n\n /**\n * Button color when active\n */\n @Prop() color: string = 'secondary';\n\n /**\n * Whether the button is disabled\n */\n @Prop() disabled: boolean = false;\n\n /**\n * Whether to show outline when inactive\n */\n @Prop() inactiveOutlined: boolean = false;\n\n /**\n * Toggle event\n */\n @Event() xplorToggle: EventEmitter<boolean>;\n\n private handleClick = () => {\n if (!this.disabled) {\n this.active = !this.active;\n this.xplorToggle.emit(this.active);\n }\n };\n\n render() {\n const buttonClasses = {\n 'xplor-btn-toggle': true,\n 'xplor-btn-toggle--active': this.active,\n 'xplor-btn-toggle--disabled': this.disabled,\n 'xplor-btn-toggle--inactive-outlined': this.inactiveOutlined && !this.active,\n };\n\n return (\n <Host>\n <button\n class={buttonClasses}\n disabled={this.disabled}\n onClick={this.handleClick}\n aria-pressed={this.active ? 'true' : 'false'}\n >\n <slot />\n </button>\n </Host>\n );\n }\n}\n",":host {\n display: inline-block;\n}\n\n.xplor-btn-toggle-group {\n display: inline-flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n height: auto;\n}\n","import { Component, Host, h, Prop } from '@stencil/core';\n\n@Component({\n tag: 'xplor-btn-toggle-group',\n styleUrl: 'xplor-btn-toggle-group.scss',\n scoped: true,\n})\nexport class XplorBtnToggleGroup {\n /**\n * Whether multiple buttons can be active at once\n */\n @Prop() multiple: boolean = false;\n\n /**\n * Density variant\n */\n @Prop() density: 'compact' | 'default' | 'comfortable' = 'default';\n\n render() {\n return (\n <Host>\n <div class=\"xplor-btn-toggle-group\" role=\"group\">\n <slot />\n </div>\n </Host>\n );\n }\n}\n",":host {\n display: inline-block;\n}\n\n.xplor-btn-toggle-secondary {\n border: 1px solid #E0E0E0;\n margin-left: 0.5rem;\n margin-right: 0.5rem;\n margin-bottom: 0.5rem;\n border-radius: 1rem;\n color: #757575;\n min-width: 70px;\n padding: 0.5rem 1rem;\n background-color: white;\n cursor: pointer;\n font-size: inherit;\n font-family: inherit;\n transition: all 0.2s ease;\n\n &:first-of-type {\n margin-left: 0;\n }\n\n &--active {\n background-color: #E6F7F7;\n color: #008480;\n border-color: #008480;\n }\n\n &--disabled {\n background-color: #FAFAFA;\n color: rgba(0, 0, 0, 0.38);\n border-color: rgba(0, 0, 0, 0.12);\n cursor: not-allowed;\n pointer-events: none;\n\n &.xplor-btn-toggle-secondary--active {\n background-color: rgba(0, 0, 0, 0.05);\n }\n }\n\n &--inactive-outlined {\n border-color: #757575;\n }\n\n &:hover:not(.xplor-btn-toggle-secondary--disabled) {\n background-color: #F5F5F5;\n\n &.xplor-btn-toggle-secondary--active {\n background-color: #D0EBD2;\n }\n }\n}\n","import { Component, Host, h, Prop, Event, EventEmitter } from '@stencil/core';\n\n@Component({\n tag: 'xplor-btn-toggle-secondary',\n styleUrl: 'xplor-btn-toggle-secondary.scss',\n scoped: true,\n})\nexport class XplorBtnToggleSecondary {\n /**\n * Whether the button is active/selected\n */\n @Prop({ mutable: true }) active: boolean = false;\n\n /**\n * Whether the button is disabled\n */\n @Prop() disabled: boolean = false;\n\n /**\n * Whether to show outline when inactive\n */\n @Prop() inactiveOutlined: boolean = false;\n\n /**\n * Toggle event\n */\n @Event() xplorToggle: EventEmitter<boolean>;\n\n private handleClick = () => {\n if (!this.disabled) {\n this.active = !this.active;\n this.xplorToggle.emit(this.active);\n }\n };\n\n render() {\n const buttonClasses = {\n 'xplor-btn-toggle-secondary': true,\n 'xplor-btn-toggle-secondary--active': this.active,\n 'xplor-btn-toggle-secondary--disabled': this.disabled,\n 'xplor-btn-toggle-secondary--inactive-outlined': this.inactiveOutlined && !this.active,\n };\n\n return (\n <Host>\n <button\n class={buttonClasses}\n disabled={this.disabled}\n onClick={this.handleClick}\n aria-pressed={this.active ? 'true' : 'false'}\n >\n <slot />\n </button>\n </Host>\n );\n }\n}\n",":host {\n display: inline-block;\n}","import { Component, Host, h, Prop } from '@stencil/core';\n\n@Component({\n tag: 'xplor-btn-tooltip',\n styleUrl: 'xplor-btn-tooltip.scss',\n scoped: true,\n})\nexport class XplorBtnTooltip {\n @Prop() text: string;\n @Prop() tooltipText: string;\n @Prop() tooltipPosition: 'top' | 'bottom' | 'left' | 'right' = 'top';\n @Prop() type: 'primary' | 'secondary' | 'ghost' | 'disabled' = 'primary';\n @Prop() mode: 'office' | 'pg';\n @Prop() iconPosition: 'start' | 'end';\n @Prop() disabled: boolean = false;\n\n render() {\n return (\n <Host>\n <xplor-tooltip\n position={this.tooltipPosition}\n content={this.tooltipText}\n trigger=\"hover\"\n arrow={true}\n disabled={this.disabled}\n >\n <xplor-button\n slot=\"trigger\"\n text={this.text}\n type={this.type}\n mode={this.mode}\n icon-position={this.iconPosition}\n >\n <slot />\n </xplor-button>\n </xplor-tooltip>\n </Host>\n );\n }\n}\n","@use '../../styles/colours.scss' as colours-pg;\n@use '../../styles/spacing.scss' as spacing;\n\n:host {\n display: block;\n}\n\n.x-button {\n display: -webkit-box;\n display: -webkit-flex;\n display: -ms-flexbox;\n display: flex;\n -webkit-box-pack: center;\n -webkit-justify-content: center;\n -ms-flex-pack: center;\n justify-content: center;\n position: relative;\n -webkit-align-items: center;\n -webkit-box-align: center;\n -ms-flex-align: center;\n align-items: center;\n border: 1px solid;\n border-radius: 1rem;\n cursor: pointer;\n display: block;\n -webkit-flex-direction: row;\n -ms-flex-direction: row;\n flex-direction: row;\n font-size: 1rem;\n font-weight: 500;\n -webkit-box-pack: center;\n -webkit-justify-content: center;\n -ms-flex-pack: center;\n justify-content: center;\n -webkit-letter-spacing: 0.75px;\n -moz-letter-spacing: 0.75px;\n -ms-letter-spacing: 0.75px;\n padding: spacing.$spacing-12 spacing.$spacing-24;\n letter-spacing: 0.75px;\n overflow: hidden;\n position: relative;\n -webkit-transition:\n background-color 0.2s,\n border-color 0.2s,\n color 0.2s;\n transition:\n background-color 0.2s,\n border-color 0.2s,\n color 0.2s;\n\n // Icon Only Button (Circular)\n &.x-button--icon-only {\n width: 48px;\n height: 48px;\n padding: 0;\n border-radius: 50%;\n min-width: 48px;\n display: flex;\n align-items: center;\n justify-content: center;\n\n .button-icon {\n font-size: 20px;\n font-weight: 300;\n display: flex;\n align-items: center;\n justify-content: center;\n\n &.button-icon--svg {\n svg {\n width: spacing.$spacing-16;\n height: spacing.$spacing-16;\n display: block;\n }\n }\n }\n }\n\n // Regular Button with Icon\n &.x-button--with-icon {\n .button-icon {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n font-size: 18px;\n line-height: 1;\n }\n\n // SVG icon styles\n &.x-button--icon-start {\n .button-icon--svg {\n margin-right: spacing.$spacing-8 ;\n }\n }\n\n &.x-button--icon-end {\n .button-icon--svg {\n margin-left: spacing.$spacing-8 ;\n }\n }\n\n .button-icon--svg {\n\n\n svg {\n display: block;\n width: 14px;\n height: 14px;\n\n\n path {\n fill: currentColor;\n }\n }\n }\n\n .button-text {\n line-height: 1;\n }\n }\n\n // Icon positioning\n &.x-button--icon-start {\n flex-direction: row;\n }\n\n &.x-button--icon-end {\n flex-direction: row;\n }\n\n &.shadow {\n box-shadow:\n 0px 2.30969px 4.25707px rgba(20, 20, 21, 0.28),\n 0px 6.38599px 11.7703px rgba(20, 20, 21, 0.0521271),\n 0px 15.375px 28.3382px rgba(20, 20, 21, 0.04),\n 0px 32px 94px rgba(20, 20, 21, 0.0278729);\n }\n\n &.primary {\n background-color: colours-pg.$primary;\n border-color: colours-pg.$primary;\n color: white;\n\n &:hover {\n background-color: colours-pg.$primary-50;\n border-color: colours-pg.$primary-50;\n color: white;\n }\n }\n\n &.secondary {\n background-color: colours-pg.$secondary;\n border-color: colours-pg.$secondary;\n color: white;\n\n &:hover {\n background-color: colours-pg.$secondary-50;\n border-color: colours-pg.$secondary-50;\n color: white;\n ;\n }\n }\n\n &.ghost {\n background-color: #fff;\n border-color: colours-pg.$secondary;\n color: colours-pg.$secondary;\n\n &:hover {\n background-color: #DFF2F1;\n border-color: colours-pg.$secondary;\n color: colours-pg.$secondary;\n\n }\n\n &:active {\n background-color: #BEE6E4;\n border-color: colours-pg.$secondary;\n color: colours-pg.$secondary;\n\n }\n }\n\n &.minimal {\n background-color: transparent;\n border-color: transparent;\n color: colours-pg.$primary;\n }\n\n &.success {\n background-color: transparent;\n border-color: colours-pg.$success;\n color: colours-pg.$success;\n\n &:hover {\n background-color: colours-pg.$success-50;\n border-color: colours-pg.$success;\n color: colours-pg.$success;\n }\n\n &:active {\n background-color: colours-pg.$success-100;\n }\n }\n\n &.text {\n background-color: transparent;\n border-color: transparent;\n color: colours-pg.$secondary;\n\n &:hover {\n background-color: colours-pg.$secondary-50;\n }\n\n &:active {\n background-color: colours-pg.$secondary-100;\n }\n }\n\n &.disabled {\n background-color: #f6f6f6;\n border-color: #a0a0a0;\n color: #a0a0a0;\n }\n}\n\n.icon {\n background-color: #ffffff;\n bottom: 0px;\n left: 0px;\n opacity: 0;\n position: absolute;\n right: 0px;\n top: 0px;\n -webkit-transition: opacity 0.2s;\n transition: opacity 0.2s;\n}\n\n// Size variations for icon-only buttons\n.x-button--icon-only {\n &.small {\n width: 36px;\n height: 36px;\n padding: spacing.$spacing-4;\n\n .button-icon {\n font-size: 16px;\n }\n }\n\n &.button-icon--svg {\n padding: spacing.$spacing-4;\n\n svg {\n width: 16px;\n height: 16px;\n\n }\n }\n\n &.large {\n width: 56px;\n height: 56px;\n\n .button-icon {\n font-size: 24px;\n }\n }\n}\n\n// Ensure disabled state works with icon buttons\n.x-button.disabled {\n\n &.x-button--icon-only,\n &.x-button--with-icon {\n cursor: not-allowed;\n opacity: 0.6;\n }\n}","import { Component, Host, h, Prop } from '@stencil/core';\n\n@Component({\n tag: 'xplor-button',\n styleUrl: 'xplor-button.scss',\n // we cant use multiple styleUrls because the mode property is not reactive only in stencilJS and once the component is rendered it wont change the css file\n // so we are using only one styleUrl and changing the styles based on the mode property in the class\n // styleUrls: {\n // default: 'xplor-button.scss',\n // dark: 'xplor-button-pg.scss',\n // pg: 'xplor-button-pg.scss',\n // office: 'xplor-button-office.scss',\n // },\n scoped: true,\n})\nexport class XplorButton {\n @Prop() text: string;\n @Prop() type: 'minimal' | 'primary' | 'secondary' | 'ghost' | 'disabled' | 'success' | 'text' = 'secondary';\n @Prop() mode?: 'dark' | 'pg' | 'office' = 'pg'; // 'dark', 'pg', 'office' (default: 'dark')\n @Prop() size?: string; // 'small', 'medium', 'large' (default:'medium')\n @Prop() styles?: string;\n @Prop() clickAction: () => void;\n\n /** Accessible label for icon-only buttons */\n @Prop() ariaLabel: string;\n\n /** Whether the button is disabled */\n @Prop() disabled: boolean = false;\n\n /**\n * Icon position: 'start' | 'end' | null\n */\n @Prop() iconPosition: 'start' | 'end' | null;\n\n /**\n * Icon to display (defaults to plus sign)\n */\n @Prop() icon: string = '+';\n @Prop() iconSvg?: string;\n\n private renderIcon() {\n if (this.icon === 'svg' && this.iconSvg) {\n return (\n <span class=\"button-icon button-icon--svg \" innerHTML={this.iconSvg}></span>\n );\n }\n return (\n <span class=\"button-icon\">\n {this.icon}\n </span>\n );\n }\n\n render() {\n const isIconOnly = !this.text && this.iconPosition !== null;\n const hasIcon = this.iconPosition !== null;\n\n return (\n <Host>\n <slot>\n <button\n role=\"button\"\n class={{\n 'x-button': true,\n [this.type]: true,\n 'shadow': this.type !== 'minimal' && this.type !== 'text',\n 'x-button--icon-only': isIconOnly,\n 'x-button--with-icon': hasIcon && !isIconOnly,\n 'x-button--icon-start': this.iconPosition === 'start' && !isIconOnly,\n 'x-button--icon-end': this.iconPosition === 'end' && !isIconOnly,\n ...(this.styles ? { [this.styles]: true } : {}),\n }}\n onClick={() => this.clickAction && this.clickAction()}\n aria-label={this.ariaLabel}\n aria-disabled={this.disabled ? 'true' : null}\n disabled={this.disabled}\n >\n {hasIcon && this.iconPosition === 'start' && this.renderIcon()}\n {this.text && <span class=\"button-text\">{this.text}</span>}\n {hasIcon && this.iconPosition === 'end' && this.renderIcon()}\n </button>\n </slot>\n </Host>\n );\n }\n}",":host {\n display: block;\n}\n\n.container {\n display: flex;\n margin-top: 20px;\n}","import { Component, Element, Host, h, State, Prop } from '@stencil/core';\n\n@Component({\n tag: 'xplor-chat-widget',\n styleUrl: 'xplor-chat-widget.scss',\n shadow: true,\n})\nexport class XplorChatWidget {\n @Prop() languageOptions: string[] = ['English', 'Spanish', 'French', 'German', 'Italian'];\n @Prop() textId: string = 'text';\n @Prop() apiKey: string; // TODO: add api key to the component\n @Element() host: HTMLElement;\n @State() selectedLanguage: string = 'English';\n @State() textValue: string;\n 'Hoy, nos divertimos mucho explorando el mundo de la arcilla. Estaban totalmente absortos en el proceso, formando cuidadosamente la arcilla en diseños y patrones únicos. Desde animales coloridos hasta formas extravagantes, la imaginación de tu hijo no tuvo límites durante este día lleno de diversión.';\n\n componentDidLoad() {\n const element = this.host.shadowRoot?.getElementById('text');\n // we need to change this to a class so we can maniplulate multipule different spots with text.\n if (element) {\n this.textValue = element.textContent || '';\n console.log('textValue:', this.textValue);\n }\n }\n\n handleClick = () => {\n // const ai = document.getElementsByClassName('ai-translate');\n // Array loop throught ai html items and remap it and update\n // each class should be seperated\n debugger;\n fetch('https://nnvy1fqqcb.execute-api.ap-southeast-2.amazonaws.com/ai_dev/ai/prompt-generation', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'x-api-key': this.apiKey, // Replace with your actual API key\n },\n body: JSON.stringify({\n service: null,\n action: 'translate',\n language: this.selectedLanguage,\n content: this.textValue || '',\n }),\n })\n .then((response) => {\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n return response.json();\n })\n .then((data) => {\n console.log('Success:', data);\n this.textValue = data.response;\n })\n .catch((error) => {\n console.error('Error:', error);\n });\n };\n\n handleChange = (event: Event) => {\n const selectElement = event.target as HTMLSelectElement;\n this.selectedLanguage = selectElement.value;\n console.log('Selected language:', this.selectedLanguage);\n };\n\n render() {\n return (\n <Host>\n <div id=\"ai-text\">{this.textValue}</div>\n <div class=\"container\">\n <xplor-dropdown\n options={this.languageOptions}\n selected={this.selectedLanguage}\n handleChange={this.handleChange}\n />\n <xplor-button text=\"translate\" mode=\"pg\" type=\"primary\" onClick={this.handleClick}></xplor-button>\n </div>\n </Host>\n );\n }\n}\n","/* custom-checkbox.scss */\n$color-gray-400: #d1d5db;\n$color-gray-600: #6b7280;\n$color-gray-700: #374151;\n$color-green-100: #d1fae5;\n$color-green-200: #a7f3d0;\n$color-green-300: #6ee7b7;\n$color-green-600: #059669;\n$color-red-100: #fee2e2;\n$color-red-200: #fecaca;\n$color-red-300: #fca5a5;\n$color-red-500: #ef4444;\n$color-white: white;\n\n$checkbox-size: 20px;\n$checkbox-radius: 4px;\n$border-width: 2px;\n$icon-size: 16px;\n$transition-speed: 0.15s;\n$focus-ring-opacity: 0.1;\n$disabled-opacity: 0.4;\n\n:host {\n display: inline-block;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n}\n\n.checkbox-wrapper {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n}\n\n.checkbox {\n width: $checkbox-size;\n height: $checkbox-size;\n border-radius: $checkbox-radius;\n border: $border-width solid $color-gray-600;\n background: $color-white;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all $transition-speed ease;\n outline: none;\n position: relative;\n\n // Hover state (unselected)\n &.hover {\n background: $color-green-100;\n border-color: $color-green-600;\n }\n\n // Focus state (unselected)\n &.focus {\n background: $color-green-200;\n border-color: $color-green-600;\n box-shadow: 0 0 0 3px rgba($color-green-600, $focus-ring-opacity);\n }\n\n // Pressed state (unselected)\n &.pressed {\n background: $color-green-300;\n border-color: $color-green-600;\n }\n\n // Selected (checked) state\n &.checked {\n background: $color-green-600;\n border-color: $color-green-600;\n\n &.hover {\n background: $color-green-100;\n border-color: $color-green-600;\n\n .check-icon {\n color: $color-green-600;\n }\n }\n\n &.focus {\n background: $color-green-200;\n border-color: $color-green-600;\n box-shadow: 0 0 0 3px rgba($color-green-600, $focus-ring-opacity);\n\n .check-icon {\n color: $color-green-600;\n }\n }\n\n &.pressed {\n background: $color-green-300;\n border-color: $color-green-600;\n\n .check-icon {\n color: $color-green-600;\n }\n }\n }\n\n // Indeterminate state\n &.indeterminate {\n background: $color-green-600;\n border-color: $color-green-600;\n\n &.hover {\n background: $color-green-100;\n border-color: $color-green-600;\n\n .indeterminate-icon {\n color: $color-green-600;\n }\n }\n\n &.focus {\n background: $color-green-200;\n border-color: $color-green-600;\n box-shadow: 0 0 0 3px rgba($color-green-600, $focus-ring-opacity);\n\n .indeterminate-icon {\n color: $color-green-600;\n }\n }\n\n &.pressed {\n background: $color-green-300;\n border-color: $color-green-600;\n\n .indeterminate-icon {\n color: $color-green-600;\n }\n }\n }\n\n // Error state (unselected)\n &.error {\n border-color: $color-red-500;\n\n &.hover {\n background: $color-red-100;\n border-color: $color-red-500;\n }\n\n &.focus {\n background: $color-red-200;\n border-color: $color-red-500;\n box-shadow: 0 0 0 3px rgba($color-red-500, $focus-ring-opacity);\n }\n\n &.pressed {\n background: $color-red-300;\n border-color: $color-red-500;\n }\n\n // Error + checked\n &.checked {\n background: $color-red-500;\n border-color: $color-red-500;\n\n &.hover {\n background: $color-red-100;\n border-color: $color-red-500;\n\n .check-icon {\n color: $color-red-500;\n }\n }\n\n &.focus {\n background: $color-red-200;\n border-color: $color-red-500;\n box-shadow: 0 0 0 3px rgba($color-red-500, $focus-ring-opacity);\n\n .check-icon {\n color: $color-red-500;\n }\n }\n\n &.pressed {\n background: $color-red-300;\n border-color: $color-red-500;\n\n .check-icon {\n color: $color-red-500;\n }\n }\n }\n\n // Error + indeterminate\n &.indeterminate {\n background: $color-red-500;\n border-color: $color-red-500;\n\n &.hover {\n background: $color-red-100;\n border-color: $color-red-500;\n\n .indeterminate-icon {\n color: $color-red-500;\n }\n }\n\n &.focus {\n background: $color-red-200;\n border-color: $color-red-500;\n box-shadow: 0 0 0 3px rgba($color-red-500, $focus-ring-opacity);\n\n .indeterminate-icon {\n color: $color-red-500;\n }\n }\n\n &.pressed {\n background: $color-red-300;\n border-color: $color-red-500;\n\n .indeterminate-icon {\n color: $color-red-500;\n }\n }\n }\n }\n\n // Disabled state\n &.disabled {\n opacity: $disabled-opacity;\n cursor: not-allowed;\n border-color: $color-gray-400;\n background: $color-white;\n\n &.checked,\n &.indeterminate {\n background: $color-gray-400;\n border-color: $color-gray-400;\n }\n }\n}\n\n.check-icon,\n.indeterminate-icon {\n width: $icon-size;\n height: $icon-size;\n color: $color-white;\n}\n\n.label {\n font-size: 14px;\n color: $color-gray-700;\n user-select: none;\n\n .checkbox.disabled~& {\n opacity: $disabled-opacity;\n }\n}","import { Component, Prop, State, Event, EventEmitter, h, Watch } from '@stencil/core';\n\nlet checkboxIdCounter = 0;\n\n@Component({\n tag: 'xplor-checkbox',\n styleUrl: 'xplor-checkbox.scss',\n shadow: true,\n})\nexport class XplorCheckbox {\n private labelId = `xplor-checkbox-label-${++checkboxIdCounter}`;\n @Prop() initialChecked: boolean = false;\n @Prop() initialIndeterminate: boolean = false;\n\n @Prop() disabled: boolean = false;\n @Prop() error: boolean = false;\n @Prop() label: string = '';\n\n @State() checked: boolean = false;\n @State() indeterminate: boolean = false;\n @State() isHovered: boolean = false;\n @State() isFocused: boolean = false;\n @State() isPressed: boolean = false;\n\n @Event() checkboxChange: EventEmitter<{ checked: boolean; indeterminate: boolean }>;\n\n @Watch('initialChecked')\n watchCheckedProp(newValue: boolean) {\n this.checked = newValue;\n }\n\n @Watch('initialIndeterminate')\n watchIndeterminateProp(newValue: boolean) {\n this.indeterminate = newValue;\n }\n\n componentWillLoad() {\n this.checked = this.initialChecked;\n this.indeterminate = this.initialIndeterminate;\n } private handleClick = () => {\n if (this.disabled) return;\n\n if (this.indeterminate) {\n // If indeterminate, go to checked state\n this.indeterminate = false;\n this.checked = true;\n } else {\n // Toggle between checked and unchecked\n this.checked = !this.checked;\n }\n\n this.checkboxChange.emit({\n checked: this.checked,\n indeterminate: this.indeterminate\n });\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (this.disabled) return;\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n this.isPressed = true;\n this.handleClick();\n }\n };\n\n private handleKeyUp = (e: KeyboardEvent) => {\n if (e.key === ' ' || e.key === 'Enter') {\n this.isPressed = false;\n }\n };\n\n private getCheckboxClass = () => {\n const classes = ['checkbox'];\n\n if (this.checked) classes.push('checked');\n if (this.indeterminate) classes.push('indeterminate');\n if (this.disabled) classes.push('disabled');\n if (this.error) classes.push('error');\n if (this.isHovered && !this.disabled) classes.push('hover');\n if (this.isFocused && !this.disabled) classes.push('focus');\n if (this.isPressed && !this.disabled) classes.push('pressed');\n\n return classes.join(' ');\n };\n\n render() {\n return (\n <div class=\"checkbox-wrapper\">\n <div\n class={this.getCheckboxClass()}\n onClick={this.handleClick}\n onMouseEnter={() => this.isHovered = true}\n onMouseLeave={() => this.isHovered = false}\n onMouseDown={() => this.isPressed = true}\n onMouseUp={() => this.isPressed = false}\n onFocus={() => this.isFocused = true}\n onBlur={() => this.isFocused = false}\n onKeyDown={this.handleKeyDown}\n onKeyUp={this.handleKeyUp}\n tabIndex={this.disabled ? -1 : 0}\n role=\"checkbox\"\n aria-checked={this.indeterminate ? 'mixed' : this.checked.toString()}\n aria-disabled={this.disabled.toString()}\n aria-labelledby={this.label ? this.labelId : undefined}\n >\n {this.checked && (\n <svg class=\"check-icon\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path\n d=\"M13.3334 4L6.00002 11.3333L2.66669 8\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n />\n </svg>\n )}\n {this.indeterminate && (\n <svg class=\"indeterminate-icon\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path\n d=\"M3.33331 8H12.6666\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n />\n </svg>\n )}\n </div>\n {this.label && <span class=\"label\" id={this.labelId}>{this.label}</span>}\n </div>\n );\n }\n}",":host {\n display: block;\n width: 100%;\n}\n\n.combobox {\n position: relative;\n width: 100%;\n\n &--disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n &--readonly {\n .combobox__input {\n background-color: #f5f5f5;\n }\n }\n}\n\n.combobox__label {\n display: block;\n font-size: 0.875rem;\n font-weight: 500;\n color: #424242;\n margin-bottom: 0.5rem;\n}\n\n.combobox__input-wrapper {\n position: relative;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 0.5rem;\n border: 1px solid #bdbdbd;\n border-radius: 4px;\n padding: 0.5rem;\n background-color: #fff;\n transition: border-color 0.2s, box-shadow 0.2s;\n\n &:focus-within {\n border-color: #1976d2;\n box-shadow: 0 0 0 3px rgba(25, 118, 210, 0.1);\n }\n}\n\n.combobox__chips {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n}\n\n.combobox__chip {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0.25rem 0.5rem;\n background-color: #e8f5e9;\n border-radius: 16px;\n font-size: 0.875rem;\n color: #2e7d32;\n}\n\n.combobox__chip-label {\n line-height: 1;\n}\n\n.combobox__chip-remove {\n background: none;\n border: none;\n font-size: 1.25rem;\n line-height: 1;\n cursor: pointer;\n padding: 0;\n width: 1rem;\n height: 1rem;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #2e7d32;\n border-radius: 50%;\n transition: background-color 0.2s;\n\n &:hover:not(:disabled) {\n background-color: rgba(46, 125, 50, 0.1);\n }\n\n &:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n}\n\n.combobox__input {\n flex: 1;\n min-width: 120px;\n border: none;\n outline: none;\n font-family: inherit;\n font-size: 1rem;\n padding: 0.25rem;\n background: transparent;\n color: #212121;\n\n &::placeholder {\n color: #9e9e9e;\n }\n\n &:disabled {\n cursor: not-allowed;\n }\n\n &[readonly] {\n cursor: default;\n }\n}\n\n.combobox__actions {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n flex-shrink: 0;\n}\n\n.combobox__clear {\n background: none;\n border: none;\n font-size: 1.25rem;\n line-height: 1;\n cursor: pointer;\n padding: 0;\n width: 1.5rem;\n height: 1.5rem;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #757575;\n border-radius: 50%;\n transition: background-color 0.2s;\n\n &:hover {\n background-color: #f5f5f5;\n color: #212121;\n }\n}\n\n.combobox__icon {\n font-size: 0.75rem;\n color: #757575;\n pointer-events: none;\n transition: transform 0.2s;\n\n .combobox--open & {\n transform: rotate(180deg);\n }\n}\n\n.combobox__dropdown {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n right: 0;\n max-height: 300px;\n overflow-y: auto;\n background-color: #fff;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);\n z-index: 1000;\n}\n\n.combobox__item {\n padding: 0.75rem 1rem;\n cursor: pointer;\n transition: background-color 0.2s;\n color: #212121;\n\n &:hover:not(&--disabled) {\n background-color: #f5f5f5;\n }\n\n &--highlighted {\n background-color: #e3f2fd;\n }\n\n &--selected {\n background-color: #1976d2;\n color: #fff;\n\n &:hover {\n background-color: #1565c0;\n }\n }\n\n &--disabled {\n opacity: 0.5;\n cursor: not-allowed;\n }\n\n &--create {\n background-color: #fff9c4;\n border-top: 1px solid #e0e0e0;\n\n &:hover {\n background-color: #fff59d;\n }\n\n &.combobox__item--highlighted {\n background-color: #fff176;\n }\n }\n}\n\n.combobox__create-label {\n color: #757575;\n font-size: 0.875rem;\n}\n\n.combobox__no-results {\n padding: 1rem;\n text-align: center;\n color: #757575;\n font-size: 0.875rem;\n}","import { Component, Host, h, Prop, State, Event, EventEmitter, Element, Listen } from '@stencil/core';\n\nexport interface ComboboxItem {\n label: string;\n value: any;\n disabled?: boolean;\n [key: string]: any;\n}\n\n@Component({\n tag: 'xplor-combobox',\n styleUrl: 'xplor-combobox.scss',\n scoped: true,\n})\nexport class XplorCombobox {\n @Element() el: HTMLElement;\n\n /**\n * Array of items to display in the dropdown\n */\n @Prop() items: ComboboxItem[] = [];\n\n /**\n * Selected value(s)\n */\n @Prop({ mutable: true }) value: any = null;\n\n /**\n * Placeholder text\n */\n @Prop() placeholder: string = 'Type to search or add...';\n\n /**\n * Label for the input\n */\n @Prop() label: string;\n\n /**\n * Accessible label for the input when no visible label is provided\n */\n @Prop() ariaLabel: string;\n\n /**\n * Disable the combobox\n */\n @Prop() disabled: boolean = false;\n\n /**\n * Make the combobox readonly\n */\n @Prop() readonly: boolean = false;\n\n /**\n * Clear button\n */\n @Prop() clearable: boolean = false;\n\n /**\n * Allow multiple selection\n */\n @Prop() multiple: boolean = false;\n\n /**\n * Allow creating new items\n */\n @Prop() allowCustom: boolean = true;\n\n /**\n * Message to display when creating new item\n */\n @Prop() createMessage: string = 'Create';\n\n @State() isOpen: boolean = false;\n @State() searchQuery: string = '';\n @State() filteredItems: ComboboxItem[] = [];\n @State() selectedItems: any[] = [];\n @State() highlightedIndex: number = -1;\n @State() customItems: ComboboxItem[] = [];\n\n @Event() xplorChange: EventEmitter<any>;\n @Event() xplorSelect: EventEmitter<ComboboxItem>;\n @Event() xplorCreate: EventEmitter<string>;\n @Event() xplorClear: EventEmitter<void>;\n @Event() xplorSearch: EventEmitter<string>;\n\n private inputEl: HTMLInputElement;\n private dropdownEl: HTMLDivElement;\n\n componentWillLoad() {\n this.filterItems();\n if (this.value !== null) {\n if (this.multiple && Array.isArray(this.value)) {\n this.selectedItems = this.value;\n } else if (!this.multiple) {\n const allItems = [...this.items, ...this.customItems];\n const selectedItem = allItems.find(item => item.value === this.value);\n if (selectedItem) {\n this.searchQuery = selectedItem.label;\n }\n }\n }\n }\n\n @Listen('click', { target: 'document' })\n handleDocumentClick(event: MouseEvent) {\n const target = event.target as Node;\n if (!this.el.contains(target)) {\n this.isOpen = false;\n }\n }\n\n private filterItems() {\n const query = this.searchQuery.toLowerCase();\n const allItems = [...this.items, ...this.customItems];\n\n if (query === '') {\n this.filteredItems = allItems;\n return;\n }\n\n this.filteredItems = allItems.filter(item =>\n item.label.toLowerCase().includes(query)\n );\n }\n\n private canCreateNew(): boolean {\n if (!this.allowCustom || this.searchQuery.trim() === '') {\n return false;\n }\n\n const allItems = [...this.items, ...this.customItems];\n const exactMatch = allItems.some(\n item => item.label.toLowerCase() === this.searchQuery.toLowerCase()\n );\n\n return !exactMatch;\n }\n\n private handleInputFocus = () => {\n if (this.disabled || this.readonly) return;\n this.isOpen = true;\n this.highlightedIndex = -1;\n };\n\n private handleInputChange = (event: Event) => {\n const input = event.target as HTMLInputElement;\n this.searchQuery = input.value;\n this.filterItems();\n this.isOpen = true;\n this.highlightedIndex = -1;\n this.xplorSearch.emit(this.searchQuery);\n\n if (!this.multiple && this.searchQuery === '') {\n this.value = null;\n this.xplorChange.emit(null);\n }\n };\n\n private handleInputKeyDown = (event: KeyboardEvent) => {\n if (this.disabled || this.readonly) return;\n\n const totalItems = this.filteredItems.length + (this.canCreateNew() ? 1 : 0);\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n this.isOpen = true;\n this.highlightedIndex = Math.min(this.highlightedIndex + 1, totalItems - 1);\n this.scrollToHighlighted();\n break;\n\n case 'ArrowUp':\n event.preventDefault();\n this.highlightedIndex = Math.max(this.highlightedIndex - 1, -1);\n this.scrollToHighlighted();\n break;\n\n case 'Enter':\n event.preventDefault();\n if (this.highlightedIndex >= 0) {\n if (this.highlightedIndex < this.filteredItems.length) {\n this.selectItem(this.filteredItems[this.highlightedIndex]);\n } else if (this.canCreateNew()) {\n this.createNewItem();\n }\n } else if (this.canCreateNew() && this.searchQuery.trim() !== '') {\n this.createNewItem();\n }\n break;\n\n case 'Escape':\n event.preventDefault();\n this.isOpen = false;\n this.inputEl?.blur();\n break;\n\n case 'Backspace':\n if (this.multiple && this.searchQuery === '' && this.selectedItems.length > 0) {\n event.preventDefault();\n this.removeItem(this.selectedItems[this.selectedItems.length - 1]);\n }\n break;\n }\n };\n\n private scrollToHighlighted() {\n if (this.dropdownEl && this.highlightedIndex >= 0) {\n const highlightedEl = this.dropdownEl.querySelector(`[data-index=\"${this.highlightedIndex}\"]`) as HTMLElement;\n if (highlightedEl) {\n highlightedEl.scrollIntoView({ block: 'nearest' });\n }\n }\n }\n\n private selectItem(item: ComboboxItem) {\n if (item.disabled) return;\n\n if (this.multiple) {\n if (!this.selectedItems.includes(item.value)) {\n this.selectedItems = [...this.selectedItems, item.value];\n this.value = this.selectedItems;\n this.xplorChange.emit(this.value);\n }\n this.searchQuery = '';\n this.filterItems();\n } else {\n this.value = item.value;\n this.searchQuery = item.label;\n this.isOpen = false;\n this.xplorChange.emit(this.value);\n }\n\n this.xplorSelect.emit(item);\n this.inputEl?.focus();\n }\n\n private createNewItem() {\n const newValue = this.searchQuery.trim();\n const newItem: ComboboxItem = {\n label: newValue,\n value: newValue,\n };\n\n this.customItems = [...this.customItems, newItem];\n this.selectItem(newItem);\n this.xplorCreate.emit(newValue);\n }\n\n private removeItem(value: any) {\n this.selectedItems = this.selectedItems.filter(v => v !== value);\n this.value = this.selectedItems;\n this.xplorChange.emit(this.value);\n }\n\n private handleClear = () => {\n this.value = this.multiple ? [] : null;\n this.selectedItems = [];\n this.searchQuery = '';\n this.filterItems();\n this.xplorChange.emit(this.value);\n this.xplorClear.emit();\n this.inputEl?.focus();\n };\n\n private getSelectedItemLabel(value: any): string {\n const allItems = [...this.items, ...this.customItems];\n const item = allItems.find(i => i.value === value);\n return item ? item.label : value;\n }\n\n render() {\n const hasValue = this.multiple ? this.selectedItems.length > 0 : this.value !== null && this.searchQuery !== '';\n const showCreateOption = this.canCreateNew();\n const listboxId = 'combobox-listbox';\n const labelId = 'combobox-label';\n const activeDescendantId = this.highlightedIndex >= 0 ? `combobox-option-${this.highlightedIndex}` : undefined;\n\n return (\n <Host>\n <div\n class={{\n 'combobox': true,\n 'combobox--disabled': this.disabled,\n 'combobox--readonly': this.readonly,\n 'combobox--open': this.isOpen,\n }}\n >\n {this.label && (\n <label class=\"combobox__label\" id={labelId}>{this.label}</label>\n )}\n\n <div class=\"combobox__input-wrapper\">\n {this.multiple && this.selectedItems.length > 0 && (\n <div class=\"combobox__chips\">\n {this.selectedItems.map(value => {\n const chipLabel = this.getSelectedItemLabel(value);\n return (\n <div class=\"combobox__chip\">\n <span class=\"combobox__chip-label\">\n {chipLabel}\n </span>\n <button\n type=\"button\"\n class=\"combobox__chip-remove\"\n onClick={() => this.removeItem(value)}\n disabled={this.disabled || this.readonly}\n aria-label={`Remove ${chipLabel}`}\n >\n ×\n </button>\n </div>\n );\n })}\n </div>\n )}\n\n <input\n ref={(el) => (this.inputEl = el)}\n type=\"text\"\n class=\"combobox__input\"\n placeholder={this.placeholder}\n value={this.searchQuery}\n onFocus={this.handleInputFocus}\n onInput={this.handleInputChange}\n onKeyDown={this.handleInputKeyDown}\n disabled={this.disabled}\n readonly={this.readonly}\n autocomplete=\"off\"\n role=\"combobox\"\n aria-expanded={this.isOpen ? 'true' : 'false'}\n aria-haspopup=\"listbox\"\n aria-controls={this.isOpen ? listboxId : undefined}\n aria-activedescendant={activeDescendantId}\n aria-labelledby={this.label ? labelId : undefined}\n aria-label={!this.label ? (this.ariaLabel || this.placeholder) : undefined}\n aria-autocomplete=\"list\"\n />\n\n <div class=\"combobox__actions\">\n {this.clearable && hasValue && !this.disabled && !this.readonly && (\n <button\n type=\"button\"\n class=\"combobox__clear\"\n onClick={this.handleClear}\n aria-label=\"Clear selection\"\n >\n ×\n </button>\n )}\n <span class=\"combobox__icon\" aria-hidden=\"true\">▼</span>\n </div>\n </div>\n\n {this.isOpen && (this.filteredItems.length > 0 || showCreateOption) && (\n <div\n class=\"combobox__dropdown\"\n ref={(el) => (this.dropdownEl = el)}\n role=\"listbox\"\n id={listboxId}\n aria-label={this.label || this.ariaLabel || 'Options'}\n >\n {this.filteredItems.map((item, index) => {\n const isSelected = this.multiple\n ? this.selectedItems.includes(item.value)\n : this.value === item.value;\n return (\n <div\n key={item.value}\n id={`combobox-option-${index}`}\n data-index={index}\n role=\"option\"\n aria-selected={isSelected ? 'true' : 'false'}\n aria-disabled={item.disabled ? 'true' : undefined}\n class={{\n 'combobox__item': true,\n 'combobox__item--highlighted': index === this.highlightedIndex,\n 'combobox__item--selected': isSelected,\n 'combobox__item--disabled': item.disabled,\n }}\n onClick={() => this.selectItem(item)}\n >\n {item.label}\n </div>\n );\n })}\n\n {showCreateOption && (\n <div\n id={`combobox-option-${this.filteredItems.length}`}\n data-index={this.filteredItems.length}\n role=\"option\"\n aria-selected=\"false\"\n class={{\n 'combobox__item': true,\n 'combobox__item--create': true,\n 'combobox__item--highlighted': this.highlightedIndex === this.filteredItems.length,\n }}\n onClick={() => this.createNewItem()}\n >\n <span class=\"combobox__create-label\">{this.createMessage}:</span>{' '}\n <strong>\"{this.searchQuery}\"</strong>\n </div>\n )}\n </div>\n )}\n\n {this.isOpen && this.filteredItems.length === 0 && !showCreateOption && (\n <div class=\"combobox__dropdown\" role=\"listbox\" id={listboxId}>\n <div class=\"combobox__no-results\" role=\"option\" aria-disabled=\"true\">No results found</div>\n </div>\n )}\n </div>\n </Host>\n );\n }\n}\n",":host {\n display: block;\n width: 100%;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n}\n\n.datatable-container {\n background: white;\n border: 1px solid #e3e4e5;\n border-radius: 8px;\n overflow: hidden;\n}\n\n.table-wrapper {\n width: 100%;\n overflow: auto;\n position: relative;\n\n &.has-height {\n max-height: 100%;\n }\n\n &.is-empty {\n min-height: 200px;\n }\n}\n\ntable {\n width: 100%;\n border-collapse: collapse;\n background: white;\n\n thead {\n background: #f7f8f9;\n position: sticky;\n top: 0;\n z-index: 10;\n\n tr {\n border-bottom: 1px solid #e3e4e5;\n }\n\n th {\n padding: 12px 16px;\n text-align: left;\n font-size: 0.75rem;\n font-weight: 600;\n color: #1a1a1a;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n border-right: 1px solid #e3e4e5;\n white-space: nowrap;\n user-select: none;\n\n &:last-child {\n border-right: none;\n }\n\n &.sortable {\n cursor: pointer;\n transition: background-color 0.2s;\n\n &:hover {\n background: #eef0f1;\n }\n }\n\n &.sorted {\n background: #e5e7e9;\n }\n\n &.fixed {\n position: sticky;\n left: 0;\n z-index: 11;\n background: #f7f8f9;\n }\n\n &.align-left {\n text-align: left;\n }\n\n &.align-center {\n text-align: center;\n }\n\n &.align-right {\n text-align: right;\n }\n\n .header-content {\n display: flex;\n align-items: center;\n gap: 8px;\n justify-content: space-between;\n }\n\n .sort-icon {\n flex-shrink: 0;\n color: #999;\n transition: color 0.2s;\n\n &.active {\n color: #008480;\n }\n }\n }\n }\n\n tbody {\n tr {\n border-bottom: 1px solid #f0f0f0;\n transition: background-color 0.15s;\n\n &:last-child {\n border-bottom: 1px solid #e3e4e5;\n }\n\n &.clickable {\n cursor: pointer;\n }\n\n &.selected {\n background-color: rgba(0, 132, 128, 0.08);\n\n &:hover {\n background-color: rgba(0, 132, 128, 0.12);\n }\n }\n\n &.empty-row {\n cursor: default;\n\n &:hover {\n background: transparent;\n }\n }\n }\n\n td {\n padding: 12px 16px;\n font-size: 0.875rem;\n color: #333;\n border-right: 1px solid #f0f0f0;\n\n &:last-child {\n border-right: none;\n }\n\n &.align-left {\n text-align: left;\n }\n\n &.align-center {\n text-align: center;\n }\n\n &.align-right {\n text-align: right;\n }\n }\n\n .select-column {\n width: 50px;\n text-align: center;\n position: sticky;\n left: 0;\n background: inherit;\n z-index: 1;\n }\n }\n\n // Horizontal lines variant\n .horizontal-lines & {\n thead th {\n border-right: none;\n }\n\n tbody td {\n border-right: none;\n }\n\n tbody tr {\n border-bottom: 1px solid #e3e4e5;\n }\n }\n\n // Striped variant\n .striped & {\n tbody tr:nth-child(even) {\n background-color: #fafafa;\n\n &.selected {\n background-color: rgba(0, 132, 128, 0.08);\n }\n }\n }\n\n // Hover effect\n &.hover tbody tr:not(.empty-row):hover {\n background-color: #f5f5f5;\n\n &.selected {\n background-color: rgba(0, 132, 128, 0.12);\n }\n }\n}\n\n// Checkbox styling\n.checkbox-label {\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 0;\n cursor: pointer;\n\n input[type='checkbox'] {\n width: 18px;\n height: 18px;\n cursor: pointer;\n accent-color: #008480;\n margin: 0;\n }\n}\n\n// Empty state\n.empty-state {\n text-align: center;\n padding: 40px 20px;\n color: #999;\n\n p {\n margin: 0;\n font-size: 0.875rem;\n }\n}\n\n// Skeleton loader\n.skeleton-loader {\n tr {\n cursor: default !important;\n\n &:hover {\n background: transparent !important;\n }\n }\n\n .skeleton {\n background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);\n background-size: 200% 100%;\n animation: skeleton-loading 1.5s ease-in-out infinite;\n border-radius: 4px;\n\n &-text {\n height: 16px;\n width: 80%;\n }\n\n &-checkbox {\n height: 18px;\n width: 18px;\n margin: 0 auto;\n }\n }\n}\n\n@keyframes skeleton-loading {\n 0% {\n background-position: 200% 0;\n }\n\n 100% {\n background-position: -200% 0;\n }\n}\n\n// Footer\n.datatable-footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 12px 16px;\n border-top: 1px solid #e3e4e5;\n background: #fafafa;\n flex-wrap: wrap;\n gap: 16px;\n\n .footer-info {\n font-size: 0.875rem;\n color: #666;\n }\n\n .footer-controls {\n display: flex;\n align-items: center;\n gap: 24px;\n flex-wrap: wrap;\n }\n\n .per-page-selector {\n label {\n display: flex;\n align-items: center;\n gap: 8px;\n font-size: 0.875rem;\n color: #666;\n }\n\n select {\n padding: 4px 8px;\n border: 1px solid #d0d0d0;\n border-radius: 4px;\n background: white;\n font-size: 0.875rem;\n cursor: pointer;\n transition: border-color 0.2s;\n\n &:hover {\n border-color: #008480;\n }\n\n &:focus {\n outline: none;\n border-color: #008480;\n box-shadow: 0 0 0 2px rgba(0, 132, 128, 0.1);\n }\n }\n }\n\n .pagination-controls {\n display: flex;\n align-items: center;\n gap: 8px;\n\n .page-info {\n font-size: 0.875rem;\n color: #333;\n padding: 0 8px;\n }\n\n .pagination-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n padding: 0;\n border: 1px solid #d0d0d0;\n border-radius: 4px;\n background: white;\n color: #333;\n cursor: pointer;\n transition: all 0.2s;\n\n &:hover:not(:disabled) {\n border-color: #008480;\n background: #f0fffe;\n color: #008480;\n }\n\n &:active:not(:disabled) {\n background: #e0f9f8;\n }\n\n &:disabled {\n opacity: 0.4;\n cursor: not-allowed;\n }\n\n svg {\n width: 16px;\n height: 16px;\n }\n }\n }\n}\n\n// Responsive adjustments\n@media (max-width: 768px) {\n .datatable-footer {\n flex-direction: column;\n align-items: stretch;\n\n .footer-controls {\n justify-content: space-between;\n }\n }\n}","import {\n Component,\n Prop,\n State,\n Element,\n Event,\n EventEmitter,\n h,\n Watch,\n Host,\n} from '@stencil/core';\n\nexport interface DatatableColumn {\n text: string;\n value: string;\n sortable?: boolean;\n width?: string | number;\n align?: 'left' | 'center' | 'right';\n fixed?: boolean;\n}\n\nexport interface DatatablePagination {\n page: number;\n perpage: number;\n total: number;\n pages?: number;\n}\n\n@Component({\n tag: 'xplor-datatable',\n styleUrl: 'xplor-datatable.scss',\n shadow: true,\n})\nexport class XplorDatatable {\n @Element() el: HTMLXplorDatatableElement;\n\n /**\n * Array of column definitions for the table headers\n */\n @Prop() headers: DatatableColumn[] = [];\n\n /**\n * Array of data items to display in the table\n */\n @Prop() items: any[] = [];\n\n /**\n * Whether the table is in a loading state\n */\n @Prop() loading: boolean = false;\n\n /**\n * Pagination configuration object\n */\n @Prop() pagination: DatatablePagination = {\n page: 1,\n perpage: 10,\n total: 0,\n };\n\n /**\n * Array of selected items (for multiselect)\n */\n @Prop() selected: any[] = [];\n\n /**\n * Enable row selection with checkboxes\n */\n @Prop() canSelect: boolean = false;\n\n /**\n * Enable horizontal lines between rows\n */\n @Prop() horizontalLines: boolean = true;\n\n /**\n * Enable striped row styling\n */\n @Prop() striped: boolean = false;\n\n /**\n * Fixed header height (e.g., \"400px\" or 400)\n */\n @Prop() height?: string | number;\n\n /**\n * Show skeleton loader when loading\n */\n @Prop() skeletonLoader: boolean = true;\n\n /**\n * Enable hover effect on rows\n */\n @Prop() hover: boolean = true;\n\n /**\n * Per page options for pagination\n */\n @Prop() perPageOptions: number[] = [10, 25, 50, 100];\n\n /**\n * Emitted when a row is clicked\n */\n @Event() rowClick: EventEmitter<any>;\n\n /**\n * Emitted when row selection changes\n */\n @Event() xplorSelectionChange: EventEmitter<any[]>;\n\n /**\n * Emitted when pagination changes\n */\n @Event() paginationChange: EventEmitter<DatatablePagination>;\n\n /**\n * Emitted when sorting changes\n */\n @Event() sortChange: EventEmitter<{ column: string; direction: 'asc' | 'desc' | null }>;\n\n @State() sortBy: string | null = null;\n @State() sortDirection: 'asc' | 'desc' | null = null;\n @State() internalSelected: Set<any> = new Set();\n @State() allSelected: boolean = false;\n\n componentWillLoad() {\n this.internalSelected = new Set(this.selected);\n }\n\n @Watch('selected')\n watchSelected(newSelected: any[]) {\n this.internalSelected = new Set(newSelected);\n this.updateAllSelectedState();\n }\n\n @Watch('items')\n watchItems() {\n this.updateAllSelectedState();\n }\n\n private updateAllSelectedState() {\n if (this.items.length === 0) {\n this.allSelected = false;\n return;\n }\n this.allSelected = this.items.every(item => this.internalSelected.has(item));\n }\n\n private handleSort = (column: DatatableColumn) => {\n if (column.sortable === false) return;\n\n if (this.sortBy === column.value) {\n // Cycle through: asc -> desc -> null\n if (this.sortDirection === 'asc') {\n this.sortDirection = 'desc';\n } else if (this.sortDirection === 'desc') {\n this.sortDirection = null;\n this.sortBy = null;\n }\n } else {\n this.sortBy = column.value;\n this.sortDirection = 'asc';\n }\n\n this.sortChange.emit({\n column: this.sortBy,\n direction: this.sortDirection,\n });\n };\n\n private handleSelectAll = (e: Event) => {\n const target = e.target as HTMLInputElement;\n const checked = target.checked;\n\n if (checked) {\n this.items.forEach(item => this.internalSelected.add(item));\n } else {\n this.internalSelected.clear();\n }\n\n this.allSelected = checked;\n this.internalSelected = new Set(this.internalSelected);\n this.xplorSelectionChange.emit(Array.from(this.internalSelected));\n };\n\n private handleSelectOne = (e: Event, item: any) => {\n const target = e.target as HTMLInputElement;\n const checked = target.checked;\n\n if (checked) {\n this.internalSelected.add(item);\n } else {\n this.internalSelected.delete(item);\n }\n\n this.internalSelected = new Set(this.internalSelected);\n this.updateAllSelectedState();\n this.xplorSelectionChange.emit(Array.from(this.internalSelected));\n };\n\n private handleRowClick = (item: any, e: MouseEvent) => {\n // Don't trigger row click if clicking on checkbox or interactive elements\n const target = e.target as HTMLElement;\n if (target.tagName === 'INPUT' || target.closest('input')) {\n return;\n }\n\n this.rowClick.emit(item);\n };\n\n private handlePageChange = (newPage: number) => {\n const updatedPagination = {\n ...this.pagination,\n page: newPage,\n };\n this.paginationChange.emit(updatedPagination);\n };\n\n private handlePerPageChange = (e: Event) => {\n const target = e.target as HTMLSelectElement;\n const perpage = parseInt(target.value, 10);\n if (!isNaN(perpage)) {\n const updatedPagination = {\n ...this.pagination,\n page: 1, // Reset to first page\n perpage,\n };\n this.paginationChange.emit(updatedPagination);\n }\n };\n\n private getSortIcon(column: DatatableColumn) {\n if (this.sortBy !== column.value) {\n return (\n <svg class=\"sort-icon\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M8 3L11 6H5L8 3Z\" fill=\"currentColor\" opacity=\"0.3\" />\n <path d=\"M8 13L5 10H11L8 13Z\" fill=\"currentColor\" opacity=\"0.3\" />\n </svg>\n );\n }\n\n if (this.sortDirection === 'asc') {\n return (\n <svg class=\"sort-icon active\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M8 3L11 6H5L8 3Z\" fill=\"currentColor\" />\n <path d=\"M8 13L5 10H11L8 13Z\" fill=\"currentColor\" opacity=\"0.3\" />\n </svg>\n );\n }\n\n return (\n <svg class=\"sort-icon active\" width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M8 3L11 6H5L8 3Z\" fill=\"currentColor\" opacity=\"0.3\" />\n <path d=\"M8 13L5 10H11L8 13Z\" fill=\"currentColor\" />\n </svg>\n );\n };\n\n private renderSkeletonLoader() {\n return (\n <tbody class=\"skeleton-loader\">\n {Array.from({ length: this.pagination.perpage }).map(() => (\n <tr>\n {this.canSelect && (\n <td>\n <div class=\"skeleton skeleton-checkbox\"></div>\n </td>\n )}\n {this.headers.map(() => (\n <td>\n <div class=\"skeleton skeleton-text\"></div>\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n );\n }\n\n private renderPagination() {\n const totalPages = Math.ceil(this.pagination.total / this.pagination.perpage);\n const currentPage = this.pagination.page;\n const start = (currentPage - 1) * this.pagination.perpage + 1;\n const end = Math.min(currentPage * this.pagination.perpage, this.pagination.total);\n\n return (\n <div class=\"datatable-footer\">\n <div class=\"footer-info\">\n {this.pagination.total > 0 ? (\n <span>\n Showing {start} to {end} of {this.pagination.total} entries\n </span>\n ) : (\n <span>No entries</span>\n )}\n </div>\n\n <div class=\"footer-controls\">\n <div class=\"per-page-selector\">\n <label>\n Rows per page:\n <select onInput={this.handlePerPageChange}>\n {this.perPageOptions.map(option => (\n <option value={option} selected={option === this.pagination.perpage}>{option}</option>\n ))}\n </select>\n </label>\n </div>\n\n <div class=\"pagination-controls\">\n <button\n class=\"pagination-btn\"\n disabled={currentPage === 1}\n onClick={() => this.handlePageChange(1)}\n aria-label=\"First page\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M11 12L7 8L11 4M5 4V12\" stroke=\"currentColor\" stroke-width=\"1.5\" />\n </svg>\n </button>\n\n <button\n class=\"pagination-btn\"\n disabled={currentPage === 1}\n onClick={() => this.handlePageChange(currentPage - 1)}\n aria-label=\"Previous page\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M10 12L6 8L10 4\" stroke=\"currentColor\" stroke-width=\"1.5\" />\n </svg>\n </button>\n\n <span class=\"page-info\">\n Page {currentPage} of {totalPages || 1}\n </span>\n\n <button\n class=\"pagination-btn\"\n disabled={currentPage >= totalPages}\n onClick={() => this.handlePageChange(currentPage + 1)}\n aria-label=\"Next page\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M6 4L10 8L6 12\" stroke=\"currentColor\" stroke-width=\"1.5\" />\n </svg>\n </button>\n\n <button\n class=\"pagination-btn\"\n disabled={currentPage >= totalPages}\n onClick={() => this.handlePageChange(totalPages)}\n aria-label=\"Last page\"\n >\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\n <path d=\"M5 4L9 8L5 12M11 4V12\" stroke=\"currentColor\" stroke-width=\"1.5\" />\n </svg>\n </button>\n </div>\n </div>\n </div>\n );\n }\n\n render() {\n const tableHeight = typeof this.height === 'number' ? `${this.height}px` : this.height;\n const hasHeight = !!this.height;\n\n return (\n <Host class=\"xplor-datatable\">\n <div class=\"datatable-container\">\n <div\n class={{\n 'table-wrapper': true,\n 'has-height': hasHeight,\n 'horizontal-lines': this.horizontalLines,\n 'striped': this.striped,\n 'is-empty': this.items.length === 0,\n }}\n style={hasHeight ? { height: tableHeight } : {}}\n >\n <table class={{ 'hover': this.hover }}>\n <thead>\n <tr>\n {this.canSelect && (\n <th class=\"select-column\">\n <label class=\"checkbox-label\">\n <input\n type=\"checkbox\"\n checked={this.allSelected}\n indeterminate={\n this.internalSelected.size > 0 &&\n this.internalSelected.size < this.items.length\n }\n onChange={this.handleSelectAll}\n aria-label=\"Select all rows\"\n />\n </label>\n </th>\n )}\n {this.headers.map(header => (\n <th\n class={{\n sortable: header.sortable !== false,\n sorted: this.sortBy === header.value,\n fixed: header.fixed,\n [`align-${header.align || 'left'}`]: true,\n }}\n style={header.width ? { width: typeof header.width === 'number' ? `${header.width}px` : header.width } : {}}\n onClick={() => header.sortable !== false && this.handleSort(header)}\n aria-sort={\n header.sortable !== false && this.sortBy === header.value\n ? this.sortDirection === 'asc'\n ? 'ascending'\n : this.sortDirection === 'desc'\n ? 'descending'\n : 'none'\n : undefined\n }\n >\n <div class=\"header-content\">\n <span>{header.text}</span>\n {header.sortable !== false && this.getSortIcon(header)}\n </div>\n </th>\n ))}\n </tr>\n </thead>\n\n {this.loading && this.skeletonLoader ? (\n this.renderSkeletonLoader()\n ) : (\n <tbody>\n {this.items.length === 0 ? (\n <tr class=\"empty-row\">\n <td colSpan={this.headers.length + (this.canSelect ? 1 : 0)}>\n <div class=\"empty-state\">\n <p>No data available</p>\n </div>\n </td>\n </tr>\n ) : (\n this.items.map(item => {\n const isSelected = this.internalSelected.has(item);\n return (\n <tr\n class={{\n selected: isSelected,\n clickable: true,\n }}\n onClick={(e) => this.handleRowClick(item, e)}\n aria-selected={this.canSelect ? isSelected ? 'true' : 'false' : undefined}\n >\n {this.canSelect && (\n <td class=\"select-column\">\n <label class=\"checkbox-label\">\n <input\n type=\"checkbox\"\n checked={isSelected}\n onChange={(e) => this.handleSelectOne(e, item)}\n />\n </label>\n </td>\n )}\n {this.headers.map(header => (\n <td class={`align-${header.align || 'left'}`}>\n <slot name={`item.${header.value}`}>\n {item[header.value]}\n </slot>\n </td>\n ))}\n </tr>\n );\n })\n )}\n </tbody>\n )}\n </table>\n </div>\n\n {this.pagination && this.pagination.total > 0 && this.renderPagination()}\n </div>\n </Host>\n );\n }\n}\n",":host {\n display: block;\n width: 100%;\n}\n\n.date-picker {\n position: relative;\n width: 100%;\n\n &--disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n &__label {\n display: block;\n font-size: 0.875rem;\n color: rgba(0, 0, 0, 0.6);\n margin-bottom: 0.25rem;\n }\n\n &__required {\n color: #d32f2f;\n margin-left: 0.25rem;\n }\n\n &__field {\n position: relative;\n display: flex;\n align-items: center;\n border: 1px solid rgba(0, 0, 0, 0.23);\n border-radius: 1rem;\n transition: border-color 0.2s ease;\n background: white;\n\n &:focus-within {\n border-color: #008480;\n border-width: 2px;\n\n .date-picker__input {\n padding: calc(0.875rem - 1px) calc(1rem - 1px);\n }\n }\n }\n\n &--error &__field {\n border-color: #d32f2f;\n }\n\n &__input {\n flex: 1;\n width: 100%;\n padding: 0.875rem 1rem;\n font-size: 1rem;\n font-family: inherit;\n border: none;\n border-radius: 1rem;\n outline: none;\n background: transparent;\n\n &::placeholder {\n color: rgba(0, 0, 0, 0.38);\n }\n\n &:disabled {\n cursor: not-allowed;\n }\n }\n\n &__actions {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n padding-right: 0.5rem;\n flex-shrink: 0;\n }\n\n &__clear {\n background: none;\n border: none;\n font-size: 1.25rem;\n cursor: pointer;\n padding: 0;\n width: 1.5rem;\n height: 1.5rem;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #757575;\n border-radius: 50%;\n transition: background-color 0.2s;\n\n &:hover {\n background-color: #f5f5f5;\n color: #212121;\n }\n }\n\n &__icon-btn {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.25rem;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #757575;\n border-radius: 50%;\n transition: background-color 0.2s;\n\n &:hover:not(:disabled) {\n background-color: #f5f5f5;\n color: #212121;\n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n }\n }\n\n &__icon-svg {\n display: block;\n }\n\n &__text-display {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n padding: 0.5rem;\n border-radius: 4px;\n color: #008480;\n font-size: 1rem;\n transition: background-color 0.2s;\n\n &:hover {\n background-color: rgba(0, 132, 128, 0.08);\n }\n }\n\n &__text-value {\n text-decoration: underline;\n }\n\n &__dropdown {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n z-index: 1000;\n background-color: #fff;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n\n &--top {\n top: auto;\n bottom: calc(100% + 4px);\n }\n }\n\n &__details {\n min-height: 1.25rem;\n padding: 0 1rem;\n font-size: 0.75rem;\n }\n\n &__error-message {\n color: #d32f2f;\n }\n}\n","import { Component, Host, h, Prop, State, Event, EventEmitter, Element, Listen } from '@stencil/core';\n\nlet datePickerIdCounter = 0;\n\n@Component({\n tag: 'xplor-date-picker',\n styleUrl: 'xplor-date-picker.scss',\n scoped: true,\n})\nexport class XplorDatePicker {\n @Element() el: HTMLElement;\n\n /** Selected date in YYYY-MM-DD format */\n @Prop({ mutable: true }) value: string = '';\n\n @Prop() label: string = '';\n @Prop() placeholder: string = 'Select date';\n\n /** 'date' or 'month' */\n @Prop() type: 'date' | 'month' = 'date';\n\n /** For month type: select start or end of month */\n @Prop() monthType: 'start' | 'end' = 'start';\n\n /** 'input' shows text input, 'text' shows clickable text */\n @Prop() display: 'input' | 'text' = 'input';\n\n /** Date display format: 'short' (DD/MM/YYYY), 'long' (1 Jan 2025), 'iso' (YYYY-MM-DD) */\n @Prop() dateFormat: 'short' | 'long' | 'iso' = 'short';\n\n @Prop() min: string = '';\n @Prop() max: string = '';\n @Prop() readonly: boolean = false;\n @Prop() disabled: boolean = false;\n @Prop() clearable: boolean = false;\n @Prop() closeOnSelect: boolean = true;\n @Prop() bgColor: string = 'white';\n @Prop() color: string = '#008480';\n @Prop() startWeekOnSunday: boolean = true;\n @Prop() error: string = '';\n @Prop() hideDetails: boolean | 'auto' = 'auto';\n @Prop() required: boolean = false;\n\n @State() isOpen: boolean = false;\n @State() inputText: string = '';\n @State() dropdownPosition: 'bottom' | 'top' = 'bottom';\n\n private inputId = `xplor-date-picker-${++datePickerIdCounter}`;\n private labelId = `${this.inputId}-label`;\n private errorId = `${this.inputId}-error`;\n\n @Event() dateChange: EventEmitter<string>;\n @Event() xplorFocus: EventEmitter<FocusEvent>;\n @Event() xplorBlur: EventEmitter<FocusEvent>;\n @Event() xplorClear: EventEmitter<void>;\n\n componentWillLoad() {\n if (this.value) {\n this.inputText = this.formatDateForDisplay(this.value);\n }\n }\n\n @Listen('click', { target: 'document' })\n handleDocumentClick(event: MouseEvent) {\n const target = event.target as Node;\n if (!this.el.contains(target)) {\n this.isOpen = false;\n }\n }\n\n /** Parse YYYY-MM-DD safely without UTC shift */\n private parseISODate(iso: string): Date | null {\n if (!iso) return null;\n const d = new Date(iso + 'T00:00:00');\n return isNaN(d.getTime()) ? null : d;\n }\n\n private formatDateForDisplay(iso: string): string {\n const date = this.parseISODate(iso);\n if (!date) return iso;\n\n if (this.type === 'month') {\n return new Intl.DateTimeFormat('en-AU', { month: 'long', year: 'numeric' }).format(date);\n }\n\n switch (this.dateFormat) {\n case 'long':\n return new Intl.DateTimeFormat('en-AU', { day: 'numeric', month: 'short', year: 'numeric' }).format(date);\n case 'iso':\n return iso;\n case 'short':\n default:\n return new Intl.DateTimeFormat('en-AU', { day: '2-digit', month: '2-digit', year: 'numeric' }).format(date);\n }\n }\n\n private toISO(date: Date): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n }\n\n /** Parse user-typed text into YYYY-MM-DD */\n private parseInputText(text: string): string | null {\n const trimmed = text.trim();\n if (!trimmed) return null;\n\n // Try DD/MM/YYYY\n const slashMatch = trimmed.match(/^(\\d{1,2})[/\\-.](\\d{1,2})[/\\-.](\\d{4})$/);\n if (slashMatch) {\n const day = parseInt(slashMatch[1], 10);\n const month = parseInt(slashMatch[2], 10);\n const year = parseInt(slashMatch[3], 10);\n const d = new Date(year, month - 1, day);\n if (d.getFullYear() === year && d.getMonth() === month - 1 && d.getDate() === day) {\n return this.toISO(d);\n }\n }\n\n // Try YYYY-MM-DD\n const isoMatch = trimmed.match(/^(\\d{4})-(\\d{1,2})-(\\d{1,2})$/);\n if (isoMatch) {\n const year = parseInt(isoMatch[1], 10);\n const month = parseInt(isoMatch[2], 10);\n const day = parseInt(isoMatch[3], 10);\n const d = new Date(year, month - 1, day);\n if (d.getFullYear() === year && d.getMonth() === month - 1 && d.getDate() === day) {\n return this.toISO(d);\n }\n }\n\n // Try natural string via Date.parse\n const d = new Date(trimmed);\n if (!isNaN(d.getTime())) {\n return this.toISO(d);\n }\n\n return null;\n }\n\n private isDateInRange(iso: string): boolean {\n if (!iso) return true;\n if (this.min && iso < this.min) return false;\n if (this.max && iso > this.max) return false;\n return true;\n }\n\n private updateDropdownPosition() {\n const rect = this.el.getBoundingClientRect();\n const spaceBelow = window.innerHeight - rect.bottom;\n this.dropdownPosition = spaceBelow < 350 ? 'top' : 'bottom';\n }\n\n private toggleDropdown = () => {\n if (this.disabled || this.readonly) return;\n this.updateDropdownPosition();\n this.isOpen = !this.isOpen;\n };\n\n private handleInputFocus = (event: FocusEvent) => {\n this.xplorFocus.emit(event);\n };\n\n private handleInputBlur = (event: FocusEvent) => {\n this.xplorBlur.emit(event);\n // Try to parse typed text\n const parsed = this.parseInputText(this.inputText);\n if (parsed && this.isDateInRange(parsed)) {\n this.value = parsed;\n this.inputText = this.formatDateForDisplay(parsed);\n this.dateChange.emit(parsed);\n } else if (this.value) {\n // Revert to current value display\n this.inputText = this.formatDateForDisplay(this.value);\n } else {\n this.inputText = '';\n }\n };\n\n private handleInputChange = (event: Event) => {\n const input = event.target as HTMLInputElement;\n this.inputText = input.value;\n };\n\n private handleDateSelected = (event: CustomEvent<string>) => {\n event.stopPropagation();\n const iso = event.detail;\n if (!this.isDateInRange(iso)) return;\n\n if (this.type === 'month') {\n const d = this.parseISODate(iso);\n if (d) {\n let finalDate: Date;\n if (this.monthType === 'end') {\n finalDate = new Date(d.getFullYear(), d.getMonth() + 1, 0);\n } else {\n finalDate = new Date(d.getFullYear(), d.getMonth(), 1);\n }\n const finalIso = this.toISO(finalDate);\n this.value = finalIso;\n this.inputText = this.formatDateForDisplay(finalIso);\n this.dateChange.emit(finalIso);\n }\n } else {\n this.value = iso;\n this.inputText = this.formatDateForDisplay(iso);\n this.dateChange.emit(iso);\n }\n\n if (this.closeOnSelect) {\n this.isOpen = false;\n }\n };\n\n private handleClear = (event: Event) => {\n event.stopPropagation();\n this.value = '';\n this.inputText = '';\n this.dateChange.emit('');\n this.xplorClear.emit();\n };\n\n private handleTextClick = () => {\n if (this.disabled || this.readonly) return;\n this.updateDropdownPosition();\n this.isOpen = !this.isOpen;\n };\n\n render() {\n const showDetails = this.hideDetails === false || (this.hideDetails === 'auto' && this.error);\n\n const calendarIcon = (\n <svg class=\"date-picker__icon-svg\" viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <rect x=\"3\" y=\"4\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect>\n <line x1=\"16\" y1=\"2\" x2=\"16\" y2=\"6\"></line>\n <line x1=\"8\" y1=\"2\" x2=\"8\" y2=\"6\"></line>\n <line x1=\"3\" y1=\"10\" x2=\"21\" y2=\"10\"></line>\n </svg>\n );\n\n return (\n <Host>\n <div class={{\n 'date-picker': true,\n 'date-picker--disabled': this.disabled,\n 'date-picker--error': !!this.error,\n 'date-picker--open': this.isOpen,\n }}>\n {this.label && (\n <label class=\"date-picker__label\" id={this.labelId} htmlFor={this.inputId}>\n {this.label}\n {this.required && <span class=\"date-picker__required\">*</span>}\n </label>\n )}\n\n {this.display === 'text' ? (\n <div\n class=\"date-picker__text-display\"\n onClick={this.handleTextClick}\n aria-expanded={this.isOpen ? 'true' : 'false'}\n aria-haspopup=\"dialog\"\n role=\"button\"\n tabIndex={0}\n >\n <span class=\"date-picker__text-value\">\n {this.value ? this.formatDateForDisplay(this.value) : this.placeholder}\n </span>\n {calendarIcon}\n </div>\n ) : (\n <div class=\"date-picker__field\">\n <input\n id={this.inputId}\n type=\"text\"\n class=\"date-picker__input\"\n value={this.inputText}\n placeholder={this.placeholder}\n disabled={this.disabled}\n readonly={this.readonly}\n onFocus={this.handleInputFocus}\n onBlur={this.handleInputBlur}\n onInput={this.handleInputChange}\n style={{ backgroundColor: this.bgColor }}\n aria-expanded={this.isOpen ? 'true' : 'false'}\n aria-haspopup=\"dialog\"\n aria-describedby={this.error ? this.errorId : undefined}\n aria-invalid={this.error ? 'true' : undefined}\n aria-required={this.required ? 'true' : undefined}\n />\n <div class=\"date-picker__actions\">\n {this.clearable && this.value && !this.disabled && !this.readonly && (\n <button type=\"button\" class=\"date-picker__clear\" onClick={this.handleClear} aria-label=\"Clear\">\n ×\n </button>\n )}\n <button type=\"button\" class=\"date-picker__icon-btn\" onClick={this.toggleDropdown} disabled={this.disabled} aria-label=\"Open calendar\">\n {calendarIcon}\n </button>\n </div>\n </div>\n )}\n\n {showDetails && (\n <div class=\"date-picker__details\">\n {this.error && <div class=\"date-picker__error-message\" id={this.errorId}>{this.error}</div>}\n </div>\n )}\n\n {this.isOpen && (\n <div class={{\n 'date-picker__dropdown': true,\n 'date-picker__dropdown--top': this.dropdownPosition === 'top',\n }}>\n <xplor-inline-date-picker\n selectedDate={this.value}\n min={this.min}\n max={this.max}\n readonly={this.readonly}\n color={this.color}\n startWeekOnSunday={this.startWeekOnSunday}\n onDateSelected={this.handleDateSelected}\n ></xplor-inline-date-picker>\n </div>\n )}\n </div>\n </Host>\n );\n }\n}\n","@use '../../styles/colours.scss' as colours;\n@use '../../styles/spacing.scss' as spacing;\n\n:host {\n display: block;\n}\n\n.drag-drop-zone {\n position: relative;\n padding-bottom: spacing.$spacing-40;\n}\n\n.drag-drop-input-hidden {\n display: none;\n}\n\n.drag-drop-card {\n background-color: colours.$gray-100;\n border-radius: 8px;\n border: 2px dashed colours.$secondary;\n min-height: 160px;\n padding: spacing.$spacing-16 spacing.$spacing-24 spacing.$spacing-32;\n text-align: center;\n transition: all 0.2s ease;\n cursor: default;\n\n &:hover:not(&--disabled) {\n border-color: colours.$secondary;\n background-color: colours.$gray-200;\n }\n\n &--dragover {\n border: 2px dashed colours.$secondary;\n background-color: colours.$gray-200;\n }\n\n &--disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n}\n\n.drag-drop-card__content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: spacing.$spacing-4;\n padding: spacing.$spacing-4 0 0;\n}\n\n.drag-drop-card__icon {\n color: colours.$secondary;\n width: 40px;\n height: 40px;\n}\n\n.drag-drop-card__title {\n color: colours.$black;\n font-family: Inter, sans-serif;\n font-size: 18px;\n font-weight: 700;\n line-height: 24px;\n letter-spacing: 0;\n margin: 0;\n}\n\n.drag-drop-card__accepts,\n.drag-drop-card__divider {\n color: colours.$black;\n font-family: Inter, sans-serif;\n font-size: 14px;\n font-weight: 400;\n line-height: 20px;\n margin: 0;\n}\n\n.drag-drop-card__action {\n position: absolute;\n left: 50%;\n bottom: 0;\n transform: translateX(-50%);\n}\n\n// File info section (shown after file is selected)\n.file-info {\n margin-top: spacing.$spacing-24;\n}\n\n.file-info__status {\n font-family: Inter, sans-serif;\n font-size: 14px;\n font-weight: 400;\n line-height: 20px;\n color: colours.$gray-700;\n margin: 0 0 spacing.$spacing-8 0;\n}\n\n.file-info__card {\n display: flex;\n align-items: flex-start;\n gap: spacing.$spacing-12;\n background-color: colours.$white;\n border: 1px solid colours.$gray-300;\n border-radius: 8px;\n padding: spacing.$spacing-12 spacing.$spacing-16;\n}\n\n.file-info__icon {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n border-radius: 8px;\n background-color: colours.$secondary-50;\n color: colours.$secondary;\n}\n\n.file-info__details {\n flex: 1;\n min-width: 0;\n}\n\n.file-info__name {\n font-family: Inter, sans-serif;\n font-size: 14px;\n font-weight: 600;\n line-height: 20px;\n color: colours.$black;\n margin: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.file-info__meta {\n font-family: Inter, sans-serif;\n font-size: 12px;\n font-weight: 400;\n line-height: 18px;\n color: colours.$secondary;\n margin: spacing.$spacing-4 0 0 0;\n}\n\n.file-info__progress-row {\n display: flex;\n align-items: center;\n gap: spacing.$spacing-8;\n margin-top: spacing.$spacing-8;\n}\n\n.file-info__progress-bar {\n flex: 1;\n height: 6px;\n background-color: colours.$gray-200;\n border-radius: 3px;\n overflow: hidden;\n}\n\n.file-info__progress-fill {\n height: 100%;\n background-color: colours.$secondary;\n border-radius: 3px;\n transition: width 0.3s ease;\n}\n\n.file-info__progress-text {\n font-family: Inter, sans-serif;\n font-size: 12px;\n font-weight: 400;\n line-height: 18px;\n color: colours.$gray-600;\n flex-shrink: 0;\n min-width: 32px;\n text-align: right;\n}\n\n.file-info__remove {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border-radius: 50%;\n border: none;\n background-color: colours.$gray-200;\n color: colours.$gray-600;\n cursor: pointer;\n padding: 0;\n transition: background-color 0.2s ease;\n\n &:hover {\n background-color: colours.$gray-300;\n color: colours.$gray-800;\n }\n}\n\n@media (max-width: 768px) {\n .drag-drop-card {\n min-height: 140px;\n }\n\n .drag-drop-card__title {\n font-size: 16px;\n line-height: 22px;\n }\n\n .drag-drop-card__accepts,\n .drag-drop-card__divider {\n font-size: 13px;\n line-height: 18px;\n }\n}\n","import { Component, Host, h, Prop, State, Event, EventEmitter, Method } from '@stencil/core';\n\nconst DEFAULT_ACCEPT_ALL = '*' + '/' + '*';\n\n@Component({\n tag: 'xplor-drag-and-drop-input',\n styleUrl: 'xplor-drag-and-drop-input.scss',\n scoped: true,\n})\nexport class XplorDragAndDropInput {\n /**\n * Disable the file upload\n */\n @Prop() disabled: boolean = false;\n\n /**\n * Accepted file types (e.g., 'image/png,.pdf')\n */\n @Prop() accepts: string = DEFAULT_ACCEPT_ALL;\n\n /**\n * Instruction text displayed in the drop zone\n */\n @Prop() label: string = 'Drag and drop your files here';\n\n /**\n * Browse button label text\n */\n @Prop() browseLabel: string = 'Browse Files';\n\n /**\n * Accessible label for the drop zone area\n */\n @Prop() ariaLabel: string;\n\n /**\n * Upload progress percentage (0-100). Set to -1 or leave undefined to hide the progress bar.\n */\n @Prop() progress: number = -1;\n\n @State() dragover: boolean = false;\n @State() currentFile: File | null = null;\n\n /**\n * Emitted when a file is selected via drop or click\n */\n @Event() fileSelect: EventEmitter<File>;\n\n /**\n * Emitted when the current file is cleared\n */\n @Event() fileClear: EventEmitter<void>;\n\n private fileInputEl: HTMLInputElement;\n\n /**\n * Clears the currently selected file\n */\n @Method()\n async clearCurrentFile() {\n this.currentFile = null;\n if (this.fileInputEl) {\n this.fileInputEl.value = '';\n }\n this.fileClear.emit();\n }\n\n private onDrop = (e: DragEvent) => {\n e.preventDefault();\n this.dragover = false;\n\n if (this.disabled) return;\n\n const file = e.dataTransfer?.files?.[0];\n if (file) {\n this.currentFile = file;\n this.fileSelect.emit(this.currentFile);\n }\n };\n\n private onDragOver = (e: DragEvent) => {\n e.preventDefault();\n if (!this.disabled) {\n this.dragover = true;\n }\n };\n\n private onDragEnter = (e: DragEvent) => {\n e.preventDefault();\n if (!this.disabled) {\n this.dragover = true;\n }\n };\n\n private onDragLeave = (e: DragEvent) => {\n e.preventDefault();\n this.dragover = false;\n };\n\n private onFileSelect = (e: Event) => {\n const input = e.target as HTMLInputElement;\n const file = input.files?.[0];\n if (file) {\n this.currentFile = file;\n this.fileSelect.emit(this.currentFile);\n }\n input.value = '';\n };\n\n private openFileDialog = () => {\n if (this.disabled) {\n return;\n }\n\n this.fileInputEl?.click();\n };\n\n private getAcceptsLabel = () => {\n const accepts = this.accepts?.trim();\n if (!accepts || accepts === DEFAULT_ACCEPT_ALL) {\n return '*';\n }\n\n return accepts;\n };\n\n private formatFileSize = (bytes: number): string => {\n if (bytes === 0) return '0 Bytes';\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];\n };\n\n private formatDate = (timestamp: number): string => {\n const date = new Date(timestamp);\n const day = date.getDate();\n const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n const month = months[date.getMonth()];\n const year = date.getFullYear();\n\n const suffix = (day === 1 || day === 21 || day === 31) ? 'st'\n : (day === 2 || day === 22) ? 'nd'\n : (day === 3 || day === 23) ? 'rd'\n : 'th';\n\n const hours = date.getHours();\n const minutes = date.getMinutes().toString().padStart(2, '0');\n const seconds = date.getSeconds().toString().padStart(2, '0');\n const ampm = hours >= 12 ? 'PM' : 'AM';\n const displayHours = hours % 12 || 12;\n\n return `${day}${suffix} ${month} ${year}, ${displayHours}:${minutes}:${seconds} ${ampm}`;\n };\n\n private showProgress = (): boolean => {\n return this.progress >= 0 && this.progress <= 100;\n };\n\n render() {\n const progressValue = Math.min(Math.max(this.progress, 0), 100);\n const dropZoneLabel = this.ariaLabel || `${this.label}. Accepted file types: ${this.getAcceptsLabel()}. Or use the ${this.browseLabel} button.`;\n\n return (\n <Host>\n <div class=\"drag-drop-zone\">\n <div\n class={{\n 'drag-drop-card': true,\n 'drag-drop-card--dragover': this.dragover,\n 'drag-drop-card--disabled': this.disabled,\n }}\n onDrop={this.onDrop}\n onDragOver={this.onDragOver}\n onDragEnter={this.onDragEnter}\n onDragLeave={this.onDragLeave}\n role=\"region\"\n aria-label={dropZoneLabel}\n >\n <div class=\"drag-drop-card__content\">\n <svg\n class=\"drag-drop-card__icon\"\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"40\"\n height=\"40\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4C9.11 4 6.6 5.64 5.35 8.04C2.34 8.36 0 10.91 0 14C0 17.31 2.69 20 6 20H19C21.76 20 24 17.76 24 15C24 12.36 21.95 10.22 19.35 10.04Z\"\n fill=\"currentColor\"\n opacity=\"0.3\"\n />\n <path\n d=\"M19.35 10.04C18.67 6.59 15.64 4 12 4C9.11 4 6.6 5.64 5.35 8.04C2.34 8.36 0 10.91 0 14C0 17.31 2.69 20 6 20H19C21.76 20 24 17.76 24 15C24 12.36 21.95 10.22 19.35 10.04ZM14 13V17H10V13H7L12 8L17 13H14Z\"\n fill=\"currentColor\"\n />\n </svg>\n <h3 class=\"drag-drop-card__title\">{this.label}</h3>\n <p class=\"drag-drop-card__accepts\">Accepted file types: {this.getAcceptsLabel()}</p>\n <p class=\"drag-drop-card__divider\">or</p>\n </div>\n </div>\n\n <div class=\"drag-drop-card__action\">\n <xplor-button\n text={this.browseLabel}\n type={this.disabled ? 'disabled' : 'secondary'}\n clickAction={this.openFileDialog}\n aria-label={this.browseLabel}\n ></xplor-button>\n </div>\n </div>\n\n {this.currentFile && (\n <div class=\"file-info\" aria-live=\"polite\">\n {this.showProgress() && (\n <p class=\"file-info__status\">\n Uploading {this.progress === 100 ? '1' : '0'} / 1\n </p>\n )}\n <div class=\"file-info__card\">\n <div class=\"file-info__icon\" aria-hidden=\"true\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M14 2H6C4.9 2 4 2.9 4 4V20C4 21.1 4.9 22 6 22H18C19.1 22 20 21.1 20 20V8L14 2ZM6 20V4H13V9H18V20H6Z\" />\n </svg>\n </div>\n <div class=\"file-info__details\">\n <p class=\"file-info__name\">{this.currentFile.name}</p>\n <p class=\"file-info__meta\">\n {this.formatFileSize(this.currentFile.size)}\n {this.currentFile.lastModified\n ? ` | Last modified: ${this.formatDate(this.currentFile.lastModified)}`\n : ''}\n </p>\n {this.showProgress() && (\n <div class=\"file-info__progress-row\">\n <div\n class=\"file-info__progress-bar\"\n role=\"progressbar\"\n aria-valuenow={progressValue}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-label={`Upload progress: ${Math.round(progressValue)}%`}\n >\n <div\n class=\"file-info__progress-fill\"\n style={{ width: `${progressValue}%` }}\n ></div>\n </div>\n <span class=\"file-info__progress-text\" aria-hidden=\"true\">{Math.round(this.progress)}%</span>\n </div>\n )}\n </div>\n <button\n class=\"file-info__remove\"\n onClick={() => this.clearCurrentFile()}\n aria-label={`Remove file ${this.currentFile.name}`}\n >\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"currentColor\" aria-hidden=\"true\">\n <path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12Z\" />\n </svg>\n </button>\n </div>\n </div>\n )}\n\n <input\n id=\"drag-drop-file-select\"\n type=\"file\"\n disabled={this.disabled}\n accept={this.accepts}\n class=\"drag-drop-input-hidden\"\n ref={(el) => (this.fileInputEl = el)}\n onChange={this.onFileSelect}\n aria-label={`${this.browseLabel} - ${this.label}`}\n tabindex={-1}\n />\n </Host>\n );\n }\n}\n",":host {\n display: block;\n}\n\n.xplor-dropdown {\n display: block;\n cursor: pointer;\n margin-right: 10px;\n border: 1px solid;\n border-radius: 1rem;\n font-size: 14px;\n font-weight: 500;\n -webkit-box-pack: center;\n letter-spacing: 0.75px;\n height: 45px;\n text-align: center;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n}","import { Component, Host, h, Prop } from '@stencil/core';\n\n@Component({\n tag: 'xplor-dropdown',\n styleUrl: 'xplor-dropdown.scss',\n shadow: true,\n})\nexport class XplorDropdown {\n @Prop() options: string[];\n @Prop() selected: string;\n @Prop() handleChange: (event: Event) => void;\n\n render() {\n return (\n <Host>\n <select class=\"xplor-dropdown\" onChange={this.handleChange}>\n {this.options.map((option) => (\n <option value={option} selected={this.selected === option}>\n {option}\n </option>\n ))}\n </select>\n </Host>\n );\n }\n}\n",":host {\n display: block;\n}\n\n.expansion-panel {\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n overflow: hidden;\n\n &+& {\n margin-top: -1px;\n }\n\n &--disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n}\n\n.expansion-panel__header {\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 1rem 1.5rem;\n background-color: #f5f5f5;\n border: none;\n cursor: pointer;\n text-align: left;\n transition: background-color 0.2s;\n font-family: inherit;\n font-size: inherit;\n\n &:hover:not(:disabled) {\n background-color: #eeeeee;\n }\n\n &:focus {\n outline: 2px solid #1976d2;\n outline-offset: -2px;\n }\n\n &:disabled {\n cursor: not-allowed;\n }\n}\n\n.expansion-panel__header-content {\n flex: 1;\n font-weight: 500;\n}\n\n.expansion-panel__icon {\n display: inline-block;\n transition: transform 0.3s ease;\n font-size: 0.75rem;\n margin-left: 0.5rem;\n\n &--open {\n transform: rotate(180deg);\n }\n}\n\n.expansion-panel__content {\n overflow: hidden;\n transition: max-height 0.3s ease;\n background-color: #fff;\n}\n\n.expansion-panel__content-inner {\n padding: 1rem 1.5rem;\n}","import { Component, Host, h, Prop, State, Event, EventEmitter, Element } from '@stencil/core';\n\nlet nextId = 0;\n\n@Component({\n tag: 'xplor-expansion-panel',\n styleUrl: 'xplor-expansion-panel.scss',\n scoped: true,\n})\nexport class XplorExpansionPanel {\n @Element() el: HTMLElement;\n\n @Prop() disabled: boolean = false;\n @Prop({ mutable: true }) open: boolean = false;\n\n @State() panelId: string;\n @State() contentHeight: number = 0;\n\n @Event() xplorPanelToggle: EventEmitter<{ id: string; isOpen: boolean }>;\n\n private contentEl: HTMLDivElement;\n\n componentWillLoad() {\n this.panelId = `panel-${nextId++}`;\n }\n\n componentDidLoad() {\n this.updateContentHeight();\n }\n\n private updateContentHeight() {\n if (this.contentEl) {\n this.contentHeight = this.contentEl.scrollHeight;\n }\n }\n\n private handleToggle = () => {\n if (this.disabled) return;\n\n this.open = !this.open;\n this.xplorPanelToggle.emit({ id: this.panelId, isOpen: this.open });\n\n // Update height after toggle\n setTimeout(() => this.updateContentHeight(), 0);\n };\n\n render() {\n return (\n <Host>\n <div\n class={{\n 'expansion-panel': true,\n 'expansion-panel--open': this.open,\n 'expansion-panel--disabled': this.disabled,\n }}\n >\n <button\n class=\"expansion-panel__header\"\n onClick={this.handleToggle}\n disabled={this.disabled}\n aria-expanded={this.open ? 'true' : 'false'}\n aria-controls={`${this.panelId}-content`}\n type=\"button\"\n >\n <div class=\"expansion-panel__header-content\">\n <slot name=\"header\" />\n </div>\n <span\n class={{\n 'expansion-panel__icon': true,\n 'expansion-panel__icon--open': this.open,\n }}\n >\n ▼\n </span>\n </button>\n <div\n class=\"expansion-panel__content\"\n id={`${this.panelId}-content`}\n role=\"region\"\n aria-labelledby={this.panelId}\n style={{\n maxHeight: this.open ? `${this.contentHeight}px` : '0',\n }}\n >\n <div\n class=\"expansion-panel__content-inner\"\n ref={(el) => (this.contentEl = el)}\n >\n <slot />\n </div>\n </div>\n </div>\n </Host>\n );\n }\n}\n",":host {\n display: block;\n}\n\n.expansion-panels {\n display: flex;\n flex-direction: column;\n gap: 0;\n}","import { Component, Host, h, Prop, State, Listen } from '@stencil/core';\n\n@Component({\n tag: 'xplor-expansion-panels',\n styleUrl: 'xplor-expansion-panels.scss',\n scoped: true,\n})\nexport class XplorExpansionPanels {\n @Prop({ mutable: true }) value: string | string[] = [];\n @Prop() multiple: boolean = false;\n @Prop() accordion: boolean = true; // accordion mode (only one open at a time when not multiple)\n\n @State() openPanels: Set<string> = new Set();\n\n componentWillLoad() {\n if (Array.isArray(this.value)) {\n this.openPanels = new Set(this.value);\n } else if (this.value) {\n this.openPanels = new Set([this.value]);\n }\n }\n\n @Listen('xplorPanelToggle')\n handlePanelToggle(event: CustomEvent<{ id: string; isOpen: boolean }>) {\n event.stopPropagation();\n const { id, isOpen } = event.detail;\n\n if (isOpen) {\n if (this.multiple) {\n this.openPanels = new Set([...this.openPanels, id]);\n } else {\n this.openPanels = new Set([id]);\n }\n } else {\n const newPanels = new Set(this.openPanels);\n newPanels.delete(id);\n this.openPanels = newPanels;\n }\n\n this.value = this.multiple ? Array.from(this.openPanels) : Array.from(this.openPanels)[0] || '';\n }\n\n render() {\n return (\n <Host>\n <div class=\"expansion-panels\" aria-label=\"Accordion\">\n <slot />\n </div>\n </Host>\n );\n }\n}\n",":host {\n display: block;\n}\n\n.file-upload {\n width: 100%;\n}\n\n.file-upload__dropzone {\n border: 2px dashed #bdbdbd;\n border-radius: 8px;\n padding: 2rem;\n text-align: center;\n transition: all 0.2s ease;\n background-color: #fafafa;\n cursor: pointer;\n position: relative;\n\n &:hover:not(&--disabled) {\n border-color: #1976d2;\n background-color: #f0f7ff;\n }\n\n &--dragging {\n border-color: #1976d2;\n background-color: #e3f2fd;\n transform: scale(1.02);\n }\n\n &--disabled {\n opacity: 0.6;\n cursor: not-allowed;\n background-color: #f5f5f5;\n }\n}\n\n.file-upload__input {\n position: absolute;\n width: 1px;\n height: 1px;\n opacity: 0;\n pointer-events: none;\n}\n\n.file-upload__content {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 0.75rem;\n}\n\n.file-upload__icon {\n color: #757575;\n}\n\n.file-upload__text {\n font-size: 1rem;\n color: #424242;\n margin: 0;\n}\n\n.file-upload__button {\n background: none;\n border: none;\n color: #1976d2;\n text-decoration: underline;\n cursor: pointer;\n font-family: inherit;\n font-size: inherit;\n padding: 0;\n transition: color 0.2s;\n\n &:hover:not(:disabled) {\n color: #1565c0;\n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.6;\n }\n}\n\n.file-upload__hint {\n font-size: 0.875rem;\n color: #757575;\n margin: 0;\n}\n\n.file-upload__error {\n margin-top: 0.5rem;\n padding: 0.75rem;\n background-color: #ffebee;\n color: #c62828;\n border-radius: 4px;\n font-size: 0.875rem;\n border-left: 4px solid #f44336;\n}\n\n.file-upload__files {\n margin-top: 1rem;\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.file-upload__file {\n display: flex;\n align-items: center;\n gap: 1rem;\n padding: 0.75rem;\n background-color: #f5f5f5;\n border-radius: 4px;\n border: 1px solid #e0e0e0;\n}\n\n.file-upload__preview {\n width: 48px;\n height: 48px;\n object-fit: cover;\n border-radius: 4px;\n flex-shrink: 0;\n}\n\n.file-upload__file-info {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n min-width: 0;\n}\n\n.file-upload__file-name {\n font-size: 0.875rem;\n font-weight: 500;\n color: #212121;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.file-upload__file-size {\n font-size: 0.75rem;\n color: #757575;\n}\n\n.file-upload__remove {\n background: none;\n border: none;\n font-size: 1.5rem;\n line-height: 1;\n cursor: pointer;\n padding: 0;\n width: 2rem;\n height: 2rem;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #757575;\n border-radius: 4px;\n transition: all 0.2s;\n flex-shrink: 0;\n\n &:hover {\n background-color: #ffebee;\n color: #f44336;\n }\n\n &:focus {\n outline: 2px solid #1976d2;\n outline-offset: 2px;\n }\n}","import { Component, Host, h, Prop, State, Event, EventEmitter } from '@stencil/core';\n\nconst DEFAULT_ACCEPT_ALL = '*' + '/' + '*';\n\nexport interface UploadedFile {\n file: File;\n id: string;\n name: string;\n size: number;\n type: string;\n dataUrl?: string;\n}\n\n@Component({\n tag: 'xplor-file-upload',\n styleUrl: 'xplor-file-upload.scss',\n scoped: true,\n})\nexport class XplorFileUpload {\n /**\n * Accepted file types (e.g., 'image/png', '.pdf', 'image/star'). Default accepts all types.\n */\n @Prop() accepts: string = DEFAULT_ACCEPT_ALL;\n\n /**\n * Maximum file size in bytes\n */\n @Prop() maxSize: number = 10 * 1024 * 1024; // 10MB default\n\n /**\n * Allow multiple file selection\n */\n @Prop() multiple: boolean = false;\n\n /**\n * Disable the file upload\n */\n @Prop() disabled: boolean = false;\n\n /**\n * Show image preview for uploaded images\n */\n @Prop() showPreview: boolean = true;\n\n /**\n * Label text for the upload button\n */\n @Prop() label: string = 'Upload Files';\n\n @State() files: UploadedFile[] = [];\n @State() isDragging: boolean = false;\n @State() error: string = '';\n\n @Event() xplorFileAdd: EventEmitter<UploadedFile[]>;\n @Event() xplorFileRemove: EventEmitter<UploadedFile>;\n @Event() xplorError: EventEmitter<string>;\n\n private fileInputEl: HTMLInputElement;\n\n private handleFileSelect = (event: Event) => {\n const input = event.target as HTMLInputElement;\n if (input.files) {\n this.processFiles(Array.from(input.files));\n }\n };\n\n private handleDragOver = (event: DragEvent) => {\n event.preventDefault();\n if (!this.disabled) {\n this.isDragging = true;\n }\n };\n\n private handleDragLeave = (event: DragEvent) => {\n event.preventDefault();\n this.isDragging = false;\n };\n\n private handleDrop = (event: DragEvent) => {\n event.preventDefault();\n this.isDragging = false;\n\n if (this.disabled) return;\n\n if (event.dataTransfer?.files) {\n this.processFiles(Array.from(event.dataTransfer.files));\n }\n };\n\n private processFiles(fileList: File[]) {\n this.error = '';\n const validFiles: UploadedFile[] = [];\n\n for (const file of fileList) {\n // Validate file size\n if (file.size > this.maxSize) {\n const maxSizeMB = (this.maxSize / (1024 * 1024)).toFixed(2);\n this.error = `File \"${file.name}\" exceeds maximum size of ${maxSizeMB}MB`;\n this.xplorError.emit(this.error);\n continue;\n }\n\n // Validate file type if specified\n if (this.accepts !== '*/*') {\n const acceptedTypes = this.accepts.split(',').map(t => t.trim());\n const fileExtension = `.${file.name.split('.').pop()}`;\n const isAccepted = acceptedTypes.some(type => {\n if (type.endsWith('/*')) {\n return file.type.startsWith(type.replace('/*', ''));\n }\n return type === file.type || type === fileExtension;\n });\n\n if (!isAccepted) {\n this.error = `File type \"${file.type}\" is not accepted`;\n this.xplorError.emit(this.error);\n continue;\n }\n }\n\n const uploadedFile: UploadedFile = {\n file,\n id: `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,\n name: file.name,\n size: file.size,\n type: file.type,\n };\n\n // Generate preview for images\n if (this.showPreview && file.type.startsWith('image/')) {\n const reader = new FileReader();\n reader.onload = (e) => {\n uploadedFile.dataUrl = e.target?.result as string;\n this.files = [...this.files];\n };\n reader.readAsDataURL(file);\n }\n\n validFiles.push(uploadedFile);\n }\n\n if (validFiles.length > 0) {\n if (this.multiple) {\n this.files = [...this.files, ...validFiles];\n } else {\n this.files = [validFiles[0]];\n }\n this.xplorFileAdd.emit(validFiles);\n }\n\n // Reset input\n if (this.fileInputEl) {\n this.fileInputEl.value = '';\n }\n }\n\n private handleRemoveFile = (fileToRemove: UploadedFile) => {\n this.files = this.files.filter(f => f.id !== fileToRemove.id);\n this.xplorFileRemove.emit(fileToRemove);\n };\n\n private handleButtonClick = () => {\n if (!this.disabled && this.fileInputEl) {\n this.fileInputEl.click();\n }\n };\n\n private formatFileSize(bytes: number): string {\n if (bytes === 0) return '0 Bytes';\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i];\n }\n\n render() {\n return (\n <Host>\n <div class=\"file-upload\">\n <div\n class={{\n 'file-upload__dropzone': true,\n 'file-upload__dropzone--dragging': this.isDragging,\n 'file-upload__dropzone--disabled': this.disabled,\n }}\n onDragOver={this.handleDragOver}\n onDragLeave={this.handleDragLeave}\n onDrop={this.handleDrop}\n aria-label={`Drop zone for file upload. ${this.accepts !== '*/*' ? `Accepts: ${this.accepts}.` : ''} Maximum size: ${this.formatFileSize(this.maxSize)}`}\n >\n <input\n ref={(el) => (this.fileInputEl = el)}\n type=\"file\"\n accept={this.accepts}\n multiple={this.multiple}\n disabled={this.disabled}\n onChange={this.handleFileSelect}\n class=\"file-upload__input\"\n />\n\n <div class=\"file-upload__content\">\n <svg class=\"file-upload__icon\" width=\"48\" height=\"48\" viewBox=\"0 0 24 24\" fill=\"none\">\n <path d=\"M12 15V3M12 3L8 7M12 3L16 7\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M2 17L2 19C2 20.1046 2.89543 21 4 21L20 21C21.1046 21 22 20.1046 22 19L22 17\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" />\n </svg>\n <p class=\"file-upload__text\">\n Drag & drop files here or{' '}\n <button\n type=\"button\"\n class=\"file-upload__button\"\n onClick={this.handleButtonClick}\n disabled={this.disabled}\n >\n {this.label}\n </button>\n </p>\n <p class=\"file-upload__hint\">\n Max size: {this.formatFileSize(this.maxSize)}\n {this.accepts !== '*/*' && ` • Accepts: ${this.accepts}`}\n </p>\n </div>\n </div>\n\n {this.error && (\n <div class=\"file-upload__error\" role=\"alert\">\n {this.error}\n </div>\n )}\n\n {this.files.length > 0 && (\n <div class=\"file-upload__files\">\n {this.files.map((file) => (\n <div key={file.id} class=\"file-upload__file\">\n {file.dataUrl && (\n <img src={file.dataUrl} alt={file.name} class=\"file-upload__preview\" />\n )}\n <div class=\"file-upload__file-info\">\n <span class=\"file-upload__file-name\" title={file.name}>\n {file.name}\n </span>\n <span class=\"file-upload__file-size\">\n {this.formatFileSize(file.size)}\n </span>\n </div>\n <button\n type=\"button\"\n class=\"file-upload__remove\"\n onClick={() => this.handleRemoveFile(file)}\n aria-label={`Remove ${file.name}`}\n >\n ×\n </button>\n </div>\n ))}\n </div>\n )}\n </div>\n </Host>\n );\n }\n}\n",":host {\n display: inline-block;\n}\n\n.xplor-inline-checkbox {\n display: inline-flex;\n align-items: center;\n gap: 0.5rem;\n cursor: pointer;\n user-select: none;\n\n &__input {\n width: 1.125rem;\n height: 1.125rem;\n cursor: pointer;\n margin: 0;\n flex-shrink: 0;\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.38;\n }\n }\n\n &__label {\n font-size: 1rem;\n color: rgba(0, 0, 0, 0.87);\n }\n\n &--disabled {\n cursor: not-allowed;\n\n .xplor-inline-checkbox__label {\n color: rgba(0, 0, 0, 0.38);\n }\n }\n}\n","import { Component, Host, h, Prop, Event, EventEmitter } from '@stencil/core';\n\n@Component({\n tag: 'xplor-inline-checkbox',\n styleUrl: 'xplor-inline-checkbox.scss',\n scoped: true,\n})\nexport class XplorInlineCheckbox {\n /**\n * Checked state\n */\n @Prop({ mutable: true }) checked: boolean = false;\n\n /**\n * Value (for use in forms)\n */\n @Prop() value: any;\n\n /**\n * Checkbox color\n */\n @Prop() color: string = '#008480';\n\n /**\n * Whether the checkbox is disabled\n */\n @Prop() disabled: boolean = false;\n\n /**\n * Whether the checkbox is indeterminate\n */\n @Prop() indeterminate: boolean = false;\n\n /**\n * Label text\n */\n @Prop() label: string = '';\n\n /**\n * Change event\n */\n @Event() xplorChange: EventEmitter<boolean>;\n\n private handleChange = (event: Event) => {\n const target = event.target as HTMLInputElement;\n this.checked = target.checked;\n this.xplorChange.emit(this.checked);\n };\n\n render() {\n const containerClasses = {\n 'xplor-inline-checkbox': true,\n 'xplor-inline-checkbox--disabled': this.disabled,\n 'xplor-inline-checkbox--checked': this.checked,\n };\n\n return (\n <Host>\n <label class={containerClasses}>\n <input\n type=\"checkbox\"\n class=\"xplor-inline-checkbox__input\"\n checked={this.checked}\n value={this.value}\n disabled={this.disabled}\n indeterminate={this.indeterminate}\n onChange={this.handleChange}\n style={{\n accentColor: this.color,\n }}\n />\n {this.label && <span class=\"xplor-inline-checkbox__label\">{this.label}</span>}\n <slot />\n </label>\n </Host>\n );\n }\n}\n",":host {\n display: inline-block;\n}\n\n.xplor-inline-date-picker {\n --picker-color: #008480;\n display: flex;\n border-radius: 1rem;\n background-color: white;\n box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),\n 0 8px 10px 1px rgba(0, 0, 0, 0.14),\n 0 3px 14px 2px rgba(0, 0, 0, 0.12);\n overflow: hidden;\n\n &__sidebar {\n background-color: var(--picker-color);\n color: white;\n padding: 1rem;\n min-width: 180px;\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n }\n\n &__sidebar-year {\n font-size: 0.875rem;\n font-weight: 700;\n }\n\n &__sidebar-day {\n font-size: 1.75rem;\n font-weight: 700;\n }\n\n &__sidebar-date {\n font-size: 1.75rem;\n font-weight: 700;\n }\n\n &__calendar {\n display: flex;\n flex-direction: column;\n width: 320px;\n padding: 1rem;\n }\n\n &__header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n margin-bottom: 1rem;\n padding: 0.5rem 0;\n }\n\n &__title {\n font-size: 1rem;\n font-weight: 700;\n color: rgba(0, 0, 0, 0.87);\n }\n\n &__arrow {\n width: 2rem;\n height: 2rem;\n border: none;\n background: transparent;\n font-size: 1.5rem;\n color: rgba(0, 0, 0, 0.54);\n cursor: pointer;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s ease;\n\n &:hover {\n background-color: rgba(0, 0, 0, 0.04);\n }\n\n &:active {\n background-color: rgba(0, 0, 0, 0.08);\n }\n }\n\n &__weekdays {\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n gap: 0.25rem;\n margin-bottom: 0.5rem;\n }\n\n &__weekday {\n text-align: center;\n font-size: 0.75rem;\n font-weight: 700;\n color: rgba(0, 0, 0, 0.6);\n padding: 0.5rem 0;\n }\n\n &__days {\n display: grid;\n grid-template-columns: repeat(7, 1fr);\n gap: 0.25rem;\n }\n\n &__day {\n aspect-ratio: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 0.875rem;\n font-weight: 500;\n border-radius: 50%;\n cursor: pointer;\n transition: background-color 0.2s ease;\n position: relative;\n\n &:not(&--empty):not(&--disabled):hover {\n background-color: rgba(0, 0, 0, 0.04);\n }\n\n &--empty {\n cursor: default;\n }\n\n &--today {\n color: var(--picker-color);\n font-weight: 700;\n\n &::before {\n content: '';\n position: absolute;\n inset: 0;\n border: 2px solid var(--picker-color);\n border-radius: 50%;\n }\n }\n\n &--selected {\n background-color: var(--picker-color);\n color: white;\n font-weight: 700;\n\n &:hover {\n background-color: var(--picker-color);\n opacity: 0.9;\n }\n\n &::before {\n display: none;\n }\n }\n\n &--disabled {\n color: rgba(0, 0, 0, 0.38);\n cursor: not-allowed;\n pointer-events: none;\n }\n }\n}\n\n// Compact variant (no sidebar)\n:host([compact]) {\n .xplor-inline-date-picker {\n &__sidebar {\n display: none;\n }\n\n &__calendar {\n width: 280px;\n }\n }\n}\n","import { Component, Host, h, Prop, Event, EventEmitter, State, Element, Listen } from '@stencil/core';\n\n@Component({\n tag: 'xplor-inline-date-picker',\n styleUrl: 'xplor-inline-date-picker.scss',\n scoped: true,\n})\nexport class XplorInlineDatePicker {\n @Element() el: HTMLElement;\n /**\n * Selected date (YYYY-MM-DD format)\n */\n @Prop({ mutable: true }) selectedDate: string = '';\n\n /**\n * Minimum selectable date (YYYY-MM-DD format)\n */\n @Prop() min: string = '';\n\n /**\n * Maximum selectable date (YYYY-MM-DD format)\n */\n @Prop() max: string = '';\n\n /**\n * Whether the date picker is readonly\n */\n @Prop() readonly: boolean = false;\n\n /**\n * Primary color\n */\n @Prop() color: string = '#008480';\n\n /**\n * Whether to start week on Sunday (default: true)\n */\n @Prop() startWeekOnSunday: boolean = true;\n\n /**\n * Date selection event\n */\n @Event() dateSelected: EventEmitter<string>;\n\n /**\n * Month change event\n */\n @Event() monthChanged: EventEmitter<{ year: number; month: number }>;\n\n @State() currentYear: number;\n @State() currentMonth: number;\n @State() viewDate: Date;\n @State() focusedDay: number = 0;\n\n private monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];\n private dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\n private dayNamesStartMonday = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];\n\n componentWillLoad() {\n const date = this.selectedDate ? new Date(this.selectedDate) : new Date();\n this.currentYear = date.getFullYear();\n this.currentMonth = date.getMonth();\n this.viewDate = new Date(this.currentYear, this.currentMonth, 1);\n this.focusedDay = date.getDate();\n }\n\n @Listen('keydown')\n handleKeyDown(event: KeyboardEvent) {\n const daysInMonth = this.getDaysInMonth();\n\n switch (event.key) {\n case 'ArrowLeft':\n event.preventDefault();\n if (this.focusedDay > 1) {\n this.focusedDay--;\n } else {\n this.previousMonth();\n this.focusedDay = this.getDaysInMonth();\n }\n break;\n case 'ArrowRight':\n event.preventDefault();\n if (this.focusedDay < daysInMonth) {\n this.focusedDay++;\n } else {\n this.nextMonth();\n this.focusedDay = 1;\n }\n break;\n case 'ArrowUp':\n event.preventDefault();\n if (this.focusedDay > 7) {\n this.focusedDay -= 7;\n } else {\n this.previousMonth();\n this.focusedDay = this.getDaysInMonth() - (7 - this.focusedDay);\n }\n break;\n case 'ArrowDown':\n event.preventDefault();\n if (this.focusedDay + 7 <= daysInMonth) {\n this.focusedDay += 7;\n } else {\n const remainder = this.focusedDay + 7 - daysInMonth;\n this.nextMonth();\n this.focusedDay = remainder;\n }\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n if (this.focusedDay >= 1 && this.focusedDay <= daysInMonth) {\n this.selectDate(this.focusedDay);\n }\n break;\n default:\n return;\n }\n\n // Focus the day cell after render\n requestAnimationFrame(() => {\n const dayEl = this.el.querySelector(`[data-day=\"${this.focusedDay}\"]`) as HTMLElement;\n if (dayEl) dayEl.focus();\n });\n }\n\n private previousMonth = () => {\n if (this.currentMonth === 0) {\n this.currentMonth = 11;\n this.currentYear--;\n } else {\n this.currentMonth--;\n }\n this.viewDate = new Date(this.currentYear, this.currentMonth, 1);\n this.monthChanged.emit({ year: this.currentYear, month: this.currentMonth });\n };\n\n private nextMonth = () => {\n if (this.currentMonth === 11) {\n this.currentMonth = 0;\n this.currentYear++;\n } else {\n this.currentMonth++;\n }\n this.viewDate = new Date(this.currentYear, this.currentMonth, 1);\n this.monthChanged.emit({ year: this.currentYear, month: this.currentMonth });\n };\n\n private selectDate = (day: number) => {\n if (this.readonly) return;\n\n const date = new Date(this.currentYear, this.currentMonth, day);\n const dateString = this.formatDate(date);\n\n if (this.isDateDisabled(date)) return;\n\n this.selectedDate = dateString;\n this.dateSelected.emit(dateString);\n };\n\n private formatDate = (date: Date): string => {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n };\n\n private isDateDisabled = (date: Date): boolean => {\n if (this.min) {\n const minDate = new Date(this.min);\n if (date < minDate) return true;\n }\n if (this.max) {\n const maxDate = new Date(this.max);\n if (date > maxDate) return true;\n }\n return false;\n };\n\n private isToday = (day: number): boolean => {\n const today = new Date();\n return (\n day === today.getDate() &&\n this.currentMonth === today.getMonth() &&\n this.currentYear === today.getFullYear()\n );\n };\n\n private isSelected = (day: number): boolean => {\n if (!this.selectedDate) return false;\n const selected = new Date(this.selectedDate);\n return (\n day === selected.getDate() &&\n this.currentMonth === selected.getMonth() &&\n this.currentYear === selected.getFullYear()\n );\n };\n\n private getDaysInMonth = (): number => {\n return new Date(this.currentYear, this.currentMonth + 1, 0).getDate();\n };\n\n private getFirstDayOfMonth = (): number => {\n const firstDay = new Date(this.currentYear, this.currentMonth, 1).getDay();\n return this.startWeekOnSunday ? firstDay : (firstDay === 0 ? 6 : firstDay - 1);\n };\n\n private renderCalendarDays = () => {\n const daysInMonth = this.getDaysInMonth();\n const firstDay = this.getFirstDayOfMonth();\n const days = [];\n\n // Empty cells for days before the first of the month\n for (let i = 0; i < firstDay; i++) {\n days.push(<div class=\"xplor-inline-date-picker__day xplor-inline-date-picker__day--empty\"></div>);\n }\n\n // Days of the month\n for (let day = 1; day <= daysInMonth; day++) {\n const date = new Date(this.currentYear, this.currentMonth, day);\n const isDisabled = this.isDateDisabled(date);\n const isToday = this.isToday(day);\n const isSelected = this.isSelected(day);\n\n days.push(\n <div\n class={{\n 'xplor-inline-date-picker__day': true,\n 'xplor-inline-date-picker__day--today': isToday,\n 'xplor-inline-date-picker__day--selected': isSelected,\n 'xplor-inline-date-picker__day--disabled': isDisabled,\n }}\n onClick={() => !isDisabled && this.selectDate(day)}\n role=\"gridcell\"\n aria-selected={isSelected ? 'true' : 'false'}\n aria-current={isToday ? 'date' : undefined}\n aria-disabled={isDisabled ? 'true' : undefined}\n tabIndex={day === this.focusedDay ? 0 : -1}\n data-day={day}\n >\n {day}\n </div>\n );\n }\n\n return days;\n };\n\n private getSidebarDate = () => {\n const date = this.selectedDate ? new Date(this.selectedDate) : new Date();\n const dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\n const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n\n return {\n year: date.getFullYear(),\n day: dayNames[date.getDay()],\n date: `${monthNames[date.getMonth()]} ${date.getDate()}`,\n };\n };\n\n render() {\n const sidebarDate = this.getSidebarDate();\n const dayHeaders = this.startWeekOnSunday ? this.dayNames : this.dayNamesStartMonday;\n\n return (\n <Host>\n <div class=\"xplor-inline-date-picker\" style={{ '--picker-color': this.color }}>\n <div class=\"xplor-inline-date-picker__sidebar\">\n <div class=\"xplor-inline-date-picker__sidebar-year\">{sidebarDate.year}</div>\n <div class=\"xplor-inline-date-picker__sidebar-day\">{sidebarDate.day},</div>\n <div class=\"xplor-inline-date-picker__sidebar-date\">{sidebarDate.date}</div>\n </div>\n\n <div class=\"xplor-inline-date-picker__calendar\">\n <div class=\"xplor-inline-date-picker__header\">\n <button\n type=\"button\"\n class=\"xplor-inline-date-picker__arrow\"\n onClick={this.previousMonth}\n aria-label=\"Previous month\"\n >\n ‹\n </button>\n <div class=\"xplor-inline-date-picker__title\">\n {this.monthNames[this.currentMonth]} {this.currentYear}\n </div>\n <button\n type=\"button\"\n class=\"xplor-inline-date-picker__arrow\"\n onClick={this.nextMonth}\n aria-label=\"Next month\"\n >\n ›\n </button>\n </div>\n\n <div class=\"xplor-inline-date-picker__weekdays\">\n {dayHeaders.map((day) => (\n <div class=\"xplor-inline-date-picker__weekday\">{day}</div>\n ))}\n </div>\n\n <div class=\"xplor-inline-date-picker__days\" role=\"grid\">{this.renderCalendarDays()}</div>\n </div>\n </div>\n </Host>\n );\n }\n}\n",":host {\n display: inline-block;\n}\n\n.xplor-inline-switch {\n --switch-color: #008480;\n display: inline-flex;\n align-items: center;\n gap: 0.75rem;\n cursor: pointer;\n user-select: none;\n\n &__input {\n position: absolute;\n opacity: 0;\n width: 0;\n height: 0;\n\n &:disabled {\n cursor: not-allowed;\n }\n }\n\n &__track {\n position: relative;\n width: 2.25rem;\n height: 1.25rem;\n background-color: rgba(0, 0, 0, 0.38);\n border-radius: 0.625rem;\n transition: background-color 0.2s ease;\n flex-shrink: 0;\n }\n\n &__thumb {\n position: absolute;\n top: 0.125rem;\n left: 0.125rem;\n width: 1rem;\n height: 1rem;\n background-color: white;\n border-radius: 50%;\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);\n }\n\n &__label {\n font-size: 1rem;\n color: rgba(0, 0, 0, 0.87);\n }\n\n // Checked state\n &--checked {\n .xplor-inline-switch__track {\n background-color: var(--switch-color);\n }\n\n .xplor-inline-switch__thumb {\n transform: translateX(1rem);\n }\n }\n\n // Disabled state\n &--disabled {\n cursor: not-allowed;\n opacity: 0.6;\n\n .xplor-inline-switch__track {\n background-color: rgba(0, 0, 0, 0.12);\n }\n\n .xplor-inline-switch__label {\n color: rgba(0, 0, 0, 0.38);\n }\n\n // Keep color when disabled but checked\n &.xplor-inline-switch--checked {\n .xplor-inline-switch__track {\n background-color: var(--switch-color);\n opacity: 0.5;\n }\n\n .xplor-inline-switch__thumb {\n background-color: white;\n }\n }\n }\n\n // Hover effect\n &:not(&--disabled):hover {\n .xplor-inline-switch__thumb {\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);\n }\n }\n\n // Focus effect\n &__input:focus + &__track {\n outline: 2px solid var(--switch-color);\n outline-offset: 2px;\n }\n}\n","import { Component, Host, h, Prop, Event, EventEmitter } from '@stencil/core';\n\n@Component({\n tag: 'xplor-inline-switch',\n styleUrl: 'xplor-inline-switch.scss',\n scoped: true,\n})\nexport class XplorInlineSwitch {\n /**\n * Checked state\n */\n @Prop({ mutable: true }) checked: boolean = false;\n\n /**\n * Value (for use in forms)\n */\n @Prop() value: any;\n\n /**\n * Switch color (applies when checked)\n */\n @Prop() color: string = '#008480';\n\n /**\n * Whether the switch is disabled\n */\n @Prop() disabled: boolean = false;\n\n /**\n * Label text\n */\n @Prop() label: string = '';\n\n /**\n * Change event\n */\n @Event() xplorChange: EventEmitter<boolean>;\n\n private handleChange = (event: Event) => {\n const target = event.target as HTMLInputElement;\n this.checked = target.checked;\n this.xplorChange.emit(this.checked);\n };\n\n render() {\n const containerClasses = {\n 'xplor-inline-switch': true,\n 'xplor-inline-switch--disabled': this.disabled,\n 'xplor-inline-switch--checked': this.checked,\n };\n\n return (\n <Host>\n <label class={containerClasses} style={{ '--switch-color': this.color }}>\n <input\n type=\"checkbox\"\n class=\"xplor-inline-switch__input\"\n checked={this.checked}\n value={this.value}\n disabled={this.disabled}\n onChange={this.handleChange}\n />\n <span class=\"xplor-inline-switch__track\">\n <span class=\"xplor-inline-switch__thumb\"></span>\n </span>\n {this.label && <span class=\"xplor-inline-switch__label\">{this.label}</span>}\n <slot />\n </label>\n </Host>\n );\n }\n}\n",":host {\n display: block;\n}\n\n.xplor-input-file {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n\n &__label {\n font-size: 0.875rem;\n color: rgba(0, 0, 0, 0.6);\n margin-bottom: 0.25rem;\n }\n\n &__field {\n position: relative;\n display: flex;\n align-items: center;\n padding: 0.875rem 1rem;\n border: 1px solid rgba(0, 0, 0, 0.23);\n border-radius: 1rem;\n background-color: white;\n cursor: pointer;\n transition: border-color 0.2s ease;\n gap: 0.75rem;\n\n &:hover:not(.xplor-input-file--disabled &) {\n border-color: rgba(0, 0, 0, 0.6);\n }\n\n &:focus-within {\n border-color: #008480;\n border-width: 2px;\n padding: calc(0.875rem - 1px) calc(1rem - 1px);\n }\n }\n\n &--disabled {\n .xplor-input-file__field {\n background-color: rgba(0, 0, 0, 0.04);\n cursor: not-allowed;\n }\n\n .xplor-input-file__placeholder,\n .xplor-input-file__icon {\n color: rgba(0, 0, 0, 0.38);\n }\n }\n\n &__icon {\n font-size: 1.25rem;\n color: rgba(0, 0, 0, 0.54);\n flex-shrink: 0;\n }\n\n &__content {\n flex: 1;\n min-width: 0;\n }\n\n &__placeholder {\n color: rgba(0, 0, 0, 0.38);\n }\n\n &__chips {\n display: flex;\n flex-wrap: wrap;\n gap: 0.5rem;\n align-items: center;\n }\n\n &__chip {\n display: inline-flex;\n align-items: center;\n gap: 0.25rem;\n padding: 0.25rem 0.75rem;\n background-color: #673AB7;\n color: white;\n border-radius: 1rem;\n font-size: 0.875rem;\n max-width: 100%;\n }\n\n &__chip-text {\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n &__chip-size {\n font-size: 0.75rem;\n opacity: 0.8;\n white-space: nowrap;\n }\n\n &__additional {\n font-size: 0.875rem;\n color: rgba(0, 0, 0, 0.6);\n margin-left: 0.5rem;\n }\n\n &__clear {\n position: relative;\n width: 1.5rem;\n height: 1.5rem;\n border: none;\n background: transparent;\n color: rgba(0, 0, 0, 0.54);\n cursor: pointer;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s ease;\n flex-shrink: 0;\n\n &:hover {\n background-color: rgba(0, 0, 0, 0.04);\n }\n\n &:active {\n background-color: rgba(0, 0, 0, 0.08);\n }\n }\n\n &__input {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n opacity: 0;\n cursor: pointer;\n\n &:disabled {\n cursor: not-allowed;\n }\n }\n\n &__counter {\n font-size: 0.75rem;\n color: rgba(0, 0, 0, 0.6);\n padding: 0 1rem;\n }\n}\n","import { Component, Host, h, Prop, Event, EventEmitter, State } from '@stencil/core';\n\nlet inputFileIdCounter = 0;\n\n@Component({\n tag: 'xplor-input-file',\n styleUrl: 'xplor-input-file.scss',\n scoped: true,\n})\nexport class XplorInputFile {\n private fileInputRef: HTMLInputElement;\n private inputId = `xplor-input-file-${++inputFileIdCounter}`;\n\n /**\n * Input label\n */\n @Prop() label: string = '';\n\n /**\n * Input placeholder\n */\n @Prop() placeholder: string = 'Choose file(s)';\n\n /**\n * Border/focus color\n */\n @Prop() color: string = '#008480';\n\n /**\n * Whether the input is disabled\n */\n @Prop() disabled: boolean = false;\n\n /**\n * Whether multiple files can be selected\n */\n @Prop() multiple: boolean = false;\n\n /**\n * Accepted file types\n */\n @Prop() accept: string = '';\n\n /**\n * Maximum number of chips to show\n */\n @Prop() maxChips: number = 1;\n\n /**\n * Whether to show file counter\n */\n @Prop() counter: boolean = true;\n\n /**\n * Whether to show file size\n */\n @Prop() showSize: number = 1000;\n\n /**\n * Prepend inner icon (default: paperclip)\n */\n @Prop() prependInnerIcon: string = '📎';\n\n /**\n * Files selected\n */\n @State() selectedFiles: File[] = [];\n\n /**\n * Attach/change event\n */\n @Event() attach: EventEmitter<File[]>;\n\n /**\n * Clear event\n */\n @Event() xplorClear: EventEmitter<void>;\n\n private handleFileChange = (event: Event) => {\n const target = event.target as HTMLInputElement;\n if (target.files) {\n this.selectedFiles = Array.from(target.files);\n this.attach.emit(this.selectedFiles);\n }\n };\n\n private handleClear = () => {\n this.selectedFiles = [];\n if (this.fileInputRef) {\n this.fileInputRef.value = '';\n }\n this.xplorClear.emit();\n };\n\n private formatFileSize = (bytes: number): string => {\n if (bytes === 0) return '0 Bytes';\n const k = 1024;\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\n const i = Math.floor(Math.log(bytes) / Math.log(k));\n return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i];\n };\n\n render() {\n const containerClasses = {\n 'xplor-input-file': true,\n 'xplor-input-file--disabled': this.disabled,\n };\n\n const visibleFiles = this.selectedFiles.slice(0, this.maxChips);\n const additionalCount = this.selectedFiles.length - this.maxChips;\n\n return (\n <Host>\n <div class={containerClasses}>\n {this.label && (\n <label class=\"xplor-input-file__label\" htmlFor={this.inputId}>{this.label}</label>\n )}\n\n <div class=\"xplor-input-file__field\">\n <span class=\"xplor-input-file__icon\">{this.prependInnerIcon}</span>\n\n <div class=\"xplor-input-file__content\">\n {this.selectedFiles.length === 0 ? (\n <span class=\"xplor-input-file__placeholder\">{this.placeholder}</span>\n ) : (\n <div class=\"xplor-input-file__chips\">\n {visibleFiles.map((file) => (\n <div class=\"xplor-input-file__chip\" key={file.name}>\n <span class=\"xplor-input-file__chip-text\">{file.name}</span>\n {this.showSize && file.size && (\n <span class=\"xplor-input-file__chip-size\">\n ({this.formatFileSize(file.size)})\n </span>\n )}\n </div>\n ))}\n {additionalCount > 0 && (\n <span class=\"xplor-input-file__additional\">\n +{additionalCount} additional file{additionalCount > 1 ? 's' : ''}\n </span>\n )}\n </div>\n )}\n </div>\n\n {this.selectedFiles.length > 0 && !this.disabled && (\n <button\n type=\"button\"\n class=\"xplor-input-file__clear\"\n onClick={this.handleClear}\n aria-label=\"Clear\"\n >\n ✕\n </button>\n )}\n\n <input\n id={this.inputId}\n ref={(el) => (this.fileInputRef = el)}\n type=\"file\"\n class=\"xplor-input-file__input\"\n multiple={this.multiple}\n accept={this.accept}\n disabled={this.disabled}\n onChange={this.handleFileChange}\n aria-label={this.label || 'Choose file'}\n />\n </div>\n\n {this.counter && this.selectedFiles.length > 0 && (\n <div class=\"xplor-input-file__counter\">\n {this.selectedFiles.length} file{this.selectedFiles.length > 1 ? 's' : ''} selected\n </div>\n )}\n </div>\n </Host>\n );\n }\n}\n",":host {\n display: block;\n}\n\n.xplor-input-search {\n display: flex;\n flex-direction: column;\n\n &__field {\n position: relative;\n display: flex;\n align-items: center;\n border: 1px solid rgba(0, 0, 0, 0.23);\n border-radius: 1rem;\n background-color: white;\n transition: border-color 0.2s ease;\n padding-right: 0.375rem;\n\n &:hover:not(.xplor-input-search--disabled &) {\n border-color: rgba(0, 0, 0, 0.6);\n }\n }\n\n &--focused {\n .xplor-input-search__field {\n border-color: #008480;\n border-width: 2px;\n padding-right: calc(0.375rem - 1px);\n }\n\n .xplor-input-search__input {\n padding-left: calc(1rem - 1px);\n }\n }\n\n &__input {\n flex: 1;\n padding: 0.875rem 1rem;\n font-size: 1rem;\n font-family: inherit;\n border: none;\n outline: none;\n background: transparent;\n min-width: 0;\n\n &::placeholder {\n color: rgba(0, 0, 0, 0.38);\n }\n\n &:disabled {\n color: rgba(0, 0, 0, 0.38);\n cursor: not-allowed;\n }\n }\n\n &__button {\n min-height: 0;\n min-width: 0;\n height: 2.5rem;\n width: 2.5rem;\n padding: 0;\n border: none;\n border-radius: 4px;\n background-color: #008480;\n color: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s ease;\n flex-shrink: 0;\n\n &:hover:not(:disabled) {\n background-color: #006D6A;\n }\n\n &:active:not(:disabled) {\n background-color: #005755;\n }\n\n &:disabled {\n opacity: 0.38;\n cursor: not-allowed;\n }\n }\n\n &__icon {\n width: 1.25rem;\n height: 1.25rem;\n fill: currentColor;\n }\n\n // Density variants\n &--compact {\n .xplor-input-search__input {\n padding: 0.625rem 1rem;\n }\n\n .xplor-input-search__button {\n height: 2rem;\n width: 2rem;\n }\n\n .xplor-input-search__icon {\n width: 1rem;\n height: 1rem;\n }\n }\n\n &--comfortable {\n .xplor-input-search__input {\n padding: 1rem 1rem;\n }\n\n .xplor-input-search__button {\n height: 2.75rem;\n width: 2.75rem;\n }\n\n .xplor-input-search__icon {\n width: 1.375rem;\n height: 1.375rem;\n }\n }\n\n &--disabled {\n .xplor-input-search__field {\n background-color: rgba(0, 0, 0, 0.04);\n }\n }\n}\n","import { Component, Host, h, Prop, Event, EventEmitter, State } from '@stencil/core';\n\nlet inputSearchIdCounter = 0;\n\n@Component({\n tag: 'xplor-input-search',\n styleUrl: 'xplor-input-search.scss',\n scoped: true,\n})\nexport class XplorInputSearch {\n private inputId = `xplor-input-search-${++inputSearchIdCounter}`;\n /**\n * Search value\n */\n @Prop({ mutable: true }) value: string = '';\n\n /**\n * Input placeholder\n */\n @Prop() placeholder: string = 'Search...';\n\n /**\n * Background color\n */\n @Prop() bgColor: string = 'white';\n\n /**\n * Button/focus color\n */\n @Prop() color: string = '#008480';\n\n /**\n * Whether the input is disabled\n */\n @Prop() disabled: boolean = false;\n\n /**\n * Density (compact, default, comfortable)\n */\n @Prop() density: 'compact' | 'default' | 'comfortable' = 'default';\n\n /**\n * Search event (triggered on button click or Enter key)\n */\n @Event() search: EventEmitter<string>;\n\n @State() isFocused: boolean = false;\n\n private handleInput = (event: Event) => {\n const target = event.target as HTMLInputElement;\n this.value = target.value;\n };\n\n private handleSearch = () => {\n this.search.emit(this.value);\n };\n\n private handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Enter') {\n this.handleSearch();\n }\n };\n\n render() {\n const containerClasses = {\n 'xplor-input-search': true,\n [`xplor-input-search--${this.density}`]: true,\n 'xplor-input-search--focused': this.isFocused,\n 'xplor-input-search--disabled': this.disabled,\n };\n\n return (\n <Host>\n <div class={containerClasses}>\n <div class=\"xplor-input-search__field\">\n <input\n id={this.inputId}\n type=\"search\"\n class=\"xplor-input-search__input\"\n value={this.value}\n placeholder={this.placeholder}\n disabled={this.disabled}\n onInput={this.handleInput}\n onKeyDown={this.handleKeyDown}\n onFocus={() => (this.isFocused = true)}\n onBlur={() => (this.isFocused = false)}\n style={{\n backgroundColor: this.bgColor,\n }}\n role=\"searchbox\"\n aria-label=\"Search\"\n />\n\n <slot name=\"append-inner\">\n <button\n type=\"button\"\n class=\"xplor-input-search__button\"\n onClick={this.handleSearch}\n disabled={this.disabled}\n data-testid=\"input-search-button\"\n aria-label=\"Search\"\n >\n <svg viewBox=\"0 0 24 24\" class=\"xplor-input-search__icon\">\n <path d=\"M9.5,3A6.5,6.5 0 0,1 16,9.5C16,11.11 15.41,12.59 14.44,13.73L14.71,14H15.5L20.5,19L19,20.5L14,15.5V14.71L13.73,14.44C12.59,15.41 11.11,16 9.5,16A6.5,6.5 0 0,1 3,9.5A6.5,6.5 0 0,1 9.5,3M9.5,5C7,5 5,7 5,9.5C5,12 7,14 9.5,14C12,14 14,12 14,9.5C14,7 12,5 9.5,5Z\" />\n </svg>\n </button>\n </slot>\n </div>\n </div>\n </Host>\n );\n }\n}\n",":host {\n display: block;\n}\n\n.xplor-input-select {\n position: relative;\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n\n &__label {\n font-size: 0.875rem;\n color: rgba(0, 0, 0, 0.6);\n margin-bottom: 0.25rem;\n }\n\n &__required {\n color: #d32f2f;\n margin-left: 0.25rem;\n }\n\n &__field {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 0.875rem 1rem;\n border: 1px solid rgba(0, 0, 0, 0.23);\n border-radius: 1rem;\n background-color: white;\n cursor: pointer;\n transition: border-color 0.2s ease;\n gap: 0.5rem;\n\n &:hover:not(.xplor-input-select--disabled &) {\n border-color: rgba(0, 0, 0, 0.6);\n }\n }\n\n &--open {\n .xplor-input-select__field {\n border-color: #008480;\n border-width: 2px;\n padding: calc(0.875rem - 1px) calc(1rem - 1px);\n }\n }\n\n &--error {\n .xplor-input-select__field {\n border-color: #d32f2f;\n }\n }\n\n &--disabled {\n .xplor-input-select__field {\n background-color: rgba(0, 0, 0, 0.04);\n cursor: not-allowed;\n }\n\n .xplor-input-select__value {\n color: rgba(0, 0, 0, 0.38);\n }\n }\n\n &__value {\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: rgba(0, 0, 0, 0.87);\n }\n\n &__arrow {\n font-size: 0.75rem;\n color: rgba(0, 0, 0, 0.54);\n transition: transform 0.2s ease;\n flex-shrink: 0;\n }\n\n &__menu {\n max-height: 300px;\n overflow-y: auto;\n background-color: white;\n border-radius: 0.5rem;\n box-shadow: 0px 5px 5px -3px rgba(0, 0, 0, 0.2),\n 0px 8px 10px 1px rgba(0, 0, 0, 0.14),\n 0px 3px 14px 2px rgba(0, 0, 0, 0.12);\n z-index: 9999;\n }\n\n &__empty {\n padding: 1rem;\n text-align: center;\n color: rgba(0, 0, 0, 0.6);\n }\n\n &__option {\n display: flex;\n align-items: center;\n padding: 0.875rem 1.25rem;\n cursor: pointer;\n transition: background-color 0.2s ease;\n gap: 0.75rem;\n\n &:hover {\n background-color: rgba(0, 0, 0, 0.04);\n }\n\n &--selected {\n background-color: rgba(0, 132, 128, 0.08);\n }\n }\n\n &__checkbox {\n flex-shrink: 0;\n width: 1.125rem;\n height: 1.125rem;\n cursor: pointer;\n }\n\n &__option-content {\n flex: 1;\n min-width: 0;\n }\n\n &__option-title {\n font-size: 1rem;\n color: rgba(0, 0, 0, 0.87);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n &__option-subtitle {\n font-size: 0.875rem;\n color: rgba(0, 0, 0, 0.6);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n\n &__details {\n min-height: 1.25rem;\n padding: 0 1rem;\n font-size: 0.75rem;\n }\n\n &__error-message {\n color: #d32f2f;\n }\n\n &__helper-text {\n color: rgba(0, 0, 0, 0.6);\n }\n}\n","import { Component, Host, h, Prop, Event, EventEmitter, State, Element, Listen } from '@stencil/core';\n\nexport interface SelectOption {\n value: any;\n title: string;\n subtitle?: string;\n [key: string]: any;\n}\n\n@Component({\n tag: 'xplor-input-select',\n styleUrl: 'xplor-input-select.scss',\n scoped: true,\n})\nexport class XplorInputSelect {\n @Element() el: HTMLElement;\n\n private selectRef: HTMLDivElement;\n private fieldRef: HTMLDivElement;\n\n /**\n * Accessible label for the select when no visible label is provided\n */\n @Prop() ariaLabel: string;\n\n /**\n * Selected value(s)\n */\n @Prop({ mutable: true }) value: any | any[] = null;\n\n /**\n * Input label\n */\n @Prop() label: string = '';\n\n /**\n * Input placeholder\n */\n @Prop() placeholder: string = 'Select...';\n\n /**\n * Options array\n */\n @Prop() options: SelectOption[] = [];\n\n /**\n * Whether multiple selection is allowed\n */\n @Prop() multiple: boolean = false;\n\n /**\n * Background color\n */\n @Prop() bgColor: string = 'white';\n\n /**\n * Border/focus color\n */\n @Prop() color: string = '#008480';\n\n /**\n * Whether the select is disabled\n */\n @Prop() disabled: boolean = false;\n\n /**\n * Whether the select is readonly\n */\n @Prop() readonly: boolean = false;\n\n /**\n * Whether to hide validation details\n */\n @Prop() hideDetails: boolean | 'auto' = 'auto';\n\n /**\n * Error message\n */\n @Prop() error: string = '';\n\n /**\n * Helper text\n */\n @Prop() helperText: string = '';\n\n /**\n * Whether the input is required\n */\n @Prop() required: boolean = false;\n\n /**\n * Change event\n */\n @Event() xplorChange: EventEmitter<any>;\n\n @State() isOpen: boolean = false;\n @State() isFocused: boolean = false;\n @State() menuPosition: { top: number; left: number; width: number } = null;\n @State() highlightedIndex: number = -1;\n\n componentDidLoad() {\n document.addEventListener('click', this.handleOutsideClick);\n }\n\n disconnectedCallback() {\n document.removeEventListener('click', this.handleOutsideClick);\n }\n\n @Listen('keydown')\n handleKeyDown(event: KeyboardEvent) {\n const totalOptions = this.options.length;\n if (totalOptions === 0) return;\n\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n if (!this.isOpen) {\n this.updateMenuPosition();\n this.isOpen = true;\n this.highlightedIndex = 0;\n } else {\n this.highlightedIndex = this.highlightedIndex < totalOptions - 1 ? this.highlightedIndex + 1 : 0;\n }\n this.scrollToHighlightedOption();\n break;\n\n case 'ArrowUp':\n event.preventDefault();\n if (!this.isOpen) {\n this.updateMenuPosition();\n this.isOpen = true;\n this.highlightedIndex = totalOptions - 1;\n } else {\n this.highlightedIndex = this.highlightedIndex > 0 ? this.highlightedIndex - 1 : totalOptions - 1;\n }\n this.scrollToHighlightedOption();\n break;\n\n case 'Enter':\n case ' ':\n event.preventDefault();\n if (this.isOpen && this.highlightedIndex >= 0 && this.highlightedIndex < totalOptions) {\n this.handleOptionClick(this.options[this.highlightedIndex]);\n } else if (!this.isOpen) {\n this.toggleDropdown();\n }\n break;\n\n case 'Escape':\n event.preventDefault();\n this.isOpen = false;\n this.highlightedIndex = -1;\n this.fieldRef?.focus();\n break;\n\n case 'Home':\n if (this.isOpen) {\n event.preventDefault();\n this.highlightedIndex = 0;\n this.scrollToHighlightedOption();\n }\n break;\n\n case 'End':\n if (this.isOpen) {\n event.preventDefault();\n this.highlightedIndex = totalOptions - 1;\n this.scrollToHighlightedOption();\n }\n break;\n\n case 'Tab':\n this.isOpen = false;\n this.highlightedIndex = -1;\n break;\n }\n }\n\n private scrollToHighlightedOption() {\n requestAnimationFrame(() => {\n if (this.selectRef && this.highlightedIndex >= 0) {\n const highlightedEl = this.selectRef.querySelector(`[data-option-index=\"${this.highlightedIndex}\"]`) as HTMLElement;\n if (highlightedEl) {\n highlightedEl.scrollIntoView({ block: 'nearest' });\n }\n }\n });\n }\n\n private updateMenuPosition = () => {\n if (this.fieldRef) {\n const rect = this.fieldRef.getBoundingClientRect();\n this.menuPosition = {\n top: rect.bottom + 4,\n left: rect.left,\n width: rect.width,\n };\n }\n };\n\n private handleOutsideClick = (event: MouseEvent) => {\n if (this.selectRef && !this.selectRef.contains(event.target as Node)) {\n this.isOpen = false;\n }\n };\n\n private toggleDropdown = () => {\n if (!this.disabled && !this.readonly) {\n if (!this.isOpen) {\n this.updateMenuPosition();\n this.highlightedIndex = -1;\n }\n this.isOpen = !this.isOpen;\n if (!this.isOpen) {\n this.highlightedIndex = -1;\n }\n }\n };\n\n private handleOptionClick = (option: SelectOption) => {\n if (this.multiple) {\n const currentValue = Array.isArray(this.value) ? this.value : [];\n const index = currentValue.findIndex((v) => v === option.value);\n\n if (index > -1) {\n this.value = currentValue.filter((_, i) => i !== index);\n } else {\n this.value = [...currentValue, option.value];\n }\n } else {\n this.value = option.value;\n this.isOpen = false;\n }\n\n this.xplorChange.emit(this.value);\n };\n\n private isSelected = (option: SelectOption): boolean => {\n if (this.multiple) {\n const currentValue = Array.isArray(this.value) ? this.value : [];\n return currentValue.includes(option.value);\n }\n return this.value === option.value;\n };\n\n private getDisplayValue = (): string => {\n if (this.multiple) {\n const currentValue = Array.isArray(this.value) ? this.value : [];\n if (currentValue.length === 0) return this.placeholder;\n\n const selectedOptions = this.options.filter((opt) =>\n currentValue.includes(opt.value)\n );\n return `${selectedOptions.length} selected`;\n }\n\n const selectedOption = this.options.find((opt) => opt.value === this.value);\n return selectedOption ? selectedOption.title : this.placeholder;\n };\n\n render() {\n const containerClasses = {\n 'xplor-input-select': true,\n 'xplor-input-select--open': this.isOpen,\n 'xplor-input-select--focused': this.isFocused,\n 'xplor-input-select--disabled': this.disabled,\n 'xplor-input-select--error': !!this.error,\n };\n\n const showDetails = this.hideDetails === false || (this.hideDetails === 'auto' && (this.error || this.helperText));\n const listboxId = 'input-select-listbox';\n const labelId = 'input-select-label';\n const errorId = 'input-select-error';\n const helperId = 'input-select-helper';\n const activeDescendantId = this.highlightedIndex >= 0 ? `input-select-option-${this.highlightedIndex}` : undefined;\n\n // Build aria-describedby from error/helper text\n const describedByParts: string[] = [];\n if (this.error) describedByParts.push(errorId);\n if (!this.error && this.helperText) describedByParts.push(helperId);\n const ariaDescribedBy = describedByParts.length > 0 ? describedByParts.join(' ') : undefined;\n\n return (\n <Host>\n <div class={containerClasses} ref={(el) => (this.selectRef = el)}>\n {this.label && (\n <label class=\"xplor-input-select__label\" id={labelId}>\n {this.label}\n {this.required && <span class=\"xplor-input-select__required\">*</span>}\n </label>\n )}\n\n <div\n class=\"xplor-input-select__field\"\n onClick={this.toggleDropdown}\n ref={(el) => (this.fieldRef = el)}\n role=\"combobox\"\n tabindex={this.disabled ? -1 : 0}\n aria-expanded={this.isOpen ? 'true' : 'false'}\n aria-haspopup=\"listbox\"\n aria-controls={this.isOpen ? listboxId : undefined}\n aria-activedescendant={activeDescendantId}\n aria-labelledby={this.label ? labelId : undefined}\n aria-label={!this.label ? (this.ariaLabel || this.placeholder) : undefined}\n aria-describedby={ariaDescribedBy}\n aria-required={this.required ? 'true' : undefined}\n aria-disabled={this.disabled ? 'true' : undefined}\n >\n <div class=\"xplor-input-select__value\">\n {this.getDisplayValue()}\n </div>\n <span class=\"xplor-input-select__arrow\" aria-hidden=\"true\">{this.isOpen ? '▲' : '▼'}</span>\n </div>\n\n {this.isOpen && this.menuPosition && (\n <div\n class=\"xplor-input-select__menu\"\n role=\"listbox\"\n id={listboxId}\n aria-label={this.label || this.ariaLabel || 'Options'}\n aria-multiselectable={this.multiple ? 'true' : undefined}\n style={{\n position: 'fixed',\n top: `${this.menuPosition.top}px`,\n left: `${this.menuPosition.left}px`,\n width: `${this.menuPosition.width}px`,\n }}\n >\n {this.options.length === 0 ? (\n <div class=\"xplor-input-select__empty\" role=\"option\" aria-disabled=\"true\">No options available</div>\n ) : (\n this.options.map((option, index) => {\n const selected = this.isSelected(option);\n return (\n <div\n key={option.value}\n id={`input-select-option-${index}`}\n data-option-index={index}\n role=\"option\"\n aria-selected={selected ? 'true' : 'false'}\n class={{\n 'xplor-input-select__option': true,\n 'xplor-input-select__option--selected': selected,\n 'xplor-input-select__option--highlighted': index === this.highlightedIndex,\n }}\n onClick={() => this.handleOptionClick(option)}\n >\n {this.multiple && (\n <input\n type=\"checkbox\"\n class=\"xplor-input-select__checkbox\"\n checked={selected}\n readOnly\n tabindex={-1}\n aria-checked={selected ? 'true' : 'false'}\n aria-hidden=\"true\"\n />\n )}\n <div class=\"xplor-input-select__option-content\">\n <div class=\"xplor-input-select__option-title\">{option.title}</div>\n {option.subtitle && (\n <div class=\"xplor-input-select__option-subtitle\">{option.subtitle}</div>\n )}\n </div>\n </div>\n );\n })\n )}\n </div>\n )}\n\n {showDetails && (\n <div class=\"xplor-input-select__details\">\n {this.error && <div class=\"xplor-input-select__error-message\" id={errorId} role=\"alert\">{this.error}</div>}\n {!this.error && this.helperText && <div class=\"xplor-input-select__helper-text\" id={helperId}>{this.helperText}</div>}\n </div>\n )}\n </div>\n </Host>\n );\n }\n}\n",":host {\n display: block;\n width: 100%;\n}\n\n.input-send {\n display: flex;\n gap: 0.5rem;\n align-items: stretch;\n width: 100%;\n\n &--disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n}\n\n.input-send__input {\n flex: 1;\n padding: 0.75rem 1rem;\n border: 1px solid #bdbdbd;\n border-radius: 4px;\n font-family: inherit;\n font-size: 1rem;\n line-height: 1.5;\n color: #212121;\n background-color: #fff;\n transition: border-color 0.2s, box-shadow 0.2s;\n\n &:focus {\n outline: none;\n border-color: #1976d2;\n box-shadow: 0 0 0 3px rgba(25, 118, 210, 0.1);\n }\n\n &::placeholder {\n color: #9e9e9e;\n }\n\n &:disabled {\n background-color: #f5f5f5;\n cursor: not-allowed;\n }\n}\n\n.input-send__button {\n flex-shrink: 0;\n}","import { Component, Host, h, Prop, State, Event, EventEmitter } from '@stencil/core';\n\n@Component({\n tag: 'xplor-input-send',\n styleUrl: 'xplor-input-send.scss',\n scoped: true,\n})\nexport class XplorInputSend {\n @Prop() placeholder: string = 'Type a message...';\n @Prop() disabled: boolean = false;\n @Prop() maxLength: number;\n @Prop({ mutable: true }) value: string = '';\n @Prop() buttonText: string = 'Send';\n @Prop() buttonType: 'primary' | 'secondary' | 'ghost' = 'primary';\n\n @State() internalValue: string = '';\n\n @Event() xplorSend: EventEmitter<string>;\n @Event() xplorValueChange: EventEmitter<string>;\n\n private inputEl: HTMLInputElement;\n\n componentWillLoad() {\n this.internalValue = this.value;\n }\n\n private handleInput = (event: Event) => {\n const input = event.target as HTMLInputElement;\n this.internalValue = input.value;\n this.value = input.value;\n this.xplorValueChange.emit(input.value);\n };\n\n private handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n this.handleSend();\n }\n };\n\n private handleSend = () => {\n if (this.disabled || !this.internalValue.trim()) {\n return;\n }\n\n this.xplorSend.emit(this.internalValue.trim());\n this.internalValue = '';\n this.value = '';\n\n // Focus back on input after sending\n if (this.inputEl) {\n this.inputEl.focus();\n }\n };\n\n render() {\n return (\n <Host>\n <div\n class={{\n 'input-send': true,\n 'input-send--disabled': this.disabled,\n }}\n >\n <input\n ref={(el) => (this.inputEl = el)}\n type=\"text\"\n class=\"input-send__input\"\n placeholder={this.placeholder}\n value={this.internalValue}\n onInput={this.handleInput}\n onKeyDown={this.handleKeyDown}\n disabled={this.disabled}\n maxLength={this.maxLength}\n aria-label={this.placeholder || 'Type a message'}\n />\n <xplor-button\n class=\"input-send__button\"\n text={this.buttonText}\n type={this.disabled || !this.internalValue.trim() ? 'disabled' : this.buttonType}\n onClick={this.handleSend}\n />\n </div>\n </Host>\n );\n }\n}\n",":host {\n display: block;\n}\n\n.xplor-input-text {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n\n &__label {\n font-size: 0.875rem;\n color: rgba(0, 0, 0, 0.6);\n margin-bottom: 0.25rem;\n }\n\n &__required {\n color: #d32f2f;\n margin-left: 0.25rem;\n }\n\n &__field {\n position: relative;\n display: flex;\n align-items: center;\n }\n\n &__input {\n width: 100%;\n padding: 0.875rem 1rem;\n font-size: 1rem;\n font-family: inherit;\n border: 1px solid rgba(0, 0, 0, 0.23);\n border-radius: 1rem;\n outline: none;\n transition: border-color 0.2s ease;\n\n &::placeholder {\n color: rgba(0, 0, 0, 0.38);\n }\n\n &:hover:not(:disabled) {\n border-color: rgba(0, 0, 0, 0.6);\n }\n\n &:focus {\n border-color: #008480;\n border-width: 2px;\n padding: calc(0.875rem - 1px) calc(1rem - 1px);\n }\n\n &:disabled {\n background-color: rgba(0, 0, 0, 0.04);\n color: rgba(0, 0, 0, 0.38);\n cursor: not-allowed;\n }\n\n &:read-only {\n background-color: rgba(0, 0, 0, 0.04);\n }\n }\n\n &--error {\n .xplor-input-text__input {\n border-color: #d32f2f;\n }\n }\n\n &__details {\n min-height: 1.25rem;\n padding: 0 1rem;\n font-size: 0.75rem;\n }\n\n &__error-message {\n color: #d32f2f;\n }\n\n &__helper-text {\n color: rgba(0, 0, 0, 0.6);\n }\n}\n","import { Component, Host, h, Prop, Event, EventEmitter, State } from '@stencil/core';\n\nlet inputTextIdCounter = 0;\n\n@Component({\n tag: 'xplor-input-text',\n styleUrl: 'xplor-input-text.scss',\n scoped: true,\n})\nexport class XplorInputText {\n private inputId = `xplor-input-text-${++inputTextIdCounter}`;\n private errorId = `${this.inputId}-error`;\n private helperId = `${this.inputId}-helper`;\n /**\n * Input value\n */\n @Prop({ mutable: true }) value: string = '';\n\n /**\n * Input label\n */\n @Prop() label: string = '';\n\n /**\n * Input placeholder\n */\n @Prop() placeholder: string = '';\n\n /**\n * Input type (text, email, password, number, etc.)\n */\n @Prop() type: string = 'text';\n\n /**\n * Background color\n */\n @Prop() bgColor: string = 'white';\n\n /**\n * Border/focus color\n */\n @Prop() color: string = '#008480';\n\n /**\n * Whether the input is disabled\n */\n @Prop() disabled: boolean = false;\n\n /**\n * Whether the input is readonly\n */\n @Prop() readonly: boolean = false;\n\n /**\n * Whether to hide validation details\n */\n @Prop() hideDetails: boolean | 'auto' = 'auto';\n\n /**\n * Error message\n */\n @Prop() error: string = '';\n\n /**\n * Helper text\n */\n @Prop() helperText: string = '';\n\n /**\n * Whether the input is required\n */\n @Prop() required: boolean = false;\n\n /**\n * Input event\n */\n @Event() xplorInput: EventEmitter<string>;\n\n /**\n * Change event\n */\n @Event() xplorChange: EventEmitter<string>;\n\n /**\n * Focus event\n */\n @Event() xplorFocus: EventEmitter<FocusEvent>;\n\n /**\n * Blur event\n */\n @Event() xplorBlur: EventEmitter<FocusEvent>;\n\n @State() isFocused: boolean = false;\n\n private handleInput = (event: Event) => {\n const target = event.target as HTMLInputElement;\n this.value = target.value;\n this.xplorInput.emit(this.value);\n };\n\n private handleChange = (event: Event) => {\n const target = event.target as HTMLInputElement;\n this.value = target.value;\n this.xplorChange.emit(this.value);\n };\n\n private handleFocus = (event: FocusEvent) => {\n this.isFocused = true;\n this.xplorFocus.emit(event);\n };\n\n private handleBlur = (event: FocusEvent) => {\n this.isFocused = false;\n this.xplorBlur.emit(event);\n };\n\n render() {\n const containerClasses = {\n 'xplor-input-text': true,\n 'xplor-input-text--focused': this.isFocused,\n 'xplor-input-text--disabled': this.disabled,\n 'xplor-input-text--error': !!this.error,\n };\n\n const showDetails = this.hideDetails === false || (this.hideDetails === 'auto' && (this.error || this.helperText));\n\n return (\n <Host>\n <div class={containerClasses}>\n {this.label && (\n <label class=\"xplor-input-text__label\" htmlFor={this.inputId}>\n {this.label}\n {this.required && <span class=\"xplor-input-text__required\">*</span>}\n </label>\n )}\n\n <div class=\"xplor-input-text__field\">\n <input\n id={this.inputId}\n type={this.type}\n class=\"xplor-input-text__input\"\n value={this.value}\n placeholder={this.placeholder}\n disabled={this.disabled}\n readonly={this.readonly}\n required={this.required}\n onInput={this.handleInput}\n onChange={this.handleChange}\n onFocus={this.handleFocus}\n onBlur={this.handleBlur}\n style={{\n backgroundColor: this.bgColor,\n }}\n aria-invalid={this.error ? 'true' : undefined}\n aria-required={this.required ? 'true' : undefined}\n aria-describedby={this.error ? this.errorId : this.helperText ? this.helperId : undefined}\n />\n <slot name=\"append-inner\" />\n </div>\n\n {showDetails && (\n <div class=\"xplor-input-text__details\">\n {this.error && <div class=\"xplor-input-text__error-message\" id={this.errorId}>{this.error}</div>}\n {!this.error && this.helperText && <div class=\"xplor-input-text__helper-text\" id={this.helperId}>{this.helperText}</div>}\n </div>\n )}\n\n <slot name=\"append\" />\n </div>\n </Host>\n );\n }\n}\n",":host {\n display: block;\n}\n\n.xplor-input-text-area {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n\n &__label {\n font-size: 0.875rem;\n color: rgba(0, 0, 0, 0.6);\n margin-bottom: 0.25rem;\n }\n\n &__required {\n color: #d32f2f;\n margin-left: 0.25rem;\n }\n\n &__field {\n position: relative;\n display: flex;\n align-items: flex-start;\n }\n\n &__input {\n width: 100%;\n padding: 0.875rem 1rem;\n font-size: 1rem;\n font-family: inherit;\n border: 1px solid rgba(0, 0, 0, 0.23);\n border-radius: 1rem;\n outline: none;\n resize: vertical;\n min-height: 56px;\n transition: border-color 0.2s ease;\n\n &::placeholder {\n color: rgba(0, 0, 0, 0.38);\n }\n\n &:hover:not(:disabled) {\n border-color: rgba(0, 0, 0, 0.6);\n }\n\n &:focus {\n border-color: #008480;\n border-width: 2px;\n padding: calc(0.875rem - 1px) calc(1rem - 1px);\n }\n\n &:disabled {\n background-color: rgba(0, 0, 0, 0.04);\n color: rgba(0, 0, 0, 0.38);\n cursor: not-allowed;\n resize: none;\n }\n\n &:read-only {\n background-color: rgba(0, 0, 0, 0.04);\n }\n }\n\n &__clear {\n position: absolute;\n right: 0.75rem;\n top: 0.75rem;\n width: 1.5rem;\n height: 1.5rem;\n border: none;\n background: transparent;\n color: rgba(0, 0, 0, 0.54);\n cursor: pointer;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s ease;\n\n &:hover {\n background-color: rgba(0, 0, 0, 0.04);\n }\n\n &:active {\n background-color: rgba(0, 0, 0, 0.08);\n }\n }\n\n &--error {\n .xplor-input-text-area__input {\n border-color: #d32f2f;\n }\n }\n\n &__details {\n min-height: 1.25rem;\n padding: 0 1rem;\n font-size: 0.75rem;\n }\n\n &__error-message {\n color: #d32f2f;\n }\n\n &__helper-text {\n color: rgba(0, 0, 0, 0.6);\n }\n}\n","import { Component, Host, h, Prop, Event, EventEmitter, State } from '@stencil/core';\n\nlet inputTextAreaIdCounter = 0;\n\n@Component({\n tag: 'xplor-input-text-area',\n styleUrl: 'xplor-input-text-area.scss',\n scoped: true,\n})\nexport class XplorInputTextArea {\n private inputId = `xplor-input-text-area-${++inputTextAreaIdCounter}`;\n private errorId = `${this.inputId}-error`;\n private helperId = `${this.inputId}-helper`;\n /**\n * Input value\n */\n @Prop({ mutable: true }) value: string = '';\n\n /**\n * Input label\n */\n @Prop() label: string = '';\n\n /**\n * Input placeholder\n */\n @Prop() placeholder: string = '';\n\n /**\n * Background color\n */\n @Prop() bgColor: string = 'white';\n\n /**\n * Border/focus color\n */\n @Prop() color: string = '#008480';\n\n /**\n * Whether the input is disabled\n */\n @Prop() disabled: boolean = false;\n\n /**\n * Whether the input is readonly\n */\n @Prop() readonly: boolean = false;\n\n /**\n * Whether to show clear button\n */\n @Prop() clearable: boolean = true;\n\n /**\n * Number of rows\n */\n @Prop() rows: number = 3;\n\n /**\n * Whether to hide validation details\n */\n @Prop() hideDetails: boolean | 'auto' = 'auto';\n\n /**\n * Error message\n */\n @Prop() error: string = '';\n\n /**\n * Helper text\n */\n @Prop() helperText: string = '';\n\n /**\n * Whether the input is required\n */\n @Prop() required: boolean = false;\n\n /**\n * Input event\n */\n @Event() xplorInput: EventEmitter<string>;\n\n /**\n * Change event\n */\n @Event() xplorChange: EventEmitter<string>;\n\n /**\n * Clear event\n */\n @Event() xplorClear: EventEmitter<void>;\n\n @State() isFocused: boolean = false;\n\n private handleInput = (event: Event) => {\n const target = event.target as HTMLTextAreaElement;\n this.value = target.value;\n this.xplorInput.emit(this.value);\n };\n\n private handleChange = (event: Event) => {\n const target = event.target as HTMLTextAreaElement;\n this.value = target.value;\n this.xplorChange.emit(this.value);\n };\n\n private handleClear = () => {\n this.value = '';\n this.xplorClear.emit();\n this.xplorChange.emit(this.value);\n };\n\n render() {\n const containerClasses = {\n 'xplor-input-text-area': true,\n 'xplor-input-text-area--focused': this.isFocused,\n 'xplor-input-text-area--disabled': this.disabled,\n 'xplor-input-text-area--error': !!this.error,\n };\n\n const showClearButton = this.clearable && this.value && !this.readonly && !this.disabled;\n const showDetails = this.hideDetails === false || (this.hideDetails === 'auto' && (this.error || this.helperText));\n\n return (\n <Host>\n <div class={containerClasses}>\n {this.label && (\n <label class=\"xplor-input-text-area__label\" htmlFor={this.inputId}>\n {this.label}\n {this.required && <span class=\"xplor-input-text-area__required\">*</span>}\n </label>\n )}\n\n <div class=\"xplor-input-text-area__field\">\n <textarea\n id={this.inputId}\n class=\"xplor-input-text-area__input\"\n value={this.value}\n placeholder={this.placeholder}\n disabled={this.disabled}\n readonly={this.readonly}\n required={this.required}\n rows={this.rows}\n onInput={this.handleInput}\n onChange={this.handleChange}\n onFocus={() => (this.isFocused = true)}\n onBlur={() => (this.isFocused = false)}\n style={{\n backgroundColor: this.bgColor,\n }}\n aria-invalid={this.error ? 'true' : undefined}\n aria-required={this.required ? 'true' : undefined}\n aria-describedby={this.error ? this.errorId : this.helperText ? this.helperId : undefined}\n />\n {showClearButton && (\n <button\n type=\"button\"\n class=\"xplor-input-text-area__clear\"\n onClick={this.handleClear}\n aria-label=\"Clear\"\n >\n ✕\n </button>\n )}\n </div>\n\n {showDetails && (\n <div class=\"xplor-input-text-area__details\">\n {this.error && <div class=\"xplor-input-text-area__error-message\" id={this.errorId}>{this.error}</div>}\n {!this.error && this.helperText && <div class=\"xplor-input-text-area__helper-text\" id={this.helperId}>{this.helperText}</div>}\n </div>\n )}\n </div>\n </Host>\n );\n }\n}\n",":host {\n display: block;\n}\n\n.input-secondary {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n\n &__label {\n font-size: 0.875rem;\n color: rgba(0, 0, 0, 0.6);\n margin-bottom: 0.25rem;\n }\n\n &__required {\n color: #d32f2f;\n margin-left: 0.25rem;\n }\n\n &__field {\n position: relative;\n display: flex;\n align-items: center;\n }\n\n &__input {\n width: 100%;\n padding: 0.875rem 1rem;\n font-size: 1rem;\n font-family: inherit;\n border: 1px solid rgba(0, 0, 0, 0.23);\n border-radius: 16px;\n outline: none;\n transition: border-color 0.2s ease, border-width 0.2s ease;\n\n &::placeholder {\n color: rgba(0, 0, 0, 0.38);\n }\n\n &:hover:not(:disabled) {\n border-color: rgba(0, 0, 0, 0.6);\n }\n\n &:focus {\n border-color: #008480;\n border-width: 2px;\n padding: calc(0.875rem - 1px) calc(1rem - 1px);\n }\n\n &:disabled {\n background-color: rgba(0, 0, 0, 0.04);\n color: rgba(0, 0, 0, 0.38);\n cursor: not-allowed;\n }\n\n &:read-only {\n background-color: rgba(0, 0, 0, 0.04);\n }\n }\n\n &--dirty {\n .input-secondary__input {\n border-color: #008480;\n border-width: 2px;\n padding: calc(0.875rem - 1px) calc(1rem - 1px);\n }\n }\n\n &--error {\n .input-secondary__input {\n border-color: #d32f2f;\n }\n }\n\n &__details {\n min-height: 1.25rem;\n padding: 0 1rem;\n font-size: 0.75rem;\n }\n\n &__error-message {\n color: #d32f2f;\n }\n\n &__helper-text {\n color: rgba(0, 0, 0, 0.6);\n }\n}\n","import { Component, Host, h, Prop, Event, EventEmitter, State } from '@stencil/core';\n\nlet inputTextSecondaryIdCounter = 0;\n\n@Component({\n tag: 'xplor-input-text-secondary',\n styleUrl: 'xplor-input-text-secondary.scss',\n scoped: true,\n})\nexport class XplorInputTextSecondary {\n private inputId = `xplor-input-text-secondary-${++inputTextSecondaryIdCounter}`;\n private errorId = `${this.inputId}-error`;\n private helperId = `${this.inputId}-helper`;\n @Prop({ mutable: true }) value: string = '';\n @Prop() label: string = '';\n @Prop() placeholder: string = '';\n @Prop() type: string = 'text';\n @Prop() bgColor: string = 'white';\n @Prop() disabled: boolean = false;\n @Prop() readonly: boolean = false;\n @Prop() hideDetails: boolean | 'auto' = 'auto';\n @Prop() error: string = '';\n @Prop() helperText: string = '';\n @Prop() required: boolean = false;\n @Prop() isDirty: boolean = false;\n\n @Event() xplorInput: EventEmitter<string>;\n @Event() xplorChange: EventEmitter<string>;\n @Event() xplorFocus: EventEmitter<FocusEvent>;\n @Event() xplorBlur: EventEmitter<FocusEvent>;\n\n @State() isFocused: boolean = false;\n\n private handleInput = (event: Event) => {\n const target = event.target as HTMLInputElement;\n this.value = target.value;\n this.xplorInput.emit(this.value);\n };\n\n private handleChange = (event: Event) => {\n const target = event.target as HTMLInputElement;\n this.value = target.value;\n this.xplorChange.emit(this.value);\n };\n\n private handleFocus = (event: FocusEvent) => {\n this.isFocused = true;\n this.xplorFocus.emit(event);\n };\n\n private handleBlur = (event: FocusEvent) => {\n this.isFocused = false;\n this.xplorBlur.emit(event);\n };\n\n render() {\n const containerClasses = {\n 'input-secondary': true,\n 'input-secondary--focused': this.isFocused,\n 'input-secondary--disabled': this.disabled,\n 'input-secondary--error': !!this.error,\n 'input-secondary--dirty': this.isDirty,\n };\n\n const showDetails = this.hideDetails === false || (this.hideDetails === 'auto' && (this.error || this.helperText));\n\n return (\n <Host>\n <div class={containerClasses}>\n {this.label && (\n <label class=\"input-secondary__label\" htmlFor={this.inputId}>\n {this.label}\n {this.required && <span class=\"input-secondary__required\">*</span>}\n </label>\n )}\n\n <div class=\"input-secondary__field\">\n <input\n id={this.inputId}\n type={this.type}\n class=\"input-secondary__input\"\n value={this.value}\n placeholder={this.placeholder}\n disabled={this.disabled}\n readonly={this.readonly}\n required={this.required}\n onInput={this.handleInput}\n onChange={this.handleChange}\n onFocus={this.handleFocus}\n onBlur={this.handleBlur}\n style={{\n backgroundColor: this.bgColor,\n }}\n aria-invalid={this.error ? 'true' : undefined}\n aria-required={this.required ? 'true' : undefined}\n aria-describedby={this.error ? this.errorId : this.helperText ? this.helperId : undefined}\n />\n <slot name=\"append-inner\" />\n </div>\n\n {showDetails && (\n <div class=\"input-secondary__details\">\n {this.error && <div class=\"input-secondary__error-message\" id={this.errorId}>{this.error}</div>}\n {!this.error && this.helperText && <div class=\"input-secondary__helper-text\" id={this.helperId}>{this.helperText}</div>}\n </div>\n )}\n\n <slot name=\"append\" />\n </div>\n </Host>\n );\n }\n}\n",":host {\n display: block;\n}\n\n.xplor-input-title {\n width: 100%;\n height: 39px;\n font-size: 28px;\n font-family: inherit;\n font-weight: 400;\n border: none;\n border-bottom: 1px solid rgba(0, 0, 0, 0.42);\n outline: none;\n padding: 0 0 4px 0;\n background: transparent;\n transition: border-color 0.2s ease;\n\n &::placeholder {\n color: rgba(0, 0, 0, 0.38);\n }\n\n &:hover:not(:disabled) {\n border-bottom-color: rgba(0, 0, 0, 0.87);\n }\n\n &:focus {\n border-bottom-width: 2px;\n border-bottom-color: #008480;\n padding-bottom: 3px;\n }\n\n &:disabled {\n color: rgba(0, 0, 0, 0.38);\n border-bottom-color: rgba(0, 0, 0, 0.26);\n cursor: not-allowed;\n }\n\n &:read-only {\n color: rgba(0, 0, 0, 0.6);\n }\n}\n","import { Component, Host, h, Prop, Event, EventEmitter } from '@stencil/core';\n\n@Component({\n tag: 'xplor-input-title',\n styleUrl: 'xplor-input-title.scss',\n scoped: true,\n})\nexport class XplorInputTitle {\n /**\n * Input value\n */\n @Prop({ mutable: true }) value: string = '';\n\n /**\n * Input placeholder\n */\n @Prop() placeholder: string = '';\n\n /**\n * Whether the input is disabled\n */\n @Prop() disabled: boolean = false;\n\n /**\n * Whether the input is readonly\n */\n @Prop() readonly: boolean = false;\n\n /**\n * Accessible label for the input\n */\n @Prop() ariaLabel: string = 'Title';\n\n /**\n * Input event\n */\n @Event() xplorInput: EventEmitter<string>;\n\n /**\n * Change event\n */\n @Event() xplorChange: EventEmitter<string>;\n\n private handleInput = (event: Event) => {\n const target = event.target as HTMLInputElement;\n this.value = target.value;\n this.xplorInput.emit(this.value);\n };\n\n private handleChange = (event: Event) => {\n const target = event.target as HTMLInputElement;\n this.value = target.value;\n this.xplorChange.emit(this.value);\n };\n\n render() {\n return (\n <Host>\n <input\n type=\"text\"\n class=\"xplor-input-title\"\n value={this.value}\n placeholder={this.placeholder}\n disabled={this.disabled}\n readonly={this.readonly}\n aria-label={this.ariaLabel}\n onInput={this.handleInput}\n onChange={this.handleChange}\n />\n </Host>\n );\n }\n}\n",":host {\n display: block;\n}\n.x-link {\n display: block;\n padding: 0.5rem 0;\n text-decoration: none;\n color: var(--xplor-link-color);\n}\n","import { Component, h, Prop, Host } from '@stencil/core';\n@Component({\n tag: 'xplor-links',\n styleUrl: 'xplor-links.css',\n shadow: true,\n})\nexport class XplorLinks {\n @Prop() brand: string;\n\n /** Alt text for the image */\n @Prop() imageAlt: string = '';\n render() {\n return (\n <Host class={`theme-${this.brand}`}>\n <a class=\"x-link\" href=\"https://google.com\">\n {' '}\n googole this is a link{' '}\n </a>\n <div class=\"bg-black p-2 rounded-md flex justify-center\">\n <h1 class=\"text-primary font-sans\">This is a Stencil component using Tailwind</h1>\n </div>\n <div class=\"bg-white py-24 sm:py-32\">\n <div class=\"mx-auto grid max-w-7xl gap-20 px-6 lg:px-8 xl:grid-cols-3\">\n <div class=\"max-w-xl\">\n <h2 class=\"text-pretty text-3xl font-semibold tracking-tight text-gray-900 sm:text-4xl\">\n Meet our leadership\n </h2>\n <p class=\"mt-6 text-lg/8 text-gray-600\">\n We’re a dynamic group of individuals who are passionate about what we do and dedicated to delivering the\n best results for our clients.\n </p>\n </div>\n <ul role=\"list\" class=\"grid gap-x-8 gap-y-12 sm:grid-cols-2 sm:gap-y-16 xl:col-span-2\">\n <li>\n <div class=\"flex items-center gap-x-6\">\n <img\n class=\"size-16 rounded-full\"\n src=\"https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80\"\n alt={this.imageAlt}\n />\n <div>\n <h3 class=\"text-base/7 font-semibold tracking-tight text-gray-900\">Leslie Alexander</h3>\n <p class=\"text-sm/6 font-semibold text-indigo-600\">Co-Founder / CEO</p>\n </div>\n </div>\n </li>\n </ul>\n </div>\n </div>\n </Host>\n );\n }\n}\n",":host {\n display: contents;\n}\n\n.xplor-modal {\n &__backdrop {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background-color: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 2000;\n padding: 1rem;\n }\n\n &__card {\n position: relative;\n background-color: white;\n border-radius: 1rem;\n padding: 1rem;\n max-width: 90vw;\n display: flex;\n flex-direction: column;\n box-shadow: 0px 11px 15px -7px rgba(0, 0, 0, 0.2),\n 0px 24px 38px 3px rgba(0, 0, 0, 0.14),\n 0px 9px 46px 8px rgba(0, 0, 0, 0.12);\n animation: xplor-modal-fade-in 0.2s ease-out;\n\n &--scrollable {\n overflow: hidden;\n }\n }\n\n &__close-btn {\n position: absolute;\n top: 1rem;\n right: 1rem;\n width: 2.25rem;\n height: 2.25rem;\n border: none;\n background-color: white;\n color: #008480;\n font-size: 1rem;\n cursor: pointer;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s ease;\n z-index: 1;\n\n &:hover {\n background-color: #E6F7F7;\n }\n\n &:active {\n background-color: #D0EBD2;\n }\n }\n\n &__title {\n padding-right: 3rem;\n margin-bottom: 0.5rem;\n font-size: 1.5rem;\n font-weight: 500;\n color: rgba(0, 0, 0, 0.87);\n white-space: normal;\n word-wrap: break-word;\n }\n\n &__subtitle {\n margin: 0.5rem;\n margin-bottom: 1rem;\n font-size: 0.875rem;\n color: rgba(0, 0, 0, 0.6);\n }\n\n &__body {\n flex: 1;\n overflow-y: auto;\n margin-bottom: 1rem;\n\n &--no-title {\n margin-top: 3.5rem;\n }\n }\n\n &__actions {\n display: flex;\n gap: 0.5rem;\n justify-content: flex-end;\n margin: 1rem 0;\n }\n\n &__loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 3rem;\n }\n\n &__spinner {\n width: 3rem;\n height: 3rem;\n border: 4px solid rgba(0, 0, 0, 0.1);\n border-top-color: #008480;\n border-radius: 50%;\n animation: xplor-spinner-rotate 0.8s linear infinite;\n }\n}\n\n@keyframes xplor-modal-fade-in {\n from {\n opacity: 0;\n transform: scale(0.95);\n }\n to {\n opacity: 1;\n transform: scale(1);\n }\n}\n\n@keyframes xplor-spinner-rotate {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(360deg);\n }\n}\n","import { Component, Host, h, Prop, Event, EventEmitter, Watch, Element, Listen } from '@stencil/core';\n\n@Component({\n tag: 'xplor-modal',\n styleUrl: 'xplor-modal.scss',\n scoped: true,\n})\nexport class XplorModal {\n /**\n * Whether the modal is open\n */\n @Prop({ mutable: true }) open: boolean = false;\n\n /**\n * Modal width\n */\n @Prop() width: string = '600px';\n\n /**\n * Maximum width\n */\n @Prop() maxWidth: string = '90%';\n\n /**\n * Maximum height\n */\n @Prop() maxHeight: string = '90%';\n\n /**\n * Whether the modal content is scrollable\n */\n @Prop() scrollable: boolean = true;\n\n /**\n * Persistent mode - prevents closing on backdrop click\n */\n @Prop() persistent: boolean = false;\n\n /**\n * Loading state\n */\n @Prop() loading: boolean = false;\n\n /**\n * Whether to show the title area (for spacing)\n */\n @Prop() showTitle: boolean = true;\n\n /**\n * Accessible label for the modal (used if no title slot)\n */\n @Prop() ariaLabel: string;\n\n /**\n * Close event\n */\n @Event() xplorClose: EventEmitter<void>;\n\n @Element() el: HTMLElement;\n\n private previouslyFocusedElement: HTMLElement | null = null;\n private dialogEl: HTMLElement;\n\n @Watch('open')\n handleOpenChange(newValue: boolean) {\n if (newValue) {\n document.body.style.overflow = 'hidden';\n this.previouslyFocusedElement = document.activeElement as HTMLElement;\n requestAnimationFrame(() => {\n this.setInitialFocus();\n });\n } else {\n document.body.style.overflow = '';\n if (this.previouslyFocusedElement) {\n this.previouslyFocusedElement.focus();\n this.previouslyFocusedElement = null;\n }\n }\n }\n\n disconnectedCallback() {\n document.body.style.overflow = '';\n }\n\n @Listen('keydown')\n handleKeyDown(event: KeyboardEvent) {\n if (!this.open) return;\n\n if (event.key === 'Escape' && !this.persistent) {\n event.preventDefault();\n this.closeModal();\n return;\n }\n\n if (event.key === 'Tab') {\n this.trapFocus(event);\n }\n }\n\n private getFocusableElements(): HTMLElement[] {\n if (!this.dialogEl) return [];\n const selectors = 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex=\"-1\"])';\n return Array.from(this.dialogEl.querySelectorAll(selectors)) as HTMLElement[];\n }\n\n private trapFocus(event: KeyboardEvent) {\n const focusableElements = this.getFocusableElements();\n if (focusableElements.length === 0) return;\n\n const firstElement = focusableElements[0];\n const lastElement = focusableElements[focusableElements.length - 1];\n\n if (event.shiftKey) {\n if (document.activeElement === firstElement) {\n event.preventDefault();\n lastElement.focus();\n }\n } else {\n if (document.activeElement === lastElement) {\n event.preventDefault();\n firstElement.focus();\n }\n }\n }\n\n private setInitialFocus() {\n const focusableElements = this.getFocusableElements();\n if (focusableElements.length > 0) {\n focusableElements[0].focus();\n } else if (this.dialogEl) {\n this.dialogEl.focus();\n }\n }\n\n private handleBackdropClick = () => {\n if (!this.persistent) {\n this.closeModal();\n }\n };\n\n private handleCardClick = (event: Event) => {\n event.stopPropagation();\n };\n\n private closeModal = () => {\n this.open = false;\n this.xplorClose.emit();\n };\n\n render() {\n if (!this.open) {\n return null;\n }\n\n const cardClasses = {\n 'xplor-modal__card': true,\n 'xplor-modal__card--scrollable': this.scrollable,\n };\n\n const bodyClasses = {\n 'xplor-modal__body': true,\n 'xplor-modal__body--no-title': !this.showTitle,\n };\n\n return (\n <Host>\n <div class=\"xplor-modal__backdrop\" onClick={this.handleBackdropClick}>\n <div\n class={cardClasses}\n style={{\n width: this.width,\n maxWidth: this.maxWidth,\n maxHeight: this.maxHeight,\n }}\n onClick={this.handleCardClick}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={this.ariaLabel ? undefined : 'xplor-modal-title'}\n aria-label={this.ariaLabel}\n tabindex=\"-1\"\n ref={(el) => (this.dialogEl = el)}\n >\n <button\n type=\"button\"\n class=\"xplor-modal__close-btn\"\n onClick={this.closeModal}\n aria-label=\"Close modal\"\n data-testid=\"common-modal-close-button\"\n >\n ✕\n </button>\n\n <div class=\"xplor-modal__title\" id=\"xplor-modal-title\">\n <slot name=\"title\" />\n </div>\n\n <div class=\"xplor-modal__subtitle\">\n <slot name=\"subtitle\" />\n </div>\n\n <div class={bodyClasses}>\n {this.loading ? (\n <div class=\"xplor-modal__loading\" role=\"status\" aria-label=\"Loading\">\n <div class=\"xplor-modal__spinner\"></div>\n </div>\n ) : ([\n <slot name=\"body\" />,\n <slot />\n ])}\n </div>\n\n <div class=\"xplor-modal__actions\">\n <slot name=\"actions\" />\n </div>\n </div>\n </div>\n </Host>\n );\n }\n}\n","import { Component, Host, h, Prop, Event, EventEmitter } from '@stencil/core';\n\n@Component({\n tag: 'xplor-modal-persistent',\n shadow: false,\n})\nexport class XplorModalPersistent {\n /**\n * Whether the modal is open\n */\n @Prop() open: boolean = false;\n\n /**\n * Modal width\n */\n @Prop() width: string = '600px';\n\n /**\n * Maximum width\n */\n @Prop() maxWidth: string = '90%';\n\n /**\n * Maximum height\n */\n @Prop() maxHeight: string = '90%';\n\n /**\n * Loading state\n */\n @Prop() loading: boolean = false;\n\n /**\n * Close event\n */\n @Event() xplorClose: EventEmitter<void>;\n\n render() {\n return (\n <Host>\n <xplor-modal\n open={this.open}\n width={this.width}\n maxWidth={this.maxWidth}\n maxHeight={this.maxHeight}\n loading={this.loading}\n persistent={true}\n onXplorClose={() => this.xplorClose.emit()}\n >\n <slot name=\"title\" slot=\"title\" />\n <slot name=\"subtitle\" slot=\"subtitle\" />\n <slot name=\"body\" slot=\"body\" />\n <slot name=\"actions\" slot=\"actions\" />\n </xplor-modal>\n </Host>\n );\n }\n}\n",":host {\n display: block;\n}\n\n.nav-tabs {\n display: flex;\n border-bottom: 2px solid #e0e0e0;\n gap: 0;\n\n &--grow {\n .nav-tabs__tab {\n flex: 1;\n }\n }\n}\n\n.nav-tabs__tab {\n background: none;\n border: none;\n padding: 0.75rem 1.5rem;\n font-family: inherit;\n font-size: 0.875rem;\n font-weight: 500;\n cursor: pointer;\n color: #757575;\n position: relative;\n transition: color 0.2s;\n white-space: nowrap;\n text-transform: uppercase;\n letter-spacing: 0.5px;\n\n &::after {\n content: '';\n position: absolute;\n bottom: -2px;\n left: 0;\n right: 0;\n height: 2px;\n background-color: transparent;\n transition: background-color 0.2s;\n }\n\n &:hover:not(&--disabled) {\n color: #424242;\n }\n\n &:focus {\n outline: 2px solid #1976d2;\n outline-offset: -2px;\n }\n\n &--active {\n color: #1976d2;\n\n &::after {\n background-color: #1976d2;\n }\n\n .nav-tabs--secondary & {\n color: #9c27b0;\n\n &::after {\n background-color: #9c27b0;\n }\n }\n }\n\n &--disabled {\n opacity: 0.4;\n cursor: not-allowed;\n }\n}\n\n.nav-tabs--secondary {\n .nav-tabs__tab {\n &:hover:not(.nav-tabs__tab--disabled) {\n color: #7b1fa2;\n }\n }\n}","import { Component, Host, h, Prop, Event, EventEmitter, Element, Listen } from '@stencil/core';\n\nexport interface NavTabItem {\n label: string;\n value: string;\n disabled?: boolean;\n}\n\n@Component({\n tag: 'xplor-nav-tabs',\n styleUrl: 'xplor-nav-tabs.scss',\n scoped: true,\n})\nexport class XplorNavTabs {\n @Element() el: HTMLElement;\n\n @Prop({ mutable: true }) value: string;\n @Prop() items: NavTabItem[] = [];\n @Prop() color: 'primary' | 'secondary' = 'primary';\n @Prop() grow: boolean = false;\n\n @Event() xplorChange: EventEmitter<string>;\n\n private handleTabClick = (item: NavTabItem) => {\n if (item.disabled) return;\n\n this.value = item.value;\n this.xplorChange.emit(item.value);\n };\n\n @Listen('keydown')\n handleKeyDown(event: KeyboardEvent) {\n const enabledItems = this.items.filter(item => !item.disabled);\n if (enabledItems.length === 0) return;\n\n const currentIndex = enabledItems.findIndex(item => item.value === this.value);\n let newIndex = currentIndex;\n\n switch (event.key) {\n case 'ArrowRight':\n event.preventDefault();\n newIndex = currentIndex < enabledItems.length - 1 ? currentIndex + 1 : 0;\n break;\n case 'ArrowLeft':\n event.preventDefault();\n newIndex = currentIndex > 0 ? currentIndex - 1 : enabledItems.length - 1;\n break;\n case 'Home':\n event.preventDefault();\n newIndex = 0;\n break;\n case 'End':\n event.preventDefault();\n newIndex = enabledItems.length - 1;\n break;\n default:\n return;\n }\n\n const newItem = enabledItems[newIndex];\n this.value = newItem.value;\n this.xplorChange.emit(newItem.value);\n\n // Focus the newly active tab button\n const buttons = this.el.querySelectorAll('button[role=\"tab\"]');\n const allItemIndex = this.items.indexOf(newItem);\n const targetButton = buttons[allItemIndex] as HTMLButtonElement;\n if (targetButton) {\n targetButton.focus();\n }\n }\n\n render() {\n return (\n <Host>\n <div\n class={{\n 'nav-tabs': true,\n 'nav-tabs--grow': this.grow,\n [`nav-tabs--${this.color}`]: true,\n }}\n role=\"tablist\"\n >\n {this.items.map((item) => (\n <button\n key={item.value}\n class={{\n 'nav-tabs__tab': true,\n 'nav-tabs__tab--active': this.value === item.value,\n 'nav-tabs__tab--disabled': item.disabled,\n }}\n onClick={() => this.handleTabClick(item)}\n disabled={item.disabled}\n role=\"tab\"\n aria-selected={this.value === item.value ? 'true' : 'false'}\n tabIndex={this.value === item.value ? 0 : -1}\n type=\"button\"\n >\n {item.label}\n </button>\n ))}\n <slot />\n </div>\n </Host>\n );\n }\n}\n","$color-gray-300: #d1d5db;\n$color-gray-400: #9ca3af;\n$color-gray-600: #6b7280;\n$color-gray-700: #374151;\n$color-green-100: #d1fae5;\n$color-green-200: #a7f3d0;\n$color-green-300: #6ee7b7;\n$color-green-600: #059669;\n$color-red-100: #fee2e2;\n$color-red-200: #fecaca;\n$color-red-300: #fca5a5;\n$color-red-500: #ef4444;\n$color-white: white;\n\n$radio-size: 20px;\n$radio-inner-size: 10px;\n$border-width: 2px;\n$transition-speed: 0.15s;\n$focus-ring-opacity: 0.2;\n$disabled-opacity: 0.4;\n\n:host {\n display: inline-block;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n}\n\n.radio-wrapper {\n display: inline-flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n\n &--disabled {\n cursor: not-allowed;\n }\n}\n\n.radio {\n width: $radio-size;\n height: $radio-size;\n border-radius: 50%;\n border: $border-width solid $color-gray-400;\n background: $color-white;\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n transition: all $transition-speed ease;\n outline: none;\n position: relative;\n flex-shrink: 0;\n\n // Hover\n &.hover {\n border-color: $color-green-600;\n background: $color-green-100;\n }\n\n // Focus\n &.focus {\n border-color: $color-green-600;\n background: $color-green-200;\n box-shadow: 0 0 0 3px rgba($color-green-600, $focus-ring-opacity);\n }\n\n // Pressed\n &.pressed {\n border-color: $color-green-600;\n background: $color-green-300;\n }\n\n // Checked\n &.checked {\n border-color: $color-green-600;\n\n &.hover {\n background: $color-green-100;\n\n .radio-inner {\n background: $color-green-600;\n }\n }\n\n &.focus {\n background: $color-green-200;\n box-shadow: 0 0 0 3px rgba($color-green-600, $focus-ring-opacity);\n\n .radio-inner {\n background: $color-green-600;\n }\n }\n\n &.pressed {\n background: $color-green-300;\n\n .radio-inner {\n background: $color-green-600;\n }\n }\n }\n\n // Error\n &.error {\n border-color: $color-red-500;\n\n &.hover {\n background: $color-red-100;\n border-color: $color-red-500;\n }\n\n &.focus {\n background: $color-red-200;\n border-color: $color-red-500;\n box-shadow: 0 0 0 3px rgba($color-red-500, $focus-ring-opacity);\n }\n\n &.pressed {\n background: $color-red-300;\n border-color: $color-red-500;\n }\n\n &.checked .radio-inner {\n background: $color-red-500;\n }\n }\n\n // Disabled\n &.disabled {\n opacity: $disabled-opacity;\n cursor: not-allowed;\n border-color: $color-gray-300;\n background: $color-white;\n\n &.checked {\n border-color: $color-gray-400;\n\n .radio-inner {\n background: $color-gray-400;\n }\n }\n }\n}\n\n.radio-inner {\n width: $radio-inner-size;\n height: $radio-inner-size;\n border-radius: 50%;\n background: $color-green-600;\n transform: scale(0);\n transition: transform $transition-speed ease;\n\n &--visible {\n transform: scale(1);\n }\n}\n\n.label {\n font-size: 14px;\n color: $color-gray-700;\n user-select: none;\n}\n\n.radio-wrapper--disabled .label {\n opacity: $disabled-opacity;\n}\n","import { Component, Prop, State, Event, EventEmitter, h, Watch, Element, Method } from '@stencil/core';\n\n@Component({\n tag: 'xplor-radio-btn',\n styleUrl: 'xplor-radio-btn.scss',\n shadow: true,\n})\nexport class XplorRadioBtn {\n @Element() el: HTMLElement;\n\n /** The label text displayed next to the radio button */\n @Prop() label: string = '';\n\n /** The value associated with this radio button */\n @Prop() value: string = '';\n\n /** The name attribute to group radio buttons together */\n @Prop() name: string = '';\n\n /** Whether this radio button is initially selected */\n @Prop() initialChecked: boolean = false;\n\n /** Whether this radio button is disabled */\n @Prop() disabled: boolean = false;\n\n /** Whether this radio button is in an error state */\n @Prop() error: boolean = false;\n\n @State() checked: boolean = false;\n @State() isHovered: boolean = false;\n @State() isFocused: boolean = false;\n @State() isPressed: boolean = false;\n\n /** Emitted when the radio button selection changes */\n @Event() radioChange: EventEmitter<{ value: string; checked: boolean }>;\n\n @Watch('initialChecked')\n watchCheckedProp(newValue: boolean) {\n this.checked = newValue;\n }\n\n componentWillLoad() {\n this.checked = this.initialChecked;\n }\n\n /** Programmatically deselect this radio button */\n @Method()\n async deselect() {\n this.checked = false;\n }\n\n private getSiblingRadios(): HTMLXplorRadioBtnElement[] {\n if (!this.name) return [];\n const parent = this.el.parentElement;\n if (!parent) return [];\n const all = Array.from(parent.querySelectorAll<HTMLXplorRadioBtnElement>(`xplor-radio-btn[name=\"${this.name}\"]`));\n return all.filter(radio => radio !== this.el);\n }\n\n private handleClick = () => {\n if (this.disabled || this.checked) return;\n\n // Deselect all siblings in the same name group\n this.getSiblingRadios().forEach(radio => radio.deselect());\n\n this.checked = true;\n this.radioChange.emit({ value: this.value, checked: this.checked });\n };\n\n private handleKeyDown = (e: KeyboardEvent) => {\n if (this.disabled) return;\n if (e.key === ' ' || e.key === 'Enter') {\n e.preventDefault();\n this.isPressed = true;\n this.handleClick();\n }\n };\n\n private handleKeyUp = (e: KeyboardEvent) => {\n if (e.key === ' ' || e.key === 'Enter') {\n this.isPressed = false;\n }\n };\n\n private getRadioClass = () => {\n const classes = ['radio'];\n\n if (this.checked) classes.push('checked');\n if (this.disabled) classes.push('disabled');\n if (this.error) classes.push('error');\n if (this.isHovered && !this.disabled) classes.push('hover');\n if (this.isFocused && !this.disabled) classes.push('focus');\n if (this.isPressed && !this.disabled) classes.push('pressed');\n\n return classes.join(' ');\n };\n\n render() {\n return (\n <label\n class={{\n 'radio-wrapper': true,\n 'radio-wrapper--disabled': this.disabled,\n }}\n >\n <div\n class={this.getRadioClass()}\n onClick={this.handleClick}\n onMouseEnter={() => (this.isHovered = true)}\n onMouseLeave={() => (this.isHovered = false)}\n onMouseDown={() => (this.isPressed = true)}\n onMouseUp={() => (this.isPressed = false)}\n onFocus={() => (this.isFocused = true)}\n onBlur={() => (this.isFocused = false)}\n onKeyDown={this.handleKeyDown}\n onKeyUp={this.handleKeyUp}\n tabIndex={this.disabled ? -1 : 0}\n role=\"radio\"\n aria-checked={this.checked.toString()}\n aria-disabled={this.disabled.toString()}\n aria-label={this.label}\n >\n <div class={{ 'radio-inner': true, 'radio-inner--visible': this.checked }} />\n </div>\n {this.label && (\n <span class=\"label\">{this.label}</span>\n )}\n </label>\n );\n }\n}\n","@use '../../styles/colours.scss' as colours;\n@use '../../styles/spacing.scss' as spacing;\n\n:host {\n display: block;\n}\n\n.section-card {\n background: white;\n display: flex;\n flex-direction: column;\n gap: 1rem;\n\n &--outlined {\n border: 2px solid #D0C7E5;\n }\n\n &--rounded {\n border-radius: 1rem;\n }\n\n &__body {\n flex: 1;\n }\n\n &__actions {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding-top: 0.5rem;\n\n &:empty {\n display: none;\n }\n }\n}\n","import { Component, Host, h, Prop } from '@stencil/core';\n\n@Component({\n tag: 'xplor-section-card',\n styleUrl: 'xplor-section-card.scss',\n scoped: true,\n})\nexport class XplorSectionCard {\n @Prop() outlined: boolean = true;\n @Prop() rounded: boolean = true;\n @Prop() padding: string = '1.5rem';\n\n render() {\n return (\n <Host>\n <div\n class={{\n 'section-card': true,\n 'section-card--outlined': this.outlined,\n 'section-card--rounded': this.rounded,\n }}\n style={{ padding: this.padding }}\n >\n <slot name=\"title\" />\n <slot name=\"subtitle\" />\n <div class=\"section-card__body\">\n <slot name=\"body\" />\n <slot />\n </div>\n <div class=\"section-card__actions\">\n <slot name=\"actions\" />\n </div>\n </div>\n </Host>\n );\n }\n}\n",":host {\n display: block;\n font-size: 1rem;\n}\n\n.section-heading {\n line-height: 1.33;\n letter-spacing: 3.2px;\n text-transform: uppercase;\n font-weight: 500;\n\n &--small {\n font-size: 0.9em;\n }\n\n &--large {\n font-size: 1.1em;\n }\n}\n","import { Component, Host, h, Prop } from '@stencil/core';\n\n@Component({\n tag: 'xplor-section-heading',\n styleUrl: 'xplor-section-heading.scss',\n scoped: true,\n})\nexport class XplorSectionHeading {\n @Prop() size: 'small' | 'medium' | 'large' = 'medium';\n @Prop() text: string;\n\n /**\n * Heading level (1-6), renders as h1-h6. Defaults to 2.\n */\n @Prop() level: 1 | 2 | 3 | 4 | 5 | 6 = 2;\n\n render() {\n const HeadingTag = `h${this.level}` as any;\n\n return (\n <Host>\n <HeadingTag\n class={{\n 'section-heading': true,\n 'section-heading--small': this.size === 'small',\n 'section-heading--large': this.size === 'large',\n }}\n >\n <slot>{this.text}</slot>\n </HeadingTag>\n </Host>\n );\n }\n}\n","import {\n Component,\n Prop,\n State,\n Element,\n Event,\n EventEmitter,\n h,\n Watch,\n Host,\n} from '@stencil/core';\nconst getIconType = (sortType) => {\n switch (sortType) {\n case 'asc':\n return 'arrow-up';\n case 'desc':\n return 'arrow-down';\n default:\n return 'dash';\n }\n};\n\n@Component({\n tag: 'xplor-table',\n // styleUrl: 'xplor-table.scss',\n shadow: true,\n})\n\nexport class XplorTable {\n @Element() el: HTMLXplorTableElement;\n\n /**\n * The header values for each column.\n */\n @Prop() columns?: string[];\n\n /**\n * The data for the body of the table.\n */\n @Prop() data?: string[][];\n\n /**\n * When true, the first column of the table is sticky and will cover the leftmost rows in a horizontally scrollable container.\n */\n @Prop() freeze?: boolean;\n\n /**\n * Toggles a selectable checkbox for each row in the table\n */\n @Prop() multiselect?: boolean;\n\n /**\n * Toggles an optional styling of the background of each even row of the table body.\n */\n @Prop() striped?: boolean;\n\n /**\n * The values for the input for each row when multiselect is activated.\n */\n @Prop() selectedValues?: string[] = [];\n\n /**\n * Toggles to show the sort button on each table head\n */\n @Prop() isSortable?: boolean = true;\n\n /**\n * Manually determined if the column is sortable\n */\n @Prop() sortableColumns?: boolean[] = [];\n\n @State() areAllSelected = false;\n\n @State() rowData: string[][];\n\n @State() hasScrolled = false;\n\n @State() selected: (string | boolean)[];\n\n @State() sortTypeArray: ('asc' | 'desc' | null)[] = [];\n @State() selectedDateRange: string = 'All';\n /**\n * Callback function that is called when the checkbox for a row of a\n * `multiselect` table is checked\n */\n @State() currentPage: number = 1;\n @State() totalPages: number = 3;\n @Event() tableSelect: EventEmitter;\n private handlePagination = (direction: 'first' | 'prev' | 'next' | 'last') => {\n switch (direction) {\n case 'first':\n this.currentPage = 1;\n break;\n case 'prev':\n if (this.currentPage > 1) this.currentPage--;\n break;\n case 'next':\n if (this.currentPage < this.totalPages) this.currentPage++;\n break;\n case 'last':\n this.currentPage = this.totalPages;\n break;\n }\n };\n \n private handleDateRangeChange = (event: Event) => {\n const target = event.target as HTMLSelectElement;\n this.selectedDateRange = target.value;\n };\n\n private handleFilterReports = () => {\n console.log('Filter reports clicked');\n };\n\n private handleDownloadAll = () => {\n console.log('Download all clicked');\n };\n\n // private handleDownloadReport = (index: number) => {\n // console.log(`Download report ${index} clicked`);\n // };\n private selectAllValue = Math.random().toString(36).slice(2);\n\n private container!: HTMLDivElement;\n\n private selectAll = (e: Event) => {\n const { target } = e;\n\n if (!(target instanceof HTMLInputElement)) return;\n\n const { checked } = target;\n\n this.areAllSelected = checked;\n\n this.selected =\n this.selectedValues.length > 0\n ? // gets all checkboxes in body\n Array.from(\n this.el.querySelectorAll('tbody td:first-child input'),\n ).map((input: HTMLInputElement) =>\n // if the select all checkbox is checked, return\n // the value from the current input. If false, set all to false.\n checked ? input?.value : checked,\n )\n : this.selected.map(() => checked);\n this.onChange();\n };\n\n private selectOne = (e: Event, checkboxIdx: number) => {\n const { target } = e;\n if (!(target instanceof HTMLInputElement)) return;\n\n const { checked, value } = target;\n\n this.areAllSelected = false;\n this.selected = this.selected.map((v, selectedIdx) => {\n // if the checkbox that fired the event is not the current idx\n // return the current value\n if (selectedIdx !== checkboxIdx) return v;\n\n /**\n * If there are values in this.selectedValues, either return the value\n * for that checkbox or false, dependent on if the checkbox is checked or not.\n * If there are no values in this.selectedValues, return the value\n * to either true or false, dependent on if the checkbox is checked or not.\n *\n */\n return this.selectedValues.length > 0\n ? checked\n ? value\n : checked\n : checked;\n });\n this.onChange();\n };\n\n private onChange = () => {\n this.tableSelect.emit({\n selected: this.selected,\n areAllSelected: this.areAllSelected,\n });\n };\n\n private onScroll = () => {\n this.hasScrolled = this.container.scrollLeft > 0;\n };\n\n private sortBy = (col: number) => {\n this.sortTypeArray = this.sortTypeArray.map((val, idx) => {\n if (idx !== col) return null;\n\n switch (val) {\n case 'asc':\n return 'desc';\n case 'desc':\n return null;\n default:\n return 'asc';\n }\n });\n\n const handleSort = (a, b) => {\n if (a[col].toLocaleLowerCase() < b[col].toLocaleLowerCase()) {\n return -1;\n }\n if (a[col].toLocaleLowerCase() > b[col].toLocaleLowerCase()) {\n return 1;\n }\n return 0;\n };\n\n if (this.sortTypeArray[col] === 'asc') {\n this.rowData.sort((a, b) => handleSort(a, b));\n } else if (this.sortTypeArray[col] === 'desc') {\n this.rowData.sort((a, b) => handleSort(b, a));\n } else {\n this.rowData = this.data;\n this.sortTypeArray[col] = null;\n }\n\n this.rowData = Array.from(this.rowData);\n this.render();\n };\n\n private setData = () => {\n this.rowData = this.data !== undefined ? Array.from(this.data) : [];\n };\n\n // Add this method to paginate rowData\nprivate getPaginatedData(): string[][] {\n const startIndex = (this.currentPage - 1) * 10;\n const endIndex = startIndex + 10;\n return this.rowData.slice(startIndex, endIndex);\n}\n\n @Watch('data')\n watchData() {\n this.setData();\n }\n\n componentWillLoad() {\n this.areAllSelected = false;\n this.setData();\n this.selected = new Array(this.rowData.length).fill(false);\n // Fill the Sort Type Array to default null depends on number of columns\n this.sortTypeArray = this.columns && this.columns.map(() => null);\n }\n\n render() {\n let className = 'xpl-table';\n if (this.striped) className += ' xpl-table--striped';\n if (this.freeze) className += ' xpl-table--freeze';\n if (this.hasScrolled) className += ' xpl-table--has-scrolled';\n\n const paginatedData = this.getPaginatedData();\n\n return (\n <Host class=\"xplor-table\">\n <div class=\"bg-white rounded-lg shadow-sm border border-gray-200 p-6 max-w-6xl mx-auto\">\n <div\n class=\"xpl-table-container\"\n onScroll={this.onScroll}\n ref={(el) => {\n this.container = el;\n }}\n >\n {/* Header */}\n <div class=\"mb-6\">\n <h1 class=\"text-xl font-semibold text-gray-900 mb-4\">Head Counts Report</h1>\n \n {/* Filter Controls */}\n <div class=\"flex flex-wrap items-center gap-4 mb-6\">\n <div class=\"flex items-center gap-2\">\n <label class=\"text-sm text-gray-600 font-medium\">Date Range</label>\n <select \n class=\"border border-gray-300 rounded px-3 py-1.5 text-sm bg-white focus:outline-none focus:ring-2 focus:ring-teal-500 focus:border-teal-500\"\n // value={this.selectedDateRange}\n onInput={this.handleDateRangeChange}\n >\n <option value=\"All\">All</option>\n <option value=\"Today\">Today</option>\n <option value=\"This Week\">This Week</option>\n <option value=\"This Month\">This Month</option>\n <option value=\"Custom\">Custom Range</option>\n </select>\n <button class=\"p-1.5 border border-gray-300 rounded hover:bg-gray-50\">\n <svg class=\"w-4 h-4 text-gray-500\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z\"/>\n </svg>\n </button>\n </div>\n \n <button \n onClick={this.handleFilterReports}\n class=\"bg-teal-600 hover:bg-teal-700 text-white px-4 py-1.5 rounded text-sm font-medium transition-colors\"\n >\n Filter Reports\n </button>\n \n <button \n onClick={this.handleDownloadAll}\n class=\"flex items-center gap-2 text-gray-600 hover:text-gray-800 text-sm\"\n >\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"/>\n </svg>\n Download All\n </button>\n </div>\n </div>\n\n <table class={`w-full ${className}`}>\n {this.columns && (\n <thead>\n {this.columns.map((column, i) => {\n const iconType = getIconType(\n this.sortTypeArray[i],\n );\n const isColumnSortable = !!(\n this.isSortable &&\n this.sortableColumns[i]\n );\n return (\n <th\n class=\"text-left py-3 px-4 text-sm font-medium text-gray-600\"\n aria-sort={\n isColumnSortable && this.sortTypeArray[i]\n ? this.sortTypeArray[i] === 'asc'\n ? 'ascending'\n : 'descending'\n : isColumnSortable\n ? 'none'\n : undefined\n }\n >\n {this.multiselect && i === 0 ? (\n <label\n onClick={(e) => {\n e.preventDefault();\n e.stopPropagation();\n if (isColumnSortable) {\n this.sortBy(i);\n }\n }}\n class={\n isColumnSortable\n ? 'cursor-pointer'\n : ''\n }\n >\n <input\n checked={\n this.areAllSelected\n }\n id=\"__xpl-table-th\"\n // appear indeterminate when at least one but not all\n // are selected\n\n indeterminate={\n !this\n .areAllSelected &&\n this.selected.some(\n (a) => a,\n )\n }\n onClick={(e) => {\n e.stopPropagation();\n this.selectAll(e);\n }}\n type=\"checkbox\"\n value={`select-all-${this.selectAllValue}`}\n aria-label=\"Select all rows\"\n />\n {column}\n {isColumnSortable &&\n !!this.sortTypeArray[\n i\n ] && (\n <xpl-icon\n icon={iconType}\n size={16}\n ></xpl-icon>\n )}\n </label>\n ) : (\n <label\n onClick={() =>\n isColumnSortable &&\n this.sortBy(i)\n }\n class={\n isColumnSortable\n ? 'cursor-pointer'\n : ''\n }\n aria-label={isColumnSortable ? `Sort by ${column}` : undefined}\n >\n {column}\n {isColumnSortable &&\n !!this.sortTypeArray[\n i\n ] && (\n <svg width=\"11\" height=\"6\" viewBox=\"0 0 11 6\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10.5 5.5L5.5 0.5L0.5 5.5L10.5 5.5Z\" fill=\"currentColor\"></path></svg>\n // <xpl-icon\n // icon={iconType}\n // size={16}\n // id=\"__xpl-icon-sort\"\n // ></xpl-icon>\n )}\n </label>\n )}\n </th>\n );\n })}\n </thead>\n )}\n <tbody>\n {paginatedData.map((row, rowNum) => (\n <tr\n class={`border-b border-gray-100 hover:bg-gray-50`}\n >\n {row.map((cell, i) => (\n <td class=\"py-3 px-4 text-sm text-gray-900\">\n {this.multiselect && i === 0 ? (\n <label\n class=\"flex items-center gap-2\"\n htmlFor={`__xpl-table-row-${\n rowNum\n }`}\n >\n <input\n id={`__xpl-table-row-${\n rowNum\n }`}\n checked={\n !!this.selected[\n rowNum\n ]\n }\n type=\"checkbox\"\n onChange={(e) =>\n this.selectOne(\n e,\n rowNum,\n )\n }\n value={\n this.selectedValues\n .length > 0\n ? this\n .selectedValues[\n rowNum\n ]\n : `xpl-table-checkbox-${rowNum}`\n }\n />\n <div innerHTML={cell} />\n </label>\n ) : (\n <div innerHTML={cell} />\n )}\n </td>\n ))}\n </tr>\n ))}\n \n </tbody>\n </table>\n {/* Pagination */}\n <div id=\"pagination\" class=\"w-full flex items-center justify-between mt-6 text-sm\">\n <div class=\"flex items-center gap-2\">\n <button \n onClick={() => this.handlePagination('first')}\n class=\"p-1.5 text-gray-400 hover:text-gray-600 disabled:opacity-50\"\n disabled={this.currentPage === 1}\n >\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M11 19l-7-7 7-7m8 14l-7-7 7-7\"/>\n </svg>\n </button>\n <button \n onClick={() => this.handlePagination('prev')}\n class=\"p-1.5 text-gray-400 hover:text-gray-600 disabled:opacity-50\"\n disabled={this.currentPage === 1}\n >\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 19l-7-7 7-7\"/>\n </svg>\n </button>\n </div>\n\n <span class=\"text-gray-600\">\n Page {this.currentPage} of {this.totalPages}\n </span>\n\n <div class=\"flex items-center gap-2\">\n <button \n onClick={() => this.handlePagination('next')}\n class=\"p-1.5 text-gray-400 hover:text-gray-600 disabled:opacity-50\"\n disabled={this.currentPage === this.totalPages}\n >\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 5l7 7-7 7\"/>\n </svg>\n </button>\n <button \n onClick={() => this.handlePagination('last')}\n class=\"p-1.5 text-gray-400 hover:text-gray-600 disabled:opacity-50\"\n disabled={this.currentPage === this.totalPages}\n >\n <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 5l7 7-7 7M5 5l7 7-7 7\"/>\n </svg>\n </button>\n </div>\n </div>\n </div>\n </div>\n </Host>\n\n );\n }\n}\n\n\n\n\n////////////// ######################## ///////////////////////////////// This code is commented out as it is not currently in use.\n\n\n\n\n// import { Component, Prop, State, h } from '@stencil/core';\n// import { StyledHost } from '../x-styles/x-styles';\n\n// interface ReportData {\n// submitDate: string;\n// time: string;\n// educatorName: string;\n// room: string;\n// }\n\n\n// @Component({\n// tag: 'xplor-table',\n// styleUrl: 'xplor-table.scss',\n// shadow: true,\n// })\n\n\n// export class XplorTable {\n// @State() selectedDateRange: string = 'All';\n// @State() currentPage: number = 1;\n// @State() totalPages: number = 1;\n// @State() sortBy: string = '';\n// @State() sortDirection: 'asc' | 'desc' = 'asc';\n// @Prop() tablecContent: ReportData[]\n// private reportData: ReportData[] = [\n// {\n// submitDate: '14/01/2025',\n// time: '10:01:21',\n// educatorName: 'Andi Kelman',\n// room: '2025 Holiday Programme'\n// },\n// {\n// submitDate: '10/10/2023',\n// time: '10:44:46',\n// educatorName: 'Andi Kelman',\n// room: '3 Kinder 3 - 23'\n// },\n// {\n// submitDate: '10/10/2023',\n// time: '10:36:15',\n// educatorName: 'Andi Kelman',\n// room: '3 Kinder 3 - 23'\n// },\n// {\n// submitDate: '28/03/2023',\n// time: '15:51:51',\n// educatorName: 'Cara Bierenkrant',\n// room: '8 KINDER 8 - CRECHE Kinder 8 2023'\n// }\n// ];\n\n// private handleDateRangeChange = (event: Event) => {\n// const target = event.target as HTMLSelectElement;\n// this.selectedDateRange = target.value;\n// };\n\n// private handleFilterReports = () => {\n// console.log('Filter reports clicked');\n// };\n\n// private handleDownloadAll = () => {\n// console.log('Download all clicked');\n// };\n\n// private handleDownloadReport = (index: number) => {\n// console.log(`Download report ${index} clicked`);\n// };\n\n// private handleSort = (column: string) => {\n// if (this.sortBy === column) {\n// this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';\n// } else {\n// this.sortBy = column;\n// this.sortDirection = 'asc';\n// }\n// };\n\n// private handlePagination = (direction: 'first' | 'prev' | 'next' | 'last') => {\n// switch (direction) {\n// case 'first':\n// this.currentPage = 1;\n// break;\n// case 'prev':\n// if (this.currentPage > 1) this.currentPage--;\n// break;\n// case 'next':\n// if (this.currentPage < this.totalPages) this.currentPage++;\n// break;\n// case 'last':\n// this.currentPage = this.totalPages;\n// break;\n// }\n// };\n\n// private getSortIcon(column: string) {\n// if (this.sortBy !== column) {\n// // Unsorted\n// return (\n// <svg class=\"w-3 h-3\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n// <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 9l4-4 4 4m0 6l-4 4-4-4\"/>\n// </svg>\n// );\n// }\n// if (this.sortDirection === 'asc') {\n// // Ascending\n// return (\n// <svg class=\"w-3 h-3\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n// <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 15l4-4 4 4\"/>\n// </svg>\n// );\n// }\n// // Descending\n// return (\n// <svg class=\"w-3 h-3\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n// <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M16 9l-4 4-4-4\"/>\n// </svg>\n// );\n// }\n\n// render() {\n// return (\n// <StyledHost class=\"xplor-table\">\n// <div class=\"bg-white rounded-lg shadow-sm border border-gray-200 p-6 max-w-6xl mx-auto\">\n// {/* Header */}\n// <div class=\"mb-6\">\n// <h1 class=\"text-xl font-semibold text-gray-900 mb-4\">Head Counts Report</h1>\n \n// {/* Filter Controls */}\n// <div class=\"flex flex-wrap items-center gap-4 mb-6\">\n// <div class=\"flex items-center gap-2\">\n// <label class=\"text-sm text-gray-600 font-medium\">Date Range</label>\n// <select \n// class=\"border border-gray-300 rounded px-3 py-1.5 text-sm bg-white focus:outline-none focus:ring-2 focus:ring-teal-500 focus:border-teal-500\"\n// // value={this.selectedDateRange}\n// onInput={this.handleDateRangeChange}\n// >\n// <option value=\"All\">All</option>\n// <option value=\"Today\">Today</option>\n// <option value=\"This Week\">This Week</option>\n// <option value=\"This Month\">This Month</option>\n// <option value=\"Custom\">Custom Range</option>\n// </select>\n// <button class=\"p-1.5 border border-gray-300 rounded hover:bg-gray-50\">\n// <svg class=\"w-4 h-4 text-gray-500\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n// <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z\"/>\n// </svg>\n// </button>\n// </div>\n \n// <button \n// onClick={this.handleFilterReports}\n// class=\"bg-teal-600 hover:bg-teal-700 text-white px-4 py-1.5 rounded text-sm font-medium transition-colors\"\n// >\n// Filter Reports\n// </button>\n \n// <button \n// onClick={this.handleDownloadAll}\n// class=\"flex items-center gap-2 text-gray-600 hover:text-gray-800 text-sm\"\n// >\n// <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n// <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"/>\n// </svg>\n// Download All\n// </button>\n// </div>\n// </div>\n\n// {/* Table */}\n// <div class=\"overflow-x-auto\">\n// <table class=\"w-full\">\n// <thead>\n// <tr class=\"border-b border-gray-200\">\n// <th class=\"text-left py-3 px-4 text-sm font-medium text-gray-600\">\n// <button \n// onClick={() => this.handleSort('submitDate')}\n// class=\"flex items-center gap-1 hover:text-gray-900\"\n// >\n// Submit Date\n// {this.getSortIcon('submitDate')}\n// </button>\n// </th>\n// <th class=\"text-left py-3 px-4 text-sm font-medium text-gray-600\">\n// <button \n// onClick={() => this.handleSort('time')}\n// class=\"flex items-center gap-1 hover:text-gray-900\"\n// >\n// Time\n// {this.getSortIcon('time')}\n// </button>\n// </th>\n// <th class=\"text-left py-3 px-4 text-sm font-medium text-gray-600\">\n// <button \n// onClick={() => this.handleSort('educatorName')}\n// class=\"flex items-center gap-1 hover:text-gray-900\"\n// >\n// Educator Name\n// {this.getSortIcon('educatorName')}\n// </button>\n// </th>\n// <th class=\"text-left py-3 px-4 text-sm font-medium text-gray-600\">\n// <button \n// onClick={() => this.handleSort('room')}\n// class=\"flex items-center gap-1 hover:text-gray-900\"\n// >\n// Room(s)\n// {this.getSortIcon('room')}\n// </button>\n// </th>\n// <th class=\"text-center py-3 px-4 text-sm font-medium text-gray-600\">\n// Download Report\n// </th>\n// </tr>\n// </thead>\n// <tbody>\n// {this.reportData.map((row, index) => (\n// <tr key={index} class=\"border-b border-gray-100 hover:bg-gray-50\">\n// <td class=\"py-3 px-4 text-sm text-gray-900\">{row.submitDate}</td>\n// <td class=\"py-3 px-4 text-sm text-gray-900\">{row.time}</td>\n// <td class=\"py-3 px-4 text-sm text-gray-900\">{row.educatorName}</td>\n// <td class=\"py-3 px-4 text-sm text-gray-900\">{row.room}</td>\n// <td class=\"py-3 px-4 text-center\">\n// <div class=\"flex items-center justify-center gap-2\">\n// <span class=\"bg-gray-100 text-gray-700 px-2 py-1 rounded text-xs\">\n// Toggle SortBy\n// </span>\n// <button \n// onClick={() => this.handleDownloadReport(index)}\n// class=\"p-1.5 text-teal-600 hover:text-teal-800 hover:bg-teal-50 rounded\"\n// >\n// <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n// <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z\"/>\n// </svg>\n// </button>\n// </div>\n// </td>\n// </tr>\n// ))}\n// </tbody>\n// </table>\n// </div>\n\n// {/* Pagination */}\n// <div class=\"flex items-center justify-between mt-6 text-sm\">\n// <div class=\"flex items-center gap-2\">\n// <button \n// onClick={() => this.handlePagination('first')}\n// class=\"p-1.5 text-gray-400 hover:text-gray-600 disabled:opacity-50\"\n// disabled={this.currentPage === 1}\n// >\n// <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n// <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M11 19l-7-7 7-7m8 14l-7-7 7-7\"/>\n// </button>\n// <button \n// onClick={() => this.handlePagination('prev')}\n// class=\"p-1.5 text-gray-400 hover:text-gray-600 disabled:opacity-50\"\n// disabled={this.currentPage === 1}\n// >\n// <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n// <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M15 19l-7-7 7-7\"/>\n// </button>\n// </div>\n\n// <span class=\"text-gray-600\">\n// Page {this.currentPage} of {this.totalPages}\n// </span>\n\n// <div class=\"flex items-center gap-2\">\n// <button \n// onClick={() => this.handlePagination('next')}\n// class=\"p-1.5 text-gray-400 hover:text-gray-600 disabled:opacity-50\"\n// disabled={this.currentPage === this.totalPages}\n// >\n// <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n// <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M9 5l7 7-7 7\"/>\n// </button>\n// <button \n// onClick={() => this.handlePagination('last')}\n// class=\"p-1.5 text-gray-400 hover:text-gray-600 disabled:opacity-50\"\n// disabled={this.currentPage === this.totalPages}\n// >\n// <svg class=\"w-4 h-4\" fill=\"none\" stroke=\"currentColor\" viewBox=\"0 0 24 24\">\n// <path stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"2\" d=\"M13 5l7 7-7 7M5 5l7 7-7 7\"/>\n// </svg>\n// </button>\n// </div>\n// </div>\n// </div>\n// </StyledHost>\n// );\n// }\n// }",":host {\n display: block;\n}\n\n.text-bubble {\n border-radius: 16px;\n padding: 12px;\n color: #000;\n\n &--green {\n border: 1px solid #00B2A8;\n background: #DFF2F1;\n }\n\n &--orange {\n border: 1px solid #F28602;\n background: #FEF2E0;\n }\n}\n","import { Component, Host, h, Prop } from '@stencil/core';\n\n@Component({\n tag: 'xplor-text-bubble',\n styleUrl: 'xplor-text-bubble.scss',\n scoped: true,\n})\nexport class XplorTextBubble {\n @Prop() color: 'green' | 'orange' = 'orange';\n\n render() {\n return (\n <Host>\n <div\n class={{\n 'text-bubble': true,\n 'text-bubble--green': this.color === 'green',\n 'text-bubble--orange': this.color === 'orange',\n }}\n >\n <slot />\n </div>\n </Host>\n );\n }\n}\n","@use '../../styles/colours.scss' as colours;\n@use '../../styles/spacing.scss' as spacing;\n@use '../../styles/mixins.scss' as mixins;\n\n:host {\n display: block;\n}\n\n.xplor-text-field {\n position: relative;\n width: 100%;\n\n &__wrapper {\n position: relative;\n display: flex;\n align-items: center;\n border-radius: 16px;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n &__input-wrapper {\n position: relative;\n flex: 1;\n display: flex;\n align-items: center;\n min-height: 56px;\n padding: 0 12px;\n }\n\n &__input {\n flex: 1;\n border: none;\n outline: none;\n background: transparent;\n font-size: 1rem;\n line-height: 1.5;\n padding: 8px 0;\n color: rgba(0, 0, 0, 0.87);\n margin-top: 8px;\n\n &::placeholder {\n color: rgba(0, 0, 0, 0.38);\n }\n\n &:disabled {\n color: rgba(0, 0, 0, 0.38);\n cursor: not-allowed;\n }\n }\n\n &__label {\n position: absolute;\n left: 12px;\n top: 50%;\n transform: translateY(-50%);\n pointer-events: none;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n font-size: 1rem;\n color: rgba(0, 0, 0, 0.6);\n background-color: transparent;\n padding: 0 4px;\n max-width: calc(100% - 24px);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n\n &--floating {\n top: 0;\n transform: translateY(0);\n font-size: 0.75rem;\n background-color: inherit;\n }\n }\n\n &__required {\n color: colours.$error;\n margin-left: 2px;\n }\n\n &__append-inner {\n display: flex;\n align-items: center;\n gap: 4px;\n margin-left: 8px;\n }\n\n &__append {\n display: flex;\n align-items: center;\n padding-right: 8px;\n }\n\n &__clear-btn {\n @include mixins.reset-button;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 24px;\n height: 24px;\n border-radius: 50%;\n color: rgba(0, 0, 0, 0.54);\n transition: all 0.2s ease;\n\n &:hover {\n background-color: rgba(0, 0, 0, 0.04);\n color: rgba(0, 0, 0, 0.87);\n }\n\n &:focus-visible {\n @include mixins.focus-ring;\n }\n }\n\n // Outlined variant (fieldset border)\n &__outline {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n margin: 0;\n padding: 0;\n border: 1px solid rgba(0, 0, 0, 0.23);\n border-radius: 16px;\n pointer-events: none;\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\n }\n\n &__outline-legend {\n padding: 0 4px;\n font-size: 0.75rem;\n visibility: hidden;\n max-width: 0.01px;\n transition: max-width 0.05s cubic-bezier(0, 0, 0.2, 1);\n white-space: nowrap;\n\n &--floating {\n max-width: 100%;\n transition: max-width 0.1s cubic-bezier(0.4, 0, 0.2, 1) 0.05s;\n }\n\n span {\n padding: 0 4px;\n display: inline-block;\n }\n }\n\n &__details {\n padding: 4px 12px 0;\n min-height: 22px;\n }\n\n &__error-messages {\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n\n &__error {\n font-size: 0.75rem;\n line-height: 1.5;\n color: colours.$error;\n }\n\n // Focused state\n &--focused {\n .xplor-text-field__outline {\n border-width: 2px;\n }\n\n .xplor-text-field__label {\n color: colours.$secondary;\n }\n }\n\n // Dirty state (field has been modified)\n &--dirty {\n .xplor-text-field__outline {\n border-color: #008480;\n border-width: 2px;\n }\n\n .xplor-text-field__label {\n color: #008480;\n }\n }\n\n // Error state\n &--error {\n .xplor-text-field__outline {\n border-color: colours.$error;\n }\n\n .xplor-text-field__label {\n color: colours.$error;\n }\n }\n\n // Disabled state\n &--disabled {\n opacity: 0.6;\n\n .xplor-text-field__outline {\n border-style: dashed;\n }\n\n .xplor-text-field__input {\n cursor: not-allowed;\n }\n }\n\n // Readonly state\n &--readonly {\n .xplor-text-field__input {\n cursor: default;\n }\n }\n\n // Color variants\n &--primary {\n &.xplor-text-field--focused {\n .xplor-text-field__outline {\n border-color: colours.$primary;\n }\n\n .xplor-text-field__label {\n color: colours.$primary;\n }\n }\n }\n\n &--secondary {\n &.xplor-text-field--focused {\n .xplor-text-field__outline {\n border-color: colours.$secondary;\n }\n\n .xplor-text-field__label {\n color: colours.$secondary;\n }\n }\n }\n\n &--success {\n &.xplor-text-field--focused {\n .xplor-text-field__outline {\n border-color: colours.$success;\n }\n\n .xplor-text-field__label {\n color: colours.$success;\n }\n }\n }\n\n &--warning {\n &.xplor-text-field--focused {\n .xplor-text-field__outline {\n border-color: colours.$warning;\n }\n\n .xplor-text-field__label {\n color: colours.$warning;\n }\n }\n }\n\n &--info {\n &.xplor-text-field--focused {\n .xplor-text-field__outline {\n border-color: colours.$info;\n }\n\n .xplor-text-field__label {\n color: colours.$info;\n }\n }\n }\n\n // Filled variant\n &--filled {\n .xplor-text-field__wrapper {\n background-color: rgba(0, 0, 0, 0.06);\n border-radius: 4px 4px 0 0;\n }\n\n .xplor-text-field__outline {\n border: none;\n border-bottom: 1px solid rgba(0, 0, 0, 0.42);\n border-radius: 0;\n }\n\n &.xplor-text-field--focused {\n .xplor-text-field__outline {\n border-bottom-width: 2px;\n }\n }\n }\n\n // Underlined variant\n &--underlined {\n .xplor-text-field__wrapper {\n background-color: transparent;\n }\n\n .xplor-text-field__outline {\n border: none;\n border-bottom: 1px solid rgba(0, 0, 0, 0.42);\n border-radius: 0;\n }\n\n &.xplor-text-field--focused {\n .xplor-text-field__outline {\n border-bottom-width: 2px;\n }\n }\n }\n}\n","import { Component, Host, h, Prop, State, Event, EventEmitter, Watch, Element } from '@stencil/core';\n\n@Component({\n tag: 'xplor-text-field',\n styleUrl: 'xplor-text-field.scss',\n scoped: true,\n})\nexport class XplorTextField {\n @Element() el: HTMLElement;\n\n /**\n * The current value of the text field\n */\n @Prop({ mutable: true }) value: string = '';\n\n /**\n * The label text for the input\n */\n @Prop() label: string = '';\n\n /**\n * Placeholder text when input is empty\n */\n @Prop() placeholder: string = '';\n\n /**\n * Input type (text, email, password, number, etc.)\n */\n @Prop() type: 'text' | 'email' | 'password' | 'number' | 'tel' | 'url' | 'search' = 'text';\n\n /**\n * Color variant (primary, secondary, success, error, warning, info)\n */\n @Prop() color: 'primary' | 'secondary' | 'success' | 'error' | 'warning' | 'info' = 'secondary';\n\n /**\n * Visual variant style\n */\n @Prop() variant: 'outlined' | 'filled' | 'underlined' = 'outlined';\n\n /**\n * Background color\n */\n @Prop() bgColor: string = 'white';\n\n /**\n * Error messages to display\n */\n @Prop() errorMessages: string[] = [];\n\n /**\n * When to show details: true (always), false (never), 'auto' (only when error)\n */\n @Prop() hideDetails: boolean | 'auto' = 'auto';\n\n /**\n * Whether the field is disabled\n */\n @Prop() disabled: boolean = false;\n\n /**\n * Whether the field is readonly\n */\n @Prop() readonly: boolean = false;\n\n /**\n * Whether the field is required\n */\n @Prop() required: boolean = false;\n\n /**\n * Whether the field has been modified (dirty state)\n */\n @Prop() isDirty: boolean = false;\n\n /**\n * Whether the field should be clearable\n */\n @Prop() clearable: boolean = false;\n\n /**\n * Custom CSS classes to apply\n */\n @Prop() customClass: string = '';\n\n /**\n * Maximum length of input\n */\n @Prop() maxlength: number;\n\n /**\n * Minimum value (for number type)\n */\n @Prop() min: number;\n\n /**\n * Maximum value (for number type)\n */\n @Prop() max: number;\n\n /**\n * Internal focused state\n */\n @State() isFocused: boolean = false;\n\n /**\n * Internal hasValue state\n */\n @State() hasValue: boolean = false;\n\n /**\n * Emitted when value changes\n */\n @Event() valueChange: EventEmitter<string>;\n\n /**\n * Emitted when input loses focus\n */\n @Event() inputBlur: EventEmitter<FocusEvent>;\n\n /**\n * Emitted when input gains focus\n */\n @Event() inputFocus: EventEmitter<FocusEvent>;\n\n /**\n * Emitted when clear button is clicked\n */\n @Event() clearClick: EventEmitter<void>;\n\n private inputElement?: HTMLInputElement;\n\n @Watch('value')\n handleValueChange(newValue: string) {\n this.hasValue = !!newValue;\n }\n\n componentWillLoad() {\n this.hasValue = !!this.value;\n }\n\n private handleInput = (e: Event) => {\n const target = e.target as HTMLInputElement;\n this.value = target.value;\n this.valueChange.emit(target.value);\n };\n\n private handleFocus = (e: FocusEvent) => {\n this.isFocused = true;\n this.inputFocus.emit(e);\n };\n\n private handleBlur = (e: FocusEvent) => {\n this.isFocused = false;\n this.inputBlur.emit(e);\n };\n\n private handleClear = (e: MouseEvent) => {\n e.stopPropagation();\n this.value = '';\n this.valueChange.emit('');\n this.clearClick.emit();\n if (this.inputElement) {\n this.inputElement.focus();\n }\n };\n\n private get hasError(): boolean {\n return this.errorMessages && this.errorMessages.length > 0;\n }\n\n private get showDetails(): boolean {\n if (typeof this.hideDetails === 'boolean') {\n return !this.hideDetails;\n }\n // hideDetails === 'auto'\n return this.hasError;\n }\n\n private get computedClasses(): { [key: string]: boolean } {\n return {\n 'xplor-text-field': true,\n [`xplor-text-field--${this.variant}`]: true,\n [`xplor-text-field--${this.color}`]: true,\n 'xplor-text-field--focused': this.isFocused,\n 'xplor-text-field--error': this.hasError,\n 'xplor-text-field--disabled': this.disabled,\n 'xplor-text-field--readonly': this.readonly,\n 'xplor-text-field--dirty': this.isDirty,\n 'xplor-text-field--has-value': this.hasValue || this.isFocused,\n [this.customClass]: !!this.customClass,\n };\n }\n\n render() {\n const labelFloating = this.isFocused || this.hasValue;\n\n return (\n <Host>\n <div class={this.computedClasses}>\n <div class=\"xplor-text-field__wrapper\" style={{ backgroundColor: this.bgColor }}>\n <div class=\"xplor-text-field__input-wrapper\">\n {/* Label */}\n {this.label && (\n <label\n class={{\n 'xplor-text-field__label': true,\n 'xplor-text-field__label--floating': labelFloating,\n }}\n >\n <slot name=\"label\">{this.label}</slot>\n {this.required && <span class=\"xplor-text-field__required\">*</span>}\n </label>\n )}\n\n {/* Input */}\n <input\n ref={(el) => (this.inputElement = el)}\n class=\"xplor-text-field__input\"\n type={this.type}\n value={this.value}\n placeholder={this.isFocused ? this.placeholder : ''}\n disabled={this.disabled}\n readonly={this.readonly}\n required={this.required}\n maxlength={this.maxlength}\n min={this.min}\n max={this.max}\n onInput={this.handleInput}\n onFocus={this.handleFocus}\n onBlur={this.handleBlur}\n aria-invalid={this.hasError ? 'true' : 'false'}\n aria-describedby={this.hasError ? 'error-messages' : undefined}\n />\n\n {/* Append Inner Slot */}\n <div class=\"xplor-text-field__append-inner\">\n {this.clearable && this.hasValue && !this.disabled && !this.readonly && (\n <button\n type=\"button\"\n class=\"xplor-text-field__clear-btn\"\n onClick={this.handleClear}\n aria-label=\"Clear\"\n >\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n <path d=\"M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z\" />\n </svg>\n </button>\n )}\n <slot name=\"append-inner\" />\n </div>\n\n {/* Field Outline */}\n <fieldset class=\"xplor-text-field__outline\">\n <legend class={{ 'xplor-text-field__outline-legend': true, 'xplor-text-field__outline-legend--floating': labelFloating }}>\n {labelFloating && this.label ? <span>{this.label}{this.required && '*'}</span> : <span></span>}\n </legend>\n </fieldset>\n </div>\n\n {/* Append Slot (outside input wrapper) */}\n <div class=\"xplor-text-field__append\">\n <slot name=\"append\" />\n </div>\n </div>\n\n {/* Details (error messages) */}\n {this.showDetails && (\n <div class=\"xplor-text-field__details\">\n {this.hasError && (\n <div id=\"error-messages\" class=\"xplor-text-field__error-messages\">\n {this.errorMessages.map((error) => (\n <div class=\"xplor-text-field__error\">{error}</div>\n ))}\n </div>\n )}\n </div>\n )}\n </div>\n </Host>\n );\n }\n}\n",":host {\n display: block;\n width: 100%;\n}\n\n.time-picker {\n position: relative;\n width: 100%;\n\n &--disabled {\n opacity: 0.6;\n cursor: not-allowed;\n }\n\n &__label {\n display: block;\n font-size: 0.875rem;\n color: rgba(0, 0, 0, 0.6);\n margin-bottom: 0.25rem;\n }\n\n &__required {\n color: #d32f2f;\n margin-left: 0.25rem;\n }\n\n &__field {\n position: relative;\n display: flex;\n align-items: center;\n border: 1px solid rgba(0, 0, 0, 0.23);\n border-radius: 1rem;\n transition: border-color 0.2s ease;\n background: white;\n\n &:focus-within {\n border-color: #008480;\n border-width: 2px;\n\n .time-picker__input {\n padding: calc(0.875rem - 1px) calc(1rem - 1px);\n }\n }\n }\n\n &--error &__field {\n border-color: #d32f2f;\n }\n\n &__input {\n flex: 1;\n width: 100%;\n padding: 0.875rem 1rem;\n font-size: 1rem;\n font-family: inherit;\n border: none;\n border-radius: 1rem;\n outline: none;\n background: transparent;\n\n &::placeholder {\n color: rgba(0, 0, 0, 0.38);\n }\n\n &:disabled {\n cursor: not-allowed;\n }\n }\n\n &__actions {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n padding-right: 0.5rem;\n flex-shrink: 0;\n }\n\n &__clear {\n background: none;\n border: none;\n font-size: 1.25rem;\n cursor: pointer;\n padding: 0;\n width: 1.5rem;\n height: 1.5rem;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #757575;\n border-radius: 50%;\n transition: background-color 0.2s;\n\n &:hover {\n background-color: #f5f5f5;\n color: #212121;\n }\n }\n\n &__icon-btn {\n background: none;\n border: none;\n cursor: pointer;\n padding: 0.25rem;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #757575;\n border-radius: 50%;\n transition: background-color 0.2s;\n\n &:hover:not(:disabled) {\n background-color: #f5f5f5;\n color: #212121;\n }\n\n &:disabled {\n cursor: not-allowed;\n opacity: 0.5;\n }\n }\n\n &__icon-svg {\n display: block;\n }\n\n &__dropdown {\n position: absolute;\n top: calc(100% + 4px);\n left: 0;\n z-index: 1000;\n background-color: #fff;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);\n padding: 1rem;\n }\n\n &__columns {\n display: flex;\n align-items: center;\n gap: 0.25rem;\n }\n\n &__column {\n display: flex;\n flex-direction: column;\n align-items: center;\n min-width: 48px;\n\n &--period {\n margin-left: 0.5rem;\n }\n }\n\n &__separator {\n font-size: 1.25rem;\n font-weight: 600;\n color: #424242;\n padding: 0 0.125rem;\n align-self: center;\n }\n\n &__spinner-btn {\n background: none;\n border: 1px solid #e0e0e0;\n border-radius: 4px;\n cursor: pointer;\n padding: 0.25rem;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #757575;\n transition: background-color 0.2s, border-color 0.2s;\n width: 100%;\n\n &:hover {\n background-color: #f5f5f5;\n border-color: #bdbdbd;\n color: #212121;\n }\n }\n\n &__value {\n font-size: 1.5rem;\n font-weight: 600;\n color: #212121;\n padding: 0.5rem 0;\n text-align: center;\n min-width: 48px;\n font-variant-numeric: tabular-nums;\n\n &--period {\n font-size: 1rem;\n font-weight: 500;\n color: #008480;\n }\n }\n\n &__details {\n min-height: 1.25rem;\n padding: 0 1rem;\n font-size: 0.75rem;\n }\n\n &__error-message {\n color: #d32f2f;\n }\n}\n","import { Component, Host, h, Prop, State, Event, EventEmitter, Element, Listen } from '@stencil/core';\n\n@Component({\n tag: 'xplor-time-picker',\n styleUrl: 'xplor-time-picker.scss',\n scoped: true,\n})\nexport class XplorTimePicker {\n @Element() el: HTMLElement;\n\n /** Time value in HH:mm:ss 24-hour format */\n @Prop({ mutable: true }) value: string = '';\n\n @Prop() label: string = '';\n @Prop() placeholder: string = 'Select time';\n @Prop() clearable: boolean = false;\n\n /** Auto-fill current time on focus if value is empty */\n @Prop() prefill: boolean = false;\n\n @Prop() bgColor: string = 'white';\n @Prop() showSeconds: boolean = false;\n @Prop() disabled: boolean = false;\n @Prop() readonly: boolean = false;\n @Prop() error: string = '';\n @Prop() hideDetails: boolean | 'auto' = 'auto';\n @Prop() required: boolean = false;\n\n @State() isOpen: boolean = false;\n @State() inputText: string = '';\n @State() hours: number = 12;\n @State() minutes: number = 0;\n @State() seconds: number = 0;\n @State() period: 'AM' | 'PM' = 'AM';\n @State() lastGoodValue: string = '';\n\n @Event() timeChange: EventEmitter<string>;\n @Event() xplorFocus: EventEmitter<FocusEvent>;\n @Event() xplorBlur: EventEmitter<FocusEvent>;\n @Event() xplorClear: EventEmitter<void>;\n\n componentWillLoad() {\n if (this.value) {\n this.parseValueToState(this.value);\n this.inputText = this.formatDisplayTime();\n this.lastGoodValue = this.inputText;\n }\n }\n\n @Listen('click', { target: 'document' })\n handleDocumentClick(event: MouseEvent) {\n const target = event.target as Node;\n if (!this.el.contains(target)) {\n this.isOpen = false;\n }\n }\n\n /** Parse HH:mm:ss (24h) into component state */\n private parseValueToState(val: string) {\n if (!val) return;\n const parts = val.split(':');\n let h = parseInt(parts[0], 10) || 0;\n const m = parseInt(parts[1], 10) || 0;\n const s = parseInt(parts[2], 10) || 0;\n\n this.period = h >= 12 ? 'PM' : 'AM';\n if (h === 0) {\n h = 12;\n } else if (h > 12) {\n h -= 12;\n }\n\n this.hours = h;\n this.minutes = m;\n this.seconds = s;\n }\n\n /** Convert current state to HH:mm:ss (24h) */\n private stateToValue(): string {\n let h = this.hours;\n if (this.period === 'AM' && h === 12) h = 0;\n else if (this.period === 'PM' && h !== 12) h += 12;\n\n const hStr = String(h).padStart(2, '0');\n const mStr = String(this.minutes).padStart(2, '0');\n const sStr = String(this.seconds).padStart(2, '0');\n return `${hStr}:${mStr}:${sStr}`;\n }\n\n /** Format for display: \"12:00 PM\" or \"12:00:00 PM\" */\n private formatDisplayTime(): string {\n const h = this.hours;\n const m = String(this.minutes).padStart(2, '0');\n if (this.showSeconds) {\n const s = String(this.seconds).padStart(2, '0');\n return `${h}:${m}:${s} ${this.period}`;\n }\n return `${h}:${m} ${this.period}`;\n }\n\n /** Port of Vue handleOnBlur time parsing logic */\n private parseInputText(text: string): boolean {\n const raw = text.trim();\n if (!raw) return false;\n\n // Handle bare am/pm\n if (raw.toLowerCase() === 'am' || raw.toLowerCase() === 'pm') {\n this.hours = 12;\n this.minutes = 0;\n this.seconds = 0;\n this.period = raw.toLowerCase() === 'pm' ? 'PM' : 'AM';\n return true;\n }\n\n // Detect AM/PM suffix\n let suffix: 'am' | 'pm' = 'am';\n if (raw.toLowerCase().indexOf('p') !== -1) {\n suffix = 'pm';\n }\n\n // Strip am/pm text\n const sanitised = raw.replace(/(\\s*)(pm|am|p|a)/gi, '').trim();\n const withColons = sanitised.replace(/\\./g, ':');\n const splits = withColons.split(':');\n\n let hour: number;\n let minute = 0;\n let second = 0;\n\n if (splits.length === 1) {\n // No colons: interpret based on length\n const num = sanitised.trim();\n if (num.length === 3) {\n hour = parseInt(num.substring(0, 1), 10);\n minute = parseInt(num.substring(1, 3), 10);\n } else if (num.length === 4) {\n hour = parseInt(num.substring(0, 2), 10);\n minute = parseInt(num.substring(2, 4), 10);\n } else if (num.length === 6) {\n hour = parseInt(num.substring(0, 2), 10);\n minute = parseInt(num.substring(2, 4), 10);\n second = parseInt(num.substring(4, 6), 10);\n } else {\n hour = parseInt(num, 10);\n }\n } else if (splits.length === 2) {\n hour = parseInt(splits[0].trim(), 10);\n minute = parseInt(splits[1].trim(), 10);\n } else if (splits.length === 3) {\n hour = parseInt(splits[0].trim(), 10);\n minute = parseInt(splits[1].trim(), 10);\n second = parseInt(splits[2].trim(), 10);\n } else {\n return false;\n }\n\n if (isNaN(hour) || hour < 0) return false;\n if (isNaN(minute)) minute = 0;\n if (isNaN(second)) second = 0;\n\n // Handle minute overflow\n if (minute >= 60) {\n hour += Math.floor(minute / 60);\n minute = minute % 60;\n }\n\n // Normalize hour and determine AM/PM\n if (hour >= 12) {\n suffix = 'pm';\n if (hour >= 24) {\n hour = hour % 24;\n suffix = hour >= 12 ? 'pm' : 'am';\n }\n if (hour > 12) {\n hour -= 12;\n }\n }\n\n if (hour === 0) {\n hour = 12;\n suffix = 'am';\n }\n\n // Clamp seconds\n if (second >= 60) second = 59;\n\n this.hours = hour;\n this.minutes = minute;\n this.seconds = second;\n this.period = suffix === 'pm' ? 'PM' : 'AM';\n return true;\n }\n\n private emitChange() {\n const val = this.stateToValue();\n this.value = val;\n this.inputText = this.formatDisplayTime();\n this.lastGoodValue = this.inputText;\n this.timeChange.emit(val);\n }\n\n private toggleDropdown = () => {\n if (this.disabled || this.readonly) return;\n this.isOpen = !this.isOpen;\n };\n\n private handleInputFocus = (event: FocusEvent) => {\n this.xplorFocus.emit(event);\n if (this.prefill && !this.value) {\n const now = new Date();\n this.hours = now.getHours() % 12 || 12;\n this.minutes = now.getMinutes();\n this.seconds = now.getSeconds();\n this.period = now.getHours() >= 12 ? 'PM' : 'AM';\n this.emitChange();\n }\n };\n\n private handleInputBlur = (event: FocusEvent) => {\n this.xplorBlur.emit(event);\n if (this.inputText.trim() === '') {\n return;\n }\n const ok = this.parseInputText(this.inputText);\n if (ok) {\n this.emitChange();\n } else {\n // Revert to last good value\n this.inputText = this.lastGoodValue;\n }\n };\n\n private handleInputChange = (event: Event) => {\n const input = event.target as HTMLInputElement;\n this.inputText = input.value;\n };\n\n private handleClear = (event: Event) => {\n event.stopPropagation();\n this.value = '';\n this.inputText = '';\n this.lastGoodValue = '';\n this.hours = 12;\n this.minutes = 0;\n this.seconds = 0;\n this.period = 'AM';\n this.timeChange.emit('');\n this.xplorClear.emit();\n };\n\n private incrementHours = () => {\n this.hours = this.hours >= 12 ? 1 : this.hours + 1;\n this.emitChange();\n };\n\n private decrementHours = () => {\n this.hours = this.hours <= 1 ? 12 : this.hours - 1;\n this.emitChange();\n };\n\n private incrementMinutes = () => {\n if (this.minutes >= 59) {\n this.minutes = 0;\n this.incrementHours();\n } else {\n this.minutes++;\n this.emitChange();\n }\n };\n\n private decrementMinutes = () => {\n if (this.minutes <= 0) {\n this.minutes = 59;\n this.decrementHours();\n } else {\n this.minutes--;\n this.emitChange();\n }\n };\n\n private incrementSeconds = () => {\n if (this.seconds >= 59) {\n this.seconds = 0;\n this.incrementMinutes();\n } else {\n this.seconds++;\n this.emitChange();\n }\n };\n\n private decrementSeconds = () => {\n if (this.seconds <= 0) {\n this.seconds = 59;\n this.decrementMinutes();\n } else {\n this.seconds--;\n this.emitChange();\n }\n };\n\n private togglePeriod = () => {\n this.period = this.period === 'AM' ? 'PM' : 'AM';\n this.emitChange();\n };\n\n private renderChevronUp() {\n return (\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"18 15 12 9 6 15\"></polyline>\n </svg>\n );\n }\n\n private renderChevronDown() {\n return (\n <svg viewBox=\"0 0 24 24\" width=\"16\" height=\"16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <polyline points=\"6 9 12 15 18 9\"></polyline>\n </svg>\n );\n }\n\n render() {\n const showDetails = this.hideDetails === false || (this.hideDetails === 'auto' && this.error);\n\n const clockIcon = (\n <svg class=\"time-picker__icon-svg\" viewBox=\"0 0 24 24\" width=\"20\" height=\"20\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"12\" cy=\"12\" r=\"10\"></circle>\n <polyline points=\"12 6 12 12 16 14\"></polyline>\n </svg>\n );\n\n return (\n <Host>\n <div class={{\n 'time-picker': true,\n 'time-picker--disabled': this.disabled,\n 'time-picker--error': !!this.error,\n 'time-picker--open': this.isOpen,\n }}>\n {this.label && (\n <label class=\"time-picker__label\">\n {this.label}\n {this.required && <span class=\"time-picker__required\">*</span>}\n </label>\n )}\n\n <div class=\"time-picker__field\">\n <input\n type=\"text\"\n class=\"time-picker__input\"\n value={this.inputText}\n placeholder={this.placeholder}\n disabled={this.disabled}\n readonly={this.readonly}\n onFocus={this.handleInputFocus}\n onBlur={this.handleInputBlur}\n onInput={this.handleInputChange}\n style={{ backgroundColor: this.bgColor }}\n />\n <div class=\"time-picker__actions\">\n {this.clearable && this.value && !this.disabled && !this.readonly && (\n <button type=\"button\" class=\"time-picker__clear\" onClick={this.handleClear} aria-label=\"Clear\">\n ×\n </button>\n )}\n <button type=\"button\" class=\"time-picker__icon-btn\" onClick={this.toggleDropdown} disabled={this.disabled} aria-label=\"Open time picker\">\n {clockIcon}\n </button>\n </div>\n </div>\n\n {showDetails && (\n <div class=\"time-picker__details\">\n {this.error && <div class=\"time-picker__error-message\">{this.error}</div>}\n </div>\n )}\n\n {this.isOpen && (\n <div class=\"time-picker__dropdown\">\n <div class=\"time-picker__columns\">\n {/* Hours column */}\n <div class=\"time-picker__column\">\n <button type=\"button\" class=\"time-picker__spinner-btn\" onClick={this.incrementHours} aria-label=\"Increase hours\">\n {this.renderChevronUp()}\n </button>\n <div class=\"time-picker__value\">{String(this.hours).padStart(2, '0')}</div>\n <button type=\"button\" class=\"time-picker__spinner-btn\" onClick={this.decrementHours} aria-label=\"Decrease hours\">\n {this.renderChevronDown()}\n </button>\n </div>\n\n <div class=\"time-picker__separator\">:</div>\n\n {/* Minutes column */}\n <div class=\"time-picker__column\">\n <button type=\"button\" class=\"time-picker__spinner-btn\" onClick={this.incrementMinutes} aria-label=\"Increase minutes\">\n {this.renderChevronUp()}\n </button>\n <div class=\"time-picker__value\">{String(this.minutes).padStart(2, '0')}</div>\n <button type=\"button\" class=\"time-picker__spinner-btn\" onClick={this.decrementMinutes} aria-label=\"Decrease minutes\">\n {this.renderChevronDown()}\n </button>\n </div>\n\n {this.showSeconds && [\n <div class=\"time-picker__separator\">:</div>,\n <div class=\"time-picker__column\">\n <button type=\"button\" class=\"time-picker__spinner-btn\" onClick={this.incrementSeconds} aria-label=\"Increase seconds\">\n {this.renderChevronUp()}\n </button>\n <div class=\"time-picker__value\">{String(this.seconds).padStart(2, '0')}</div>\n <button type=\"button\" class=\"time-picker__spinner-btn\" onClick={this.decrementSeconds} aria-label=\"Decrease seconds\">\n {this.renderChevronDown()}\n </button>\n </div>\n ]}\n\n {/* AM/PM column */}\n <div class=\"time-picker__column time-picker__column--period\">\n <button type=\"button\" class=\"time-picker__spinner-btn\" onClick={this.togglePeriod} aria-label=\"Toggle AM/PM\">\n {this.renderChevronUp()}\n </button>\n <div class=\"time-picker__value time-picker__value--period\">{this.period}</div>\n <button type=\"button\" class=\"time-picker__spinner-btn\" onClick={this.togglePeriod} aria-label=\"Toggle AM/PM\">\n {this.renderChevronDown()}\n </button>\n </div>\n </div>\n </div>\n )}\n </div>\n </Host>\n );\n }\n}\n",":host {\n display: inline-block;\n position: relative;\n}\n\n.tooltip-trigger {\n display: inline-flex;\n cursor: pointer;\n}\n\n.tooltip {\n position: fixed;\n z-index: 9999;\n background-color: #424242;\n color: #fff;\n border-radius: 4px;\n padding: 0.5rem 0.75rem;\n font-size: 0.875rem;\n line-height: 1.4;\n max-width: 300px;\n word-wrap: break-word;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n pointer-events: none;\n opacity: 0;\n animation: tooltipFadeIn 0.2s ease forwards;\n}\n\n@keyframes tooltipFadeIn {\n from {\n opacity: 0;\n transform: scale(0.9);\n }\n\n to {\n opacity: 1;\n transform: scale(1);\n }\n}\n\n.tooltip__content {\n position: relative;\n z-index: 1;\n}\n\n.tooltip__arrow {\n position: absolute;\n width: 12px;\n height: 12px;\n background-color: #424242;\n z-index: 0;\n}\n\n.tooltip--top .tooltip__arrow {\n margin-top: -6px;\n box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);\n}\n\n.tooltip--bottom .tooltip__arrow {\n box-shadow: -2px -2px 4px rgba(0, 0, 0, 0.1);\n}\n\n.tooltip--left .tooltip__arrow {\n margin-left: -6px;\n display: block;\n box-shadow: 2px -2px 4px rgba(0, 0, 0, 0.1);\n}\n\n.tooltip--right .tooltip__arrow {\n box-shadow: -2px 2px 4px rgba(0, 0, 0, 0.1);\n}","import { Component, Host, h, Prop, State, Element, Listen } from '@stencil/core';\n\nlet tooltipIdCounter = 0;\n\nexport type TooltipPosition = 'top' | 'bottom' | 'left' | 'right';\nexport type TooltipTrigger = 'hover' | 'click' | 'manual';\n\n@Component({\n tag: 'xplor-tooltip',\n styleUrl: 'xplor-tooltip.scss',\n scoped: true,\n})\nexport class XplorTooltip {\n @Element() el: HTMLElement;\n\n @Prop() position: TooltipPosition = 'top';\n @Prop() trigger: TooltipTrigger = 'hover';\n @Prop() arrow: boolean = true;\n @Prop({ mutable: true }) open: boolean = false;\n @Prop() content: string;\n @Prop() disabled: boolean = false;\n\n @State() tooltipStyle: any = {};\n @State() arrowStyle: any = {};\n\n private tooltipId = `xplor-tooltip-${++tooltipIdCounter}`;\n\n private triggerEl: HTMLDivElement;\n private tooltipEl: HTMLDivElement;\n private hideTimeout: any;\n\n componentDidLoad() {\n if (this.trigger === 'hover') {\n this.setupHoverListeners();\n }\n }\n\n disconnectedCallback() {\n this.cleanupListeners();\n if (this.hideTimeout) {\n clearTimeout(this.hideTimeout);\n }\n }\n\n private setupHoverListeners() {\n if (this.triggerEl) {\n this.triggerEl.addEventListener('mouseenter', this.handleMouseEnter);\n this.triggerEl.addEventListener('mouseleave', this.handleMouseLeave);\n this.triggerEl.addEventListener('focusin', this.handleFocusIn);\n this.triggerEl.addEventListener('focusout', this.handleFocusOut);\n }\n }\n\n private cleanupListeners() {\n if (this.triggerEl) {\n this.triggerEl.removeEventListener('mouseenter', this.handleMouseEnter);\n this.triggerEl.removeEventListener('mouseleave', this.handleMouseLeave);\n this.triggerEl.removeEventListener('focusin', this.handleFocusIn);\n this.triggerEl.removeEventListener('focusout', this.handleFocusOut);\n }\n }\n\n private handleMouseEnter = () => {\n if (this.disabled) return;\n if (this.hideTimeout) {\n clearTimeout(this.hideTimeout);\n }\n this.showTooltip();\n };\n\n private handleMouseLeave = () => {\n if (this.disabled) return;\n this.hideTimeout = setTimeout(() => {\n this.hideTooltip();\n }, 100);\n };\n\n private handleFocusIn = () => {\n if (this.disabled) return;\n this.showTooltip();\n };\n\n private handleFocusOut = () => {\n if (this.disabled) return;\n this.hideTooltip();\n };\n\n private handleClick = () => {\n if (this.disabled) return;\n if (this.trigger === 'click') {\n this.open = !this.open;\n if (this.open) {\n requestAnimationFrame(() => this.updatePosition());\n }\n }\n };\n\n @Listen('click', { target: 'document' })\n handleDocumentClick(event: MouseEvent) {\n if (this.trigger === 'click' && this.open) {\n const target = event.target as Node;\n if (!this.el.contains(target)) {\n this.open = false;\n }\n }\n }\n\n private showTooltip() {\n this.open = true;\n requestAnimationFrame(() => this.updatePosition());\n }\n\n private hideTooltip() {\n this.open = false;\n }\n\n private updatePosition() {\n if (!this.triggerEl || !this.tooltipEl) return;\n\n const triggerRect = this.triggerEl.getBoundingClientRect();\n const tooltipRect = this.tooltipEl.getBoundingClientRect();\n const gap = 8; // Space between trigger and tooltip\n const arrowSize = this.arrow ? 6 : 0;\n\n let top = 0;\n let left = 0;\n let arrowTop = '';\n let arrowLeft = '';\n let arrowTransform = '';\n\n switch (this.position) {\n case 'top':\n top = triggerRect.top - tooltipRect.height - gap - arrowSize;\n left = triggerRect.left + triggerRect.width / 2 - tooltipRect.width / 2;\n arrowTop = '100%';\n arrowLeft = '50%';\n arrowTransform = 'translateX(-50%) rotate(45deg)';\n break;\n\n case 'bottom':\n top = triggerRect.bottom + gap + arrowSize;\n left = triggerRect.left + triggerRect.width / 2 - tooltipRect.width / 2;\n arrowTop = '-6px';\n arrowLeft = '50%';\n arrowTransform = 'translateX(-50%) rotate(45deg)';\n break;\n\n case 'left':\n top = triggerRect.top + triggerRect.height / 2 - tooltipRect.height / 2;\n left = triggerRect.left - tooltipRect.width - gap - arrowSize;\n arrowTop = '50%';\n arrowLeft = '100%';\n arrowTransform = 'translateY(-50%) rotate(45deg)';\n break;\n\n case 'right':\n top = triggerRect.top + triggerRect.height / 2 - tooltipRect.height / 2;\n left = triggerRect.right + gap + arrowSize;\n arrowTop = '50%';\n arrowLeft = '-6px';\n arrowTransform = 'translateY(-50%) rotate(45deg)';\n break;\n }\n\n // Keep tooltip within viewport\n const viewportPadding = 8;\n if (left < viewportPadding) {\n left = viewportPadding;\n } else if (left + tooltipRect.width > window.innerWidth - viewportPadding) {\n left = window.innerWidth - tooltipRect.width - viewportPadding;\n }\n\n if (top < viewportPadding) {\n top = viewportPadding;\n } else if (top + tooltipRect.height > window.innerHeight - viewportPadding) {\n top = window.innerHeight - tooltipRect.height - viewportPadding;\n }\n\n this.tooltipStyle = {\n top: `${top}px`,\n left: `${left}px`,\n };\n\n this.arrowStyle = {\n top: arrowTop,\n left: arrowLeft,\n transform: arrowTransform,\n };\n }\n\n render() {\n return (\n <Host>\n <div\n class=\"tooltip-trigger\"\n ref={(el) => (this.triggerEl = el)}\n onClick={this.handleClick}\n aria-describedby={this.open ? this.tooltipId : undefined}\n >\n <slot name=\"trigger\" />\n </div>\n\n {this.open && (\n <div\n class={{\n 'tooltip': true,\n [`tooltip--${this.position}`]: true,\n }}\n style={this.tooltipStyle}\n ref={(el) => (this.tooltipEl = el)}\n role=\"tooltip\"\n id={this.tooltipId}\n >\n <div class=\"tooltip__content\">\n <slot>{this.content}</slot>\n </div>\n {this.arrow && (\n <div\n class=\"tooltip__arrow\"\n style={this.arrowStyle}\n />\n )}\n </div>\n )}\n </Host>\n );\n }\n}\n"],"mappings":"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","ignoreList":[]}
|