snice 5.2.3 → 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,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* snice
|
|
2
|
+
* snice v6.0.0
|
|
3
3
|
* A decorator-driven web component library with differential rendering, routing, controllers, and 130+ ready-made UI components. Use as much or as little as you want. Zero dependencies, works anywhere.
|
|
4
4
|
* (c) 2024
|
|
5
5
|
* Released under the MIT License.
|
|
@@ -64,6 +64,34 @@ var SniceChat = (function (exports, snice) {
|
|
|
64
64
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
65
65
|
};
|
|
66
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Built-in snice icon set — a small curated subset of Heroicons, used by
|
|
69
|
+
* components as their default glyph when no consumer slot or `icon` prop is
|
|
70
|
+
* provided. Consumers can always override by slotting their own icon library
|
|
71
|
+
* (Font Awesome, Material Symbols, Lucide, custom SVG, etc.).
|
|
72
|
+
*
|
|
73
|
+
* Copied from Heroicons v2 — MIT License, © Tailwind Labs.
|
|
74
|
+
* https://github.com/tailwindlabs/heroicons
|
|
75
|
+
*
|
|
76
|
+
* Why embed instead of depending on a package:
|
|
77
|
+
* - Snice ships zero runtime dependencies beyond the framework itself.
|
|
78
|
+
* - We only need ~15 glyphs; the full Heroicons package is 600+ icons.
|
|
79
|
+
* - Embedding sidesteps shadow DOM / module-resolution concerns and keeps
|
|
80
|
+
* default icons available even in sandboxed environments.
|
|
81
|
+
*
|
|
82
|
+
* All SVGs:
|
|
83
|
+
* - viewBox="0 0 24 24"
|
|
84
|
+
* - solid variants use `fill="currentColor"`
|
|
85
|
+
* - outline variants use `stroke="currentColor"` + no fill
|
|
86
|
+
*
|
|
87
|
+
* Components pass `currentColor` through by setting `color:` on the wrapper.
|
|
88
|
+
*/
|
|
89
|
+
// ─── SOLID (filled) — used for status / selected / active contexts ────────
|
|
90
|
+
const PAPER_AIRPLANE_SOLID = /*html*/ `<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M3.478 2.404a.75.75 0 0 0-.926.941l2.432 7.905H13.5a.75.75 0 0 1 0 1.5H4.984l-2.432 7.905a.75.75 0 0 0 .926.94 60.519 60.519 0 0 0 18.445-8.986.75.75 0 0 0 0-1.218A60.517 60.517 0 0 0 3.478 2.404Z"/></svg>`;
|
|
91
|
+
const TRASH = /*html*/ `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m14.74 9-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 0 1-2.244 2.077H8.084a2.25 2.25 0 0 1-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 0 0-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 0 1 3.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 0 0-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 0 0-7.5 0"/></svg>`;
|
|
92
|
+
const PENCIL = /*html*/ `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m16.862 4.487 1.687-1.688a1.875 1.875 0 1 1 2.652 2.652L6.832 19.82a4.5 4.5 0 0 1-1.897 1.13l-2.685.8.8-2.685a4.5 4.5 0 0 1 1.13-1.897L16.863 4.487Zm0 0L19.5 7.125"/></svg>`;
|
|
93
|
+
const PAPER_CLIP = /*html*/ `<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m18.375 12.739-7.693 7.693a4.5 4.5 0 0 1-6.364-6.364l10.94-10.94A3 3 0 1 1 19.5 7.372L8.552 18.32m.009-.01-.01.01m5.699-9.941-7.81 7.81a1.5 1.5 0 0 0 2.112 2.13"/></svg>`;
|
|
94
|
+
|
|
67
95
|
/**
|
|
68
96
|
* Detects icon type and returns appropriate template
|
|
69
97
|
*
|
|
@@ -120,6 +148,15 @@ var SniceChat = (function (exports, snice) {
|
|
|
120
148
|
}
|
|
121
149
|
return snice.html `<span class="${className}" part="icon">${icon}</span>`;
|
|
122
150
|
}
|
|
151
|
+
/**
|
|
152
|
+
* Fallback accent hues (muted/business tones). Used when CSS vars haven't
|
|
153
|
+
* been applied (test environments, SSR) or when the 8 accent tokens have
|
|
154
|
+
* been stripped. Keep in lockstep with `theme.css` --snice-color-accent-1..8.
|
|
155
|
+
*/
|
|
156
|
+
const FALLBACK_ACCENTS = [
|
|
157
|
+
'hsl(214 55% 48%)', 'hsl(27 62% 50%)', 'hsl(160 40% 40%)', 'hsl(275 32% 52%)',
|
|
158
|
+
'hsl(42 62% 48%)', 'hsl(340 42% 55%)', 'hsl(110 32% 42%)', 'hsl(195 45% 46%)',
|
|
159
|
+
];
|
|
123
160
|
|
|
124
161
|
var cssContent$1 = ":host{display:block;font-family:var(--snice-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif)}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:var(--snice-spacing-2xl,3rem) var(--snice-spacing-xl,2rem);color:var(--snice-color-text-secondary,rgb(82 82 82));animation:snice-empty-in 360ms var(--snice-ease-out,ease) backwards}@keyframes snice-empty-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.empty-state--small{padding:var(--snice-spacing-xl,2rem) var(--snice-spacing-lg,1.5rem)}.empty-state--medium{padding:var(--snice-spacing-2xl,3rem) var(--snice-spacing-xl,2rem)}.empty-state--large{padding:var(--snice-spacing-3xl,4rem) var(--snice-spacing-2xl,2.5rem)}.empty-state__icon-wrapper{display:flex;align-items:center;justify-content:center;margin-bottom:var(--snice-spacing-lg,1.5rem);position:relative;width:calc(var(--snice-font-size-4xl,4rem) * 1.8);height:calc(var(--snice-font-size-4xl,4rem) * 1.8)}.empty-state__icon-wrapper::before{content:'';position:absolute;inset:0;border-radius:50%;border:1px dashed color-mix(in srgb,var(--snice-color-border,#ddd) 70%,transparent);animation:18s linear infinite snice-empty-halo}@keyframes snice-empty-halo{to{transform:rotate(360deg)}}.empty-state__icon{font-size:var(--snice-font-size-4xl, 4rem);opacity:.5;line-height:1}.empty-state__icon-wrapper ::slotted(*){display:flex;align-items:center;justify-content:center;font-size:var(--snice-font-size-4xl, 4rem);opacity:.5;line-height:1}.empty-state__icon-wrapper ::slotted(svg){width:var(--snice-font-size-4xl,4rem);height:var(--snice-font-size-4xl,4rem)}.empty-state__icon-wrapper ::slotted(img){width:var(--snice-font-size-4xl,4rem);height:var(--snice-font-size-4xl,4rem);object-fit:contain}.empty-state--small .empty-state__icon-wrapper{margin-bottom:var(--snice-spacing-md,1rem);width:calc(var(--snice-font-size-3xl,3rem) * 1.8);height:calc(var(--snice-font-size-3xl,3rem) * 1.8)}.empty-state--small .empty-state__icon{font-size:var(--snice-font-size-3xl, 3rem)}.empty-state--small .empty-state__icon-wrapper ::slotted(*){font-size:var(--snice-font-size-3xl, 3rem)}.empty-state--small .empty-state__icon-wrapper ::slotted(img),.empty-state--small .empty-state__icon-wrapper ::slotted(svg){width:var(--snice-font-size-3xl,3rem);height:var(--snice-font-size-3xl,3rem)}.empty-state--large .empty-state__icon-wrapper{margin-bottom:var(--snice-spacing-xl,2rem);width:calc(var(--snice-font-size-5xl,5rem) * 1.8);height:calc(var(--snice-font-size-5xl,5rem) * 1.8)}.empty-state--large .empty-state__icon{font-size:var(--snice-font-size-5xl, 5rem)}.empty-state--large .empty-state__icon-wrapper ::slotted(*){font-size:var(--snice-font-size-5xl, 5rem)}.empty-state--large .empty-state__icon-wrapper ::slotted(img),.empty-state--large .empty-state__icon-wrapper ::slotted(svg){width:var(--snice-font-size-5xl,5rem);height:var(--snice-font-size-5xl,5rem)}.empty-state__title{font-family:var(--snice-font-family-display);font-size:var(--snice-heading-lg, 1.25rem);font-weight:var(--snice-font-weight-semibold,600);color:var(--snice-color-text,rgb(23 23 23));margin:0 0 var(--snice-spacing-xs,.5rem) 0}.empty-state--small .empty-state__title{font-family:var(--snice-font-family-display);font-size:var(--snice-heading-md, 1.125rem);margin-bottom:var(--snice-spacing-2xs,.375rem)}.empty-state--large .empty-state__title{font-family:var(--snice-font-family-display);font-size:var(--snice-heading-xl, 1.5rem);margin-bottom:var(--snice-spacing-sm,.75rem)}.empty-state__description{font-size:var(--snice-font-size-sm, .875rem);color:var(--snice-color-text-secondary,rgb(82 82 82));margin:0 0 var(--snice-spacing-lg,1.5rem) 0;max-width:32rem;line-height:var(--snice-line-height-normal, 1.5)}.empty-state--small .empty-state__description{font-size:var(--snice-font-size-xs, .8125rem);margin-bottom:var(--snice-spacing-md,1rem)}.empty-state--large .empty-state__description{font-size:var(--snice-font-size-md, 1rem);margin-bottom:var(--snice-spacing-xl,2rem)}.empty-state__action{display:inline-flex;align-items:center;justify-content:center;padding:var(--snice-spacing-xs,.5rem) var(--snice-spacing-md,1rem);font-size:var(--snice-font-size-sm, .875rem);font-weight:var(--snice-font-weight-medium,500);color:var(--snice-color-text-inverse,rgb(250 250 250));background:var(--snice-color-primary,rgb(37 99 235));border:none;border-radius:var(--snice-border-radius-md,.375rem);text-decoration:none;cursor:pointer;transition:background var(--snice-transition-fast, 150ms)}.empty-state__action:hover{background:var(--snice-color-primary-hover,rgb(29 78 216))}.empty-state--small .empty-state__action{padding:var(--snice-spacing-2xs,.375rem) var(--snice-spacing-sm,.75rem);font-size:var(--snice-font-size-xs, .8125rem)}.empty-state--large .empty-state__action{padding:var(--snice-spacing-sm,.625rem) var(--snice-spacing-lg,1.25rem);font-size:var(--snice-font-size-md, 1rem)}.empty-state__extra ::slotted(*){margin-top:var(--snice-spacing-md,1rem)}";
|
|
125
162
|
|
|
@@ -241,7 +278,416 @@ var SniceChat = (function (exports, snice) {
|
|
|
241
278
|
return _classThis;
|
|
242
279
|
})();
|
|
243
280
|
|
|
244
|
-
var
|
|
281
|
+
var markdownStyles = ":host{display:block;font-family:var(--snice-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif);contain:layout style paint;color:var(--snice-color-text,rgb(23 23 23));line-height:var(--snice-line-height-normal, 1.5);font-size:var(--snice-font-size-md, 1rem);word-wrap:break-word;overflow-wrap:break-word}.markdown-body{max-width:100%}.markdown-body h1,.markdown-body h2,.markdown-body h3,.markdown-body h4,.markdown-body h5,.markdown-body h6{font-family:var(--snice-font-family-display);color:var(--snice-color-text,rgb(23 23 23));font-weight:var(--snice-font-weight-semibold,600);line-height:1.25;margin-top:var(--snice-spacing-lg,1.5rem);margin-bottom:var(--snice-spacing-md,1rem)}.markdown-body h1{font-family:var(--snice-font-family-display);font-size:2rem;border-bottom:1px solid var(--snice-color-border,rgb(226 226 226));padding-bottom:var(--snice-spacing-xs,.5rem)}.markdown-body h2{font-family:var(--snice-font-family-display);font-size:1.5rem;border-bottom:1px solid var(--snice-color-border,rgb(226 226 226));padding-bottom:var(--snice-spacing-xs,.5rem)}.markdown-body h3{font-family:var(--snice-font-family-display);font-size:1.25rem}.markdown-body h4{font-family:var(--snice-font-family-display);font-size:1rem}.markdown-body h5{font-family:var(--snice-font-family-display);font-size:.875rem}.markdown-body h6{font-family:var(--snice-font-family-display);font-size:.875rem;color:var(--snice-color-text-tertiary,rgb(115 115 115))}.markdown-body p{margin-top:0;margin-bottom:var(--snice-spacing-md,1rem)}.markdown-body a{color:var(--snice-color-primary,rgb(37 99 235));text-decoration:none;cursor:pointer}.markdown-body a:hover{text-decoration:underline}.markdown-body strong{font-weight:var(--snice-font-weight-semibold,600)}.markdown-body em{font-style:italic}.markdown-body del{text-decoration:line-through;color:var(--snice-color-text-secondary,rgb(82 82 82))}.markdown-body ol,.markdown-body ul{margin-top:0;margin-bottom:var(--snice-spacing-md,1rem);padding-left:var(--snice-spacing-xl,2rem)}.markdown-body li{margin-bottom:var(--snice-spacing-2xs,.25rem)}.markdown-body li>ol,.markdown-body li>ul{margin-top:var(--snice-spacing-2xs,.25rem);margin-bottom:0}.markdown-body .task-list-item{list-style-type:none;margin-left:-1.5rem;padding-left:0}.markdown-body .task-list-item input[type=checkbox]{margin-right:var(--snice-spacing-xs,.5rem);vertical-align:middle}.markdown-body blockquote{margin:0 0 var(--snice-spacing-md,1rem) 0;padding:var(--snice-spacing-xs,.5rem) var(--snice-spacing-md,1rem);border-left:4px solid var(--snice-color-border,rgb(226 226 226));color:var(--snice-color-text-secondary,rgb(82 82 82));background:var(--snice-color-surface-container-high,rgb(252 251 249));border-radius:0 var(--snice-border-radius-md,.25rem) var(--snice-border-radius-md,.25rem) 0}.markdown-body blockquote>:last-child{margin-bottom:0}.markdown-body code{padding:.125rem .375rem;font-size:.875em;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);font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;white-space:nowrap}.markdown-body pre{margin-top:0;margin-bottom:var(--snice-spacing-md,1rem);padding: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-lg,.5rem);overflow-x:auto;font-size:.875rem;line-height:1.6}.markdown-body pre code{padding:0;background:0 0;border:none;border-radius:0;white-space:pre;font-size:inherit}.markdown-body table{width:100%;border-collapse:collapse;margin-bottom:var(--snice-spacing-md,1rem);font-size:var(--snice-font-size-sm, .875rem)}.markdown-body td,.markdown-body th{padding:var(--snice-spacing-xs,.5rem) var(--snice-spacing-sm,.75rem);border:1px solid var(--snice-color-border,rgb(226 226 226));text-align:left}.markdown-body th{background:var(--snice-color-surface-container-high,rgb(252 251 249));font-weight:var(--snice-font-weight-semibold,600)}.markdown-body tr:nth-child(2n){background:var(--snice-color-surface-container-high,rgb(252 251 249))}.markdown-body hr{border:none;border-top:1px solid var(--snice-color-border,rgb(226 226 226));margin:var(--snice-spacing-lg,1.5rem) 0}.markdown-body img{max-width:100%;height:auto;border-radius:var(--snice-border-radius-md,.25rem)}:host([theme=github]) .markdown-body h1{font-family:var(--snice-font-family-display);font-size:2em}:host([theme=github]) .markdown-body h2{font-family:var(--snice-font-family-display);font-size:1.5em}:host([theme=github]) .markdown-body h3{font-family:var(--snice-font-family-display);font-size:1.25em}:host([theme=github]) .markdown-body blockquote{border-left-color:var(--snice-color-text-tertiary,rgb(115 115 115));background:0 0}:host([theme=github]) .markdown-body pre{background:var(--snice-color-surface-container,rgb(246 248 250));color:var(--snice-color-text,rgb(36 41 47))}:host([theme=github]) .markdown-body code{background:var(--snice-color-surface-container,rgb(246 248 250));color:var(--snice-color-text,rgb(36 41 47))}";
|
|
282
|
+
|
|
283
|
+
// Sanitization: strip dangerous tags/attributes
|
|
284
|
+
const DANGEROUS_TAGS = /^(script|iframe|object|embed|form|input|button|select|textarea|link|meta|style|applet|base|basefont|bgsound|blink|body|frame|frameset|head|html|isindex|ilayer|layer|marquee|param|plaintext|title|xml)$/i;
|
|
285
|
+
const DANGEROUS_ATTRS = /^(on\w+|style|srcdoc|action|formaction|data-bind|xmlns)$/i;
|
|
286
|
+
const DANGEROUS_PROTOCOLS = /^(javascript|vbscript|data):/i;
|
|
287
|
+
function sanitizeHtml(html) {
|
|
288
|
+
// Pre-strip script/style tags before DOMParser to prevent execution in some environments
|
|
289
|
+
const preStripped = html.replace(/<(script|style)\b[^>]*>[\s\S]*?<\/\1>/gi, '').replace(/<(script|style)\b[^>]*\/?>/gi, '');
|
|
290
|
+
const parser = new DOMParser();
|
|
291
|
+
const doc = parser.parseFromString(preStripped, 'text/html');
|
|
292
|
+
const walk = (node) => {
|
|
293
|
+
const children = Array.from(node.children);
|
|
294
|
+
for (const child of children) {
|
|
295
|
+
if (DANGEROUS_TAGS.test(child.tagName)) {
|
|
296
|
+
child.remove();
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
const attrs = Array.from(child.attributes);
|
|
300
|
+
for (const attr of attrs) {
|
|
301
|
+
if (DANGEROUS_ATTRS.test(attr.name)) {
|
|
302
|
+
child.removeAttribute(attr.name);
|
|
303
|
+
}
|
|
304
|
+
if (attr.name === 'href' || attr.name === 'src') {
|
|
305
|
+
if (DANGEROUS_PROTOCOLS.test(attr.value.trim())) {
|
|
306
|
+
child.removeAttribute(attr.name);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
walk(child);
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
walk(doc.body);
|
|
314
|
+
return doc.body.innerHTML;
|
|
315
|
+
}
|
|
316
|
+
// Escape HTML special characters
|
|
317
|
+
function escapeHtml(str) {
|
|
318
|
+
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
319
|
+
}
|
|
320
|
+
// Lightweight GFM-compatible markdown parser
|
|
321
|
+
function parseMarkdown(md) {
|
|
322
|
+
if (!md)
|
|
323
|
+
return '';
|
|
324
|
+
let result = md;
|
|
325
|
+
// Normalize line endings
|
|
326
|
+
result = result.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
|
|
327
|
+
// Extract code blocks first to protect them from parsing
|
|
328
|
+
const codeBlocks = [];
|
|
329
|
+
result = result.replace(/```(\w*)\n([\s\S]*?)```/g, (_match, lang, code) => {
|
|
330
|
+
const escaped = escapeHtml(code.replace(/\n$/, ''));
|
|
331
|
+
const langAttr = lang ? ` class="language-${escapeHtml(lang)}"` : '';
|
|
332
|
+
codeBlocks.push(`<pre><code${langAttr}>${escaped}</code></pre>`);
|
|
333
|
+
return `\x00CB${codeBlocks.length - 1}\x00`;
|
|
334
|
+
});
|
|
335
|
+
// Extract inline code
|
|
336
|
+
const inlineCodes = [];
|
|
337
|
+
result = result.replace(/`([^`\n]+)`/g, (_match, code) => {
|
|
338
|
+
inlineCodes.push(`<code>${escapeHtml(code)}</code>`);
|
|
339
|
+
return `\x00IC${inlineCodes.length - 1}\x00`;
|
|
340
|
+
});
|
|
341
|
+
// Horizontal rules (before list processing)
|
|
342
|
+
result = result.replace(/^([-*_]){3,}\s*$/gm, '<hr>');
|
|
343
|
+
// Headings
|
|
344
|
+
result = result.replace(/^######\s+(.+)$/gm, '<h6>$1</h6>');
|
|
345
|
+
result = result.replace(/^#####\s+(.+)$/gm, '<h5>$1</h5>');
|
|
346
|
+
result = result.replace(/^####\s+(.+)$/gm, '<h4>$1</h4>');
|
|
347
|
+
result = result.replace(/^###\s+(.+)$/gm, '<h3>$1</h3>');
|
|
348
|
+
result = result.replace(/^##\s+(.+)$/gm, '<h2>$1</h2>');
|
|
349
|
+
result = result.replace(/^#\s+(.+)$/gm, '<h1>$1</h1>');
|
|
350
|
+
// Blockquotes
|
|
351
|
+
result = result.replace(/^((?:>\s?.*\n?)+)/gm, (match) => {
|
|
352
|
+
const content = match.replace(/^>\s?/gm, '').trim();
|
|
353
|
+
return `<blockquote>${content}</blockquote>`;
|
|
354
|
+
});
|
|
355
|
+
// Tables (GFM)
|
|
356
|
+
result = result.replace(/^(\|.+\|)\n(\|[-:\s|]+\|)\n((?:\|.+\|\n?)*)/gm, (_match, headerRow, _separator, bodyRows) => {
|
|
357
|
+
const headers = headerRow.split('|').filter((c) => c.trim()).map((c) => `<th>${c.trim()}</th>`).join('');
|
|
358
|
+
const rows = bodyRows.trim().split('\n').map((row) => {
|
|
359
|
+
const cells = row.split('|').filter((c) => c.trim()).map((c) => `<td>${c.trim()}</td>`).join('');
|
|
360
|
+
return `<tr>${cells}</tr>`;
|
|
361
|
+
}).join('');
|
|
362
|
+
return `<table><thead><tr>${headers}</tr></thead><tbody>${rows}</tbody></table>`;
|
|
363
|
+
});
|
|
364
|
+
// Task lists (before regular lists)
|
|
365
|
+
result = result.replace(/^(\s*)- \[x\]\s+(.+)$/gm, '$1<li class="task-list-item"><input type="checkbox" checked disabled> $2</li>');
|
|
366
|
+
result = result.replace(/^(\s*)- \[ \]\s+(.+)$/gm, '$1<li class="task-list-item"><input type="checkbox" disabled> $2</li>');
|
|
367
|
+
// Unordered lists
|
|
368
|
+
result = result.replace(/^((?:\s*[-*+]\s+.+\n?)+)/gm, (match) => {
|
|
369
|
+
const items = match.trim().split('\n').map(line => {
|
|
370
|
+
const content = line.replace(/^\s*[-*+]\s+/, '');
|
|
371
|
+
if (content.startsWith('<li class="task-list-item">'))
|
|
372
|
+
return content;
|
|
373
|
+
return `<li>${content}</li>`;
|
|
374
|
+
}).join('');
|
|
375
|
+
return `<ul>${items}</ul>`;
|
|
376
|
+
});
|
|
377
|
+
// Ordered lists
|
|
378
|
+
result = result.replace(/^((?:\s*\d+\.\s+.+\n?)+)/gm, (match) => {
|
|
379
|
+
const items = match.trim().split('\n').map(line => {
|
|
380
|
+
const content = line.replace(/^\s*\d+\.\s+/, '');
|
|
381
|
+
return `<li>${content}</li>`;
|
|
382
|
+
}).join('');
|
|
383
|
+
return `<ol>${items}</ol>`;
|
|
384
|
+
});
|
|
385
|
+
// Images — escape src attribute and alt text so payloads like
|
|
386
|
+
//  cannot break out of the attribute context.
|
|
387
|
+
result = result.replace(/!\[([^\]]*)\]\(([^)]+)\)/g, (_m, alt, src) => `<img src="${snice.escapeAttr(src)}" alt="${snice.escapeAttr(alt)}">`);
|
|
388
|
+
// Links — same escaping for href + text.
|
|
389
|
+
result = result.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_m, text, href) => `<a href="${snice.escapeAttr(href)}">${escapeHtml(text)}</a>`);
|
|
390
|
+
// Autolinks (GFM)
|
|
391
|
+
result = result.replace(/(^|[^"(])(https?:\/\/[^\s<>]+)/g, (_m, lead, url) => `${lead}<a href="${snice.escapeAttr(url)}">${escapeHtml(url)}</a>`);
|
|
392
|
+
// Bold and italic (process bold first)
|
|
393
|
+
result = result.replace(/\*\*\*(.+?)\*\*\*/g, '<strong><em>$1</em></strong>');
|
|
394
|
+
result = result.replace(/___(.+?)___/g, '<strong><em>$1</em></strong>');
|
|
395
|
+
result = result.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>');
|
|
396
|
+
result = result.replace(/__(.+?)__/g, '<strong>$1</strong>');
|
|
397
|
+
result = result.replace(/\*(.+?)\*/g, '<em>$1</em>');
|
|
398
|
+
result = result.replace(/_(.+?)_/g, '<em>$1</em>');
|
|
399
|
+
// Strikethrough (GFM)
|
|
400
|
+
result = result.replace(/~~(.+?)~~/g, '<del>$1</del>');
|
|
401
|
+
// Paragraphs: wrap standalone text lines
|
|
402
|
+
result = result.replace(/^(?!<[a-z/]|$|\x00)(.+)$/gm, '<p>$1</p>');
|
|
403
|
+
// Clean up double paragraphs / empty paragraphs
|
|
404
|
+
result = result.replace(/<p><\/p>/g, '');
|
|
405
|
+
result = result.replace(/(<\/(?:ul|ol|blockquote|table|pre|h[1-6]|hr)>)\s*<p>/g, '$1\n<p>');
|
|
406
|
+
// Restore inline codes
|
|
407
|
+
result = result.replace(/\x00IC(\d+)\x00/g, (_match, idx) => inlineCodes[parseInt(idx)]);
|
|
408
|
+
// Restore code blocks
|
|
409
|
+
result = result.replace(/(?:<p>)?\x00CB(\d+)\x00(?:<\/p>)?/g, (_match, idx) => codeBlocks[parseInt(idx)]);
|
|
410
|
+
return result.trim();
|
|
411
|
+
}
|
|
412
|
+
(() => {
|
|
413
|
+
let _classDecorators = [snice.element('snice-markdown')];
|
|
414
|
+
let _classDescriptor;
|
|
415
|
+
let _classExtraInitializers = [];
|
|
416
|
+
let _classThis;
|
|
417
|
+
let _classSuper = HTMLElement;
|
|
418
|
+
let _instanceExtraInitializers = [];
|
|
419
|
+
let _content_decorators;
|
|
420
|
+
let _content_initializers = [];
|
|
421
|
+
let _content_extraInitializers = [];
|
|
422
|
+
let _sanitize_decorators;
|
|
423
|
+
let _sanitize_initializers = [];
|
|
424
|
+
let _sanitize_extraInitializers = [];
|
|
425
|
+
let _theme_decorators;
|
|
426
|
+
let _theme_initializers = [];
|
|
427
|
+
let _theme_extraInitializers = [];
|
|
428
|
+
let _renderedHtml_decorators;
|
|
429
|
+
let _renderedHtml_initializers = [];
|
|
430
|
+
let _renderedHtml_extraInitializers = [];
|
|
431
|
+
let _componentStyles_decorators;
|
|
432
|
+
let _init_decorators;
|
|
433
|
+
let _handleSlotChange_decorators;
|
|
434
|
+
let _handleContentChange_decorators;
|
|
435
|
+
let _handleSanitizeChange_decorators;
|
|
436
|
+
let _handleLinkClick_decorators;
|
|
437
|
+
let _emitRender_decorators;
|
|
438
|
+
let _emitLinkClick_decorators;
|
|
439
|
+
let _renderContent_decorators;
|
|
440
|
+
(class extends _classSuper {
|
|
441
|
+
static { _classThis = this; }
|
|
442
|
+
static {
|
|
443
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
444
|
+
_content_decorators = [snice.property({ attribute: false })];
|
|
445
|
+
_sanitize_decorators = [snice.property({ type: Boolean })];
|
|
446
|
+
_theme_decorators = [snice.property()];
|
|
447
|
+
_renderedHtml_decorators = [snice.property({ attribute: false })];
|
|
448
|
+
_componentStyles_decorators = [snice.styles()];
|
|
449
|
+
_init_decorators = [snice.ready()];
|
|
450
|
+
_handleSlotChange_decorators = [snice.on('slotchange', { target: 'slot' })];
|
|
451
|
+
_handleContentChange_decorators = [snice.watch('content')];
|
|
452
|
+
_handleSanitizeChange_decorators = [snice.watch('sanitize')];
|
|
453
|
+
_handleLinkClick_decorators = [snice.on('click', { target: 'a' })];
|
|
454
|
+
_emitRender_decorators = [snice.dispatch('markdown-render', { bubbles: true, composed: true })];
|
|
455
|
+
_emitLinkClick_decorators = [snice.dispatch('link-click', { bubbles: true, composed: true })];
|
|
456
|
+
_renderContent_decorators = [snice.render()];
|
|
457
|
+
__esDecorate(this, null, _componentStyles_decorators, { kind: "method", name: "componentStyles", static: false, private: false, access: { has: obj => "componentStyles" in obj, get: obj => obj.componentStyles }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
458
|
+
__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);
|
|
459
|
+
__esDecorate(this, null, _handleSlotChange_decorators, { kind: "method", name: "handleSlotChange", static: false, private: false, access: { has: obj => "handleSlotChange" in obj, get: obj => obj.handleSlotChange }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
460
|
+
__esDecorate(this, null, _handleContentChange_decorators, { kind: "method", name: "handleContentChange", static: false, private: false, access: { has: obj => "handleContentChange" in obj, get: obj => obj.handleContentChange }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
461
|
+
__esDecorate(this, null, _handleSanitizeChange_decorators, { kind: "method", name: "handleSanitizeChange", static: false, private: false, access: { has: obj => "handleSanitizeChange" in obj, get: obj => obj.handleSanitizeChange }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
462
|
+
__esDecorate(this, null, _handleLinkClick_decorators, { kind: "method", name: "handleLinkClick", static: false, private: false, access: { has: obj => "handleLinkClick" in obj, get: obj => obj.handleLinkClick }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
463
|
+
__esDecorate(this, null, _emitRender_decorators, { kind: "method", name: "emitRender", static: false, private: false, access: { has: obj => "emitRender" in obj, get: obj => obj.emitRender }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
464
|
+
__esDecorate(this, null, _emitLinkClick_decorators, { kind: "method", name: "emitLinkClick", static: false, private: false, access: { has: obj => "emitLinkClick" in obj, get: obj => obj.emitLinkClick }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
465
|
+
__esDecorate(this, null, _renderContent_decorators, { kind: "method", name: "renderContent", static: false, private: false, access: { has: obj => "renderContent" in obj, get: obj => obj.renderContent }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
466
|
+
__esDecorate(null, null, _content_decorators, { kind: "field", name: "content", static: false, private: false, access: { has: obj => "content" in obj, get: obj => obj.content, set: (obj, value) => { obj.content = value; } }, metadata: _metadata }, _content_initializers, _content_extraInitializers);
|
|
467
|
+
__esDecorate(null, null, _sanitize_decorators, { kind: "field", name: "sanitize", static: false, private: false, access: { has: obj => "sanitize" in obj, get: obj => obj.sanitize, set: (obj, value) => { obj.sanitize = value; } }, metadata: _metadata }, _sanitize_initializers, _sanitize_extraInitializers);
|
|
468
|
+
__esDecorate(null, null, _theme_decorators, { kind: "field", name: "theme", static: false, private: false, access: { has: obj => "theme" in obj, get: obj => obj.theme, set: (obj, value) => { obj.theme = value; } }, metadata: _metadata }, _theme_initializers, _theme_extraInitializers);
|
|
469
|
+
__esDecorate(null, null, _renderedHtml_decorators, { kind: "field", name: "renderedHtml", static: false, private: false, access: { has: obj => "renderedHtml" in obj, get: obj => obj.renderedHtml, set: (obj, value) => { obj.renderedHtml = value; } }, metadata: _metadata }, _renderedHtml_initializers, _renderedHtml_extraInitializers);
|
|
470
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
471
|
+
_classThis = _classDescriptor.value;
|
|
472
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
473
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
474
|
+
}
|
|
475
|
+
componentStyles() {
|
|
476
|
+
return snice.css /*css*/ `${markdownStyles}`;
|
|
477
|
+
}
|
|
478
|
+
init() {
|
|
479
|
+
if (!this.content) {
|
|
480
|
+
this.readSlottedContent();
|
|
481
|
+
}
|
|
482
|
+
if (this.content) {
|
|
483
|
+
this.renderMarkdown();
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
handleSlotChange() {
|
|
487
|
+
this.readSlottedContent();
|
|
488
|
+
}
|
|
489
|
+
readSlottedContent() {
|
|
490
|
+
const text = this.textContent?.trim();
|
|
491
|
+
if (text) {
|
|
492
|
+
this.content = text;
|
|
493
|
+
this.renderMarkdown();
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
handleContentChange() {
|
|
497
|
+
this.renderMarkdown();
|
|
498
|
+
}
|
|
499
|
+
handleSanitizeChange() {
|
|
500
|
+
this.renderMarkdown();
|
|
501
|
+
}
|
|
502
|
+
renderMarkdown() {
|
|
503
|
+
let parsed = parseMarkdown(this.content);
|
|
504
|
+
if (this.sanitize) {
|
|
505
|
+
parsed = sanitizeHtml(parsed);
|
|
506
|
+
}
|
|
507
|
+
this.renderedHtml = parsed;
|
|
508
|
+
this.emitRender();
|
|
509
|
+
}
|
|
510
|
+
handleLinkClick(e) {
|
|
511
|
+
const anchor = e.target;
|
|
512
|
+
if (anchor?.tagName === 'A') {
|
|
513
|
+
e.preventDefault();
|
|
514
|
+
this.emitLinkClick(anchor.getAttribute('href') || '', anchor.textContent || '');
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
emitRender() {
|
|
518
|
+
return { html: this.renderedHtml };
|
|
519
|
+
}
|
|
520
|
+
emitLinkClick(href, text) {
|
|
521
|
+
return { href, text };
|
|
522
|
+
}
|
|
523
|
+
/** Set content programmatically and re-render */
|
|
524
|
+
setContent(markdown) {
|
|
525
|
+
this.content = markdown;
|
|
526
|
+
this.renderMarkdown();
|
|
527
|
+
}
|
|
528
|
+
renderContent() {
|
|
529
|
+
return snice.html /*html*/ `
|
|
530
|
+
<slot style="display:none"></slot>
|
|
531
|
+
<div class="markdown-body" part="base">${snice.unsafeHTML(this.renderedHtml)}</div>
|
|
532
|
+
`;
|
|
533
|
+
}
|
|
534
|
+
constructor() {
|
|
535
|
+
super(...arguments);
|
|
536
|
+
// Reactive so parents can drive it via a .content template binding — a
|
|
537
|
+
// plain field would render once and go stale on later assignments.
|
|
538
|
+
this.content = (__runInitializers(this, _instanceExtraInitializers), __runInitializers(this, _content_initializers, ''));
|
|
539
|
+
this.sanitize = (__runInitializers(this, _content_extraInitializers), __runInitializers(this, _sanitize_initializers, true));
|
|
540
|
+
this.theme = (__runInitializers(this, _sanitize_extraInitializers), __runInitializers(this, _theme_initializers, 'default'));
|
|
541
|
+
this.renderedHtml = (__runInitializers(this, _theme_extraInitializers), __runInitializers(this, _renderedHtml_initializers, ''));
|
|
542
|
+
__runInitializers(this, _renderedHtml_extraInitializers);
|
|
543
|
+
}
|
|
544
|
+
});
|
|
545
|
+
return _classThis;
|
|
546
|
+
})();
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* snice-chat-message - declarative message authoring for snice-chat.
|
|
550
|
+
*
|
|
551
|
+
* A config-carrier element (same pattern as snice-column): it renders only a
|
|
552
|
+
* <slot> and exposes getMessageDefinition() so the parent snice-chat can read
|
|
553
|
+
* its props + slotted body as a ChatMessage. It does not render the message
|
|
554
|
+
* itself — the parent owns all rendering and the styling part surface.
|
|
555
|
+
*
|
|
556
|
+
* @element snice-chat-message
|
|
557
|
+
*/
|
|
558
|
+
(() => {
|
|
559
|
+
let _classDecorators = [snice.element('snice-chat-message')];
|
|
560
|
+
let _classDescriptor;
|
|
561
|
+
let _classExtraInitializers = [];
|
|
562
|
+
let _classThis;
|
|
563
|
+
let _classSuper = HTMLElement;
|
|
564
|
+
let _instanceExtraInitializers = [];
|
|
565
|
+
let _author_decorators;
|
|
566
|
+
let _author_initializers = [];
|
|
567
|
+
let _author_extraInitializers = [];
|
|
568
|
+
let _avatar_decorators;
|
|
569
|
+
let _avatar_initializers = [];
|
|
570
|
+
let _avatar_extraInitializers = [];
|
|
571
|
+
let _type_decorators;
|
|
572
|
+
let _type_initializers = [];
|
|
573
|
+
let _type_extraInitializers = [];
|
|
574
|
+
let _format_decorators;
|
|
575
|
+
let _format_initializers = [];
|
|
576
|
+
let _format_extraInitializers = [];
|
|
577
|
+
let _edited_decorators;
|
|
578
|
+
let _edited_initializers = [];
|
|
579
|
+
let _edited_extraInitializers = [];
|
|
580
|
+
let _authorColor_decorators;
|
|
581
|
+
let _authorColor_initializers = [];
|
|
582
|
+
let _authorColor_extraInitializers = [];
|
|
583
|
+
let _reactions_decorators;
|
|
584
|
+
let _reactions_initializers = [];
|
|
585
|
+
let _reactions_extraInitializers = [];
|
|
586
|
+
let _attachment_decorators;
|
|
587
|
+
let _attachment_initializers = [];
|
|
588
|
+
let _attachment_extraInitializers = [];
|
|
589
|
+
let _thread_decorators;
|
|
590
|
+
let _thread_initializers = [];
|
|
591
|
+
let _thread_extraInitializers = [];
|
|
592
|
+
let _render_decorators;
|
|
593
|
+
(class extends _classSuper {
|
|
594
|
+
static { _classThis = this; }
|
|
595
|
+
static {
|
|
596
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
597
|
+
_author_decorators = [snice.property()];
|
|
598
|
+
_avatar_decorators = [snice.property()];
|
|
599
|
+
_type_decorators = [snice.property()];
|
|
600
|
+
_format_decorators = [snice.property()];
|
|
601
|
+
_edited_decorators = [snice.property({ type: Boolean })];
|
|
602
|
+
_authorColor_decorators = [snice.property({ attribute: 'author-color' })];
|
|
603
|
+
_reactions_decorators = [snice.property({ type: Array, attribute: false })];
|
|
604
|
+
_attachment_decorators = [snice.property({ type: Object, attribute: false })];
|
|
605
|
+
_thread_decorators = [snice.property({ type: Array, attribute: false })];
|
|
606
|
+
_render_decorators = [snice.render()];
|
|
607
|
+
__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);
|
|
608
|
+
__esDecorate(null, null, _author_decorators, { kind: "field", name: "author", static: false, private: false, access: { has: obj => "author" in obj, get: obj => obj.author, set: (obj, value) => { obj.author = value; } }, metadata: _metadata }, _author_initializers, _author_extraInitializers);
|
|
609
|
+
__esDecorate(null, null, _avatar_decorators, { kind: "field", name: "avatar", static: false, private: false, access: { has: obj => "avatar" in obj, get: obj => obj.avatar, set: (obj, value) => { obj.avatar = value; } }, metadata: _metadata }, _avatar_initializers, _avatar_extraInitializers);
|
|
610
|
+
__esDecorate(null, null, _type_decorators, { kind: "field", name: "type", static: false, private: false, access: { has: obj => "type" in obj, get: obj => obj.type, set: (obj, value) => { obj.type = value; } }, metadata: _metadata }, _type_initializers, _type_extraInitializers);
|
|
611
|
+
__esDecorate(null, null, _format_decorators, { kind: "field", name: "format", static: false, private: false, access: { has: obj => "format" in obj, get: obj => obj.format, set: (obj, value) => { obj.format = value; } }, metadata: _metadata }, _format_initializers, _format_extraInitializers);
|
|
612
|
+
__esDecorate(null, null, _edited_decorators, { kind: "field", name: "edited", static: false, private: false, access: { has: obj => "edited" in obj, get: obj => obj.edited, set: (obj, value) => { obj.edited = value; } }, metadata: _metadata }, _edited_initializers, _edited_extraInitializers);
|
|
613
|
+
__esDecorate(null, null, _authorColor_decorators, { kind: "field", name: "authorColor", static: false, private: false, access: { has: obj => "authorColor" in obj, get: obj => obj.authorColor, set: (obj, value) => { obj.authorColor = value; } }, metadata: _metadata }, _authorColor_initializers, _authorColor_extraInitializers);
|
|
614
|
+
__esDecorate(null, null, _reactions_decorators, { kind: "field", name: "reactions", static: false, private: false, access: { has: obj => "reactions" in obj, get: obj => obj.reactions, set: (obj, value) => { obj.reactions = value; } }, metadata: _metadata }, _reactions_initializers, _reactions_extraInitializers);
|
|
615
|
+
__esDecorate(null, null, _attachment_decorators, { kind: "field", name: "attachment", static: false, private: false, access: { has: obj => "attachment" in obj, get: obj => obj.attachment, set: (obj, value) => { obj.attachment = value; } }, metadata: _metadata }, _attachment_initializers, _attachment_extraInitializers);
|
|
616
|
+
__esDecorate(null, null, _thread_decorators, { kind: "field", name: "thread", static: false, private: false, access: { has: obj => "thread" in obj, get: obj => obj.thread, set: (obj, value) => { obj.thread = value; } }, metadata: _metadata }, _thread_initializers, _thread_extraInitializers);
|
|
617
|
+
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
618
|
+
_classThis = _classDescriptor.value;
|
|
619
|
+
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
620
|
+
__runInitializers(_classThis, _classExtraInitializers);
|
|
621
|
+
}
|
|
622
|
+
render() {
|
|
623
|
+
return snice.html /*html*/ `<slot></slot>`;
|
|
624
|
+
}
|
|
625
|
+
/** Serialize this element into a ChatMessage for the parent chat. */
|
|
626
|
+
getMessageDefinition() {
|
|
627
|
+
const timestampAttr = this.getAttribute('timestamp');
|
|
628
|
+
const definition = {
|
|
629
|
+
id: '',
|
|
630
|
+
type: this.type,
|
|
631
|
+
content: (this.textContent ?? '').trim(),
|
|
632
|
+
author: this.author,
|
|
633
|
+
timestamp: timestampAttr ? new Date(timestampAttr) : new Date(),
|
|
634
|
+
edited: this.edited,
|
|
635
|
+
};
|
|
636
|
+
if (this.format)
|
|
637
|
+
definition.format = this.format;
|
|
638
|
+
if (this.avatar)
|
|
639
|
+
definition.avatar = this.avatar;
|
|
640
|
+
if (this.authorColor)
|
|
641
|
+
definition.authorColor = this.authorColor;
|
|
642
|
+
if (this.reactions)
|
|
643
|
+
definition.reactions = this.reactions;
|
|
644
|
+
if (this.attachment)
|
|
645
|
+
definition.attachment = this.attachment;
|
|
646
|
+
if (this.thread)
|
|
647
|
+
definition.thread = this.thread;
|
|
648
|
+
return definition;
|
|
649
|
+
}
|
|
650
|
+
constructor() {
|
|
651
|
+
super(...arguments);
|
|
652
|
+
this.author = (__runInitializers(this, _instanceExtraInitializers), __runInitializers(this, _author_initializers, ''));
|
|
653
|
+
this.avatar = (__runInitializers(this, _author_extraInitializers), __runInitializers(this, _avatar_initializers, ''));
|
|
654
|
+
this.type = (__runInitializers(this, _avatar_extraInitializers), __runInitializers(this, _type_initializers, 'text'));
|
|
655
|
+
// No default: undefined defers to the chat-level `markdown` flag, exactly
|
|
656
|
+
// like an imperative addMessage() without a format.
|
|
657
|
+
this.format = (__runInitializers(this, _type_extraInitializers), __runInitializers(this, _format_initializers, void 0));
|
|
658
|
+
this.edited = (__runInitializers(this, _format_extraInitializers), __runInitializers(this, _edited_initializers, false));
|
|
659
|
+
this.authorColor = (__runInitializers(this, _edited_extraInitializers), __runInitializers(this, _authorColor_initializers, ''));
|
|
660
|
+
// Rich fields have no attribute form — set them as JS properties.
|
|
661
|
+
this.reactions = (__runInitializers(this, _authorColor_extraInitializers), __runInitializers(this, _reactions_initializers, void 0));
|
|
662
|
+
this.attachment = (__runInitializers(this, _reactions_extraInitializers), __runInitializers(this, _attachment_initializers, void 0));
|
|
663
|
+
this.thread = (__runInitializers(this, _attachment_extraInitializers), __runInitializers(this, _thread_initializers, void 0));
|
|
664
|
+
__runInitializers(this, _thread_extraInitializers);
|
|
665
|
+
}
|
|
666
|
+
});
|
|
667
|
+
return _classThis;
|
|
668
|
+
})();
|
|
669
|
+
|
|
670
|
+
/**
|
|
671
|
+
* Types for the snice-chat component
|
|
672
|
+
*/
|
|
673
|
+
/**
|
|
674
|
+
* How a message body is rendered
|
|
675
|
+
*/
|
|
676
|
+
var MessageFormat;
|
|
677
|
+
(function (MessageFormat) {
|
|
678
|
+
MessageFormat["Text"] = "text";
|
|
679
|
+
MessageFormat["Markdown"] = "markdown";
|
|
680
|
+
})(MessageFormat || (MessageFormat = {}));
|
|
681
|
+
/**
|
|
682
|
+
* Built-in message layout for snice-chat
|
|
683
|
+
*/
|
|
684
|
+
var ChatLayout;
|
|
685
|
+
(function (ChatLayout) {
|
|
686
|
+
ChatLayout["Default"] = "default";
|
|
687
|
+
ChatLayout["Bubbles"] = "bubbles";
|
|
688
|
+
})(ChatLayout || (ChatLayout = {}));
|
|
689
|
+
|
|
690
|
+
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))}";
|
|
245
691
|
|
|
246
692
|
/**
|
|
247
693
|
* Generate unique ID
|
|
@@ -279,6 +725,26 @@ var SniceChat = (function (exports, snice) {
|
|
|
279
725
|
.toUpperCase()
|
|
280
726
|
.substring(0, 2);
|
|
281
727
|
}
|
|
728
|
+
/**
|
|
729
|
+
* Stable color for an author name: hash → one of the 8 accent slots. Returns a
|
|
730
|
+
* theme accent var with the shared concrete fallback.
|
|
731
|
+
*/
|
|
732
|
+
function autoAuthorColor(name) {
|
|
733
|
+
let hash = 0;
|
|
734
|
+
for (let i = 0; i < name.length; i++) {
|
|
735
|
+
hash = (hash * 31 + name.charCodeAt(i)) >>> 0;
|
|
736
|
+
}
|
|
737
|
+
const slot = (hash % 8) + 1;
|
|
738
|
+
return `var(--snice-color-accent-${slot}, ${FALLBACK_ACCENTS[slot - 1]})`;
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* Author colors ride on message data, so they can come from a backend. A CSS
|
|
742
|
+
* color never needs `;`, `{`, or `}` — reject values that could smuggle extra
|
|
743
|
+
* declarations into the inline style attribute.
|
|
744
|
+
*/
|
|
745
|
+
function isSafeCssColor(value) {
|
|
746
|
+
return !/[;{}]/.test(value);
|
|
747
|
+
}
|
|
282
748
|
/**
|
|
283
749
|
* snice-chat - Chat interface component
|
|
284
750
|
*
|
|
@@ -290,7 +756,6 @@ var SniceChat = (function (exports, snice) {
|
|
|
290
756
|
* @fires {CustomEvent<{ messageId: string; newContent: string }>} message-edit - Fires when editing a message
|
|
291
757
|
* @fires {CustomEvent<{ messageId: string }>} message-delete - Fires when deleting a message
|
|
292
758
|
* @fires {CustomEvent<{ messageId: string; emoji: string }>} message-react - Fires when reacting to a message
|
|
293
|
-
* @fires {CustomEvent<{ messageId: string }>} message-thread - Fires when starting a thread
|
|
294
759
|
* @fires {CustomEvent<{}>} typing-start - Fires when user starts typing
|
|
295
760
|
* @fires {CustomEvent<{}>} typing-stop - Fires when user stops typing
|
|
296
761
|
*/
|
|
@@ -325,23 +790,53 @@ var SniceChat = (function (exports, snice) {
|
|
|
325
790
|
let _showTimestamps_decorators;
|
|
326
791
|
let _showTimestamps_initializers = [];
|
|
327
792
|
let _showTimestamps_extraInitializers = [];
|
|
793
|
+
let _authorColors_decorators;
|
|
794
|
+
let _authorColors_initializers = [];
|
|
795
|
+
let _authorColors_extraInitializers = [];
|
|
796
|
+
let _colorAuthors_decorators;
|
|
797
|
+
let _colorAuthors_initializers = [];
|
|
798
|
+
let _colorAuthors_extraInitializers = [];
|
|
799
|
+
let _markdown_decorators;
|
|
800
|
+
let _markdown_initializers = [];
|
|
801
|
+
let _markdown_extraInitializers = [];
|
|
802
|
+
let _layout_decorators;
|
|
803
|
+
let _layout_initializers = [];
|
|
804
|
+
let _layout_extraInitializers = [];
|
|
805
|
+
let _editingId_decorators;
|
|
806
|
+
let _editingId_initializers = [];
|
|
807
|
+
let _editingId_extraInitializers = [];
|
|
808
|
+
let _confirmingDeleteId_decorators;
|
|
809
|
+
let _confirmingDeleteId_initializers = [];
|
|
810
|
+
let _confirmingDeleteId_extraInitializers = [];
|
|
328
811
|
let _messagesArea_decorators;
|
|
329
812
|
let _messagesArea_initializers = [];
|
|
330
813
|
let _messagesArea_extraInitializers = [];
|
|
331
814
|
let _inputField_decorators;
|
|
332
815
|
let _inputField_initializers = [];
|
|
333
816
|
let _inputField_extraInitializers = [];
|
|
817
|
+
let _editField_decorators;
|
|
818
|
+
let _editField_initializers = [];
|
|
819
|
+
let _editField_extraInitializers = [];
|
|
820
|
+
let _editBox_decorators;
|
|
821
|
+
let _editBox_initializers = [];
|
|
822
|
+
let _editBox_extraInitializers = [];
|
|
823
|
+
let _confirmBox_decorators;
|
|
824
|
+
let _confirmBox_initializers = [];
|
|
825
|
+
let _confirmBox_extraInitializers = [];
|
|
334
826
|
let _styles_decorators;
|
|
335
827
|
let _init_decorators;
|
|
828
|
+
let _onSlottedMessagesChanged_decorators;
|
|
829
|
+
let _onSlottedMessageAttributesChanged_decorators;
|
|
336
830
|
let _cleanup_decorators;
|
|
337
831
|
let _messagesChanged_decorators;
|
|
338
832
|
let _emitMessageSend_decorators;
|
|
339
833
|
let _emitMessageEdit_decorators;
|
|
340
834
|
let _emitMessageDelete_decorators;
|
|
341
835
|
let _emitMessageReact_decorators;
|
|
342
|
-
let _emitMessageThread_decorators;
|
|
343
836
|
let _emitTypingStart_decorators;
|
|
344
837
|
let _emitTypingStop_decorators;
|
|
838
|
+
let _focusEditField_decorators;
|
|
839
|
+
let _revealDeleteConfirm_decorators;
|
|
345
840
|
let _render_decorators;
|
|
346
841
|
(class extends _classSuper {
|
|
347
842
|
static { _classThis = this; }
|
|
@@ -355,11 +850,28 @@ var SniceChat = (function (exports, snice) {
|
|
|
355
850
|
this.showTyping = (__runInitializers(this, _allowFiles_extraInitializers), __runInitializers(this, _showTyping_initializers, true));
|
|
356
851
|
this.showAvatars = (__runInitializers(this, _showTyping_extraInitializers), __runInitializers(this, _showAvatars_initializers, true));
|
|
357
852
|
this.showTimestamps = (__runInitializers(this, _showAvatars_extraInitializers), __runInitializers(this, _showTimestamps_initializers, true));
|
|
358
|
-
this.
|
|
853
|
+
this.authorColors = (__runInitializers(this, _showTimestamps_extraInitializers), __runInitializers(this, _authorColors_initializers, {}));
|
|
854
|
+
this.colorAuthors = (__runInitializers(this, _authorColors_extraInitializers), __runInitializers(this, _colorAuthors_initializers, false));
|
|
855
|
+
this.markdown = (__runInitializers(this, _colorAuthors_extraInitializers), __runInitializers(this, _markdown_initializers, false));
|
|
856
|
+
this.layout = (__runInitializers(this, _markdown_extraInitializers), __runInitializers(this, _layout_initializers, ChatLayout.Default));
|
|
857
|
+
// Internal reactive state: id of the message currently being edited inline.
|
|
858
|
+
this.editingId = (__runInitializers(this, _layout_extraInitializers), __runInitializers(this, _editingId_initializers, null));
|
|
859
|
+
// Internal reactive state: id of the message pending inline delete-confirm.
|
|
860
|
+
this.confirmingDeleteId = (__runInitializers(this, _editingId_extraInitializers), __runInitializers(this, _confirmingDeleteId_initializers, null));
|
|
861
|
+
this.messagesArea = (__runInitializers(this, _confirmingDeleteId_extraInitializers), __runInitializers(this, _messagesArea_initializers, void 0));
|
|
359
862
|
this.inputField = (__runInitializers(this, _messagesArea_extraInitializers), __runInitializers(this, _inputField_initializers, void 0));
|
|
360
|
-
this.
|
|
863
|
+
this.editField = (__runInitializers(this, _inputField_extraInitializers), __runInitializers(this, _editField_initializers, void 0));
|
|
864
|
+
this.editBox = (__runInitializers(this, _editField_extraInitializers), __runInitializers(this, _editBox_initializers, void 0));
|
|
865
|
+
this.confirmBox = (__runInitializers(this, _editBox_extraInitializers), __runInitializers(this, _confirmBox_initializers, void 0));
|
|
866
|
+
this.typingIndicators = (__runInitializers(this, _confirmBox_extraInitializers), new Map());
|
|
361
867
|
this.typingTimeout = null;
|
|
362
868
|
this.fileInput = null;
|
|
869
|
+
// Element → stable message id, so re-ingesting doesn't mint new ids and
|
|
870
|
+
// orphan reactions/edit state keyed to the old ones.
|
|
871
|
+
this.slotMessageIds = new WeakMap();
|
|
872
|
+
// Every id ever minted for a slot element, so a removed slot child isn't
|
|
873
|
+
// misclassified as an imperative message and resurrected on re-ingest.
|
|
874
|
+
this.mintedSlotIds = new Set();
|
|
363
875
|
this.handleKeyDown = (e) => {
|
|
364
876
|
const target = e.target;
|
|
365
877
|
if (target !== this.inputField)
|
|
@@ -380,31 +892,46 @@ var SniceChat = (function (exports, snice) {
|
|
|
380
892
|
_showTyping_decorators = [snice.property({ type: Boolean, attribute: 'show-typing' })];
|
|
381
893
|
_showAvatars_decorators = [snice.property({ type: Boolean, attribute: 'show-avatars' })];
|
|
382
894
|
_showTimestamps_decorators = [snice.property({ type: Boolean, attribute: 'show-timestamps' })];
|
|
895
|
+
_authorColors_decorators = [snice.property({ type: Object, attribute: false })];
|
|
896
|
+
_colorAuthors_decorators = [snice.property({ type: Boolean, attribute: 'color-authors' })];
|
|
897
|
+
_markdown_decorators = [snice.property({ type: Boolean })];
|
|
898
|
+
_layout_decorators = [snice.property()];
|
|
899
|
+
_editingId_decorators = [snice.property({ attribute: false })];
|
|
900
|
+
_confirmingDeleteId_decorators = [snice.property({ attribute: false })];
|
|
383
901
|
_messagesArea_decorators = [snice.query('.messages-area')];
|
|
384
902
|
_inputField_decorators = [snice.query('.input-field')];
|
|
903
|
+
_editField_decorators = [snice.query('.edit-field')];
|
|
904
|
+
_editBox_decorators = [snice.query('.message-edit')];
|
|
905
|
+
_confirmBox_decorators = [snice.query('.message-confirm')];
|
|
385
906
|
_styles_decorators = [snice.styles()];
|
|
386
907
|
_init_decorators = [snice.ready()];
|
|
908
|
+
_onSlottedMessagesChanged_decorators = [snice.observe('mutation:childList')];
|
|
909
|
+
_onSlottedMessageAttributesChanged_decorators = [snice.observe('mutation:attributes', { subtree: true })];
|
|
387
910
|
_cleanup_decorators = [snice.dispose()];
|
|
388
911
|
_messagesChanged_decorators = [snice.watch('messages')];
|
|
389
912
|
_emitMessageSend_decorators = [snice.dispatch('message-send', { bubbles: true, composed: true })];
|
|
390
913
|
_emitMessageEdit_decorators = [snice.dispatch('message-edit', { bubbles: true, composed: true })];
|
|
391
914
|
_emitMessageDelete_decorators = [snice.dispatch('message-delete', { bubbles: true, composed: true })];
|
|
392
915
|
_emitMessageReact_decorators = [snice.dispatch('message-react', { bubbles: true, composed: true })];
|
|
393
|
-
_emitMessageThread_decorators = [snice.dispatch('message-thread', { bubbles: true, composed: true })];
|
|
394
916
|
_emitTypingStart_decorators = [snice.dispatch('typing-start', { bubbles: true, composed: true })];
|
|
395
917
|
_emitTypingStop_decorators = [snice.dispatch('typing-stop', { bubbles: true, composed: true })];
|
|
918
|
+
_focusEditField_decorators = [snice.watch('editingId')];
|
|
919
|
+
_revealDeleteConfirm_decorators = [snice.watch('confirmingDeleteId')];
|
|
396
920
|
_render_decorators = [snice.render()];
|
|
397
921
|
__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);
|
|
398
922
|
__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);
|
|
923
|
+
__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);
|
|
924
|
+
__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);
|
|
399
925
|
__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);
|
|
400
926
|
__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);
|
|
401
927
|
__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);
|
|
402
928
|
__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);
|
|
403
929
|
__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);
|
|
404
930
|
__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);
|
|
405
|
-
__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);
|
|
406
931
|
__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);
|
|
407
932
|
__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);
|
|
933
|
+
__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);
|
|
934
|
+
__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);
|
|
408
935
|
__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);
|
|
409
936
|
__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);
|
|
410
937
|
__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);
|
|
@@ -414,8 +941,17 @@ var SniceChat = (function (exports, snice) {
|
|
|
414
941
|
__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);
|
|
415
942
|
__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);
|
|
416
943
|
__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);
|
|
944
|
+
__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);
|
|
945
|
+
__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);
|
|
946
|
+
__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);
|
|
947
|
+
__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);
|
|
948
|
+
__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);
|
|
949
|
+
__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);
|
|
417
950
|
__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);
|
|
418
951
|
__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);
|
|
952
|
+
__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);
|
|
953
|
+
__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);
|
|
954
|
+
__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);
|
|
419
955
|
__esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
|
|
420
956
|
_classThis = _classDescriptor.value;
|
|
421
957
|
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
@@ -426,6 +962,50 @@ var SniceChat = (function (exports, snice) {
|
|
|
426
962
|
}
|
|
427
963
|
init() {
|
|
428
964
|
this.addEventListener('keydown', this.handleKeyDown);
|
|
965
|
+
this.ingestSlottedMessages();
|
|
966
|
+
}
|
|
967
|
+
// Declarative dual-API: read slotted <snice-chat-message> children as the
|
|
968
|
+
// messages source. An empty slot leaves the array untouched. Mirrors
|
|
969
|
+
// snice-table / snice-column. Slotted messages keep a stable id across
|
|
970
|
+
// re-ingests (keyed per element), runtime state (reactions, inline edits)
|
|
971
|
+
// survives, and imperatively-added messages are appended after the slot set.
|
|
972
|
+
onSlottedMessagesChanged() {
|
|
973
|
+
this.ingestSlottedMessages();
|
|
974
|
+
}
|
|
975
|
+
onSlottedMessageAttributesChanged() {
|
|
976
|
+
this.ingestSlottedMessages();
|
|
977
|
+
}
|
|
978
|
+
ingestSlottedMessages() {
|
|
979
|
+
const els = Array.from(this.querySelectorAll('snice-chat-message'));
|
|
980
|
+
if (els.length === 0)
|
|
981
|
+
return;
|
|
982
|
+
const existingById = new Map(this.messages.map((m) => [m.id, m]));
|
|
983
|
+
const slotMessages = els.map((el) => {
|
|
984
|
+
let id = this.slotMessageIds.get(el);
|
|
985
|
+
if (!id) {
|
|
986
|
+
id = generateId();
|
|
987
|
+
this.slotMessageIds.set(el, id);
|
|
988
|
+
this.mintedSlotIds.add(id);
|
|
989
|
+
}
|
|
990
|
+
const definition = { ...el.getMessageDefinition(), id };
|
|
991
|
+
const existing = existingById.get(id);
|
|
992
|
+
if (!existing)
|
|
993
|
+
return definition;
|
|
994
|
+
// Runtime state outranks the (possibly stale) light DOM: keep reactions
|
|
995
|
+
// accumulated via the UI unless the element declares its own, and keep
|
|
996
|
+
// an inline edit's content over the original slotted text.
|
|
997
|
+
if (!definition.reactions && existing.reactions)
|
|
998
|
+
definition.reactions = existing.reactions;
|
|
999
|
+
if (existing.edited && !definition.edited) {
|
|
1000
|
+
definition.content = existing.content;
|
|
1001
|
+
definition.edited = true;
|
|
1002
|
+
}
|
|
1003
|
+
return definition;
|
|
1004
|
+
});
|
|
1005
|
+
// Imperatively-added messages (addMessage) are not backed by an element;
|
|
1006
|
+
// keep them, appended after the slot set.
|
|
1007
|
+
const imperative = this.messages.filter((m) => !this.mintedSlotIds.has(m.id));
|
|
1008
|
+
this.messages = [...slotMessages, ...imperative];
|
|
429
1009
|
}
|
|
430
1010
|
cleanup() {
|
|
431
1011
|
this.removeEventListener('keydown', this.handleKeyDown);
|
|
@@ -433,9 +1013,13 @@ var SniceChat = (function (exports, snice) {
|
|
|
433
1013
|
clearTimeout(this.typingTimeout);
|
|
434
1014
|
}
|
|
435
1015
|
}
|
|
436
|
-
messagesChanged() {
|
|
437
|
-
// Scroll to bottom when
|
|
438
|
-
|
|
1016
|
+
messagesChanged(oldMessages, newMessages) {
|
|
1017
|
+
// Scroll to bottom only when a message was appended — reactions and edits
|
|
1018
|
+
// reassign the array too, and must not yank the viewport while the user
|
|
1019
|
+
// is scrolled up reading history.
|
|
1020
|
+
if ((newMessages?.length ?? 0) > (oldMessages?.length ?? 0)) {
|
|
1021
|
+
setTimeout(() => this.scrollToBottom(), 0);
|
|
1022
|
+
}
|
|
439
1023
|
}
|
|
440
1024
|
emitMessageSend(message, attachments) {
|
|
441
1025
|
return { message, attachments };
|
|
@@ -449,9 +1033,6 @@ var SniceChat = (function (exports, snice) {
|
|
|
449
1033
|
emitMessageReact(messageId, emoji) {
|
|
450
1034
|
return { messageId, emoji };
|
|
451
1035
|
}
|
|
452
|
-
emitMessageThread(messageId) {
|
|
453
|
-
return { messageId };
|
|
454
|
-
}
|
|
455
1036
|
emitTypingStart() {
|
|
456
1037
|
return {};
|
|
457
1038
|
}
|
|
@@ -566,26 +1147,95 @@ var SniceChat = (function (exports, snice) {
|
|
|
566
1147
|
this.inputField.style.height = 'auto';
|
|
567
1148
|
this.inputField.style.height = `${Math.min(this.inputField.scrollHeight, 150)}px`;
|
|
568
1149
|
}
|
|
1150
|
+
// Reactions are social: anyone can react to any message. Toggle the current
|
|
1151
|
+
// user on/off the emoji, update the local model, and emit for a backend.
|
|
569
1152
|
handleReaction(messageId, emoji) {
|
|
1153
|
+
const me = this.currentUser;
|
|
1154
|
+
this.messages = this.messages.map((m) => {
|
|
1155
|
+
if (m.id !== messageId)
|
|
1156
|
+
return m;
|
|
1157
|
+
const reactions = [...(m.reactions ?? [])];
|
|
1158
|
+
const i = reactions.findIndex((r) => r.emoji === emoji);
|
|
1159
|
+
if (i === -1) {
|
|
1160
|
+
reactions.push({ emoji, count: 1, users: [me] });
|
|
1161
|
+
}
|
|
1162
|
+
else {
|
|
1163
|
+
const r = reactions[i];
|
|
1164
|
+
const removing = r.users.includes(me);
|
|
1165
|
+
const users = removing ? r.users.filter((u) => u !== me) : [...r.users, me];
|
|
1166
|
+
// Adjust by ±1 — never recompute from users.length, which destroys
|
|
1167
|
+
// server counts backed by truncated user lists (count 128, users [2]).
|
|
1168
|
+
const count = Math.max(users.length, r.count + (removing ? -1 : 1));
|
|
1169
|
+
if (count === 0)
|
|
1170
|
+
reactions.splice(i, 1);
|
|
1171
|
+
else
|
|
1172
|
+
reactions[i] = { ...r, count, users };
|
|
1173
|
+
}
|
|
1174
|
+
return { ...m, reactions };
|
|
1175
|
+
});
|
|
570
1176
|
this.emitMessageReact(messageId, emoji);
|
|
571
1177
|
}
|
|
572
|
-
|
|
1178
|
+
// Edit is inline: clicking edit swaps the body for a textarea. Owner-only.
|
|
1179
|
+
// Inline modes are exclusive: opening one closes the other.
|
|
1180
|
+
startEdit(messageId) {
|
|
1181
|
+
this.confirmingDeleteId = null;
|
|
1182
|
+
this.editingId = messageId;
|
|
1183
|
+
}
|
|
1184
|
+
cancelEdit() {
|
|
1185
|
+
this.editingId = null;
|
|
1186
|
+
}
|
|
1187
|
+
commitEdit(messageId) {
|
|
1188
|
+
const next = (this.editField?.value ?? '').trim();
|
|
573
1189
|
const message = this.messages.find((m) => m.id === messageId);
|
|
574
|
-
|
|
1190
|
+
this.editingId = null;
|
|
1191
|
+
if (!message || !next || next === message.content)
|
|
575
1192
|
return;
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
1193
|
+
this.updateMessage(messageId, { content: next, edited: true });
|
|
1194
|
+
this.emitMessageEdit(messageId, next);
|
|
1195
|
+
}
|
|
1196
|
+
handleEditKeydown(e, messageId) {
|
|
1197
|
+
if (e.key === 'Enter' && !e.shiftKey) {
|
|
1198
|
+
e.preventDefault();
|
|
1199
|
+
this.commitEdit(messageId);
|
|
580
1200
|
}
|
|
1201
|
+
else if (e.key === 'Escape') {
|
|
1202
|
+
e.preventDefault();
|
|
1203
|
+
this.cancelEdit();
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
focusEditField() {
|
|
1207
|
+
if (this.editingId === null)
|
|
1208
|
+
return;
|
|
1209
|
+
// Watchers run before the re-render is even scheduled (renders flush on
|
|
1210
|
+
// a microtask), so defer to a frame where the editor exists.
|
|
1211
|
+
requestAnimationFrame(() => {
|
|
1212
|
+
this.editField?.focus();
|
|
1213
|
+
// The editor is taller than the message body it replaces; on the last
|
|
1214
|
+
// message its Save/Cancel row would clip below the scroll area.
|
|
1215
|
+
this.editBox?.scrollIntoView({ block: 'nearest' });
|
|
1216
|
+
});
|
|
581
1217
|
}
|
|
1218
|
+
// Delete asks for inline confirmation (not a native confirm dialog).
|
|
1219
|
+
// Owner-only. On confirm, updates the local model and emits for a backend.
|
|
1220
|
+
// Inline modes are exclusive: opening one closes the other.
|
|
582
1221
|
handleDelete(messageId) {
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
1222
|
+
this.editingId = null;
|
|
1223
|
+
this.confirmingDeleteId = messageId;
|
|
1224
|
+
}
|
|
1225
|
+
revealDeleteConfirm() {
|
|
1226
|
+
if (this.confirmingDeleteId === null)
|
|
1227
|
+
return;
|
|
1228
|
+
// Same clipping problem as the inline editor: the confirm row extends
|
|
1229
|
+
// the last message past the bottom of the scroll area.
|
|
1230
|
+
requestAnimationFrame(() => this.confirmBox?.scrollIntoView({ block: 'nearest' }));
|
|
1231
|
+
}
|
|
1232
|
+
confirmDelete(messageId) {
|
|
1233
|
+
this.confirmingDeleteId = null;
|
|
1234
|
+
this.deleteMessage(messageId);
|
|
1235
|
+
this.emitMessageDelete(messageId);
|
|
586
1236
|
}
|
|
587
|
-
|
|
588
|
-
this.
|
|
1237
|
+
cancelDelete() {
|
|
1238
|
+
this.confirmingDeleteId = null;
|
|
589
1239
|
}
|
|
590
1240
|
render() {
|
|
591
1241
|
return snice.html /*html*/ `
|
|
@@ -612,23 +1262,58 @@ var SniceChat = (function (exports, snice) {
|
|
|
612
1262
|
</div>
|
|
613
1263
|
`;
|
|
614
1264
|
}
|
|
1265
|
+
// Per-message author color. Precedence: per-message override → authorColors
|
|
1266
|
+
// map → auto (only when color-authors is set) → none (falls through to the
|
|
1267
|
+
// default token in CSS). Computed per element instance — no global registry.
|
|
1268
|
+
resolveAuthorColor(message) {
|
|
1269
|
+
if (message.authorColor && isSafeCssColor(message.authorColor))
|
|
1270
|
+
return message.authorColor;
|
|
1271
|
+
const mapped = this.authorColors[message.author];
|
|
1272
|
+
if (mapped && isSafeCssColor(mapped))
|
|
1273
|
+
return mapped;
|
|
1274
|
+
if (this.colorAuthors)
|
|
1275
|
+
return autoAuthorColor(message.author);
|
|
1276
|
+
return '';
|
|
1277
|
+
}
|
|
1278
|
+
// Markdown is opt-in: per-message format='markdown', or the component-wide
|
|
1279
|
+
// `markdown` attribute (which a per-message format='text' can override).
|
|
1280
|
+
shouldRenderMarkdown(message) {
|
|
1281
|
+
if (message.format === MessageFormat.Markdown)
|
|
1282
|
+
return true;
|
|
1283
|
+
if (this.markdown && message.format !== MessageFormat.Text)
|
|
1284
|
+
return true;
|
|
1285
|
+
return false;
|
|
1286
|
+
}
|
|
1287
|
+
renderMessageBody(message) {
|
|
1288
|
+
if (this.shouldRenderMarkdown(message)) {
|
|
1289
|
+
return snice.html /*html*/ `<snice-markdown part="message-text" class="message-text" .content=${message.content}></snice-markdown>`;
|
|
1290
|
+
}
|
|
1291
|
+
return snice.html /*html*/ `<div part="message-text" class="message-text">${message.content}</div>`;
|
|
1292
|
+
}
|
|
615
1293
|
renderMessage(message) {
|
|
616
1294
|
const isSystem = message.type === 'system';
|
|
617
1295
|
const isCurrentUser = message.author === this.currentUser;
|
|
618
1296
|
if (isSystem) {
|
|
619
1297
|
return snice.html /*html*/ `
|
|
620
|
-
<div class="message system" data-message-id="${message.id}">
|
|
1298
|
+
<div part="message system-message" class="message system" data-message-id="${message.id}">
|
|
621
1299
|
<div class="message-content">
|
|
622
|
-
<div class="message-text">${message.content}</div>
|
|
1300
|
+
<div part="message-text" class="message-text">${message.content}</div>
|
|
623
1301
|
</div>
|
|
624
1302
|
</div>
|
|
625
1303
|
`;
|
|
626
1304
|
}
|
|
1305
|
+
const ownClass = isCurrentUser ? 'own' : 'other';
|
|
1306
|
+
const ownPart = isCurrentUser ? 'message-own' : 'message-other';
|
|
1307
|
+
const authorColor = this.resolveAuthorColor(message);
|
|
1308
|
+
const authorStyle = authorColor ? `--snice-chat-author-color:${authorColor}` : '';
|
|
1309
|
+
const isEditing = this.editingId === message.id;
|
|
1310
|
+
const isConfirmingDelete = this.confirmingDeleteId === message.id;
|
|
1311
|
+
const hasReactions = !!message.reactions && message.reactions.length > 0;
|
|
627
1312
|
return snice.html /*html*/ `
|
|
628
|
-
<div class="message" data-message-id="${message.id}">
|
|
1313
|
+
<div part="message ${ownPart}" class="message ${ownClass}" data-message-id="${message.id}">
|
|
629
1314
|
${this.showAvatars
|
|
630
1315
|
? snice.html `
|
|
631
|
-
<div class="message-avatar">
|
|
1316
|
+
<div part="avatar" class="message-avatar">
|
|
632
1317
|
${message.avatar
|
|
633
1318
|
? snice.html `<img src="${message.avatar}" alt="${message.author}" />`
|
|
634
1319
|
: getInitials(message.author)}
|
|
@@ -637,55 +1322,70 @@ var SniceChat = (function (exports, snice) {
|
|
|
637
1322
|
: ''}
|
|
638
1323
|
<div class="message-content">
|
|
639
1324
|
<div class="message-header">
|
|
640
|
-
<span class="message-author">${message.author}</span>
|
|
1325
|
+
<span part="author" class="message-author" style="${authorStyle}">${message.author}</span>
|
|
641
1326
|
${this.showTimestamps
|
|
642
|
-
? snice.html `<span class="message-timestamp">${formatTime(message.timestamp)}</span>`
|
|
1327
|
+
? snice.html `<span part="timestamp" class="message-timestamp">${formatTime(message.timestamp)}</span>`
|
|
643
1328
|
: ''}
|
|
644
|
-
${message.edited ? snice.html `<span class="message-edited">(edited)</span>` : ''}
|
|
1329
|
+
${message.edited ? snice.html `<span part="edited" class="message-edited">(edited)</span>` : ''}
|
|
645
1330
|
</div>
|
|
646
|
-
${
|
|
1331
|
+
${isEditing
|
|
1332
|
+
? this.renderEditor(message)
|
|
1333
|
+
: message.content ? this.renderMessageBody(message) : ''}
|
|
647
1334
|
${message.attachment ? this.renderAttachment(message.attachment) : ''}
|
|
648
|
-
${message.
|
|
649
|
-
|
|
650
|
-
|
|
1335
|
+
${hasReactions ? this.renderReactions(message.id, message.reactions) : ''}
|
|
1336
|
+
${isConfirmingDelete ? this.renderDeleteConfirm(message) : ''}
|
|
1337
|
+
</div>
|
|
1338
|
+
${isEditing || isConfirmingDelete ? '' : this.renderActions(message.id, isCurrentUser)}
|
|
1339
|
+
</div>
|
|
1340
|
+
`;
|
|
1341
|
+
}
|
|
1342
|
+
// Inline message editor — replaces the body while editing. Enter saves,
|
|
1343
|
+
// Shift+Enter newlines, Esc cancels.
|
|
1344
|
+
renderEditor(message) {
|
|
1345
|
+
return snice.html /*html*/ `
|
|
1346
|
+
<div class="message-edit">
|
|
1347
|
+
<textarea
|
|
1348
|
+
part="edit-input"
|
|
1349
|
+
class="edit-field"
|
|
1350
|
+
.value=${message.content}
|
|
1351
|
+
@keydown=${(e) => this.handleEditKeydown(e, message.id)}
|
|
1352
|
+
></textarea>
|
|
1353
|
+
<div class="edit-actions">
|
|
1354
|
+
<button part="edit-save" class="edit-button edit-save" @click=${() => this.commitEdit(message.id)}>Save</button>
|
|
1355
|
+
<button part="edit-cancel" class="edit-button" @click=${() => this.cancelEdit()}>Cancel</button>
|
|
651
1356
|
</div>
|
|
1357
|
+
</div>
|
|
1358
|
+
`;
|
|
1359
|
+
}
|
|
1360
|
+
// Inline delete confirmation — replaces the hover actions while pending, so
|
|
1361
|
+
// a misclick can't destroy a message. Confirm deletes + emits; Cancel aborts.
|
|
1362
|
+
renderDeleteConfirm(message) {
|
|
1363
|
+
return snice.html /*html*/ `
|
|
1364
|
+
<div part="delete-confirm" class="message-confirm">
|
|
1365
|
+
<span class="confirm-text">Delete this message?</span>
|
|
1366
|
+
<div class="confirm-actions">
|
|
1367
|
+
<button part="delete-confirm-yes" class="confirm-button confirm-delete" @click=${() => this.confirmDelete(message.id)}>Delete</button>
|
|
1368
|
+
<button part="delete-confirm-no" class="confirm-button" @click=${() => this.cancelDelete()}>Cancel</button>
|
|
1369
|
+
</div>
|
|
1370
|
+
</div>
|
|
1371
|
+
`;
|
|
1372
|
+
}
|
|
1373
|
+
// Hover action menu. React is available on every message (you react to
|
|
1374
|
+
// others, not just yourself); edit and delete are owner-only.
|
|
1375
|
+
renderActions(messageId, isCurrentUser) {
|
|
1376
|
+
return snice.html /*html*/ `
|
|
1377
|
+
<div part="actions" class="message-actions">
|
|
1378
|
+
<button class="action-button" @click=${() => this.handleReaction(messageId, '👍')} title="React" aria-label="React">
|
|
1379
|
+
<span class="action-emoji" aria-hidden="true">🙂</span>
|
|
1380
|
+
</button>
|
|
652
1381
|
${isCurrentUser
|
|
653
1382
|
? snice.html `
|
|
654
|
-
<
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
<svg viewBox="0 0 16 16" fill="currentColor">
|
|
661
|
-
<path
|
|
662
|
-
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"
|
|
663
|
-
/>
|
|
664
|
-
</svg>
|
|
665
|
-
</button>
|
|
666
|
-
<button
|
|
667
|
-
class="action-button"
|
|
668
|
-
@click="${() => this.handleEdit(message.id)}"
|
|
669
|
-
title="Edit"
|
|
670
|
-
>
|
|
671
|
-
<svg viewBox="0 0 16 16" fill="currentColor">
|
|
672
|
-
<path
|
|
673
|
-
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"
|
|
674
|
-
/>
|
|
675
|
-
</svg>
|
|
676
|
-
</button>
|
|
677
|
-
<button
|
|
678
|
-
class="action-button"
|
|
679
|
-
@click="${() => this.handleDelete(message.id)}"
|
|
680
|
-
title="Delete"
|
|
681
|
-
>
|
|
682
|
-
<svg viewBox="0 0 16 16" fill="currentColor">
|
|
683
|
-
<path
|
|
684
|
-
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"
|
|
685
|
-
/>
|
|
686
|
-
</svg>
|
|
687
|
-
</button>
|
|
688
|
-
</div>
|
|
1383
|
+
<button class="action-button" @click=${() => this.startEdit(messageId)} title="Edit" aria-label="Edit message">
|
|
1384
|
+
${snice.unsafeHTML(PENCIL)}
|
|
1385
|
+
</button>
|
|
1386
|
+
<button class="action-button" @click=${() => this.handleDelete(messageId)} title="Delete" aria-label="Delete message">
|
|
1387
|
+
${snice.unsafeHTML(TRASH)}
|
|
1388
|
+
</button>
|
|
689
1389
|
`
|
|
690
1390
|
: ''}
|
|
691
1391
|
</div>
|
|
@@ -696,13 +1396,13 @@ var SniceChat = (function (exports, snice) {
|
|
|
696
1396
|
return '';
|
|
697
1397
|
if (attachment.type === 'image') {
|
|
698
1398
|
return snice.html /*html*/ `
|
|
699
|
-
<div class="message-attachment">
|
|
1399
|
+
<div part="attachment" class="message-attachment">
|
|
700
1400
|
<img src="${attachment.url}" alt="${attachment.name}" />
|
|
701
1401
|
</div>
|
|
702
1402
|
`;
|
|
703
1403
|
}
|
|
704
1404
|
return snice.html /*html*/ `
|
|
705
|
-
<div class="message-attachment">
|
|
1405
|
+
<div part="attachment" class="message-attachment">
|
|
706
1406
|
<div class="attachment-file">
|
|
707
1407
|
<div class="attachment-icon">
|
|
708
1408
|
<svg viewBox="0 0 16 16" fill="currentColor">
|
|
@@ -721,20 +1421,24 @@ var SniceChat = (function (exports, snice) {
|
|
|
721
1421
|
</div>
|
|
722
1422
|
`;
|
|
723
1423
|
}
|
|
724
|
-
renderReactions(messageId, reactions
|
|
1424
|
+
renderReactions(messageId, reactions) {
|
|
725
1425
|
if (!reactions || reactions.length === 0)
|
|
726
1426
|
return '';
|
|
727
1427
|
return snice.html /*html*/ `
|
|
728
|
-
<div class="message-reactions">
|
|
729
|
-
${reactions.map((reaction) =>
|
|
1428
|
+
<div part="reactions" class="message-reactions">
|
|
1429
|
+
${reactions.map((reaction) => {
|
|
1430
|
+
const isActive = reaction.users.includes(this.currentUser);
|
|
1431
|
+
return snice.html `
|
|
730
1432
|
<div
|
|
731
|
-
|
|
1433
|
+
part="reaction ${isActive ? 'reaction-active' : ''}"
|
|
1434
|
+
class="reaction ${isActive ? 'active' : ''}"
|
|
732
1435
|
@click="${() => this.handleReaction(messageId, reaction.emoji)}"
|
|
733
1436
|
>
|
|
734
1437
|
<span class="reaction-emoji">${reaction.emoji}</span>
|
|
735
1438
|
<span class="reaction-count">${reaction.count}</span>
|
|
736
1439
|
</div>
|
|
737
|
-
|
|
1440
|
+
`;
|
|
1441
|
+
})}
|
|
738
1442
|
</div>
|
|
739
1443
|
`;
|
|
740
1444
|
}
|
|
@@ -744,7 +1448,7 @@ var SniceChat = (function (exports, snice) {
|
|
|
744
1448
|
return '';
|
|
745
1449
|
return snice.html /*html*/ `
|
|
746
1450
|
<div class="typing-indicators">
|
|
747
|
-
<div class="typing-indicator">
|
|
1451
|
+
<div part="typing-indicator" class="typing-indicator">
|
|
748
1452
|
<span>${users.map((u) => u.user).join(', ')} ${users.length === 1 ? 'is' : 'are'} typing</span>
|
|
749
1453
|
<div class="typing-dots">
|
|
750
1454
|
<div class="typing-dot"></div>
|
|
@@ -775,20 +1479,12 @@ var SniceChat = (function (exports, snice) {
|
|
|
775
1479
|
@click="${() => this.handleFileClick()}"
|
|
776
1480
|
title="Attach file"
|
|
777
1481
|
>
|
|
778
|
-
|
|
779
|
-
<path
|
|
780
|
-
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"
|
|
781
|
-
/>
|
|
782
|
-
</svg>
|
|
1482
|
+
${snice.unsafeHTML(PAPER_CLIP)}
|
|
783
1483
|
</button>
|
|
784
1484
|
`
|
|
785
1485
|
: ''}
|
|
786
1486
|
<button class="input-button send" @click="${() => this.sendMessage()}" title="Send">
|
|
787
|
-
|
|
788
|
-
<path
|
|
789
|
-
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"
|
|
790
|
-
/>
|
|
791
|
-
</svg>
|
|
1487
|
+
${snice.unsafeHTML(PAPER_AIRPLANE_SOLID)}
|
|
792
1488
|
</button>
|
|
793
1489
|
</div>
|
|
794
1490
|
</div>
|