snice 5.1.0 → 5.2.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.
Files changed (305) hide show
  1. package/adapters/react/SniceProvider.js +1 -1
  2. package/adapters/react/SniceRouter.js +1 -1
  3. package/adapters/react/matchRoute.js +1 -1
  4. package/adapters/react/useRequestHandler.js +1 -1
  5. package/dist/cdn/accordion/snice-accordion.js +1 -1
  6. package/dist/cdn/accordion/snice-accordion.min.js +1 -1
  7. package/dist/cdn/action-bar/snice-action-bar.js +1 -1
  8. package/dist/cdn/action-bar/snice-action-bar.min.js +1 -1
  9. package/dist/cdn/activity-feed/snice-activity-feed.js +1 -1
  10. package/dist/cdn/activity-feed/snice-activity-feed.min.js +1 -1
  11. package/dist/cdn/alert/snice-alert.js +1 -1
  12. package/dist/cdn/alert/snice-alert.min.js +1 -1
  13. package/dist/cdn/app-tiles/snice-app-tiles.js +1 -1
  14. package/dist/cdn/app-tiles/snice-app-tiles.min.js +1 -1
  15. package/dist/cdn/approval-flow/snice-approval-flow.js +1 -1
  16. package/dist/cdn/approval-flow/snice-approval-flow.min.js +1 -1
  17. package/dist/cdn/audio-recorder/snice-audio-recorder.js +1 -1
  18. package/dist/cdn/audio-recorder/snice-audio-recorder.min.js +1 -1
  19. package/dist/cdn/availability/snice-availability.js +1 -1
  20. package/dist/cdn/availability/snice-availability.min.js +1 -1
  21. package/dist/cdn/avatar/snice-avatar.js +1 -1
  22. package/dist/cdn/avatar/snice-avatar.min.js +1 -1
  23. package/dist/cdn/avatar-group/snice-avatar-group.js +1 -1
  24. package/dist/cdn/avatar-group/snice-avatar-group.min.js +1 -1
  25. package/dist/cdn/badge/snice-badge.js +1 -1
  26. package/dist/cdn/badge/snice-badge.min.js +1 -1
  27. package/dist/cdn/banner/snice-banner.js +1 -1
  28. package/dist/cdn/banner/snice-banner.min.js +1 -1
  29. package/dist/cdn/binpack/snice-binpack.js +1 -1
  30. package/dist/cdn/binpack/snice-binpack.min.js +1 -1
  31. package/dist/cdn/book/snice-book.js +1 -1
  32. package/dist/cdn/book/snice-book.min.js +1 -1
  33. package/dist/cdn/booking/snice-booking.js +1 -1
  34. package/dist/cdn/booking/snice-booking.min.js +1 -1
  35. package/dist/cdn/breadcrumbs/snice-breadcrumbs.js +1 -1
  36. package/dist/cdn/breadcrumbs/snice-breadcrumbs.min.js +1 -1
  37. package/dist/cdn/button/snice-button.js +1 -1
  38. package/dist/cdn/button/snice-button.min.js +1 -1
  39. package/dist/cdn/calendar/snice-calendar.js +1 -1
  40. package/dist/cdn/calendar/snice-calendar.min.js +1 -1
  41. package/dist/cdn/camera/snice-camera.js +1 -1
  42. package/dist/cdn/camera/snice-camera.min.js +1 -1
  43. package/dist/cdn/camera-annotate/snice-camera-annotate.js +1 -1
  44. package/dist/cdn/camera-annotate/snice-camera-annotate.min.js +1 -1
  45. package/dist/cdn/candlestick/snice-candlestick.js +1 -1
  46. package/dist/cdn/candlestick/snice-candlestick.min.js +1 -1
  47. package/dist/cdn/card/snice-card.js +1 -1
  48. package/dist/cdn/card/snice-card.min.js +1 -1
  49. package/dist/cdn/carousel/snice-carousel.js +1 -1
  50. package/dist/cdn/carousel/snice-carousel.min.js +1 -1
  51. package/dist/cdn/cart/snice-cart.js +1 -1
  52. package/dist/cdn/cart/snice-cart.min.js +1 -1
  53. package/dist/cdn/chart/snice-chart.js +1 -1
  54. package/dist/cdn/chart/snice-chart.min.js +1 -1
  55. package/dist/cdn/chat/snice-chat.js +1 -1
  56. package/dist/cdn/chat/snice-chat.min.js +1 -1
  57. package/dist/cdn/checkbox/snice-checkbox.js +1 -1
  58. package/dist/cdn/checkbox/snice-checkbox.min.js +1 -1
  59. package/dist/cdn/chip/snice-chip.js +1 -1
  60. package/dist/cdn/chip/snice-chip.min.js +1 -1
  61. package/dist/cdn/code-block/snice-code-block.js +1 -1
  62. package/dist/cdn/code-block/snice-code-block.min.js +1 -1
  63. package/dist/cdn/color-display/snice-color-display.js +1 -1
  64. package/dist/cdn/color-display/snice-color-display.min.js +1 -1
  65. package/dist/cdn/color-picker/snice-color-picker.js +1 -1
  66. package/dist/cdn/color-picker/snice-color-picker.min.js +1 -1
  67. package/dist/cdn/command-palette/snice-command-palette.js +1 -1
  68. package/dist/cdn/command-palette/snice-command-palette.min.js +1 -1
  69. package/dist/cdn/comments/snice-comments.js +1 -1
  70. package/dist/cdn/comments/snice-comments.min.js +1 -1
  71. package/dist/cdn/countdown/snice-countdown.js +1 -1
  72. package/dist/cdn/countdown/snice-countdown.min.js +1 -1
  73. package/dist/cdn/cropper/snice-cropper.js +1 -1
  74. package/dist/cdn/cropper/snice-cropper.min.js +1 -1
  75. package/dist/cdn/data-card/snice-data-card.js +1 -1
  76. package/dist/cdn/data-card/snice-data-card.min.js +1 -1
  77. package/dist/cdn/date-picker/snice-date-picker.js +1 -1
  78. package/dist/cdn/date-picker/snice-date-picker.min.js +1 -1
  79. package/dist/cdn/date-range-picker/snice-date-range-picker.js +1 -1
  80. package/dist/cdn/date-range-picker/snice-date-range-picker.min.js +1 -1
  81. package/dist/cdn/date-time-picker/snice-date-time-picker.js +1 -1
  82. package/dist/cdn/date-time-picker/snice-date-time-picker.min.js +1 -1
  83. package/dist/cdn/diff/snice-diff.js +1 -1
  84. package/dist/cdn/diff/snice-diff.min.js +1 -1
  85. package/dist/cdn/divider/snice-divider.js +1 -1
  86. package/dist/cdn/divider/snice-divider.min.js +1 -1
  87. package/dist/cdn/doc/snice-doc.js +1 -1
  88. package/dist/cdn/doc/snice-doc.min.js +1 -1
  89. package/dist/cdn/draw/snice-draw.js +1 -1
  90. package/dist/cdn/draw/snice-draw.min.js +1 -1
  91. package/dist/cdn/drawer/snice-drawer.js +1 -1
  92. package/dist/cdn/drawer/snice-drawer.min.js +1 -1
  93. package/dist/cdn/empty-state/snice-empty-state.js +1 -1
  94. package/dist/cdn/empty-state/snice-empty-state.min.js +1 -1
  95. package/dist/cdn/estimate/snice-estimate.js +1 -1
  96. package/dist/cdn/estimate/snice-estimate.min.js +1 -1
  97. package/dist/cdn/file-gallery/snice-file-gallery.js +1 -1
  98. package/dist/cdn/file-gallery/snice-file-gallery.min.js +1 -1
  99. package/dist/cdn/file-upload/snice-file-upload.js +1 -1
  100. package/dist/cdn/file-upload/snice-file-upload.min.js +1 -1
  101. package/dist/cdn/flip-card/snice-flip-card.js +1 -1
  102. package/dist/cdn/flip-card/snice-flip-card.min.js +1 -1
  103. package/dist/cdn/flow/snice-flow.js +1 -1
  104. package/dist/cdn/flow/snice-flow.min.js +1 -1
  105. package/dist/cdn/form-layout/snice-form-layout.js +1 -1
  106. package/dist/cdn/form-layout/snice-form-layout.min.js +1 -1
  107. package/dist/cdn/funnel/snice-funnel.js +1 -1
  108. package/dist/cdn/funnel/snice-funnel.min.js +1 -1
  109. package/dist/cdn/gantt/snice-gantt.js +1 -1
  110. package/dist/cdn/gantt/snice-gantt.min.js +1 -1
  111. package/dist/cdn/gauge/snice-gauge.js +1 -1
  112. package/dist/cdn/gauge/snice-gauge.min.js +1 -1
  113. package/dist/cdn/grid/snice-grid.js +1 -1
  114. package/dist/cdn/grid/snice-grid.min.js +1 -1
  115. package/dist/cdn/heatmap/snice-heatmap.js +1 -1
  116. package/dist/cdn/heatmap/snice-heatmap.min.js +1 -1
  117. package/dist/cdn/image/snice-image.js +1 -1
  118. package/dist/cdn/image/snice-image.min.js +1 -1
  119. package/dist/cdn/input/snice-input.js +1 -1
  120. package/dist/cdn/input/snice-input.min.js +1 -1
  121. package/dist/cdn/invoice/snice-invoice.js +1 -1
  122. package/dist/cdn/invoice/snice-invoice.min.js +1 -1
  123. package/dist/cdn/kanban/snice-kanban.js +1 -1
  124. package/dist/cdn/kanban/snice-kanban.min.js +1 -1
  125. package/dist/cdn/key-value/snice-key-value.js +1 -1
  126. package/dist/cdn/key-value/snice-key-value.min.js +1 -1
  127. package/dist/cdn/kpi/snice-kpi.js +1 -1
  128. package/dist/cdn/kpi/snice-kpi.min.js +1 -1
  129. package/dist/cdn/layout/snice-layout.js +1 -1
  130. package/dist/cdn/layout/snice-layout.min.js +1 -1
  131. package/dist/cdn/leaderboard/snice-leaderboard.js +1 -1
  132. package/dist/cdn/leaderboard/snice-leaderboard.min.js +1 -1
  133. package/dist/cdn/link/snice-link.js +1 -1
  134. package/dist/cdn/link/snice-link.min.js +1 -1
  135. package/dist/cdn/link-preview/snice-link-preview.js +1 -1
  136. package/dist/cdn/link-preview/snice-link-preview.min.js +1 -1
  137. package/dist/cdn/list/snice-list.js +1 -1
  138. package/dist/cdn/list/snice-list.min.js +1 -1
  139. package/dist/cdn/location/snice-location.js +1 -1
  140. package/dist/cdn/location/snice-location.min.js +1 -1
  141. package/dist/cdn/login/snice-login.js +1 -1
  142. package/dist/cdn/login/snice-login.min.js +1 -1
  143. package/dist/cdn/map/snice-map.js +1 -1
  144. package/dist/cdn/map/snice-map.min.js +1 -1
  145. package/dist/cdn/markdown/snice-markdown.js +1 -1
  146. package/dist/cdn/markdown/snice-markdown.min.js +1 -1
  147. package/dist/cdn/masonry/snice-masonry.js +1 -1
  148. package/dist/cdn/masonry/snice-masonry.min.js +1 -1
  149. package/dist/cdn/menu/snice-menu.js +1 -1
  150. package/dist/cdn/menu/snice-menu.min.js +1 -1
  151. package/dist/cdn/message-strip/snice-message-strip.js +1 -1
  152. package/dist/cdn/message-strip/snice-message-strip.min.js +1 -1
  153. package/dist/cdn/metric-table/snice-metric-table.js +1 -1
  154. package/dist/cdn/metric-table/snice-metric-table.min.js +1 -1
  155. package/dist/cdn/modal/snice-modal.js +1 -1
  156. package/dist/cdn/modal/snice-modal.min.js +1 -1
  157. package/dist/cdn/music-player/snice-music-player.js +1 -1
  158. package/dist/cdn/music-player/snice-music-player.min.js +1 -1
  159. package/dist/cdn/nav/snice-nav.js +1 -1
  160. package/dist/cdn/nav/snice-nav.min.js +1 -1
  161. package/dist/cdn/network-graph/snice-network-graph.js +1 -1
  162. package/dist/cdn/network-graph/snice-network-graph.min.js +1 -1
  163. package/dist/cdn/notification-center/snice-notification-center.js +1 -1
  164. package/dist/cdn/notification-center/snice-notification-center.min.js +1 -1
  165. package/dist/cdn/order-tracker/snice-order-tracker.js +1 -1
  166. package/dist/cdn/order-tracker/snice-order-tracker.min.js +1 -1
  167. package/dist/cdn/org-chart/snice-org-chart.js +1 -1
  168. package/dist/cdn/org-chart/snice-org-chart.min.js +1 -1
  169. package/dist/cdn/pagination/snice-pagination.js +1 -1
  170. package/dist/cdn/pagination/snice-pagination.min.js +1 -1
  171. package/dist/cdn/paint/snice-paint.js +1 -1
  172. package/dist/cdn/paint/snice-paint.min.js +1 -1
  173. package/dist/cdn/pdf-viewer/snice-pdf-viewer.js +1 -1
  174. package/dist/cdn/pdf-viewer/snice-pdf-viewer.min.js +1 -1
  175. package/dist/cdn/permission-matrix/snice-permission-matrix.js +1 -1
  176. package/dist/cdn/permission-matrix/snice-permission-matrix.min.js +1 -1
  177. package/dist/cdn/podcast-player/snice-podcast-player.js +1 -1
  178. package/dist/cdn/podcast-player/snice-podcast-player.min.js +1 -1
  179. package/dist/cdn/popover/snice-popover.js +1 -1
  180. package/dist/cdn/popover/snice-popover.min.js +1 -1
  181. package/dist/cdn/pricing-table/snice-pricing-table.js +1 -1
  182. package/dist/cdn/pricing-table/snice-pricing-table.min.js +1 -1
  183. package/dist/cdn/product-card/snice-product-card.js +1 -1
  184. package/dist/cdn/product-card/snice-product-card.min.js +1 -1
  185. package/dist/cdn/progress/snice-progress.js +1 -1
  186. package/dist/cdn/progress/snice-progress.min.js +1 -1
  187. package/dist/cdn/progress-ring/snice-progress-ring.js +1 -1
  188. package/dist/cdn/progress-ring/snice-progress-ring.min.js +1 -1
  189. package/dist/cdn/qr-code/snice-qr-code.js +1 -1
  190. package/dist/cdn/qr-code/snice-qr-code.min.js +1 -1
  191. package/dist/cdn/qr-reader/snice-qr-reader.js +1 -1
  192. package/dist/cdn/qr-reader/snice-qr-reader.min.js +1 -1
  193. package/dist/cdn/radio/snice-radio.js +1 -1
  194. package/dist/cdn/radio/snice-radio.min.js +1 -1
  195. package/dist/cdn/range-slider/snice-range-slider.js +1 -1
  196. package/dist/cdn/range-slider/snice-range-slider.min.js +1 -1
  197. package/dist/cdn/rating/snice-rating.js +1 -1
  198. package/dist/cdn/rating/snice-rating.min.js +1 -1
  199. package/dist/cdn/receipt/snice-receipt.js +1 -1
  200. package/dist/cdn/receipt/snice-receipt.min.js +1 -1
  201. package/dist/cdn/recipe/snice-recipe.js +1 -1
  202. package/dist/cdn/recipe/snice-recipe.min.js +1 -1
  203. package/dist/cdn/runtime/snice-runtime.esm.js +220 -205
  204. package/dist/cdn/runtime/snice-runtime.esm.js.map +1 -1
  205. package/dist/cdn/runtime/snice-runtime.esm.min.js +8 -8
  206. package/dist/cdn/runtime/snice-runtime.esm.min.js.map +1 -1
  207. package/dist/cdn/runtime/snice-runtime.js +220 -205
  208. package/dist/cdn/runtime/snice-runtime.js.map +1 -1
  209. package/dist/cdn/runtime/snice-runtime.min.js +8 -8
  210. package/dist/cdn/runtime/snice-runtime.min.js.map +1 -1
  211. package/dist/cdn/sankey/snice-sankey.js +1 -1
  212. package/dist/cdn/sankey/snice-sankey.min.js +1 -1
  213. package/dist/cdn/segmented-control/snice-segmented-control.js +1 -1
  214. package/dist/cdn/segmented-control/snice-segmented-control.min.js +1 -1
  215. package/dist/cdn/select/snice-select.js +1 -1
  216. package/dist/cdn/select/snice-select.min.js +1 -1
  217. package/dist/cdn/skeleton/snice-skeleton.js +1 -1
  218. package/dist/cdn/skeleton/snice-skeleton.min.js +1 -1
  219. package/dist/cdn/slider/snice-slider.js +1 -1
  220. package/dist/cdn/slider/snice-slider.min.js +1 -1
  221. package/dist/cdn/sortable/snice-sortable.js +1 -1
  222. package/dist/cdn/sortable/snice-sortable.min.js +1 -1
  223. package/dist/cdn/sparkline/snice-sparkline.js +1 -1
  224. package/dist/cdn/sparkline/snice-sparkline.min.js +1 -1
  225. package/dist/cdn/spinner/snice-spinner.js +1 -1
  226. package/dist/cdn/spinner/snice-spinner.min.js +1 -1
  227. package/dist/cdn/split-button/snice-split-button.js +1 -1
  228. package/dist/cdn/split-button/snice-split-button.min.js +1 -1
  229. package/dist/cdn/split-pane/snice-split-pane.js +1 -1
  230. package/dist/cdn/split-pane/snice-split-pane.min.js +1 -1
  231. package/dist/cdn/spotlight/snice-spotlight.js +1 -1
  232. package/dist/cdn/spotlight/snice-spotlight.min.js +1 -1
  233. package/dist/cdn/stat-group/snice-stat-group.js +1 -1
  234. package/dist/cdn/stat-group/snice-stat-group.min.js +1 -1
  235. package/dist/cdn/step-input/snice-step-input.js +1 -1
  236. package/dist/cdn/step-input/snice-step-input.min.js +1 -1
  237. package/dist/cdn/stepper/snice-stepper.js +1 -1
  238. package/dist/cdn/stepper/snice-stepper.min.js +1 -1
  239. package/dist/cdn/switch/snice-switch.js +1 -1
  240. package/dist/cdn/switch/snice-switch.min.js +1 -1
  241. package/dist/cdn/table/snice-table.js +1 -1
  242. package/dist/cdn/table/snice-table.min.js +1 -1
  243. package/dist/cdn/tabs/snice-tabs.js +1 -1
  244. package/dist/cdn/tabs/snice-tabs.min.js +1 -1
  245. package/dist/cdn/tag/snice-tag.js +1 -1
  246. package/dist/cdn/tag/snice-tag.min.js +1 -1
  247. package/dist/cdn/tag-input/snice-tag-input.js +1 -1
  248. package/dist/cdn/tag-input/snice-tag-input.min.js +1 -1
  249. package/dist/cdn/terminal/snice-terminal.js +1 -1
  250. package/dist/cdn/terminal/snice-terminal.min.js +1 -1
  251. package/dist/cdn/testimonial/snice-testimonial.js +1 -1
  252. package/dist/cdn/testimonial/snice-testimonial.min.js +1 -1
  253. package/dist/cdn/textarea/snice-textarea.js +1 -1
  254. package/dist/cdn/textarea/snice-textarea.min.js +1 -1
  255. package/dist/cdn/time-picker/snice-time-picker.js +1 -1
  256. package/dist/cdn/time-picker/snice-time-picker.min.js +1 -1
  257. package/dist/cdn/time-range-picker/snice-time-range-picker.js +1 -1
  258. package/dist/cdn/time-range-picker/snice-time-range-picker.min.js +1 -1
  259. package/dist/cdn/timeline/snice-timeline.js +1 -1
  260. package/dist/cdn/timeline/snice-timeline.min.js +1 -1
  261. package/dist/cdn/timer/snice-timer.js +1 -1
  262. package/dist/cdn/timer/snice-timer.min.js +1 -1
  263. package/dist/cdn/toast/snice-toast.js +1 -1
  264. package/dist/cdn/toast/snice-toast.min.js +1 -1
  265. package/dist/cdn/tooltip/snice-tooltip.js +1 -1
  266. package/dist/cdn/tooltip/snice-tooltip.min.js +1 -1
  267. package/dist/cdn/tree/snice-tree.js +1 -1
  268. package/dist/cdn/tree/snice-tree.min.js +1 -1
  269. package/dist/cdn/treemap/snice-treemap.js +1 -1
  270. package/dist/cdn/treemap/snice-treemap.min.js +1 -1
  271. package/dist/cdn/user-card/snice-user-card.js +1 -1
  272. package/dist/cdn/user-card/snice-user-card.min.js +1 -1
  273. package/dist/cdn/video-player/snice-video-player.js +1 -1
  274. package/dist/cdn/video-player/snice-video-player.min.js +1 -1
  275. package/dist/cdn/virtual-scroller/snice-virtual-scroller.js +1 -1
  276. package/dist/cdn/virtual-scroller/snice-virtual-scroller.min.js +1 -1
  277. package/dist/cdn/waterfall/snice-waterfall.js +1 -1
  278. package/dist/cdn/waterfall/snice-waterfall.min.js +1 -1
  279. package/dist/cdn/weather/snice-weather.js +1 -1
  280. package/dist/cdn/weather/snice-weather.min.js +1 -1
  281. package/dist/cdn/work-order/snice-work-order.js +1 -1
  282. package/dist/cdn/work-order/snice-work-order.min.js +1 -1
  283. package/dist/context.d.ts +2 -2
  284. package/dist/index.cjs +217 -202
  285. package/dist/index.cjs.map +1 -1
  286. package/dist/index.esm.js +217 -202
  287. package/dist/index.esm.js.map +1 -1
  288. package/dist/index.iife.js +217 -202
  289. package/dist/index.iife.js.map +1 -1
  290. package/dist/react/SniceProvider.js +1 -1
  291. package/dist/react/SniceRouter.js +1 -1
  292. package/dist/react/index.js +1 -1
  293. package/dist/react/matchRoute.js +1 -1
  294. package/dist/react/useRequestHandler.js +1 -1
  295. package/dist/symbols.cjs +1 -1
  296. package/dist/symbols.esm.js +1 -1
  297. package/dist/transitions.cjs +1 -1
  298. package/dist/transitions.esm.js +1 -1
  299. package/docs/STORYBOOK.md +1 -1
  300. package/docs/ai/api.md +4 -5
  301. package/docs/ai/decorators.md +2 -2
  302. package/docs/components/drawer.md +1 -1
  303. package/docs/elements.md +1 -1
  304. package/docs/routing.md +1 -1
  305. package/package.json +1 -1
@@ -1,11 +1,11 @@
1
1
  /*!
2
- * snice v5.1.0
2
+ * snice v5.2.0
3
3
  * A decorator-driven web component library with differential rendering, routing, controllers, and 130+ ready-made UI components. Use as much or as little as you want. Zero dependencies, works anywhere.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
6
6
  */
7
7
  /*!
8
- * snice v5.0.0
8
+ * snice v5.1.0
9
9
  * 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.
10
10
  * (c) 2024
11
11
  * Released under the MIT License.
@@ -2685,6 +2685,208 @@ function cleanupEventHandlers(instance) {
2685
2685
  instance[CLEANUP].events = [];
2686
2686
  }
2687
2687
 
2688
+ /**
2689
+ * @context decorator for receiving router context updates
2690
+ */
2691
+ const CONTEXT_HANDLERS = getSymbol('context-handlers');
2692
+ /**
2693
+ * @context decorator for receiving router context updates
2694
+ *
2695
+ * Works on both methods and fields:
2696
+ *
2697
+ * - **Method form**: the method is invoked with the current Context on every
2698
+ * update (and once at register time so the first render sees the context).
2699
+ * - **Field form**: the field is overwritten with the current Context on
2700
+ * every update (and once at register time). Pair with `@property` if you
2701
+ * want assignment to also schedule a re-render.
2702
+ *
2703
+ * @example
2704
+ * ```typescript
2705
+ * @element('my-layout')
2706
+ * class MyLayout extends HTMLElement {
2707
+ * // Method form
2708
+ * @context()
2709
+ * handleContext(ctx: Context) {
2710
+ * this.renderNav(ctx.navigation.placards, ctx.navigation.route);
2711
+ * }
2712
+ *
2713
+ * // Field form — the field is populated before first render
2714
+ * @context() ctx!: Context;
2715
+ *
2716
+ * // Field + @property — assignment also triggers re-render
2717
+ * @property({ attribute: false }) @context() reactiveCtx!: Context;
2718
+ * }
2719
+ * ```
2720
+ */
2721
+ function context$1(options = {}) {
2722
+ return function (value, decoratorContext) {
2723
+ const name = decoratorContext.name;
2724
+ const kind = decoratorContext.kind;
2725
+ const registerHandler = function () {
2726
+ const constructor = this.constructor;
2727
+ // De-dupe: methods identify by reference, fields identify by name.
2728
+ if (!Object.prototype.hasOwnProperty.call(constructor, CONTEXT_METHODS)) {
2729
+ constructor[CONTEXT_METHODS] = new Set();
2730
+ }
2731
+ const dedupeKey = kind === 'method' ? value : `field:${name}`;
2732
+ if (constructor[CONTEXT_METHODS].has(dedupeKey))
2733
+ return;
2734
+ constructor[CONTEXT_METHODS].add(dedupeKey);
2735
+ if (!Object.prototype.hasOwnProperty.call(constructor, CONTEXT_HANDLERS)) {
2736
+ const inherited = constructor[CONTEXT_HANDLERS];
2737
+ constructor[CONTEXT_HANDLERS] = inherited ? [...inherited] : [];
2738
+ }
2739
+ if (kind === 'method') {
2740
+ constructor[CONTEXT_HANDLERS].push({
2741
+ kind: 'method',
2742
+ methodName: name,
2743
+ method: value,
2744
+ options,
2745
+ });
2746
+ }
2747
+ else if (kind === 'field' || kind === 'accessor') {
2748
+ constructor[CONTEXT_HANDLERS].push({
2749
+ kind: 'field',
2750
+ fieldName: name,
2751
+ options,
2752
+ });
2753
+ }
2754
+ };
2755
+ if (kind === 'method') {
2756
+ decoratorContext.addInitializer(registerHandler);
2757
+ return value;
2758
+ }
2759
+ // Field decorators: do registration via the init function (fires per
2760
+ // instance during construction, with `this` bound). Returning the init
2761
+ // function is the canonical Stage 3 way for field decorators —
2762
+ // `addInitializer` for fields can be late or unreliable across runtimes.
2763
+ return function (initialValue) {
2764
+ registerHandler.call(this);
2765
+ return initialValue;
2766
+ };
2767
+ };
2768
+ }
2769
+ /**
2770
+ * Setup context handler for an element instance
2771
+ * Called automatically during element connection
2772
+ */
2773
+ // Accepts an HTMLElement OR a controller instance — both are plain objects
2774
+ // that may carry CONTEXT_HANDLER and a constructor with CONTEXT_HANDLERS.
2775
+ function setupContextHandler(element) {
2776
+ const handlers = element.constructor[CONTEXT_HANDLERS];
2777
+ if (!handlers || !Array.isArray(handlers) || handlers.length === 0) {
2778
+ return;
2779
+ }
2780
+ // Get the Context instance from the router
2781
+ const ctx = element[CONTEXT_HANDLER];
2782
+ if (!ctx) {
2783
+ return;
2784
+ }
2785
+ // Store the Context instance for cleanup
2786
+ element[NAVIGATION_CONTEXT_INSTANCE] = ctx;
2787
+ // Per-element Map of handler-name → wrapped function. Symbol-keyed so it
2788
+ // doesn't pollute the element's public surface.
2789
+ let wrapped = element[WRAPPED_CONTEXT_HANDLERS];
2790
+ if (!wrapped) {
2791
+ wrapped = new Map();
2792
+ element[WRAPPED_CONTEXT_HANDLERS] = wrapped;
2793
+ }
2794
+ // Register each handler with the Context
2795
+ for (const handler of handlers) {
2796
+ const { kind, options } = handler;
2797
+ const handlerName = kind === 'field' ? handler.fieldName : handler.methodName;
2798
+ // Create wrapped method with timing controls
2799
+ const wrappedFn = function (context) {
2800
+ // Skip if already called once
2801
+ if (options.once && element[CONTEXT_CALLED]) {
2802
+ return;
2803
+ }
2804
+ const callMethod = () => {
2805
+ if (kind === 'field') {
2806
+ element[handler.fieldName] = context;
2807
+ }
2808
+ else {
2809
+ handler.method.call(element, context);
2810
+ }
2811
+ // Handle once option
2812
+ if (options.once) {
2813
+ element[CONTEXT_CALLED] = true;
2814
+ // Unregister after first call
2815
+ const ctx = element[NAVIGATION_CONTEXT_INSTANCE];
2816
+ if (ctx && typeof ctx[CONTEXT_UNREGISTER] === 'function') {
2817
+ ctx[CONTEXT_UNREGISTER](element);
2818
+ }
2819
+ }
2820
+ };
2821
+ // Per-handler timer slot to avoid debounce/throttle handlers on the same
2822
+ // element overwriting each other's state.
2823
+ const timerSlot = element[CONTEXT_TIMER] ||
2824
+ (element[CONTEXT_TIMER] = {});
2825
+ const timerKey = handlerName;
2826
+ if (options.debounce) {
2827
+ clearTimeout(timerSlot[timerKey]?.timeout);
2828
+ timerSlot[timerKey] = {
2829
+ timeout: setTimeout(callMethod, options.debounce),
2830
+ };
2831
+ return;
2832
+ }
2833
+ if (options.throttle) {
2834
+ const now = Date.now();
2835
+ const lastCall = timerSlot[timerKey]?.lastCall || 0;
2836
+ if (now - lastCall >= options.throttle) {
2837
+ timerSlot[timerKey] = { lastCall: now };
2838
+ callMethod();
2839
+ }
2840
+ return;
2841
+ }
2842
+ callMethod();
2843
+ };
2844
+ wrapped.set(handlerName, wrappedFn);
2845
+ // Register with the Context using the handler name (lookup goes through
2846
+ // the WRAPPED_CONTEXT_HANDLERS Map on the element).
2847
+ if (typeof ctx[CONTEXT_REGISTER] === 'function') {
2848
+ ctx[CONTEXT_REGISTER](element, handlerName);
2849
+ }
2850
+ // Synchronously emit current context to the just-registered handler so
2851
+ // field/method values are populated BEFORE the first render microtask
2852
+ // flushes — eliminates the cold-render flicker where ctx is undefined.
2853
+ try {
2854
+ wrappedFn(ctx);
2855
+ }
2856
+ catch (error) {
2857
+ console.error(`Error invoking @context handler at registration:`, error);
2858
+ }
2859
+ }
2860
+ }
2861
+ /**
2862
+ * Cleanup context handler for an element instance
2863
+ * Called automatically during element disconnection
2864
+ */
2865
+ function cleanupContextHandler(element) {
2866
+ const handlers = element.constructor[CONTEXT_HANDLERS];
2867
+ if (!handlers || !Array.isArray(handlers) || handlers.length === 0) {
2868
+ return;
2869
+ }
2870
+ // Clear any pending debounce timers (per-handler slots)
2871
+ const timerSlot = element[CONTEXT_TIMER];
2872
+ if (timerSlot && typeof timerSlot === 'object') {
2873
+ for (const key of Object.keys(timerSlot)) {
2874
+ if (timerSlot[key]?.timeout)
2875
+ clearTimeout(timerSlot[key].timeout);
2876
+ }
2877
+ delete element[CONTEXT_TIMER];
2878
+ }
2879
+ // Drop the per-element wrapped-handlers Map.
2880
+ delete element[WRAPPED_CONTEXT_HANDLERS];
2881
+ // Unregister from Context if available
2882
+ const ctx = element[NAVIGATION_CONTEXT_INSTANCE];
2883
+ if (ctx && typeof ctx[CONTEXT_UNREGISTER] === 'function') {
2884
+ ctx[CONTEXT_UNREGISTER](element);
2885
+ }
2886
+ delete element[NAVIGATION_CONTEXT_INSTANCE];
2887
+ delete element[CONTEXT_CALLED];
2888
+ }
2889
+
2688
2890
  // Controller-scoped cleanup registry
2689
2891
  class ControllerScope {
2690
2892
  constructor() {
@@ -2790,6 +2992,14 @@ async function attachController(element, controllerName) {
2790
2992
  if (routerContext !== undefined) {
2791
2993
  controllerInstance[ROUTER_CONTEXT] = routerContext;
2792
2994
  }
2995
+ // Mirror the element's CONTEXT_HANDLER onto the controller so
2996
+ // setupContextHandler can wire @context() handlers declared on the
2997
+ // controller class. This makes @context() work identically on elements
2998
+ // and controllers.
2999
+ const ctxHandler = element[CONTEXT_HANDLER];
3000
+ if (ctxHandler !== undefined) {
3001
+ controllerInstance[CONTEXT_HANDLER] = ctxHandler;
3002
+ }
2793
3003
  // Store references
2794
3004
  element[CONTROLLER_KEY] = controllerInstance;
2795
3005
  element[CONTROLLER_NAME_KEY] = controllerName;
@@ -2828,6 +3038,8 @@ async function attachController(element, controllerName) {
2828
3038
  setupResponseHandlers(controllerInstance, element);
2829
3039
  // Setup @on event handlers for controller
2830
3040
  setupEventHandlers(controllerInstance, element);
3041
+ // Setup @context() handlers for controller (fires sync emit at register)
3042
+ setupContextHandler(controllerInstance);
2831
3043
  element.dispatchEvent(new CustomEvent('controller-attached', {
2832
3044
  detail: { name: controllerName, controller: controllerInstance }
2833
3045
  }));
@@ -2864,12 +3076,15 @@ async function detachController(element) {
2864
3076
  cleanupResponseHandlers(controllerInstance);
2865
3077
  // Cleanup @on event handlers for controller
2866
3078
  cleanupEventHandlers(controllerInstance);
3079
+ // Cleanup @context() handlers for controller
3080
+ cleanupContextHandler(controllerInstance);
2867
3081
  // Cleanup the controller scope
2868
3082
  if (scope) {
2869
3083
  await scope.cleanup();
2870
3084
  }
2871
- // Clean up router context reference
3085
+ // Clean up router/context references
2872
3086
  delete controllerInstance[ROUTER_CONTEXT];
3087
+ delete controllerInstance[CONTEXT_HANDLER];
2873
3088
  delete element[CONTROLLER_KEY];
2874
3089
  delete element[CONTROLLER_NAME_KEY];
2875
3090
  delete element[CONTROLLER_OPERATIONS];
@@ -2964,206 +3179,6 @@ function useNativeElementControllers() {
2964
3179
  globalThis.sniceNativeControllerObserver = observer;
2965
3180
  }
2966
3181
 
2967
- /**
2968
- * @context decorator for receiving router context updates
2969
- */
2970
- const CONTEXT_HANDLERS = getSymbol('context-handlers');
2971
- /**
2972
- * @context decorator for receiving router context updates
2973
- *
2974
- * Works on both methods and fields:
2975
- *
2976
- * - **Method form**: the method is invoked with the current Context on every
2977
- * update (and once at register time so the first render sees the context).
2978
- * - **Field form**: the field is overwritten with the current Context on
2979
- * every update (and once at register time). Pair with `@property` if you
2980
- * want assignment to also schedule a re-render.
2981
- *
2982
- * @example
2983
- * ```typescript
2984
- * @element('my-layout')
2985
- * class MyLayout extends HTMLElement {
2986
- * // Method form
2987
- * @context()
2988
- * handleContext(ctx: Context) {
2989
- * this.renderNav(ctx.navigation.placards, ctx.navigation.route);
2990
- * }
2991
- *
2992
- * // Field form — the field is populated before first render
2993
- * @context() ctx!: Context;
2994
- *
2995
- * // Field + @property — assignment also triggers re-render
2996
- * @property({ attribute: false }) @context() reactiveCtx!: Context;
2997
- * }
2998
- * ```
2999
- */
3000
- function context$1(options = {}) {
3001
- return function (value, decoratorContext) {
3002
- const name = decoratorContext.name;
3003
- const kind = decoratorContext.kind;
3004
- const registerHandler = function () {
3005
- const constructor = this.constructor;
3006
- // De-dupe: methods identify by reference, fields identify by name.
3007
- if (!Object.prototype.hasOwnProperty.call(constructor, CONTEXT_METHODS)) {
3008
- constructor[CONTEXT_METHODS] = new Set();
3009
- }
3010
- const dedupeKey = kind === 'method' ? value : `field:${name}`;
3011
- if (constructor[CONTEXT_METHODS].has(dedupeKey))
3012
- return;
3013
- constructor[CONTEXT_METHODS].add(dedupeKey);
3014
- if (!Object.prototype.hasOwnProperty.call(constructor, CONTEXT_HANDLERS)) {
3015
- const inherited = constructor[CONTEXT_HANDLERS];
3016
- constructor[CONTEXT_HANDLERS] = inherited ? [...inherited] : [];
3017
- }
3018
- if (kind === 'method') {
3019
- constructor[CONTEXT_HANDLERS].push({
3020
- kind: 'method',
3021
- methodName: name,
3022
- method: value,
3023
- options,
3024
- });
3025
- }
3026
- else if (kind === 'field' || kind === 'accessor') {
3027
- constructor[CONTEXT_HANDLERS].push({
3028
- kind: 'field',
3029
- fieldName: name,
3030
- options,
3031
- });
3032
- }
3033
- };
3034
- if (kind === 'method') {
3035
- decoratorContext.addInitializer(registerHandler);
3036
- return value;
3037
- }
3038
- // Field decorators: do registration via the init function (fires per
3039
- // instance during construction, with `this` bound). Returning the init
3040
- // function is the canonical Stage 3 way for field decorators —
3041
- // `addInitializer` for fields can be late or unreliable across runtimes.
3042
- return function (initialValue) {
3043
- registerHandler.call(this);
3044
- return initialValue;
3045
- };
3046
- };
3047
- }
3048
- /**
3049
- * Setup context handler for an element instance
3050
- * Called automatically during element connection
3051
- */
3052
- function setupContextHandler(element) {
3053
- const handlers = element.constructor[CONTEXT_HANDLERS];
3054
- if (!handlers || !Array.isArray(handlers) || handlers.length === 0) {
3055
- return;
3056
- }
3057
- // Get the Context instance from the router
3058
- const ctx = element[CONTEXT_HANDLER];
3059
- if (!ctx) {
3060
- return;
3061
- }
3062
- // Store the Context instance for cleanup
3063
- element[NAVIGATION_CONTEXT_INSTANCE] = ctx;
3064
- // Per-element Map of handler-name → wrapped function. Symbol-keyed so it
3065
- // doesn't pollute the element's public surface.
3066
- let wrapped = element[WRAPPED_CONTEXT_HANDLERS];
3067
- if (!wrapped) {
3068
- wrapped = new Map();
3069
- element[WRAPPED_CONTEXT_HANDLERS] = wrapped;
3070
- }
3071
- // Register each handler with the Context
3072
- for (const handler of handlers) {
3073
- const { kind, options } = handler;
3074
- const handlerName = kind === 'field' ? handler.fieldName : handler.methodName;
3075
- // Create wrapped method with timing controls
3076
- const wrappedFn = function (context) {
3077
- // Skip if already called once
3078
- if (options.once && element[CONTEXT_CALLED]) {
3079
- return;
3080
- }
3081
- const callMethod = () => {
3082
- if (kind === 'field') {
3083
- element[handler.fieldName] = context;
3084
- }
3085
- else {
3086
- handler.method.call(element, context);
3087
- }
3088
- // Handle once option
3089
- if (options.once) {
3090
- element[CONTEXT_CALLED] = true;
3091
- // Unregister after first call
3092
- const ctx = element[NAVIGATION_CONTEXT_INSTANCE];
3093
- if (ctx && typeof ctx[CONTEXT_UNREGISTER] === 'function') {
3094
- ctx[CONTEXT_UNREGISTER](element);
3095
- }
3096
- }
3097
- };
3098
- // Per-handler timer slot to avoid debounce/throttle handlers on the same
3099
- // element overwriting each other's state.
3100
- const timerSlot = element[CONTEXT_TIMER] ||
3101
- (element[CONTEXT_TIMER] = {});
3102
- const timerKey = handlerName;
3103
- if (options.debounce) {
3104
- clearTimeout(timerSlot[timerKey]?.timeout);
3105
- timerSlot[timerKey] = {
3106
- timeout: setTimeout(callMethod, options.debounce),
3107
- };
3108
- return;
3109
- }
3110
- if (options.throttle) {
3111
- const now = Date.now();
3112
- const lastCall = timerSlot[timerKey]?.lastCall || 0;
3113
- if (now - lastCall >= options.throttle) {
3114
- timerSlot[timerKey] = { lastCall: now };
3115
- callMethod();
3116
- }
3117
- return;
3118
- }
3119
- callMethod();
3120
- };
3121
- wrapped.set(handlerName, wrappedFn);
3122
- // Register with the Context using the handler name (lookup goes through
3123
- // the WRAPPED_CONTEXT_HANDLERS Map on the element).
3124
- if (typeof ctx[CONTEXT_REGISTER] === 'function') {
3125
- ctx[CONTEXT_REGISTER](element, handlerName);
3126
- }
3127
- // Synchronously emit current context to the just-registered handler so
3128
- // field/method values are populated BEFORE the first render microtask
3129
- // flushes — eliminates the cold-render flicker where ctx is undefined.
3130
- try {
3131
- wrappedFn(ctx);
3132
- }
3133
- catch (error) {
3134
- console.error(`Error invoking @context handler at registration:`, error);
3135
- }
3136
- }
3137
- }
3138
- /**
3139
- * Cleanup context handler for an element instance
3140
- * Called automatically during element disconnection
3141
- */
3142
- function cleanupContextHandler(element) {
3143
- const handlers = element.constructor[CONTEXT_HANDLERS];
3144
- if (!handlers || !Array.isArray(handlers) || handlers.length === 0) {
3145
- return;
3146
- }
3147
- // Clear any pending debounce timers (per-handler slots)
3148
- const timerSlot = element[CONTEXT_TIMER];
3149
- if (timerSlot && typeof timerSlot === 'object') {
3150
- for (const key of Object.keys(timerSlot)) {
3151
- if (timerSlot[key]?.timeout)
3152
- clearTimeout(timerSlot[key].timeout);
3153
- }
3154
- delete element[CONTEXT_TIMER];
3155
- }
3156
- // Drop the per-element wrapped-handlers Map.
3157
- delete element[WRAPPED_CONTEXT_HANDLERS];
3158
- // Unregister from Context if available
3159
- const ctx = element[NAVIGATION_CONTEXT_INSTANCE];
3160
- if (ctx && typeof ctx[CONTEXT_UNREGISTER] === 'function') {
3161
- ctx[CONTEXT_UNREGISTER](element);
3162
- }
3163
- delete element[NAVIGATION_CONTEXT_INSTANCE];
3164
- delete element[CONTEXT_CALLED];
3165
- }
3166
-
3167
3182
  /**
3168
3183
  * @render and @styles decorators for Snice v3.0.0
3169
3184
  * Provides automatic differential rendering on property changes
@@ -6161,7 +6176,7 @@ if (typeof document !== 'undefined') {
6161
6176
  }
6162
6177
 
6163
6178
  /*!
6164
- * snice v5.0.0
6179
+ * snice v5.1.0
6165
6180
  * 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.
6166
6181
  * (c) 2024
6167
6182
  * Released under the MIT License.
@@ -6180,7 +6195,7 @@ if (!globalThis.snice) {
6180
6195
  }
6181
6196
 
6182
6197
  /*!
6183
- * snice v5.0.0
6198
+ * snice v5.1.0
6184
6199
  * 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.
6185
6200
  * (c) 2024
6186
6201
  * Released under the MIT License.