snice 4.13.0 → 4.15.0

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