snice 4.13.0 → 4.15.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/adapters/react/doc.d.ts +1 -0
- package/adapters/react/doc.d.ts.map +1 -1
- package/adapters/react/doc.js +1 -1
- package/adapters/react/doc.js.map +1 -1
- package/adapters/react/doc.tsx +2 -1
- package/adapters/react/modal.d.ts +2 -0
- package/adapters/react/modal.d.ts.map +1 -1
- package/adapters/react/modal.js +1 -1
- package/adapters/react/modal.js.map +1 -1
- package/adapters/react/modal.tsx +3 -1
- package/dist/cdn/accordion/snice-accordion.js +1 -1
- package/dist/cdn/accordion/snice-accordion.min.js +1 -1
- package/dist/cdn/alert/snice-alert.js +1 -1
- package/dist/cdn/alert/snice-alert.min.js +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/audio-recorder/snice-audio-recorder.js +1 -1
- package/dist/cdn/audio-recorder/snice-audio-recorder.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/badge/snice-badge.js +1 -1
- package/dist/cdn/badge/snice-badge.min.js +1 -1
- package/dist/cdn/banner/snice-banner.js +1 -1
- package/dist/cdn/banner/snice-banner.min.js +1 -1
- package/dist/cdn/book/README.md +2 -2
- package/dist/cdn/book/snice-book.js +29 -8
- package/dist/cdn/book/snice-book.js.map +1 -1
- package/dist/cdn/book/snice-book.min.js +3 -3
- package/dist/cdn/book/snice-book.min.js.map +1 -1
- package/dist/cdn/breadcrumbs/snice-breadcrumbs.js +1 -1
- package/dist/cdn/breadcrumbs/snice-breadcrumbs.min.js +1 -1
- package/dist/cdn/button/snice-button.js +1 -1
- package/dist/cdn/button/snice-button.min.js +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/chart/snice-chart.js +1 -1
- package/dist/cdn/chart/snice-chart.min.js +1 -1
- package/dist/cdn/chat/snice-chat.js +1 -1
- package/dist/cdn/chat/snice-chat.min.js +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.min.js +1 -1
- package/dist/cdn/code-block/snice-code-block.js +5 -5
- package/dist/cdn/code-block/snice-code-block.js.map +1 -1
- package/dist/cdn/code-block/snice-code-block.min.js +3 -3
- package/dist/cdn/code-block/snice-code-block.min.js.map +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/snice-command-palette.js +1 -1
- package/dist/cdn/command-palette/snice-command-palette.min.js +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/date-picker/README.md +1 -1
- package/dist/cdn/date-picker/snice-date-picker.js +49 -39
- package/dist/cdn/date-picker/snice-date-picker.js.map +1 -1
- package/dist/cdn/date-picker/snice-date-picker.min.js +4 -4
- package/dist/cdn/date-picker/snice-date-picker.min.js.map +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/README.md +2 -2
- package/dist/cdn/doc/snice-doc.js +221 -35
- package/dist/cdn/doc/snice-doc.js.map +1 -1
- package/dist/cdn/doc/snice-doc.min.js +2 -2
- package/dist/cdn/doc/snice-doc.min.js.map +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.min.js +1 -1
- package/dist/cdn/empty-state/snice-empty-state.js +1 -1
- package/dist/cdn/empty-state/snice-empty-state.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/funnel/snice-funnel.js +1 -1
- package/dist/cdn/funnel/snice-funnel.min.js +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/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.min.js +1 -1
- package/dist/cdn/input/snice-input.js +1 -1
- package/dist/cdn/input/snice-input.min.js +1 -1
- package/dist/cdn/kanban/snice-kanban.js +1 -1
- package/dist/cdn/kanban/snice-kanban.min.js +1 -1
- package/dist/cdn/kpi/snice-kpi.js +1 -1
- package/dist/cdn/kpi/snice-kpi.min.js +1 -1
- package/dist/cdn/layout/snice-layout.js +1 -1
- package/dist/cdn/layout/snice-layout.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 +2 -2
- package/dist/cdn/link-preview/snice-link-preview.js.map +1 -1
- package/dist/cdn/link-preview/snice-link-preview.min.js +2 -2
- package/dist/cdn/link-preview/snice-link-preview.min.js.map +1 -1
- package/dist/cdn/list/snice-list.js +4 -4
- package/dist/cdn/list/snice-list.js.map +1 -1
- package/dist/cdn/list/snice-list.min.js +2 -2
- 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.min.js +1 -1
- package/dist/cdn/login/snice-login.js +1 -1
- package/dist/cdn/login/snice-login.min.js +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/snice-markdown.js +1 -1
- package/dist/cdn/markdown/snice-markdown.min.js +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/modal/README.md +2 -2
- package/dist/cdn/modal/snice-modal.js +34 -18
- package/dist/cdn/modal/snice-modal.js.map +1 -1
- package/dist/cdn/modal/snice-modal.min.js +24 -20
- package/dist/cdn/modal/snice-modal.min.js.map +1 -1
- package/dist/cdn/music-player/README.md +2 -2
- package/dist/cdn/music-player/snice-music-player.js +8 -1
- package/dist/cdn/music-player/snice-music-player.js.map +1 -1
- package/dist/cdn/music-player/snice-music-player.min.js +3 -3
- package/dist/cdn/music-player/snice-music-player.min.js.map +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.min.js +1 -1
- package/dist/cdn/notification-center/snice-notification-center.js +1 -1
- package/dist/cdn/notification-center/snice-notification-center.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/podcast-player/snice-podcast-player.js +1 -1
- package/dist/cdn/podcast-player/snice-podcast-player.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/progress/snice-progress.js +1 -1
- package/dist/cdn/progress/snice-progress.min.js +1 -1
- package/dist/cdn/qr-code/README.md +2 -2
- package/dist/cdn/qr-code/snice-qr-code.js +149 -20
- package/dist/cdn/qr-code/snice-qr-code.js.map +1 -1
- package/dist/cdn/qr-code/snice-qr-code.min.js +3 -3
- package/dist/cdn/qr-code/snice-qr-code.min.js.map +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/README.md +2 -2
- package/dist/cdn/radio/snice-radio.js +23 -3
- package/dist/cdn/radio/snice-radio.js.map +1 -1
- package/dist/cdn/radio/snice-radio.min.js +3 -3
- package/dist/cdn/radio/snice-radio.min.js.map +1 -1
- package/dist/cdn/rating/snice-rating.js +1 -1
- package/dist/cdn/rating/snice-rating.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 +514 -47
- package/dist/cdn/runtime/snice-runtime.esm.js.map +1 -1
- package/dist/cdn/runtime/snice-runtime.esm.min.js +6 -6
- package/dist/cdn/runtime/snice-runtime.esm.min.js.map +1 -1
- package/dist/cdn/runtime/snice-runtime.js +6420 -5951
- package/dist/cdn/runtime/snice-runtime.js.map +1 -1
- package/dist/cdn/runtime/snice-runtime.min.js +18 -18
- 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.min.js +1 -1
- package/dist/cdn/select/README.md +2 -2
- package/dist/cdn/select/snice-select.js +46 -92
- package/dist/cdn/select/snice-select.js.map +1 -1
- package/dist/cdn/select/snice-select.min.js +5 -13
- package/dist/cdn/select/snice-select.min.js.map +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 +2 -2
- package/dist/cdn/slider/snice-slider.js.map +1 -1
- package/dist/cdn/slider/snice-slider.min.js +5 -5
- package/dist/cdn/slider/snice-slider.min.js.map +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-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/spreadsheet/snice-spreadsheet.js +1 -1
- package/dist/cdn/spreadsheet/snice-spreadsheet.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/README.md +1 -1
- package/dist/cdn/switch/snice-switch.js +33 -23
- package/dist/cdn/switch/snice-switch.js.map +1 -1
- package/dist/cdn/switch/snice-switch.min.js +3 -3
- package/dist/cdn/switch/snice-switch.min.js.map +1 -1
- package/dist/cdn/table/README.md +2 -2
- package/dist/cdn/table/snice-table.js +2857 -110
- package/dist/cdn/table/snice-table.js.map +1 -1
- package/dist/cdn/table/snice-table.min.js +187 -47
- 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-input/snice-tag-input.js +1 -1
- package/dist/cdn/tag-input/snice-tag-input.min.js +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-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.min.js +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/README.md +1 -1
- package/dist/cdn/toast/snice-toast.js +3 -3
- package/dist/cdn/toast/snice-toast.js.map +1 -1
- package/dist/cdn/toast/snice-toast.min.js +2 -2
- 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.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/components/book/snice-book.d.ts +2 -0
- package/dist/components/book/snice-book.js +28 -7
- package/dist/components/book/snice-book.js.map +1 -1
- package/dist/components/book/snice-book.types.d.ts +7 -0
- package/dist/components/code-block/snice-code-block.js +4 -4
- package/dist/components/code-block/snice-code-block.js.map +1 -1
- package/dist/components/code-block/snice-code-block.types.d.ts +3 -3
- package/dist/components/date-picker/snice-date-picker.d.ts +2 -0
- package/dist/components/date-picker/snice-date-picker.js +49 -39
- package/dist/components/date-picker/snice-date-picker.js.map +1 -1
- package/dist/components/doc/snice-doc.d.ts +20 -0
- package/dist/components/doc/snice-doc.js +220 -34
- package/dist/components/doc/snice-doc.js.map +1 -1
- package/dist/components/link-preview/snice-link-preview.js +1 -1
- package/dist/components/link-preview/snice-link-preview.js.map +1 -1
- package/dist/components/list/snice-list.js +3 -3
- package/dist/components/list/snice-list.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/modal/snice-modal.d.ts +2 -0
- package/dist/components/modal/snice-modal.js +33 -17
- package/dist/components/modal/snice-modal.js.map +1 -1
- package/dist/components/modal/snice-modal.types.d.ts +2 -0
- package/dist/components/music-player/snice-music-player.d.ts +1 -0
- package/dist/components/music-player/snice-music-player.js +7 -0
- package/dist/components/music-player/snice-music-player.js.map +1 -1
- package/dist/components/notification-center/snice-notification-center.d.ts +1 -1
- package/dist/components/notification-center/snice-notification-center.js.map +1 -1
- package/dist/components/notification-center/snice-notification-center.types.d.ts +1 -0
- package/dist/components/qr-code/qrcode.d.ts +1 -0
- package/dist/components/qr-code/qrcode.js +16 -8
- package/dist/components/qr-code/qrcode.js.map +1 -1
- package/dist/components/qr-code/snice-qr-code.d.ts +5 -2
- package/dist/components/qr-code/snice-qr-code.js +132 -11
- package/dist/components/qr-code/snice-qr-code.js.map +1 -1
- package/dist/components/qr-code/snice-qr-code.types.d.ts +3 -2
- package/dist/components/radio/snice-radio.d.ts +1 -0
- package/dist/components/radio/snice-radio.js +22 -2
- package/dist/components/radio/snice-radio.js.map +1 -1
- package/dist/components/select/snice-select.d.ts +2 -4
- package/dist/components/select/snice-select.js +46 -92
- package/dist/components/select/snice-select.js.map +1 -1
- package/dist/components/slider/snice-slider.js +1 -1
- package/dist/components/slider/snice-slider.js.map +1 -1
- package/dist/components/switch/snice-switch.d.ts +2 -0
- package/dist/components/switch/snice-switch.js +32 -22
- package/dist/components/switch/snice-switch.js.map +1 -1
- package/dist/components/table/snice-table.d.ts +2 -0
- package/dist/components/table/snice-table.js +17 -3
- package/dist/components/table/snice-table.js.map +1 -1
- package/dist/components/toast/snice-toast-container.js +2 -2
- package/dist/components/toast/snice-toast-container.js.map +1 -1
- package/dist/index.cjs +513 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.esm.js +512 -45
- package/dist/index.esm.js.map +1 -1
- package/dist/index.iife.js +513 -44
- package/dist/index.iife.js.map +1 -1
- package/dist/symbols.cjs +1 -1
- package/dist/symbols.esm.js +1 -1
- package/dist/tooltip-observer.d.ts +11 -0
- package/dist/transitions.cjs +1 -1
- package/dist/transitions.esm.js +1 -1
- package/dist/types/request-options.d.ts +1 -1
- package/docs/ai/DEVELOPMENT.md +1 -1
- package/docs/ai/api.md +15 -11
- package/docs/ai/architecture.md +18 -5
- package/docs/ai/components/app-tiles.md +1 -1
- package/docs/ai/components/book.md +5 -6
- package/docs/ai/components/camera-annotate.md +3 -3
- package/docs/ai/components/candlestick.md +3 -3
- package/docs/ai/components/chart.md +1 -1
- package/docs/ai/components/code-block.md +4 -4
- package/docs/ai/components/doc.md +26 -15
- package/docs/ai/components/file-gallery.md +1 -1
- package/docs/ai/components/link-preview.md +1 -1
- package/docs/ai/components/list.md +2 -2
- package/docs/ai/components/markdown.md +13 -6
- package/docs/ai/components/modal.md +2 -0
- package/docs/ai/components/music-player.md +3 -2
- package/docs/ai/components/network-graph.md +5 -5
- package/docs/ai/components/notification-center.md +1 -0
- package/docs/ai/components/pdf-viewer.md +1 -1
- package/docs/ai/components/radio.md +2 -2
- package/docs/ai/components/sankey.md +3 -3
- package/docs/ai/components/select.md +1 -1
- package/docs/ai/components/tooltip.md +54 -0
- package/docs/ai/decorators.md +6 -6
- package/docs/ai/patterns.md +17 -6
- package/docs/code-block.md +5 -7
- package/docs/components/app-tiles.md +1 -1
- package/docs/components/book.md +3 -4
- package/docs/components/button.md +2 -2
- package/docs/components/camera-annotate.md +6 -6
- package/docs/components/candlestick.md +6 -6
- package/docs/components/chart.md +4 -6
- package/docs/components/checkbox.md +3 -3
- package/docs/components/chip.md +4 -4
- package/docs/components/code-block.md +4 -3
- package/docs/components/doc.md +99 -58
- package/docs/components/file-gallery.md +25 -3
- package/docs/components/kpi.md +2 -3
- package/docs/components/link-preview.md +2 -2
- package/docs/components/list.md +3 -3
- package/docs/components/markdown.md +14 -36
- package/docs/components/modal.md +2 -0
- package/docs/components/music-player.md +3 -2
- package/docs/components/network-graph.md +7 -7
- package/docs/components/notification-center.md +1 -0
- package/docs/components/pdf-viewer.md +1 -1
- package/docs/components/sankey.md +6 -6
- package/docs/components/switch.md +1 -1
- package/docs/components/table.md +2 -2
- package/docs/components/tooltip.md +133 -0
- package/docs/controllers.md +92 -396
- package/docs/elements.md +131 -118
- package/docs/events.md +75 -81
- package/docs/fetcher.md +64 -76
- package/docs/observe.md +13 -33
- package/docs/placards.md +6 -16
- package/docs/request-response.md +173 -693
- package/docs/routing.md +67 -136
- package/package.json +1 -1
- package/docs/migration-v2-to-v3.md +0 -569
package/docs/elements.md
CHANGED
|
@@ -10,7 +10,7 @@ Elements are the core building blocks of Snice components. They define custom HT
|
|
|
10
10
|
- [Queries](#queries)
|
|
11
11
|
- [Styling](#styling)
|
|
12
12
|
- [Template Events](#template-events)
|
|
13
|
-
- [Advanced Examples](#advanced-examples)
|
|
13
|
+
- [Advanced Examples](#advanced-examples) (Watch, Context, Conditionals)
|
|
14
14
|
|
|
15
15
|
## Basic Usage
|
|
16
16
|
|
|
@@ -30,8 +30,10 @@ class MyButton extends HTMLElement {
|
|
|
30
30
|
|
|
31
31
|
### Element Decorator Options
|
|
32
32
|
|
|
33
|
-
The `@element` decorator accepts
|
|
33
|
+
The `@element` decorator accepts:
|
|
34
34
|
- `tagName: string` - The custom element tag name (must contain a hyphen)
|
|
35
|
+
- `options?: ElementOptions` - Optional configuration
|
|
36
|
+
- `formAssociated?: boolean` - Enable form association (default: false)
|
|
35
37
|
|
|
36
38
|
## Lifecycle Methods
|
|
37
39
|
|
|
@@ -106,7 +108,7 @@ class SimpleList extends HTMLElement {
|
|
|
106
108
|
- Avoiding differential rendering issues with dynamic attributes
|
|
107
109
|
- Simple components where full re-render is acceptable
|
|
108
110
|
|
|
109
|
-
**Note:** When `differential: false`, the render method must return a string (not `html\`...\``)
|
|
111
|
+
**Note:** When `differential: false`, the render method must return a string (not `html\`...\``). Conditional rendering (`<if>`, `<switch>/<case>`) is NOT available — use ternary operators in the string template instead.
|
|
110
112
|
|
|
111
113
|
### Imperative Rendering
|
|
112
114
|
|
|
@@ -132,7 +134,7 @@ class UserCard extends HTMLElement {
|
|
|
132
134
|
}
|
|
133
135
|
|
|
134
136
|
@watch('name', 'role')
|
|
135
|
-
update() {
|
|
137
|
+
update(oldVal: any, newVal: any, prop: string) {
|
|
136
138
|
if (!this.$name) return;
|
|
137
139
|
this.$name.textContent = this.name;
|
|
138
140
|
this.$role.textContent = this.role;
|
|
@@ -195,44 +197,39 @@ class StyledCard extends HTMLElement {
|
|
|
195
197
|
}
|
|
196
198
|
```
|
|
197
199
|
|
|
198
|
-
**
|
|
200
|
+
**Note:** Only one `@styles()` method is supported per element. If multiple are declared, only the last one is used. Combine all styles in a single method:
|
|
201
|
+
|
|
199
202
|
```typescript
|
|
200
203
|
@styles()
|
|
201
|
-
|
|
204
|
+
componentStyles() {
|
|
202
205
|
return css`
|
|
203
206
|
:host { display: block; }
|
|
204
|
-
// ...
|
|
205
|
-
`;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
@styles()
|
|
209
|
-
themeStyles() {
|
|
210
|
-
return css`
|
|
211
207
|
.card { background: var(--bg-color); }
|
|
212
|
-
// ...
|
|
213
208
|
`;
|
|
214
209
|
}
|
|
215
210
|
```
|
|
216
211
|
|
|
217
212
|
### Lifecycle Decorators
|
|
218
213
|
|
|
219
|
-
**@ready()** - Called after
|
|
214
|
+
**@ready()** - Called after styles are applied and event handlers are set up. The initial render may still be completing in a microtask — use `@query` (which re-queries each access) to safely access rendered DOM:
|
|
220
215
|
|
|
221
216
|
```typescript
|
|
222
|
-
import { element, ready, render, html } from 'snice';
|
|
217
|
+
import { element, ready, query, render, html } from 'snice';
|
|
218
|
+
|
|
219
|
+
@element('auto-resize-textarea')
|
|
220
|
+
class AutoResizeTextarea extends HTMLElement {
|
|
221
|
+
@query('textarea') textarea?: HTMLTextAreaElement;
|
|
223
222
|
|
|
224
|
-
@element('data-loader')
|
|
225
|
-
class DataLoader extends HTMLElement {
|
|
226
223
|
@ready()
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
224
|
+
adjustHeight() {
|
|
225
|
+
if (this.textarea) {
|
|
226
|
+
this.textarea.style.height = `${this.textarea.scrollHeight}px`;
|
|
227
|
+
}
|
|
231
228
|
}
|
|
232
229
|
|
|
233
230
|
@render()
|
|
234
231
|
renderContent() {
|
|
235
|
-
return html`<
|
|
232
|
+
return html`<textarea @input=${this.adjustHeight}></textarea>`;
|
|
236
233
|
}
|
|
237
234
|
}
|
|
238
235
|
```
|
|
@@ -240,27 +237,29 @@ class DataLoader extends HTMLElement {
|
|
|
240
237
|
**@dispose()** - Called when element is removed from DOM:
|
|
241
238
|
|
|
242
239
|
```typescript
|
|
243
|
-
@element('
|
|
244
|
-
class
|
|
245
|
-
private
|
|
240
|
+
@element('animated-element')
|
|
241
|
+
class AnimatedElement extends HTMLElement {
|
|
242
|
+
private rafId?: number;
|
|
246
243
|
|
|
247
244
|
@ready()
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
245
|
+
startAnimation() {
|
|
246
|
+
const animate = () => {
|
|
247
|
+
// Update animation frame
|
|
248
|
+
this.rafId = requestAnimationFrame(animate);
|
|
249
|
+
};
|
|
250
|
+
this.rafId = requestAnimationFrame(animate);
|
|
252
251
|
}
|
|
253
252
|
|
|
254
253
|
@dispose()
|
|
255
|
-
|
|
256
|
-
if (this.
|
|
257
|
-
|
|
254
|
+
stopAnimation() {
|
|
255
|
+
if (this.rafId) {
|
|
256
|
+
cancelAnimationFrame(this.rafId);
|
|
258
257
|
}
|
|
259
258
|
}
|
|
260
259
|
|
|
261
260
|
@render()
|
|
262
261
|
renderContent() {
|
|
263
|
-
return html`<
|
|
262
|
+
return html`<canvas width="300" height="200"></canvas>`;
|
|
264
263
|
}
|
|
265
264
|
}
|
|
266
265
|
```
|
|
@@ -279,20 +278,23 @@ await (el as any).ready; // Wait for element to be ready
|
|
|
279
278
|
|
|
280
279
|
All elements automatically use Shadow DOM for style encapsulation.
|
|
281
280
|
|
|
282
|
-
### Accessing Shadow
|
|
281
|
+
### Accessing Shadow DOM Elements
|
|
282
|
+
|
|
283
|
+
Use `@query` instead of manual `shadowRoot.querySelector`:
|
|
283
284
|
|
|
284
285
|
```typescript
|
|
285
286
|
@element('shadow-demo')
|
|
286
287
|
class ShadowDemo extends HTMLElement {
|
|
288
|
+
@query('#content') content?: HTMLElement;
|
|
289
|
+
|
|
287
290
|
@render()
|
|
288
291
|
renderContent() {
|
|
289
292
|
return html`<div id="content">Hello</div>`;
|
|
290
293
|
}
|
|
291
294
|
|
|
292
295
|
updateContent(text: string) {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
content.textContent = text;
|
|
296
|
+
if (this.content) {
|
|
297
|
+
this.content.textContent = text;
|
|
296
298
|
}
|
|
297
299
|
}
|
|
298
300
|
}
|
|
@@ -341,9 +343,8 @@ Usage:
|
|
|
341
343
|
```typescript
|
|
342
344
|
interface PropertyOptions {
|
|
343
345
|
type?: String | Number | Boolean | Array | Object | Date | BigInt | SimpleArray;
|
|
344
|
-
attribute?: string;
|
|
346
|
+
attribute?: string | boolean; // Custom attribute name, or false to disable attribute sync
|
|
345
347
|
converter?: PropertyConverter; // Custom converter
|
|
346
|
-
hasChanged?: (value: any, oldValue: any) => boolean;
|
|
347
348
|
}
|
|
348
349
|
```
|
|
349
350
|
|
|
@@ -351,10 +352,12 @@ interface PropertyOptions {
|
|
|
351
352
|
|
|
352
353
|
All properties automatically:
|
|
353
354
|
- Read from DOM attributes when present
|
|
354
|
-
- Reflect changes to corresponding attributes
|
|
355
|
+
- Reflect property setter changes to corresponding attributes
|
|
355
356
|
- Convert between string attributes and typed properties
|
|
356
357
|
- Trigger re-renders when changed
|
|
357
358
|
|
|
359
|
+
**Note:** Initial field values (defaults like `name = 'Anonymous'`) are NOT reflected to attributes. Only changes made via the property setter are reflected. Set `attribute: false` to disable attribute sync entirely.
|
|
360
|
+
|
|
358
361
|
```typescript
|
|
359
362
|
@element('reflected-props')
|
|
360
363
|
class ReflectedProps extends HTMLElement {
|
|
@@ -568,26 +571,28 @@ class ScopedStyles extends HTMLElement {
|
|
|
568
571
|
|
|
569
572
|
### Dynamic Styles
|
|
570
573
|
|
|
574
|
+
`@styles()` is called **once** during initialization and does not update on property changes. For dynamic styling, use CSS custom properties set in the template:
|
|
575
|
+
|
|
571
576
|
```typescript
|
|
572
577
|
@element('theme-component')
|
|
573
578
|
class ThemeComponent extends HTMLElement {
|
|
574
579
|
@property()
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
@property({ type: Number })
|
|
578
|
-
fontSize = 16;
|
|
580
|
+
accentColor = '#007bff';
|
|
579
581
|
|
|
580
582
|
@render()
|
|
581
583
|
renderContent() {
|
|
582
|
-
return html
|
|
584
|
+
return html`
|
|
585
|
+
<div class="themed" style="--accent: ${this.accentColor}">
|
|
586
|
+
Themed content
|
|
587
|
+
</div>
|
|
588
|
+
`;
|
|
583
589
|
}
|
|
584
590
|
|
|
585
591
|
@styles()
|
|
586
592
|
themeStyles() {
|
|
587
593
|
return css`
|
|
588
594
|
.themed {
|
|
589
|
-
color:
|
|
590
|
-
font-size: ${this.fontSize}px;
|
|
595
|
+
color: var(--accent);
|
|
591
596
|
}
|
|
592
597
|
`;
|
|
593
598
|
}
|
|
@@ -722,35 +727,38 @@ class FormHandler extends HTMLElement {
|
|
|
722
727
|
|
|
723
728
|
## Advanced Examples
|
|
724
729
|
|
|
725
|
-
###
|
|
730
|
+
### Form Component
|
|
731
|
+
|
|
732
|
+
Elements handle visual behavior — they render the form and emit events. Business logic (API calls, validation) belongs in controllers:
|
|
726
733
|
|
|
727
734
|
```typescript
|
|
728
|
-
import { element, property, query,
|
|
735
|
+
import { element, property, query, dispatch, render, styles, html, css } from 'snice';
|
|
729
736
|
|
|
730
737
|
@element('registration-form')
|
|
731
738
|
class RegistrationForm extends HTMLElement {
|
|
732
739
|
@property({ type: Boolean })
|
|
733
740
|
loading = false;
|
|
734
741
|
|
|
735
|
-
@query('form')
|
|
736
|
-
|
|
742
|
+
@query('form') form?: HTMLFormElement;
|
|
743
|
+
|
|
744
|
+
@dispatch('register-submit')
|
|
745
|
+
handleSubmit(event: Event) {
|
|
746
|
+
event.preventDefault();
|
|
747
|
+
return Object.fromEntries(new FormData(this.form!));
|
|
748
|
+
}
|
|
737
749
|
|
|
738
750
|
@render()
|
|
739
751
|
renderContent() {
|
|
740
752
|
return html`
|
|
741
753
|
<form @submit=${this.handleSubmit}>
|
|
742
|
-
<h2>Register</h2>
|
|
743
|
-
|
|
744
754
|
<div class="field">
|
|
745
755
|
<label>Username</label>
|
|
746
756
|
<input type="text" name="username" required>
|
|
747
757
|
</div>
|
|
748
|
-
|
|
749
758
|
<div class="field">
|
|
750
759
|
<label>Email</label>
|
|
751
760
|
<input type="email" name="email" required>
|
|
752
761
|
</div>
|
|
753
|
-
|
|
754
762
|
<button type="submit" ?disabled=${this.loading}>
|
|
755
763
|
${this.loading ? 'Registering...' : 'Register'}
|
|
756
764
|
</button>
|
|
@@ -764,78 +772,37 @@ class RegistrationForm extends HTMLElement {
|
|
|
764
772
|
:host {
|
|
765
773
|
display: block;
|
|
766
774
|
max-width: 400px;
|
|
767
|
-
margin: 0 auto;
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
form {
|
|
771
|
-
padding: 20px;
|
|
772
|
-
background: white;
|
|
773
|
-
border-radius: 8px;
|
|
774
775
|
}
|
|
775
776
|
|
|
776
777
|
.field {
|
|
777
|
-
margin-bottom:
|
|
778
|
+
margin-bottom: 1rem;
|
|
778
779
|
}
|
|
779
780
|
|
|
780
781
|
label {
|
|
781
782
|
display: block;
|
|
782
|
-
margin-bottom:
|
|
783
|
+
margin-bottom: 0.25rem;
|
|
783
784
|
font-weight: bold;
|
|
784
785
|
}
|
|
785
786
|
|
|
786
787
|
input {
|
|
787
788
|
width: 100%;
|
|
788
|
-
padding:
|
|
789
|
-
border: 1px solid #ddd;
|
|
789
|
+
padding: 0.5rem;
|
|
790
|
+
border: 1px solid var(--snice-color-border, #ddd);
|
|
790
791
|
border-radius: 4px;
|
|
791
792
|
}
|
|
792
793
|
|
|
793
|
-
button {
|
|
794
|
-
width: 100%;
|
|
795
|
-
padding: 10px;
|
|
796
|
-
background: #007bff;
|
|
797
|
-
color: white;
|
|
798
|
-
border: none;
|
|
799
|
-
border-radius: 4px;
|
|
800
|
-
cursor: pointer;
|
|
801
|
-
}
|
|
802
|
-
|
|
803
794
|
button:disabled {
|
|
804
795
|
opacity: 0.6;
|
|
805
796
|
cursor: not-allowed;
|
|
806
797
|
}
|
|
807
798
|
`;
|
|
808
799
|
}
|
|
809
|
-
|
|
810
|
-
async handleSubmit(event: Event) {
|
|
811
|
-
event.preventDefault();
|
|
812
|
-
|
|
813
|
-
this.loading = true;
|
|
814
|
-
|
|
815
|
-
try {
|
|
816
|
-
const formData = new FormData(this.form!);
|
|
817
|
-
|
|
818
|
-
// Simulate API call
|
|
819
|
-
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
820
|
-
|
|
821
|
-
this.dispatchEvent(new CustomEvent('registration-success', {
|
|
822
|
-
detail: Object.fromEntries(formData),
|
|
823
|
-
bubbles: true
|
|
824
|
-
}));
|
|
825
|
-
|
|
826
|
-
this.form?.reset();
|
|
827
|
-
} catch (error) {
|
|
828
|
-
console.error('Registration failed:', error);
|
|
829
|
-
} finally {
|
|
830
|
-
this.loading = false;
|
|
831
|
-
}
|
|
832
|
-
}
|
|
833
800
|
}
|
|
834
801
|
```
|
|
835
802
|
|
|
836
803
|
### Watch Decorator
|
|
837
804
|
|
|
838
|
-
Use `@watch` to react to property changes:
|
|
805
|
+
Use `@watch` to react to property changes. Handlers receive three arguments: `(oldValue, newValue, propertyName)`.
|
|
839
806
|
|
|
840
807
|
```typescript
|
|
841
808
|
@element('reactive-component')
|
|
@@ -847,8 +814,8 @@ class ReactiveComponent extends HTMLElement {
|
|
|
847
814
|
score = 0;
|
|
848
815
|
|
|
849
816
|
@watch('userName')
|
|
850
|
-
onUserNameChange(oldVal: string, newVal: string) {
|
|
851
|
-
console.log(
|
|
817
|
+
onUserNameChange(oldVal: string, newVal: string, prop: string) {
|
|
818
|
+
console.log(`${prop} changed from ${oldVal} to ${newVal}`);
|
|
852
819
|
}
|
|
853
820
|
|
|
854
821
|
@watch('score')
|
|
@@ -858,6 +825,12 @@ class ReactiveComponent extends HTMLElement {
|
|
|
858
825
|
}
|
|
859
826
|
}
|
|
860
827
|
|
|
828
|
+
// Wildcard watcher — fires on any @property change
|
|
829
|
+
@watch('*')
|
|
830
|
+
onAnyChange(oldVal: any, newVal: any, prop: string) {
|
|
831
|
+
console.log(`${prop}: ${oldVal} → ${newVal}`);
|
|
832
|
+
}
|
|
833
|
+
|
|
861
834
|
@render()
|
|
862
835
|
renderContent() {
|
|
863
836
|
return html`
|
|
@@ -870,6 +843,60 @@ class ReactiveComponent extends HTMLElement {
|
|
|
870
843
|
}
|
|
871
844
|
```
|
|
872
845
|
|
|
846
|
+
### @context() Decorator
|
|
847
|
+
|
|
848
|
+
Receive router context updates. The decorated method is called whenever the router context changes (navigation, app context update, etc.):
|
|
849
|
+
|
|
850
|
+
```typescript
|
|
851
|
+
import { element, context, property, render, html } from 'snice';
|
|
852
|
+
import type { Context, Placard } from 'snice';
|
|
853
|
+
|
|
854
|
+
@element('nav-bar')
|
|
855
|
+
class NavBar extends HTMLElement {
|
|
856
|
+
@property({ type: Array })
|
|
857
|
+
placards: Placard[] = [];
|
|
858
|
+
|
|
859
|
+
@property()
|
|
860
|
+
currentRoute = '';
|
|
861
|
+
|
|
862
|
+
@context()
|
|
863
|
+
onContextUpdate(ctx: Context) {
|
|
864
|
+
this.placards = ctx.navigation.placards;
|
|
865
|
+
this.currentRoute = ctx.navigation.route;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
@render()
|
|
869
|
+
renderContent() {
|
|
870
|
+
return html`
|
|
871
|
+
<nav>
|
|
872
|
+
${this.placards
|
|
873
|
+
.filter(p => p.show !== false)
|
|
874
|
+
.map(p => html`
|
|
875
|
+
<a href="#/${p.name}" class="${this.currentRoute === p.name ? 'active' : ''}">
|
|
876
|
+
${p.icon} ${p.title}
|
|
877
|
+
</a>
|
|
878
|
+
`)}
|
|
879
|
+
</nav>
|
|
880
|
+
`;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
```
|
|
884
|
+
|
|
885
|
+
**Context Options:**
|
|
886
|
+
|
|
887
|
+
```typescript
|
|
888
|
+
@context({ debounce: 300 }) // Wait 300ms after last change
|
|
889
|
+
@context({ throttle: 500 }) // At most once per 500ms
|
|
890
|
+
@context({ once: true }) // Only called once, then auto-unregisters
|
|
891
|
+
```
|
|
892
|
+
|
|
893
|
+
The `Context` object provides:
|
|
894
|
+
- `ctx.application` — App context (theme, auth, config, etc.)
|
|
895
|
+
- `ctx.navigation.route` — Current route path
|
|
896
|
+
- `ctx.navigation.params` — Route parameters
|
|
897
|
+
- `ctx.navigation.placards` — All registered page placards
|
|
898
|
+
- `ctx.fetch` — Fetch with middleware support (see Fetcher docs)
|
|
899
|
+
|
|
873
900
|
### Conditional Rendering
|
|
874
901
|
|
|
875
902
|
```typescript
|
|
@@ -898,18 +925,4 @@ class ConditionalContent extends HTMLElement {
|
|
|
898
925
|
}
|
|
899
926
|
```
|
|
900
927
|
|
|
901
|
-
## Best Practices
|
|
902
|
-
|
|
903
|
-
1. **Use @render() for templates**: Always return `html\`...\`` tagged templates
|
|
904
|
-
2. **Use @styles() for CSS**: Always return `css\`...\`` tagged templates
|
|
905
|
-
3. **Leverage auto-rendering**: Properties automatically trigger re-renders
|
|
906
|
-
4. **Use template events**: Handle events with `@event=${handler}` in templates
|
|
907
|
-
5. **Clean up resources**: Use @dispose() for cleanup tasks
|
|
908
|
-
6. **Type your queries**: Use proper TypeScript types for queried elements
|
|
909
|
-
7. **Handle errors**: Wrap async operations in try-catch blocks
|
|
910
|
-
|
|
911
|
-
## Removed in v3.0.0
|
|
912
928
|
|
|
913
|
-
- **@part decorator**: Removed in favor of differential rendering. Use `@render()` with templates instead.
|
|
914
|
-
- **html() method**: Replaced with `@render()` decorator
|
|
915
|
-
- **css() method**: Replaced with `@styles()` decorator
|
package/docs/events.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Events API Documentation
|
|
2
2
|
|
|
3
|
-
Event handling in Snice provides two powerful approaches: **template event syntax** and the **`@on` decorator
|
|
3
|
+
Event handling in Snice provides two powerful approaches: **template event syntax** and the **`@on` decorator**. The `@on` decorator works in **both elements AND controllers** with full event delegation, keyboard modifiers, debounce/throttle, and more. Additionally, the `@dispatch` decorator enables automatic custom event dispatching.
|
|
4
4
|
|
|
5
5
|
## Table of Contents
|
|
6
6
|
- [Template Event Syntax](#template-event-syntax)
|
|
7
|
-
- [@on Decorator
|
|
7
|
+
- [@on Decorator](#on-decorator)
|
|
8
8
|
- [@dispatch Decorator](#dispatch-decorator)
|
|
9
9
|
- [Custom Events](#custom-events)
|
|
10
10
|
- [Event Delegation](#event-delegation)
|
|
@@ -247,15 +247,15 @@ class TaskList extends HTMLElement {
|
|
|
247
247
|
}
|
|
248
248
|
```
|
|
249
249
|
|
|
250
|
-
## @on Decorator
|
|
250
|
+
## @on Decorator
|
|
251
251
|
|
|
252
|
-
The `@on` decorator
|
|
252
|
+
The `@on` decorator works in **both elements AND controllers**. It provides powerful event delegation, keyboard modifiers, debounce/throttle, and automatic event handling features.
|
|
253
253
|
|
|
254
254
|
**Use `@on` when you need:**
|
|
255
255
|
- Event delegation with CSS selectors
|
|
256
256
|
- Keyboard modifier matching (`Enter`, `ctrl+s`, etc.)
|
|
257
257
|
- Debounce or throttle
|
|
258
|
-
- Multiple events on one handler
|
|
258
|
+
- Multiple events on one handler (accepts `string[]`: `@on(['mouseenter', 'focus'])`)
|
|
259
259
|
- Automatic preventDefault or stopPropagation
|
|
260
260
|
|
|
261
261
|
### Basic Controller Usage
|
|
@@ -378,11 +378,11 @@ interface OnOptions {
|
|
|
378
378
|
preventDefault?: boolean; // Automatically call preventDefault on the event
|
|
379
379
|
stopPropagation?: boolean; // Automatically call stopPropagation on the event
|
|
380
380
|
|
|
381
|
-
// Timing controls
|
|
381
|
+
// Timing controls
|
|
382
382
|
debounce?: number; // Debounce the handler by specified milliseconds
|
|
383
383
|
throttle?: number; // Throttle the handler by specified milliseconds
|
|
384
384
|
|
|
385
|
-
//
|
|
385
|
+
// Shadow DOM delegation
|
|
386
386
|
target?: string; // CSS selector to target specific elements within shadow root
|
|
387
387
|
}
|
|
388
388
|
```
|
|
@@ -437,8 +437,8 @@ While template syntax is preferred, `@on` can also be used in elements:
|
|
|
437
437
|
```typescript
|
|
438
438
|
import { element, on, render, html } from 'snice';
|
|
439
439
|
|
|
440
|
-
@element('
|
|
441
|
-
class
|
|
440
|
+
@element('my-button')
|
|
441
|
+
class MyButton extends HTMLElement {
|
|
442
442
|
@render()
|
|
443
443
|
renderContent() {
|
|
444
444
|
return html`<button class="btn">Click me</button>`;
|
|
@@ -505,6 +505,8 @@ input.addEventListener('value-changed', (e: CustomEvent) => {
|
|
|
505
505
|
|
|
506
506
|
### Event Options
|
|
507
507
|
|
|
508
|
+
Events dispatched by `@dispatch` default to `bubbles: true` and `composed: true` (crosses shadow DOM boundaries). Override if needed:
|
|
509
|
+
|
|
508
510
|
```typescript
|
|
509
511
|
@element('status-indicator')
|
|
510
512
|
class StatusIndicator extends HTMLElement {
|
|
@@ -513,7 +515,8 @@ class StatusIndicator extends HTMLElement {
|
|
|
513
515
|
return html`<div>Status</div>`;
|
|
514
516
|
}
|
|
515
517
|
|
|
516
|
-
|
|
518
|
+
// Defaults: bubbles: true, composed: true
|
|
519
|
+
@dispatch('status-changed')
|
|
517
520
|
updateStatus(status: string) {
|
|
518
521
|
return {
|
|
519
522
|
status,
|
|
@@ -523,36 +526,77 @@ class StatusIndicator extends HTMLElement {
|
|
|
523
526
|
}
|
|
524
527
|
```
|
|
525
528
|
|
|
526
|
-
###
|
|
529
|
+
### DispatchOptions
|
|
530
|
+
|
|
531
|
+
```typescript
|
|
532
|
+
interface DispatchOptions extends EventInit {
|
|
533
|
+
dispatchOnUndefined?: boolean; // Skip dispatch when return is undefined (default: true)
|
|
534
|
+
debounce?: number; // Debounce dispatch by ms
|
|
535
|
+
throttle?: number; // Throttle dispatch by ms
|
|
536
|
+
}
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
### Debounce/Throttle
|
|
540
|
+
|
|
541
|
+
```typescript
|
|
542
|
+
@element('search-box')
|
|
543
|
+
class SearchBox extends HTMLElement {
|
|
544
|
+
@render()
|
|
545
|
+
renderContent() {
|
|
546
|
+
return html`<input @input=${this.handleInput}>`;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
handleInput(e: Event) {
|
|
550
|
+
this.emitSearch((e.target as HTMLInputElement).value);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
@dispatch('search-query', { debounce: 300 })
|
|
554
|
+
emitSearch(query: string) {
|
|
555
|
+
return { query };
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
### Async Methods
|
|
561
|
+
|
|
562
|
+
`@dispatch` works with async methods — the event dispatches after the promise resolves:
|
|
563
|
+
|
|
564
|
+
```typescript
|
|
565
|
+
@dispatch('validation-complete')
|
|
566
|
+
async validate() {
|
|
567
|
+
const result = await this.runValidation();
|
|
568
|
+
return { valid: result.isValid, errors: result.errors };
|
|
569
|
+
}
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
### Multiple Events
|
|
527
573
|
|
|
528
574
|
```typescript
|
|
529
|
-
@element('
|
|
530
|
-
class
|
|
531
|
-
|
|
575
|
+
@element('color-picker')
|
|
576
|
+
class ColorPicker extends HTMLElement {
|
|
577
|
+
@property() color = '#000000';
|
|
532
578
|
|
|
533
579
|
@render()
|
|
534
580
|
renderContent() {
|
|
535
|
-
return html
|
|
581
|
+
return html`
|
|
582
|
+
<input type="color" .value=${this.color} @input=${this.handleInput}>
|
|
583
|
+
<button @click=${this.confirm}>OK</button>
|
|
584
|
+
`;
|
|
536
585
|
}
|
|
537
586
|
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
this.data.push(item);
|
|
541
|
-
return { item, total: this.data.length };
|
|
587
|
+
handleInput(e: Event) {
|
|
588
|
+
this.changeColor((e.target as HTMLInputElement).value);
|
|
542
589
|
}
|
|
543
590
|
|
|
544
|
-
@dispatch('
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
return { id, item, total: this.data.length };
|
|
591
|
+
@dispatch('color-preview')
|
|
592
|
+
changeColor(color: string) {
|
|
593
|
+
this.color = color;
|
|
594
|
+
return { color };
|
|
549
595
|
}
|
|
550
596
|
|
|
551
|
-
@dispatch('
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
this.data = [];
|
|
555
|
-
return { clearedCount: count };
|
|
597
|
+
@dispatch('color-selected')
|
|
598
|
+
confirm() {
|
|
599
|
+
return { color: this.color };
|
|
556
600
|
}
|
|
557
601
|
}
|
|
558
602
|
```
|
|
@@ -615,8 +659,8 @@ class TableController implements IController {
|
|
|
615
659
|
// Single event listener handles all rows
|
|
616
660
|
@on('click', 'tr')
|
|
617
661
|
handleRowClick(event: MouseEvent) {
|
|
618
|
-
const row = event.
|
|
619
|
-
console.log('Row clicked:', row
|
|
662
|
+
const row = (event.target as HTMLElement).closest('tr');
|
|
663
|
+
console.log('Row clicked:', row?.dataset.id);
|
|
620
664
|
}
|
|
621
665
|
|
|
622
666
|
// Handle button clicks in cells
|
|
@@ -754,54 +798,4 @@ class KeyboardController implements IController {
|
|
|
754
798
|
}
|
|
755
799
|
```
|
|
756
800
|
|
|
757
|
-
## Best Practices
|
|
758
|
-
|
|
759
|
-
### For Elements
|
|
760
|
-
|
|
761
|
-
1. **Prefer template syntax**: Use `@event=${handler}` in templates
|
|
762
|
-
2. **Use arrow functions for parameters**: `@click=${() => this.delete(id)}`
|
|
763
|
-
3. **Handle events at appropriate level**: Use event delegation for dynamic content
|
|
764
|
-
4. **Prevent default when needed**: Call `e.preventDefault()` in handlers
|
|
765
|
-
5. **Use keyboard shortcuts**: Leverage `@keydown.ctrl+s` syntax
|
|
766
|
-
|
|
767
|
-
### For Controllers
|
|
768
|
-
|
|
769
|
-
1. **Use @on decorator**: Controllers should use `@on` for event handling
|
|
770
|
-
2. **Leverage event delegation**: Use selectors to handle dynamic content
|
|
771
|
-
3. **Throttle/debounce high-frequency events**: Use `{ throttle }` or `{ debounce }` options
|
|
772
|
-
4. **Clean up automatically**: Event listeners are cleaned up on detach
|
|
773
|
-
5. **Handle keyboard shortcuts**: Use `@on('keydown:Ctrl+S')` syntax
|
|
774
|
-
|
|
775
|
-
### General
|
|
776
|
-
|
|
777
|
-
1. **Type your events**: Use TypeScript event types for type safety
|
|
778
|
-
2. **Stop propagation carefully**: Only use `stopPropagation()` when necessary
|
|
779
|
-
3. **Use custom events**: Dispatch custom events for component communication
|
|
780
|
-
4. **Compose events**: Use `{ composed: true }` for cross-shadow-DOM events
|
|
781
|
-
5. **Test event handlers**: Write tests for all event handling logic
|
|
782
|
-
|
|
783
|
-
## Event Types Reference
|
|
784
|
-
|
|
785
|
-
**Mouse Events:**
|
|
786
|
-
- `click`, `dblclick`, `mousedown`, `mouseup`
|
|
787
|
-
- `mouseenter`, `mouseleave`, `mousemove`, `mouseover`, `mouseout`
|
|
788
|
-
- `contextmenu`
|
|
789
|
-
|
|
790
|
-
**Keyboard Events:**
|
|
791
|
-
- `keydown`, `keyup`, `keypress`
|
|
792
|
-
|
|
793
|
-
**Form Events:**
|
|
794
|
-
- `input`, `change`, `submit`, `reset`
|
|
795
|
-
- `focus`, `blur`, `focusin`, `focusout`
|
|
796
|
-
|
|
797
|
-
**Drag Events:**
|
|
798
|
-
- `drag`, `dragstart`, `dragend`
|
|
799
|
-
- `dragenter`, `dragover`, `dragleave`, `drop`
|
|
800
|
-
|
|
801
|
-
**Touch Events:**
|
|
802
|
-
- `touchstart`, `touchmove`, `touchend`, `touchcancel`
|
|
803
801
|
|
|
804
|
-
**Other Events:**
|
|
805
|
-
- `scroll`, `resize`, `load`, `error`
|
|
806
|
-
- `animationstart`, `animationend`, `animationiteration`
|
|
807
|
-
- `transitionstart`, `transitionend`
|