snice 4.28.0 → 4.30.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 +3 -10
- package/adapters/react/SniceProvider.d.ts +71 -0
- package/adapters/react/SniceProvider.js +49 -0
- package/adapters/react/SniceProvider.js.map +1 -0
- package/adapters/react/SniceRouter.d.ts +44 -0
- package/adapters/react/SniceRouter.js +190 -0
- package/adapters/react/SniceRouter.js.map +1 -0
- package/adapters/react/action-bar.d.ts +30 -0
- package/adapters/react/action-bar.d.ts.map +1 -0
- package/adapters/react/action-bar.js +24 -0
- package/adapters/react/action-bar.js.map +1 -0
- package/adapters/react/action-bar.tsx +38 -0
- package/adapters/react/binpack.d.ts +35 -0
- package/adapters/react/binpack.d.ts.map +1 -0
- package/adapters/react/binpack.js +24 -0
- package/adapters/react/binpack.js.map +1 -0
- package/adapters/react/binpack.tsx +43 -0
- package/adapters/react/components.d.ts +6 -0
- package/adapters/react/components.d.ts.map +1 -1
- package/adapters/react/components.js +3 -0
- package/adapters/react/components.js.map +1 -1
- package/adapters/react/components.ts +6 -0
- package/adapters/react/grid.d.ts +36 -0
- package/adapters/react/grid.d.ts.map +1 -0
- package/adapters/react/grid.js +24 -0
- package/adapters/react/grid.js.map +1 -0
- package/adapters/react/grid.tsx +44 -0
- package/adapters/react/index.d.ts +5 -0
- package/adapters/react/index.d.ts.map +1 -1
- package/adapters/react/index.js +3 -2
- package/adapters/react/index.js.map +1 -1
- package/adapters/react/index.ts +6 -3
- package/adapters/react/matchRoute.d.ts +16 -0
- package/adapters/react/matchRoute.js +32 -0
- package/adapters/react/matchRoute.js.map +1 -0
- package/adapters/react/types.d.ts +1 -15
- package/adapters/react/types.d.ts.map +1 -1
- package/adapters/react/types.ts +1 -15
- package/adapters/react/useRequestHandler.d.ts +56 -0
- package/adapters/react/useRequestHandler.js +103 -0
- package/adapters/react/useRequestHandler.js.map +1 -0
- package/bin/snice.js +8 -13
- package/bin/templates/{pwa → default}/index.html +1 -1
- package/bin/templates/{pwa → default}/src/components/app-header.ts +36 -18
- package/bin/templates/{pwa → default}/src/components/notification-badge.ts +2 -21
- package/bin/templates/{pwa → default}/src/components/search-bar.ts +12 -12
- package/bin/templates/default/src/context.ts +17 -0
- package/bin/templates/{pwa → default}/src/controllers/notification-controller.ts +10 -15
- package/bin/templates/{pwa → default}/src/daemons/notifications.ts +0 -12
- package/bin/templates/{pwa → default}/src/main.ts +1 -7
- package/bin/templates/{pwa → default}/src/middleware/error.ts +1 -8
- package/bin/templates/{pwa → default}/src/pages/dashboard.ts +17 -18
- package/bin/templates/{pwa → default}/src/pages/data.ts +24 -24
- package/bin/templates/{pwa → default}/src/pages/login.ts +3 -6
- package/bin/templates/{pwa → default}/src/pages/notifications.ts +21 -19
- package/bin/templates/{pwa → default}/src/pages/profile.ts +10 -12
- package/bin/templates/{pwa → default}/src/pages/settings.ts +22 -22
- package/bin/templates/default/src/router.ts +13 -0
- package/bin/templates/default/src/styles/global.css +16 -0
- package/bin/templates/{pwa → default}/tsconfig.json +2 -1
- package/bin/templates/react/README.md +124 -0
- package/bin/templates/react/global.d.ts +10 -0
- package/bin/templates/react/index.html +15 -0
- package/bin/templates/react/package.json +31 -0
- package/bin/templates/react/src/App.tsx +112 -0
- package/bin/templates/react/src/components/AppHeader.tsx +85 -0
- package/bin/templates/react/src/components/AppLayout.tsx +11 -0
- package/bin/templates/react/src/components/NotificationBadge.tsx +13 -0
- package/bin/templates/react/src/components/SearchBar.tsx +63 -0
- package/bin/templates/react/src/daemons/notifications.ts +136 -0
- package/bin/templates/react/src/fetcher.ts +15 -0
- package/bin/templates/react/src/guards/auth.ts +6 -0
- package/bin/templates/react/src/main.tsx +27 -0
- package/bin/templates/react/src/middleware/auth.ts +16 -0
- package/bin/templates/react/src/middleware/error.ts +29 -0
- package/bin/templates/react/src/middleware/retry.ts +31 -0
- package/bin/templates/react/src/pages/DashboardPage.tsx +111 -0
- package/bin/templates/react/src/pages/DataPage.tsx +119 -0
- package/bin/templates/react/src/pages/LoginPage.tsx +46 -0
- package/bin/templates/react/src/pages/NotificationsPage.tsx +119 -0
- package/bin/templates/react/src/pages/ProfilePage.tsx +92 -0
- package/bin/templates/react/src/pages/SettingsPage.tsx +165 -0
- package/bin/templates/react/src/services/auth.ts +48 -0
- package/bin/templates/react/src/services/jwt.ts +35 -0
- package/bin/templates/react/src/services/storage.ts +24 -0
- package/bin/templates/react/src/styles/global.css +382 -0
- package/bin/templates/react/src/types/auth.ts +21 -0
- package/bin/templates/react/src/types/notifications.ts +9 -0
- package/bin/templates/react/tests/helpers/test-utils.ts +79 -0
- package/bin/templates/react/tests/middleware/auth.test.ts +67 -0
- package/bin/templates/react/tests/middleware/error.test.ts +105 -0
- package/bin/templates/react/tests/middleware/retry.test.ts +103 -0
- package/bin/templates/react/tests/services/auth.test.ts +89 -0
- package/bin/templates/react/tests/services/jwt.test.ts +76 -0
- package/bin/templates/react/tests/services/storage.test.ts +69 -0
- package/bin/templates/{base → react}/tsconfig.json +4 -6
- package/bin/templates/react/vite.config.ts +18 -0
- package/bin/templates/react/vitest.config.ts +18 -0
- 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 +27 -0
- package/dist/cdn/action-bar/snice-action-bar.js +249 -0
- package/dist/cdn/action-bar/snice-action-bar.js.map +1 -0
- package/dist/cdn/action-bar/snice-action-bar.min.js +12 -0
- package/dist/cdn/action-bar/snice-action-bar.min.js.map +1 -0
- 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.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/approval-flow/snice-approval-flow.js +1 -1
- package/dist/cdn/approval-flow/snice-approval-flow.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/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.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/binpack/README.md +27 -0
- package/dist/cdn/binpack/snice-binpack.js +1037 -0
- package/dist/cdn/binpack/snice-binpack.js.map +1 -0
- package/dist/cdn/binpack/snice-binpack.min.js +13 -0
- package/dist/cdn/binpack/snice-binpack.min.js.map +1 -0
- 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.min.js +1 -1
- package/dist/cdn/button/README.md +1 -1
- package/dist/cdn/button/snice-button.js +2 -2
- package/dist/cdn/button/snice-button.js.map +1 -1
- package/dist/cdn/button/snice-button.min.js +2 -2
- 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.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/README.md +2 -2
- package/dist/cdn/chip/snice-chip.js +2 -2
- package/dist/cdn/chip/snice-chip.js.map +1 -1
- package/dist/cdn/chip/snice-chip.min.js +3 -3
- 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/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/data-card/snice-data-card.js +1 -1
- package/dist/cdn/data-card/snice-data-card.min.js +1 -1
- package/dist/cdn/date-picker/README.md +1 -1
- package/dist/cdn/date-picker/snice-date-picker.js +2 -2
- package/dist/cdn/date-picker/snice-date-picker.js.map +1 -1
- package/dist/cdn/date-picker/snice-date-picker.min.js +2 -2
- package/dist/cdn/date-picker/snice-date-picker.min.js.map +1 -1
- package/dist/cdn/date-range-picker/README.md +1 -1
- package/dist/cdn/date-range-picker/snice-date-range-picker.js +2 -2
- package/dist/cdn/date-range-picker/snice-date-range-picker.js.map +1 -1
- package/dist/cdn/date-range-picker/snice-date-range-picker.min.js +11 -11
- package/dist/cdn/date-range-picker/snice-date-range-picker.min.js.map +1 -1
- package/dist/cdn/date-time-picker/README.md +1 -1
- package/dist/cdn/date-time-picker/snice-date-time-picker.js +2 -2
- package/dist/cdn/date-time-picker/snice-date-time-picker.js.map +1 -1
- package/dist/cdn/date-time-picker/snice-date-time-picker.min.js +2 -2
- package/dist/cdn/date-time-picker/snice-date-time-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/snice-doc.js +1 -1
- package/dist/cdn/doc/snice-doc.min.js +1 -1
- package/dist/cdn/draw/README.md +2 -2
- package/dist/cdn/draw/snice-draw.js +26 -4
- package/dist/cdn/draw/snice-draw.js.map +1 -1
- package/dist/cdn/draw/snice-draw.min.js +3 -3
- package/dist/cdn/draw/snice-draw.min.js.map +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/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.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/grid/README.md +27 -0
- package/dist/cdn/grid/snice-grid.js +862 -0
- package/dist/cdn/grid/snice-grid.js.map +1 -0
- package/dist/cdn/grid/snice-grid.min.js +13 -0
- package/dist/cdn/grid/snice-grid.min.js.map +1 -0
- 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/invoice/snice-invoice.js +1 -1
- package/dist/cdn/invoice/snice-invoice.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/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.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/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.min.js +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/README.md +2 -2
- package/dist/cdn/login/snice-login.js +2 -2
- package/dist/cdn/login/snice-login.js.map +1 -1
- package/dist/cdn/login/snice-login.min.js +2 -2
- 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/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 +1 -1
- package/dist/cdn/menu/snice-menu.min.js +1 -1
- package/dist/cdn/message-strip/README.md +2 -2
- package/dist/cdn/message-strip/snice-message-strip.js +2 -2
- package/dist/cdn/message-strip/snice-message-strip.js.map +1 -1
- package/dist/cdn/message-strip/snice-message-strip.min.js +6 -6
- 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.min.js +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.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/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/README.md +2 -2
- package/dist/cdn/paint/snice-paint.js +26 -3
- package/dist/cdn/paint/snice-paint.js.map +1 -1
- package/dist/cdn/paint/snice-paint.min.js +3 -3
- package/dist/cdn/paint/snice-paint.min.js.map +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/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/README.md +1 -1
- package/dist/cdn/product-card/snice-product-card.js +1 -1
- package/dist/cdn/product-card/snice-product-card.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/progress-ring/snice-progress-ring.js +1 -1
- package/dist/cdn/progress-ring/snice-progress-ring.min.js +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 +109 -16
- 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 +109 -15
- package/dist/cdn/runtime/snice-runtime.js.map +1 -1
- package/dist/cdn/runtime/snice-runtime.min.js +7 -7
- 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/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.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/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 +2 -2
- package/dist/cdn/table/snice-table.js.map +1 -1
- package/dist/cdn/table/snice-table.min.js +2 -2
- 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/README.md +1 -1
- package/dist/cdn/tag/snice-tag.js +2 -2
- package/dist/cdn/tag/snice-tag.js.map +1 -1
- package/dist/cdn/tag/snice-tag.min.js +3 -3
- package/dist/cdn/tag/snice-tag.min.js.map +1 -1
- package/dist/cdn/tag-input/README.md +2 -2
- 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 +2 -2
- package/dist/cdn/time-picker/snice-time-picker.js.map +1 -1
- package/dist/cdn/time-picker/snice-time-picker.min.js +2 -2
- 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.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 +7 -3
- package/dist/cdn/toast/snice-toast.js.map +1 -1
- package/dist/cdn/toast/snice-toast.min.js +6 -6
- 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/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/README.md +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.d.ts +22 -0
- package/dist/components/action-bar/snice-action-bar.js +182 -0
- package/dist/components/action-bar/snice-action-bar.js.map +1 -0
- package/dist/components/action-bar/snice-action-bar.types.d.ts +17 -0
- package/dist/components/binpack/snice-binpack.d.ts +82 -0
- package/dist/components/binpack/snice-binpack.js +970 -0
- package/dist/components/binpack/snice-binpack.js.map +1 -0
- package/dist/components/binpack/snice-binpack.types.d.ts +52 -0
- package/dist/components/button/snice-button.js +1 -1
- package/dist/components/button/snice-button.js.map +1 -1
- package/dist/components/chip/snice-chip.js +1 -1
- package/dist/components/chip/snice-chip.js.map +1 -1
- package/dist/components/date-picker/snice-date-picker.js +1 -1
- package/dist/components/date-picker/snice-date-picker.js.map +1 -1
- package/dist/components/date-range-picker/snice-date-range-picker.js +1 -1
- package/dist/components/date-range-picker/snice-date-range-picker.js.map +1 -1
- package/dist/components/date-time-picker/snice-date-time-picker.js +1 -1
- package/dist/components/date-time-picker/snice-date-time-picker.js.map +1 -1
- package/dist/components/draw/snice-draw.d.ts +2 -0
- package/dist/components/draw/snice-draw.js +25 -3
- package/dist/components/draw/snice-draw.js.map +1 -1
- package/dist/components/grid/snice-grid.d.ts +73 -0
- package/dist/components/grid/snice-grid.js +795 -0
- package/dist/components/grid/snice-grid.js.map +1 -0
- package/dist/components/grid/snice-grid.types.d.ts +41 -0
- package/dist/components/message-strip/snice-message-strip.js +1 -1
- package/dist/components/message-strip/snice-message-strip.js.map +1 -1
- package/dist/components/paint/snice-paint.d.ts +2 -0
- package/dist/components/paint/snice-paint.js +25 -2
- package/dist/components/paint/snice-paint.js.map +1 -1
- package/dist/components/tag/snice-tag.js +1 -1
- package/dist/components/tag/snice-tag.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/theme/theme.css +15 -0
- package/dist/components/time-picker/snice-time-picker.js +1 -1
- package/dist/components/time-picker/snice-time-picker.js.map +1 -1
- package/dist/components/toast/snice-toast-container.js +4 -0
- package/dist/components/toast/snice-toast-container.js.map +1 -1
- package/dist/components/toast/snice-toast.js +2 -2
- package/dist/create-request-handler.d.ts +42 -0
- package/dist/index.cjs +106 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +106 -13
- package/dist/index.esm.js.map +1 -1
- package/dist/index.iife.js +106 -12
- package/dist/index.iife.js.map +1 -1
- package/dist/react/SniceProvider.d.ts +71 -0
- package/dist/react/SniceProvider.js +49 -0
- package/dist/react/SniceProvider.js.map +1 -0
- package/dist/react/SniceRouter.d.ts +44 -0
- package/dist/react/SniceRouter.js +190 -0
- package/dist/react/SniceRouter.js.map +1 -0
- package/dist/react/index.d.ts +3 -0
- package/dist/react/index.js +14 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/matchRoute.d.ts +16 -0
- package/dist/react/matchRoute.js +32 -0
- package/dist/react/matchRoute.js.map +1 -0
- package/dist/react/useRequestHandler.d.ts +56 -0
- package/dist/react/useRequestHandler.js +103 -0
- package/dist/react/useRequestHandler.js.map +1 -0
- package/dist/symbols.cjs +1 -1
- package/dist/symbols.esm.js +1 -1
- package/dist/transitions.cjs +1 -1
- package/dist/transitions.esm.js +1 -1
- package/dist/types/guard.d.ts +4 -11
- package/docs/ai/DEVELOPMENT.md +1 -1
- package/docs/ai/README.md +7 -7
- package/docs/ai/components/accordion.md +46 -80
- package/docs/ai/components/action-bar.md +75 -0
- package/docs/ai/components/activity-feed.md +7 -7
- package/docs/ai/components/alert.md +26 -44
- package/docs/ai/components/app-tiles.md +34 -39
- package/docs/ai/components/approval-flow.md +1 -1
- package/docs/ai/components/audio-recorder.md +35 -67
- package/docs/ai/components/availability.md +13 -34
- package/docs/ai/components/avatar-group.md +26 -13
- package/docs/ai/components/avatar.md +52 -36
- package/docs/ai/components/badge.md +21 -32
- package/docs/ai/components/banner.md +21 -43
- package/docs/ai/components/binpack.md +89 -0
- package/docs/ai/components/book.md +25 -23
- package/docs/ai/components/booking.md +31 -36
- package/docs/ai/components/breadcrumbs.md +36 -11
- package/docs/ai/components/button.md +33 -44
- package/docs/ai/components/calendar.md +37 -70
- package/docs/ai/components/camera-annotate.md +31 -64
- package/docs/ai/components/camera.md +38 -120
- package/docs/ai/components/candlestick.md +32 -52
- package/docs/ai/components/card.md +20 -30
- package/docs/ai/components/carousel.md +32 -32
- package/docs/ai/components/cart.md +24 -29
- package/docs/ai/components/chart.md +29 -114
- package/docs/ai/components/chat.md +38 -75
- package/docs/ai/components/checkbox.md +22 -41
- package/docs/ai/components/chip.md +18 -54
- package/docs/ai/components/code-block.md +57 -178
- package/docs/ai/components/color-display.md +12 -32
- package/docs/ai/components/color-picker.md +17 -39
- package/docs/ai/components/command-palette.md +49 -71
- package/docs/ai/components/comments.md +55 -36
- package/docs/ai/components/countdown.md +28 -30
- package/docs/ai/components/cropper.md +33 -33
- package/docs/ai/components/data-card.md +20 -14
- package/docs/ai/components/date-picker.md +40 -47
- package/docs/ai/components/date-range-picker.md +31 -15
- package/docs/ai/components/date-time-picker.md +23 -46
- package/docs/ai/components/diff.md +30 -31
- package/docs/ai/components/divider.md +17 -47
- package/docs/ai/components/doc.md +43 -68
- package/docs/ai/components/draw.md +35 -87
- package/docs/ai/components/drawer.md +48 -77
- package/docs/ai/components/empty-state.md +10 -44
- package/docs/ai/components/estimate.md +33 -58
- package/docs/ai/components/file-gallery.md +48 -100
- package/docs/ai/components/file-upload.md +17 -53
- package/docs/ai/components/flip-card.md +31 -23
- package/docs/ai/components/flow.md +37 -65
- package/docs/ai/components/form-builder.md +35 -75
- package/docs/ai/components/form-layout.md +10 -20
- package/docs/ai/components/funnel.md +33 -48
- package/docs/ai/components/gantt.md +27 -23
- package/docs/ai/components/gauge.md +16 -17
- package/docs/ai/components/grid.md +116 -0
- package/docs/ai/components/heatmap.md +21 -21
- package/docs/ai/components/image.md +7 -13
- package/docs/ai/components/input.md +38 -70
- package/docs/ai/components/invoice.md +35 -36
- package/docs/ai/components/kanban.md +32 -61
- package/docs/ai/components/key-value.md +32 -16
- package/docs/ai/components/kpi.md +38 -73
- package/docs/ai/components/layout.md +29 -23
- package/docs/ai/components/leaderboard.md +28 -37
- package/docs/ai/components/link-preview.md +12 -18
- package/docs/ai/components/link.md +10 -7
- package/docs/ai/components/list.md +21 -5
- package/docs/ai/components/location.md +21 -25
- package/docs/ai/components/login.md +14 -9
- package/docs/ai/components/map.md +27 -33
- package/docs/ai/components/markdown.md +20 -24
- package/docs/ai/components/masonry.md +10 -14
- package/docs/ai/components/mentions.md +26 -12
- package/docs/ai/components/menu.md +54 -52
- package/docs/ai/components/message-strip.md +20 -20
- package/docs/ai/components/metric-table.md +14 -21
- package/docs/ai/components/modal.md +27 -18
- package/docs/ai/components/music-player.md +49 -41
- package/docs/ai/components/nav.md +34 -31
- package/docs/ai/components/network-graph.md +27 -42
- package/docs/ai/components/notification-center.md +31 -33
- package/docs/ai/components/order-tracker.md +36 -27
- package/docs/ai/components/org-chart.md +36 -31
- package/docs/ai/components/pagination.md +34 -26
- package/docs/ai/components/paint.md +53 -91
- package/docs/ai/components/pdf-viewer.md +35 -36
- package/docs/ai/components/permission-matrix.md +26 -31
- package/docs/ai/components/podcast-player.md +64 -70
- package/docs/ai/components/pricing-table.md +37 -48
- package/docs/ai/components/product-card.md +58 -41
- package/docs/ai/components/progress-ring.md +20 -24
- package/docs/ai/components/progress.md +28 -45
- package/docs/ai/components/qr-code.md +25 -27
- package/docs/ai/components/qr-reader.md +20 -23
- package/docs/ai/components/radio.md +17 -15
- package/docs/ai/components/range-slider.md +22 -11
- package/docs/ai/components/rating.md +29 -33
- package/docs/ai/components/receipt.md +50 -127
- package/docs/ai/components/recipe.md +44 -42
- package/docs/ai/components/sankey.md +21 -30
- package/docs/ai/components/scheduler.md +29 -41
- package/docs/ai/components/segmented-control.md +11 -15
- package/docs/ai/components/select.md +58 -102
- package/docs/ai/components/skeleton.md +16 -30
- package/docs/ai/components/slider.md +26 -20
- package/docs/ai/components/sortable.md +25 -27
- package/docs/ai/components/sparkline.md +21 -17
- package/docs/ai/components/spinner.md +9 -5
- package/docs/ai/components/split-button.md +10 -13
- package/docs/ai/components/split-pane.md +19 -14
- package/docs/ai/components/spotlight.md +31 -26
- package/docs/ai/components/spreadsheet.md +51 -97
- package/docs/ai/components/stat-group.md +9 -19
- package/docs/ai/components/step-input.md +17 -15
- package/docs/ai/components/stepper.md +14 -15
- package/docs/ai/components/switch.md +15 -9
- package/docs/ai/components/table.md +24 -84
- package/docs/ai/components/tabs.md +18 -10
- package/docs/ai/components/tag-input.md +18 -29
- package/docs/ai/components/tag.md +10 -22
- package/docs/ai/components/terminal.md +9 -9
- package/docs/ai/components/testimonial.md +9 -19
- package/docs/ai/components/textarea.md +15 -16
- package/docs/ai/components/theme.md +3 -3
- package/docs/ai/components/time-picker.md +30 -49
- package/docs/ai/components/time-range-picker.md +16 -15
- package/docs/ai/components/timeline.md +5 -4
- package/docs/ai/components/timer.md +8 -8
- package/docs/ai/components/toast.md +24 -18
- package/docs/ai/components/tooltip.md +11 -22
- package/docs/ai/components/tree.md +9 -9
- package/docs/ai/components/treemap.md +14 -13
- package/docs/ai/components/user-card.md +21 -27
- package/docs/ai/components/video-player.md +35 -52
- package/docs/ai/components/virtual-scroller.md +1 -1
- package/docs/ai/components/waterfall.md +17 -16
- package/docs/ai/components/weather.md +19 -34
- package/docs/ai/components/work-order.md +58 -134
- package/docs/ai/patterns.md +87 -0
- package/docs/ai/react-integration.md +97 -0
- package/docs/components/accordion.md +72 -151
- package/docs/components/action-bar.md +185 -0
- package/docs/components/activity-feed.md +9 -14
- package/docs/components/alert.md +17 -109
- package/docs/components/app-tiles.md +58 -43
- package/docs/components/approval-flow.md +8 -14
- package/docs/components/audio-recorder.md +45 -51
- package/docs/components/availability.md +30 -45
- package/docs/components/avatar-group.md +34 -14
- package/docs/components/avatar.md +20 -55
- package/docs/components/badge.md +53 -470
- package/docs/components/banner.md +44 -30
- package/docs/components/binpack.md +208 -0
- package/docs/components/book.md +78 -57
- package/docs/components/booking.md +35 -87
- package/docs/components/breadcrumbs.md +74 -448
- package/docs/components/button.md +72 -603
- package/docs/components/calendar.md +77 -261
- package/docs/components/camera-annotate.md +44 -96
- package/docs/components/camera.md +94 -333
- package/docs/components/candlestick.md +79 -116
- package/docs/components/card.md +51 -689
- package/docs/components/carousel.md +29 -76
- package/docs/components/cart.md +44 -136
- package/docs/components/chart.md +95 -438
- package/docs/components/chat.md +175 -439
- package/docs/components/checkbox.md +52 -609
- package/docs/components/chip.md +45 -574
- package/docs/components/code-block.md +157 -421
- package/docs/components/color-display.md +45 -54
- package/docs/components/color-picker.md +103 -36
- package/docs/components/command-palette.md +98 -92
- package/docs/components/comments.md +16 -10
- package/docs/components/countdown.md +15 -20
- package/docs/components/cropper.md +14 -16
- package/docs/components/data-card.md +16 -15
- package/docs/components/date-picker.md +45 -25
- package/docs/components/date-range-picker.md +140 -87
- package/docs/components/date-time-picker.md +25 -28
- package/docs/components/diff.md +22 -17
- package/docs/components/divider.md +18 -20
- package/docs/components/doc.md +105 -197
- package/docs/components/draw.md +117 -223
- package/docs/components/drawer.md +113 -478
- package/docs/components/empty-state.md +13 -29
- package/docs/components/estimate.md +58 -118
- package/docs/components/file-gallery.md +123 -495
- package/docs/components/file-upload.md +36 -123
- package/docs/components/flip-card.md +30 -34
- package/docs/components/flow.md +74 -89
- package/docs/components/form-builder.md +59 -86
- package/docs/components/form-layout.md +21 -31
- package/docs/components/funnel.md +21 -22
- package/docs/components/gantt.md +5 -5
- package/docs/components/gauge.md +5 -23
- package/docs/components/grid.md +249 -0
- package/docs/components/heatmap.md +13 -55
- package/docs/components/image.md +28 -32
- package/docs/components/input.md +25 -14
- package/docs/components/invoice.md +34 -33
- package/docs/components/kanban.md +99 -394
- package/docs/components/key-value.md +22 -12
- package/docs/components/kpi.md +41 -112
- package/docs/components/layout.md +7 -13
- package/docs/components/leaderboard.md +52 -76
- package/docs/components/link-preview.md +20 -16
- package/docs/components/link.md +22 -19
- package/docs/components/list.md +44 -26
- package/docs/components/location.md +9 -13
- package/docs/components/login.md +42 -36
- package/docs/components/map.md +24 -46
- package/docs/components/markdown.md +14 -25
- package/docs/components/masonry.md +15 -13
- package/docs/components/mentions.md +36 -25
- package/docs/components/menu.md +39 -46
- package/docs/components/message-strip.md +15 -51
- package/docs/components/metric-table.md +50 -72
- package/docs/components/modal.md +32 -43
- package/docs/components/music-player.md +41 -49
- package/docs/components/nav.md +23 -13
- package/docs/components/network-graph.md +14 -13
- package/docs/components/notification-center.md +68 -172
- package/docs/components/order-tracker.md +72 -117
- package/docs/components/org-chart.md +58 -207
- package/docs/components/pagination.md +67 -89
- package/docs/components/paint.md +86 -172
- package/docs/components/pdf-viewer.md +46 -151
- package/docs/components/permission-matrix.md +61 -112
- package/docs/components/podcast-player.md +41 -119
- package/docs/components/pricing-table.md +104 -147
- package/docs/components/product-card.md +94 -197
- package/docs/components/progress-ring.md +29 -32
- package/docs/components/progress.md +30 -61
- package/docs/components/qr-code.md +53 -61
- package/docs/components/qr-reader.md +53 -42
- package/docs/components/radio.md +42 -40
- package/docs/components/range-slider.md +41 -30
- package/docs/components/rating.md +50 -84
- package/docs/components/receipt.md +91 -129
- package/docs/components/recipe.md +107 -216
- package/docs/components/sankey.md +47 -83
- package/docs/components/scheduler.md +81 -184
- package/docs/components/segmented-control.md +48 -40
- package/docs/components/select.md +107 -129
- package/docs/components/skeleton.md +33 -47
- package/docs/components/slider.md +49 -53
- package/docs/components/sortable.md +43 -186
- package/docs/components/sparkline.md +26 -25
- package/docs/components/spinner.md +32 -37
- package/docs/components/split-button.md +43 -23
- package/docs/components/split-pane.md +41 -58
- package/docs/components/spotlight.md +53 -145
- package/docs/components/spreadsheet.md +84 -307
- package/docs/components/stat-group.md +27 -61
- package/docs/components/step-input.md +44 -41
- package/docs/components/stepper.md +55 -89
- package/docs/components/switch.md +39 -39
- package/docs/components/table.md +27 -32
- package/docs/components/tabs.md +36 -27
- package/docs/components/tag-input.md +50 -176
- package/docs/components/tag.md +12 -50
- package/docs/components/terminal.md +32 -37
- package/docs/components/testimonial.md +24 -81
- package/docs/components/textarea.md +9 -14
- package/docs/components/theme.md +10 -23
- package/docs/components/time-picker.md +48 -72
- package/docs/components/time-range-picker.md +22 -41
- package/docs/components/timeline.md +7 -14
- package/docs/components/timer.md +16 -32
- package/docs/components/toast.md +19 -45
- package/docs/components/tooltip.md +13 -115
- package/docs/components/tree.md +2 -19
- package/docs/components/treemap.md +19 -43
- package/docs/components/user-card.md +13 -22
- package/docs/components/video-player.md +53 -227
- package/docs/components/virtual-scroller.md +11 -44
- package/docs/components/waterfall.md +58 -137
- package/docs/components/weather.md +94 -153
- package/docs/components/work-order.md +56 -143
- package/docs/plans/2026-03-09-action-bar-design.md +104 -0
- package/docs/plans/2026-03-09-action-bar-plan.md +676 -0
- package/docs/plans/2026-03-10-grid-component-design.md +138 -0
- package/docs/plans/2026-03-10-grid-component-plan.md +716 -0
- package/docs/plans/2026-03-10-react-integration-design.md +166 -0
- package/docs/plans/2026-03-10-react-integration-plan.md +1178 -0
- package/docs/react-integration.md +508 -0
- package/docs/request-response.md +63 -0
- package/package.json +1 -1
- package/bin/templates/base/README.md +0 -33
- package/bin/templates/base/global.d.ts +0 -14
- package/bin/templates/base/index.html +0 -13
- package/bin/templates/base/package.json +0 -21
- package/bin/templates/base/src/components/counter-button.ts +0 -88
- package/bin/templates/base/src/components/counter-button.types.ts +0 -7
- package/bin/templates/base/src/components/feature-card.ts +0 -59
- package/bin/templates/base/src/components/feature-card.types.ts +0 -5
- package/bin/templates/base/src/controllers/counter-controller.ts +0 -24
- package/bin/templates/base/src/main.ts +0 -24
- package/bin/templates/base/src/pages/about-page.ts +0 -68
- package/bin/templates/base/src/pages/home-page.ts +0 -105
- package/bin/templates/base/src/pages/not-found-page.ts +0 -55
- package/bin/templates/base/src/router.ts +0 -9
- package/bin/templates/base/src/styles/global.css +0 -27
- package/bin/templates/base/src/types/api-response.ts +0 -5
- package/bin/templates/base/src/types/status.ts +0 -1
- package/bin/templates/base/src/types/theme.ts +0 -1
- package/bin/templates/base/src/types/user.ts +0 -5
- package/bin/templates/base/vite.config.ts +0 -38
- package/bin/templates/pwa/public/vite.svg +0 -1
- package/bin/templates/pwa/src/router.ts +0 -20
- package/bin/templates/pwa/src/styles/global.css +0 -64
- /package/bin/templates/{pwa → default}/README.md +0 -0
- /package/bin/templates/{pwa → default}/global.d.ts +0 -0
- /package/bin/templates/{pwa → default}/package.json +0 -0
- /package/bin/templates/{pwa → default}/public/icons/.gitkeep +0 -0
- /package/bin/templates/{base → default}/public/vite.svg +0 -0
- /package/bin/templates/{pwa → default}/src/fetcher.ts +0 -0
- /package/bin/templates/{pwa → default}/src/guards/auth.ts +0 -0
- /package/bin/templates/{pwa → default}/src/middleware/auth.ts +0 -0
- /package/bin/templates/{pwa → default}/src/middleware/retry.ts +0 -0
- /package/bin/templates/{pwa → default}/src/services/auth.ts +0 -0
- /package/bin/templates/{pwa → default}/src/services/jwt.ts +0 -0
- /package/bin/templates/{pwa → default}/src/services/storage.ts +0 -0
- /package/bin/templates/{pwa → default}/src/types/auth.ts +0 -0
- /package/bin/templates/{pwa → default}/src/types/notifications.ts +0 -0
- /package/bin/templates/{pwa → default}/tests/helpers/test-utils.ts +0 -0
- /package/bin/templates/{pwa → default}/tests/middleware/auth.test.ts +0 -0
- /package/bin/templates/{pwa → default}/tests/middleware/error.test.ts +0 -0
- /package/bin/templates/{pwa → default}/tests/middleware/retry.test.ts +0 -0
- /package/bin/templates/{pwa → default}/tests/services/auth.test.ts +0 -0
- /package/bin/templates/{pwa → default}/tests/services/jwt.test.ts +0 -0
- /package/bin/templates/{pwa → default}/tests/services/storage.test.ts +0 -0
- /package/bin/templates/{pwa → default}/vite.config.ts +0 -0
- /package/bin/templates/{pwa → default}/vitest.config.ts +0 -0
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
<!-- AI: For the AI-optimized version of this doc, see docs/ai/react-integration.md -->
|
|
2
|
+
|
|
3
|
+
# React Integration
|
|
4
|
+
|
|
5
|
+
Snice's React integration lets you build full Snice-powered apps using hooks and JSX — routing, guards, layouts, context — without decorators or custom element classes.
|
|
6
|
+
|
|
7
|
+
React pages and Snice web component pages coexist in the same route table. Migration is incremental.
|
|
8
|
+
|
|
9
|
+
## Table of Contents
|
|
10
|
+
- [Installation](#installation)
|
|
11
|
+
- [Quick Start](#quick-start)
|
|
12
|
+
- [SniceRouter](#snicerouter)
|
|
13
|
+
- [Route](#route)
|
|
14
|
+
- [Hooks](#hooks)
|
|
15
|
+
- [useSniceContext](#usesnicecontext)
|
|
16
|
+
- [useNavigate](#usenavigate)
|
|
17
|
+
- [useParams](#useparams)
|
|
18
|
+
- [useRoute](#useroute)
|
|
19
|
+
- [useRequestHandler](#userequesthandler)
|
|
20
|
+
- [Guards](#guards)
|
|
21
|
+
- [Layouts](#layouts)
|
|
22
|
+
- [Mixed Pages](#mixed-pages)
|
|
23
|
+
- [Context (Standalone)](#context-standalone)
|
|
24
|
+
- [Context Shape Reference](#context-shape-reference)
|
|
25
|
+
- [Vanilla Snice Comparison](#vanilla-snice-comparison)
|
|
26
|
+
- [Behavior Notes](#behavior-notes)
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
Snice's React integration is included in the main package:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install snice
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Everything imports from `snice/react`:
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
import {
|
|
40
|
+
SniceRouter,
|
|
41
|
+
Route,
|
|
42
|
+
SniceProvider,
|
|
43
|
+
useSniceContext,
|
|
44
|
+
useNavigate,
|
|
45
|
+
useParams,
|
|
46
|
+
useRoute,
|
|
47
|
+
useRequestHandler,
|
|
48
|
+
} from 'snice/react';
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
You can also deep-import individual modules:
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
import { useRequestHandler } from 'snice/react/useRequestHandler';
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### TypeScript Types
|
|
58
|
+
|
|
59
|
+
```tsx
|
|
60
|
+
import type {
|
|
61
|
+
SniceReactContext,
|
|
62
|
+
SniceRouterProps,
|
|
63
|
+
RouteProps,
|
|
64
|
+
SniceProviderProps,
|
|
65
|
+
Placard,
|
|
66
|
+
UseRequestRouteMap,
|
|
67
|
+
UseRequestHandlerOptions,
|
|
68
|
+
} from 'snice/react';
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Quick Start
|
|
72
|
+
|
|
73
|
+
```tsx
|
|
74
|
+
import { SniceRouter, Route } from 'snice/react';
|
|
75
|
+
|
|
76
|
+
function App() {
|
|
77
|
+
return (
|
|
78
|
+
<SniceRouter mode="hash" context={{ user: null, theme: 'dark' }}>
|
|
79
|
+
<Route path="/" page={HomePage} />
|
|
80
|
+
<Route path="/about" page={AboutPage} />
|
|
81
|
+
</SniceRouter>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function HomePage() {
|
|
86
|
+
return <h1>Welcome</h1>;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function AboutPage() {
|
|
90
|
+
return <h1>About</h1>;
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## SniceRouter
|
|
95
|
+
|
|
96
|
+
The root provider component. Manages URL state, route matching, guard execution, layout selection, and context propagation.
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
<SniceRouter
|
|
100
|
+
mode="hash"
|
|
101
|
+
context={{ user, theme: 'dark' }}
|
|
102
|
+
layout={DefaultLayout}
|
|
103
|
+
loading={<Spinner />}
|
|
104
|
+
fallback={<NotFound />}
|
|
105
|
+
>
|
|
106
|
+
<Route ... />
|
|
107
|
+
</SniceRouter>
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Props
|
|
111
|
+
|
|
112
|
+
| Prop | Type | Default | Description |
|
|
113
|
+
|------|------|---------|-------------|
|
|
114
|
+
| `mode` | `"hash"` \| `"history"` | *required* | URL strategy. Hash uses `#/path`, history uses browser pushState. |
|
|
115
|
+
| `context` | `object` | `{}` | Application context passed to guards and available via `useSniceContext()`. |
|
|
116
|
+
| `layout` | `Component \| string` | none | Default layout wrapping all pages. String = Snice web component tag. |
|
|
117
|
+
| `loading` | `Component \| string \| JSX` | centered spinner | Shown while async guards are running. |
|
|
118
|
+
| `fallback` | `Component \| string \| JSX` | "404 — Page not found" | Shown when no route matches. |
|
|
119
|
+
|
|
120
|
+
For `layout`, `loading`, and `fallback`: pass a React component, a Snice web component tag name (string), or raw JSX.
|
|
121
|
+
|
|
122
|
+
## Route
|
|
123
|
+
|
|
124
|
+
Defines a route within `<SniceRouter>`. The `<Route>` component itself renders nothing — `SniceRouter` reads its props to build the route table.
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
<Route
|
|
128
|
+
path="/users/:id"
|
|
129
|
+
page={UserPage}
|
|
130
|
+
|
|
131
|
+
guard={authGuard}
|
|
132
|
+
guardRedirect="/login"
|
|
133
|
+
|
|
134
|
+
layout={DashboardLayout}
|
|
135
|
+
/>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Props
|
|
139
|
+
|
|
140
|
+
| Prop | Type | Description |
|
|
141
|
+
|------|------|-------------|
|
|
142
|
+
| `path` | `string` | URL pattern. Supports dynamic segments: `/users/:id`, `/posts/:slug`. |
|
|
143
|
+
| `page` | `Component \| string` | What to render. React component receives route params as props. String = Snice web component tag name (params set as attributes). |
|
|
144
|
+
| `guard` | `(ctx, params) => boolean \| Promise<boolean>` | Single guard function. |
|
|
145
|
+
| `guards` | `function[]` | Multiple guards — all must pass (AND logic). |
|
|
146
|
+
| `guardRedirect` | `string` | Redirect path if any guard rejects. Without this, the router renders nothing on rejection. |
|
|
147
|
+
| `layout` | `Component \| string \| false` | Override the router's default layout. `false` = explicitly no layout. |
|
|
148
|
+
| `placard` | `Placard` | Page metadata for layouts — navigation titles, icons, breadcrumbs. Import `Placard` type from `snice/react`. |
|
|
149
|
+
|
|
150
|
+
## Hooks
|
|
151
|
+
|
|
152
|
+
### useSniceContext()
|
|
153
|
+
|
|
154
|
+
Returns the full merged context. Mirrors the shape of Snice's `@context` decorator:
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
import { useSniceContext } from 'snice/react';
|
|
158
|
+
|
|
159
|
+
function UserPage() {
|
|
160
|
+
const ctx = useSniceContext();
|
|
161
|
+
|
|
162
|
+
// ctx.application — your context object (whatever you passed to SniceRouter)
|
|
163
|
+
// ctx.navigation.route — matched route pattern, e.g., "/users/:id"
|
|
164
|
+
// ctx.navigation.params — route params, e.g., { id: "42" }
|
|
165
|
+
// ctx.navigation.placards — all registered placards
|
|
166
|
+
// ctx.navigate — (path: string) => void
|
|
167
|
+
// ctx.fetch — fetch function (if provided to SniceProvider)
|
|
168
|
+
|
|
169
|
+
return <div>User: {ctx.application.user?.name}</div>;
|
|
170
|
+
}
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Must be used inside `<SniceRouter>` or `<SniceProvider>`. Throws if used outside.
|
|
174
|
+
|
|
175
|
+
### useNavigate()
|
|
176
|
+
|
|
177
|
+
Convenience hook for programmatic navigation:
|
|
178
|
+
|
|
179
|
+
```tsx
|
|
180
|
+
import { useNavigate } from 'snice/react';
|
|
181
|
+
|
|
182
|
+
function LoginButton() {
|
|
183
|
+
const navigate = useNavigate();
|
|
184
|
+
return <button onClick={() => navigate('/dashboard')}>Go to Dashboard</button>;
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### useParams()
|
|
189
|
+
|
|
190
|
+
Returns current route parameters. Shortcut for `useSniceContext().navigation.params`:
|
|
191
|
+
|
|
192
|
+
```tsx
|
|
193
|
+
import { useParams } from 'snice/react';
|
|
194
|
+
|
|
195
|
+
// Route: <Route path="/users/:id" page={UserPage} />
|
|
196
|
+
function UserPage() {
|
|
197
|
+
const params = useParams(); // { id: "42" }
|
|
198
|
+
return <div>User #{params.id}</div>;
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Note: React page components also receive params directly as props (e.g., `function UserPage({ id }) { ... }`), so `useParams()` is optional if you prefer the props pattern.
|
|
203
|
+
|
|
204
|
+
### useRoute()
|
|
205
|
+
|
|
206
|
+
Returns the current matched route pattern string:
|
|
207
|
+
|
|
208
|
+
```tsx
|
|
209
|
+
import { useRoute } from 'snice/react';
|
|
210
|
+
|
|
211
|
+
function ActiveIndicator() {
|
|
212
|
+
const route = useRoute(); // "/users/:id"
|
|
213
|
+
return <span>{route}</span>;
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### useRequestHandler()
|
|
218
|
+
|
|
219
|
+
Handle `@request` channels from Snice web components in React. This is how React code responds to requests from Snice elements that use the `@request` decorator.
|
|
220
|
+
|
|
221
|
+
**Why:** Snice elements make requests via `@request('channel-name')`. Normally a `@respond` controller handles these. `useRequestHandler` lets React components be the responder — no controller class needed.
|
|
222
|
+
|
|
223
|
+
```tsx
|
|
224
|
+
import { useRef } from 'react';
|
|
225
|
+
import { useRequestHandler } from 'snice/react';
|
|
226
|
+
|
|
227
|
+
function Dashboard() {
|
|
228
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
229
|
+
|
|
230
|
+
useRequestHandler(containerRef, {
|
|
231
|
+
'fetch-user': async (payload) => {
|
|
232
|
+
const res = await fetch(`/api/users/${payload.id}`);
|
|
233
|
+
return res.json();
|
|
234
|
+
},
|
|
235
|
+
'save-settings': async (payload) => {
|
|
236
|
+
await fetch('/api/settings', { method: 'POST', body: JSON.stringify(payload) });
|
|
237
|
+
return { ok: true };
|
|
238
|
+
},
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
return (
|
|
242
|
+
<div ref={containerRef}>
|
|
243
|
+
<snice-user-card />
|
|
244
|
+
<snice-settings-panel />
|
|
245
|
+
</div>
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
#### Global Handler
|
|
251
|
+
|
|
252
|
+
Pass `null` as the ref to listen on `document` (catches all bubbling requests):
|
|
253
|
+
|
|
254
|
+
```tsx
|
|
255
|
+
function GlobalProvider({ children }) {
|
|
256
|
+
useRequestHandler(null, {
|
|
257
|
+
'fetch-config': async () => ({ theme: 'dark', locale: 'en' }),
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
return <>{children}</>;
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
#### Options
|
|
265
|
+
|
|
266
|
+
```tsx
|
|
267
|
+
useRequestHandler(ref, routes, { passive: true });
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
| Option | Type | Default | Description |
|
|
271
|
+
|--------|------|---------|-------------|
|
|
272
|
+
| `passive` | `boolean` | `false` | When `true`, doesn't stop event propagation. Allows multiple handlers to observe the same request (only one can respond). |
|
|
273
|
+
|
|
274
|
+
#### Behavior
|
|
275
|
+
|
|
276
|
+
- Route callbacks always use the latest version (ref-stable) — **no `useCallback` needed**
|
|
277
|
+
- Listeners re-attach only when the set of channel names changes
|
|
278
|
+
- Cleanup happens automatically on unmount
|
|
279
|
+
|
|
280
|
+
## Guards
|
|
281
|
+
|
|
282
|
+
Guards protect routes. The same function signature works in both Snice and React:
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
type Guard = (
|
|
286
|
+
context: Record<string, any>, // your context object
|
|
287
|
+
params: Record<string, string> // route params
|
|
288
|
+
) => boolean | Promise<boolean>;
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Sync Guards
|
|
292
|
+
|
|
293
|
+
```tsx
|
|
294
|
+
const authGuard = (ctx, params) => !!ctx.user;
|
|
295
|
+
|
|
296
|
+
<Route path="/settings" page={SettingsPage} guard={authGuard} guardRedirect="/login" />
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### Async Guards
|
|
300
|
+
|
|
301
|
+
Async guards show the `loading` component while resolving:
|
|
302
|
+
|
|
303
|
+
```tsx
|
|
304
|
+
const roleGuard = async (ctx, params) => {
|
|
305
|
+
const roles = await fetchUserRoles(ctx.user.id);
|
|
306
|
+
return roles.includes('admin');
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
<SniceRouter loading={<Spinner />}>
|
|
310
|
+
<Route path="/admin" page={AdminPage} guard={roleGuard} guardRedirect="/forbidden" />
|
|
311
|
+
</SniceRouter>
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
If no `loading` prop is set, a default centered spinner is shown.
|
|
315
|
+
|
|
316
|
+
### Multiple Guards
|
|
317
|
+
|
|
318
|
+
All guards must pass (AND logic). They run sequentially — first failure short-circuits:
|
|
319
|
+
|
|
320
|
+
```tsx
|
|
321
|
+
<Route
|
|
322
|
+
path="/admin/users/:id"
|
|
323
|
+
page={AdminUserPage}
|
|
324
|
+
guards={[authGuard, roleGuard]}
|
|
325
|
+
guardRedirect="/login"
|
|
326
|
+
/>
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### Guard Failure
|
|
330
|
+
|
|
331
|
+
When a guard returns `false` (or rejects):
|
|
332
|
+
1. If `guardRedirect` is set → navigate to that path
|
|
333
|
+
2. If no `guardRedirect` → render nothing (blank)
|
|
334
|
+
|
|
335
|
+
Guard errors (thrown exceptions) are treated as rejection.
|
|
336
|
+
|
|
337
|
+
### Sharing Guards
|
|
338
|
+
|
|
339
|
+
Guards are plain functions. The same guard works in both vanilla Snice and React:
|
|
340
|
+
|
|
341
|
+
```typescript
|
|
342
|
+
// guards.ts — shared between vanilla and React
|
|
343
|
+
export const isAuthenticated = (ctx, params) => !!ctx.user;
|
|
344
|
+
export const isAdmin = (ctx, params) => ctx.user?.role === 'admin';
|
|
345
|
+
export const hasPermission = (permission) => (ctx, params) =>
|
|
346
|
+
ctx.user?.permissions?.includes(permission);
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
## Layouts
|
|
350
|
+
|
|
351
|
+
React layouts are components that render `{children}`:
|
|
352
|
+
|
|
353
|
+
```tsx
|
|
354
|
+
function DashboardLayout({ children }) {
|
|
355
|
+
const ctx = useSniceContext();
|
|
356
|
+
return (
|
|
357
|
+
<div className="dashboard">
|
|
358
|
+
<Sidebar user={ctx.application.user} />
|
|
359
|
+
<main>{children}</main>
|
|
360
|
+
</div>
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
### Default Layout
|
|
366
|
+
|
|
367
|
+
Set on the router — wraps all pages by default:
|
|
368
|
+
|
|
369
|
+
```tsx
|
|
370
|
+
<SniceRouter layout={DashboardLayout}>
|
|
371
|
+
<Route path="/" page={HomePage} />
|
|
372
|
+
<Route path="/users/:id" page={UserPage} />
|
|
373
|
+
</SniceRouter>
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### Per-Route Override
|
|
377
|
+
|
|
378
|
+
Override the default layout for specific routes:
|
|
379
|
+
|
|
380
|
+
```tsx
|
|
381
|
+
<SniceRouter layout={DashboardLayout}>
|
|
382
|
+
<Route path="/" page={HomePage} />
|
|
383
|
+
<Route path="/reports" page={ReportsPage} layout={ReportsLayout} />
|
|
384
|
+
<Route path="/login" page={LoginPage} layout={false} />
|
|
385
|
+
</SniceRouter>
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
- `layout={ReportsLayout}` — use a different layout
|
|
389
|
+
- `layout={false}` — explicitly no layout (e.g., login page)
|
|
390
|
+
|
|
391
|
+
### Snice Layouts
|
|
392
|
+
|
|
393
|
+
Pass a string to use a Snice web component as the layout:
|
|
394
|
+
|
|
395
|
+
```tsx
|
|
396
|
+
<Route path="/legacy" page="legacy-page" layout="legacy-layout" />
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
## Mixed Pages
|
|
400
|
+
|
|
401
|
+
Snice web component pages and React pages coexist in the same route table:
|
|
402
|
+
|
|
403
|
+
```tsx
|
|
404
|
+
function App() {
|
|
405
|
+
return (
|
|
406
|
+
<SniceRouter mode="hash" context={{ user, theme: 'dark' }} layout={AppShell}>
|
|
407
|
+
{/* React pages */}
|
|
408
|
+
<Route path="/" page={HomePage} />
|
|
409
|
+
<Route path="/settings" page={SettingsPage} guard={authGuard} guardRedirect="/login" />
|
|
410
|
+
|
|
411
|
+
{/* Snice web component pages */}
|
|
412
|
+
<Route path="/legacy" page="legacy-dashboard" />
|
|
413
|
+
<Route path="/reports" page="report-page" layout="report-layout" />
|
|
414
|
+
|
|
415
|
+
{/* No layout */}
|
|
416
|
+
<Route path="/login" page={LoginPage} layout={false} />
|
|
417
|
+
</SniceRouter>
|
|
418
|
+
);
|
|
419
|
+
}
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
When `page` is a string, the router creates the web component element and sets route params as attributes. When `page` is a React component, params are passed as props.
|
|
423
|
+
|
|
424
|
+
The same string-or-component pattern works for `layout`, `loading`, and `fallback`.
|
|
425
|
+
|
|
426
|
+
## Context (Standalone)
|
|
427
|
+
|
|
428
|
+
`<SniceProvider>` can be used without a router for simpler apps that just need shared context:
|
|
429
|
+
|
|
430
|
+
```tsx
|
|
431
|
+
import { SniceProvider, useSniceContext } from 'snice/react';
|
|
432
|
+
|
|
433
|
+
function App() {
|
|
434
|
+
return (
|
|
435
|
+
<SniceProvider context={{ user: currentUser, theme: 'dark' }}>
|
|
436
|
+
<MyComponent />
|
|
437
|
+
</SniceProvider>
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
function MyComponent() {
|
|
442
|
+
const ctx = useSniceContext();
|
|
443
|
+
return <div>Theme: {ctx.application.theme}</div>;
|
|
444
|
+
}
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
### SniceProvider Props
|
|
448
|
+
|
|
449
|
+
| Prop | Type | Default | Description |
|
|
450
|
+
|------|------|---------|-------------|
|
|
451
|
+
| `context` | `object` | `{}` | Application context. |
|
|
452
|
+
| `navigate` | `(path: string) => void` | no-op | Navigation function. |
|
|
453
|
+
| `route` | `string` | `""` | Current route pattern. |
|
|
454
|
+
| `params` | `Record<string, string>` | `{}` | Current route params. |
|
|
455
|
+
| `placards` | `Placard[]` | `[]` | Registered placards. |
|
|
456
|
+
| `fetch` | `typeof fetch` | none | Optional context-aware fetch function. |
|
|
457
|
+
|
|
458
|
+
When used inside `<SniceRouter>`, these props are set automatically. Use `<SniceProvider>` directly only when you don't need routing.
|
|
459
|
+
|
|
460
|
+
## Context Shape Reference
|
|
461
|
+
|
|
462
|
+
`useSniceContext()` returns a `SniceReactContext` object:
|
|
463
|
+
|
|
464
|
+
```typescript
|
|
465
|
+
interface SniceReactContext {
|
|
466
|
+
/** Your application context (whatever you passed to context={}) */
|
|
467
|
+
application: Record<string, any>;
|
|
468
|
+
|
|
469
|
+
/** Navigation state */
|
|
470
|
+
navigation: {
|
|
471
|
+
route: string; // matched route pattern, e.g., "/users/:id"
|
|
472
|
+
params: Record<string, string>; // route params, e.g., { id: "42" }
|
|
473
|
+
placards: Placard[]; // all registered placards
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
/** Programmatic navigation */
|
|
477
|
+
navigate: (path: string) => void;
|
|
478
|
+
|
|
479
|
+
/** Context-aware fetch (if provided to SniceProvider) */
|
|
480
|
+
fetch?: typeof globalThis.fetch;
|
|
481
|
+
}
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
This mirrors the shape of Snice's vanilla `Context` class used by the `@context` decorator.
|
|
485
|
+
|
|
486
|
+
## Vanilla Snice Comparison
|
|
487
|
+
|
|
488
|
+
| Concept | Vanilla Snice | React |
|
|
489
|
+
|---------|--------------|-------|
|
|
490
|
+
| Router setup | `Router({ target, type: 'hash', layout, context })` | `<SniceRouter mode="hash" layout={...} context={...}>` |
|
|
491
|
+
| Page definition | `@page({ tag, routes, guards })` | `<Route path="..." page={...} guard={...} />` |
|
|
492
|
+
| Navigation | `navigate('/path')` | `const nav = useNavigate(); nav('/path')` |
|
|
493
|
+
| Context access | `@context() handleCtx(ctx) { ... }` | `const ctx = useSniceContext()` |
|
|
494
|
+
| Request handling | `@respond('channel')` controller | `useRequestHandler(ref, { 'channel': handler })` |
|
|
495
|
+
| Guards | `(ctx, params) => boolean \| Promise<boolean>` | Same — shared functions work in both |
|
|
496
|
+
| Layouts | `@layout('tag') class ... { }` | `function Layout({ children }) { ... }` |
|
|
497
|
+
|
|
498
|
+
Guards, context shape, and page contracts are identical across both systems. A guard written for vanilla Snice works in React and vice versa.
|
|
499
|
+
|
|
500
|
+
## Behavior Notes
|
|
501
|
+
|
|
502
|
+
**Guards run on navigation, not on context change.** If your context changes (e.g., user logs out), guards on the current route are not re-evaluated until the next navigation. This matches standard router behavior.
|
|
503
|
+
|
|
504
|
+
**Route params as props.** React page components receive the matched route params directly as props: `<Route path="/users/:id" page={UserPage} />` means `UserPage` gets `{ id: "42" }` as props. You can also access them via `useParams()`.
|
|
505
|
+
|
|
506
|
+
**Route matching uses [pica-route](https://www.npmjs.com/package/pica-route)** — the same library as vanilla Snice's router. Routes are sorted by specificity (longest path first), so `/users/:id` takes priority over `/users`.
|
|
507
|
+
|
|
508
|
+
**Default loading.** If no `loading` prop is provided, async guards show a simple centered CSS spinner. Pass your own `loading` component/JSX to customize it.
|
package/docs/request-response.md
CHANGED
|
@@ -330,3 +330,66 @@ class TickerController implements IController {
|
|
|
330
330
|
}
|
|
331
331
|
}
|
|
332
332
|
```
|
|
333
|
+
|
|
334
|
+
## Using Without Decorators
|
|
335
|
+
|
|
336
|
+
For vanilla JS or React code that needs to respond to `@request` channels without using the decorator system.
|
|
337
|
+
|
|
338
|
+
### Vanilla JS: createRequestHandler
|
|
339
|
+
|
|
340
|
+
```javascript
|
|
341
|
+
import { createRequestHandler } from 'snice';
|
|
342
|
+
|
|
343
|
+
// Attach handlers to any DOM target (events bubble, so ancestors work)
|
|
344
|
+
const cleanup = createRequestHandler(document.getElementById('app'), {
|
|
345
|
+
'fetch-user': async (payload) => {
|
|
346
|
+
const res = await fetch(`/api/users/${payload.id}`);
|
|
347
|
+
return res.json();
|
|
348
|
+
},
|
|
349
|
+
'save-settings': async (payload) => {
|
|
350
|
+
await fetch('/api/settings', { method: 'POST', body: JSON.stringify(payload) });
|
|
351
|
+
return { ok: true };
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// Global handler (catches all bubbling requests)
|
|
356
|
+
const globalCleanup = createRequestHandler(document, {
|
|
357
|
+
'fetch-user': async (payload) => ({ name: 'Jane', id: payload.id }),
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
// Remove all listeners when done
|
|
361
|
+
cleanup();
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
**Options:**
|
|
365
|
+
|
|
366
|
+
| Option | Type | Default | Description |
|
|
367
|
+
|--------|------|---------|-------------|
|
|
368
|
+
| `passive` | `boolean` | `false` | When true, doesn't stop event propagation (allows multiple handlers) |
|
|
369
|
+
|
|
370
|
+
### React: useRequestHandler
|
|
371
|
+
|
|
372
|
+
For full documentation, examples, options, and global handler patterns, see the **[React Integration guide](./react-integration.md#userequesthandler)**.
|
|
373
|
+
|
|
374
|
+
```tsx
|
|
375
|
+
import { useRequestHandler } from 'snice/react';
|
|
376
|
+
|
|
377
|
+
function Dashboard() {
|
|
378
|
+
const ref = useRef<HTMLDivElement>(null);
|
|
379
|
+
|
|
380
|
+
useRequestHandler(ref, {
|
|
381
|
+
'fetch-user': async (payload) => {
|
|
382
|
+
const res = await fetch(`/api/users/${payload.id}`);
|
|
383
|
+
return res.json();
|
|
384
|
+
},
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
return (
|
|
388
|
+
<div ref={ref}>
|
|
389
|
+
<snice-user-card />
|
|
390
|
+
</div>
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
```
|
|
394
|
+
|
|
395
|
+
Route callbacks are ref-stable — no `useCallback` needed. Listeners re-attach only when channel names change. Cleanup is automatic on unmount.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "snice",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.30.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A decorator-driven web component library with differential rendering, routing, controllers, and 130+ ready-made UI components. Use as much or as little as you want. Zero dependencies, works anywhere.",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# {{projectName}}
|
|
2
|
-
|
|
3
|
-
A Snice application
|
|
4
|
-
|
|
5
|
-
## Development
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm run dev
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Build
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
npm run build
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## Preview Production Build
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
npm run preview
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
## Project Structure
|
|
24
|
-
|
|
25
|
-
- `src/pages/` - Application pages/routes
|
|
26
|
-
- `src/components/` - Reusable components
|
|
27
|
-
- `src/controllers/` - Business logic controllers
|
|
28
|
-
- `src/styles/` - Global styles and shared styles
|
|
29
|
-
- `src/types/` - TypeScript interfaces and types
|
|
30
|
-
- `src/router.ts` - Router configuration
|
|
31
|
-
- `src/main.ts` - Application entry point
|
|
32
|
-
|
|
33
|
-
Built with [Snice](https://gitlab.com/Hedzer/snice)
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
declare module '*.css' {
|
|
2
|
-
const content: string;
|
|
3
|
-
export default content;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
declare module '*.css?inline' {
|
|
7
|
-
const content: string;
|
|
8
|
-
export default content;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
declare module '*.html' {
|
|
12
|
-
const content: string;
|
|
13
|
-
export default content;
|
|
14
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>{{projectName}}</title>
|
|
7
|
-
<link rel="icon" type="image/svg+xml" href="/vite.svg">
|
|
8
|
-
</head>
|
|
9
|
-
<body>
|
|
10
|
-
<div id="app"></div>
|
|
11
|
-
<script type="module" src="/src/main.ts"></script>
|
|
12
|
-
</body>
|
|
13
|
-
</html>
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "{{projectName}}",
|
|
3
|
-
"private": true,
|
|
4
|
-
"version": "0.0.0",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"dev": "vite",
|
|
8
|
-
"build": "tsc && vite build",
|
|
9
|
-
"type-check": "tsc --noEmit"
|
|
10
|
-
},
|
|
11
|
-
"dependencies": {
|
|
12
|
-
"snice": "^4.0.0"
|
|
13
|
-
},
|
|
14
|
-
"devDependencies": {
|
|
15
|
-
"@types/node": "^20.0.0",
|
|
16
|
-
"terser": "^5.24.0",
|
|
17
|
-
"typescript": "^5.3.3",
|
|
18
|
-
"unplugin-swc": "^1.5.7",
|
|
19
|
-
"vite": "^5.0.10"
|
|
20
|
-
}
|
|
21
|
-
}
|