snice 5.2.2 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -8
- package/adapters/react/SniceProvider.js +1 -1
- package/adapters/react/SniceRouter.js +1 -1
- package/adapters/react/audio-recorder.d.ts +0 -4
- package/adapters/react/audio-recorder.d.ts.map +1 -1
- package/adapters/react/audio-recorder.js +1 -1
- package/adapters/react/audio-recorder.js.map +1 -1
- package/adapters/react/audio-recorder.tsx +1 -5
- package/adapters/react/avatar.d.ts +0 -1
- package/adapters/react/avatar.d.ts.map +1 -1
- package/adapters/react/avatar.js +1 -1
- package/adapters/react/avatar.js.map +1 -1
- package/adapters/react/avatar.tsx +1 -2
- package/adapters/react/breadcrumbs.d.ts +0 -1
- package/adapters/react/breadcrumbs.d.ts.map +1 -1
- package/adapters/react/breadcrumbs.js +1 -1
- package/adapters/react/breadcrumbs.js.map +1 -1
- package/adapters/react/breadcrumbs.tsx +1 -2
- package/adapters/react/camera-annotate.d.ts +0 -5
- package/adapters/react/camera-annotate.d.ts.map +1 -1
- package/adapters/react/camera-annotate.js +1 -1
- package/adapters/react/camera-annotate.js.map +1 -1
- package/adapters/react/camera-annotate.tsx +1 -6
- package/adapters/react/card.d.ts +0 -2
- package/adapters/react/card.d.ts.map +1 -1
- package/adapters/react/card.js +1 -1
- package/adapters/react/card.js.map +1 -1
- package/adapters/react/card.tsx +1 -3
- package/adapters/react/carousel.d.ts +0 -1
- package/adapters/react/carousel.d.ts.map +1 -1
- package/adapters/react/carousel.js +1 -1
- package/adapters/react/carousel.js.map +1 -1
- package/adapters/react/carousel.tsx +1 -2
- package/adapters/react/cart.d.ts +0 -1
- package/adapters/react/cart.d.ts.map +1 -1
- package/adapters/react/cart.js +1 -1
- package/adapters/react/cart.js.map +1 -1
- package/adapters/react/cart.tsx +1 -2
- package/adapters/react/chart.d.ts +0 -5
- package/adapters/react/chart.d.ts.map +1 -1
- package/adapters/react/chart.js +1 -1
- package/adapters/react/chart.js.map +1 -1
- package/adapters/react/chart.tsx +1 -6
- package/adapters/react/chat.d.ts +4 -1
- package/adapters/react/chat.d.ts.map +1 -1
- package/adapters/react/chat.js +2 -2
- package/adapters/react/chat.js.map +1 -1
- package/adapters/react/chat.tsx +6 -3
- package/adapters/react/chip.d.ts +0 -1
- package/adapters/react/chip.d.ts.map +1 -1
- package/adapters/react/chip.js +1 -1
- package/adapters/react/chip.js.map +1 -1
- package/adapters/react/chip.tsx +1 -2
- package/adapters/react/command-palette.d.ts +0 -4
- package/adapters/react/command-palette.d.ts.map +1 -1
- package/adapters/react/command-palette.js +1 -1
- package/adapters/react/command-palette.js.map +1 -1
- package/adapters/react/command-palette.tsx +1 -5
- package/adapters/react/comments.d.ts +0 -1
- package/adapters/react/comments.d.ts.map +1 -1
- package/adapters/react/comments.js +1 -1
- package/adapters/react/comments.js.map +1 -1
- package/adapters/react/comments.tsx +1 -2
- package/adapters/react/countdown.d.ts +0 -4
- package/adapters/react/countdown.d.ts.map +1 -1
- package/adapters/react/countdown.js +1 -1
- package/adapters/react/countdown.js.map +1 -1
- package/adapters/react/countdown.tsx +1 -5
- package/adapters/react/date-time-picker.d.ts +0 -1
- package/adapters/react/date-time-picker.d.ts.map +1 -1
- package/adapters/react/date-time-picker.js +1 -1
- package/adapters/react/date-time-picker.js.map +1 -1
- package/adapters/react/date-time-picker.tsx +1 -2
- package/adapters/react/file-upload.d.ts +0 -2
- package/adapters/react/file-upload.d.ts.map +1 -1
- package/adapters/react/file-upload.js +1 -1
- package/adapters/react/file-upload.js.map +1 -1
- package/adapters/react/file-upload.tsx +1 -3
- package/adapters/react/heatmap.d.ts +0 -4
- package/adapters/react/heatmap.d.ts.map +1 -1
- package/adapters/react/heatmap.js +1 -1
- package/adapters/react/heatmap.js.map +1 -1
- package/adapters/react/heatmap.tsx +1 -5
- package/adapters/react/image.d.ts +0 -2
- package/adapters/react/image.d.ts.map +1 -1
- package/adapters/react/image.js +1 -1
- package/adapters/react/image.js.map +1 -1
- package/adapters/react/image.tsx +1 -3
- package/adapters/react/kanban.d.ts +0 -4
- package/adapters/react/kanban.d.ts.map +1 -1
- package/adapters/react/kanban.js +1 -1
- package/adapters/react/kanban.js.map +1 -1
- package/adapters/react/kanban.tsx +1 -5
- package/adapters/react/key-value.d.ts +0 -2
- package/adapters/react/key-value.d.ts.map +1 -1
- package/adapters/react/key-value.js +1 -1
- package/adapters/react/key-value.js.map +1 -1
- package/adapters/react/key-value.tsx +1 -3
- package/adapters/react/leaderboard.d.ts +0 -1
- package/adapters/react/leaderboard.d.ts.map +1 -1
- package/adapters/react/leaderboard.js +1 -1
- package/adapters/react/leaderboard.js.map +1 -1
- package/adapters/react/leaderboard.tsx +1 -2
- package/adapters/react/map.d.ts +0 -3
- package/adapters/react/map.d.ts.map +1 -1
- package/adapters/react/map.js +1 -1
- package/adapters/react/map.js.map +1 -1
- package/adapters/react/map.tsx +1 -4
- package/adapters/react/markdown.d.ts +1 -1
- package/adapters/react/markdown.d.ts.map +1 -1
- package/adapters/react/markdown.js +1 -1
- package/adapters/react/markdown.js.map +1 -1
- package/adapters/react/markdown.tsx +2 -2
- package/adapters/react/matchRoute.d.ts +1 -1
- package/adapters/react/matchRoute.js +38 -4
- package/adapters/react/matchRoute.js.map +1 -1
- package/adapters/react/message-strip.d.ts +1 -1
- package/adapters/react/message-strip.js +1 -1
- package/adapters/react/message-strip.tsx +2 -2
- package/adapters/react/music-player.d.ts +0 -1
- package/adapters/react/music-player.d.ts.map +1 -1
- package/adapters/react/music-player.js +1 -1
- package/adapters/react/music-player.js.map +1 -1
- package/adapters/react/music-player.tsx +1 -2
- package/adapters/react/org-chart.d.ts +0 -1
- package/adapters/react/org-chart.d.ts.map +1 -1
- package/adapters/react/org-chart.js +1 -1
- package/adapters/react/org-chart.js.map +1 -1
- package/adapters/react/org-chart.tsx +1 -2
- package/adapters/react/paint.d.ts +0 -1
- package/adapters/react/paint.d.ts.map +1 -1
- package/adapters/react/paint.js +1 -1
- package/adapters/react/paint.js.map +1 -1
- package/adapters/react/paint.tsx +1 -2
- package/adapters/react/podcast-player.d.ts +0 -2
- package/adapters/react/podcast-player.d.ts.map +1 -1
- package/adapters/react/podcast-player.js +1 -1
- package/adapters/react/podcast-player.js.map +1 -1
- package/adapters/react/podcast-player.tsx +1 -3
- package/adapters/react/product-card.d.ts +0 -3
- package/adapters/react/product-card.d.ts.map +1 -1
- package/adapters/react/product-card.js +1 -1
- package/adapters/react/product-card.js.map +1 -1
- package/adapters/react/product-card.tsx +1 -4
- package/adapters/react/qr-reader.d.ts +0 -4
- package/adapters/react/qr-reader.d.ts.map +1 -1
- package/adapters/react/qr-reader.js +1 -1
- package/adapters/react/qr-reader.js.map +1 -1
- package/adapters/react/qr-reader.tsx +1 -5
- package/adapters/react/recipe.d.ts +0 -5
- package/adapters/react/recipe.d.ts.map +1 -1
- package/adapters/react/recipe.js +1 -1
- package/adapters/react/recipe.js.map +1 -1
- package/adapters/react/recipe.tsx +1 -6
- package/adapters/react/route-specificity.d.ts +1 -0
- package/adapters/react/spotlight.d.ts +0 -2
- package/adapters/react/spotlight.d.ts.map +1 -1
- package/adapters/react/spotlight.js +1 -1
- package/adapters/react/spotlight.js.map +1 -1
- package/adapters/react/spotlight.tsx +1 -3
- package/adapters/react/tag-input.d.ts +0 -4
- package/adapters/react/tag-input.d.ts.map +1 -1
- package/adapters/react/tag-input.js +1 -1
- package/adapters/react/tag-input.js.map +1 -1
- package/adapters/react/tag-input.tsx +1 -5
- package/adapters/react/terminal.d.ts +0 -1
- package/adapters/react/terminal.d.ts.map +1 -1
- package/adapters/react/terminal.js +1 -1
- package/adapters/react/terminal.js.map +1 -1
- package/adapters/react/terminal.tsx +1 -2
- package/adapters/react/time-picker.d.ts +0 -1
- package/adapters/react/time-picker.d.ts.map +1 -1
- package/adapters/react/time-picker.js +1 -1
- package/adapters/react/time-picker.js.map +1 -1
- package/adapters/react/time-picker.tsx +1 -2
- package/adapters/react/timer.d.ts +0 -1
- package/adapters/react/timer.d.ts.map +1 -1
- package/adapters/react/timer.js +1 -1
- package/adapters/react/timer.js.map +1 -1
- package/adapters/react/timer.tsx +1 -2
- package/adapters/react/useRequestHandler.js +1 -1
- package/adapters/react/video-player.d.ts +0 -6
- package/adapters/react/video-player.d.ts.map +1 -1
- package/adapters/react/video-player.js +1 -1
- package/adapters/react/video-player.js.map +1 -1
- package/adapters/react/video-player.tsx +1 -7
- package/adapters/react/virtual-scroller.d.ts +0 -1
- package/adapters/react/virtual-scroller.d.ts.map +1 -1
- package/adapters/react/virtual-scroller.js +1 -1
- package/adapters/react/virtual-scroller.js.map +1 -1
- package/adapters/react/virtual-scroller.tsx +1 -2
- package/bin/templates/default/tests/services/jwt.test.ts +8 -1
- package/bin/templates/react/tests/services/jwt.test.ts +10 -3
- package/dist/cdn/accordion/snice-accordion.js +1 -1
- package/dist/cdn/accordion/snice-accordion.min.js +1 -1
- package/dist/cdn/action-bar/README.md +2 -2
- package/dist/cdn/action-bar/snice-action-bar.js +2 -2
- package/dist/cdn/action-bar/snice-action-bar.js.map +1 -1
- package/dist/cdn/action-bar/snice-action-bar.min.js +2 -2
- package/dist/cdn/action-bar/snice-action-bar.min.js.map +1 -1
- package/dist/cdn/activity-feed/snice-activity-feed.js +1 -1
- package/dist/cdn/activity-feed/snice-activity-feed.min.js +1 -1
- package/dist/cdn/alert/snice-alert.js +1 -1
- package/dist/cdn/alert/snice-alert.js.map +1 -1
- package/dist/cdn/alert/snice-alert.min.js +1 -1
- package/dist/cdn/alert/snice-alert.min.js.map +1 -1
- package/dist/cdn/app-tiles/snice-app-tiles.js +1 -1
- package/dist/cdn/app-tiles/snice-app-tiles.min.js +1 -1
- package/dist/cdn/approval-flow/snice-approval-flow.js +1 -1
- package/dist/cdn/approval-flow/snice-approval-flow.js.map +1 -1
- package/dist/cdn/approval-flow/snice-approval-flow.min.js +1 -1
- package/dist/cdn/approval-flow/snice-approval-flow.min.js.map +1 -1
- package/dist/cdn/audio-recorder/snice-audio-recorder.js +1 -1
- package/dist/cdn/audio-recorder/snice-audio-recorder.min.js +1 -1
- package/dist/cdn/availability/snice-availability.js +1 -1
- package/dist/cdn/availability/snice-availability.min.js +1 -1
- package/dist/cdn/avatar/snice-avatar.js +1 -1
- package/dist/cdn/avatar/snice-avatar.min.js +1 -1
- package/dist/cdn/avatar-group/snice-avatar-group.js +1 -1
- package/dist/cdn/avatar-group/snice-avatar-group.min.js +1 -1
- package/dist/cdn/badge/snice-badge.js +1 -1
- package/dist/cdn/badge/snice-badge.js.map +1 -1
- package/dist/cdn/badge/snice-badge.min.js +1 -1
- package/dist/cdn/badge/snice-badge.min.js.map +1 -1
- package/dist/cdn/banner/README.md +1 -1
- package/dist/cdn/banner/snice-banner.js +2 -2
- package/dist/cdn/banner/snice-banner.js.map +1 -1
- package/dist/cdn/banner/snice-banner.min.js +2 -2
- package/dist/cdn/banner/snice-banner.min.js.map +1 -1
- package/dist/cdn/binpack/snice-binpack.js +1 -1
- package/dist/cdn/binpack/snice-binpack.min.js +1 -1
- package/dist/cdn/book/snice-book.js +1 -1
- package/dist/cdn/book/snice-book.min.js +1 -1
- package/dist/cdn/booking/snice-booking.js +1 -1
- package/dist/cdn/booking/snice-booking.min.js +1 -1
- package/dist/cdn/breadcrumbs/snice-breadcrumbs.js +1 -1
- package/dist/cdn/breadcrumbs/snice-breadcrumbs.js.map +1 -1
- package/dist/cdn/breadcrumbs/snice-breadcrumbs.min.js +1 -1
- package/dist/cdn/breadcrumbs/snice-breadcrumbs.min.js.map +1 -1
- package/dist/cdn/button/snice-button.js +1 -1
- package/dist/cdn/button/snice-button.js.map +1 -1
- package/dist/cdn/button/snice-button.min.js +1 -1
- package/dist/cdn/button/snice-button.min.js.map +1 -1
- package/dist/cdn/calendar/snice-calendar.js +1 -1
- package/dist/cdn/calendar/snice-calendar.min.js +1 -1
- package/dist/cdn/camera/snice-camera.js +1 -1
- package/dist/cdn/camera/snice-camera.min.js +1 -1
- package/dist/cdn/camera-annotate/snice-camera-annotate.js +1 -1
- package/dist/cdn/camera-annotate/snice-camera-annotate.min.js +1 -1
- package/dist/cdn/candlestick/snice-candlestick.js +1 -1
- package/dist/cdn/candlestick/snice-candlestick.min.js +1 -1
- package/dist/cdn/card/snice-card.js +1 -1
- package/dist/cdn/card/snice-card.min.js +1 -1
- package/dist/cdn/carousel/snice-carousel.js +1 -1
- package/dist/cdn/carousel/snice-carousel.min.js +1 -1
- package/dist/cdn/cart/snice-cart.js +1 -1
- package/dist/cdn/cart/snice-cart.min.js +1 -1
- package/dist/cdn/chart/snice-chart.js +1 -1
- package/dist/cdn/chart/snice-chart.js.map +1 -1
- package/dist/cdn/chart/snice-chart.min.js +1 -1
- package/dist/cdn/chart/snice-chart.min.js.map +1 -1
- package/dist/cdn/chat/README.md +2 -2
- package/dist/cdn/chat/snice-chat.js +785 -89
- package/dist/cdn/chat/snice-chat.js.map +1 -1
- package/dist/cdn/chat/snice-chat.min.js +71 -75
- package/dist/cdn/chat/snice-chat.min.js.map +1 -1
- package/dist/cdn/checkbox/snice-checkbox.js +1 -1
- package/dist/cdn/checkbox/snice-checkbox.min.js +1 -1
- package/dist/cdn/chip/snice-chip.js +1 -1
- package/dist/cdn/chip/snice-chip.js.map +1 -1
- package/dist/cdn/chip/snice-chip.min.js +1 -1
- package/dist/cdn/chip/snice-chip.min.js.map +1 -1
- package/dist/cdn/code-block/snice-code-block.js +1 -1
- package/dist/cdn/code-block/snice-code-block.min.js +1 -1
- package/dist/cdn/color-display/snice-color-display.js +1 -1
- package/dist/cdn/color-display/snice-color-display.min.js +1 -1
- package/dist/cdn/color-picker/snice-color-picker.js +1 -1
- package/dist/cdn/color-picker/snice-color-picker.min.js +1 -1
- package/dist/cdn/command-palette/README.md +1 -1
- package/dist/cdn/command-palette/snice-command-palette.js +2 -2
- package/dist/cdn/command-palette/snice-command-palette.js.map +1 -1
- package/dist/cdn/command-palette/snice-command-palette.min.js +2 -2
- package/dist/cdn/command-palette/snice-command-palette.min.js.map +1 -1
- package/dist/cdn/comments/snice-comments.js +1 -1
- package/dist/cdn/comments/snice-comments.min.js +1 -1
- package/dist/cdn/countdown/snice-countdown.js +1 -1
- package/dist/cdn/countdown/snice-countdown.min.js +1 -1
- package/dist/cdn/cropper/snice-cropper.js +1 -1
- package/dist/cdn/cropper/snice-cropper.min.js +1 -1
- package/dist/cdn/data-card/snice-data-card.js +1 -1
- package/dist/cdn/data-card/snice-data-card.js.map +1 -1
- package/dist/cdn/data-card/snice-data-card.min.js +1 -1
- package/dist/cdn/data-card/snice-data-card.min.js.map +1 -1
- package/dist/cdn/date-picker/snice-date-picker.js +1 -1
- package/dist/cdn/date-picker/snice-date-picker.min.js +1 -1
- package/dist/cdn/date-range-picker/snice-date-range-picker.js +1 -1
- package/dist/cdn/date-range-picker/snice-date-range-picker.min.js +1 -1
- package/dist/cdn/date-time-picker/snice-date-time-picker.js +1 -1
- package/dist/cdn/date-time-picker/snice-date-time-picker.min.js +1 -1
- package/dist/cdn/diff/snice-diff.js +1 -1
- package/dist/cdn/diff/snice-diff.min.js +1 -1
- package/dist/cdn/divider/snice-divider.js +1 -1
- package/dist/cdn/divider/snice-divider.min.js +1 -1
- package/dist/cdn/doc/snice-doc.js +1 -1
- package/dist/cdn/doc/snice-doc.min.js +1 -1
- package/dist/cdn/draw/snice-draw.js +1 -1
- package/dist/cdn/draw/snice-draw.min.js +1 -1
- package/dist/cdn/drawer/snice-drawer.js +1 -1
- package/dist/cdn/drawer/snice-drawer.js.map +1 -1
- package/dist/cdn/drawer/snice-drawer.min.js +1 -1
- package/dist/cdn/drawer/snice-drawer.min.js.map +1 -1
- package/dist/cdn/empty-state/snice-empty-state.js +1 -1
- package/dist/cdn/empty-state/snice-empty-state.js.map +1 -1
- package/dist/cdn/empty-state/snice-empty-state.min.js +1 -1
- package/dist/cdn/empty-state/snice-empty-state.min.js.map +1 -1
- package/dist/cdn/estimate/snice-estimate.js +1 -1
- package/dist/cdn/estimate/snice-estimate.min.js +1 -1
- package/dist/cdn/file-gallery/snice-file-gallery.js +1 -1
- package/dist/cdn/file-gallery/snice-file-gallery.min.js +1 -1
- package/dist/cdn/file-upload/snice-file-upload.js +1 -1
- package/dist/cdn/file-upload/snice-file-upload.min.js +1 -1
- package/dist/cdn/flip-card/snice-flip-card.js +1 -1
- package/dist/cdn/flip-card/snice-flip-card.min.js +1 -1
- package/dist/cdn/flow/snice-flow.js +1 -1
- package/dist/cdn/flow/snice-flow.min.js +1 -1
- package/dist/cdn/form-layout/snice-form-layout.js +1 -1
- package/dist/cdn/form-layout/snice-form-layout.min.js +1 -1
- package/dist/cdn/funnel/snice-funnel.js +1 -1
- package/dist/cdn/funnel/snice-funnel.js.map +1 -1
- package/dist/cdn/funnel/snice-funnel.min.js +1 -1
- package/dist/cdn/funnel/snice-funnel.min.js.map +1 -1
- package/dist/cdn/gantt/snice-gantt.js +1 -1
- package/dist/cdn/gantt/snice-gantt.min.js +1 -1
- package/dist/cdn/gauge/snice-gauge.js +1 -1
- package/dist/cdn/gauge/snice-gauge.min.js +1 -1
- package/dist/cdn/grid/snice-grid.js +1 -1
- package/dist/cdn/grid/snice-grid.min.js +1 -1
- package/dist/cdn/heatmap/snice-heatmap.js +1 -1
- package/dist/cdn/heatmap/snice-heatmap.min.js +1 -1
- package/dist/cdn/image/snice-image.js +1 -1
- package/dist/cdn/image/snice-image.js.map +1 -1
- package/dist/cdn/image/snice-image.min.js +1 -1
- package/dist/cdn/image/snice-image.min.js.map +1 -1
- package/dist/cdn/input/snice-input.js +1 -1
- package/dist/cdn/input/snice-input.js.map +1 -1
- package/dist/cdn/input/snice-input.min.js +1 -1
- package/dist/cdn/input/snice-input.min.js.map +1 -1
- package/dist/cdn/invoice/README.md +1 -1
- package/dist/cdn/invoice/snice-invoice.js +2 -2
- package/dist/cdn/invoice/snice-invoice.js.map +1 -1
- package/dist/cdn/invoice/snice-invoice.min.js +2 -2
- package/dist/cdn/invoice/snice-invoice.min.js.map +1 -1
- package/dist/cdn/kanban/snice-kanban.js +1 -1
- package/dist/cdn/kanban/snice-kanban.min.js +1 -1
- package/dist/cdn/key-value/snice-key-value.js +1 -1
- package/dist/cdn/key-value/snice-key-value.min.js +1 -1
- package/dist/cdn/kpi/snice-kpi.js +1 -1
- package/dist/cdn/kpi/snice-kpi.js.map +1 -1
- package/dist/cdn/kpi/snice-kpi.min.js +1 -1
- package/dist/cdn/kpi/snice-kpi.min.js.map +1 -1
- package/dist/cdn/layout/snice-layout.js +1 -1
- package/dist/cdn/layout/snice-layout.min.js +1 -1
- package/dist/cdn/leaderboard/snice-leaderboard.js +1 -1
- package/dist/cdn/leaderboard/snice-leaderboard.min.js +1 -1
- package/dist/cdn/link/snice-link.js +1 -1
- package/dist/cdn/link/snice-link.min.js +1 -1
- package/dist/cdn/link-preview/snice-link-preview.js +1 -1
- package/dist/cdn/link-preview/snice-link-preview.min.js +1 -1
- package/dist/cdn/list/snice-list.js +1 -1
- package/dist/cdn/list/snice-list.js.map +1 -1
- package/dist/cdn/list/snice-list.min.js +1 -1
- package/dist/cdn/list/snice-list.min.js.map +1 -1
- package/dist/cdn/location/snice-location.js +1 -1
- package/dist/cdn/location/snice-location.js.map +1 -1
- package/dist/cdn/location/snice-location.min.js +1 -1
- package/dist/cdn/location/snice-location.min.js.map +1 -1
- package/dist/cdn/login/snice-login.js +3 -1
- package/dist/cdn/login/snice-login.js.map +1 -1
- package/dist/cdn/login/snice-login.min.js +1 -1
- package/dist/cdn/login/snice-login.min.js.map +1 -1
- package/dist/cdn/map/snice-map.js +1 -1
- package/dist/cdn/map/snice-map.min.js +1 -1
- package/dist/cdn/markdown/README.md +2 -2
- package/dist/cdn/markdown/snice-markdown.js +16 -3
- package/dist/cdn/markdown/snice-markdown.js.map +1 -1
- package/dist/cdn/markdown/snice-markdown.min.js +3 -3
- package/dist/cdn/markdown/snice-markdown.min.js.map +1 -1
- package/dist/cdn/masonry/snice-masonry.js +1 -1
- package/dist/cdn/masonry/snice-masonry.min.js +1 -1
- package/dist/cdn/menu/snice-menu.js +2 -2
- package/dist/cdn/menu/snice-menu.js.map +1 -1
- package/dist/cdn/menu/snice-menu.min.js +2 -2
- package/dist/cdn/menu/snice-menu.min.js.map +1 -1
- package/dist/cdn/message-strip/snice-message-strip.js +9 -9
- package/dist/cdn/message-strip/snice-message-strip.js.map +1 -1
- package/dist/cdn/message-strip/snice-message-strip.min.js +3 -3
- package/dist/cdn/message-strip/snice-message-strip.min.js.map +1 -1
- package/dist/cdn/metric-table/snice-metric-table.js +1 -1
- package/dist/cdn/metric-table/snice-metric-table.min.js +1 -1
- package/dist/cdn/modal/snice-modal.js +1 -1
- package/dist/cdn/modal/snice-modal.js.map +1 -1
- package/dist/cdn/modal/snice-modal.min.js +1 -1
- package/dist/cdn/modal/snice-modal.min.js.map +1 -1
- package/dist/cdn/music-player/snice-music-player.js +1 -1
- package/dist/cdn/music-player/snice-music-player.min.js +1 -1
- package/dist/cdn/nav/snice-nav.js +1 -1
- package/dist/cdn/nav/snice-nav.min.js +1 -1
- package/dist/cdn/network-graph/snice-network-graph.js +1 -1
- package/dist/cdn/network-graph/snice-network-graph.js.map +1 -1
- package/dist/cdn/network-graph/snice-network-graph.min.js +1 -1
- package/dist/cdn/network-graph/snice-network-graph.min.js.map +1 -1
- package/dist/cdn/notification-center/snice-notification-center.js +1 -1
- package/dist/cdn/notification-center/snice-notification-center.js.map +1 -1
- package/dist/cdn/notification-center/snice-notification-center.min.js +1 -1
- package/dist/cdn/notification-center/snice-notification-center.min.js.map +1 -1
- package/dist/cdn/order-tracker/snice-order-tracker.js +1 -1
- package/dist/cdn/order-tracker/snice-order-tracker.min.js +1 -1
- package/dist/cdn/org-chart/snice-org-chart.js +1 -1
- package/dist/cdn/org-chart/snice-org-chart.min.js +1 -1
- package/dist/cdn/pagination/snice-pagination.js +1 -1
- package/dist/cdn/pagination/snice-pagination.min.js +1 -1
- package/dist/cdn/paint/snice-paint.js +1 -1
- package/dist/cdn/paint/snice-paint.min.js +1 -1
- package/dist/cdn/pdf-viewer/snice-pdf-viewer.js +1 -1
- package/dist/cdn/pdf-viewer/snice-pdf-viewer.min.js +1 -1
- package/dist/cdn/permission-matrix/snice-permission-matrix.js +1 -1
- package/dist/cdn/permission-matrix/snice-permission-matrix.min.js +1 -1
- package/dist/cdn/podcast-player/snice-podcast-player.js +1 -1
- package/dist/cdn/podcast-player/snice-podcast-player.min.js +1 -1
- package/dist/cdn/popover/snice-popover.js +1 -1
- package/dist/cdn/popover/snice-popover.min.js +1 -1
- package/dist/cdn/pricing-table/snice-pricing-table.js +1 -1
- package/dist/cdn/pricing-table/snice-pricing-table.min.js +1 -1
- package/dist/cdn/product-card/snice-product-card.js +3 -3
- package/dist/cdn/product-card/snice-product-card.js.map +1 -1
- package/dist/cdn/product-card/snice-product-card.min.js +3 -3
- package/dist/cdn/product-card/snice-product-card.min.js.map +1 -1
- package/dist/cdn/progress/README.md +1 -1
- package/dist/cdn/progress/snice-progress.js +2 -2
- package/dist/cdn/progress/snice-progress.js.map +1 -1
- package/dist/cdn/progress/snice-progress.min.js +2 -2
- package/dist/cdn/progress/snice-progress.min.js.map +1 -1
- package/dist/cdn/progress-ring/snice-progress-ring.js +2 -2
- package/dist/cdn/progress-ring/snice-progress-ring.js.map +1 -1
- package/dist/cdn/progress-ring/snice-progress-ring.min.js +2 -2
- package/dist/cdn/progress-ring/snice-progress-ring.min.js.map +1 -1
- package/dist/cdn/qr-code/snice-qr-code.js +1 -1
- package/dist/cdn/qr-code/snice-qr-code.min.js +1 -1
- package/dist/cdn/qr-reader/snice-qr-reader.js +1 -1
- package/dist/cdn/qr-reader/snice-qr-reader.min.js +1 -1
- package/dist/cdn/radio/snice-radio.js +1 -1
- package/dist/cdn/radio/snice-radio.min.js +1 -1
- package/dist/cdn/range-slider/snice-range-slider.js +1 -1
- package/dist/cdn/range-slider/snice-range-slider.min.js +1 -1
- package/dist/cdn/rating/snice-rating.js +1 -1
- package/dist/cdn/rating/snice-rating.min.js +1 -1
- package/dist/cdn/receipt/snice-receipt.js +1 -1
- package/dist/cdn/receipt/snice-receipt.min.js +1 -1
- package/dist/cdn/recipe/snice-recipe.js +1 -1
- package/dist/cdn/recipe/snice-recipe.min.js +1 -1
- package/dist/cdn/runtime/README.md +2 -2
- package/dist/cdn/runtime/snice-runtime.esm.js +644 -172
- package/dist/cdn/runtime/snice-runtime.esm.js.map +1 -1
- package/dist/cdn/runtime/snice-runtime.esm.min.js +8 -8
- package/dist/cdn/runtime/snice-runtime.esm.min.js.map +1 -1
- package/dist/cdn/runtime/snice-runtime.js +644 -172
- package/dist/cdn/runtime/snice-runtime.js.map +1 -1
- package/dist/cdn/runtime/snice-runtime.min.js +8 -8
- package/dist/cdn/runtime/snice-runtime.min.js.map +1 -1
- package/dist/cdn/sankey/snice-sankey.js +1 -1
- package/dist/cdn/sankey/snice-sankey.js.map +1 -1
- package/dist/cdn/sankey/snice-sankey.min.js +1 -1
- package/dist/cdn/sankey/snice-sankey.min.js.map +1 -1
- package/dist/cdn/segmented-control/snice-segmented-control.js +1 -1
- package/dist/cdn/segmented-control/snice-segmented-control.min.js +1 -1
- package/dist/cdn/select/snice-select.js +1 -1
- package/dist/cdn/select/snice-select.min.js +1 -1
- package/dist/cdn/skeleton/snice-skeleton.js +1 -1
- package/dist/cdn/skeleton/snice-skeleton.min.js +1 -1
- package/dist/cdn/slider/snice-slider.js +1 -1
- package/dist/cdn/slider/snice-slider.min.js +1 -1
- package/dist/cdn/sortable/snice-sortable.js +1 -1
- package/dist/cdn/sortable/snice-sortable.min.js +1 -1
- package/dist/cdn/sparkline/snice-sparkline.js +1 -1
- package/dist/cdn/sparkline/snice-sparkline.min.js +1 -1
- package/dist/cdn/spinner/snice-spinner.js +1 -1
- package/dist/cdn/spinner/snice-spinner.min.js +1 -1
- package/dist/cdn/split-button/snice-split-button.js +1 -1
- package/dist/cdn/split-button/snice-split-button.js.map +1 -1
- package/dist/cdn/split-button/snice-split-button.min.js +1 -1
- package/dist/cdn/split-button/snice-split-button.min.js.map +1 -1
- package/dist/cdn/split-pane/snice-split-pane.js +1 -1
- package/dist/cdn/split-pane/snice-split-pane.min.js +1 -1
- package/dist/cdn/spotlight/snice-spotlight.js +1 -1
- package/dist/cdn/spotlight/snice-spotlight.min.js +1 -1
- package/dist/cdn/stat-group/snice-stat-group.js +1 -1
- package/dist/cdn/stat-group/snice-stat-group.min.js +1 -1
- package/dist/cdn/step-input/snice-step-input.js +1 -1
- package/dist/cdn/step-input/snice-step-input.min.js +1 -1
- package/dist/cdn/stepper/snice-stepper.js +1 -1
- package/dist/cdn/stepper/snice-stepper.min.js +1 -1
- package/dist/cdn/switch/snice-switch.js +1 -1
- package/dist/cdn/switch/snice-switch.min.js +1 -1
- package/dist/cdn/table/README.md +1 -1
- package/dist/cdn/table/snice-table.js +14 -4
- package/dist/cdn/table/snice-table.js.map +1 -1
- package/dist/cdn/table/snice-table.min.js +14 -4
- package/dist/cdn/table/snice-table.min.js.map +1 -1
- package/dist/cdn/tabs/snice-tabs.js +1 -1
- package/dist/cdn/tabs/snice-tabs.min.js +1 -1
- package/dist/cdn/tag/snice-tag.js +1 -1
- package/dist/cdn/tag/snice-tag.min.js +1 -1
- package/dist/cdn/tag-input/snice-tag-input.js +2 -2
- package/dist/cdn/tag-input/snice-tag-input.js.map +1 -1
- package/dist/cdn/tag-input/snice-tag-input.min.js +2 -2
- package/dist/cdn/tag-input/snice-tag-input.min.js.map +1 -1
- package/dist/cdn/terminal/snice-terminal.js +1 -1
- package/dist/cdn/terminal/snice-terminal.min.js +1 -1
- package/dist/cdn/testimonial/snice-testimonial.js +1 -1
- package/dist/cdn/testimonial/snice-testimonial.min.js +1 -1
- package/dist/cdn/textarea/snice-textarea.js +1 -1
- package/dist/cdn/textarea/snice-textarea.min.js +1 -1
- package/dist/cdn/time-picker/README.md +1 -1
- package/dist/cdn/time-picker/snice-time-picker.js +18 -13
- package/dist/cdn/time-picker/snice-time-picker.js.map +1 -1
- package/dist/cdn/time-picker/snice-time-picker.min.js +3 -3
- package/dist/cdn/time-picker/snice-time-picker.min.js.map +1 -1
- package/dist/cdn/time-range-picker/snice-time-range-picker.js +1 -1
- package/dist/cdn/time-range-picker/snice-time-range-picker.min.js +1 -1
- package/dist/cdn/timeline/snice-timeline.js +1 -1
- package/dist/cdn/timeline/snice-timeline.js.map +1 -1
- package/dist/cdn/timeline/snice-timeline.min.js +1 -1
- package/dist/cdn/timeline/snice-timeline.min.js.map +1 -1
- package/dist/cdn/timer/snice-timer.js +1 -1
- package/dist/cdn/timer/snice-timer.min.js +1 -1
- package/dist/cdn/toast/snice-toast.js +1 -1
- package/dist/cdn/toast/snice-toast.js.map +1 -1
- package/dist/cdn/toast/snice-toast.min.js +1 -1
- package/dist/cdn/toast/snice-toast.min.js.map +1 -1
- package/dist/cdn/tooltip/snice-tooltip.js +1 -1
- package/dist/cdn/tooltip/snice-tooltip.min.js +1 -1
- package/dist/cdn/tree/snice-tree.js +1 -1
- package/dist/cdn/tree/snice-tree.min.js +1 -1
- package/dist/cdn/treemap/snice-treemap.js +1 -1
- package/dist/cdn/treemap/snice-treemap.js.map +1 -1
- package/dist/cdn/treemap/snice-treemap.min.js +1 -1
- package/dist/cdn/treemap/snice-treemap.min.js.map +1 -1
- package/dist/cdn/user-card/snice-user-card.js +1 -1
- package/dist/cdn/user-card/snice-user-card.min.js +1 -1
- package/dist/cdn/video-player/snice-video-player.js +1 -1
- package/dist/cdn/video-player/snice-video-player.min.js +1 -1
- package/dist/cdn/virtual-scroller/snice-virtual-scroller.js +1 -1
- package/dist/cdn/virtual-scroller/snice-virtual-scroller.min.js +1 -1
- package/dist/cdn/waterfall/snice-waterfall.js +1 -1
- package/dist/cdn/waterfall/snice-waterfall.min.js +1 -1
- package/dist/cdn/weather/snice-weather.js +1 -1
- package/dist/cdn/weather/snice-weather.min.js +1 -1
- package/dist/cdn/work-order/snice-work-order.js +1 -1
- package/dist/cdn/work-order/snice-work-order.min.js +1 -1
- package/dist/components/action-bar/snice-action-bar.js +1 -1
- package/dist/components/action-bar/snice-action-bar.js.map +1 -1
- package/dist/components/banner/snice-banner.js +1 -1
- package/dist/components/banner/snice-banner.js.map +1 -1
- package/dist/components/chat/snice-chat-message.d.ts +32 -0
- package/dist/components/chat/snice-chat-message.js +127 -0
- package/dist/components/chat/snice-chat-message.js.map +1 -0
- package/dist/components/chat/snice-chat-message.types.d.ts +30 -0
- package/dist/components/chat/snice-chat.d.ts +31 -4
- package/dist/components/chat/snice-chat.js +363 -90
- package/dist/components/chat/snice-chat.js.map +1 -1
- package/dist/components/chat/snice-chat.types.d.ts +34 -3
- package/dist/components/command-palette/snice-command-palette.js +1 -1
- package/dist/components/command-palette/snice-command-palette.js.map +1 -1
- package/dist/components/icons/index.d.ts +4 -0
- package/dist/components/icons/index.js +5 -1
- package/dist/components/icons/index.js.map +1 -1
- package/dist/components/invoice/snice-invoice.js +1 -1
- package/dist/components/invoice/snice-invoice.js.map +1 -1
- package/dist/components/login/snice-login.d.ts +2 -2
- package/dist/components/login/snice-login.js +2 -0
- package/dist/components/login/snice-login.js.map +1 -1
- package/dist/components/login/snice-login.types.d.ts +4 -0
- package/dist/components/markdown/snice-markdown.d.ts +1 -0
- package/dist/components/markdown/snice-markdown.js +15 -2
- package/dist/components/markdown/snice-markdown.js.map +1 -1
- package/dist/components/menu/snice-menu.js +1 -1
- package/dist/components/menu/snice-menu.js.map +1 -1
- package/dist/components/message-strip/snice-message-strip.d.ts +1 -1
- package/dist/components/message-strip/snice-message-strip.js +8 -8
- package/dist/components/message-strip/snice-message-strip.types.d.ts +1 -1
- package/dist/components/product-card/snice-product-card.js +2 -2
- package/dist/components/product-card/snice-product-card.js.map +1 -1
- package/dist/components/progress/snice-progress.js +1 -1
- package/dist/components/progress/snice-progress.js.map +1 -1
- package/dist/components/progress-ring/snice-progress-ring.js +1 -1
- package/dist/components/progress-ring/snice-progress-ring.js.map +1 -1
- package/dist/components/table/snice-table.js +13 -3
- package/dist/components/table/snice-table.js.map +1 -1
- package/dist/components/tag-input/snice-tag-input.js +1 -1
- package/dist/components/tag-input/snice-tag-input.js.map +1 -1
- package/dist/components/time-picker/snice-time-picker.js +17 -12
- package/dist/components/time-picker/snice-time-picker.js.map +1 -1
- package/dist/components/utils.d.ts +6 -0
- package/dist/components/utils.js +1 -1
- package/dist/components/utils.js.map +1 -1
- package/dist/element.d.ts +2 -1
- package/dist/events.d.ts +6 -0
- package/dist/index.cjs +641 -169
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +641 -169
- package/dist/index.esm.js.map +1 -1
- package/dist/index.iife.js +641 -169
- package/dist/index.iife.js.map +1 -1
- package/dist/parts.d.ts +1 -8
- package/dist/react/SniceProvider.js +1 -1
- package/dist/react/SniceRouter.js +1 -1
- package/dist/react/index.js +1 -1
- package/dist/react/matchRoute.d.ts +1 -1
- package/dist/react/matchRoute.js +38 -4
- package/dist/react/matchRoute.js.map +1 -1
- package/dist/react/route-specificity.d.ts +1 -0
- package/dist/react/useRequestHandler.js +1 -1
- package/dist/render.d.ts +7 -0
- package/dist/route-specificity.d.ts +1 -0
- package/dist/symbols.cjs +14 -1
- package/dist/symbols.cjs.map +1 -1
- package/dist/symbols.d.ts +3 -0
- package/dist/symbols.esm.js +12 -2
- package/dist/symbols.esm.js.map +1 -1
- package/dist/transitions.cjs +1 -1
- package/dist/transitions.esm.js +1 -1
- package/dist/types/context.d.ts +5 -2
- package/dist/types/dispatch-options.d.ts +7 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/on-options.d.ts +14 -0
- package/dist/types/watch-options.d.ts +9 -0
- package/dist/utils.d.ts +26 -0
- package/docs/ai/DEVELOPMENT.md +1 -1
- package/docs/ai/README.md +11 -0
- package/docs/ai/api.md +24 -5
- package/docs/ai/cdn.md +31 -0
- package/docs/ai/components/chat.md +57 -1
- package/docs/ai/components/message-strip.md +3 -3
- package/docs/ai/decorators.md +44 -5
- package/docs/cdn.md +56 -0
- package/docs/components/chat.md +108 -2
- package/docs/components/message-strip.md +8 -8
- package/docs/elements.md +21 -0
- package/docs/events.md +88 -0
- package/docs/superpowers/specs/2026-05-26-chat-styling-design.md +155 -0
- package/docs/superpowers/specs/2026-05-27-chat-theming-REMAINING.md +83 -0
- package/docs/superpowers/specs/2026-06-09-chat-custom-content-design.md +233 -0
- package/package.json +1 -1
|
@@ -6,7 +6,7 @@ Inline contextual message bar within content flow. Differs from alert (card), ba
|
|
|
6
6
|
|
|
7
7
|
```ts
|
|
8
8
|
variant: 'info'|'success'|'warning'|'danger' = 'info';
|
|
9
|
-
|
|
9
|
+
dismissible: boolean = false;
|
|
10
10
|
icon: string = ''; // Custom icon (set "none" to hide)
|
|
11
11
|
```
|
|
12
12
|
|
|
@@ -43,8 +43,8 @@ import 'snice/components/message-strip/snice-message-strip';
|
|
|
43
43
|
<snice-message-strip variant="warning">Review your changes.</snice-message-strip>
|
|
44
44
|
<snice-message-strip variant="danger">An error occurred.</snice-message-strip>
|
|
45
45
|
|
|
46
|
-
<!--
|
|
47
|
-
<snice-message-strip variant="info"
|
|
46
|
+
<!-- Dismissible -->
|
|
47
|
+
<snice-message-strip variant="info" dismissible>You can close this.</snice-message-strip>
|
|
48
48
|
|
|
49
49
|
<!-- Custom icon -->
|
|
50
50
|
<snice-message-strip variant="info" icon="🔔">New notification.</snice-message-strip>
|
package/docs/ai/decorators.md
CHANGED
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
|
|
14
14
|
## Properties
|
|
15
15
|
- `@property({ type?, attribute?: string|boolean, converter?, hasChanged? })` - Reactive, syncs attrs. Initial defaults NOT reflected to attrs.
|
|
16
|
-
- `@watch('propName')` -
|
|
16
|
+
- `@watch('propName')` - Fires once on init as `(undefined, initialValue, propertyName)`, then on every change: `(oldVal, newVal, propertyName) => void`.
|
|
17
|
+
- `@watch('propName', { immediate: false })` - Change-only; skips the init call (use for watchers that dispatch events). Options object is the last arg (works with multiple names).
|
|
17
18
|
|
|
18
19
|
## Lifecycle
|
|
19
20
|
- `@ready()` - After first render. Fires once.
|
|
@@ -27,8 +28,37 @@
|
|
|
27
28
|
- `@queryAll('selector', { light? })` - NodeList
|
|
28
29
|
|
|
29
30
|
## Events
|
|
30
|
-
- `@on('event', 'selector?')` - Delegation, auto-bound
|
|
31
|
-
- `@dispatch('event-name', options?)` - Emit CustomEvent, detail = return value. Supports async. Options: `{ debounce?, throttle?, dispatchOnUndefined
|
|
31
|
+
- `@on('event', 'selector?', options?)` - Delegation, auto-bound. Options: `{ capture?, once?, passive?, preventDefault?, stopPropagation?, debounce?, throttle?, scope? }`
|
|
32
|
+
- `@dispatch('event-name', options?)` - Emit CustomEvent, detail = return value. Supports async. Options: `{ debounce?, throttle?, dispatchOnUndefined?, scope?, ...EventInit }`
|
|
33
|
+
|
|
34
|
+
### scope (on both `@on` and `@dispatch`)
|
|
35
|
+
|
|
36
|
+
Redirects where the listener is attached / event is dispatched. Default: host element.
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
scope?: 'global' | string | EventTarget | ((this: HTMLElement) => EventTarget | null)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
| value | resolves to |
|
|
43
|
+
|---|---|
|
|
44
|
+
| omitted | host element |
|
|
45
|
+
| `'global'` | `document` |
|
|
46
|
+
| selector string | `host.closest(selector)` — nearest ancestor |
|
|
47
|
+
| Element / EventTarget | that node |
|
|
48
|
+
| resolver fn | called with host as `this`; `null` skips |
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
@on('bus:save', { scope: 'global' }) onSave(e) {}
|
|
52
|
+
@on('bus:cart-added', { scope: 'cart-shell' }) onAdd(e) {}
|
|
53
|
+
@on('go', { scope: someEl }) onGo(e) {}
|
|
54
|
+
@on('beep', { scope() { return this.closest('app-shell'); } }) onBeep(e) {}
|
|
55
|
+
|
|
56
|
+
@dispatch('bus:cart-added', { scope: 'global' }) add(id) { return { id }; }
|
|
57
|
+
@dispatch('bus:x', { scope: 'cart-shell' }) fire() { return 1; }
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Unresolved scope → `console.warn`, listener not attached / event not dispatched.
|
|
61
|
+
Resolver re-runs on reconnect — listeners track DOM moves.
|
|
32
62
|
|
|
33
63
|
## Communication
|
|
34
64
|
- `@request(channel, options?)` - Async generator request pattern
|
|
@@ -58,9 +88,18 @@ attr="${val}" - String attribute
|
|
|
58
88
|
@event=${fn} - Event listener (auto-bound)
|
|
59
89
|
```
|
|
60
90
|
|
|
61
|
-
## Event Modifiers
|
|
91
|
+
## Event Modifiers (keyboard only)
|
|
92
|
+
Template dotted/colon modifiers apply ONLY to keydown/keyup/keypress — they are
|
|
93
|
+
key filters, not general event options. A dot in any other event name is part of
|
|
94
|
+
the event name (e.g. `@app.ready`).
|
|
62
95
|
```
|
|
63
96
|
@keydown:Enter=${fn} - Key filter
|
|
64
97
|
@keydown.ctrl+s=${fn} - Key combo
|
|
65
|
-
@
|
|
98
|
+
@keydown.~enter=${fn} - Key, any modifiers
|
|
99
|
+
```
|
|
100
|
+
`once` / `preventDefault` / `stopPropagation` / `capture` are NOT template
|
|
101
|
+
modifiers — use the `@on` decorator's options object:
|
|
102
|
+
```typescript
|
|
103
|
+
@on('click', { once: true, preventDefault: true, stopPropagation: true })
|
|
104
|
+
handleClick(e: Event) {}
|
|
66
105
|
```
|
package/docs/cdn.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<!-- AI: For the AI-optimized version of this doc, see docs/ai/cdn.md -->
|
|
2
|
+
|
|
3
|
+
# CDN / Standalone Usage
|
|
4
|
+
|
|
5
|
+
Use any Snice component on a plain HTML page — no bundler, no build step. Each component is a standalone `.min.js` bundle that shares one small runtime.
|
|
6
|
+
|
|
7
|
+
## Load Order
|
|
8
|
+
|
|
9
|
+
Load the runtime **once, first**, then one bundle per component. Components load in any order *after* the runtime:
|
|
10
|
+
|
|
11
|
+
```html
|
|
12
|
+
<link rel="stylesheet" href="theme.css"> <!-- optional: design tokens + dark mode -->
|
|
13
|
+
<script src="snice-runtime.min.js"></script> <!-- required, load first -->
|
|
14
|
+
<script src="snice-button.min.js"></script> <!-- one bundle per component -->
|
|
15
|
+
<script src="snice-card.min.js"></script>
|
|
16
|
+
|
|
17
|
+
<snice-button variant="primary">Click me</snice-button>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`snice-runtime.min.js` is shared by every component. Load it before any `snice-<name>.min.js` — without it the custom elements never register and the page renders blank.
|
|
21
|
+
|
|
22
|
+
## Bundle Families
|
|
23
|
+
|
|
24
|
+
One bundle registers its whole element family — you don't load sub-elements separately:
|
|
25
|
+
|
|
26
|
+
| Bundle | Registers |
|
|
27
|
+
|--------|-----------|
|
|
28
|
+
| `snice-tabs.min.js` | `<snice-tabs>`, `<snice-tab>`, `<snice-tab-panel>` |
|
|
29
|
+
| `snice-select.min.js` | `<snice-select>`, `<snice-option>` |
|
|
30
|
+
| `snice-toast.min.js` | `<snice-toast>`, `<snice-toast-container>` |
|
|
31
|
+
|
|
32
|
+
## Theme and Dark Mode
|
|
33
|
+
|
|
34
|
+
Components ship with built-in light-mode token fallbacks, so they render correctly with no stylesheet. Add `theme.css` for the full design-token set and dark mode:
|
|
35
|
+
|
|
36
|
+
```html
|
|
37
|
+
<link rel="stylesheet" href="theme.css">
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Dark mode follows the OS setting automatically. To force it, set `data-theme` on the root element:
|
|
41
|
+
|
|
42
|
+
```html
|
|
43
|
+
<html data-theme="dark"> <!-- or data-theme="light" to pin light -->
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Use the `.min.js` Builds
|
|
47
|
+
|
|
48
|
+
Load the `.min.js` (IIFE) bundles in `<script src>` tags. The `.esm.min.js` builds are ES modules for bundler/`import` use, not `<script src>`.
|
|
49
|
+
|
|
50
|
+
## Generating Bundles
|
|
51
|
+
|
|
52
|
+
Bundles are published to the CDN, or build them yourself:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
snice build-component button
|
|
56
|
+
```
|
package/docs/components/chat.md
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
# Chat Component
|
|
4
4
|
|
|
5
|
-
Slack-style chat interface with messages, typing indicators, reactions, file attachments
|
|
5
|
+
Slack-style chat interface with messages, typing indicators, reactions, and file attachments.
|
|
6
6
|
|
|
7
7
|
## Table of Contents
|
|
8
|
+
- [Components](#components)
|
|
8
9
|
- [Properties](#properties)
|
|
9
10
|
- [Methods](#methods)
|
|
10
11
|
- [Events](#events)
|
|
@@ -14,6 +15,13 @@ Slack-style chat interface with messages, typing indicators, reactions, file att
|
|
|
14
15
|
- [Examples](#examples)
|
|
15
16
|
- [Accessibility](#accessibility)
|
|
16
17
|
|
|
18
|
+
## Components
|
|
19
|
+
|
|
20
|
+
| Element | Description |
|
|
21
|
+
|---------|-------------|
|
|
22
|
+
| `snice-chat` | The chat container — renders messages, input, typing indicators. |
|
|
23
|
+
| `snice-chat-message` | Declarative message authoring. Provide messages as child elements instead of (or as well as) the `messages` array; child elements render first, array entries append after. |
|
|
24
|
+
|
|
17
25
|
## Properties
|
|
18
26
|
|
|
19
27
|
| Property | Type | Default | Description |
|
|
@@ -26,6 +34,23 @@ Slack-style chat interface with messages, typing indicators, reactions, file att
|
|
|
26
34
|
| `showTyping` (attr: `show-typing`) | `boolean` | `true` | Show typing indicators |
|
|
27
35
|
| `showAvatars` (attr: `show-avatars`) | `boolean` | `true` | Show user avatars |
|
|
28
36
|
| `showTimestamps` (attr: `show-timestamps`) | `boolean` | `true` | Show message timestamps |
|
|
37
|
+
| `authorColors` | `Record<string, string>` | `{}` | Per-author name colors, keyed by author name (property only) |
|
|
38
|
+
| `colorAuthors` (attr: `color-authors`) | `boolean` | `false` | Auto-assign a stable color to each author |
|
|
39
|
+
| `markdown` | `boolean` | `false` | Render message content as markdown by default |
|
|
40
|
+
| `layout` | `'default' \| 'bubbles'` | `'default'` | Built-in message layout; `'bubbles'` aligns own messages right in colored bubbles |
|
|
41
|
+
|
|
42
|
+
### snice-chat-message Attributes
|
|
43
|
+
|
|
44
|
+
| Attribute | Type | Default | Description |
|
|
45
|
+
|-----------|------|---------|-------------|
|
|
46
|
+
| `author` | `string` | `''` | Message author name |
|
|
47
|
+
| `avatar` | `string` | `''` | Author avatar URL |
|
|
48
|
+
| `type` | `'text' \| 'file' \| 'image' \| 'system'` | `'text'` | Message type |
|
|
49
|
+
| `format` | `'text' \| 'markdown'` | — | How the body is rendered; unset defers to the chat-level `markdown` flag |
|
|
50
|
+
| `edited` | `boolean` | `false` | Marks the message as edited |
|
|
51
|
+
| `author-color` | `string` | `''` | Per-message author color override |
|
|
52
|
+
|
|
53
|
+
The message body is the element's text content. Rich fields with no attribute form — `reactions`, `attachment` — can be set as JS properties on the element and are carried into the message.
|
|
29
54
|
|
|
30
55
|
### ChatMessage Interface
|
|
31
56
|
|
|
@@ -41,6 +66,8 @@ interface ChatMessage {
|
|
|
41
66
|
reactions?: MessageReaction[];
|
|
42
67
|
thread?: ChatMessage[];
|
|
43
68
|
attachment?: MessageAttachment;
|
|
69
|
+
format?: 'text' | 'markdown'; // unset = the chat-level markdown flag applies
|
|
70
|
+
authorColor?: string; // per-message author color override (CSS color; values containing ; { } are rejected)
|
|
44
71
|
}
|
|
45
72
|
|
|
46
73
|
interface MessageAttachment {
|
|
@@ -79,10 +106,11 @@ interface MessageReaction {
|
|
|
79
106
|
| `message-edit` | `{ messageId: string, newContent: string }` | User edits a message |
|
|
80
107
|
| `message-delete` | `{ messageId: string }` | User deletes a message |
|
|
81
108
|
| `message-react` | `{ messageId: string, emoji: string }` | User reacts to a message |
|
|
82
|
-
| `message-thread` | `{ messageId: string }` | User starts a thread |
|
|
83
109
|
| `typing-start` | `{}` | Current user starts typing |
|
|
84
110
|
| `typing-stop` | `{}` | Current user stops typing |
|
|
85
111
|
|
|
112
|
+
React, edit, and delete are applied to the local `messages` model by the component itself in addition to emitting the event — your handler should persist the change to a backend, not re-apply it to `messages` (doing both double-applies). If the backend rejects a change, revert it with `updateMessage()` (or by reassigning `messages`) from your handler. Reactions work on any message (yours or another user's); edit and delete are owner-only. Delete asks for inline confirmation before removing. `message-send` is the exception: the component does not self-add the sent message, so your handler appends it.
|
|
113
|
+
|
|
86
114
|
## CSS Custom Properties
|
|
87
115
|
|
|
88
116
|
| Property | Description |
|
|
@@ -132,6 +160,27 @@ interface MessageReaction {
|
|
|
132
160
|
|------|-------------|
|
|
133
161
|
| `base` | The chat container |
|
|
134
162
|
| `messages` | The scrollable messages area |
|
|
163
|
+
| `message` | A message row (every message) |
|
|
164
|
+
| `message-own` | A message row authored by the current user |
|
|
165
|
+
| `message-other` | A message row authored by someone else |
|
|
166
|
+
| `system-message` | A system message row |
|
|
167
|
+
| `avatar` | A message avatar |
|
|
168
|
+
| `author` | A message author name |
|
|
169
|
+
| `timestamp` | A message timestamp |
|
|
170
|
+
| `edited` | The "(edited)" marker |
|
|
171
|
+
| `message-text` | A message body |
|
|
172
|
+
| `attachment` | A message attachment |
|
|
173
|
+
| `reactions` | A message's reactions container |
|
|
174
|
+
| `reaction` | A single reaction |
|
|
175
|
+
| `reaction-active` | A reaction the current user has added |
|
|
176
|
+
| `actions` | The hover action menu |
|
|
177
|
+
| `edit-input` | The inline edit textarea (shown while editing) |
|
|
178
|
+
| `edit-save` | The save button in the inline editor |
|
|
179
|
+
| `edit-cancel` | The cancel button in the inline editor |
|
|
180
|
+
| `delete-confirm` | The inline delete-confirmation row |
|
|
181
|
+
| `delete-confirm-yes` | The confirm (delete) button |
|
|
182
|
+
| `delete-confirm-no` | The cancel button in the delete confirmation |
|
|
183
|
+
| `typing-indicator` | A typing indicator row |
|
|
135
184
|
| `input-area` | The input area wrapper |
|
|
136
185
|
| `input-container` | Container holding the input and buttons |
|
|
137
186
|
| `input` | The message input field |
|
|
@@ -231,6 +280,63 @@ setTimeout(() => {
|
|
|
231
280
|
}, 2000);
|
|
232
281
|
```
|
|
233
282
|
|
|
283
|
+
### Declarative Messages
|
|
284
|
+
|
|
285
|
+
Author messages as `snice-chat-message` children instead of the `messages` array. When both are present, child elements render first and array entries (including `addMessage()` calls) append after them. Slotted messages keep their identity across DOM updates, so reactions and edits made in the UI survive re-renders.
|
|
286
|
+
|
|
287
|
+
```html
|
|
288
|
+
<snice-chat current-user="Me">
|
|
289
|
+
<snice-chat-message slot="messages" author="Alice" timestamp="2026-05-26T09:24:00Z">Hey, deploy is green</snice-chat-message>
|
|
290
|
+
<snice-chat-message slot="messages" author="Me" timestamp="2026-05-26T09:25:00Z">Merging now</snice-chat-message>
|
|
291
|
+
</snice-chat>
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### Per-User Name Colors
|
|
295
|
+
|
|
296
|
+
Set `colorAuthors` to auto-assign a stable color per author, or supply explicit colors with `authorColors`. A per-message `authorColor` overrides both.
|
|
297
|
+
|
|
298
|
+
```html
|
|
299
|
+
<snice-chat color-authors></snice-chat>
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
```javascript
|
|
303
|
+
chat.authorColors = { Alice: '#e11d48', Bob: '#2563eb' };
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
### Markdown
|
|
307
|
+
|
|
308
|
+
Set `markdown` to render every message body as markdown, or set `format: 'markdown'` per message. A per-message `format: 'text'` opts out of the component-wide default.
|
|
309
|
+
|
|
310
|
+
```html
|
|
311
|
+
<snice-chat markdown></snice-chat>
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
```javascript
|
|
315
|
+
chat.addMessage({
|
|
316
|
+
type: 'text', author: 'Alice', timestamp: new Date(),
|
|
317
|
+
format: 'markdown',
|
|
318
|
+
content: 'shipped **v5.3** — run `npm i snice@latest`'
|
|
319
|
+
});
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### Bubble Layout
|
|
323
|
+
|
|
324
|
+
Set `layout="bubbles"` for a mobile-OS style: own messages right-aligned in colored bubbles, others left.
|
|
325
|
+
|
|
326
|
+
```html
|
|
327
|
+
<snice-chat layout="bubbles" current-user="Me"></snice-chat>
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Custom Styling with Parts
|
|
331
|
+
|
|
332
|
+
Every message internal is exposed as a CSS part.
|
|
333
|
+
|
|
334
|
+
```css
|
|
335
|
+
snice-chat::part(author) { font-family: 'Inter'; }
|
|
336
|
+
snice-chat::part(message-own) { background: rgba(37, 99, 235, 0.06); }
|
|
337
|
+
snice-chat::part(message-text) { font-size: 0.9375rem; }
|
|
338
|
+
```
|
|
339
|
+
|
|
234
340
|
## Accessibility
|
|
235
341
|
|
|
236
342
|
- Keyboard navigation for messages and controls
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
# Message Strip
|
|
4
4
|
`<snice-message-strip>`
|
|
5
5
|
|
|
6
|
-
An inline contextual message bar for displaying status messages within content flow. Unlike alerts (
|
|
6
|
+
An inline contextual message bar for displaying status messages within content flow. Unlike alerts (dismissible card), banners (full-width top), and toasts (floating), message strips are designed to sit inline within your content.
|
|
7
7
|
|
|
8
8
|
## Table of Contents
|
|
9
9
|
- [Properties](#properties)
|
|
@@ -20,7 +20,7 @@ An inline contextual message bar for displaying status messages within content f
|
|
|
20
20
|
| Property | Type | Default | Description |
|
|
21
21
|
|----------|------|---------|-------------|
|
|
22
22
|
| `variant` | `'info' \| 'success' \| 'warning' \| 'danger'` | `'info'` | Message type / color |
|
|
23
|
-
| `
|
|
23
|
+
| `dismissible` | `boolean` | `false` | Show dismiss button |
|
|
24
24
|
| `icon` | `string` | `''` | Custom icon (set "none" to hide default icon) |
|
|
25
25
|
|
|
26
26
|
## Methods
|
|
@@ -86,12 +86,12 @@ Use the `variant` attribute to indicate the message type.
|
|
|
86
86
|
<snice-message-strip variant="danger">An error occurred while saving.</snice-message-strip>
|
|
87
87
|
```
|
|
88
88
|
|
|
89
|
-
###
|
|
89
|
+
### Dismissible
|
|
90
90
|
|
|
91
|
-
Set the `
|
|
91
|
+
Set the `dismissible` attribute to allow users to close the message.
|
|
92
92
|
|
|
93
93
|
```html
|
|
94
|
-
<snice-message-strip variant="info"
|
|
94
|
+
<snice-message-strip variant="info" dismissible>
|
|
95
95
|
You can dismiss this message.
|
|
96
96
|
</snice-message-strip>
|
|
97
97
|
```
|
|
@@ -142,7 +142,7 @@ messageStrip.show();
|
|
|
142
142
|
|
|
143
143
|
```html
|
|
144
144
|
<form>
|
|
145
|
-
<snice-message-strip variant="danger"
|
|
145
|
+
<snice-message-strip variant="danger" dismissible style="display: none;">
|
|
146
146
|
Please fill in all required fields.
|
|
147
147
|
</snice-message-strip>
|
|
148
148
|
|
|
@@ -155,10 +155,10 @@ messageStrip.show();
|
|
|
155
155
|
|
|
156
156
|
```html
|
|
157
157
|
<div style="display: flex; flex-direction: column; gap: 8px;">
|
|
158
|
-
<snice-message-strip variant="danger"
|
|
158
|
+
<snice-message-strip variant="danger" dismissible>
|
|
159
159
|
Server connection lost.
|
|
160
160
|
</snice-message-strip>
|
|
161
|
-
<snice-message-strip variant="warning"
|
|
161
|
+
<snice-message-strip variant="warning" dismissible>
|
|
162
162
|
Your session will expire in 5 minutes.
|
|
163
163
|
</snice-message-strip>
|
|
164
164
|
<snice-message-strip variant="info">
|
package/docs/elements.md
CHANGED
|
@@ -995,6 +995,27 @@ class ReactiveComponent extends HTMLElement {
|
|
|
995
995
|
}
|
|
996
996
|
```
|
|
997
997
|
|
|
998
|
+
**Initial values.** By default a watcher fires once during initialization with the element's starting value — from markup (`<reactive-component user-name="Ada">`) or the field default — with `oldValue` undefined, then again on every later change:
|
|
999
|
+
|
|
1000
|
+
```typescript
|
|
1001
|
+
@watch('userName')
|
|
1002
|
+
onUserNameChange(oldVal: string | undefined, newVal: string) {
|
|
1003
|
+
// Init: (undefined, 'Ada')
|
|
1004
|
+
// Change: ('Ada', 'Grace')
|
|
1005
|
+
}
|
|
1006
|
+
```
|
|
1007
|
+
|
|
1008
|
+
Pass `{ immediate: false }` as the last argument for a change-only watcher — one that must not run on mount, such as a watcher that dispatches an event:
|
|
1009
|
+
|
|
1010
|
+
```typescript
|
|
1011
|
+
@watch('value', { immediate: false })
|
|
1012
|
+
onValueChange(oldVal: string, newVal: string) {
|
|
1013
|
+
this.dispatchChange(); // only on real changes, never on mount
|
|
1014
|
+
}
|
|
1015
|
+
```
|
|
1016
|
+
|
|
1017
|
+
The options object always comes after the property names, so it works with multiple watched properties too: `@watch('width', 'height', { immediate: false })`.
|
|
1018
|
+
|
|
998
1019
|
### @context() Decorator
|
|
999
1020
|
|
|
1000
1021
|
Receive router context updates. The decorated method is called whenever the router context changes (navigation, app context update, etc.):
|
package/docs/events.md
CHANGED
|
@@ -385,9 +385,56 @@ interface OnOptions {
|
|
|
385
385
|
|
|
386
386
|
// Shadow DOM delegation
|
|
387
387
|
target?: string; // CSS selector to target specific elements within shadow root
|
|
388
|
+
|
|
389
|
+
// Where to attach the listener (see scope section below)
|
|
390
|
+
scope?: 'global' | string | EventTarget | ((this: HTMLElement) => EventTarget | null);
|
|
388
391
|
}
|
|
389
392
|
```
|
|
390
393
|
|
|
394
|
+
#### scope — controlling the listener target
|
|
395
|
+
|
|
396
|
+
By default, `@on` attaches the listener to the host element. The `scope` option redirects
|
|
397
|
+
that attachment to another target, which is how Snice expresses cross-cutting events.
|
|
398
|
+
|
|
399
|
+
| `scope` value | Listener attaches to |
|
|
400
|
+
|---|---|
|
|
401
|
+
| omitted | host element (default) |
|
|
402
|
+
| `'global'` | `document` |
|
|
403
|
+
| selector string | `host.closest(selector)` — nearest matching ancestor |
|
|
404
|
+
| `Element` / `EventTarget` | that node directly |
|
|
405
|
+
| `(this) => EventTarget \| null` | called at connect; `null` skips |
|
|
406
|
+
|
|
407
|
+
The resolver function is called with the host element as `this` and re-resolves each time
|
|
408
|
+
the component reconnects to the DOM, so listeners follow the host when it moves.
|
|
409
|
+
|
|
410
|
+
```typescript
|
|
411
|
+
// Cross-cutting global event (document)
|
|
412
|
+
@on('bus:save', { scope: 'global' })
|
|
413
|
+
onSave(e: CustomEvent) { /* ... */ }
|
|
414
|
+
|
|
415
|
+
// Scoped to nearest ancestor matching the selector
|
|
416
|
+
@on('bus:cart-added', { scope: 'cart-shell' })
|
|
417
|
+
onCartAdded(e: CustomEvent) { /* ... */ }
|
|
418
|
+
|
|
419
|
+
// Explicit EventTarget
|
|
420
|
+
@on('go', { scope: someElement })
|
|
421
|
+
onGo() { /* ... */ }
|
|
422
|
+
|
|
423
|
+
// Resolver — full control, re-runs on reconnect
|
|
424
|
+
@on('beep', { scope() { return this.closest('app-shell'); } })
|
|
425
|
+
onBeep() { /* ... */ }
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
If `scope` cannot resolve (selector matches no ancestor, resolver returns `null` or throws),
|
|
429
|
+
the listener is **not attached** and a `console.warn` is emitted. The component still
|
|
430
|
+
mounts; only the listener is skipped.
|
|
431
|
+
|
|
432
|
+
Disconnect removes the listener from whichever target it was attached to. Reconnect
|
|
433
|
+
re-resolves and re-attaches, so resolver-based scopes track DOM moves correctly.
|
|
434
|
+
|
|
435
|
+
`scope` is compatible with the delegation selector — the listener attaches on the
|
|
436
|
+
scoped target and still matches the selector when an event fires within it.
|
|
437
|
+
|
|
391
438
|
#### Throttling
|
|
392
439
|
|
|
393
440
|
```typescript
|
|
@@ -534,9 +581,50 @@ interface DispatchOptions extends EventInit {
|
|
|
534
581
|
dispatchOnUndefined?: boolean; // Skip dispatch when return is undefined (default: true)
|
|
535
582
|
debounce?: number; // Debounce dispatch by ms
|
|
536
583
|
throttle?: number; // Throttle dispatch by ms
|
|
584
|
+
// Where to dispatch the event (see scope section below)
|
|
585
|
+
scope?: 'global' | string | EventTarget | ((this: HTMLElement) => EventTarget | null);
|
|
586
|
+
}
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
#### scope — controlling the dispatch target
|
|
590
|
+
|
|
591
|
+
By default, `@dispatch` calls `this.dispatchEvent(event)` — the event originates from
|
|
592
|
+
the host element. The `scope` option redirects the dispatch to another target so the
|
|
593
|
+
event behaves as if it originated there. Use this with `@on({ scope })` to express
|
|
594
|
+
cross-cutting events without going through bubbling.
|
|
595
|
+
|
|
596
|
+
| `scope` value | Event dispatched on |
|
|
597
|
+
|---|---|
|
|
598
|
+
| omitted | host element (default) |
|
|
599
|
+
| `'global'` | `document` |
|
|
600
|
+
| selector string | `host.closest(selector)` — nearest matching ancestor |
|
|
601
|
+
| `Element` / `EventTarget` | that node directly |
|
|
602
|
+
| `(this) => EventTarget \| null` | called per dispatch; `null` skips |
|
|
603
|
+
|
|
604
|
+
```typescript
|
|
605
|
+
// Global cart-add bus
|
|
606
|
+
@element('add-to-cart-button')
|
|
607
|
+
class AddToCartButton extends HTMLElement {
|
|
608
|
+
@on('click', 'button')
|
|
609
|
+
click() { this.add(this.productId); }
|
|
610
|
+
|
|
611
|
+
@dispatch('bus:cart-added', { scope: 'global' })
|
|
612
|
+
add(id: string) { return { id }; }
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
// Listener on any other element
|
|
616
|
+
@element('cart-counter')
|
|
617
|
+
class CartCounter extends HTMLElement {
|
|
618
|
+
@on('bus:cart-added', { scope: 'global' })
|
|
619
|
+
bump() { this.count++; }
|
|
537
620
|
}
|
|
538
621
|
```
|
|
539
622
|
|
|
623
|
+
If `scope` cannot resolve (selector matches no ancestor, resolver returns `null`),
|
|
624
|
+
the event is **not dispatched** and a `console.warn` is emitted. The method's return
|
|
625
|
+
value still flows through `dispatchOnUndefined` / `debounce` / `throttle` semantics
|
|
626
|
+
before the scope check.
|
|
627
|
+
|
|
540
628
|
### Debounce/Throttle
|
|
541
629
|
|
|
542
630
|
```typescript
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# snice-chat: full theming surface + declarative messages + markdown
|
|
2
|
+
|
|
3
|
+
**Date:** 2026-05-26
|
|
4
|
+
**Status:** Approved design, pre-implementation
|
|
5
|
+
|
|
6
|
+
## Problem
|
|
7
|
+
|
|
8
|
+
`snice-chat` is barely styleable. It exposes only 5 CSS parts (`base`, `messages`,
|
|
9
|
+
`input-area`, `input-container`, `input`) and theme tokens. None of the per-message
|
|
10
|
+
pieces — author name, avatar, timestamp, bubble, reactions — are reachable from
|
|
11
|
+
outside the shadow DOM. There is no per-user color, no own-vs-other distinction
|
|
12
|
+
(the component computes `isCurrentUser` but never writes it to the DOM), no
|
|
13
|
+
markdown, and no declarative authoring API (it is imperative-only via `messages[]`).
|
|
14
|
+
|
|
15
|
+
## Goals
|
|
16
|
+
|
|
17
|
+
Deliver five capabilities, all **opt-in** and **purely additive** — the default
|
|
18
|
+
render must be byte-for-byte identical to today:
|
|
19
|
+
|
|
20
|
+
- **A · Per-user name colors** — each author's name colored, Slack/Discord style.
|
|
21
|
+
- **B · Own vs other** — style "my" messages differently; ship an opt-in bubble layout.
|
|
22
|
+
- **C · Bubble / message-type theming** — restyle bubble, system message, reactions, timestamps.
|
|
23
|
+
- **D · Full part surface** — every internal element exposed as a CSS `::part`.
|
|
24
|
+
- **E · Markdown** — render message content as markdown, opt-in.
|
|
25
|
+
|
|
26
|
+
Plus the architectural change the user approved:
|
|
27
|
+
|
|
28
|
+
- **Declarative `<snice-chat-message>` sub-element** giving `snice-chat` the dual API
|
|
29
|
+
(imperative array **or** slotted children) required of collection components.
|
|
30
|
+
|
|
31
|
+
## Non-Goals (explicitly out of scope)
|
|
32
|
+
|
|
33
|
+
- **CDN bundling of the new sub-element.** The known table/`snice-column` CDN
|
|
34
|
+
gotcha is not solved here. Do not touch the CDN build for this work.
|
|
35
|
+
- Inline message editing UX (stays the existing `prompt()` behavior).
|
|
36
|
+
- Threads / reaction pickers / any new interaction.
|
|
37
|
+
|
|
38
|
+
## Architecture
|
|
39
|
+
|
|
40
|
+
Follows the existing **table / `snice-column` pattern**: the sub-element is a
|
|
41
|
+
declarative *config carrier*, not a self-rendering element. The parent keeps
|
|
42
|
+
ownership of all rendering, so the styling part surface stays flat — no nested
|
|
43
|
+
shadow DOM, no `exportparts` chaining.
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
<snice-chat> parent — owns rendering, owns the part surface
|
|
47
|
+
├─ messages[] (imperative API) ┐
|
|
48
|
+
│ ├─ merged → renders message rows in its shadow DOM
|
|
49
|
+
└─ <snice-chat-message slot> ──┘ (slot wins when present)
|
|
50
|
+
(declarative config carrier, render() = <slot></slot>, renders nothing)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Ingestion mirrors the table:
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
await customElements.whenDefined('snice-chat-message');
|
|
57
|
+
const els = Array.from(this.querySelectorAll('snice-chat-message[slot="messages"]'));
|
|
58
|
+
this.messages = els.map(el => el.getMessageDefinition());
|
|
59
|
+
// re-read on bubbling 'message-changed'
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## New element: `<snice-chat-message>`
|
|
63
|
+
|
|
64
|
+
Files: `components/chat/snice-chat-message.ts`, `snice-chat-message.types.ts`, `snice-chat-message.css` (minimal).
|
|
65
|
+
|
|
66
|
+
- `@element('snice-chat-message')`, `@render()` → `html\`<slot></slot>\``.
|
|
67
|
+
- Attributes: `author`, `avatar`, `timestamp`, `type`, `format` (`text` | `markdown`),
|
|
68
|
+
`edited` (boolean), `author-color`.
|
|
69
|
+
- Message body = default slot text content.
|
|
70
|
+
- `getMessageDefinition(): ChatMessage` — serializes props to a `ChatMessage`.
|
|
71
|
+
- Bubbles `message-changed` (`{ message: ChatMessage }`) on any prop change, so the
|
|
72
|
+
parent re-reads (same as `snice-column`'s `column-changed`).
|
|
73
|
+
|
|
74
|
+
## `<snice-chat>` additions — all additive
|
|
75
|
+
|
|
76
|
+
### 1. Dual API
|
|
77
|
+
Keep `messages[]`, `addMessage`, `updateMessage`, `deleteMessage`, `clear`. Also
|
|
78
|
+
ingest slotted `<snice-chat-message slot="messages">` via the table pattern above.
|
|
79
|
+
Slot children win when present.
|
|
80
|
+
|
|
81
|
+
### 2. Per-user name colors (A)
|
|
82
|
+
- New property `authorColors: Record<string, string>` (override map).
|
|
83
|
+
- New boolean attribute `color-authors` — opt-in to automatic coloring.
|
|
84
|
+
- Resolution per message, computed inside the component instance (no global
|
|
85
|
+
registry, no singleton):
|
|
86
|
+
1. `authorColors[author]` if set, else
|
|
87
|
+
2. auto: stable hash of author name → fixed accent palette **only when `color-authors` is present**, else
|
|
88
|
+
3. unset → falls through to the current default color.
|
|
89
|
+
- Implementation: author element gets `style="--snice-chat-author-color:${resolved}"`
|
|
90
|
+
when a color resolves; CSS reads `color: var(--snice-chat-author-color, <current default token>)`.
|
|
91
|
+
Inline-CSS-var injection is the established snice idiom (`--c`, `--bar-delay`,
|
|
92
|
+
`--volume-percent`, `--form-columns`). **No `data-*` styling hooks.**
|
|
93
|
+
|
|
94
|
+
### 3. Own vs other (B)
|
|
95
|
+
- Each message row gets space-separated part names: `part="message message-own"`
|
|
96
|
+
or `part="message message-other"` (the established stateful-variant idiom —
|
|
97
|
+
cf. `part="button first-button"`). Default CSS for these adds nothing visual.
|
|
98
|
+
- Opt-in `layout="bubbles"` attribute ships the aligned colored-bubble look via
|
|
99
|
+
`:host([layout="bubbles"])` rules. Absent attribute = today's look.
|
|
100
|
+
|
|
101
|
+
### 4. Bubble / type theming (C) + full part surface (D)
|
|
102
|
+
Add `part=` to: `avatar`, `author`, `timestamp`, `edited`, `message-text`,
|
|
103
|
+
`attachment`, `reactions`, `reaction`, `message-actions`, `system-message`,
|
|
104
|
+
`typing-indicator`. (Generic role names; stateful variants via space-separated
|
|
105
|
+
second names where applicable.)
|
|
106
|
+
|
|
107
|
+
### 5. Markdown (E)
|
|
108
|
+
- Add `format?: 'text' | 'markdown'` to `ChatMessage`.
|
|
109
|
+
- New boolean attribute `markdown` — component-wide default.
|
|
110
|
+
- A message renders as markdown when `message.format === 'markdown'`, or when the
|
|
111
|
+
`markdown` attribute is set and `message.format !== 'text'` (per-message `'text'`
|
|
112
|
+
overrides the component default).
|
|
113
|
+
- Markdown rendered through the existing `<snice-markdown>` component; import follows
|
|
114
|
+
the existing `import '../empty-state/snice-empty-state'` precedent. Off by default.
|
|
115
|
+
|
|
116
|
+
### Types
|
|
117
|
+
- `ChatMessage` gains `format?: 'text' | 'markdown'`.
|
|
118
|
+
- New `SniceChatMessageElement` interface + `SniceChatMessageEventMap`.
|
|
119
|
+
- `snice-chat` gains `authorColors`, `markdown`, `colorAuthors`, `layout` on its element interface.
|
|
120
|
+
|
|
121
|
+
## Deliverables
|
|
122
|
+
|
|
123
|
+
- Source: the new element (3 files) + additive edits to `snice-chat.ts`, `.types.ts`, `.css`.
|
|
124
|
+
- React adapter: metadata for `snice-chat` (new props) and new `snice-chat-message` in
|
|
125
|
+
`scripts/generate-react-adapters.js`; regenerate adapters + tests.
|
|
126
|
+
- Tests: unit tests for both elements (see Verification).
|
|
127
|
+
- Docs: `docs/components/chat.md` and `docs/ai/components/chat.md` updated to mirror —
|
|
128
|
+
new properties, attributes, parts, the sub-element, markdown, layout. Behavior + API
|
|
129
|
+
only; no internal symbol names or framework plumbing in the prose.
|
|
130
|
+
- Showcase: update `public/showcases/chat.html` to demo the new capabilities.
|
|
131
|
+
|
|
132
|
+
## Verification (required before calling done)
|
|
133
|
+
|
|
134
|
+
- **Tests for everything authored.** Cover: dual-API ingestion (array, slot, both →
|
|
135
|
+
slot wins), boundary cases (no messages, one, many), author-color resolution
|
|
136
|
+
(map / auto / default / `color-authors` off), own/other part names, markdown
|
|
137
|
+
on/off and per-message override, all new parts present, default render unchanged.
|
|
138
|
+
- **Full suite:** `npm test` — the whole vitest suite, not a filtered path. Every
|
|
139
|
+
failure is in scope to fix; no "pre-existing" excuses.
|
|
140
|
+
- **Visual confirmation of all authored code** — exercise the live component in the
|
|
141
|
+
browser (showcase/demo), in **both dark and light** (Snice defaults to dark). Confirm:
|
|
142
|
+
default render unchanged, per-user colors, bubble layout, markdown, system messages,
|
|
143
|
+
reactions. Visual defects are bugs, not "polish later".
|
|
144
|
+
|
|
145
|
+
## Key design decisions
|
|
146
|
+
|
|
147
|
+
1. **Sub-element is a config carrier, not self-rendering** — mirrors `snice-column`.
|
|
148
|
+
Keeps the part surface on the parent's shadow DOM (flat `::part`, no `exportparts`).
|
|
149
|
+
2. **Auto-coloring is opt-in (`color-authors`), not on by default** — preserves the
|
|
150
|
+
byte-for-byte-unchanged default render. `authorColors` map always wins over auto.
|
|
151
|
+
3. **Per-author color via inline `--snice-chat-author-color`, not `data-*`** — matches
|
|
152
|
+
the snice dynamic-per-item idiom; `data-*` in snice are behavioral/JS hooks only.
|
|
153
|
+
4. **Own/other via space-separated part names**, matching `part="button first-button"`.
|
|
154
|
+
5. **Markdown reuses `<snice-markdown>`**, imported like the existing empty-state import.
|
|
155
|
+
6. **CDN bundling of the sub-element is out of scope** by explicit instruction.
|