igniteui-webcomponents 6.1.2 → 6.3.0-alpha.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/CHANGELOG.md +32 -0
- package/LICENSE +1 -1
- package/README.md +13 -1
- package/components/card/themes/content.js +7 -0
- package/components/card/themes/content.js.map +1 -1
- package/components/card/themes/shared/content/card.content.indigo.css.d.ts +1 -0
- package/components/card/themes/shared/content/card.content.indigo.css.js +3 -0
- package/components/card/themes/shared/content/card.content.indigo.css.js.map +1 -0
- package/components/carousel/carousel-indicator.d.ts +1 -1
- package/components/carousel/carousel-indicator.js.map +1 -1
- package/components/carousel/carousel-slide.d.ts +3 -3
- package/components/carousel/carousel-slide.js +7 -13
- package/components/carousel/carousel-slide.js.map +1 -1
- package/components/carousel/carousel.d.ts +39 -38
- package/components/carousel/carousel.js +160 -153
- package/components/carousel/carousel.js.map +1 -1
- package/components/chat/chat-input.d.ts +70 -0
- package/components/chat/chat-input.js +266 -0
- package/components/chat/chat-input.js.map +1 -0
- package/components/chat/chat-message-list.d.ts +111 -0
- package/components/chat/chat-message-list.js +178 -0
- package/components/chat/chat-message-list.js.map +1 -0
- package/components/chat/chat-message.d.ts +57 -0
- package/components/chat/chat-message.js +59 -0
- package/components/chat/chat-message.js.map +1 -0
- package/components/chat/chat-state.d.ts +155 -0
- package/components/chat/chat-state.js +167 -0
- package/components/chat/chat-state.js.map +1 -0
- package/components/chat/chat.d.ts +164 -0
- package/components/chat/chat.js +168 -0
- package/components/chat/chat.js.map +1 -0
- package/components/chat/markdown-util.d.ts +2 -0
- package/components/chat/markdown-util.js +22 -0
- package/components/chat/markdown-util.js.map +1 -0
- package/components/chat/message-attachments.d.ts +45 -0
- package/components/chat/message-attachments.js +127 -0
- package/components/chat/message-attachments.js.map +1 -0
- package/components/chat/themes/chat.base.css.d.ts +1 -0
- package/components/chat/themes/chat.base.css.js +3 -0
- package/components/chat/themes/chat.base.css.js.map +1 -0
- package/components/chat/themes/dark/chat.bootstrap.css.d.ts +1 -0
- package/components/chat/themes/dark/chat.bootstrap.css.js +3 -0
- package/components/chat/themes/dark/chat.bootstrap.css.js.map +1 -0
- package/components/chat/themes/dark/chat.fluent.css.d.ts +1 -0
- package/components/chat/themes/dark/chat.fluent.css.js +3 -0
- package/components/chat/themes/dark/chat.fluent.css.js.map +1 -0
- package/components/chat/themes/dark/chat.indigo.css.d.ts +1 -0
- package/components/chat/themes/dark/chat.indigo.css.js +3 -0
- package/components/chat/themes/dark/chat.indigo.css.js.map +1 -0
- package/components/chat/themes/dark/chat.material.css.d.ts +1 -0
- package/components/chat/themes/dark/chat.material.css.js +3 -0
- package/components/chat/themes/dark/chat.material.css.js.map +1 -0
- package/components/chat/themes/input.base.css.d.ts +1 -0
- package/components/chat/themes/input.base.css.js +3 -0
- package/components/chat/themes/input.base.css.js.map +1 -0
- package/components/chat/themes/input.d.ts +2 -0
- package/components/chat/themes/input.js +35 -0
- package/components/chat/themes/input.js.map +1 -0
- package/components/chat/themes/light/chat.bootstrap.css.d.ts +1 -0
- package/components/chat/themes/light/chat.bootstrap.css.js +3 -0
- package/components/chat/themes/light/chat.bootstrap.css.js.map +1 -0
- package/components/chat/themes/light/chat.fluent.css.d.ts +1 -0
- package/components/chat/themes/light/chat.fluent.css.js +3 -0
- package/components/chat/themes/light/chat.fluent.css.js.map +1 -0
- package/components/chat/themes/light/chat.indigo.css.d.ts +1 -0
- package/components/chat/themes/light/chat.indigo.css.js +3 -0
- package/components/chat/themes/light/chat.indigo.css.js.map +1 -0
- package/components/chat/themes/light/chat.material.css.d.ts +1 -0
- package/components/chat/themes/light/chat.material.css.js +3 -0
- package/components/chat/themes/light/chat.material.css.js.map +1 -0
- package/components/chat/themes/light/chat.shared.css.d.ts +1 -0
- package/components/chat/themes/light/chat.shared.css.js +3 -0
- package/components/chat/themes/light/chat.shared.css.js.map +1 -0
- package/components/chat/themes/message-attachments.base.css.d.ts +1 -0
- package/components/chat/themes/message-attachments.base.css.js +3 -0
- package/components/chat/themes/message-attachments.base.css.js.map +1 -0
- package/components/chat/themes/message-list.base.css.d.ts +1 -0
- package/components/chat/themes/message-list.base.css.js +3 -0
- package/components/chat/themes/message-list.base.css.js.map +1 -0
- package/components/chat/themes/message.base.css.d.ts +1 -0
- package/components/chat/themes/message.base.css.js +3 -0
- package/components/chat/themes/message.base.css.js.map +1 -0
- package/components/chat/themes/shared/chat-message.common.css.d.ts +1 -0
- package/components/chat/themes/shared/chat-message.common.css.js +3 -0
- package/components/chat/themes/shared/chat-message.common.css.js.map +1 -0
- package/components/chat/themes/shared/chat.common.css.d.ts +1 -0
- package/components/chat/themes/shared/chat.common.css.js +3 -0
- package/components/chat/themes/shared/chat.common.css.js.map +1 -0
- package/components/chat/themes/shared/input/input.bootstrap.css.d.ts +1 -0
- package/components/chat/themes/shared/input/input.bootstrap.css.js +3 -0
- package/components/chat/themes/shared/input/input.bootstrap.css.js.map +1 -0
- package/components/chat/themes/shared/input/input.common.css.d.ts +1 -0
- package/components/chat/themes/shared/input/input.common.css.js +3 -0
- package/components/chat/themes/shared/input/input.common.css.js.map +1 -0
- package/components/chat/themes/shared/input/input.fluent.css.d.ts +1 -0
- package/components/chat/themes/shared/input/input.fluent.css.js +3 -0
- package/components/chat/themes/shared/input/input.fluent.css.js.map +1 -0
- package/components/chat/themes/shared/input/input.indigo.css.d.ts +1 -0
- package/components/chat/themes/shared/input/input.indigo.css.js +3 -0
- package/components/chat/themes/shared/input/input.indigo.css.js.map +1 -0
- package/components/chat/themes/shared/input/input.material.css.d.ts +1 -0
- package/components/chat/themes/shared/input/input.material.css.js +3 -0
- package/components/chat/themes/shared/input/input.material.css.js.map +1 -0
- package/components/chat/themes/shared/message-attachments.common.css.d.ts +1 -0
- package/components/chat/themes/shared/message-attachments.common.css.js +3 -0
- package/components/chat/themes/shared/message-attachments.common.css.js.map +1 -0
- package/components/chat/themes/shared/message-list.common.css.d.ts +1 -0
- package/components/chat/themes/shared/message-list.common.css.js +3 -0
- package/components/chat/themes/shared/message-list.common.css.js.map +1 -0
- package/components/chat/themes/themes.d.ts +2 -0
- package/components/chat/themes/themes.js +46 -0
- package/components/chat/themes/themes.js.map +1 -0
- package/components/chat/types.d.ts +190 -0
- package/components/chat/types.js +8 -0
- package/components/chat/types.js.map +1 -0
- package/components/checkbox/checkbox-base.d.ts +3 -5
- package/components/checkbox/checkbox-base.js +15 -21
- package/components/checkbox/checkbox-base.js.map +1 -1
- package/components/checkbox/checkbox.d.ts +3 -4
- package/components/checkbox/checkbox.js +18 -17
- package/components/checkbox/checkbox.js.map +1 -1
- package/components/checkbox/switch.d.ts +0 -1
- package/components/checkbox/switch.js +7 -10
- package/components/checkbox/switch.js.map +1 -1
- package/components/checkbox/themes/dark/checkbox/checkbox.bootstrap.css.js +1 -1
- package/components/checkbox/themes/dark/checkbox/checkbox.bootstrap.css.js.map +1 -1
- package/components/checkbox/themes/dark/checkbox/checkbox.fluent.css.js +1 -1
- package/components/checkbox/themes/dark/checkbox/checkbox.fluent.css.js.map +1 -1
- package/components/checkbox/themes/dark/switch/switch.bootstrap.css.js +1 -1
- package/components/checkbox/themes/dark/switch/switch.bootstrap.css.js.map +1 -1
- package/components/checkbox/themes/dark/switch/switch.fluent.css.js +1 -1
- package/components/checkbox/themes/dark/switch/switch.fluent.css.js.map +1 -1
- package/components/checkbox/themes/dark/switch/switch.indigo.css.js +1 -1
- package/components/checkbox/themes/dark/switch/switch.indigo.css.js.map +1 -1
- package/components/checkbox/themes/dark/switch/switch.material.css.js +1 -1
- package/components/checkbox/themes/dark/switch/switch.material.css.js.map +1 -1
- package/components/checkbox/themes/light/switch/switch.bootstrap.css.js +1 -1
- package/components/checkbox/themes/light/switch/switch.bootstrap.css.js.map +1 -1
- package/components/checkbox/themes/light/switch/switch.fluent.css.js +1 -1
- package/components/checkbox/themes/light/switch/switch.fluent.css.js.map +1 -1
- package/components/checkbox/themes/light/switch/switch.indigo.css.js +1 -1
- package/components/checkbox/themes/light/switch/switch.indigo.css.js.map +1 -1
- package/components/checkbox/themes/light/switch/switch.material.css.js +1 -1
- package/components/checkbox/themes/light/switch/switch.material.css.js.map +1 -1
- package/components/checkbox/themes/shared/checkbox/checkbox.bootstrap.css.js +1 -1
- package/components/checkbox/themes/shared/checkbox/checkbox.bootstrap.css.js.map +1 -1
- package/components/checkbox/themes/shared/checkbox/checkbox.common.css.js +1 -1
- package/components/checkbox/themes/shared/checkbox/checkbox.common.css.js.map +1 -1
- package/components/checkbox/themes/shared/checkbox/checkbox.fluent.css.js +1 -1
- package/components/checkbox/themes/shared/checkbox/checkbox.fluent.css.js.map +1 -1
- package/components/checkbox/themes/shared/checkbox/checkbox.indigo.css.js +1 -1
- package/components/checkbox/themes/shared/checkbox/checkbox.indigo.css.js.map +1 -1
- package/components/checkbox/themes/shared/checkbox/checkbox.material.css.js +1 -1
- package/components/checkbox/themes/shared/checkbox/checkbox.material.css.js.map +1 -1
- package/components/chip/chip.d.ts +11 -11
- package/components/chip/chip.js +61 -65
- package/components/chip/chip.js.map +1 -1
- package/components/combo/combo.d.ts +3 -3
- package/components/combo/combo.js +12 -6
- package/components/combo/combo.js.map +1 -1
- package/components/combo/themes/shared/combo.common.css.js +1 -1
- package/components/combo/themes/shared/combo.common.css.js.map +1 -1
- package/components/combo/themes/shared/combo.indigo.css.js +1 -1
- package/components/combo/themes/shared/combo.indigo.css.js.map +1 -1
- package/components/combo/themes/shared/combo.material.css.js +1 -1
- package/components/combo/themes/shared/combo.material.css.js.map +1 -1
- package/components/common/context.d.ts +5 -1
- package/components/common/context.js +2 -1
- package/components/common/context.js.map +1 -1
- package/components/common/controllers/internals.d.ts +66 -2
- package/components/common/controllers/internals.js +21 -0
- package/components/common/controllers/internals.js.map +1 -1
- package/components/common/controllers/slot.d.ts +87 -0
- package/components/common/controllers/slot.js +75 -0
- package/components/common/controllers/slot.js.map +1 -0
- package/components/common/definitions/defineAllComponents.js +2 -0
- package/components/common/definitions/defineAllComponents.js.map +1 -1
- package/components/common/mixins/forms/associated.d.ts +1 -1
- package/components/common/mixins/forms/associated.js +91 -36
- package/components/common/mixins/forms/associated.js.map +1 -1
- package/components/common/mixins/forms/form-transformers.d.ts +21 -0
- package/components/common/mixins/forms/form-transformers.js +64 -0
- package/components/common/mixins/forms/form-transformers.js.map +1 -0
- package/components/common/mixins/forms/form-value.d.ts +7 -36
- package/components/common/mixins/forms/form-value.js +2 -64
- package/components/common/mixins/forms/form-value.js.map +1 -1
- package/components/common/mixins/forms/types.d.ts +19 -10
- package/components/common/mixins/forms/types.js +2 -1
- package/components/common/mixins/forms/types.js.map +1 -1
- package/components/common/util.d.ts +1 -0
- package/components/common/util.js +3 -0
- package/components/common/util.js.map +1 -1
- package/components/date-picker/date-picker.d.ts +1 -3
- package/components/date-picker/date-picker.js +11 -13
- package/components/date-picker/date-picker.js.map +1 -1
- package/components/date-picker/themes/dark/date-picker.indigo.css.js +1 -1
- package/components/date-picker/themes/dark/date-picker.indigo.css.js.map +1 -1
- package/components/date-picker/themes/shared/date-picker.bootstrap.css.js +1 -1
- package/components/date-picker/themes/shared/date-picker.bootstrap.css.js.map +1 -1
- package/components/date-picker/themes/shared/date-picker.common.css.js +1 -1
- package/components/date-picker/themes/shared/date-picker.common.css.js.map +1 -1
- package/components/date-picker/themes/shared/date-picker.fluent.css.js +1 -1
- package/components/date-picker/themes/shared/date-picker.fluent.css.js.map +1 -1
- package/components/date-picker/themes/shared/date-picker.indigo.css.js +1 -1
- package/components/date-picker/themes/shared/date-picker.indigo.css.js.map +1 -1
- package/components/date-picker/themes/shared/date-picker.material.css.js +1 -1
- package/components/date-picker/themes/shared/date-picker.material.css.js.map +1 -1
- package/components/date-range-picker/date-range-picker.d.ts +1 -3
- package/components/date-range-picker/date-range-picker.js +19 -26
- package/components/date-range-picker/date-range-picker.js.map +1 -1
- package/components/date-range-picker/themes/dark/date-range-picker.indigo.css.js +1 -1
- package/components/date-range-picker/themes/dark/date-range-picker.indigo.css.js.map +1 -1
- package/components/date-range-picker/themes/shared/date-range-picker.bootstrap.css.js +1 -1
- package/components/date-range-picker/themes/shared/date-range-picker.bootstrap.css.js.map +1 -1
- package/components/date-range-picker/themes/shared/date-range-picker.common.css.js +1 -1
- package/components/date-range-picker/themes/shared/date-range-picker.common.css.js.map +1 -1
- package/components/date-range-picker/themes/shared/date-range-picker.fluent.css.js +1 -1
- package/components/date-range-picker/themes/shared/date-range-picker.fluent.css.js.map +1 -1
- package/components/date-range-picker/themes/shared/date-range-picker.indigo.css.js +1 -1
- package/components/date-range-picker/themes/shared/date-range-picker.indigo.css.js.map +1 -1
- package/components/date-range-picker/themes/shared/date-range-picker.material.css.js +1 -1
- package/components/date-range-picker/themes/shared/date-range-picker.material.css.js.map +1 -1
- package/components/date-time-input/date-time-input.d.ts +1 -2
- package/components/date-time-input/date-time-input.js +7 -7
- package/components/date-time-input/date-time-input.js.map +1 -1
- package/components/dialog/dialog.d.ts +23 -25
- package/components/dialog/dialog.js +108 -115
- package/components/dialog/dialog.js.map +1 -1
- package/components/dialog/themes/dark/dialog.bootstrap.css.js +1 -1
- package/components/dialog/themes/dark/dialog.bootstrap.css.js.map +1 -1
- package/components/expansion-panel/expansion-panel.d.ts +12 -14
- package/components/expansion-panel/expansion-panel.js +43 -56
- package/components/expansion-panel/expansion-panel.js.map +1 -1
- package/components/file-input/file-input.d.ts +1 -3
- package/components/file-input/file-input.js +6 -11
- package/components/file-input/file-input.js.map +1 -1
- package/components/file-input/themes/shared/file-input.bootstrap.css.js +1 -1
- package/components/file-input/themes/shared/file-input.bootstrap.css.js.map +1 -1
- package/components/file-input/themes/shared/file-input.material.css.js +1 -1
- package/components/file-input/themes/shared/file-input.material.css.js.map +1 -1
- package/components/input/input.d.ts +1 -4
- package/components/input/input.js +7 -12
- package/components/input/input.js.map +1 -1
- package/components/input/themes/shared/input.bootstrap.css.js +1 -1
- package/components/input/themes/shared/input.bootstrap.css.js.map +1 -1
- package/components/input/themes/shared/input.common.css.js +1 -1
- package/components/input/themes/shared/input.common.css.js.map +1 -1
- package/components/input/themes/shared/input.fluent.css.js +1 -1
- package/components/input/themes/shared/input.fluent.css.js.map +1 -1
- package/components/input/themes/shared/input.indigo.css.js +1 -1
- package/components/input/themes/shared/input.indigo.css.js.map +1 -1
- package/components/input/themes/shared/input.material.css.js +1 -1
- package/components/input/themes/shared/input.material.css.js.map +1 -1
- package/components/mask-input/mask-input-base.js +1 -0
- package/components/mask-input/mask-input-base.js.map +1 -1
- package/components/mask-input/mask-input.d.ts +2 -3
- package/components/mask-input/mask-input.js +5 -8
- package/components/mask-input/mask-input.js.map +1 -1
- package/components/nav-drawer/nav-drawer-item.d.ts +3 -4
- package/components/nav-drawer/nav-drawer-item.js +15 -18
- package/components/nav-drawer/nav-drawer-item.js.map +1 -1
- package/components/nav-drawer/nav-drawer.d.ts +1 -2
- package/components/nav-drawer/nav-drawer.js +9 -11
- package/components/nav-drawer/nav-drawer.js.map +1 -1
- package/components/nav-drawer/themes/container.base.css.js +1 -1
- package/components/nav-drawer/themes/container.base.css.js.map +1 -1
- package/components/nav-drawer/themes/shared/container/nav-drawer.common.css.js +1 -1
- package/components/nav-drawer/themes/shared/container/nav-drawer.common.css.js.map +1 -1
- package/components/popover/popover.d.ts +17 -16
- package/components/popover/popover.js +81 -91
- package/components/popover/popover.js.map +1 -1
- package/components/progress/base.d.ts +8 -8
- package/components/progress/base.js +19 -23
- package/components/progress/base.js.map +1 -1
- package/components/progress/circular-gradient.js.map +1 -1
- package/components/progress/circular-progress.d.ts +3 -4
- package/components/progress/circular-progress.js +15 -18
- package/components/progress/circular-progress.js.map +1 -1
- package/components/progress/linear-progress.d.ts +1 -0
- package/components/progress/linear-progress.js +5 -1
- package/components/progress/linear-progress.js.map +1 -1
- package/components/radio/radio.d.ts +3 -5
- package/components/radio/radio.js +33 -31
- package/components/radio/radio.js.map +1 -1
- package/components/radio/themes/dark/radio.fluent.css.js +1 -1
- package/components/radio/themes/dark/radio.fluent.css.js.map +1 -1
- package/components/radio/themes/shared/radio.bootstrap.css.js +1 -1
- package/components/radio/themes/shared/radio.bootstrap.css.js.map +1 -1
- package/components/radio/themes/shared/radio.common.css.js +1 -1
- package/components/radio/themes/shared/radio.common.css.js.map +1 -1
- package/components/radio/themes/shared/radio.fluent.css.js +1 -1
- package/components/radio/themes/shared/radio.fluent.css.js.map +1 -1
- package/components/radio/themes/shared/radio.indigo.css.js +1 -1
- package/components/radio/themes/shared/radio.indigo.css.js.map +1 -1
- package/components/radio/themes/shared/radio.material.css.js +1 -1
- package/components/radio/themes/shared/radio.material.css.js.map +1 -1
- package/components/radio-group/radio-group.d.ts +4 -4
- package/components/radio-group/radio-group.js +24 -21
- package/components/radio-group/radio-group.js.map +1 -1
- package/components/rating/rating.d.ts +1 -2
- package/components/rating/rating.js +4 -3
- package/components/rating/rating.js.map +1 -1
- package/components/select/select.d.ts +35 -38
- package/components/select/select.js +138 -146
- package/components/select/select.js.map +1 -1
- package/components/select/themes/shared/select.bootstrap.css.js +1 -1
- package/components/select/themes/shared/select.bootstrap.css.js.map +1 -1
- package/components/select/themes/shared/select.common.css.js +1 -1
- package/components/select/themes/shared/select.common.css.js.map +1 -1
- package/components/select/themes/shared/select.fluent.css.js +1 -1
- package/components/select/themes/shared/select.fluent.css.js.map +1 -1
- package/components/select/themes/shared/select.indigo.css.js +1 -1
- package/components/select/themes/shared/select.indigo.css.js.map +1 -1
- package/components/select/themes/shared/select.material.css.js +1 -1
- package/components/select/themes/shared/select.material.css.js.map +1 -1
- package/components/slider/slider-label.js.map +1 -1
- package/components/slider/slider.d.ts +1 -2
- package/components/slider/slider.js +5 -2
- package/components/slider/slider.js.map +1 -1
- package/components/textarea/textarea.d.ts +13 -20
- package/components/textarea/textarea.js +66 -90
- package/components/textarea/textarea.js.map +1 -1
- package/components/textarea/themes/shared/textarea.bootstrap.css.js +1 -1
- package/components/textarea/themes/shared/textarea.bootstrap.css.js.map +1 -1
- package/components/textarea/themes/shared/textarea.common.css.js +1 -1
- package/components/textarea/themes/shared/textarea.common.css.js.map +1 -1
- package/components/textarea/themes/shared/textarea.fluent.css.js +1 -1
- package/components/textarea/themes/shared/textarea.fluent.css.js.map +1 -1
- package/components/textarea/themes/shared/textarea.indigo.css.js +1 -1
- package/components/textarea/themes/shared/textarea.indigo.css.js.map +1 -1
- package/components/textarea/themes/shared/textarea.material.css.js +1 -1
- package/components/textarea/themes/shared/textarea.material.css.js.map +1 -1
- package/components/tile-manager/position.js +2 -1
- package/components/tile-manager/position.js.map +1 -1
- package/components/tile-manager/tile.d.ts +8 -12
- package/components/tile-manager/tile.js +16 -37
- package/components/tile-manager/tile.js.map +1 -1
- package/components/validation-container/validation-container.d.ts +2 -1
- package/components/validation-container/validation-container.js +19 -14
- package/components/validation-container/validation-container.js.map +1 -1
- package/custom-elements.json +38469 -33868
- package/igniteui-webcomponents.css-data.json +1 -1
- package/igniteui-webcomponents.html-data.json +1 -1
- package/index.d.ts +3 -0
- package/index.js +1 -0
- package/index.js.map +1 -1
- package/package.json +1 -1
- package/web-types.json +2 -2
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
/**
|
|
3
|
+
* A chat message list component that displays a list of chat messages grouped by date.
|
|
4
|
+
*
|
|
5
|
+
* @element igc-chat-message-list
|
|
6
|
+
*
|
|
7
|
+
* This component:
|
|
8
|
+
* - Renders messages using the `<igc-chat-message>` component.
|
|
9
|
+
* - Supports keyboard navigation between messages (Home, End, ArrowUp, ArrowDown).
|
|
10
|
+
* - Manages focus highlighting on active messages.
|
|
11
|
+
* - Automatically scrolls to the bottom when new messages arrive, unless auto-scroll is disabled.
|
|
12
|
+
* - Displays a typing indicator if the chat state option `isComposing` is true.
|
|
13
|
+
*
|
|
14
|
+
* Accessibility:
|
|
15
|
+
* - Uses ARIA roles and properties for grouping and active descendant management.
|
|
16
|
+
* - Message items have role="option" for assistive technologies.
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
export default class IgcChatMessageListComponent extends LitElement {
|
|
20
|
+
/** Tag name of the custom element. */
|
|
21
|
+
static readonly tagName = "igc-chat-message-list";
|
|
22
|
+
/** Styles applied to the component */
|
|
23
|
+
static styles: import("lit").CSSResult[];
|
|
24
|
+
/**
|
|
25
|
+
* Consumed chat state context providing messages, options, and user data.
|
|
26
|
+
* @private
|
|
27
|
+
*/
|
|
28
|
+
private _chatState?;
|
|
29
|
+
/**
|
|
30
|
+
* Currently active message id used for focus and keyboard navigation.
|
|
31
|
+
* @private
|
|
32
|
+
*/
|
|
33
|
+
private _activeMessageId;
|
|
34
|
+
/**
|
|
35
|
+
* Registers this component and its dependencies.
|
|
36
|
+
* Used internally for component setup.
|
|
37
|
+
*/
|
|
38
|
+
static register(): void;
|
|
39
|
+
constructor();
|
|
40
|
+
/**
|
|
41
|
+
* Formats a date to a human-readable label.
|
|
42
|
+
* Returns 'Today', 'Yesterday', or localized date string.
|
|
43
|
+
* @param date - Date object to format
|
|
44
|
+
* @returns formatted string
|
|
45
|
+
* @private
|
|
46
|
+
*/
|
|
47
|
+
private formatDate;
|
|
48
|
+
/**
|
|
49
|
+
* Groups messages by their date labels.
|
|
50
|
+
* @param messages - Array of messages to group
|
|
51
|
+
* @returns Array of groups with date label and messages
|
|
52
|
+
* @private
|
|
53
|
+
*/
|
|
54
|
+
private groupMessagesByDate;
|
|
55
|
+
/**
|
|
56
|
+
* Scrolls the container to the bottom, typically called after new messages are rendered.
|
|
57
|
+
* @private
|
|
58
|
+
*/
|
|
59
|
+
private scrollToBottom;
|
|
60
|
+
/**
|
|
61
|
+
* Scrolls the view to a specific message by id.
|
|
62
|
+
* @param messageId - The id of the message to scroll to
|
|
63
|
+
* @private
|
|
64
|
+
*/
|
|
65
|
+
private scrollToMessage;
|
|
66
|
+
/**
|
|
67
|
+
* Handles focus entering the message list container.
|
|
68
|
+
* Sets the active message to the last message for keyboard navigation.
|
|
69
|
+
* @private
|
|
70
|
+
*/
|
|
71
|
+
private handleFocusIn;
|
|
72
|
+
/**
|
|
73
|
+
* Handles focus leaving the message list container.
|
|
74
|
+
* Clears the active message.
|
|
75
|
+
* @private
|
|
76
|
+
*/
|
|
77
|
+
private handleFocusOut;
|
|
78
|
+
/**
|
|
79
|
+
* Handles keyboard navigation within the message list.
|
|
80
|
+
* Supports Home, End, ArrowUp, ArrowDown keys to move active message focus.
|
|
81
|
+
* @param e KeyboardEvent from user input
|
|
82
|
+
* @private
|
|
83
|
+
*/
|
|
84
|
+
private navigateToMessage;
|
|
85
|
+
/**
|
|
86
|
+
* Lifecycle: called when the component updates.
|
|
87
|
+
* Scrolls to bottom unless auto-scroll is disabled.
|
|
88
|
+
*/
|
|
89
|
+
protected updated(): void;
|
|
90
|
+
/**
|
|
91
|
+
* Lifecycle: called after first render.
|
|
92
|
+
* Scrolls to bottom unless auto-scroll is disabled.
|
|
93
|
+
*/
|
|
94
|
+
protected firstUpdated(): void;
|
|
95
|
+
/**
|
|
96
|
+
* Renders the typing indicator template if composing.
|
|
97
|
+
* @protected
|
|
98
|
+
*/
|
|
99
|
+
protected renderLoadingTemplate(): Generator<import("lit-html").TemplateResult<1>, void, unknown>;
|
|
100
|
+
/**
|
|
101
|
+
* Main render method.
|
|
102
|
+
* Groups messages by date and renders each message.
|
|
103
|
+
* Shows the typing indicator if applicable.
|
|
104
|
+
*/
|
|
105
|
+
protected render(): import("lit-html").TemplateResult<1>;
|
|
106
|
+
}
|
|
107
|
+
declare global {
|
|
108
|
+
interface HTMLElementTagNameMap {
|
|
109
|
+
'igc-chat-message-list': IgcChatMessageListComponent;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { consume } from '@lit/context';
|
|
8
|
+
import { html, LitElement, nothing } from 'lit';
|
|
9
|
+
import { state } from 'lit/decorators.js';
|
|
10
|
+
import { repeat } from 'lit/directives/repeat.js';
|
|
11
|
+
import { chatContext } from '../common/context.js';
|
|
12
|
+
import { addKeybindings, arrowDown, arrowUp, endKey, homeKey, } from '../common/controllers/key-bindings.js';
|
|
13
|
+
import { registerComponent } from '../common/definitions/register.js';
|
|
14
|
+
import IgcChatMessageComponent from './chat-message.js';
|
|
15
|
+
import { styles } from './themes/message-list.base.css.js';
|
|
16
|
+
import { styles as shared } from './themes/shared/message-list.common.css.js';
|
|
17
|
+
class IgcChatMessageListComponent extends LitElement {
|
|
18
|
+
static register() {
|
|
19
|
+
registerComponent(IgcChatMessageListComponent, IgcChatMessageComponent);
|
|
20
|
+
}
|
|
21
|
+
constructor() {
|
|
22
|
+
super();
|
|
23
|
+
this._activeMessageId = '';
|
|
24
|
+
addKeybindings(this)
|
|
25
|
+
.set(homeKey, this.navigateToMessage)
|
|
26
|
+
.set(endKey, this.navigateToMessage)
|
|
27
|
+
.set(arrowUp, this.navigateToMessage)
|
|
28
|
+
.set(arrowDown, this.navigateToMessage);
|
|
29
|
+
}
|
|
30
|
+
formatDate(date) {
|
|
31
|
+
const today = new Date();
|
|
32
|
+
const yesterday = new Date(today);
|
|
33
|
+
yesterday.setDate(yesterday.getDate() - 1);
|
|
34
|
+
if (date.toDateString() === today.toDateString()) {
|
|
35
|
+
return 'Today';
|
|
36
|
+
}
|
|
37
|
+
if (date.toDateString() === yesterday.toDateString()) {
|
|
38
|
+
return 'Yesterday';
|
|
39
|
+
}
|
|
40
|
+
return date.toLocaleDateString('en-US', {
|
|
41
|
+
weekday: 'long',
|
|
42
|
+
month: 'short',
|
|
43
|
+
day: 'numeric',
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
groupMessagesByDate(messages) {
|
|
47
|
+
const grouped = {};
|
|
48
|
+
messages.forEach((message) => {
|
|
49
|
+
const dateStr = this.formatDate(message.timestamp);
|
|
50
|
+
if (!grouped[dateStr]) {
|
|
51
|
+
grouped[dateStr] = [];
|
|
52
|
+
}
|
|
53
|
+
grouped[dateStr].push(message);
|
|
54
|
+
});
|
|
55
|
+
return Object.keys(grouped).map((date) => ({
|
|
56
|
+
date,
|
|
57
|
+
messages: grouped[date],
|
|
58
|
+
}));
|
|
59
|
+
}
|
|
60
|
+
scrollToBottom() {
|
|
61
|
+
requestAnimationFrame(() => {
|
|
62
|
+
const container = this.shadowRoot?.host;
|
|
63
|
+
if (container) {
|
|
64
|
+
container.scrollTop = container.scrollHeight;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
scrollToMessage(messageId) {
|
|
69
|
+
const messageElement = this.shadowRoot?.querySelector(`#message-${messageId}`);
|
|
70
|
+
messageElement?.scrollIntoView();
|
|
71
|
+
}
|
|
72
|
+
handleFocusIn() {
|
|
73
|
+
if (!this._chatState?.messages || this._chatState.messages.length === 0) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const lastMessage = this._chatState.sortedMessagesIds?.pop() ?? '';
|
|
77
|
+
this._activeMessageId = lastMessage !== '' ? `message-${lastMessage}` : '';
|
|
78
|
+
}
|
|
79
|
+
handleFocusOut() {
|
|
80
|
+
this._activeMessageId = '';
|
|
81
|
+
}
|
|
82
|
+
navigateToMessage(e) {
|
|
83
|
+
if (!this._chatState?.messages || this._chatState.messages.length === 0) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const currentIndex = this._chatState?.sortedMessagesIds.findIndex((id) => `message-${id}` === this._activeMessageId);
|
|
87
|
+
let activeMessageId = '';
|
|
88
|
+
const key = e.key.toLowerCase();
|
|
89
|
+
switch (key) {
|
|
90
|
+
case 'home':
|
|
91
|
+
activeMessageId = this._chatState.sortedMessagesIds[0];
|
|
92
|
+
break;
|
|
93
|
+
case 'end':
|
|
94
|
+
activeMessageId =
|
|
95
|
+
this._chatState.sortedMessagesIds[this._chatState.sortedMessagesIds.length - 1];
|
|
96
|
+
break;
|
|
97
|
+
case 'arrowup':
|
|
98
|
+
if (currentIndex > 0) {
|
|
99
|
+
activeMessageId = this._chatState.sortedMessagesIds[currentIndex - 1];
|
|
100
|
+
}
|
|
101
|
+
break;
|
|
102
|
+
case 'arrowdown':
|
|
103
|
+
if (currentIndex < this._chatState?.messages.length - 1) {
|
|
104
|
+
activeMessageId = this._chatState.sortedMessagesIds[currentIndex + 1];
|
|
105
|
+
}
|
|
106
|
+
break;
|
|
107
|
+
default:
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
this._activeMessageId = `message-${activeMessageId}`;
|
|
111
|
+
this.scrollToMessage(activeMessageId);
|
|
112
|
+
}
|
|
113
|
+
updated() {
|
|
114
|
+
if (!this._chatState?.options?.disableAutoScroll) {
|
|
115
|
+
this.scrollToBottom();
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
firstUpdated() {
|
|
119
|
+
if (!this._chatState?.options?.disableAutoScroll) {
|
|
120
|
+
this.scrollToBottom();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
*renderLoadingTemplate() {
|
|
124
|
+
yield html `${this._chatState?.options?.templates?.composingIndicatorTemplate
|
|
125
|
+
? this._chatState.options.templates.composingIndicatorTemplate
|
|
126
|
+
: html `<div part="typing-indicator">
|
|
127
|
+
<div part="typing-dot"></div>
|
|
128
|
+
<div part="typing-dot"></div>
|
|
129
|
+
<div part="typing-dot"></div>
|
|
130
|
+
</div>`}`;
|
|
131
|
+
}
|
|
132
|
+
render() {
|
|
133
|
+
const groupedMessages = this.groupMessagesByDate(this._chatState?.messages ?? []);
|
|
134
|
+
return html `
|
|
135
|
+
<div
|
|
136
|
+
part="message-container"
|
|
137
|
+
aria-activedescendant=${this._activeMessageId}
|
|
138
|
+
role="group"
|
|
139
|
+
aria-label="Message list"
|
|
140
|
+
tabindex="0"
|
|
141
|
+
@focusin=${this.handleFocusIn}
|
|
142
|
+
@focusout=${this.handleFocusOut}
|
|
143
|
+
></div>
|
|
144
|
+
<div part="message-list">
|
|
145
|
+
${repeat(groupedMessages, (group) => group.date, (group) => html `
|
|
146
|
+
${repeat(group.messages, (message) => message.id, (message) => {
|
|
147
|
+
const messageId = `message-${message.id}`;
|
|
148
|
+
return html `
|
|
149
|
+
<igc-chat-message
|
|
150
|
+
id=${messageId}
|
|
151
|
+
role="option"
|
|
152
|
+
part="message-item ${this._activeMessageId === messageId
|
|
153
|
+
? 'active'
|
|
154
|
+
: ''}"
|
|
155
|
+
.message=${message}
|
|
156
|
+
>
|
|
157
|
+
</igc-chat-message>
|
|
158
|
+
`;
|
|
159
|
+
})}
|
|
160
|
+
`)}
|
|
161
|
+
${this._chatState?.options?.isComposing
|
|
162
|
+
? this.renderLoadingTemplate()
|
|
163
|
+
: nothing}
|
|
164
|
+
</div>
|
|
165
|
+
</div>
|
|
166
|
+
`;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
IgcChatMessageListComponent.tagName = 'igc-chat-message-list';
|
|
170
|
+
IgcChatMessageListComponent.styles = [styles, shared];
|
|
171
|
+
export default IgcChatMessageListComponent;
|
|
172
|
+
__decorate([
|
|
173
|
+
consume({ context: chatContext, subscribe: true })
|
|
174
|
+
], IgcChatMessageListComponent.prototype, "_chatState", void 0);
|
|
175
|
+
__decorate([
|
|
176
|
+
state()
|
|
177
|
+
], IgcChatMessageListComponent.prototype, "_activeMessageId", void 0);
|
|
178
|
+
//# sourceMappingURL=chat-message-list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-message-list.js","sourceRoot":"","sources":["../../../src/components/chat/chat-message-list.ts"],"names":[],"mappings":"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","sourcesContent":["import { consume } from '@lit/context';\nimport { html, LitElement, nothing } from 'lit';\nimport { state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { chatContext } from '../common/context.js';\nimport {\n addKeybindings,\n arrowDown,\n arrowUp,\n endKey,\n homeKey,\n} from '../common/controllers/key-bindings.js';\nimport { registerComponent } from '../common/definitions/register.js';\nimport IgcChatMessageComponent from './chat-message.js';\nimport type { ChatState } from './chat-state.js';\nimport { styles } from './themes/message-list.base.css.js';\nimport { styles as shared } from './themes/shared/message-list.common.css.js';\nimport type { IgcMessage } from './types.js';\n\n/**\n * A chat message list component that displays a list of chat messages grouped by date.\n *\n * @element igc-chat-message-list\n *\n * This component:\n * - Renders messages using the `<igc-chat-message>` component.\n * - Supports keyboard navigation between messages (Home, End, ArrowUp, ArrowDown).\n * - Manages focus highlighting on active messages.\n * - Automatically scrolls to the bottom when new messages arrive, unless auto-scroll is disabled.\n * - Displays a typing indicator if the chat state option `isComposing` is true.\n *\n * Accessibility:\n * - Uses ARIA roles and properties for grouping and active descendant management.\n * - Message items have role=\"option\" for assistive technologies.\n *\n */\nexport default class IgcChatMessageListComponent extends LitElement {\n /** Tag name of the custom element. */\n public static readonly tagName = 'igc-chat-message-list';\n\n /** Styles applied to the component */\n public static override styles = [styles, shared];\n\n /**\n * Consumed chat state context providing messages, options, and user data.\n * @private\n */\n @consume({ context: chatContext, subscribe: true })\n private _chatState?: ChatState;\n\n /**\n * Currently active message id used for focus and keyboard navigation.\n * @private\n */\n @state()\n private _activeMessageId = '';\n\n /**\n * Registers this component and its dependencies.\n * Used internally for component setup.\n */\n /* blazorSuppress */\n public static register() {\n registerComponent(IgcChatMessageListComponent, IgcChatMessageComponent);\n }\n\n constructor() {\n super();\n addKeybindings(this)\n .set(homeKey, this.navigateToMessage)\n .set(endKey, this.navigateToMessage)\n .set(arrowUp, this.navigateToMessage)\n .set(arrowDown, this.navigateToMessage);\n }\n\n /**\n * Formats a date to a human-readable label.\n * Returns 'Today', 'Yesterday', or localized date string.\n * @param date - Date object to format\n * @returns formatted string\n * @private\n */\n private formatDate(date: Date): string {\n const today = new Date();\n const yesterday = new Date(today);\n yesterday.setDate(yesterday.getDate() - 1);\n\n if (date.toDateString() === today.toDateString()) {\n return 'Today';\n }\n\n if (date.toDateString() === yesterday.toDateString()) {\n return 'Yesterday';\n }\n\n return date.toLocaleDateString('en-US', {\n weekday: 'long',\n month: 'short',\n day: 'numeric',\n });\n }\n\n /**\n * Groups messages by their date labels.\n * @param messages - Array of messages to group\n * @returns Array of groups with date label and messages\n * @private\n */\n private groupMessagesByDate(\n messages: IgcMessage[]\n ): { date: string; messages: IgcMessage[] }[] {\n const grouped: { [key: string]: IgcMessage[] } = {};\n\n messages.forEach((message) => {\n const dateStr = this.formatDate(message.timestamp);\n if (!grouped[dateStr]) {\n grouped[dateStr] = [];\n }\n grouped[dateStr].push(message);\n });\n\n return Object.keys(grouped).map((date) => ({\n date,\n messages: grouped[date],\n }));\n }\n\n /**\n * Scrolls the container to the bottom, typically called after new messages are rendered.\n * @private\n */\n private scrollToBottom() {\n requestAnimationFrame(() => {\n const container = this.shadowRoot?.host as HTMLElement;\n if (container) {\n container.scrollTop = container.scrollHeight;\n }\n });\n }\n\n /**\n * Scrolls the view to a specific message by id.\n * @param messageId - The id of the message to scroll to\n * @private\n */\n private scrollToMessage(messageId: string) {\n const messageElement = this.shadowRoot?.querySelector(\n `#message-${messageId}`\n );\n messageElement?.scrollIntoView();\n }\n\n /**\n * Handles focus entering the message list container.\n * Sets the active message to the last message for keyboard navigation.\n * @private\n */\n private handleFocusIn() {\n if (!this._chatState?.messages || this._chatState.messages.length === 0) {\n return;\n }\n const lastMessage = this._chatState.sortedMessagesIds?.pop() ?? '';\n this._activeMessageId = lastMessage !== '' ? `message-${lastMessage}` : '';\n }\n\n /**\n * Handles focus leaving the message list container.\n * Clears the active message.\n * @private\n */\n private handleFocusOut() {\n this._activeMessageId = '';\n }\n\n /**\n * Handles keyboard navigation within the message list.\n * Supports Home, End, ArrowUp, ArrowDown keys to move active message focus.\n * @param e KeyboardEvent from user input\n * @private\n */\n private navigateToMessage(e: KeyboardEvent) {\n if (!this._chatState?.messages || this._chatState.messages.length === 0) {\n return;\n }\n\n const currentIndex = this._chatState?.sortedMessagesIds.findIndex(\n (id) => `message-${id}` === this._activeMessageId\n );\n let activeMessageId = '';\n const key = e.key.toLowerCase();\n\n switch (key) {\n case 'home':\n activeMessageId = this._chatState.sortedMessagesIds[0];\n break;\n case 'end':\n activeMessageId =\n this._chatState.sortedMessagesIds[\n this._chatState.sortedMessagesIds.length - 1\n ];\n break;\n case 'arrowup':\n if (currentIndex > 0) {\n activeMessageId = this._chatState.sortedMessagesIds[currentIndex - 1];\n }\n break;\n case 'arrowdown':\n if (currentIndex < this._chatState?.messages.length - 1) {\n activeMessageId = this._chatState.sortedMessagesIds[currentIndex + 1];\n }\n break;\n default:\n return; // Ignore other keys\n }\n\n this._activeMessageId = `message-${activeMessageId}`;\n this.scrollToMessage(activeMessageId);\n }\n\n /**\n * Lifecycle: called when the component updates.\n * Scrolls to bottom unless auto-scroll is disabled.\n */\n protected override updated() {\n if (!this._chatState?.options?.disableAutoScroll) {\n this.scrollToBottom();\n }\n }\n\n /**\n * Lifecycle: called after first render.\n * Scrolls to bottom unless auto-scroll is disabled.\n */\n protected override firstUpdated() {\n if (!this._chatState?.options?.disableAutoScroll) {\n this.scrollToBottom();\n }\n }\n\n /**\n * Renders the typing indicator template if composing.\n * @protected\n */\n protected *renderLoadingTemplate() {\n yield html`${this._chatState?.options?.templates?.composingIndicatorTemplate\n ? this._chatState.options.templates.composingIndicatorTemplate\n : html`<div part=\"typing-indicator\">\n <div part=\"typing-dot\"></div>\n <div part=\"typing-dot\"></div>\n <div part=\"typing-dot\"></div>\n </div>`}`;\n }\n\n /**\n * Main render method.\n * Groups messages by date and renders each message.\n * Shows the typing indicator if applicable.\n */\n protected override render() {\n const groupedMessages = this.groupMessagesByDate(\n this._chatState?.messages ?? []\n );\n\n return html`\n <div\n part=\"message-container\"\n aria-activedescendant=${this._activeMessageId}\n role=\"group\"\n aria-label=\"Message list\"\n tabindex=\"0\"\n @focusin=${this.handleFocusIn}\n @focusout=${this.handleFocusOut}\n ></div>\n <div part=\"message-list\">\n ${repeat(\n groupedMessages,\n (group) => group.date,\n (group) => html`\n ${repeat(\n group.messages,\n (message) => message.id,\n (message) => {\n const messageId = `message-${message.id}`;\n return html`\n <igc-chat-message\n id=${messageId}\n role=\"option\"\n part=\"message-item ${this._activeMessageId === messageId\n ? 'active'\n : ''}\"\n .message=${message}\n >\n </igc-chat-message>\n `;\n }\n )}\n `\n )}\n ${\n this._chatState?.options?.isComposing\n ? this.renderLoadingTemplate()\n : nothing\n }\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'igc-chat-message-list': IgcChatMessageListComponent;\n }\n}\n"]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
import type { IgcMessage } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* A chat message component for displaying individual messages in `<igc-chat>`.
|
|
5
|
+
*
|
|
6
|
+
* @element igc-chat-message
|
|
7
|
+
*
|
|
8
|
+
* This component renders a single chat message including:
|
|
9
|
+
* - Message text (sanitized)
|
|
10
|
+
* - Attachments (if any)
|
|
11
|
+
* - Custom templates for message content and actions (if provided via chat options)
|
|
12
|
+
*
|
|
13
|
+
* It distinguishes sent messages from received messages by comparing
|
|
14
|
+
* the message sender with the current user ID from chat state.
|
|
15
|
+
*
|
|
16
|
+
* The message text is sanitized with DOMPurify before rendering,
|
|
17
|
+
* and can be rendered with a markdown renderer if provided.
|
|
18
|
+
*/
|
|
19
|
+
export default class IgcChatMessageComponent extends LitElement {
|
|
20
|
+
/** Tag name of the custom element. */
|
|
21
|
+
static readonly tagName = "igc-chat-message";
|
|
22
|
+
/** Styles applied to the component. */
|
|
23
|
+
static styles: import("lit").CSSResult[];
|
|
24
|
+
/**
|
|
25
|
+
* Injected chat state context. Provides message data, user info, and options.
|
|
26
|
+
* @private
|
|
27
|
+
*/
|
|
28
|
+
private _chatState?;
|
|
29
|
+
/**
|
|
30
|
+
* Registers this component and its dependencies.
|
|
31
|
+
* This is used internally to set up the component definitions.
|
|
32
|
+
*/
|
|
33
|
+
static register(): void;
|
|
34
|
+
/**
|
|
35
|
+
* The chat message to render.
|
|
36
|
+
*/
|
|
37
|
+
message: IgcMessage | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Sanitizes message text to prevent XSS or invalid HTML.
|
|
40
|
+
* @param text The raw message text
|
|
41
|
+
* @returns Sanitized text safe for HTML rendering
|
|
42
|
+
* @private
|
|
43
|
+
*/
|
|
44
|
+
private sanitizeMessageText;
|
|
45
|
+
/**
|
|
46
|
+
* Renders the chat message template.
|
|
47
|
+
* - Applies 'sent' CSS class if the message sender matches current user.
|
|
48
|
+
* - Uses markdown rendering if configured.
|
|
49
|
+
* - Renders attachments and custom templates if provided.
|
|
50
|
+
*/
|
|
51
|
+
protected render(): import("lit-html").TemplateResult<1>;
|
|
52
|
+
}
|
|
53
|
+
declare global {
|
|
54
|
+
interface HTMLElementTagNameMap {
|
|
55
|
+
'igc-chat-message': IgcChatMessageComponent;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { consume } from '@lit/context';
|
|
8
|
+
import DOMPurify from 'dompurify';
|
|
9
|
+
import { html, LitElement, nothing } from 'lit';
|
|
10
|
+
import { property } from 'lit/decorators.js';
|
|
11
|
+
import IgcAvatarComponent from '../avatar/avatar.js';
|
|
12
|
+
import { chatContext } from '../common/context.js';
|
|
13
|
+
import { registerComponent } from '../common/definitions/register.js';
|
|
14
|
+
import { renderMarkdown } from './markdown-util.js';
|
|
15
|
+
import IgcMessageAttachmentsComponent from './message-attachments.js';
|
|
16
|
+
import { styles } from './themes/message.base.css.js';
|
|
17
|
+
import { styles as shared } from './themes/shared/chat-message.common.css.js';
|
|
18
|
+
class IgcChatMessageComponent extends LitElement {
|
|
19
|
+
static register() {
|
|
20
|
+
registerComponent(IgcChatMessageComponent, IgcMessageAttachmentsComponent, IgcAvatarComponent);
|
|
21
|
+
}
|
|
22
|
+
sanitizeMessageText(text) {
|
|
23
|
+
return DOMPurify.sanitize(text);
|
|
24
|
+
}
|
|
25
|
+
render() {
|
|
26
|
+
const containerPart = `message-container ${this.message?.sender === this._chatState?.currentUserId ? 'sent' : ''}`;
|
|
27
|
+
const sanitizedMessageText = this.sanitizeMessageText(this.message?.text.trim() || '');
|
|
28
|
+
const renderer = this._chatState?.options?.markdownRenderer || renderMarkdown;
|
|
29
|
+
return html `
|
|
30
|
+
<div part=${containerPart}>
|
|
31
|
+
<div part="bubble">
|
|
32
|
+
${this._chatState?.options?.templates?.messageTemplate && this.message
|
|
33
|
+
? this._chatState.options.templates.messageTemplate(this.message)
|
|
34
|
+
: html `${sanitizedMessageText
|
|
35
|
+
? html `<div>${renderer(sanitizedMessageText)}</div>`
|
|
36
|
+
: nothing}`}
|
|
37
|
+
${this.message?.attachments && this.message?.attachments.length > 0
|
|
38
|
+
? html `<igc-message-attachments .message=${this.message}>
|
|
39
|
+
</igc-message-attachments>`
|
|
40
|
+
: nothing}
|
|
41
|
+
${this._chatState?.options?.templates?.messageActionsTemplate &&
|
|
42
|
+
this.message
|
|
43
|
+
? this._chatState.options.templates.messageActionsTemplate(this.message)
|
|
44
|
+
: nothing}
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
`;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
IgcChatMessageComponent.tagName = 'igc-chat-message';
|
|
51
|
+
IgcChatMessageComponent.styles = [styles, shared];
|
|
52
|
+
export default IgcChatMessageComponent;
|
|
53
|
+
__decorate([
|
|
54
|
+
consume({ context: chatContext, subscribe: true })
|
|
55
|
+
], IgcChatMessageComponent.prototype, "_chatState", void 0);
|
|
56
|
+
__decorate([
|
|
57
|
+
property({ attribute: false })
|
|
58
|
+
], IgcChatMessageComponent.prototype, "message", void 0);
|
|
59
|
+
//# sourceMappingURL=chat-message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-message.js","sourceRoot":"","sources":["../../../src/components/chat/chat-message.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,SAAS,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,kBAAkB,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AAEtE,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,8BAA8B,MAAM,0BAA0B,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,MAAM,8BAA8B,CAAC;AACtD,OAAO,EAAE,MAAM,IAAI,MAAM,EAAE,MAAM,4CAA4C,CAAC;AAmB9E,MAAqB,uBAAwB,SAAQ,UAAU;IAmBtD,MAAM,CAAC,QAAQ;QACpB,iBAAiB,CACf,uBAAuB,EACvB,8BAA8B,EAC9B,kBAAkB,CACnB,CAAC;IACJ,CAAC;IAcO,mBAAmB,CAAC,IAAY;QACtC,OAAO,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAClC,CAAC;IAQkB,MAAM;QACvB,MAAM,aAAa,GAAG,qBAAqB,IAAI,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACnH,MAAM,oBAAoB,GAAG,IAAI,CAAC,mBAAmB,CACnD,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,CAChC,CAAC;QACF,MAAM,QAAQ,GACZ,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,gBAAgB,IAAI,cAAc,CAAC;QAE/D,OAAO,IAAI,CAAA;kBACG,aAAa;;YAEnB,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,eAAe,IAAI,IAAI,CAAC,OAAO;YACpE,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC;YACjE,CAAC,CAAC,IAAI,CAAA,GAAG,oBAAoB;gBACzB,CAAC,CAAC,IAAI,CAAA,QAAQ,QAAQ,CAAC,oBAAoB,CAAC,QAAQ;gBACpD,CAAC,CAAC,OAAO,EAAE;YACf,IAAI,CAAC,OAAO,EAAE,WAAW,IAAI,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,GAAG,CAAC;YACjE,CAAC,CAAC,IAAI,CAAA,qCAAqC,IAAI,CAAC,OAAO;yCAC1B;YAC7B,CAAC,CAAC,OAAO;YACT,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,sBAAsB;YAC7D,IAAI,CAAC,OAAO;YACV,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,sBAAsB,CACtD,IAAI,CAAC,OAAO,CACb;YACH,CAAC,CAAC,OAAO;;;KAGhB,CAAC;IACJ,CAAC;;AA5EsB,+BAAO,GAAG,kBAAkB,CAAC;AAG7B,8BAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;eAL9B,uBAAuB;AAYlC;IADP,OAAO,CAAC,EAAE,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;2DACpB;AAmBxB;IADN,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;wDACQ","sourcesContent":["import { consume } from '@lit/context';\nimport DOMPurify from 'dompurify';\nimport { html, LitElement, nothing } from 'lit';\nimport { property } from 'lit/decorators.js';\nimport IgcAvatarComponent from '../avatar/avatar.js';\nimport { chatContext } from '../common/context.js';\nimport { registerComponent } from '../common/definitions/register.js';\nimport type { ChatState } from './chat-state.js';\nimport { renderMarkdown } from './markdown-util.js';\nimport IgcMessageAttachmentsComponent from './message-attachments.js';\nimport { styles } from './themes/message.base.css.js';\nimport { styles as shared } from './themes/shared/chat-message.common.css.js';\nimport type { IgcMessage } from './types.js';\n\n/**\n * A chat message component for displaying individual messages in `<igc-chat>`.\n *\n * @element igc-chat-message\n *\n * This component renders a single chat message including:\n * - Message text (sanitized)\n * - Attachments (if any)\n * - Custom templates for message content and actions (if provided via chat options)\n *\n * It distinguishes sent messages from received messages by comparing\n * the message sender with the current user ID from chat state.\n *\n * The message text is sanitized with DOMPurify before rendering,\n * and can be rendered with a markdown renderer if provided.\n */\nexport default class IgcChatMessageComponent extends LitElement {\n /** Tag name of the custom element. */\n public static readonly tagName = 'igc-chat-message';\n\n /** Styles applied to the component. */\n public static override styles = [styles, shared];\n\n /**\n * Injected chat state context. Provides message data, user info, and options.\n * @private\n */\n @consume({ context: chatContext, subscribe: true })\n private _chatState?: ChatState;\n\n /**\n * Registers this component and its dependencies.\n * This is used internally to set up the component definitions.\n */\n /* blazorSuppress */\n public static register() {\n registerComponent(\n IgcChatMessageComponent,\n IgcMessageAttachmentsComponent,\n IgcAvatarComponent\n );\n }\n\n /**\n * The chat message to render.\n */\n @property({ attribute: false })\n public message: IgcMessage | undefined;\n\n /**\n * Sanitizes message text to prevent XSS or invalid HTML.\n * @param text The raw message text\n * @returns Sanitized text safe for HTML rendering\n * @private\n */\n private sanitizeMessageText(text: string): string {\n return DOMPurify.sanitize(text);\n }\n\n /**\n * Renders the chat message template.\n * - Applies 'sent' CSS class if the message sender matches current user.\n * - Uses markdown rendering if configured.\n * - Renders attachments and custom templates if provided.\n */\n protected override render() {\n const containerPart = `message-container ${this.message?.sender === this._chatState?.currentUserId ? 'sent' : ''}`;\n const sanitizedMessageText = this.sanitizeMessageText(\n this.message?.text.trim() || ''\n );\n const renderer =\n this._chatState?.options?.markdownRenderer || renderMarkdown;\n\n return html`\n <div part=${containerPart}>\n <div part=\"bubble\">\n ${this._chatState?.options?.templates?.messageTemplate && this.message\n ? this._chatState.options.templates.messageTemplate(this.message)\n : html`${sanitizedMessageText\n ? html`<div>${renderer(sanitizedMessageText)}</div>`\n : nothing}`}\n ${this.message?.attachments && this.message?.attachments.length > 0\n ? html`<igc-message-attachments .message=${this.message}>\n </igc-message-attachments>`\n : nothing}\n ${this._chatState?.options?.templates?.messageActionsTemplate &&\n this.message\n ? this._chatState.options.templates.messageActionsTemplate(\n this.message\n )\n : nothing}\n </div>\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'igc-chat-message': IgcChatMessageComponent;\n }\n}\n"]}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import type IgcTextareaComponent from '../textarea/textarea.js';
|
|
2
|
+
import type IgcChatComponent from './chat.js';
|
|
3
|
+
import type { IgcChatComponentEventMap } from './chat.js';
|
|
4
|
+
import type { IgcChatOptions, IgcMessage, IgcMessageAttachment } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Internal state manager for the `<igc-chat>` component.
|
|
7
|
+
*
|
|
8
|
+
* Manages messages, input value, attachments, options, and event emissions.
|
|
9
|
+
*/
|
|
10
|
+
export declare class ChatState {
|
|
11
|
+
private readonly _host;
|
|
12
|
+
/** Reference to the text area input component */
|
|
13
|
+
private _textArea;
|
|
14
|
+
/** The current list of messages */
|
|
15
|
+
private _messages;
|
|
16
|
+
/** Sorted copy of messages by timestamp */
|
|
17
|
+
private _sortedMessages;
|
|
18
|
+
/** Chat options/configuration */
|
|
19
|
+
private _options?;
|
|
20
|
+
/** List of current input attachments */
|
|
21
|
+
private _inputAttachments;
|
|
22
|
+
/** Current input text */
|
|
23
|
+
private _inputValue;
|
|
24
|
+
/**
|
|
25
|
+
* Cache of accepted file types, organized into extensions, mimeTypes, and wildcardTypes
|
|
26
|
+
*/
|
|
27
|
+
private _acceptedTypesCache;
|
|
28
|
+
private _suggestionsPosition;
|
|
29
|
+
/**
|
|
30
|
+
* Array of message IDs sorted by timestamp ascending.
|
|
31
|
+
*/
|
|
32
|
+
get sortedMessagesIds(): string[];
|
|
33
|
+
/**
|
|
34
|
+
* Gets the list of chat messages.
|
|
35
|
+
*/
|
|
36
|
+
get messages(): IgcMessage[];
|
|
37
|
+
/**
|
|
38
|
+
* Sets the list of chat messages.
|
|
39
|
+
* Also sorts messages by timestamp and requests host update.
|
|
40
|
+
*/
|
|
41
|
+
set messages(value: IgcMessage[]);
|
|
42
|
+
/**
|
|
43
|
+
* Gets current chat options.
|
|
44
|
+
*/
|
|
45
|
+
get options(): IgcChatOptions | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Sets chat options and requests host update.
|
|
48
|
+
*/
|
|
49
|
+
set options(value: IgcChatOptions);
|
|
50
|
+
/**
|
|
51
|
+
* Gets the current user ID from options or returns 'user' as fallback.
|
|
52
|
+
*/
|
|
53
|
+
get currentUserId(): string;
|
|
54
|
+
/**
|
|
55
|
+
* Gets the current suggestionsPosition from options or returns the default value 'below-messages'.
|
|
56
|
+
*/
|
|
57
|
+
get suggestionsPosition(): string;
|
|
58
|
+
/**
|
|
59
|
+
* Gets the text area component.
|
|
60
|
+
*/
|
|
61
|
+
get textArea(): IgcTextareaComponent | null;
|
|
62
|
+
/**
|
|
63
|
+
* Sets the text area component.
|
|
64
|
+
*/
|
|
65
|
+
set textArea(value: IgcTextareaComponent);
|
|
66
|
+
/**
|
|
67
|
+
* Gets the list of attachments currently attached to input.
|
|
68
|
+
*/
|
|
69
|
+
get inputAttachments(): IgcMessageAttachment[];
|
|
70
|
+
/**
|
|
71
|
+
* Sets the input attachments and requests host update.
|
|
72
|
+
*/
|
|
73
|
+
set inputAttachments(value: IgcMessageAttachment[]);
|
|
74
|
+
/**
|
|
75
|
+
* Gets the current input value.
|
|
76
|
+
*/
|
|
77
|
+
get inputValue(): string;
|
|
78
|
+
/**
|
|
79
|
+
* Sets the current input value and requests host update.
|
|
80
|
+
*/
|
|
81
|
+
set inputValue(value: string);
|
|
82
|
+
/**
|
|
83
|
+
* Creates an instance of ChatState.
|
|
84
|
+
* @param chat The host `<igc-chat>` component.
|
|
85
|
+
*/
|
|
86
|
+
constructor(chat: IgcChatComponent);
|
|
87
|
+
/**
|
|
88
|
+
* Emits a custom event from the host component.
|
|
89
|
+
* @param name Event name (key of IgcChatComponentEventMap)
|
|
90
|
+
* @param args Event detail or options
|
|
91
|
+
* @returns true if event was not canceled, false otherwise
|
|
92
|
+
*/
|
|
93
|
+
emitEvent(name: keyof IgcChatComponentEventMap, args?: any): boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Handles input text changes.
|
|
96
|
+
* Updates internal inputValue and emits 'igcInputChange' event.
|
|
97
|
+
* @param value New input value
|
|
98
|
+
*/
|
|
99
|
+
handleInputChange(value: string): void;
|
|
100
|
+
/**
|
|
101
|
+
* Adds a new chat message.
|
|
102
|
+
* Emits 'igcMessageCreated' event which can be canceled to prevent adding.
|
|
103
|
+
* Clears input value and attachments on success.
|
|
104
|
+
* @param message Partial message object with optional id, sender, timestamp
|
|
105
|
+
*/
|
|
106
|
+
addMessage(message: {
|
|
107
|
+
id?: string;
|
|
108
|
+
text: string;
|
|
109
|
+
sender?: string;
|
|
110
|
+
timestamp?: Date;
|
|
111
|
+
attachments?: IgcMessageAttachment[];
|
|
112
|
+
}): void;
|
|
113
|
+
/**
|
|
114
|
+
* Adds files as attachments to the input.
|
|
115
|
+
* Emits 'igcAttachmentChange' event which can be canceled to prevent adding.
|
|
116
|
+
* @param files Array of File objects to attach
|
|
117
|
+
*/
|
|
118
|
+
attachFiles(files: File[]): void;
|
|
119
|
+
/**
|
|
120
|
+
* Removes an attachment by index.
|
|
121
|
+
* Emits 'igcAttachmentChange' event which can be canceled to prevent removal.
|
|
122
|
+
* @param index Index of the attachment to remove
|
|
123
|
+
*/
|
|
124
|
+
removeAttachment(index: number): void;
|
|
125
|
+
/**
|
|
126
|
+
* Handles when a suggestion is clicked.
|
|
127
|
+
* Adds the suggestion as a new message and focuses the text area.
|
|
128
|
+
* @param suggestion The suggestion string clicked
|
|
129
|
+
*/
|
|
130
|
+
handleSuggestionClick(suggestion: string): void;
|
|
131
|
+
/**
|
|
132
|
+
* Updates the chat options partially.
|
|
133
|
+
* @param options Partial options to merge with current options
|
|
134
|
+
*/
|
|
135
|
+
updateOptions(options: Partial<IgcChatOptions>): void;
|
|
136
|
+
/**
|
|
137
|
+
* Updates the internal cache for accepted file types.
|
|
138
|
+
* Parses the acceptedFiles string option into extensions, mimeTypes, and wildcard types.
|
|
139
|
+
*/
|
|
140
|
+
updateAcceptedTypesCache(): void;
|
|
141
|
+
/**
|
|
142
|
+
* Checks if a file's type or extension is accepted by the chat's acceptedFiles setting.
|
|
143
|
+
* @param file File object to check
|
|
144
|
+
* @param type Optional MIME type override if no file provided
|
|
145
|
+
* @returns True if accepted, false otherwise
|
|
146
|
+
*/
|
|
147
|
+
isFileTypeAccepted(file: File, type?: string): boolean;
|
|
148
|
+
/**
|
|
149
|
+
* Checks if a slot is empty.
|
|
150
|
+
* @param name Slot name to check
|
|
151
|
+
* @returns True if the slot has content, false otherwise
|
|
152
|
+
*/
|
|
153
|
+
hasSlotContent(name: string): boolean;
|
|
154
|
+
}
|
|
155
|
+
export declare function createChatState(host: IgcChatComponent): ChatState;
|