@xplor-education/core-stencil-components 2.1.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-BaDLDCH5.js → p-DURNLP66.js} +71 -6
- package/components/p-DURNLP66.js.map +1 -0
- 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 +1 -1
- 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 +7 -4
- package/components/xplor-drag-and-drop-input.js.map +1 -1
- package/components/xplor-expansion-panel.js +3 -3
- 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-date-picker.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 +107 -7
- package/components/xplor-input-select.js.map +1 -1
- package/components/xplor-input-send.js +2 -2
- 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 +1 -1
- 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.js +99 -4
- package/components/xplor-radio-btn.js.map +1 -1
- 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} +3 -3
- package/dist/cjs/index-BjAapk2n.js.map +1 -0
- package/dist/cjs/loader.cjs.js +2 -2
- package/dist/cjs/xplor-alert-dialog_58.cjs.entry.js +673 -100
- package/dist/cjs/xplor-alert-dialog_58.cjs.entry.js.map +1 -1
- package/dist/cjs/xplor-component-library.cjs.js +2 -2
- 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.js +24 -3
- package/dist/collection/components/xplor-drag-and-drop-input/xplor-drag-and-drop-input.js.map +1 -1
- package/dist/collection/components/xplor-expansion-panel/xplor-expansion-panel.js +3 -3
- 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-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-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.js +133 -6
- 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 +1 -1
- 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-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 +116 -1
- package/dist/collection/components/xplor-radio-btn/xplor-radio-btn.js +258 -2
- package/dist/collection/components/xplor-radio-btn/xplor-radio-btn.js.map +1 -1
- 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-CXJd350E.js → p-Dh0wQJt6.js} +71 -6
- package/dist/components/p-Dh0wQJt6.js.map +1 -0
- 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 +1 -1
- 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 +7 -4
- package/dist/components/xplor-drag-and-drop-input.js.map +1 -1
- package/dist/components/xplor-expansion-panel.js +3 -3
- 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-date-picker.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 +107 -7
- package/dist/components/xplor-input-select.js.map +1 -1
- package/dist/components/xplor-input-send.js +2 -2
- 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 +1 -1
- 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.js +99 -4
- package/dist/components/xplor-radio-btn.js.map +1 -1
- 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} +3 -3
- package/dist/esm/index-KRfMjDC2.js.map +1 -0
- package/dist/esm/loader.js +3 -3
- package/dist/esm/xplor-alert-dialog_58.entry.js +673 -100
- package/dist/esm/xplor-alert-dialog_58.entry.js.map +1 -1
- package/dist/esm/xplor-component-library.js +3 -3
- package/dist/hydrate/index.js +718 -116
- package/dist/hydrate/index.mjs +718 -116
- 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 +4 -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 +8 -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 +32 -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 +205 -0
- 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-BaDLDCH5.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/dist/cjs/index-Bc5o_4vY.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-CXJd350E.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/xplor-component-library/p-07d83c17.entry.js +0 -2
- package/dist/xplor-component-library/p-07d83c17.entry.js.map +0 -1
- package/dist/xplor-component-library/p-Zkk2NJif.js.map +0 -1
|
@@ -20,6 +20,7 @@ const XplorAlertDialog$1 = /*@__PURE__*/ proxyCustomElement(class XplorAlertDial
|
|
|
20
20
|
* Persistent mode - prevents closing on backdrop click
|
|
21
21
|
*/
|
|
22
22
|
this.persistent = true;
|
|
23
|
+
this.previouslyFocusedElement = null;
|
|
23
24
|
this.handleBackdropClick = () => {
|
|
24
25
|
if (!this.persistent) {
|
|
25
26
|
this.closeDialog();
|
|
@@ -37,20 +38,75 @@ const XplorAlertDialog$1 = /*@__PURE__*/ proxyCustomElement(class XplorAlertDial
|
|
|
37
38
|
handleOpenChange(newValue) {
|
|
38
39
|
if (newValue) {
|
|
39
40
|
document.body.style.overflow = 'hidden';
|
|
41
|
+
this.previouslyFocusedElement = document.activeElement;
|
|
42
|
+
requestAnimationFrame(() => {
|
|
43
|
+
this.setInitialFocus();
|
|
44
|
+
});
|
|
40
45
|
}
|
|
41
46
|
else {
|
|
42
47
|
document.body.style.overflow = '';
|
|
48
|
+
if (this.previouslyFocusedElement) {
|
|
49
|
+
this.previouslyFocusedElement.focus();
|
|
50
|
+
this.previouslyFocusedElement = null;
|
|
51
|
+
}
|
|
43
52
|
}
|
|
44
53
|
}
|
|
45
54
|
disconnectedCallback() {
|
|
46
55
|
document.body.style.overflow = '';
|
|
47
56
|
}
|
|
57
|
+
handleKeyDown(event) {
|
|
58
|
+
if (!this.open)
|
|
59
|
+
return;
|
|
60
|
+
if (event.key === 'Escape' && !this.persistent) {
|
|
61
|
+
event.preventDefault();
|
|
62
|
+
this.closeDialog();
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (event.key === 'Tab') {
|
|
66
|
+
this.trapFocus(event);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
getFocusableElements() {
|
|
70
|
+
if (!this.dialogEl)
|
|
71
|
+
return [];
|
|
72
|
+
const selectors = 'a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
73
|
+
return Array.from(this.dialogEl.querySelectorAll(selectors));
|
|
74
|
+
}
|
|
75
|
+
trapFocus(event) {
|
|
76
|
+
const focusableElements = this.getFocusableElements();
|
|
77
|
+
if (focusableElements.length === 0)
|
|
78
|
+
return;
|
|
79
|
+
const firstElement = focusableElements[0];
|
|
80
|
+
const lastElement = focusableElements[focusableElements.length - 1];
|
|
81
|
+
if (event.shiftKey) {
|
|
82
|
+
if (document.activeElement === firstElement) {
|
|
83
|
+
event.preventDefault();
|
|
84
|
+
lastElement.focus();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
if (document.activeElement === lastElement) {
|
|
89
|
+
event.preventDefault();
|
|
90
|
+
firstElement.focus();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
setInitialFocus() {
|
|
95
|
+
const focusableElements = this.getFocusableElements();
|
|
96
|
+
if (focusableElements.length > 0) {
|
|
97
|
+
focusableElements[0].focus();
|
|
98
|
+
}
|
|
99
|
+
else if (this.dialogEl) {
|
|
100
|
+
this.dialogEl.focus();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
48
103
|
render() {
|
|
49
104
|
if (!this.open) {
|
|
50
105
|
return null;
|
|
51
106
|
}
|
|
52
|
-
return (h(Host, null, h("div", { class: "xplor-alert-dialog__backdrop", onClick: this.handleBackdropClick }, h("div", { class: "xplor-alert-dialog__card", style: { width: this.width }, onClick: this.handleCardClick }, h("button", { type: "button", class: "xplor-alert-dialog__close-btn", onClick: this.closeDialog, "aria-label": "Close dialog" }, "\u2715"), h("div", { class: "xplor-alert-dialog__title" }, h("slot", { name: "title" })), h("div", { class: "xplor-alert-dialog__text" }, h("slot", { name: "text" })), h("div", { class: "xplor-alert-dialog__actions" }, h("slot", { name: "actions" }))))));
|
|
107
|
+
return (h(Host, null, h("div", { class: "xplor-alert-dialog__backdrop", onClick: this.handleBackdropClick }, h("div", { class: "xplor-alert-dialog__card", style: { width: this.width }, onClick: this.handleCardClick, role: "alertdialog", "aria-modal": "true", "aria-labelledby": this.ariaLabel ? undefined : 'xplor-alert-dialog-title', "aria-label": this.ariaLabel, "aria-describedby": "xplor-alert-dialog-text", tabindex: "-1", ref: (el) => (this.dialogEl = el) }, h("button", { type: "button", class: "xplor-alert-dialog__close-btn", onClick: this.closeDialog, "aria-label": "Close dialog" }, "\u2715"), h("div", { class: "xplor-alert-dialog__title", id: "xplor-alert-dialog-title" }, h("slot", { name: "title" })), h("div", { class: "xplor-alert-dialog__text", id: "xplor-alert-dialog-text" }, h("slot", { name: "text" })), h("div", { class: "xplor-alert-dialog__actions" }, h("slot", { name: "actions" }))))));
|
|
53
108
|
}
|
|
109
|
+
get el() { return this; }
|
|
54
110
|
static get watchers() { return {
|
|
55
111
|
"open": ["handleOpenChange"]
|
|
56
112
|
}; }
|
|
@@ -58,8 +114,9 @@ const XplorAlertDialog$1 = /*@__PURE__*/ proxyCustomElement(class XplorAlertDial
|
|
|
58
114
|
}, [6, "xplor-alert-dialog", {
|
|
59
115
|
"open": [1028],
|
|
60
116
|
"width": [1],
|
|
61
|
-
"persistent": [4]
|
|
62
|
-
|
|
117
|
+
"persistent": [4],
|
|
118
|
+
"ariaLabel": [1, "aria-label"]
|
|
119
|
+
}, [[0, "keydown", "handleKeyDown"]], {
|
|
63
120
|
"open": ["handleOpenChange"]
|
|
64
121
|
}]);
|
|
65
122
|
function defineCustomElement$1() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"file":"xplor-alert-dialog.js","mappings":";;AAAA,MAAM,mBAAmB,GAAG,w/QAAw/Q;;MCOvgRA,kBAAgB,iBAAAC,kBAAA,CAAA,MAAA,gBAAA,SAAAC,CAAA,CAAA;AAL7B,IAAA,WAAA,GAAA;;;;;AAME;;AAEG;AACsB,QAAA,IAAI,CAAA,IAAA,GAAY,KAAK;AAE9C;;AAEG;AACK,QAAA,IAAK,CAAA,KAAA,GAAW,OAAO;AAE/B;;AAEG;AACK,QAAA,IAAU,CAAA,UAAA,GAAY,IAAI;AAyB1B,QAAA,IAAmB,CAAA,mBAAA,GAAG,MAAK;AACjC,YAAA,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE;gBACpB,IAAI,CAAC,WAAW,EAAE;;AAEtB,SAAC;AAEO,QAAA,IAAA,CAAA,eAAe,GAAG,CAAC,KAAY,KAAI;YACzC,KAAK,CAAC,eAAe,EAAE;AACzB,SAAC;AAEO,QAAA,IAAW,CAAA,WAAA,GAAG,MAAK;AACzB,YAAA,IAAI,CAAC,IAAI,GAAG,KAAK;AACjB,YAAA,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE;AACtB,YAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,KAAK,CAAC;AACpC,SAAC;AAwCF;AAlEC,IAAA,gBAAgB,CAAC,QAAiB,EAAA;QAChC,IAAI,QAAQ,EAAE;YACZ,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,QAAQ;;aAClC;YACL,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAE;;;IAIrC,oBAAoB,GAAA;QAClB,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,EAAE;;IAmBnC,MAAM,GAAA;AACJ,QAAA,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;AACd,YAAA,OAAO,IAAI;;AAGb,QAAA,QACE,EAAC,IAAI,EAAA,IAAA,EACH,CAAK,CAAA,KAAA,EAAA,EAAA,KAAK,EAAC,8BAA8B,EAAC,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAA,EACzE,CAAA,CAAA,KAAA,EAAA,EACE,KAAK,EAAC,0BAA0B,EAChC,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,EAC5B,OAAO,EAAE,IAAI,CAAC,eAAe,EAAA,EAE7B,CAAA,CAAA,QAAA,EAAA,EACE,IAAI,EAAC,QAAQ,EACb,KAAK,EAAC,+BAA+B,EACrC,OAAO,EAAE,IAAI,CAAC,WAAW,EAAA,YAAA,EACd,cAAc,EAGlB,EAAA,QAAA,CAAA,EAET,CAAK,CAAA,KAAA,EAAA,EAAA,KAAK,EAAC,2BAA2B,EAAA,EACpC,CAAA,CAAA,MAAA,EAAA,EAAM,IAAI,EAAC,OAAO,EAAA,CAAG,CACjB,EAEN,CAAK,CAAA,KAAA,EAAA,EAAA,KAAK,EAAC,0BAA0B,EAAA,EACnC,CAAA,CAAA,MAAA,EAAA,EAAM,IAAI,EAAC,MAAM,EAAA,CAAG,CAChB,EAEN,CAAK,CAAA,KAAA,EAAA,EAAA,KAAK,EAAC,6BAA6B,EAAA,EACtC,CAAM,CAAA,MAAA,EAAA,EAAA,IAAI,EAAC,SAAS,EAAA,CAAG,CACnB,CACF,CACF,CACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","names":["XplorAlertDialog","__stencil_proxyCustomElement","HTMLElement"],"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"],"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 } 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 * Close event\n */\n @Event() xplorClose: EventEmitter<void>;\n\n /**\n * Dialog state change event\n */\n @Event() xplorDialogChange: EventEmitter<boolean>;\n\n @Watch('open')\n handleOpenChange(newValue: boolean) {\n if (newValue) {\n document.body.style.overflow = 'hidden';\n } else {\n document.body.style.overflow = '';\n }\n }\n\n disconnectedCallback() {\n document.body.style.overflow = '';\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 >\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\">\n <slot name=\"title\" />\n </div>\n\n <div class=\"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"],"version":3}
|
|
1
|
+
{"file":"xplor-alert-dialog.js","mappings":"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","names":["XplorAlertDialog","__stencil_proxyCustomElement","HTMLElement"],"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"],"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"],"version":3}
|
|
@@ -438,10 +438,10 @@ const AssistantInput = (props) => {
|
|
|
438
438
|
enableVoiceInput && (h("button", { type: "button", class: {
|
|
439
439
|
'xplor-assistant__voice-button': true,
|
|
440
440
|
'xplor-assistant__voice-button--listening': isListening,
|
|
441
|
-
}, onClick: handleVoiceClick, disabled: disabled || isLoading, title: isListening ? 'Stop listening' : 'Start voice input' },
|
|
441
|
+
}, onClick: handleVoiceClick, disabled: disabled || isLoading, title: isListening ? 'Stop listening' : 'Start voice input', "aria-label": "Voice input" },
|
|
442
442
|
h("span", { class: "xplor-assistant__voice-icon", innerHTML: microphoneIcon }))),
|
|
443
443
|
h("input", { type: "text", class: "xplor-assistant__input", placeholder: placeholder, value: inputValue, onInput: handleInputChange, disabled: disabled || isLoading }),
|
|
444
|
-
h("button", { type: "submit", class: "xplor-assistant__send-button", disabled: isSendDisabled, title: "Send message" },
|
|
444
|
+
h("button", { type: "submit", class: "xplor-assistant__send-button", disabled: isSendDisabled, title: "Send message", "aria-label": "Send message" },
|
|
445
445
|
h("span", { class: "xplor-assistant__send-icon", innerHTML: sendIcon })))));
|
|
446
446
|
};
|
|
447
447
|
|
|
@@ -704,7 +704,7 @@ const XplorAssistant$1 = /*@__PURE__*/ proxyCustomElement(class XplorAssistant e
|
|
|
704
704
|
return (h(Host, null, h("div", { class: {
|
|
705
705
|
'xplor-assistant': true,
|
|
706
706
|
'xplor-assistant--disabled': this.disabled,
|
|
707
|
-
}, style: { maxHeight: this.maxHeight } }, h("div", { class: "xplor-assistant__messages", ref: (el) => (this.messagesContainerRef = el) }, this.messages.map((message) => (h(AssistantMessage, { message: message, enableTextToSpeech: this.enableTextToSpeech, autoSpeak: false, isSpeaking: this.isSpeaking, onSpeak: this.handleSpeak, onStopSpeaking: this.handleStopSpeaking }))), this.isLoading && (h("div", { class: "xplor-assistant__message xplor-assistant__message--assistant" }, h(TypingIndicator, null))), this.error && this.apiEndpoint && (h("div", { class: "xplor-assistant__error-banner" }, this.error))), this.quickReplies && this.quickReplies.length > 0 && (h(QuickReplies, { replies: this.quickReplies, disabled: this.disabled || this.isLoading, onReplyClick: this.handleQuickReply })), h(AssistantInput, { placeholder: this.placeholder, disabled: this.disabled, isLoading: this.isLoading, enableVoiceInput: this.enableVoiceInput && this.hasVoiceSupport, isListening: this.isListening, onSendMessage: this.handleSendMessage, onStartListening: this.handleStartListening, onStopListening: this.handleStopListening, inputValue: this.inputValue, setInputValue: this.setInputValue }))));
|
|
707
|
+
}, style: { maxHeight: this.maxHeight } }, h("div", { class: "xplor-assistant__messages", ref: (el) => (this.messagesContainerRef = el), role: "log", "aria-live": "polite", "aria-busy": this.isLoading ? 'true' : 'false' }, this.messages.map((message) => (h(AssistantMessage, { message: message, enableTextToSpeech: this.enableTextToSpeech, autoSpeak: false, isSpeaking: this.isSpeaking, onSpeak: this.handleSpeak, onStopSpeaking: this.handleStopSpeaking }))), this.isLoading && (h("div", { class: "xplor-assistant__message xplor-assistant__message--assistant" }, h(TypingIndicator, null))), this.error && this.apiEndpoint && (h("div", { class: "xplor-assistant__error-banner" }, this.error))), this.quickReplies && this.quickReplies.length > 0 && (h(QuickReplies, { replies: this.quickReplies, disabled: this.disabled || this.isLoading, onReplyClick: this.handleQuickReply })), h(AssistantInput, { placeholder: this.placeholder, disabled: this.disabled, isLoading: this.isLoading, enableVoiceInput: this.enableVoiceInput && this.hasVoiceSupport, isListening: this.isListening, onSendMessage: this.handleSendMessage, onStartListening: this.handleStartListening, onStopListening: this.handleStopListening, inputValue: this.inputValue, setInputValue: this.setInputValue }))));
|
|
708
708
|
}
|
|
709
709
|
get el() { return this; }
|
|
710
710
|
static get watchers() { return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"file":"xplor-assistant.js","mappings":"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","names":["XplorAssistant","__stencil_proxyCustomElement","HTMLElement"],"sources":["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"],"sourcesContent":["/**\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 >\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 >\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 >\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"],"version":3}
|
|
1
|
+
{"file":"xplor-assistant.js","mappings":"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","names":["XplorAssistant","__stencil_proxyCustomElement","HTMLElement"],"sources":["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"],"sourcesContent":["/**\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"],"version":3}
|
|
@@ -202,25 +202,30 @@ const XplorAutocomplete$1 = /*@__PURE__*/ proxyCustomElement(class XplorAutocomp
|
|
|
202
202
|
}
|
|
203
203
|
render() {
|
|
204
204
|
const hasValue = this.multiple ? this.selectedItems.length > 0 : this.value !== null && this.searchQuery !== '';
|
|
205
|
-
|
|
205
|
+
const listboxId = 'autocomplete-listbox';
|
|
206
|
+
const labelId = 'autocomplete-label';
|
|
207
|
+
const activeDescendantId = this.highlightedIndex >= 0 ? `autocomplete-option-${this.highlightedIndex}` : undefined;
|
|
208
|
+
return (h(Host, { key: 'f76ac5f9d1cd6e6c9618ac3884bc86a2bfabb3c5' }, h("div", { key: 'efd2bd854c305c56971b5d6e19a5b9eb497099f8', class: {
|
|
206
209
|
'autocomplete': true,
|
|
207
210
|
'autocomplete--disabled': this.disabled,
|
|
208
211
|
'autocomplete--readonly': this.readonly,
|
|
209
212
|
'autocomplete--open': this.isOpen,
|
|
210
|
-
} }, this.label && (h("label", { key: '
|
|
213
|
+
} }, this.label && (h("label", { key: '97bb161105b66181558d22519c9f0cd1287b2c49', class: "autocomplete__label", id: labelId }, this.label)), h("div", { key: '128acf53793205be89a8d619ce548107aaed8b28', class: "autocomplete__input-wrapper" }, this.multiple && this.selectedItems.length > 0 && (h("div", { key: '670da50897139688951c077db4b6116b88bfadfa', class: "autocomplete__chips" }, this.selectedItems.map(value => {
|
|
211
214
|
const item = this.findItemByValue(value);
|
|
212
|
-
|
|
213
|
-
|
|
215
|
+
const chipLabel = this.getSelectedItemLabel(value);
|
|
216
|
+
return (h("div", { class: "autocomplete__chip" }, h("span", { class: "autocomplete__chip-label" }, this.renderSelection && item ? this.renderSelection(item) : chipLabel), h("button", { type: "button", class: "autocomplete__chip-remove", onClick: () => this.removeItem(value), disabled: this.disabled || this.readonly, "aria-label": `Remove ${chipLabel}` }, "\u00D7")));
|
|
217
|
+
}))), h("input", { key: '25e9e5111726cd720ab88a4a5ae25f84b48eee1e', ref: (el) => (this.inputEl = el), type: "text", class: "autocomplete__input", placeholder: this.placeholder, value: this.searchQuery, onFocus: this.handleInputFocus, onInput: this.handleInputChange, onKeyDown: this.handleInputKeyDown, disabled: this.disabled, readonly: this.readonly, autocomplete: "off", role: "combobox", "aria-expanded": this.isOpen ? 'true' : 'false', "aria-haspopup": "listbox", "aria-controls": this.isOpen ? listboxId : undefined, "aria-activedescendant": activeDescendantId, "aria-labelledby": this.label ? labelId : undefined, "aria-label": !this.label ? (this.ariaLabel || this.placeholder) : undefined, "aria-autocomplete": "list" }), h("div", { key: '5128b893c4743a49439a279b0cb7094077ebd528', class: "autocomplete__actions" }, this.clearable && hasValue && !this.disabled && !this.readonly && (h("button", { key: '512d7956e79d9767e072462f1ec309b081716c86', type: "button", class: "autocomplete__clear", onClick: this.handleClear, "aria-label": "Clear selection" }, "\u00D7")), h("span", { key: 'e0cfba3c1513b63f9697835ad6919d045c7011db', class: "autocomplete__icon", "aria-hidden": "true" }, "\u25BC"))), this.isOpen && this.filteredItems.length > 0 && (h("div", { key: '9c100abedb5ee252df82994722c0da9d5787d1bf', class: "autocomplete__dropdown", ref: (el) => (this.dropdownEl = el), style: { maxWidth: this.menuMaxWidth }, role: "listbox", id: listboxId, "aria-label": this.label || this.ariaLabel || 'Suggestions' }, this.filteredItems.map((item, index) => {
|
|
214
218
|
const itemVal = this.getItemValue(item);
|
|
215
|
-
|
|
219
|
+
const isSelected = this.multiple
|
|
220
|
+
? this.selectedItems.includes(itemVal)
|
|
221
|
+
: this.value === itemVal;
|
|
222
|
+
return (h("div", { key: itemVal, id: `autocomplete-option-${index}`, "data-index": index, role: "option", "aria-selected": isSelected ? 'true' : 'false', "aria-disabled": item.disabled ? 'true' : undefined, class: {
|
|
216
223
|
'autocomplete__item': true,
|
|
217
224
|
'autocomplete__item--highlighted': index === this.highlightedIndex,
|
|
218
|
-
'autocomplete__item--selected':
|
|
219
|
-
? this.selectedItems.includes(itemVal)
|
|
220
|
-
: this.value === itemVal,
|
|
225
|
+
'autocomplete__item--selected': isSelected,
|
|
221
226
|
'autocomplete__item--disabled': item.disabled,
|
|
222
227
|
}, onClick: () => this.selectItem(item) }, this.renderItem ? this.renderItem(item) : this.getItemText(item)));
|
|
223
|
-
}))), this.isOpen && this.filteredItems.length === 0 && (h("div", { key: '
|
|
228
|
+
}))), this.isOpen && this.filteredItems.length === 0 && (h("div", { key: '329f92d7f4bf36bb114909853e249978412ae82f', class: "autocomplete__dropdown", style: { maxWidth: this.menuMaxWidth }, role: "listbox", id: listboxId }, h("div", { key: '400e97f955724f59830fb37b52d99c3723627e51', class: "autocomplete__no-results", role: "option", "aria-disabled": "true" }, "No results found"))))));
|
|
224
229
|
}
|
|
225
230
|
get el() { return this; }
|
|
226
231
|
static get style() { return xplorAutocompleteCss; }
|
|
@@ -229,6 +234,7 @@ const XplorAutocomplete$1 = /*@__PURE__*/ proxyCustomElement(class XplorAutocomp
|
|
|
229
234
|
"value": [1032],
|
|
230
235
|
"placeholder": [1],
|
|
231
236
|
"label": [1],
|
|
237
|
+
"ariaLabel": [1, "aria-label"],
|
|
232
238
|
"disabled": [4],
|
|
233
239
|
"readonly": [4],
|
|
234
240
|
"clearable": [4],
|