snice 5.2.2 → 6.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/README.md +5 -8
- package/adapters/react/SniceProvider.js +1 -1
- package/adapters/react/SniceRouter.js +1 -1
- package/adapters/react/audio-recorder.d.ts +0 -4
- package/adapters/react/audio-recorder.d.ts.map +1 -1
- package/adapters/react/audio-recorder.js +1 -1
- package/adapters/react/audio-recorder.js.map +1 -1
- package/adapters/react/audio-recorder.tsx +1 -5
- package/adapters/react/avatar.d.ts +0 -1
- package/adapters/react/avatar.d.ts.map +1 -1
- package/adapters/react/avatar.js +1 -1
- package/adapters/react/avatar.js.map +1 -1
- package/adapters/react/avatar.tsx +1 -2
- package/adapters/react/breadcrumbs.d.ts +0 -1
- package/adapters/react/breadcrumbs.d.ts.map +1 -1
- package/adapters/react/breadcrumbs.js +1 -1
- package/adapters/react/breadcrumbs.js.map +1 -1
- package/adapters/react/breadcrumbs.tsx +1 -2
- package/adapters/react/camera-annotate.d.ts +0 -5
- package/adapters/react/camera-annotate.d.ts.map +1 -1
- package/adapters/react/camera-annotate.js +1 -1
- package/adapters/react/camera-annotate.js.map +1 -1
- package/adapters/react/camera-annotate.tsx +1 -6
- package/adapters/react/card.d.ts +0 -2
- package/adapters/react/card.d.ts.map +1 -1
- package/adapters/react/card.js +1 -1
- package/adapters/react/card.js.map +1 -1
- package/adapters/react/card.tsx +1 -3
- package/adapters/react/carousel.d.ts +0 -1
- package/adapters/react/carousel.d.ts.map +1 -1
- package/adapters/react/carousel.js +1 -1
- package/adapters/react/carousel.js.map +1 -1
- package/adapters/react/carousel.tsx +1 -2
- package/adapters/react/cart.d.ts +0 -1
- package/adapters/react/cart.d.ts.map +1 -1
- package/adapters/react/cart.js +1 -1
- package/adapters/react/cart.js.map +1 -1
- package/adapters/react/cart.tsx +1 -2
- package/adapters/react/chart.d.ts +0 -5
- package/adapters/react/chart.d.ts.map +1 -1
- package/adapters/react/chart.js +1 -1
- package/adapters/react/chart.js.map +1 -1
- package/adapters/react/chart.tsx +1 -6
- package/adapters/react/chat.d.ts +4 -1
- package/adapters/react/chat.d.ts.map +1 -1
- package/adapters/react/chat.js +2 -2
- package/adapters/react/chat.js.map +1 -1
- package/adapters/react/chat.tsx +6 -3
- package/adapters/react/chip.d.ts +0 -1
- package/adapters/react/chip.d.ts.map +1 -1
- package/adapters/react/chip.js +1 -1
- package/adapters/react/chip.js.map +1 -1
- package/adapters/react/chip.tsx +1 -2
- package/adapters/react/command-palette.d.ts +0 -4
- package/adapters/react/command-palette.d.ts.map +1 -1
- package/adapters/react/command-palette.js +1 -1
- package/adapters/react/command-palette.js.map +1 -1
- package/adapters/react/command-palette.tsx +1 -5
- package/adapters/react/comments.d.ts +0 -1
- package/adapters/react/comments.d.ts.map +1 -1
- package/adapters/react/comments.js +1 -1
- package/adapters/react/comments.js.map +1 -1
- package/adapters/react/comments.tsx +1 -2
- package/adapters/react/countdown.d.ts +0 -4
- package/adapters/react/countdown.d.ts.map +1 -1
- package/adapters/react/countdown.js +1 -1
- package/adapters/react/countdown.js.map +1 -1
- package/adapters/react/countdown.tsx +1 -5
- package/adapters/react/date-time-picker.d.ts +0 -1
- package/adapters/react/date-time-picker.d.ts.map +1 -1
- package/adapters/react/date-time-picker.js +1 -1
- package/adapters/react/date-time-picker.js.map +1 -1
- package/adapters/react/date-time-picker.tsx +1 -2
- package/adapters/react/file-upload.d.ts +0 -2
- package/adapters/react/file-upload.d.ts.map +1 -1
- package/adapters/react/file-upload.js +1 -1
- package/adapters/react/file-upload.js.map +1 -1
- package/adapters/react/file-upload.tsx +1 -3
- package/adapters/react/heatmap.d.ts +0 -4
- package/adapters/react/heatmap.d.ts.map +1 -1
- package/adapters/react/heatmap.js +1 -1
- package/adapters/react/heatmap.js.map +1 -1
- package/adapters/react/heatmap.tsx +1 -5
- package/adapters/react/image.d.ts +0 -2
- package/adapters/react/image.d.ts.map +1 -1
- package/adapters/react/image.js +1 -1
- package/adapters/react/image.js.map +1 -1
- package/adapters/react/image.tsx +1 -3
- package/adapters/react/kanban.d.ts +0 -4
- package/adapters/react/kanban.d.ts.map +1 -1
- package/adapters/react/kanban.js +1 -1
- package/adapters/react/kanban.js.map +1 -1
- package/adapters/react/kanban.tsx +1 -5
- package/adapters/react/key-value.d.ts +0 -2
- package/adapters/react/key-value.d.ts.map +1 -1
- package/adapters/react/key-value.js +1 -1
- package/adapters/react/key-value.js.map +1 -1
- package/adapters/react/key-value.tsx +1 -3
- package/adapters/react/leaderboard.d.ts +0 -1
- package/adapters/react/leaderboard.d.ts.map +1 -1
- package/adapters/react/leaderboard.js +1 -1
- package/adapters/react/leaderboard.js.map +1 -1
- package/adapters/react/leaderboard.tsx +1 -2
- package/adapters/react/map.d.ts +0 -3
- package/adapters/react/map.d.ts.map +1 -1
- package/adapters/react/map.js +1 -1
- package/adapters/react/map.js.map +1 -1
- package/adapters/react/map.tsx +1 -4
- package/adapters/react/markdown.d.ts +1 -1
- package/adapters/react/markdown.d.ts.map +1 -1
- package/adapters/react/markdown.js +1 -1
- package/adapters/react/markdown.js.map +1 -1
- package/adapters/react/markdown.tsx +2 -2
- package/adapters/react/matchRoute.d.ts +1 -1
- package/adapters/react/matchRoute.js +38 -4
- package/adapters/react/matchRoute.js.map +1 -1
- package/adapters/react/message-strip.d.ts +1 -1
- package/adapters/react/message-strip.js +1 -1
- package/adapters/react/message-strip.tsx +2 -2
- package/adapters/react/music-player.d.ts +0 -1
- package/adapters/react/music-player.d.ts.map +1 -1
- package/adapters/react/music-player.js +1 -1
- package/adapters/react/music-player.js.map +1 -1
- package/adapters/react/music-player.tsx +1 -2
- package/adapters/react/org-chart.d.ts +0 -1
- package/adapters/react/org-chart.d.ts.map +1 -1
- package/adapters/react/org-chart.js +1 -1
- package/adapters/react/org-chart.js.map +1 -1
- package/adapters/react/org-chart.tsx +1 -2
- package/adapters/react/paint.d.ts +0 -1
- package/adapters/react/paint.d.ts.map +1 -1
- package/adapters/react/paint.js +1 -1
- package/adapters/react/paint.js.map +1 -1
- package/adapters/react/paint.tsx +1 -2
- package/adapters/react/podcast-player.d.ts +0 -2
- package/adapters/react/podcast-player.d.ts.map +1 -1
- package/adapters/react/podcast-player.js +1 -1
- package/adapters/react/podcast-player.js.map +1 -1
- package/adapters/react/podcast-player.tsx +1 -3
- package/adapters/react/product-card.d.ts +0 -3
- package/adapters/react/product-card.d.ts.map +1 -1
- package/adapters/react/product-card.js +1 -1
- package/adapters/react/product-card.js.map +1 -1
- package/adapters/react/product-card.tsx +1 -4
- package/adapters/react/qr-reader.d.ts +0 -4
- package/adapters/react/qr-reader.d.ts.map +1 -1
- package/adapters/react/qr-reader.js +1 -1
- package/adapters/react/qr-reader.js.map +1 -1
- package/adapters/react/qr-reader.tsx +1 -5
- package/adapters/react/recipe.d.ts +0 -5
- package/adapters/react/recipe.d.ts.map +1 -1
- package/adapters/react/recipe.js +1 -1
- package/adapters/react/recipe.js.map +1 -1
- package/adapters/react/recipe.tsx +1 -6
- package/adapters/react/route-specificity.d.ts +1 -0
- package/adapters/react/spotlight.d.ts +0 -2
- package/adapters/react/spotlight.d.ts.map +1 -1
- package/adapters/react/spotlight.js +1 -1
- package/adapters/react/spotlight.js.map +1 -1
- package/adapters/react/spotlight.tsx +1 -3
- package/adapters/react/tag-input.d.ts +0 -4
- package/adapters/react/tag-input.d.ts.map +1 -1
- package/adapters/react/tag-input.js +1 -1
- package/adapters/react/tag-input.js.map +1 -1
- package/adapters/react/tag-input.tsx +1 -5
- package/adapters/react/terminal.d.ts +0 -1
- package/adapters/react/terminal.d.ts.map +1 -1
- package/adapters/react/terminal.js +1 -1
- package/adapters/react/terminal.js.map +1 -1
- package/adapters/react/terminal.tsx +1 -2
- package/adapters/react/time-picker.d.ts +0 -1
- package/adapters/react/time-picker.d.ts.map +1 -1
- package/adapters/react/time-picker.js +1 -1
- package/adapters/react/time-picker.js.map +1 -1
- package/adapters/react/time-picker.tsx +1 -2
- package/adapters/react/timer.d.ts +0 -1
- package/adapters/react/timer.d.ts.map +1 -1
- package/adapters/react/timer.js +1 -1
- package/adapters/react/timer.js.map +1 -1
- package/adapters/react/timer.tsx +1 -2
- package/adapters/react/useRequestHandler.js +1 -1
- package/adapters/react/video-player.d.ts +0 -6
- package/adapters/react/video-player.d.ts.map +1 -1
- package/adapters/react/video-player.js +1 -1
- package/adapters/react/video-player.js.map +1 -1
- package/adapters/react/video-player.tsx +1 -7
- package/adapters/react/virtual-scroller.d.ts +0 -1
- package/adapters/react/virtual-scroller.d.ts.map +1 -1
- package/adapters/react/virtual-scroller.js +1 -1
- package/adapters/react/virtual-scroller.js.map +1 -1
- package/adapters/react/virtual-scroller.tsx +1 -2
- package/bin/templates/default/tests/services/jwt.test.ts +8 -1
- package/bin/templates/react/tests/services/jwt.test.ts +10 -3
- package/dist/cdn/accordion/snice-accordion.js +1 -1
- package/dist/cdn/accordion/snice-accordion.min.js +1 -1
- package/dist/cdn/action-bar/README.md +2 -2
- package/dist/cdn/action-bar/snice-action-bar.js +2 -2
- package/dist/cdn/action-bar/snice-action-bar.js.map +1 -1
- package/dist/cdn/action-bar/snice-action-bar.min.js +2 -2
- package/dist/cdn/action-bar/snice-action-bar.min.js.map +1 -1
- package/dist/cdn/activity-feed/snice-activity-feed.js +1 -1
- package/dist/cdn/activity-feed/snice-activity-feed.min.js +1 -1
- package/dist/cdn/alert/snice-alert.js +1 -1
- package/dist/cdn/alert/snice-alert.js.map +1 -1
- package/dist/cdn/alert/snice-alert.min.js +1 -1
- package/dist/cdn/alert/snice-alert.min.js.map +1 -1
- package/dist/cdn/app-tiles/snice-app-tiles.js +1 -1
- package/dist/cdn/app-tiles/snice-app-tiles.min.js +1 -1
- package/dist/cdn/approval-flow/snice-approval-flow.js +1 -1
- package/dist/cdn/approval-flow/snice-approval-flow.js.map +1 -1
- package/dist/cdn/approval-flow/snice-approval-flow.min.js +1 -1
- package/dist/cdn/approval-flow/snice-approval-flow.min.js.map +1 -1
- package/dist/cdn/audio-recorder/snice-audio-recorder.js +1 -1
- package/dist/cdn/audio-recorder/snice-audio-recorder.min.js +1 -1
- package/dist/cdn/availability/snice-availability.js +1 -1
- package/dist/cdn/availability/snice-availability.min.js +1 -1
- package/dist/cdn/avatar/snice-avatar.js +1 -1
- package/dist/cdn/avatar/snice-avatar.min.js +1 -1
- package/dist/cdn/avatar-group/snice-avatar-group.js +1 -1
- package/dist/cdn/avatar-group/snice-avatar-group.min.js +1 -1
- package/dist/cdn/badge/snice-badge.js +1 -1
- package/dist/cdn/badge/snice-badge.js.map +1 -1
- package/dist/cdn/badge/snice-badge.min.js +1 -1
- package/dist/cdn/badge/snice-badge.min.js.map +1 -1
- package/dist/cdn/banner/README.md +1 -1
- package/dist/cdn/banner/snice-banner.js +2 -2
- package/dist/cdn/banner/snice-banner.js.map +1 -1
- package/dist/cdn/banner/snice-banner.min.js +2 -2
- package/dist/cdn/banner/snice-banner.min.js.map +1 -1
- package/dist/cdn/binpack/snice-binpack.js +1 -1
- package/dist/cdn/binpack/snice-binpack.min.js +1 -1
- package/dist/cdn/book/snice-book.js +1 -1
- package/dist/cdn/book/snice-book.min.js +1 -1
- package/dist/cdn/booking/snice-booking.js +1 -1
- package/dist/cdn/booking/snice-booking.min.js +1 -1
- package/dist/cdn/breadcrumbs/snice-breadcrumbs.js +1 -1
- package/dist/cdn/breadcrumbs/snice-breadcrumbs.js.map +1 -1
- package/dist/cdn/breadcrumbs/snice-breadcrumbs.min.js +1 -1
- package/dist/cdn/breadcrumbs/snice-breadcrumbs.min.js.map +1 -1
- package/dist/cdn/button/snice-button.js +1 -1
- package/dist/cdn/button/snice-button.js.map +1 -1
- package/dist/cdn/button/snice-button.min.js +1 -1
- package/dist/cdn/button/snice-button.min.js.map +1 -1
- package/dist/cdn/calendar/snice-calendar.js +1 -1
- package/dist/cdn/calendar/snice-calendar.min.js +1 -1
- package/dist/cdn/camera/snice-camera.js +1 -1
- package/dist/cdn/camera/snice-camera.min.js +1 -1
- package/dist/cdn/camera-annotate/snice-camera-annotate.js +1 -1
- package/dist/cdn/camera-annotate/snice-camera-annotate.min.js +1 -1
- package/dist/cdn/candlestick/snice-candlestick.js +1 -1
- package/dist/cdn/candlestick/snice-candlestick.min.js +1 -1
- package/dist/cdn/card/snice-card.js +1 -1
- package/dist/cdn/card/snice-card.min.js +1 -1
- package/dist/cdn/carousel/snice-carousel.js +1 -1
- package/dist/cdn/carousel/snice-carousel.min.js +1 -1
- package/dist/cdn/cart/snice-cart.js +1 -1
- package/dist/cdn/cart/snice-cart.min.js +1 -1
- package/dist/cdn/chart/snice-chart.js +1 -1
- package/dist/cdn/chart/snice-chart.js.map +1 -1
- package/dist/cdn/chart/snice-chart.min.js +1 -1
- package/dist/cdn/chart/snice-chart.min.js.map +1 -1
- package/dist/cdn/chat/README.md +2 -2
- package/dist/cdn/chat/snice-chat.js +785 -89
- package/dist/cdn/chat/snice-chat.js.map +1 -1
- package/dist/cdn/chat/snice-chat.min.js +71 -75
- package/dist/cdn/chat/snice-chat.min.js.map +1 -1
- package/dist/cdn/checkbox/snice-checkbox.js +1 -1
- package/dist/cdn/checkbox/snice-checkbox.min.js +1 -1
- package/dist/cdn/chip/snice-chip.js +1 -1
- package/dist/cdn/chip/snice-chip.js.map +1 -1
- package/dist/cdn/chip/snice-chip.min.js +1 -1
- package/dist/cdn/chip/snice-chip.min.js.map +1 -1
- package/dist/cdn/code-block/snice-code-block.js +1 -1
- package/dist/cdn/code-block/snice-code-block.min.js +1 -1
- package/dist/cdn/color-display/snice-color-display.js +1 -1
- package/dist/cdn/color-display/snice-color-display.min.js +1 -1
- package/dist/cdn/color-picker/snice-color-picker.js +1 -1
- package/dist/cdn/color-picker/snice-color-picker.min.js +1 -1
- package/dist/cdn/command-palette/README.md +1 -1
- package/dist/cdn/command-palette/snice-command-palette.js +2 -2
- package/dist/cdn/command-palette/snice-command-palette.js.map +1 -1
- package/dist/cdn/command-palette/snice-command-palette.min.js +2 -2
- package/dist/cdn/command-palette/snice-command-palette.min.js.map +1 -1
- package/dist/cdn/comments/snice-comments.js +1 -1
- package/dist/cdn/comments/snice-comments.min.js +1 -1
- package/dist/cdn/countdown/snice-countdown.js +1 -1
- package/dist/cdn/countdown/snice-countdown.min.js +1 -1
- package/dist/cdn/cropper/snice-cropper.js +1 -1
- package/dist/cdn/cropper/snice-cropper.min.js +1 -1
- package/dist/cdn/data-card/snice-data-card.js +1 -1
- package/dist/cdn/data-card/snice-data-card.js.map +1 -1
- package/dist/cdn/data-card/snice-data-card.min.js +1 -1
- package/dist/cdn/data-card/snice-data-card.min.js.map +1 -1
- package/dist/cdn/date-picker/snice-date-picker.js +1 -1
- package/dist/cdn/date-picker/snice-date-picker.min.js +1 -1
- package/dist/cdn/date-range-picker/snice-date-range-picker.js +1 -1
- package/dist/cdn/date-range-picker/snice-date-range-picker.min.js +1 -1
- package/dist/cdn/date-time-picker/snice-date-time-picker.js +1 -1
- package/dist/cdn/date-time-picker/snice-date-time-picker.min.js +1 -1
- package/dist/cdn/diff/snice-diff.js +1 -1
- package/dist/cdn/diff/snice-diff.min.js +1 -1
- package/dist/cdn/divider/snice-divider.js +1 -1
- package/dist/cdn/divider/snice-divider.min.js +1 -1
- package/dist/cdn/doc/snice-doc.js +1 -1
- package/dist/cdn/doc/snice-doc.min.js +1 -1
- package/dist/cdn/draw/snice-draw.js +1 -1
- package/dist/cdn/draw/snice-draw.min.js +1 -1
- package/dist/cdn/drawer/snice-drawer.js +1 -1
- package/dist/cdn/drawer/snice-drawer.js.map +1 -1
- package/dist/cdn/drawer/snice-drawer.min.js +1 -1
- package/dist/cdn/drawer/snice-drawer.min.js.map +1 -1
- package/dist/cdn/empty-state/snice-empty-state.js +1 -1
- package/dist/cdn/empty-state/snice-empty-state.js.map +1 -1
- package/dist/cdn/empty-state/snice-empty-state.min.js +1 -1
- package/dist/cdn/empty-state/snice-empty-state.min.js.map +1 -1
- package/dist/cdn/estimate/snice-estimate.js +1 -1
- package/dist/cdn/estimate/snice-estimate.min.js +1 -1
- package/dist/cdn/file-gallery/snice-file-gallery.js +1 -1
- package/dist/cdn/file-gallery/snice-file-gallery.min.js +1 -1
- package/dist/cdn/file-upload/snice-file-upload.js +1 -1
- package/dist/cdn/file-upload/snice-file-upload.min.js +1 -1
- package/dist/cdn/flip-card/snice-flip-card.js +1 -1
- package/dist/cdn/flip-card/snice-flip-card.min.js +1 -1
- package/dist/cdn/flow/snice-flow.js +1 -1
- package/dist/cdn/flow/snice-flow.min.js +1 -1
- package/dist/cdn/form-layout/snice-form-layout.js +1 -1
- package/dist/cdn/form-layout/snice-form-layout.min.js +1 -1
- package/dist/cdn/funnel/snice-funnel.js +1 -1
- package/dist/cdn/funnel/snice-funnel.js.map +1 -1
- package/dist/cdn/funnel/snice-funnel.min.js +1 -1
- package/dist/cdn/funnel/snice-funnel.min.js.map +1 -1
- package/dist/cdn/gantt/snice-gantt.js +1 -1
- package/dist/cdn/gantt/snice-gantt.min.js +1 -1
- package/dist/cdn/gauge/snice-gauge.js +1 -1
- package/dist/cdn/gauge/snice-gauge.min.js +1 -1
- package/dist/cdn/grid/snice-grid.js +1 -1
- package/dist/cdn/grid/snice-grid.min.js +1 -1
- package/dist/cdn/heatmap/snice-heatmap.js +1 -1
- package/dist/cdn/heatmap/snice-heatmap.min.js +1 -1
- package/dist/cdn/image/snice-image.js +1 -1
- package/dist/cdn/image/snice-image.js.map +1 -1
- package/dist/cdn/image/snice-image.min.js +1 -1
- package/dist/cdn/image/snice-image.min.js.map +1 -1
- package/dist/cdn/input/snice-input.js +1 -1
- package/dist/cdn/input/snice-input.js.map +1 -1
- package/dist/cdn/input/snice-input.min.js +1 -1
- package/dist/cdn/input/snice-input.min.js.map +1 -1
- package/dist/cdn/invoice/README.md +1 -1
- package/dist/cdn/invoice/snice-invoice.js +2 -2
- package/dist/cdn/invoice/snice-invoice.js.map +1 -1
- package/dist/cdn/invoice/snice-invoice.min.js +2 -2
- package/dist/cdn/invoice/snice-invoice.min.js.map +1 -1
- package/dist/cdn/kanban/snice-kanban.js +1 -1
- package/dist/cdn/kanban/snice-kanban.min.js +1 -1
- package/dist/cdn/key-value/snice-key-value.js +1 -1
- package/dist/cdn/key-value/snice-key-value.min.js +1 -1
- package/dist/cdn/kpi/snice-kpi.js +1 -1
- package/dist/cdn/kpi/snice-kpi.js.map +1 -1
- package/dist/cdn/kpi/snice-kpi.min.js +1 -1
- package/dist/cdn/kpi/snice-kpi.min.js.map +1 -1
- package/dist/cdn/layout/snice-layout.js +1 -1
- package/dist/cdn/layout/snice-layout.min.js +1 -1
- package/dist/cdn/leaderboard/snice-leaderboard.js +1 -1
- package/dist/cdn/leaderboard/snice-leaderboard.min.js +1 -1
- package/dist/cdn/link/snice-link.js +1 -1
- package/dist/cdn/link/snice-link.min.js +1 -1
- package/dist/cdn/link-preview/snice-link-preview.js +1 -1
- package/dist/cdn/link-preview/snice-link-preview.min.js +1 -1
- package/dist/cdn/list/snice-list.js +1 -1
- package/dist/cdn/list/snice-list.js.map +1 -1
- package/dist/cdn/list/snice-list.min.js +1 -1
- package/dist/cdn/list/snice-list.min.js.map +1 -1
- package/dist/cdn/location/snice-location.js +1 -1
- package/dist/cdn/location/snice-location.js.map +1 -1
- package/dist/cdn/location/snice-location.min.js +1 -1
- package/dist/cdn/location/snice-location.min.js.map +1 -1
- package/dist/cdn/login/snice-login.js +3 -1
- package/dist/cdn/login/snice-login.js.map +1 -1
- package/dist/cdn/login/snice-login.min.js +1 -1
- package/dist/cdn/login/snice-login.min.js.map +1 -1
- package/dist/cdn/map/snice-map.js +1 -1
- package/dist/cdn/map/snice-map.min.js +1 -1
- package/dist/cdn/markdown/README.md +2 -2
- package/dist/cdn/markdown/snice-markdown.js +16 -3
- package/dist/cdn/markdown/snice-markdown.js.map +1 -1
- package/dist/cdn/markdown/snice-markdown.min.js +3 -3
- package/dist/cdn/markdown/snice-markdown.min.js.map +1 -1
- package/dist/cdn/masonry/snice-masonry.js +1 -1
- package/dist/cdn/masonry/snice-masonry.min.js +1 -1
- package/dist/cdn/menu/snice-menu.js +2 -2
- package/dist/cdn/menu/snice-menu.js.map +1 -1
- package/dist/cdn/menu/snice-menu.min.js +2 -2
- package/dist/cdn/menu/snice-menu.min.js.map +1 -1
- package/dist/cdn/message-strip/snice-message-strip.js +9 -9
- package/dist/cdn/message-strip/snice-message-strip.js.map +1 -1
- package/dist/cdn/message-strip/snice-message-strip.min.js +3 -3
- package/dist/cdn/message-strip/snice-message-strip.min.js.map +1 -1
- package/dist/cdn/metric-table/snice-metric-table.js +1 -1
- package/dist/cdn/metric-table/snice-metric-table.min.js +1 -1
- package/dist/cdn/modal/snice-modal.js +1 -1
- package/dist/cdn/modal/snice-modal.js.map +1 -1
- package/dist/cdn/modal/snice-modal.min.js +1 -1
- package/dist/cdn/modal/snice-modal.min.js.map +1 -1
- package/dist/cdn/music-player/snice-music-player.js +1 -1
- package/dist/cdn/music-player/snice-music-player.min.js +1 -1
- package/dist/cdn/nav/snice-nav.js +1 -1
- package/dist/cdn/nav/snice-nav.min.js +1 -1
- package/dist/cdn/network-graph/snice-network-graph.js +1 -1
- package/dist/cdn/network-graph/snice-network-graph.js.map +1 -1
- package/dist/cdn/network-graph/snice-network-graph.min.js +1 -1
- package/dist/cdn/network-graph/snice-network-graph.min.js.map +1 -1
- package/dist/cdn/notification-center/snice-notification-center.js +1 -1
- package/dist/cdn/notification-center/snice-notification-center.js.map +1 -1
- package/dist/cdn/notification-center/snice-notification-center.min.js +1 -1
- package/dist/cdn/notification-center/snice-notification-center.min.js.map +1 -1
- package/dist/cdn/order-tracker/snice-order-tracker.js +1 -1
- package/dist/cdn/order-tracker/snice-order-tracker.min.js +1 -1
- package/dist/cdn/org-chart/snice-org-chart.js +1 -1
- package/dist/cdn/org-chart/snice-org-chart.min.js +1 -1
- package/dist/cdn/pagination/snice-pagination.js +1 -1
- package/dist/cdn/pagination/snice-pagination.min.js +1 -1
- package/dist/cdn/paint/snice-paint.js +1 -1
- package/dist/cdn/paint/snice-paint.min.js +1 -1
- package/dist/cdn/pdf-viewer/snice-pdf-viewer.js +1 -1
- package/dist/cdn/pdf-viewer/snice-pdf-viewer.min.js +1 -1
- package/dist/cdn/permission-matrix/snice-permission-matrix.js +1 -1
- package/dist/cdn/permission-matrix/snice-permission-matrix.min.js +1 -1
- package/dist/cdn/podcast-player/snice-podcast-player.js +1 -1
- package/dist/cdn/podcast-player/snice-podcast-player.min.js +1 -1
- package/dist/cdn/popover/snice-popover.js +1 -1
- package/dist/cdn/popover/snice-popover.min.js +1 -1
- package/dist/cdn/pricing-table/snice-pricing-table.js +1 -1
- package/dist/cdn/pricing-table/snice-pricing-table.min.js +1 -1
- package/dist/cdn/product-card/snice-product-card.js +3 -3
- package/dist/cdn/product-card/snice-product-card.js.map +1 -1
- package/dist/cdn/product-card/snice-product-card.min.js +3 -3
- package/dist/cdn/product-card/snice-product-card.min.js.map +1 -1
- package/dist/cdn/progress/README.md +1 -1
- package/dist/cdn/progress/snice-progress.js +2 -2
- package/dist/cdn/progress/snice-progress.js.map +1 -1
- package/dist/cdn/progress/snice-progress.min.js +2 -2
- package/dist/cdn/progress/snice-progress.min.js.map +1 -1
- package/dist/cdn/progress-ring/snice-progress-ring.js +2 -2
- package/dist/cdn/progress-ring/snice-progress-ring.js.map +1 -1
- package/dist/cdn/progress-ring/snice-progress-ring.min.js +2 -2
- package/dist/cdn/progress-ring/snice-progress-ring.min.js.map +1 -1
- package/dist/cdn/qr-code/snice-qr-code.js +1 -1
- package/dist/cdn/qr-code/snice-qr-code.min.js +1 -1
- package/dist/cdn/qr-reader/snice-qr-reader.js +1 -1
- package/dist/cdn/qr-reader/snice-qr-reader.min.js +1 -1
- package/dist/cdn/radio/snice-radio.js +1 -1
- package/dist/cdn/radio/snice-radio.min.js +1 -1
- package/dist/cdn/range-slider/snice-range-slider.js +1 -1
- package/dist/cdn/range-slider/snice-range-slider.min.js +1 -1
- package/dist/cdn/rating/snice-rating.js +1 -1
- package/dist/cdn/rating/snice-rating.min.js +1 -1
- package/dist/cdn/receipt/snice-receipt.js +1 -1
- package/dist/cdn/receipt/snice-receipt.min.js +1 -1
- package/dist/cdn/recipe/snice-recipe.js +1 -1
- package/dist/cdn/recipe/snice-recipe.min.js +1 -1
- package/dist/cdn/runtime/README.md +2 -2
- package/dist/cdn/runtime/snice-runtime.esm.js +644 -172
- package/dist/cdn/runtime/snice-runtime.esm.js.map +1 -1
- package/dist/cdn/runtime/snice-runtime.esm.min.js +8 -8
- package/dist/cdn/runtime/snice-runtime.esm.min.js.map +1 -1
- package/dist/cdn/runtime/snice-runtime.js +644 -172
- package/dist/cdn/runtime/snice-runtime.js.map +1 -1
- package/dist/cdn/runtime/snice-runtime.min.js +8 -8
- package/dist/cdn/runtime/snice-runtime.min.js.map +1 -1
- package/dist/cdn/sankey/snice-sankey.js +1 -1
- package/dist/cdn/sankey/snice-sankey.js.map +1 -1
- package/dist/cdn/sankey/snice-sankey.min.js +1 -1
- package/dist/cdn/sankey/snice-sankey.min.js.map +1 -1
- package/dist/cdn/segmented-control/snice-segmented-control.js +1 -1
- package/dist/cdn/segmented-control/snice-segmented-control.min.js +1 -1
- package/dist/cdn/select/snice-select.js +1 -1
- package/dist/cdn/select/snice-select.min.js +1 -1
- package/dist/cdn/skeleton/snice-skeleton.js +1 -1
- package/dist/cdn/skeleton/snice-skeleton.min.js +1 -1
- package/dist/cdn/slider/snice-slider.js +1 -1
- package/dist/cdn/slider/snice-slider.min.js +1 -1
- package/dist/cdn/sortable/snice-sortable.js +1 -1
- package/dist/cdn/sortable/snice-sortable.min.js +1 -1
- package/dist/cdn/sparkline/snice-sparkline.js +1 -1
- package/dist/cdn/sparkline/snice-sparkline.min.js +1 -1
- package/dist/cdn/spinner/snice-spinner.js +1 -1
- package/dist/cdn/spinner/snice-spinner.min.js +1 -1
- package/dist/cdn/split-button/snice-split-button.js +1 -1
- package/dist/cdn/split-button/snice-split-button.js.map +1 -1
- package/dist/cdn/split-button/snice-split-button.min.js +1 -1
- package/dist/cdn/split-button/snice-split-button.min.js.map +1 -1
- package/dist/cdn/split-pane/snice-split-pane.js +1 -1
- package/dist/cdn/split-pane/snice-split-pane.min.js +1 -1
- package/dist/cdn/spotlight/snice-spotlight.js +1 -1
- package/dist/cdn/spotlight/snice-spotlight.min.js +1 -1
- package/dist/cdn/stat-group/snice-stat-group.js +1 -1
- package/dist/cdn/stat-group/snice-stat-group.min.js +1 -1
- package/dist/cdn/step-input/snice-step-input.js +1 -1
- package/dist/cdn/step-input/snice-step-input.min.js +1 -1
- package/dist/cdn/stepper/snice-stepper.js +1 -1
- package/dist/cdn/stepper/snice-stepper.min.js +1 -1
- package/dist/cdn/switch/snice-switch.js +1 -1
- package/dist/cdn/switch/snice-switch.min.js +1 -1
- package/dist/cdn/table/README.md +1 -1
- package/dist/cdn/table/snice-table.js +14 -4
- package/dist/cdn/table/snice-table.js.map +1 -1
- package/dist/cdn/table/snice-table.min.js +14 -4
- package/dist/cdn/table/snice-table.min.js.map +1 -1
- package/dist/cdn/tabs/snice-tabs.js +1 -1
- package/dist/cdn/tabs/snice-tabs.min.js +1 -1
- package/dist/cdn/tag/snice-tag.js +1 -1
- package/dist/cdn/tag/snice-tag.min.js +1 -1
- package/dist/cdn/tag-input/snice-tag-input.js +2 -2
- package/dist/cdn/tag-input/snice-tag-input.js.map +1 -1
- package/dist/cdn/tag-input/snice-tag-input.min.js +2 -2
- package/dist/cdn/tag-input/snice-tag-input.min.js.map +1 -1
- package/dist/cdn/terminal/snice-terminal.js +1 -1
- package/dist/cdn/terminal/snice-terminal.min.js +1 -1
- package/dist/cdn/testimonial/snice-testimonial.js +1 -1
- package/dist/cdn/testimonial/snice-testimonial.min.js +1 -1
- package/dist/cdn/textarea/snice-textarea.js +1 -1
- package/dist/cdn/textarea/snice-textarea.min.js +1 -1
- package/dist/cdn/time-picker/README.md +1 -1
- package/dist/cdn/time-picker/snice-time-picker.js +18 -13
- package/dist/cdn/time-picker/snice-time-picker.js.map +1 -1
- package/dist/cdn/time-picker/snice-time-picker.min.js +3 -3
- package/dist/cdn/time-picker/snice-time-picker.min.js.map +1 -1
- package/dist/cdn/time-range-picker/snice-time-range-picker.js +1 -1
- package/dist/cdn/time-range-picker/snice-time-range-picker.min.js +1 -1
- package/dist/cdn/timeline/snice-timeline.js +1 -1
- package/dist/cdn/timeline/snice-timeline.js.map +1 -1
- package/dist/cdn/timeline/snice-timeline.min.js +1 -1
- package/dist/cdn/timeline/snice-timeline.min.js.map +1 -1
- package/dist/cdn/timer/snice-timer.js +1 -1
- package/dist/cdn/timer/snice-timer.min.js +1 -1
- package/dist/cdn/toast/snice-toast.js +1 -1
- package/dist/cdn/toast/snice-toast.js.map +1 -1
- package/dist/cdn/toast/snice-toast.min.js +1 -1
- package/dist/cdn/toast/snice-toast.min.js.map +1 -1
- package/dist/cdn/tooltip/snice-tooltip.js +1 -1
- package/dist/cdn/tooltip/snice-tooltip.min.js +1 -1
- package/dist/cdn/tree/snice-tree.js +1 -1
- package/dist/cdn/tree/snice-tree.min.js +1 -1
- package/dist/cdn/treemap/snice-treemap.js +1 -1
- package/dist/cdn/treemap/snice-treemap.js.map +1 -1
- package/dist/cdn/treemap/snice-treemap.min.js +1 -1
- package/dist/cdn/treemap/snice-treemap.min.js.map +1 -1
- package/dist/cdn/user-card/snice-user-card.js +1 -1
- package/dist/cdn/user-card/snice-user-card.min.js +1 -1
- package/dist/cdn/video-player/snice-video-player.js +1 -1
- package/dist/cdn/video-player/snice-video-player.min.js +1 -1
- package/dist/cdn/virtual-scroller/snice-virtual-scroller.js +1 -1
- package/dist/cdn/virtual-scroller/snice-virtual-scroller.min.js +1 -1
- package/dist/cdn/waterfall/snice-waterfall.js +1 -1
- package/dist/cdn/waterfall/snice-waterfall.min.js +1 -1
- package/dist/cdn/weather/snice-weather.js +1 -1
- package/dist/cdn/weather/snice-weather.min.js +1 -1
- package/dist/cdn/work-order/snice-work-order.js +1 -1
- package/dist/cdn/work-order/snice-work-order.min.js +1 -1
- package/dist/components/action-bar/snice-action-bar.js +1 -1
- package/dist/components/action-bar/snice-action-bar.js.map +1 -1
- package/dist/components/banner/snice-banner.js +1 -1
- package/dist/components/banner/snice-banner.js.map +1 -1
- package/dist/components/chat/snice-chat-message.d.ts +32 -0
- package/dist/components/chat/snice-chat-message.js +127 -0
- package/dist/components/chat/snice-chat-message.js.map +1 -0
- package/dist/components/chat/snice-chat-message.types.d.ts +30 -0
- package/dist/components/chat/snice-chat.d.ts +31 -4
- package/dist/components/chat/snice-chat.js +363 -90
- package/dist/components/chat/snice-chat.js.map +1 -1
- package/dist/components/chat/snice-chat.types.d.ts +34 -3
- package/dist/components/command-palette/snice-command-palette.js +1 -1
- package/dist/components/command-palette/snice-command-palette.js.map +1 -1
- package/dist/components/icons/index.d.ts +4 -0
- package/dist/components/icons/index.js +5 -1
- package/dist/components/icons/index.js.map +1 -1
- package/dist/components/invoice/snice-invoice.js +1 -1
- package/dist/components/invoice/snice-invoice.js.map +1 -1
- package/dist/components/login/snice-login.d.ts +2 -2
- package/dist/components/login/snice-login.js +2 -0
- package/dist/components/login/snice-login.js.map +1 -1
- package/dist/components/login/snice-login.types.d.ts +4 -0
- package/dist/components/markdown/snice-markdown.d.ts +1 -0
- package/dist/components/markdown/snice-markdown.js +15 -2
- package/dist/components/markdown/snice-markdown.js.map +1 -1
- package/dist/components/menu/snice-menu.js +1 -1
- package/dist/components/menu/snice-menu.js.map +1 -1
- package/dist/components/message-strip/snice-message-strip.d.ts +1 -1
- package/dist/components/message-strip/snice-message-strip.js +8 -8
- package/dist/components/message-strip/snice-message-strip.types.d.ts +1 -1
- package/dist/components/product-card/snice-product-card.js +2 -2
- package/dist/components/product-card/snice-product-card.js.map +1 -1
- package/dist/components/progress/snice-progress.js +1 -1
- package/dist/components/progress/snice-progress.js.map +1 -1
- package/dist/components/progress-ring/snice-progress-ring.js +1 -1
- package/dist/components/progress-ring/snice-progress-ring.js.map +1 -1
- package/dist/components/table/snice-table.js +13 -3
- package/dist/components/table/snice-table.js.map +1 -1
- package/dist/components/tag-input/snice-tag-input.js +1 -1
- package/dist/components/tag-input/snice-tag-input.js.map +1 -1
- package/dist/components/time-picker/snice-time-picker.js +17 -12
- package/dist/components/time-picker/snice-time-picker.js.map +1 -1
- package/dist/components/utils.d.ts +6 -0
- package/dist/components/utils.js +1 -1
- package/dist/components/utils.js.map +1 -1
- package/dist/element.d.ts +2 -1
- package/dist/events.d.ts +6 -0
- package/dist/index.cjs +641 -169
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +641 -169
- package/dist/index.esm.js.map +1 -1
- package/dist/index.iife.js +641 -169
- package/dist/index.iife.js.map +1 -1
- package/dist/parts.d.ts +1 -8
- package/dist/react/SniceProvider.js +1 -1
- package/dist/react/SniceRouter.js +1 -1
- package/dist/react/index.js +1 -1
- package/dist/react/matchRoute.d.ts +1 -1
- package/dist/react/matchRoute.js +38 -4
- package/dist/react/matchRoute.js.map +1 -1
- package/dist/react/route-specificity.d.ts +1 -0
- package/dist/react/useRequestHandler.js +1 -1
- package/dist/render.d.ts +7 -0
- package/dist/route-specificity.d.ts +1 -0
- package/dist/symbols.cjs +14 -1
- package/dist/symbols.cjs.map +1 -1
- package/dist/symbols.d.ts +3 -0
- package/dist/symbols.esm.js +12 -2
- package/dist/symbols.esm.js.map +1 -1
- package/dist/transitions.cjs +1 -1
- package/dist/transitions.esm.js +1 -1
- package/dist/types/context.d.ts +5 -2
- package/dist/types/dispatch-options.d.ts +7 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/on-options.d.ts +14 -0
- package/dist/types/watch-options.d.ts +9 -0
- package/dist/utils.d.ts +26 -0
- package/docs/ai/DEVELOPMENT.md +1 -1
- package/docs/ai/README.md +11 -0
- package/docs/ai/api.md +24 -5
- package/docs/ai/cdn.md +31 -0
- package/docs/ai/components/chat.md +57 -1
- package/docs/ai/components/message-strip.md +3 -3
- package/docs/ai/decorators.md +44 -5
- package/docs/cdn.md +56 -0
- package/docs/components/chat.md +108 -2
- package/docs/components/message-strip.md +8 -8
- package/docs/elements.md +21 -0
- package/docs/events.md +88 -0
- package/docs/superpowers/specs/2026-05-26-chat-styling-design.md +155 -0
- package/docs/superpowers/specs/2026-05-27-chat-theming-REMAINING.md +83 -0
- package/docs/superpowers/specs/2026-06-09-chat-custom-content-design.md +233 -0
- package/package.json +1 -1
|
@@ -1,9 +1,32 @@
|
|
|
1
1
|
import { __runInitializers, __esDecorate } from 'tslib';
|
|
2
|
-
import { element, property, query, styles, ready, dispose, watch, dispatch, render, css, html } from 'snice';
|
|
2
|
+
import { element, property, query, styles, ready, observe, dispose, watch, dispatch, render, css, html, unsafeHTML } from 'snice';
|
|
3
|
+
import { PENCIL, TRASH, PAPER_CLIP, PAPER_AIRPLANE_SOLID } from '../icons/index.js';
|
|
4
|
+
import { FALLBACK_ACCENTS } from '../utils.js';
|
|
3
5
|
import '../empty-state/snice-empty-state.js';
|
|
4
|
-
import '../
|
|
6
|
+
import '../markdown/snice-markdown.js';
|
|
7
|
+
import './snice-chat-message.js';
|
|
5
8
|
|
|
6
|
-
|
|
9
|
+
/**
|
|
10
|
+
* Types for the snice-chat component
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* How a message body is rendered
|
|
14
|
+
*/
|
|
15
|
+
var MessageFormat;
|
|
16
|
+
(function (MessageFormat) {
|
|
17
|
+
MessageFormat["Text"] = "text";
|
|
18
|
+
MessageFormat["Markdown"] = "markdown";
|
|
19
|
+
})(MessageFormat || (MessageFormat = {}));
|
|
20
|
+
/**
|
|
21
|
+
* Built-in message layout for snice-chat
|
|
22
|
+
*/
|
|
23
|
+
var ChatLayout;
|
|
24
|
+
(function (ChatLayout) {
|
|
25
|
+
ChatLayout["Default"] = "default";
|
|
26
|
+
ChatLayout["Bubbles"] = "bubbles";
|
|
27
|
+
})(ChatLayout || (ChatLayout = {}));
|
|
28
|
+
|
|
29
|
+
var cssContent = ":host{display:flex;flex-direction:column;height:var(--snice-chat-height,37.5rem);font-family:var(--snice-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif);font-size:var(--snice-font-size-md, 1rem);line-height:1.5;color:var(--snice-color-text,rgb(23 23 23));background:var(--snice-color-surface-container-high,rgb(252 251 249));border:1px solid var(--snice-color-border,rgb(226 226 226));border-radius:var(--snice-border-radius-md,.25rem);overflow:hidden;box-shadow:var(--snice-shadow-md,0 4px 6px -1px rgb(0 0 0 / .1),0 2px 4px -2px rgb(0 0 0 / .1))}.chat-container{display:flex;flex-direction:column;height:100%}.messages-area{flex:1;overflow-y:auto;padding:var(--snice-spacing-md,1rem);display:flex;flex-direction:column;gap:var(--snice-spacing-sm,.75rem)}.messages-area::-webkit-scrollbar{width:8px}.messages-area::-webkit-scrollbar-track{background:0 0}.messages-area::-webkit-scrollbar-thumb{background:var(--snice-color-border,rgb(226 226 226));border-radius:var(--snice-border-radius-md,.25rem)}.messages-area::-webkit-scrollbar-thumb:hover{background:var(--snice-color-text-secondary,rgb(82 82 82))}.message{display:flex;gap:var(--snice-spacing-sm,.75rem);padding:var(--snice-spacing-2xs,.25rem) 0;position:relative}.message:hover .message-actions{opacity:1}.message-avatar{width:2.25rem;height:2.25rem;border-radius:var(--snice-border-radius-md,.25rem);background:var(--snice-color-surface-container-low,rgb(250 250 250));display:flex;align-items:center;justify-content:center;color:var(--snice-color-text-secondary,rgb(82 82 82));font-weight:var(--snice-font-weight-semibold,600);font-size:var(--snice-font-size-sm, .875rem);flex-shrink:0}.message-avatar img{width:100%;height:100%;border-radius:var(--snice-border-radius-md,.25rem);object-fit:cover}.message-content{flex:1;min-width:0}.message-header{font-family:var(--snice-font-family-display);display:flex;align-items:baseline;gap:var(--snice-spacing-xs,.5rem);margin-bottom:var(--snice-spacing-3xs,.125rem)}.message-author{font-weight:var(--snice-font-weight-bold,700);color:var(--snice-chat-author-color,var(--snice-color-text,rgb(23 23 23)))}.message-timestamp{font-size:var(--snice-font-size-xs, .75rem);color:var(--snice-color-text-secondary,rgb(82 82 82))}.message-edited{font-size:var(--snice-font-size-xs, .75rem);color:var(--snice-color-text-secondary,rgb(82 82 82));font-style:italic}.message-text{word-wrap:break-word;white-space:pre-wrap;color:var(--snice-color-text,rgb(23 23 23))}snice-markdown.message-text{white-space:normal;display:block}.message.system{justify-content:center}.message.system .message-text{text-align:center;color:var(--snice-color-text-secondary,rgb(82 82 82));font-size:var(--snice-font-size-sm, .875rem);font-style:italic}.message-attachment{margin-top:var(--snice-spacing-xs,.5rem);border:1px solid var(--snice-color-border,rgb(226 226 226));border-radius:var(--snice-border-radius-md,.25rem);overflow:hidden;max-width:25rem}.message-attachment img{max-width:100%;display:block}.attachment-file{display:flex;align-items:center;gap:var(--snice-spacing-sm,.75rem);padding:var(--snice-spacing-sm,.75rem);background:var(--snice-color-surface-container-low,rgb(250 250 250))}.attachment-icon{width:2rem;height:2rem;display:flex;align-items:center;justify-content:center;background:var(--snice-color-surface,rgb(255 255 255));border-radius:var(--snice-border-radius-md,.25rem);color:var(--snice-color-text-secondary,rgb(82 82 82))}.attachment-info{flex:1;min-width:0}.attachment-name{font-weight:var(--snice-font-weight-medium,500);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.attachment-size{font-size:var(--snice-font-size-xs, .75rem);color:var(--snice-color-text-secondary,rgb(82 82 82))}.message-reactions{display:flex;gap:var(--snice-spacing-2xs,.25rem);margin-top:var(--snice-spacing-2xs,.25rem);flex-wrap:wrap}.reaction{display:flex;align-items:center;gap:var(--snice-spacing-2xs,.25rem);padding:var(--snice-spacing-3xs,.125rem) var(--snice-spacing-xs,.5rem);background:var(--snice-color-surface-container-low,rgb(250 250 250));border:1px solid var(--snice-color-border,rgb(226 226 226));border-radius:12px;font-size:var(--snice-font-size-sm, .875rem);cursor:pointer;transition:all var(--snice-transition-fast, 150ms)}.reaction:hover{background:var(--snice-color-surface-hover,rgb(242 242 242))}.reaction.active{background:var(--snice-color-primary,rgb(37 99 235));color:var(--snice-color-text-inverse,rgb(250 250 250));border-color:var(--snice-color-primary,rgb(37 99 235))}.reaction-emoji{font-size:var(--snice-font-size-sm, .875rem)}.reaction-count{font-size:var(--snice-font-size-xs, .75rem);font-weight:var(--snice-font-weight-medium,500)}.message-actions{position:absolute;top:-.75rem;right:var(--snice-spacing-md,1rem);background:var(--snice-color-surface-container-high,rgb(252 251 249));border:1px solid var(--snice-color-border,rgb(226 226 226));border-radius:var(--snice-border-radius-md,.25rem);box-shadow:var(--snice-shadow-md,0 4px 6px -1px rgb(0 0 0 / .1),0 2px 4px -2px rgb(0 0 0 / .1));display:flex;gap:var(--snice-spacing-3xs,.125rem);opacity:0;transition:opacity var(--snice-transition-fast, 150ms);padding:var(--snice-spacing-3xs,.125rem)}.action-button{width:1.75rem;height:1.75rem;border:none;background:0 0;cursor:pointer;border-radius:var(--snice-border-radius-md,.25rem);display:flex;align-items:center;justify-content:center;color:var(--snice-color-text-secondary,rgb(82 82 82));transition:background var(--snice-transition-fast, 150ms)}.action-button:hover{background:var(--snice-color-surface-hover,rgb(242 242 242))}.action-button svg{width:1rem;height:1rem}.action-emoji{font-size:var(--snice-font-size-sm, .875rem);line-height:1}.message-edit{display:flex;flex-direction:column;gap:var(--snice-spacing-xs,.5rem);margin-top:var(--snice-spacing-3xs,.125rem)}.edit-field{width:100%;box-sizing:border-box;resize:vertical;min-height:2.5rem;font-family:inherit;font-size:var(--snice-font-size-md, 1rem);line-height:1.5;color:var(--snice-color-text,rgb(23 23 23));background:var(--snice-color-surface-container-lowest,rgb(255 255 255));border:1px solid var(--snice-color-border,rgb(226 226 226));border-radius:var(--snice-border-radius-md,.25rem);padding:var(--snice-spacing-xs,.5rem)}.edit-field:focus{outline:0;border-color:var(--snice-color-primary,rgb(37 99 235))}.confirm-actions,.edit-actions{display:flex;gap:var(--snice-spacing-xs,.5rem)}.confirm-button,.edit-button{cursor:pointer;font-family:inherit;font-size:var(--snice-font-size-sm, .875rem);font-weight:var(--snice-font-weight-medium,500);padding:var(--snice-spacing-3xs,.125rem) var(--snice-spacing-sm,.75rem);border:1px solid var(--snice-color-border,rgb(226 226 226));border-radius:var(--snice-border-radius-md,.25rem);background:var(--snice-color-surface,rgb(255 255 255));color:var(--snice-color-text,rgb(23 23 23));transition:background var(--snice-transition-fast, 150ms)}.confirm-button:hover,.edit-button:hover{background:var(--snice-color-surface-hover,rgb(242 242 242))}.edit-save{background:var(--snice-color-primary,rgb(37 99 235));color:var(--snice-color-text-inverse,rgb(250 250 250));border-color:var(--snice-color-primary,rgb(37 99 235))}.edit-save:hover{background:var(--snice-color-primary-hover,rgb(29 78 216))}.message-confirm{display:flex;align-items:center;flex-wrap:wrap;gap:var(--snice-spacing-sm,.75rem);margin-top:var(--snice-spacing-xs,.5rem);padding:var(--snice-spacing-xs,.5rem) var(--snice-spacing-sm,.75rem);background:var(--snice-color-surface-container-low,rgb(250 250 250));border:1px solid var(--snice-color-border,rgb(226 226 226));border-radius:var(--snice-border-radius-md,.25rem)}.confirm-text{font-size:var(--snice-font-size-sm, .875rem);color:var(--snice-color-text-secondary,rgb(82 82 82))}.confirm-delete{background:var(--snice-color-danger,rgb(220 38 38));color:var(--snice-color-text-inverse,rgb(250 250 250));border-color:var(--snice-color-danger,rgb(220 38 38))}.confirm-delete:hover{background:var(--snice-color-danger,rgb(220 38 38));filter:brightness(.92)}.typing-indicators{padding:0 var(--snice-spacing-md,1rem) var(--snice-spacing-xs,.5rem);min-height:1.5rem}.typing-indicator{display:flex;align-items:center;gap:var(--snice-spacing-xs,.5rem);font-size:var(--snice-font-size-sm, .875rem);color:var(--snice-color-text-secondary,rgb(82 82 82));font-style:italic}.typing-dots{display:flex;gap:.1875rem}.typing-dot{width:6px;height:6px;background:var(--snice-color-text-secondary,rgb(82 82 82));border-radius:50%;animation:1.4s ease-in-out infinite typing-bounce}.typing-dot:first-child{animation-delay:0s}.typing-dot:nth-child(2){animation-delay:.2s}.typing-dot:nth-child(3){animation-delay:.4s}@keyframes typing-bounce{0%,100%,60%{transform:translateY(0)}30%{transform:translateY(-4px)}}.input-area{border-top:1px solid var(--snice-color-border,rgb(226 226 226));padding:var(--snice-spacing-md,1rem);background:var(--snice-color-surface-container-high,rgb(252 251 249))}.input-container{display:flex;align-items:flex-end;gap:var(--snice-spacing-xs,.5rem);background:var(--snice-color-surface-container-lowest,rgb(255 255 255));border:1px solid var(--snice-color-border,rgb(226 226 226));border-radius:var(--snice-border-radius-md,.25rem);padding:var(--snice-spacing-xs,.5rem);transition:border-color var(--snice-transition-fast, 150ms)}.input-container:focus-within{border-color:var(--snice-color-primary,rgb(37 99 235))}.input-field{flex:1;border:none;outline:0;resize:none;font-family:inherit;font-size:var(--snice-font-size-md, 1rem);line-height:1.5;min-height:1.375rem;max-height:9.375rem;overflow-y:auto;background:0 0;color:var(--snice-color-text,rgb(23 23 23))}.input-field::placeholder{color:var(--snice-color-text-secondary,rgb(82 82 82))}.input-field::-webkit-scrollbar{width:4px}.input-field::-webkit-scrollbar-thumb{background:var(--snice-color-border,rgb(226 226 226));border-radius:var(--snice-border-radius-sm,.125rem)}.input-buttons{display:flex;gap:var(--snice-spacing-2xs,.25rem)}.input-button{width:2rem;height:2rem;border:none;background:0 0;cursor:pointer;border-radius:var(--snice-border-radius-md,.25rem);display:flex;align-items:center;justify-content:center;color:var(--snice-color-text-secondary,rgb(82 82 82));transition:background var(--snice-transition-fast, 150ms)}.input-button:hover{background:var(--snice-color-surface-hover,rgb(242 242 242))}.input-button:disabled{opacity:.5;cursor:not-allowed}.input-button.send{color:var(--snice-color-text-inverse,rgb(250 250 250));background:var(--snice-color-primary,rgb(37 99 235))}.input-button.send:hover:not(:disabled){background:var(--snice-color-primary-hover,rgb(29 78 216))}.input-button svg{width:1.125rem;height:1.125rem}input[type=file]{display:none}:host([layout=bubbles]) .message.own{flex-direction:row-reverse}:host([layout=bubbles]) .message.own .message-content{display:flex;flex-direction:column;align-items:flex-end}:host([layout=bubbles]) .message.own .message-header{flex-direction:row-reverse}:host([layout=bubbles]) .message .message-text{display:inline-block;padding:var(--snice-spacing-xs,.5rem) var(--snice-spacing-sm,.75rem);border-radius:var(--snice-border-radius-lg,.5rem);background:var(--snice-color-surface-container,rgb(242 242 242))}:host([layout=bubbles]) .message.own .message-text{background:var(--snice-color-primary,rgb(37 99 235));color:var(--snice-color-text-inverse,rgb(250 250 250))}";
|
|
7
30
|
|
|
8
31
|
/**
|
|
9
32
|
* Generate unique ID
|
|
@@ -41,6 +64,26 @@ function getInitials(name) {
|
|
|
41
64
|
.toUpperCase()
|
|
42
65
|
.substring(0, 2);
|
|
43
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Stable color for an author name: hash → one of the 8 accent slots. Returns a
|
|
69
|
+
* theme accent var with the shared concrete fallback.
|
|
70
|
+
*/
|
|
71
|
+
function autoAuthorColor(name) {
|
|
72
|
+
let hash = 0;
|
|
73
|
+
for (let i = 0; i < name.length; i++) {
|
|
74
|
+
hash = (hash * 31 + name.charCodeAt(i)) >>> 0;
|
|
75
|
+
}
|
|
76
|
+
const slot = (hash % 8) + 1;
|
|
77
|
+
return `var(--snice-color-accent-${slot}, ${FALLBACK_ACCENTS[slot - 1]})`;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Author colors ride on message data, so they can come from a backend. A CSS
|
|
81
|
+
* color never needs `;`, `{`, or `}` — reject values that could smuggle extra
|
|
82
|
+
* declarations into the inline style attribute.
|
|
83
|
+
*/
|
|
84
|
+
function isSafeCssColor(value) {
|
|
85
|
+
return !/[;{}]/.test(value);
|
|
86
|
+
}
|
|
44
87
|
/**
|
|
45
88
|
* snice-chat - Chat interface component
|
|
46
89
|
*
|
|
@@ -52,7 +95,6 @@ function getInitials(name) {
|
|
|
52
95
|
* @fires {CustomEvent<{ messageId: string; newContent: string }>} message-edit - Fires when editing a message
|
|
53
96
|
* @fires {CustomEvent<{ messageId: string }>} message-delete - Fires when deleting a message
|
|
54
97
|
* @fires {CustomEvent<{ messageId: string; emoji: string }>} message-react - Fires when reacting to a message
|
|
55
|
-
* @fires {CustomEvent<{ messageId: string }>} message-thread - Fires when starting a thread
|
|
56
98
|
* @fires {CustomEvent<{}>} typing-start - Fires when user starts typing
|
|
57
99
|
* @fires {CustomEvent<{}>} typing-stop - Fires when user stops typing
|
|
58
100
|
*/
|
|
@@ -87,23 +129,53 @@ let SniceChat = (() => {
|
|
|
87
129
|
let _showTimestamps_decorators;
|
|
88
130
|
let _showTimestamps_initializers = [];
|
|
89
131
|
let _showTimestamps_extraInitializers = [];
|
|
132
|
+
let _authorColors_decorators;
|
|
133
|
+
let _authorColors_initializers = [];
|
|
134
|
+
let _authorColors_extraInitializers = [];
|
|
135
|
+
let _colorAuthors_decorators;
|
|
136
|
+
let _colorAuthors_initializers = [];
|
|
137
|
+
let _colorAuthors_extraInitializers = [];
|
|
138
|
+
let _markdown_decorators;
|
|
139
|
+
let _markdown_initializers = [];
|
|
140
|
+
let _markdown_extraInitializers = [];
|
|
141
|
+
let _layout_decorators;
|
|
142
|
+
let _layout_initializers = [];
|
|
143
|
+
let _layout_extraInitializers = [];
|
|
144
|
+
let _editingId_decorators;
|
|
145
|
+
let _editingId_initializers = [];
|
|
146
|
+
let _editingId_extraInitializers = [];
|
|
147
|
+
let _confirmingDeleteId_decorators;
|
|
148
|
+
let _confirmingDeleteId_initializers = [];
|
|
149
|
+
let _confirmingDeleteId_extraInitializers = [];
|
|
90
150
|
let _messagesArea_decorators;
|
|
91
151
|
let _messagesArea_initializers = [];
|
|
92
152
|
let _messagesArea_extraInitializers = [];
|
|
93
153
|
let _inputField_decorators;
|
|
94
154
|
let _inputField_initializers = [];
|
|
95
155
|
let _inputField_extraInitializers = [];
|
|
156
|
+
let _editField_decorators;
|
|
157
|
+
let _editField_initializers = [];
|
|
158
|
+
let _editField_extraInitializers = [];
|
|
159
|
+
let _editBox_decorators;
|
|
160
|
+
let _editBox_initializers = [];
|
|
161
|
+
let _editBox_extraInitializers = [];
|
|
162
|
+
let _confirmBox_decorators;
|
|
163
|
+
let _confirmBox_initializers = [];
|
|
164
|
+
let _confirmBox_extraInitializers = [];
|
|
96
165
|
let _styles_decorators;
|
|
97
166
|
let _init_decorators;
|
|
167
|
+
let _onSlottedMessagesChanged_decorators;
|
|
168
|
+
let _onSlottedMessageAttributesChanged_decorators;
|
|
98
169
|
let _cleanup_decorators;
|
|
99
170
|
let _messagesChanged_decorators;
|
|
100
171
|
let _emitMessageSend_decorators;
|
|
101
172
|
let _emitMessageEdit_decorators;
|
|
102
173
|
let _emitMessageDelete_decorators;
|
|
103
174
|
let _emitMessageReact_decorators;
|
|
104
|
-
let _emitMessageThread_decorators;
|
|
105
175
|
let _emitTypingStart_decorators;
|
|
106
176
|
let _emitTypingStop_decorators;
|
|
177
|
+
let _focusEditField_decorators;
|
|
178
|
+
let _revealDeleteConfirm_decorators;
|
|
107
179
|
let _render_decorators;
|
|
108
180
|
(class extends _classSuper {
|
|
109
181
|
static { _classThis = this; }
|
|
@@ -117,11 +189,28 @@ let SniceChat = (() => {
|
|
|
117
189
|
this.showTyping = (__runInitializers(this, _allowFiles_extraInitializers), __runInitializers(this, _showTyping_initializers, true));
|
|
118
190
|
this.showAvatars = (__runInitializers(this, _showTyping_extraInitializers), __runInitializers(this, _showAvatars_initializers, true));
|
|
119
191
|
this.showTimestamps = (__runInitializers(this, _showAvatars_extraInitializers), __runInitializers(this, _showTimestamps_initializers, true));
|
|
120
|
-
this.
|
|
192
|
+
this.authorColors = (__runInitializers(this, _showTimestamps_extraInitializers), __runInitializers(this, _authorColors_initializers, {}));
|
|
193
|
+
this.colorAuthors = (__runInitializers(this, _authorColors_extraInitializers), __runInitializers(this, _colorAuthors_initializers, false));
|
|
194
|
+
this.markdown = (__runInitializers(this, _colorAuthors_extraInitializers), __runInitializers(this, _markdown_initializers, false));
|
|
195
|
+
this.layout = (__runInitializers(this, _markdown_extraInitializers), __runInitializers(this, _layout_initializers, ChatLayout.Default));
|
|
196
|
+
// Internal reactive state: id of the message currently being edited inline.
|
|
197
|
+
this.editingId = (__runInitializers(this, _layout_extraInitializers), __runInitializers(this, _editingId_initializers, null));
|
|
198
|
+
// Internal reactive state: id of the message pending inline delete-confirm.
|
|
199
|
+
this.confirmingDeleteId = (__runInitializers(this, _editingId_extraInitializers), __runInitializers(this, _confirmingDeleteId_initializers, null));
|
|
200
|
+
this.messagesArea = (__runInitializers(this, _confirmingDeleteId_extraInitializers), __runInitializers(this, _messagesArea_initializers, void 0));
|
|
121
201
|
this.inputField = (__runInitializers(this, _messagesArea_extraInitializers), __runInitializers(this, _inputField_initializers, void 0));
|
|
122
|
-
this.
|
|
202
|
+
this.editField = (__runInitializers(this, _inputField_extraInitializers), __runInitializers(this, _editField_initializers, void 0));
|
|
203
|
+
this.editBox = (__runInitializers(this, _editField_extraInitializers), __runInitializers(this, _editBox_initializers, void 0));
|
|
204
|
+
this.confirmBox = (__runInitializers(this, _editBox_extraInitializers), __runInitializers(this, _confirmBox_initializers, void 0));
|
|
205
|
+
this.typingIndicators = (__runInitializers(this, _confirmBox_extraInitializers), new Map());
|
|
123
206
|
this.typingTimeout = null;
|
|
124
207
|
this.fileInput = null;
|
|
208
|
+
// Element → stable message id, so re-ingesting doesn't mint new ids and
|
|
209
|
+
// orphan reactions/edit state keyed to the old ones.
|
|
210
|
+
this.slotMessageIds = new WeakMap();
|
|
211
|
+
// Every id ever minted for a slot element, so a removed slot child isn't
|
|
212
|
+
// misclassified as an imperative message and resurrected on re-ingest.
|
|
213
|
+
this.mintedSlotIds = new Set();
|
|
125
214
|
this.handleKeyDown = (e) => {
|
|
126
215
|
const target = e.target;
|
|
127
216
|
if (target !== this.inputField)
|
|
@@ -142,31 +231,46 @@ let SniceChat = (() => {
|
|
|
142
231
|
_showTyping_decorators = [property({ type: Boolean, attribute: 'show-typing' })];
|
|
143
232
|
_showAvatars_decorators = [property({ type: Boolean, attribute: 'show-avatars' })];
|
|
144
233
|
_showTimestamps_decorators = [property({ type: Boolean, attribute: 'show-timestamps' })];
|
|
234
|
+
_authorColors_decorators = [property({ type: Object, attribute: false })];
|
|
235
|
+
_colorAuthors_decorators = [property({ type: Boolean, attribute: 'color-authors' })];
|
|
236
|
+
_markdown_decorators = [property({ type: Boolean })];
|
|
237
|
+
_layout_decorators = [property()];
|
|
238
|
+
_editingId_decorators = [property({ attribute: false })];
|
|
239
|
+
_confirmingDeleteId_decorators = [property({ attribute: false })];
|
|
145
240
|
_messagesArea_decorators = [query('.messages-area')];
|
|
146
241
|
_inputField_decorators = [query('.input-field')];
|
|
242
|
+
_editField_decorators = [query('.edit-field')];
|
|
243
|
+
_editBox_decorators = [query('.message-edit')];
|
|
244
|
+
_confirmBox_decorators = [query('.message-confirm')];
|
|
147
245
|
_styles_decorators = [styles()];
|
|
148
246
|
_init_decorators = [ready()];
|
|
247
|
+
_onSlottedMessagesChanged_decorators = [observe('mutation:childList')];
|
|
248
|
+
_onSlottedMessageAttributesChanged_decorators = [observe('mutation:attributes', { subtree: true })];
|
|
149
249
|
_cleanup_decorators = [dispose()];
|
|
150
250
|
_messagesChanged_decorators = [watch('messages')];
|
|
151
251
|
_emitMessageSend_decorators = [dispatch('message-send', { bubbles: true, composed: true })];
|
|
152
252
|
_emitMessageEdit_decorators = [dispatch('message-edit', { bubbles: true, composed: true })];
|
|
153
253
|
_emitMessageDelete_decorators = [dispatch('message-delete', { bubbles: true, composed: true })];
|
|
154
254
|
_emitMessageReact_decorators = [dispatch('message-react', { bubbles: true, composed: true })];
|
|
155
|
-
_emitMessageThread_decorators = [dispatch('message-thread', { bubbles: true, composed: true })];
|
|
156
255
|
_emitTypingStart_decorators = [dispatch('typing-start', { bubbles: true, composed: true })];
|
|
157
256
|
_emitTypingStop_decorators = [dispatch('typing-stop', { bubbles: true, composed: true })];
|
|
257
|
+
_focusEditField_decorators = [watch('editingId')];
|
|
258
|
+
_revealDeleteConfirm_decorators = [watch('confirmingDeleteId')];
|
|
158
259
|
_render_decorators = [render()];
|
|
159
260
|
__esDecorate(this, null, _styles_decorators, { kind: "method", name: "styles", static: false, private: false, access: { has: obj => "styles" in obj, get: obj => obj.styles }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
160
261
|
__esDecorate(this, null, _init_decorators, { kind: "method", name: "init", static: false, private: false, access: { has: obj => "init" in obj, get: obj => obj.init }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
262
|
+
__esDecorate(this, null, _onSlottedMessagesChanged_decorators, { kind: "method", name: "onSlottedMessagesChanged", static: false, private: false, access: { has: obj => "onSlottedMessagesChanged" in obj, get: obj => obj.onSlottedMessagesChanged }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
263
|
+
__esDecorate(this, null, _onSlottedMessageAttributesChanged_decorators, { kind: "method", name: "onSlottedMessageAttributesChanged", static: false, private: false, access: { has: obj => "onSlottedMessageAttributesChanged" in obj, get: obj => obj.onSlottedMessageAttributesChanged }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
161
264
|
__esDecorate(this, null, _cleanup_decorators, { kind: "method", name: "cleanup", static: false, private: false, access: { has: obj => "cleanup" in obj, get: obj => obj.cleanup }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
162
265
|
__esDecorate(this, null, _messagesChanged_decorators, { kind: "method", name: "messagesChanged", static: false, private: false, access: { has: obj => "messagesChanged" in obj, get: obj => obj.messagesChanged }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
163
266
|
__esDecorate(this, null, _emitMessageSend_decorators, { kind: "method", name: "emitMessageSend", static: false, private: false, access: { has: obj => "emitMessageSend" in obj, get: obj => obj.emitMessageSend }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
164
267
|
__esDecorate(this, null, _emitMessageEdit_decorators, { kind: "method", name: "emitMessageEdit", static: false, private: false, access: { has: obj => "emitMessageEdit" in obj, get: obj => obj.emitMessageEdit }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
165
268
|
__esDecorate(this, null, _emitMessageDelete_decorators, { kind: "method", name: "emitMessageDelete", static: false, private: false, access: { has: obj => "emitMessageDelete" in obj, get: obj => obj.emitMessageDelete }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
166
269
|
__esDecorate(this, null, _emitMessageReact_decorators, { kind: "method", name: "emitMessageReact", static: false, private: false, access: { has: obj => "emitMessageReact" in obj, get: obj => obj.emitMessageReact }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
167
|
-
__esDecorate(this, null, _emitMessageThread_decorators, { kind: "method", name: "emitMessageThread", static: false, private: false, access: { has: obj => "emitMessageThread" in obj, get: obj => obj.emitMessageThread }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
168
270
|
__esDecorate(this, null, _emitTypingStart_decorators, { kind: "method", name: "emitTypingStart", static: false, private: false, access: { has: obj => "emitTypingStart" in obj, get: obj => obj.emitTypingStart }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
169
271
|
__esDecorate(this, null, _emitTypingStop_decorators, { kind: "method", name: "emitTypingStop", static: false, private: false, access: { has: obj => "emitTypingStop" in obj, get: obj => obj.emitTypingStop }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
272
|
+
__esDecorate(this, null, _focusEditField_decorators, { kind: "method", name: "focusEditField", static: false, private: false, access: { has: obj => "focusEditField" in obj, get: obj => obj.focusEditField }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
273
|
+
__esDecorate(this, null, _revealDeleteConfirm_decorators, { kind: "method", name: "revealDeleteConfirm", static: false, private: false, access: { has: obj => "revealDeleteConfirm" in obj, get: obj => obj.revealDeleteConfirm }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
170
274
|
__esDecorate(this, null, _render_decorators, { kind: "method", name: "render", static: false, private: false, access: { has: obj => "render" in obj, get: obj => obj.render }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
171
275
|
__esDecorate(null, null, _messages_decorators, { kind: "field", name: "messages", static: false, private: false, access: { has: obj => "messages" in obj, get: obj => obj.messages, set: (obj, value) => { obj.messages = value; } }, metadata: _metadata }, _messages_initializers, _messages_extraInitializers);
|
|
172
276
|
__esDecorate(null, null, _currentUser_decorators, { kind: "field", name: "currentUser", static: false, private: false, access: { has: obj => "currentUser" in obj, get: obj => obj.currentUser, set: (obj, value) => { obj.currentUser = value; } }, metadata: _metadata }, _currentUser_initializers, _currentUser_extraInitializers);
|
|
@@ -176,8 +280,17 @@ let SniceChat = (() => {
|
|
|
176
280
|
__esDecorate(null, null, _showTyping_decorators, { kind: "field", name: "showTyping", static: false, private: false, access: { has: obj => "showTyping" in obj, get: obj => obj.showTyping, set: (obj, value) => { obj.showTyping = value; } }, metadata: _metadata }, _showTyping_initializers, _showTyping_extraInitializers);
|
|
177
281
|
__esDecorate(null, null, _showAvatars_decorators, { kind: "field", name: "showAvatars", static: false, private: false, access: { has: obj => "showAvatars" in obj, get: obj => obj.showAvatars, set: (obj, value) => { obj.showAvatars = value; } }, metadata: _metadata }, _showAvatars_initializers, _showAvatars_extraInitializers);
|
|
178
282
|
__esDecorate(null, null, _showTimestamps_decorators, { kind: "field", name: "showTimestamps", static: false, private: false, access: { has: obj => "showTimestamps" in obj, get: obj => obj.showTimestamps, set: (obj, value) => { obj.showTimestamps = value; } }, metadata: _metadata }, _showTimestamps_initializers, _showTimestamps_extraInitializers);
|
|
283
|
+
__esDecorate(null, null, _authorColors_decorators, { kind: "field", name: "authorColors", static: false, private: false, access: { has: obj => "authorColors" in obj, get: obj => obj.authorColors, set: (obj, value) => { obj.authorColors = value; } }, metadata: _metadata }, _authorColors_initializers, _authorColors_extraInitializers);
|
|
284
|
+
__esDecorate(null, null, _colorAuthors_decorators, { kind: "field", name: "colorAuthors", static: false, private: false, access: { has: obj => "colorAuthors" in obj, get: obj => obj.colorAuthors, set: (obj, value) => { obj.colorAuthors = value; } }, metadata: _metadata }, _colorAuthors_initializers, _colorAuthors_extraInitializers);
|
|
285
|
+
__esDecorate(null, null, _markdown_decorators, { kind: "field", name: "markdown", static: false, private: false, access: { has: obj => "markdown" in obj, get: obj => obj.markdown, set: (obj, value) => { obj.markdown = value; } }, metadata: _metadata }, _markdown_initializers, _markdown_extraInitializers);
|
|
286
|
+
__esDecorate(null, null, _layout_decorators, { kind: "field", name: "layout", static: false, private: false, access: { has: obj => "layout" in obj, get: obj => obj.layout, set: (obj, value) => { obj.layout = value; } }, metadata: _metadata }, _layout_initializers, _layout_extraInitializers);
|
|
287
|
+
__esDecorate(null, null, _editingId_decorators, { kind: "field", name: "editingId", static: false, private: false, access: { has: obj => "editingId" in obj, get: obj => obj.editingId, set: (obj, value) => { obj.editingId = value; } }, metadata: _metadata }, _editingId_initializers, _editingId_extraInitializers);
|
|
288
|
+
__esDecorate(null, null, _confirmingDeleteId_decorators, { kind: "field", name: "confirmingDeleteId", static: false, private: false, access: { has: obj => "confirmingDeleteId" in obj, get: obj => obj.confirmingDeleteId, set: (obj, value) => { obj.confirmingDeleteId = value; } }, metadata: _metadata }, _confirmingDeleteId_initializers, _confirmingDeleteId_extraInitializers);
|
|
179
289
|
__esDecorate(null, null, _messagesArea_decorators, { kind: "field", name: "messagesArea", static: false, private: false, access: { has: obj => "messagesArea" in obj, get: obj => obj.messagesArea, set: (obj, value) => { obj.messagesArea = value; } }, metadata: _metadata }, _messagesArea_initializers, _messagesArea_extraInitializers);
|
|
180
290
|
__esDecorate(null, null, _inputField_decorators, { kind: "field", name: "inputField", static: false, private: false, access: { has: obj => "inputField" in obj, get: obj => obj.inputField, set: (obj, value) => { obj.inputField = value; } }, metadata: _metadata }, _inputField_initializers, _inputField_extraInitializers);
|
|
291
|
+
__esDecorate(null, null, _editField_decorators, { kind: "field", name: "editField", static: false, private: false, access: { has: obj => "editField" in obj, get: obj => obj.editField, set: (obj, value) => { obj.editField = value; } }, metadata: _metadata }, _editField_initializers, _editField_extraInitializers);
|
|
292
|
+
__esDecorate(null, null, _editBox_decorators, { kind: "field", name: "editBox", static: false, private: false, access: { has: obj => "editBox" in obj, get: obj => obj.editBox, set: (obj, value) => { obj.editBox = value; } }, metadata: _metadata }, _editBox_initializers, _editBox_extraInitializers);
|
|
293
|
+
__esDecorate(null, null, _confirmBox_decorators, { kind: "field", name: "confirmBox", static: false, private: false, access: { has: obj => "confirmBox" in obj, get: obj => obj.confirmBox, set: (obj, value) => { obj.confirmBox = value; } }, metadata: _metadata }, _confirmBox_initializers, _confirmBox_extraInitializers);
|
|
181
294
|
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
182
295
|
_classThis = _classDescriptor.value;
|
|
183
296
|
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
@@ -188,6 +301,50 @@ let SniceChat = (() => {
|
|
|
188
301
|
}
|
|
189
302
|
init() {
|
|
190
303
|
this.addEventListener('keydown', this.handleKeyDown);
|
|
304
|
+
this.ingestSlottedMessages();
|
|
305
|
+
}
|
|
306
|
+
// Declarative dual-API: read slotted <snice-chat-message> children as the
|
|
307
|
+
// messages source. An empty slot leaves the array untouched. Mirrors
|
|
308
|
+
// snice-table / snice-column. Slotted messages keep a stable id across
|
|
309
|
+
// re-ingests (keyed per element), runtime state (reactions, inline edits)
|
|
310
|
+
// survives, and imperatively-added messages are appended after the slot set.
|
|
311
|
+
onSlottedMessagesChanged() {
|
|
312
|
+
this.ingestSlottedMessages();
|
|
313
|
+
}
|
|
314
|
+
onSlottedMessageAttributesChanged() {
|
|
315
|
+
this.ingestSlottedMessages();
|
|
316
|
+
}
|
|
317
|
+
ingestSlottedMessages() {
|
|
318
|
+
const els = Array.from(this.querySelectorAll('snice-chat-message'));
|
|
319
|
+
if (els.length === 0)
|
|
320
|
+
return;
|
|
321
|
+
const existingById = new Map(this.messages.map((m) => [m.id, m]));
|
|
322
|
+
const slotMessages = els.map((el) => {
|
|
323
|
+
let id = this.slotMessageIds.get(el);
|
|
324
|
+
if (!id) {
|
|
325
|
+
id = generateId();
|
|
326
|
+
this.slotMessageIds.set(el, id);
|
|
327
|
+
this.mintedSlotIds.add(id);
|
|
328
|
+
}
|
|
329
|
+
const definition = { ...el.getMessageDefinition(), id };
|
|
330
|
+
const existing = existingById.get(id);
|
|
331
|
+
if (!existing)
|
|
332
|
+
return definition;
|
|
333
|
+
// Runtime state outranks the (possibly stale) light DOM: keep reactions
|
|
334
|
+
// accumulated via the UI unless the element declares its own, and keep
|
|
335
|
+
// an inline edit's content over the original slotted text.
|
|
336
|
+
if (!definition.reactions && existing.reactions)
|
|
337
|
+
definition.reactions = existing.reactions;
|
|
338
|
+
if (existing.edited && !definition.edited) {
|
|
339
|
+
definition.content = existing.content;
|
|
340
|
+
definition.edited = true;
|
|
341
|
+
}
|
|
342
|
+
return definition;
|
|
343
|
+
});
|
|
344
|
+
// Imperatively-added messages (addMessage) are not backed by an element;
|
|
345
|
+
// keep them, appended after the slot set.
|
|
346
|
+
const imperative = this.messages.filter((m) => !this.mintedSlotIds.has(m.id));
|
|
347
|
+
this.messages = [...slotMessages, ...imperative];
|
|
191
348
|
}
|
|
192
349
|
cleanup() {
|
|
193
350
|
this.removeEventListener('keydown', this.handleKeyDown);
|
|
@@ -195,9 +352,13 @@ let SniceChat = (() => {
|
|
|
195
352
|
clearTimeout(this.typingTimeout);
|
|
196
353
|
}
|
|
197
354
|
}
|
|
198
|
-
messagesChanged() {
|
|
199
|
-
// Scroll to bottom when
|
|
200
|
-
|
|
355
|
+
messagesChanged(oldMessages, newMessages) {
|
|
356
|
+
// Scroll to bottom only when a message was appended — reactions and edits
|
|
357
|
+
// reassign the array too, and must not yank the viewport while the user
|
|
358
|
+
// is scrolled up reading history.
|
|
359
|
+
if ((newMessages?.length ?? 0) > (oldMessages?.length ?? 0)) {
|
|
360
|
+
setTimeout(() => this.scrollToBottom(), 0);
|
|
361
|
+
}
|
|
201
362
|
}
|
|
202
363
|
emitMessageSend(message, attachments) {
|
|
203
364
|
return { message, attachments };
|
|
@@ -211,9 +372,6 @@ let SniceChat = (() => {
|
|
|
211
372
|
emitMessageReact(messageId, emoji) {
|
|
212
373
|
return { messageId, emoji };
|
|
213
374
|
}
|
|
214
|
-
emitMessageThread(messageId) {
|
|
215
|
-
return { messageId };
|
|
216
|
-
}
|
|
217
375
|
emitTypingStart() {
|
|
218
376
|
return {};
|
|
219
377
|
}
|
|
@@ -328,26 +486,95 @@ let SniceChat = (() => {
|
|
|
328
486
|
this.inputField.style.height = 'auto';
|
|
329
487
|
this.inputField.style.height = `${Math.min(this.inputField.scrollHeight, 150)}px`;
|
|
330
488
|
}
|
|
489
|
+
// Reactions are social: anyone can react to any message. Toggle the current
|
|
490
|
+
// user on/off the emoji, update the local model, and emit for a backend.
|
|
331
491
|
handleReaction(messageId, emoji) {
|
|
492
|
+
const me = this.currentUser;
|
|
493
|
+
this.messages = this.messages.map((m) => {
|
|
494
|
+
if (m.id !== messageId)
|
|
495
|
+
return m;
|
|
496
|
+
const reactions = [...(m.reactions ?? [])];
|
|
497
|
+
const i = reactions.findIndex((r) => r.emoji === emoji);
|
|
498
|
+
if (i === -1) {
|
|
499
|
+
reactions.push({ emoji, count: 1, users: [me] });
|
|
500
|
+
}
|
|
501
|
+
else {
|
|
502
|
+
const r = reactions[i];
|
|
503
|
+
const removing = r.users.includes(me);
|
|
504
|
+
const users = removing ? r.users.filter((u) => u !== me) : [...r.users, me];
|
|
505
|
+
// Adjust by ±1 — never recompute from users.length, which destroys
|
|
506
|
+
// server counts backed by truncated user lists (count 128, users [2]).
|
|
507
|
+
const count = Math.max(users.length, r.count + (removing ? -1 : 1));
|
|
508
|
+
if (count === 0)
|
|
509
|
+
reactions.splice(i, 1);
|
|
510
|
+
else
|
|
511
|
+
reactions[i] = { ...r, count, users };
|
|
512
|
+
}
|
|
513
|
+
return { ...m, reactions };
|
|
514
|
+
});
|
|
332
515
|
this.emitMessageReact(messageId, emoji);
|
|
333
516
|
}
|
|
334
|
-
|
|
517
|
+
// Edit is inline: clicking edit swaps the body for a textarea. Owner-only.
|
|
518
|
+
// Inline modes are exclusive: opening one closes the other.
|
|
519
|
+
startEdit(messageId) {
|
|
520
|
+
this.confirmingDeleteId = null;
|
|
521
|
+
this.editingId = messageId;
|
|
522
|
+
}
|
|
523
|
+
cancelEdit() {
|
|
524
|
+
this.editingId = null;
|
|
525
|
+
}
|
|
526
|
+
commitEdit(messageId) {
|
|
527
|
+
const next = (this.editField?.value ?? '').trim();
|
|
335
528
|
const message = this.messages.find((m) => m.id === messageId);
|
|
336
|
-
|
|
529
|
+
this.editingId = null;
|
|
530
|
+
if (!message || !next || next === message.content)
|
|
337
531
|
return;
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
532
|
+
this.updateMessage(messageId, { content: next, edited: true });
|
|
533
|
+
this.emitMessageEdit(messageId, next);
|
|
534
|
+
}
|
|
535
|
+
handleEditKeydown(e, messageId) {
|
|
536
|
+
if (e.key === 'Enter' && !e.shiftKey) {
|
|
537
|
+
e.preventDefault();
|
|
538
|
+
this.commitEdit(messageId);
|
|
539
|
+
}
|
|
540
|
+
else if (e.key === 'Escape') {
|
|
541
|
+
e.preventDefault();
|
|
542
|
+
this.cancelEdit();
|
|
342
543
|
}
|
|
343
544
|
}
|
|
545
|
+
focusEditField() {
|
|
546
|
+
if (this.editingId === null)
|
|
547
|
+
return;
|
|
548
|
+
// Watchers run before the re-render is even scheduled (renders flush on
|
|
549
|
+
// a microtask), so defer to a frame where the editor exists.
|
|
550
|
+
requestAnimationFrame(() => {
|
|
551
|
+
this.editField?.focus();
|
|
552
|
+
// The editor is taller than the message body it replaces; on the last
|
|
553
|
+
// message its Save/Cancel row would clip below the scroll area.
|
|
554
|
+
this.editBox?.scrollIntoView({ block: 'nearest' });
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
// Delete asks for inline confirmation (not a native confirm dialog).
|
|
558
|
+
// Owner-only. On confirm, updates the local model and emits for a backend.
|
|
559
|
+
// Inline modes are exclusive: opening one closes the other.
|
|
344
560
|
handleDelete(messageId) {
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
561
|
+
this.editingId = null;
|
|
562
|
+
this.confirmingDeleteId = messageId;
|
|
563
|
+
}
|
|
564
|
+
revealDeleteConfirm() {
|
|
565
|
+
if (this.confirmingDeleteId === null)
|
|
566
|
+
return;
|
|
567
|
+
// Same clipping problem as the inline editor: the confirm row extends
|
|
568
|
+
// the last message past the bottom of the scroll area.
|
|
569
|
+
requestAnimationFrame(() => this.confirmBox?.scrollIntoView({ block: 'nearest' }));
|
|
570
|
+
}
|
|
571
|
+
confirmDelete(messageId) {
|
|
572
|
+
this.confirmingDeleteId = null;
|
|
573
|
+
this.deleteMessage(messageId);
|
|
574
|
+
this.emitMessageDelete(messageId);
|
|
348
575
|
}
|
|
349
|
-
|
|
350
|
-
this.
|
|
576
|
+
cancelDelete() {
|
|
577
|
+
this.confirmingDeleteId = null;
|
|
351
578
|
}
|
|
352
579
|
render() {
|
|
353
580
|
return html /*html*/ `
|
|
@@ -374,23 +601,58 @@ let SniceChat = (() => {
|
|
|
374
601
|
</div>
|
|
375
602
|
`;
|
|
376
603
|
}
|
|
604
|
+
// Per-message author color. Precedence: per-message override → authorColors
|
|
605
|
+
// map → auto (only when color-authors is set) → none (falls through to the
|
|
606
|
+
// default token in CSS). Computed per element instance — no global registry.
|
|
607
|
+
resolveAuthorColor(message) {
|
|
608
|
+
if (message.authorColor && isSafeCssColor(message.authorColor))
|
|
609
|
+
return message.authorColor;
|
|
610
|
+
const mapped = this.authorColors[message.author];
|
|
611
|
+
if (mapped && isSafeCssColor(mapped))
|
|
612
|
+
return mapped;
|
|
613
|
+
if (this.colorAuthors)
|
|
614
|
+
return autoAuthorColor(message.author);
|
|
615
|
+
return '';
|
|
616
|
+
}
|
|
617
|
+
// Markdown is opt-in: per-message format='markdown', or the component-wide
|
|
618
|
+
// `markdown` attribute (which a per-message format='text' can override).
|
|
619
|
+
shouldRenderMarkdown(message) {
|
|
620
|
+
if (message.format === MessageFormat.Markdown)
|
|
621
|
+
return true;
|
|
622
|
+
if (this.markdown && message.format !== MessageFormat.Text)
|
|
623
|
+
return true;
|
|
624
|
+
return false;
|
|
625
|
+
}
|
|
626
|
+
renderMessageBody(message) {
|
|
627
|
+
if (this.shouldRenderMarkdown(message)) {
|
|
628
|
+
return html /*html*/ `<snice-markdown part="message-text" class="message-text" .content=${message.content}></snice-markdown>`;
|
|
629
|
+
}
|
|
630
|
+
return html /*html*/ `<div part="message-text" class="message-text">${message.content}</div>`;
|
|
631
|
+
}
|
|
377
632
|
renderMessage(message) {
|
|
378
633
|
const isSystem = message.type === 'system';
|
|
379
634
|
const isCurrentUser = message.author === this.currentUser;
|
|
380
635
|
if (isSystem) {
|
|
381
636
|
return html /*html*/ `
|
|
382
|
-
<div class="message system" data-message-id="${message.id}">
|
|
637
|
+
<div part="message system-message" class="message system" data-message-id="${message.id}">
|
|
383
638
|
<div class="message-content">
|
|
384
|
-
<div class="message-text">${message.content}</div>
|
|
639
|
+
<div part="message-text" class="message-text">${message.content}</div>
|
|
385
640
|
</div>
|
|
386
641
|
</div>
|
|
387
642
|
`;
|
|
388
643
|
}
|
|
644
|
+
const ownClass = isCurrentUser ? 'own' : 'other';
|
|
645
|
+
const ownPart = isCurrentUser ? 'message-own' : 'message-other';
|
|
646
|
+
const authorColor = this.resolveAuthorColor(message);
|
|
647
|
+
const authorStyle = authorColor ? `--snice-chat-author-color:${authorColor}` : '';
|
|
648
|
+
const isEditing = this.editingId === message.id;
|
|
649
|
+
const isConfirmingDelete = this.confirmingDeleteId === message.id;
|
|
650
|
+
const hasReactions = !!message.reactions && message.reactions.length > 0;
|
|
389
651
|
return html /*html*/ `
|
|
390
|
-
<div class="message" data-message-id="${message.id}">
|
|
652
|
+
<div part="message ${ownPart}" class="message ${ownClass}" data-message-id="${message.id}">
|
|
391
653
|
${this.showAvatars
|
|
392
654
|
? html `
|
|
393
|
-
<div class="message-avatar">
|
|
655
|
+
<div part="avatar" class="message-avatar">
|
|
394
656
|
${message.avatar
|
|
395
657
|
? html `<img src="${message.avatar}" alt="${message.author}" />`
|
|
396
658
|
: getInitials(message.author)}
|
|
@@ -399,55 +661,70 @@ let SniceChat = (() => {
|
|
|
399
661
|
: ''}
|
|
400
662
|
<div class="message-content">
|
|
401
663
|
<div class="message-header">
|
|
402
|
-
<span class="message-author">${message.author}</span>
|
|
664
|
+
<span part="author" class="message-author" style="${authorStyle}">${message.author}</span>
|
|
403
665
|
${this.showTimestamps
|
|
404
|
-
? html `<span class="message-timestamp">${formatTime(message.timestamp)}</span>`
|
|
666
|
+
? html `<span part="timestamp" class="message-timestamp">${formatTime(message.timestamp)}</span>`
|
|
405
667
|
: ''}
|
|
406
|
-
${message.edited ? html `<span class="message-edited">(edited)</span>` : ''}
|
|
668
|
+
${message.edited ? html `<span part="edited" class="message-edited">(edited)</span>` : ''}
|
|
407
669
|
</div>
|
|
408
|
-
${
|
|
670
|
+
${isEditing
|
|
671
|
+
? this.renderEditor(message)
|
|
672
|
+
: message.content ? this.renderMessageBody(message) : ''}
|
|
409
673
|
${message.attachment ? this.renderAttachment(message.attachment) : ''}
|
|
410
|
-
${message.
|
|
411
|
-
|
|
412
|
-
|
|
674
|
+
${hasReactions ? this.renderReactions(message.id, message.reactions) : ''}
|
|
675
|
+
${isConfirmingDelete ? this.renderDeleteConfirm(message) : ''}
|
|
676
|
+
</div>
|
|
677
|
+
${isEditing || isConfirmingDelete ? '' : this.renderActions(message.id, isCurrentUser)}
|
|
678
|
+
</div>
|
|
679
|
+
`;
|
|
680
|
+
}
|
|
681
|
+
// Inline message editor — replaces the body while editing. Enter saves,
|
|
682
|
+
// Shift+Enter newlines, Esc cancels.
|
|
683
|
+
renderEditor(message) {
|
|
684
|
+
return html /*html*/ `
|
|
685
|
+
<div class="message-edit">
|
|
686
|
+
<textarea
|
|
687
|
+
part="edit-input"
|
|
688
|
+
class="edit-field"
|
|
689
|
+
.value=${message.content}
|
|
690
|
+
@keydown=${(e) => this.handleEditKeydown(e, message.id)}
|
|
691
|
+
></textarea>
|
|
692
|
+
<div class="edit-actions">
|
|
693
|
+
<button part="edit-save" class="edit-button edit-save" @click=${() => this.commitEdit(message.id)}>Save</button>
|
|
694
|
+
<button part="edit-cancel" class="edit-button" @click=${() => this.cancelEdit()}>Cancel</button>
|
|
695
|
+
</div>
|
|
696
|
+
</div>
|
|
697
|
+
`;
|
|
698
|
+
}
|
|
699
|
+
// Inline delete confirmation — replaces the hover actions while pending, so
|
|
700
|
+
// a misclick can't destroy a message. Confirm deletes + emits; Cancel aborts.
|
|
701
|
+
renderDeleteConfirm(message) {
|
|
702
|
+
return html /*html*/ `
|
|
703
|
+
<div part="delete-confirm" class="message-confirm">
|
|
704
|
+
<span class="confirm-text">Delete this message?</span>
|
|
705
|
+
<div class="confirm-actions">
|
|
706
|
+
<button part="delete-confirm-yes" class="confirm-button confirm-delete" @click=${() => this.confirmDelete(message.id)}>Delete</button>
|
|
707
|
+
<button part="delete-confirm-no" class="confirm-button" @click=${() => this.cancelDelete()}>Cancel</button>
|
|
413
708
|
</div>
|
|
709
|
+
</div>
|
|
710
|
+
`;
|
|
711
|
+
}
|
|
712
|
+
// Hover action menu. React is available on every message (you react to
|
|
713
|
+
// others, not just yourself); edit and delete are owner-only.
|
|
714
|
+
renderActions(messageId, isCurrentUser) {
|
|
715
|
+
return html /*html*/ `
|
|
716
|
+
<div part="actions" class="message-actions">
|
|
717
|
+
<button class="action-button" @click=${() => this.handleReaction(messageId, '👍')} title="React" aria-label="React">
|
|
718
|
+
<span class="action-emoji" aria-hidden="true">🙂</span>
|
|
719
|
+
</button>
|
|
414
720
|
${isCurrentUser
|
|
415
721
|
? html `
|
|
416
|
-
<
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
<svg viewBox="0 0 16 16" fill="currentColor">
|
|
423
|
-
<path
|
|
424
|
-
d="M8 0a8 8 0 1 1 0 16A8 8 0 0 1 8 0zM5.5 7.5a1 1 0 1 0 0-2 1 1 0 0 0 0 2zm5 0a1 1 0 1 0 0-2 1 1 0 0 0 0 2zM8 11c1.5 0 2.7-1 3.2-2H4.8c.5 1 1.7 2 3.2 2z"
|
|
425
|
-
/>
|
|
426
|
-
</svg>
|
|
427
|
-
</button>
|
|
428
|
-
<button
|
|
429
|
-
class="action-button"
|
|
430
|
-
@click="${() => this.handleEdit(message.id)}"
|
|
431
|
-
title="Edit"
|
|
432
|
-
>
|
|
433
|
-
<svg viewBox="0 0 16 16" fill="currentColor">
|
|
434
|
-
<path
|
|
435
|
-
d="M11.013 1.427a1.75 1.75 0 0 1 2.474 0l1.086 1.086a1.75 1.75 0 0 1 0 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 0 1-.927-.928l.929-3.25a1.75 1.75 0 0 1 .445-.758l8.61-8.61z"
|
|
436
|
-
/>
|
|
437
|
-
</svg>
|
|
438
|
-
</button>
|
|
439
|
-
<button
|
|
440
|
-
class="action-button"
|
|
441
|
-
@click="${() => this.handleDelete(message.id)}"
|
|
442
|
-
title="Delete"
|
|
443
|
-
>
|
|
444
|
-
<svg viewBox="0 0 16 16" fill="currentColor">
|
|
445
|
-
<path
|
|
446
|
-
d="M11 1.75V3h2.25a.75.75 0 0 1 0 1.5H2.75a.75.75 0 0 1 0-1.5H5V1.75C5 .784 5.784 0 6.75 0h2.5C10.216 0 11 .784 11 1.75zM4.496 6.675l.66 6.6a.25.25 0 0 0 .249.225h5.19a.25.25 0 0 0 .249-.225l.66-6.6a.75.75 0 0 1 1.492.149l-.66 6.6A1.748 1.748 0 0 1 10.595 15h-5.19a1.75 1.75 0 0 1-1.741-1.575l-.66-6.6a.75.75 0 1 1 1.492-.15z"
|
|
447
|
-
/>
|
|
448
|
-
</svg>
|
|
449
|
-
</button>
|
|
450
|
-
</div>
|
|
722
|
+
<button class="action-button" @click=${() => this.startEdit(messageId)} title="Edit" aria-label="Edit message">
|
|
723
|
+
${unsafeHTML(PENCIL)}
|
|
724
|
+
</button>
|
|
725
|
+
<button class="action-button" @click=${() => this.handleDelete(messageId)} title="Delete" aria-label="Delete message">
|
|
726
|
+
${unsafeHTML(TRASH)}
|
|
727
|
+
</button>
|
|
451
728
|
`
|
|
452
729
|
: ''}
|
|
453
730
|
</div>
|
|
@@ -458,13 +735,13 @@ let SniceChat = (() => {
|
|
|
458
735
|
return '';
|
|
459
736
|
if (attachment.type === 'image') {
|
|
460
737
|
return html /*html*/ `
|
|
461
|
-
<div class="message-attachment">
|
|
738
|
+
<div part="attachment" class="message-attachment">
|
|
462
739
|
<img src="${attachment.url}" alt="${attachment.name}" />
|
|
463
740
|
</div>
|
|
464
741
|
`;
|
|
465
742
|
}
|
|
466
743
|
return html /*html*/ `
|
|
467
|
-
<div class="message-attachment">
|
|
744
|
+
<div part="attachment" class="message-attachment">
|
|
468
745
|
<div class="attachment-file">
|
|
469
746
|
<div class="attachment-icon">
|
|
470
747
|
<svg viewBox="0 0 16 16" fill="currentColor">
|
|
@@ -483,20 +760,24 @@ let SniceChat = (() => {
|
|
|
483
760
|
</div>
|
|
484
761
|
`;
|
|
485
762
|
}
|
|
486
|
-
renderReactions(messageId, reactions
|
|
763
|
+
renderReactions(messageId, reactions) {
|
|
487
764
|
if (!reactions || reactions.length === 0)
|
|
488
765
|
return '';
|
|
489
766
|
return html /*html*/ `
|
|
490
|
-
<div class="message-reactions">
|
|
491
|
-
${reactions.map((reaction) =>
|
|
767
|
+
<div part="reactions" class="message-reactions">
|
|
768
|
+
${reactions.map((reaction) => {
|
|
769
|
+
const isActive = reaction.users.includes(this.currentUser);
|
|
770
|
+
return html `
|
|
492
771
|
<div
|
|
493
|
-
|
|
772
|
+
part="reaction ${isActive ? 'reaction-active' : ''}"
|
|
773
|
+
class="reaction ${isActive ? 'active' : ''}"
|
|
494
774
|
@click="${() => this.handleReaction(messageId, reaction.emoji)}"
|
|
495
775
|
>
|
|
496
776
|
<span class="reaction-emoji">${reaction.emoji}</span>
|
|
497
777
|
<span class="reaction-count">${reaction.count}</span>
|
|
498
778
|
</div>
|
|
499
|
-
|
|
779
|
+
`;
|
|
780
|
+
})}
|
|
500
781
|
</div>
|
|
501
782
|
`;
|
|
502
783
|
}
|
|
@@ -506,7 +787,7 @@ let SniceChat = (() => {
|
|
|
506
787
|
return '';
|
|
507
788
|
return html /*html*/ `
|
|
508
789
|
<div class="typing-indicators">
|
|
509
|
-
<div class="typing-indicator">
|
|
790
|
+
<div part="typing-indicator" class="typing-indicator">
|
|
510
791
|
<span>${users.map((u) => u.user).join(', ')} ${users.length === 1 ? 'is' : 'are'} typing</span>
|
|
511
792
|
<div class="typing-dots">
|
|
512
793
|
<div class="typing-dot"></div>
|
|
@@ -537,20 +818,12 @@ let SniceChat = (() => {
|
|
|
537
818
|
@click="${() => this.handleFileClick()}"
|
|
538
819
|
title="Attach file"
|
|
539
820
|
>
|
|
540
|
-
|
|
541
|
-
<path
|
|
542
|
-
d="M11.28 6.22a.75.75 0 0 0-1.06 0L7.25 9.19 5.78 7.72a.75.75 0 0 0-1.06 1.06l2 2a.75.75 0 0 0 1.06 0l3.5-3.5a.75.75 0 0 0 0-1.06zM16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-1.5 0a6.5 6.5 0 1 0-13 0 6.5 6.5 0 0 0 13 0z"
|
|
543
|
-
/>
|
|
544
|
-
</svg>
|
|
821
|
+
${unsafeHTML(PAPER_CLIP)}
|
|
545
822
|
</button>
|
|
546
823
|
`
|
|
547
824
|
: ''}
|
|
548
825
|
<button class="input-button send" @click="${() => this.sendMessage()}" title="Send">
|
|
549
|
-
|
|
550
|
-
<path
|
|
551
|
-
d="M1.724 2.016a.75.75 0 0 1 1.048-.964l12.5 7a.75.75 0 0 1 0 1.292l-12.5 7a.75.75 0 0 1-1.048-.964l1.5-6.5a.75.75 0 0 1 .584-.584l5.916-1.188-5.916-1.188a.75.75 0 0 1-.584-.584l-1.5-6.5z"
|
|
552
|
-
/>
|
|
553
|
-
</svg>
|
|
826
|
+
${unsafeHTML(PAPER_AIRPLANE_SOLID)}
|
|
554
827
|
</button>
|
|
555
828
|
</div>
|
|
556
829
|
</div>
|