snice 4.14.0 → 4.16.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 (384) 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/input.d.ts +3 -0
  7. package/adapters/react/input.d.ts.map +1 -1
  8. package/adapters/react/input.js +1 -1
  9. package/adapters/react/input.js.map +1 -1
  10. package/adapters/react/input.tsx +4 -1
  11. package/adapters/react/modal.d.ts +2 -0
  12. package/adapters/react/modal.d.ts.map +1 -1
  13. package/adapters/react/modal.js +1 -1
  14. package/adapters/react/modal.js.map +1 -1
  15. package/adapters/react/modal.tsx +3 -1
  16. package/dist/cdn/accordion/snice-accordion.js +1 -1
  17. package/dist/cdn/accordion/snice-accordion.min.js +1 -1
  18. package/dist/cdn/alert/snice-alert.js +1 -1
  19. package/dist/cdn/alert/snice-alert.min.js +1 -1
  20. package/dist/cdn/app-tiles/snice-app-tiles.js +1 -1
  21. package/dist/cdn/app-tiles/snice-app-tiles.min.js +1 -1
  22. package/dist/cdn/audio-recorder/snice-audio-recorder.js +1 -1
  23. package/dist/cdn/audio-recorder/snice-audio-recorder.min.js +1 -1
  24. package/dist/cdn/avatar/snice-avatar.js +1 -1
  25. package/dist/cdn/avatar/snice-avatar.min.js +1 -1
  26. package/dist/cdn/badge/snice-badge.js +1 -1
  27. package/dist/cdn/badge/snice-badge.min.js +1 -1
  28. package/dist/cdn/banner/snice-banner.js +1 -1
  29. package/dist/cdn/banner/snice-banner.min.js +1 -1
  30. package/dist/cdn/book/README.md +2 -2
  31. package/dist/cdn/book/snice-book.js +29 -8
  32. package/dist/cdn/book/snice-book.js.map +1 -1
  33. package/dist/cdn/book/snice-book.min.js +3 -3
  34. package/dist/cdn/book/snice-book.min.js.map +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/chart/snice-chart.js +1 -1
  52. package/dist/cdn/chart/snice-chart.min.js +1 -1
  53. package/dist/cdn/chat/snice-chat.js +1 -1
  54. package/dist/cdn/chat/snice-chat.min.js +1 -1
  55. package/dist/cdn/checkbox/snice-checkbox.js +1 -1
  56. package/dist/cdn/checkbox/snice-checkbox.min.js +1 -1
  57. package/dist/cdn/chip/snice-chip.js +1 -1
  58. package/dist/cdn/chip/snice-chip.min.js +1 -1
  59. package/dist/cdn/code-block/snice-code-block.js +4 -4
  60. package/dist/cdn/code-block/snice-code-block.js.map +1 -1
  61. package/dist/cdn/code-block/snice-code-block.min.js +2 -2
  62. package/dist/cdn/code-block/snice-code-block.min.js.map +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/date-picker/README.md +1 -1
  76. package/dist/cdn/date-picker/snice-date-picker.js +49 -39
  77. package/dist/cdn/date-picker/snice-date-picker.js.map +1 -1
  78. package/dist/cdn/date-picker/snice-date-picker.min.js +4 -4
  79. package/dist/cdn/date-picker/snice-date-picker.min.js.map +1 -1
  80. package/dist/cdn/diff/snice-diff.js +1 -1
  81. package/dist/cdn/diff/snice-diff.min.js +1 -1
  82. package/dist/cdn/divider/snice-divider.js +1 -1
  83. package/dist/cdn/divider/snice-divider.min.js +1 -1
  84. package/dist/cdn/doc/README.md +2 -2
  85. package/dist/cdn/doc/snice-doc.js +221 -35
  86. package/dist/cdn/doc/snice-doc.js.map +1 -1
  87. package/dist/cdn/doc/snice-doc.min.js +2 -2
  88. package/dist/cdn/doc/snice-doc.min.js.map +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/file-gallery/snice-file-gallery.js +1 -1
  96. package/dist/cdn/file-gallery/snice-file-gallery.min.js +1 -1
  97. package/dist/cdn/file-upload/snice-file-upload.js +1 -1
  98. package/dist/cdn/file-upload/snice-file-upload.min.js +1 -1
  99. package/dist/cdn/flip-card/snice-flip-card.js +1 -1
  100. package/dist/cdn/flip-card/snice-flip-card.min.js +1 -1
  101. package/dist/cdn/flow/snice-flow.js +1 -1
  102. package/dist/cdn/flow/snice-flow.min.js +1 -1
  103. package/dist/cdn/funnel/snice-funnel.js +1 -1
  104. package/dist/cdn/funnel/snice-funnel.min.js +1 -1
  105. package/dist/cdn/gantt/snice-gantt.js +1 -1
  106. package/dist/cdn/gantt/snice-gantt.min.js +1 -1
  107. package/dist/cdn/gauge/snice-gauge.js +1 -1
  108. package/dist/cdn/gauge/snice-gauge.min.js +1 -1
  109. package/dist/cdn/heatmap/snice-heatmap.js +1 -1
  110. package/dist/cdn/heatmap/snice-heatmap.min.js +1 -1
  111. package/dist/cdn/image/snice-image.js +1 -1
  112. package/dist/cdn/image/snice-image.min.js +1 -1
  113. package/dist/cdn/input/README.md +2 -2
  114. package/dist/cdn/input/snice-input.js +21 -3
  115. package/dist/cdn/input/snice-input.js.map +1 -1
  116. package/dist/cdn/input/snice-input.min.js +3 -3
  117. package/dist/cdn/input/snice-input.min.js.map +1 -1
  118. package/dist/cdn/kanban/snice-kanban.js +1 -1
  119. package/dist/cdn/kanban/snice-kanban.min.js +1 -1
  120. package/dist/cdn/kpi/snice-kpi.js +1 -1
  121. package/dist/cdn/kpi/snice-kpi.min.js +1 -1
  122. package/dist/cdn/layout/snice-layout.js +1 -1
  123. package/dist/cdn/layout/snice-layout.min.js +1 -1
  124. package/dist/cdn/link/snice-link.js +1 -1
  125. package/dist/cdn/link/snice-link.min.js +1 -1
  126. package/dist/cdn/link-preview/snice-link-preview.js +2 -2
  127. package/dist/cdn/link-preview/snice-link-preview.js.map +1 -1
  128. package/dist/cdn/link-preview/snice-link-preview.min.js +2 -2
  129. package/dist/cdn/link-preview/snice-link-preview.min.js.map +1 -1
  130. package/dist/cdn/list/snice-list.js +4 -4
  131. package/dist/cdn/list/snice-list.js.map +1 -1
  132. package/dist/cdn/list/snice-list.min.js +2 -2
  133. package/dist/cdn/list/snice-list.min.js.map +1 -1
  134. package/dist/cdn/location/snice-location.js +1 -1
  135. package/dist/cdn/location/snice-location.min.js +1 -1
  136. package/dist/cdn/login/snice-login.js +1 -1
  137. package/dist/cdn/login/snice-login.min.js +1 -1
  138. package/dist/cdn/map/snice-map.js +1 -1
  139. package/dist/cdn/map/snice-map.min.js +1 -1
  140. package/dist/cdn/markdown/snice-markdown.js +1 -1
  141. package/dist/cdn/markdown/snice-markdown.min.js +1 -1
  142. package/dist/cdn/masonry/snice-masonry.js +1 -1
  143. package/dist/cdn/masonry/snice-masonry.min.js +1 -1
  144. package/dist/cdn/menu/snice-menu.js +2 -2
  145. package/dist/cdn/menu/snice-menu.js.map +1 -1
  146. package/dist/cdn/menu/snice-menu.min.js +2 -2
  147. package/dist/cdn/menu/snice-menu.min.js.map +1 -1
  148. package/dist/cdn/modal/README.md +2 -2
  149. package/dist/cdn/modal/snice-modal.js +34 -18
  150. package/dist/cdn/modal/snice-modal.js.map +1 -1
  151. package/dist/cdn/modal/snice-modal.min.js +24 -20
  152. package/dist/cdn/modal/snice-modal.min.js.map +1 -1
  153. package/dist/cdn/music-player/README.md +2 -2
  154. package/dist/cdn/music-player/snice-music-player.js +8 -1
  155. package/dist/cdn/music-player/snice-music-player.js.map +1 -1
  156. package/dist/cdn/music-player/snice-music-player.min.js +3 -3
  157. package/dist/cdn/music-player/snice-music-player.min.js.map +1 -1
  158. package/dist/cdn/nav/snice-nav.js +1 -1
  159. package/dist/cdn/nav/snice-nav.min.js +1 -1
  160. package/dist/cdn/network-graph/snice-network-graph.js +1 -1
  161. package/dist/cdn/network-graph/snice-network-graph.min.js +1 -1
  162. package/dist/cdn/notification-center/snice-notification-center.js +1 -1
  163. package/dist/cdn/notification-center/snice-notification-center.min.js +1 -1
  164. package/dist/cdn/org-chart/snice-org-chart.js +1 -1
  165. package/dist/cdn/org-chart/snice-org-chart.min.js +1 -1
  166. package/dist/cdn/pagination/snice-pagination.js +1 -1
  167. package/dist/cdn/pagination/snice-pagination.min.js +1 -1
  168. package/dist/cdn/paint/snice-paint.js +1 -1
  169. package/dist/cdn/paint/snice-paint.min.js +1 -1
  170. package/dist/cdn/pdf-viewer/snice-pdf-viewer.js +1 -1
  171. package/dist/cdn/pdf-viewer/snice-pdf-viewer.min.js +1 -1
  172. package/dist/cdn/podcast-player/snice-podcast-player.js +1 -1
  173. package/dist/cdn/podcast-player/snice-podcast-player.min.js +1 -1
  174. package/dist/cdn/pricing-table/snice-pricing-table.js +1 -1
  175. package/dist/cdn/pricing-table/snice-pricing-table.min.js +1 -1
  176. package/dist/cdn/progress/snice-progress.js +1 -1
  177. package/dist/cdn/progress/snice-progress.min.js +1 -1
  178. package/dist/cdn/qr-code/snice-qr-code.js +1 -1
  179. package/dist/cdn/qr-code/snice-qr-code.min.js +1 -1
  180. package/dist/cdn/qr-reader/snice-qr-reader.js +1 -1
  181. package/dist/cdn/qr-reader/snice-qr-reader.min.js +1 -1
  182. package/dist/cdn/radio/README.md +2 -2
  183. package/dist/cdn/radio/snice-radio.js +23 -3
  184. package/dist/cdn/radio/snice-radio.js.map +1 -1
  185. package/dist/cdn/radio/snice-radio.min.js +3 -3
  186. package/dist/cdn/radio/snice-radio.min.js.map +1 -1
  187. package/dist/cdn/rating/snice-rating.js +1 -1
  188. package/dist/cdn/rating/snice-rating.min.js +1 -1
  189. package/dist/cdn/recipe/snice-recipe.js +1 -1
  190. package/dist/cdn/recipe/snice-recipe.min.js +1 -1
  191. package/dist/cdn/runtime/README.md +2 -2
  192. package/dist/cdn/runtime/snice-runtime.esm.js +513 -46
  193. package/dist/cdn/runtime/snice-runtime.esm.js.map +1 -1
  194. package/dist/cdn/runtime/snice-runtime.esm.min.js +6 -6
  195. package/dist/cdn/runtime/snice-runtime.esm.min.js.map +1 -1
  196. package/dist/cdn/runtime/snice-runtime.js +6420 -5951
  197. package/dist/cdn/runtime/snice-runtime.js.map +1 -1
  198. package/dist/cdn/runtime/snice-runtime.min.js +18 -18
  199. package/dist/cdn/runtime/snice-runtime.min.js.map +1 -1
  200. package/dist/cdn/sankey/snice-sankey.js +1 -1
  201. package/dist/cdn/sankey/snice-sankey.min.js +1 -1
  202. package/dist/cdn/select/README.md +2 -2
  203. package/dist/cdn/select/snice-select.js +46 -92
  204. package/dist/cdn/select/snice-select.js.map +1 -1
  205. package/dist/cdn/select/snice-select.min.js +5 -13
  206. package/dist/cdn/select/snice-select.min.js.map +1 -1
  207. package/dist/cdn/skeleton/snice-skeleton.js +1 -1
  208. package/dist/cdn/skeleton/snice-skeleton.min.js +1 -1
  209. package/dist/cdn/slider/snice-slider.js +1 -1
  210. package/dist/cdn/slider/snice-slider.min.js +1 -1
  211. package/dist/cdn/sortable/snice-sortable.js +1 -1
  212. package/dist/cdn/sortable/snice-sortable.min.js +1 -1
  213. package/dist/cdn/sparkline/snice-sparkline.js +1 -1
  214. package/dist/cdn/sparkline/snice-sparkline.min.js +1 -1
  215. package/dist/cdn/spinner/snice-spinner.js +1 -1
  216. package/dist/cdn/spinner/snice-spinner.min.js +1 -1
  217. package/dist/cdn/split-pane/snice-split-pane.js +1 -1
  218. package/dist/cdn/split-pane/snice-split-pane.min.js +1 -1
  219. package/dist/cdn/spotlight/snice-spotlight.js +1 -1
  220. package/dist/cdn/spotlight/snice-spotlight.min.js +1 -1
  221. package/dist/cdn/spreadsheet/snice-spreadsheet.js +1 -1
  222. package/dist/cdn/spreadsheet/snice-spreadsheet.min.js +1 -1
  223. package/dist/cdn/stepper/snice-stepper.js +1 -1
  224. package/dist/cdn/stepper/snice-stepper.min.js +1 -1
  225. package/dist/cdn/switch/README.md +1 -1
  226. package/dist/cdn/switch/snice-switch.js +33 -23
  227. package/dist/cdn/switch/snice-switch.js.map +1 -1
  228. package/dist/cdn/switch/snice-switch.min.js +3 -3
  229. package/dist/cdn/switch/snice-switch.min.js.map +1 -1
  230. package/dist/cdn/table/README.md +2 -2
  231. package/dist/cdn/table/snice-table.js +2876 -111
  232. package/dist/cdn/table/snice-table.js.map +1 -1
  233. package/dist/cdn/table/snice-table.min.js +187 -47
  234. package/dist/cdn/table/snice-table.min.js.map +1 -1
  235. package/dist/cdn/tabs/snice-tabs.js +1 -1
  236. package/dist/cdn/tabs/snice-tabs.min.js +1 -1
  237. package/dist/cdn/tag-input/snice-tag-input.js +1 -1
  238. package/dist/cdn/tag-input/snice-tag-input.min.js +1 -1
  239. package/dist/cdn/terminal/snice-terminal.js +1 -1
  240. package/dist/cdn/terminal/snice-terminal.min.js +1 -1
  241. package/dist/cdn/testimonial/snice-testimonial.js +1 -1
  242. package/dist/cdn/testimonial/snice-testimonial.min.js +1 -1
  243. package/dist/cdn/textarea/snice-textarea.js +1 -1
  244. package/dist/cdn/textarea/snice-textarea.min.js +1 -1
  245. package/dist/cdn/time-range-picker/snice-time-range-picker.js +1 -1
  246. package/dist/cdn/time-range-picker/snice-time-range-picker.min.js +1 -1
  247. package/dist/cdn/timeline/snice-timeline.js +1 -1
  248. package/dist/cdn/timeline/snice-timeline.min.js +1 -1
  249. package/dist/cdn/timer/snice-timer.js +1 -1
  250. package/dist/cdn/timer/snice-timer.min.js +1 -1
  251. package/dist/cdn/toast/README.md +1 -1
  252. package/dist/cdn/toast/snice-toast.js +3 -3
  253. package/dist/cdn/toast/snice-toast.js.map +1 -1
  254. package/dist/cdn/toast/snice-toast.min.js +2 -2
  255. package/dist/cdn/toast/snice-toast.min.js.map +1 -1
  256. package/dist/cdn/tooltip/snice-tooltip.js +1 -1
  257. package/dist/cdn/tooltip/snice-tooltip.min.js +1 -1
  258. package/dist/cdn/tree/snice-tree.js +1 -1
  259. package/dist/cdn/tree/snice-tree.min.js +1 -1
  260. package/dist/cdn/treemap/snice-treemap.js +1 -1
  261. package/dist/cdn/treemap/snice-treemap.min.js +1 -1
  262. package/dist/cdn/video-player/snice-video-player.js +1 -1
  263. package/dist/cdn/video-player/snice-video-player.min.js +1 -1
  264. package/dist/cdn/virtual-scroller/snice-virtual-scroller.js +1 -1
  265. package/dist/cdn/virtual-scroller/snice-virtual-scroller.min.js +1 -1
  266. package/dist/cdn/waterfall/snice-waterfall.js +1 -1
  267. package/dist/cdn/waterfall/snice-waterfall.min.js +1 -1
  268. package/dist/cdn/weather/snice-weather.js +1 -1
  269. package/dist/cdn/weather/snice-weather.min.js +1 -1
  270. package/dist/components/book/snice-book.d.ts +2 -0
  271. package/dist/components/book/snice-book.js +28 -7
  272. package/dist/components/book/snice-book.js.map +1 -1
  273. package/dist/components/book/snice-book.types.d.ts +7 -0
  274. package/dist/components/code-block/snice-code-block.js +3 -3
  275. package/dist/components/code-block/snice-code-block.js.map +1 -1
  276. package/dist/components/code-block/snice-code-block.types.d.ts +3 -3
  277. package/dist/components/date-picker/snice-date-picker.d.ts +2 -0
  278. package/dist/components/date-picker/snice-date-picker.js +49 -39
  279. package/dist/components/date-picker/snice-date-picker.js.map +1 -1
  280. package/dist/components/doc/snice-doc.d.ts +20 -0
  281. package/dist/components/doc/snice-doc.js +220 -34
  282. package/dist/components/doc/snice-doc.js.map +1 -1
  283. package/dist/components/input/snice-input.d.ts +3 -0
  284. package/dist/components/input/snice-input.js +20 -2
  285. package/dist/components/input/snice-input.js.map +1 -1
  286. package/dist/components/input/snice-input.types.d.ts +3 -0
  287. package/dist/components/link-preview/snice-link-preview.js +1 -1
  288. package/dist/components/link-preview/snice-link-preview.js.map +1 -1
  289. package/dist/components/list/snice-list.js +3 -3
  290. package/dist/components/list/snice-list.js.map +1 -1
  291. package/dist/components/menu/snice-menu.js +1 -1
  292. package/dist/components/menu/snice-menu.js.map +1 -1
  293. package/dist/components/modal/snice-modal.d.ts +2 -0
  294. package/dist/components/modal/snice-modal.js +33 -17
  295. package/dist/components/modal/snice-modal.js.map +1 -1
  296. package/dist/components/modal/snice-modal.types.d.ts +2 -0
  297. package/dist/components/music-player/snice-music-player.d.ts +1 -0
  298. package/dist/components/music-player/snice-music-player.js +7 -0
  299. package/dist/components/music-player/snice-music-player.js.map +1 -1
  300. package/dist/components/notification-center/snice-notification-center.d.ts +1 -1
  301. package/dist/components/notification-center/snice-notification-center.js.map +1 -1
  302. package/dist/components/notification-center/snice-notification-center.types.d.ts +1 -0
  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/switch/snice-switch.d.ts +2 -0
  310. package/dist/components/switch/snice-switch.js +32 -22
  311. package/dist/components/switch/snice-switch.js.map +1 -1
  312. package/dist/components/table/snice-table.d.ts +2 -0
  313. package/dist/components/table/snice-table.js +17 -3
  314. package/dist/components/table/snice-table.js.map +1 -1
  315. package/dist/components/toast/snice-toast-container.js +2 -2
  316. package/dist/components/toast/snice-toast-container.js.map +1 -1
  317. package/dist/index.cjs +512 -43
  318. package/dist/index.cjs.map +1 -1
  319. package/dist/index.d.ts +1 -0
  320. package/dist/index.esm.js +511 -44
  321. package/dist/index.esm.js.map +1 -1
  322. package/dist/index.iife.js +512 -43
  323. package/dist/index.iife.js.map +1 -1
  324. package/dist/symbols.cjs +1 -1
  325. package/dist/symbols.esm.js +1 -1
  326. package/dist/tooltip-observer.d.ts +11 -0
  327. package/dist/transitions.cjs +1 -1
  328. package/dist/transitions.esm.js +1 -1
  329. package/docs/ai/DEVELOPMENT.md +1 -1
  330. package/docs/ai/api.md +14 -10
  331. package/docs/ai/architecture.md +18 -5
  332. package/docs/ai/components/app-tiles.md +1 -1
  333. package/docs/ai/components/book.md +5 -6
  334. package/docs/ai/components/camera-annotate.md +3 -3
  335. package/docs/ai/components/candlestick.md +3 -3
  336. package/docs/ai/components/chart.md +1 -1
  337. package/docs/ai/components/code-block.md +3 -3
  338. package/docs/ai/components/doc.md +26 -15
  339. package/docs/ai/components/file-gallery.md +1 -1
  340. package/docs/ai/components/input.md +10 -0
  341. package/docs/ai/components/link-preview.md +1 -1
  342. package/docs/ai/components/list.md +2 -2
  343. package/docs/ai/components/markdown.md +13 -6
  344. package/docs/ai/components/modal.md +2 -0
  345. package/docs/ai/components/music-player.md +3 -2
  346. package/docs/ai/components/network-graph.md +5 -5
  347. package/docs/ai/components/notification-center.md +1 -0
  348. package/docs/ai/components/pdf-viewer.md +1 -1
  349. package/docs/ai/components/radio.md +2 -2
  350. package/docs/ai/components/sankey.md +3 -3
  351. package/docs/ai/components/select.md +1 -1
  352. package/docs/ai/components/tooltip.md +54 -0
  353. package/docs/ai/decorators.md +4 -4
  354. package/docs/code-block.md +4 -4
  355. package/docs/components/app-tiles.md +1 -1
  356. package/docs/components/book.md +3 -4
  357. package/docs/components/button.md +2 -2
  358. package/docs/components/camera-annotate.md +6 -6
  359. package/docs/components/candlestick.md +6 -6
  360. package/docs/components/chart.md +4 -6
  361. package/docs/components/checkbox.md +3 -3
  362. package/docs/components/chip.md +4 -4
  363. package/docs/components/code-block.md +4 -3
  364. package/docs/components/doc.md +99 -58
  365. package/docs/components/file-gallery.md +25 -3
  366. package/docs/components/input.md +20 -0
  367. package/docs/components/kpi.md +2 -3
  368. package/docs/components/link-preview.md +2 -2
  369. package/docs/components/list.md +3 -3
  370. package/docs/components/markdown.md +14 -36
  371. package/docs/components/modal.md +2 -0
  372. package/docs/components/music-player.md +3 -2
  373. package/docs/components/network-graph.md +7 -7
  374. package/docs/components/notification-center.md +1 -0
  375. package/docs/components/pdf-viewer.md +1 -1
  376. package/docs/components/sankey.md +6 -6
  377. package/docs/components/switch.md +1 -1
  378. package/docs/components/table.md +2 -2
  379. package/docs/components/tooltip.md +133 -0
  380. package/docs/controllers.md +3 -14
  381. package/docs/elements.md +0 -1
  382. package/docs/events.md +3 -0
  383. package/docs/request-response.md +2 -0
  384. package/package.json +1 -1
@@ -1,11 +1,11 @@
1
1
  /*!
2
- * snice v4.13.0
2
+ * snice v4.15.0
3
3
  * Imperative TypeScript framework for building vanilla web components with decorators, differential rendering, routing, and controllers. No virtual DOM, no build complexity.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
6
6
  */
7
7
  /*!
8
- * snice v4.13.0
8
+ * snice v4.15.0
9
9
  * Imperative TypeScript framework for building vanilla web components with decorators, differential rendering, routing, and controllers. No virtual DOM, no build complexity.
10
10
  * (c) 2024
11
11
  * Released under the MIT License.
@@ -1813,10 +1813,12 @@ class ConditionalCasePart extends Part {
1813
1813
  this.defaultChild = null;
1814
1814
  this.currentChild = null;
1815
1815
  this.caseElement = caseElement;
1816
+ this.caseElement.style.display = 'contents';
1816
1817
  // Build map and store children in fragments initially
1817
1818
  for (const child of Array.from(this.caseElement.children)) {
1818
1819
  const childTag = child.tagName.toLowerCase();
1819
1820
  if (childTag === 'when') {
1821
+ child.style.display = 'contents';
1820
1822
  const whenValue = child.getAttribute('value') || '';
1821
1823
  this.childrenMap.set(whenValue, child);
1822
1824
  const fragment = document.createDocumentFragment();
@@ -1824,6 +1826,7 @@ class ConditionalCasePart extends Part {
1824
1826
  this.fragments.set(child, fragment);
1825
1827
  }
1826
1828
  else if (childTag === 'default') {
1829
+ child.style.display = 'contents';
1827
1830
  this.defaultChild = child;
1828
1831
  const fragment = document.createDocumentFragment();
1829
1832
  fragment.appendChild(child);
@@ -2310,7 +2313,7 @@ async function attachController(element, controllerName) {
2310
2313
  setupResponseHandlers(controllerInstance, element);
2311
2314
  // Setup @on event handlers for controller
2312
2315
  setupEventHandlers(controllerInstance, element);
2313
- element.dispatchEvent(new CustomEvent('@snice/controller-attached', {
2316
+ element.dispatchEvent(new CustomEvent('controller-attached', {
2314
2317
  detail: { name: controllerName, controller: controllerInstance }
2315
2318
  }));
2316
2319
  }
@@ -2350,7 +2353,7 @@ async function detachController(element) {
2350
2353
  delete element[CONTROLLER_KEY];
2351
2354
  delete element[CONTROLLER_NAME_KEY];
2352
2355
  delete element[CONTROLLER_OPERATIONS];
2353
- element.dispatchEvent(new CustomEvent('@snice/controller-detached', {
2356
+ element.dispatchEvent(new CustomEvent('controller-detached', {
2354
2357
  detail: { name: controllerName, controller: controllerInstance }
2355
2358
  }));
2356
2359
  }
@@ -3192,10 +3195,12 @@ function applyElementFunctionality(constructor) {
3192
3195
  if (!observedAttributes.includes('controller')) {
3193
3196
  observedAttributes.push('controller');
3194
3197
  }
3195
- // Add all properties to observed attributes (not just reflected ones)
3198
+ // Add all properties to observed attributes (skip attribute: false)
3196
3199
  const properties = constructor[PROPERTIES];
3197
3200
  if (properties) {
3198
3201
  for (const [propName, propOptions] of properties) {
3202
+ if (propOptions.attribute === false)
3203
+ continue;
3199
3204
  const attributeName = typeof propOptions.attribute === 'string' ? propOptions.attribute : propName.toLowerCase();
3200
3205
  if (!observedAttributes.includes(attributeName)) {
3201
3206
  observedAttributes.push(attributeName);
@@ -3282,6 +3287,9 @@ function applyElementFunctionality(constructor) {
3282
3287
  const properties = constructor[PROPERTIES];
3283
3288
  if (properties) {
3284
3289
  for (const [propName, propOptions] of properties) {
3290
+ // Skip properties that opted out of attribute sync
3291
+ if (propOptions.attribute === false)
3292
+ continue;
3285
3293
  // Check for attribute using proper attribute name
3286
3294
  const attributeName = typeof propOptions.attribute === 'string' ? propOptions.attribute : propName.toLowerCase();
3287
3295
  if (this.hasAttribute(attributeName)) {
@@ -3598,6 +3606,16 @@ function property(options) {
3598
3606
  if (!Object.hasOwnProperty.call(this.constructor.prototype, propertyKey)) {
3599
3607
  const descriptor = {
3600
3608
  get() {
3609
+ // attribute: false — use internal storage only, no DOM sync
3610
+ if (finalOptions?.attribute === false) {
3611
+ if (this[PROPERTY_VALUES] && propertyKey in this[PROPERTY_VALUES]) {
3612
+ return this[PROPERTY_VALUES][propertyKey];
3613
+ }
3614
+ if (this[PRE_INIT_PROPERTY_VALUES]?.has(propertyKey)) {
3615
+ return this[PRE_INIT_PROPERTY_VALUES].get(propertyKey);
3616
+ }
3617
+ return initialValue;
3618
+ }
3601
3619
  // Always read from DOM attribute - no internal state
3602
3620
  const attributeName = typeof finalOptions?.attribute === 'string' ? finalOptions?.attribute : propertyKey.toLowerCase();
3603
3621
  const attrValue = this.getAttribute?.(attributeName);
@@ -3635,28 +3653,37 @@ function property(options) {
3635
3653
  this[PRE_INIT_PROPERTY_VALUES].set(propertyKey, newValue);
3636
3654
  return;
3637
3655
  }
3638
- // Reflect to DOM - properties are backed by attributes
3639
- const attributeName = typeof finalOptions.attribute === 'string' ? finalOptions.attribute : propertyKey.toLowerCase();
3640
- const attributeValue = valueToAttribute(newValue, finalOptions, initialValue);
3641
- // Mark as explicitly set for boolean handling
3642
- if (!this[EXPLICITLY_SET_PROPERTIES]) {
3643
- this[EXPLICITLY_SET_PROPERTIES] = new Set();
3644
- }
3645
- this[EXPLICITLY_SET_PROPERTIES].add(propertyKey);
3646
- // Flag to prevent attributeChangedCallback from triggering watchers for this change
3647
- if (!this._settingFromProperty)
3648
- this._settingFromProperty = new Set();
3649
- this._settingFromProperty.add(attributeName.toLowerCase());
3650
- if (attributeValue === null) {
3651
- this.removeAttribute?.(attributeName);
3656
+ // attribute: false store internally, skip DOM reflection
3657
+ if (finalOptions?.attribute === false) {
3658
+ if (!this[PROPERTY_VALUES]) {
3659
+ this[PROPERTY_VALUES] = {};
3660
+ }
3661
+ this[PROPERTY_VALUES][propertyKey] = newValue;
3652
3662
  }
3653
3663
  else {
3654
- this.setAttribute?.(attributeName, attributeValue);
3664
+ // Reflect to DOM - properties are backed by attributes
3665
+ const attributeName = typeof finalOptions.attribute === 'string' ? finalOptions.attribute : propertyKey.toLowerCase();
3666
+ const attributeValue = valueToAttribute(newValue, finalOptions, initialValue);
3667
+ // Mark as explicitly set for boolean handling
3668
+ if (!this[EXPLICITLY_SET_PROPERTIES]) {
3669
+ this[EXPLICITLY_SET_PROPERTIES] = new Set();
3670
+ }
3671
+ this[EXPLICITLY_SET_PROPERTIES].add(propertyKey);
3672
+ // Flag to prevent attributeChangedCallback from triggering watchers for this change
3673
+ if (!this._settingFromProperty)
3674
+ this._settingFromProperty = new Set();
3675
+ this._settingFromProperty.add(attributeName.toLowerCase());
3676
+ if (attributeValue === null) {
3677
+ this.removeAttribute?.(attributeName);
3678
+ }
3679
+ else {
3680
+ this.setAttribute?.(attributeName, attributeValue);
3681
+ }
3682
+ // Remove the flag after a short delay to allow attributeChangedCallback to run
3683
+ setTimeout(() => {
3684
+ this._settingFromProperty?.delete(attributeName.toLowerCase());
3685
+ }, 0);
3655
3686
  }
3656
- // Remove the flag after a short delay to allow attributeChangedCallback to run
3657
- setTimeout(() => {
3658
- this._settingFromProperty?.delete(attributeName.toLowerCase());
3659
- }, 0);
3660
3687
  // Trigger watchers directly with proper parsed values
3661
3688
  const constructor = this.constructor;
3662
3689
  const watchers = constructor[PROPERTY_WATCHERS];
@@ -4799,6 +4826,8 @@ var RouteResult;
4799
4826
  * @returns An object containing the router's API methods.
4800
4827
  */
4801
4828
  function Router(options) {
4829
+ const win = options.window ?? window;
4830
+ const doc = options.document ?? document;
4802
4831
  const routes = [];
4803
4832
  let is_sorted = false;
4804
4833
  let placards = []; // Store collected placards
@@ -4862,11 +4891,11 @@ function Router(options) {
4862
4891
  delete this[CONTEXT_HANDLER];
4863
4892
  };
4864
4893
  // Define the custom element (skip if already registered)
4865
- if (customElements.get(pageOptions.tag)) {
4894
+ if (win.customElements.get(pageOptions.tag)) {
4866
4895
  console.warn(`[snice] Page "${pageOptions.tag}" is already registered. Skipping duplicate registration.`);
4867
4896
  }
4868
4897
  else {
4869
- customElements.define(pageOptions.tag, constructor);
4898
+ win.customElements.define(pageOptions.tag, constructor);
4870
4899
  }
4871
4900
  // Register the routes with guards, layout, and placard
4872
4901
  pageOptions.routes.forEach(route => register(route, pageOptions.tag, pageOptions.transition, pageOptions.guards, pageOptions.layout, pageOptions.placard));
@@ -4897,8 +4926,8 @@ function Router(options) {
4897
4926
  const isHashType = options.type === 'hash';
4898
4927
  const isPushStateType = options.type === 'pushstate';
4899
4928
  if (isHashType) {
4900
- window.addEventListener('hashchange', () => {
4901
- const targetExists = !!document.querySelector(options.target);
4929
+ win.addEventListener('hashchange', () => {
4930
+ const targetExists = !!doc.querySelector(options.target);
4902
4931
  if (!targetExists) {
4903
4932
  return;
4904
4933
  }
@@ -4907,8 +4936,8 @@ function Router(options) {
4907
4936
  });
4908
4937
  }
4909
4938
  if (isPushStateType) {
4910
- window.addEventListener('popstate', () => {
4911
- const targetExists = !!document.querySelector(options.target);
4939
+ win.addEventListener('popstate', () => {
4940
+ const targetExists = !!doc.querySelector(options.target);
4912
4941
  if (!targetExists) {
4913
4942
  return;
4914
4943
  }
@@ -4923,7 +4952,7 @@ function Router(options) {
4923
4952
  * initialize();
4924
4953
  */
4925
4954
  function initialize() {
4926
- const target = document.querySelector(options.target);
4955
+ const target = doc.querySelector(options.target);
4927
4956
  if (!target) {
4928
4957
  throw new Error(`Target element not found: ${options.target}`);
4929
4958
  }
@@ -4968,20 +4997,20 @@ function Router(options) {
4968
4997
  function getPath() {
4969
4998
  switch (options.type) {
4970
4999
  case 'hash':
4971
- return window.location.hash.slice(1);
5000
+ return win.location.hash.slice(1);
4972
5001
  case 'pushstate':
4973
- return window.location.pathname;
5002
+ return win.location.pathname;
4974
5003
  }
4975
5004
  }
4976
5005
  function renderForbiddenPage(target) {
4977
5006
  let newPageElement;
4978
5007
  const has403Page = !!_403;
4979
5008
  if (has403Page) {
4980
- newPageElement = document.createElement(_403);
5009
+ newPageElement = doc.createElement(_403);
4981
5010
  newPageElement[ROUTER_CONTEXT] = context;
4982
5011
  }
4983
5012
  if (!has403Page) {
4984
- const div = document.createElement('div');
5013
+ const div = doc.createElement('div');
4985
5014
  div.className = 'default-403';
4986
5015
  div.innerHTML = /*html*/ `<h1>403</h1><p>Unauthorized</p>`;
4987
5016
  newPageElement = div;
@@ -5007,9 +5036,9 @@ function Router(options) {
5007
5036
  return true;
5008
5037
  }
5009
5038
  function createHomeElement() {
5010
- const newPageElement = document.createElement(home);
5039
+ const newPageElement = doc.createElement(home);
5011
5040
  newPageElement[ROUTER_CONTEXT] = context;
5012
- const constructor = customElements.get(home);
5041
+ const constructor = win.customElements.get(home);
5013
5042
  const transition = constructor?.[PAGE_TRANSITION];
5014
5043
  const homeRoute = routes.find(r => r.route.match('/'));
5015
5044
  return { element: newPageElement, transition, layout: homeRoute?.layout };
@@ -5017,13 +5046,13 @@ function Router(options) {
5017
5046
  function create404Element() {
5018
5047
  const has404Page = !!_404;
5019
5048
  if (has404Page) {
5020
- const newPageElement = document.createElement(_404);
5049
+ const newPageElement = doc.createElement(_404);
5021
5050
  newPageElement[ROUTER_CONTEXT] = context;
5022
- const constructor = customElements.get(_404);
5051
+ const constructor = win.customElements.get(_404);
5023
5052
  const transition = constructor?.[PAGE_TRANSITION];
5024
5053
  return { element: newPageElement, transition, layout: undefined };
5025
5054
  }
5026
- const div = document.createElement('div');
5055
+ const div = doc.createElement('div');
5027
5056
  div.className = 'default-404';
5028
5057
  div.innerHTML = /*html*/ `<h1>404</h1><p>Page not found</p>`;
5029
5058
  return { element: div, transition: undefined, layout: undefined };
@@ -5039,7 +5068,7 @@ function Router(options) {
5039
5068
  if (!guardsAllowed) {
5040
5069
  return { result: RouteResult.GUARDS_FAILED };
5041
5070
  }
5042
- const newPageElement = document.createElement(route.tag);
5071
+ const newPageElement = doc.createElement(route.tag);
5043
5072
  newPageElement[ROUTER_CONTEXT] = context;
5044
5073
  newPageElement[CONTEXT_HANDLER] = navigationContext;
5045
5074
  const routeParams = params;
@@ -5073,7 +5102,7 @@ function Router(options) {
5073
5102
  if (shouldCreateLayout) {
5074
5103
  const timestamp = Date.now();
5075
5104
  currentLayoutTimestamp = timestamp;
5076
- const layoutElement = document.createElement(layoutToUse);
5105
+ const layoutElement = doc.createElement(layoutToUse);
5077
5106
  layoutElement[ROUTER_CONTEXT] = context;
5078
5107
  layoutElement[CREATED_AT] = timestamp;
5079
5108
  return { element: layoutElement, needsNewLayout: true };
@@ -5125,13 +5154,13 @@ function Router(options) {
5125
5154
  * navigate('/login');
5126
5155
  */
5127
5156
  async function navigate(path) {
5128
- const target = document.querySelector(options.target);
5157
+ const target = doc.querySelector(options.target);
5129
5158
  if (!target) {
5130
5159
  throw new Error(`Target element not found: ${options.target}`);
5131
5160
  }
5132
5161
  // Collect fresh placards before navigation
5133
5162
  collectPlacards();
5134
- window.scrollTo(0, 0);
5163
+ win.scrollTo(0, 0);
5135
5164
  const isHomePath = (path?.trim() === '' || path === '/') && !!home;
5136
5165
  if (isHomePath) {
5137
5166
  const homeRoute = routes.find(r => r.route.match('/'));
@@ -5200,6 +5229,444 @@ function Router(options) {
5200
5229
  };
5201
5230
  }
5202
5231
 
5232
+ // Portal CSS inlined (from snice-tooltip-portal.css)
5233
+ const portalCss = `.snice-tooltip--visible{opacity:1!important;transform:scale(1)!important}.snice-tooltip__arrow{position:absolute;width:0;height:0;border-style:solid;border-color:transparent}.snice-tooltip--top .snice-tooltip__arrow,.snice-tooltip--top-start .snice-tooltip__arrow,.snice-tooltip--top-end .snice-tooltip__arrow{bottom:-6px;border-width:6px 6px 0;border-top-color:hsl(0 0% 20%)}.snice-tooltip--bottom .snice-tooltip__arrow,.snice-tooltip--bottom-start .snice-tooltip__arrow,.snice-tooltip--bottom-end .snice-tooltip__arrow{top:-6px;border-width:0 6px 6px;border-bottom-color:hsl(0 0% 20%)}.snice-tooltip--left .snice-tooltip__arrow,.snice-tooltip--left-start .snice-tooltip__arrow,.snice-tooltip--left-end .snice-tooltip__arrow{right:-6px;border-width:6px 0 6px 6px;border-left-color:hsl(0 0% 20%)}.snice-tooltip--right .snice-tooltip__arrow,.snice-tooltip--right-start .snice-tooltip__arrow,.snice-tooltip--right-end .snice-tooltip__arrow{left:-6px;border-width:6px 6px 6px 0;border-right-color:hsl(0 0% 20%)}.snice-tooltip--top .snice-tooltip__arrow,.snice-tooltip--bottom .snice-tooltip__arrow{left:50%;transform:translateX(-50%)}.snice-tooltip--top-start .snice-tooltip__arrow,.snice-tooltip--bottom-start .snice-tooltip__arrow{left:16px}.snice-tooltip--top-end .snice-tooltip__arrow,.snice-tooltip--bottom-end .snice-tooltip__arrow{right:16px}.snice-tooltip--left .snice-tooltip__arrow,.snice-tooltip--right .snice-tooltip__arrow{top:50%;transform:translateY(-50%)}.snice-tooltip--left-start .snice-tooltip__arrow,.snice-tooltip--right-start .snice-tooltip__arrow{top:16px}.snice-tooltip--left-end .snice-tooltip__arrow,.snice-tooltip--right-end .snice-tooltip__arrow{bottom:16px;top:auto}`;
5234
+ const stateMap = new WeakMap();
5235
+ let portalStylesInjected = false;
5236
+ function ensurePortalStyles() {
5237
+ if (portalStylesInjected)
5238
+ return;
5239
+ try {
5240
+ if ('adoptedStyleSheets' in document && 'CSSStyleSheet' in window) {
5241
+ const sheet = new CSSStyleSheet();
5242
+ sheet.replaceSync(portalCss);
5243
+ document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
5244
+ }
5245
+ else {
5246
+ const style = document.createElement('style');
5247
+ style.textContent = portalCss;
5248
+ document.head.appendChild(style);
5249
+ }
5250
+ portalStylesInjected = true;
5251
+ }
5252
+ catch (error) {
5253
+ console.warn('Failed to inject tooltip portal styles:', error);
5254
+ }
5255
+ }
5256
+ function readConfig(el) {
5257
+ const cs = getComputedStyle(el);
5258
+ const get = (name, fallback) => cs.getPropertyValue(name).trim() || fallback;
5259
+ return {
5260
+ position: get('--tooltip-position', 'top'),
5261
+ trigger: get('--tooltip-trigger', 'hover'),
5262
+ delay: parseInt(get('--tooltip-delay', '0'), 10),
5263
+ hideDelay: parseInt(get('--tooltip-hide-delay', '0'), 10),
5264
+ offset: parseInt(get('--tooltip-offset', '12'), 10),
5265
+ arrow: get('--tooltip-arrow', 'auto') !== 'none',
5266
+ maxWidth: parseInt(get('--tooltip-max-width', '250'), 10),
5267
+ zIndex: parseInt(get('--tooltip-z-index', '10000'), 10),
5268
+ strictPositioning: get('--tooltip-strict-positioning', '') === 'true',
5269
+ bg: get('--tooltip-bg', 'hsl(0 0% 20%)'),
5270
+ color: get('--tooltip-color', 'white'),
5271
+ padding: get('--tooltip-padding', '8px 12px'),
5272
+ radius: get('--tooltip-radius', '6px'),
5273
+ fontSize: get('--tooltip-font-size', '14px'),
5274
+ };
5275
+ }
5276
+ // --- Positioning (ported from snice-tooltip.ts) ---
5277
+ function getPositionCoordinates(triggerRect, tooltipRect, position, offset, arrowSize) {
5278
+ let left = 0;
5279
+ let top = 0;
5280
+ const centerX = triggerRect.left + triggerRect.width / 2;
5281
+ const centerY = triggerRect.top + triggerRect.height / 2;
5282
+ const verticalOffset = offset;
5283
+ const horizontalOffset = offset + arrowSize;
5284
+ switch (position) {
5285
+ case 'top':
5286
+ left = centerX - tooltipRect.width / 2;
5287
+ top = triggerRect.top - tooltipRect.height - verticalOffset;
5288
+ break;
5289
+ case 'top-start':
5290
+ left = triggerRect.left;
5291
+ top = triggerRect.top - tooltipRect.height - verticalOffset;
5292
+ break;
5293
+ case 'top-end':
5294
+ left = triggerRect.right - tooltipRect.width;
5295
+ top = triggerRect.top - tooltipRect.height - verticalOffset;
5296
+ break;
5297
+ case 'bottom':
5298
+ left = centerX - tooltipRect.width / 2;
5299
+ top = triggerRect.bottom + verticalOffset;
5300
+ break;
5301
+ case 'bottom-start':
5302
+ left = triggerRect.left;
5303
+ top = triggerRect.bottom + verticalOffset;
5304
+ break;
5305
+ case 'bottom-end':
5306
+ left = triggerRect.right - tooltipRect.width;
5307
+ top = triggerRect.bottom + verticalOffset;
5308
+ break;
5309
+ case 'left':
5310
+ left = triggerRect.left - tooltipRect.width - horizontalOffset;
5311
+ top = centerY - tooltipRect.height / 2;
5312
+ break;
5313
+ case 'left-start':
5314
+ left = triggerRect.left - tooltipRect.width - horizontalOffset;
5315
+ top = triggerRect.top;
5316
+ break;
5317
+ case 'left-end':
5318
+ left = triggerRect.left - tooltipRect.width - horizontalOffset;
5319
+ top = triggerRect.bottom - tooltipRect.height;
5320
+ break;
5321
+ case 'right':
5322
+ left = triggerRect.right + horizontalOffset;
5323
+ top = centerY - tooltipRect.height / 2;
5324
+ break;
5325
+ case 'right-start':
5326
+ left = triggerRect.right + horizontalOffset;
5327
+ top = triggerRect.top;
5328
+ break;
5329
+ case 'right-end':
5330
+ left = triggerRect.right + horizontalOffset;
5331
+ top = triggerRect.bottom - tooltipRect.height;
5332
+ break;
5333
+ }
5334
+ return { left, top };
5335
+ }
5336
+ function getAlternativePositions(position) {
5337
+ const opposites = {
5338
+ 'top': ['bottom', 'left', 'right'],
5339
+ 'top-start': ['bottom-start', 'left', 'right'],
5340
+ 'top-end': ['bottom-end', 'left', 'right'],
5341
+ 'bottom': ['top', 'left', 'right'],
5342
+ 'bottom-start': ['top-start', 'left', 'right'],
5343
+ 'bottom-end': ['top-end', 'left', 'right'],
5344
+ 'left': ['right', 'top', 'bottom'],
5345
+ 'left-start': ['right-start', 'top', 'bottom'],
5346
+ 'left-end': ['right-end', 'top', 'bottom'],
5347
+ 'right': ['left', 'top', 'bottom'],
5348
+ 'right-start': ['left-start', 'top', 'bottom'],
5349
+ 'right-end': ['left-end', 'top', 'bottom'],
5350
+ };
5351
+ return opposites[position] || ['top', 'bottom', 'left', 'right'];
5352
+ }
5353
+ function calculatePosition(triggerRect, tooltipRect, position, offset, arrowSize, strictPositioning) {
5354
+ const vw = window.innerWidth;
5355
+ const vh = window.innerHeight;
5356
+ let pos = position;
5357
+ let coords = getPositionCoordinates(triggerRect, tooltipRect, pos, offset, arrowSize);
5358
+ if (!strictPositioning) {
5359
+ const fits = coords.left >= 0 &&
5360
+ coords.top >= 0 &&
5361
+ coords.left + tooltipRect.width <= vw &&
5362
+ coords.top + tooltipRect.height <= vh;
5363
+ if (!fits) {
5364
+ for (const alt of getAlternativePositions(pos)) {
5365
+ const altCoords = getPositionCoordinates(triggerRect, tooltipRect, alt, offset, arrowSize);
5366
+ if (altCoords.left >= 0 &&
5367
+ altCoords.top >= 0 &&
5368
+ altCoords.left + tooltipRect.width <= vw &&
5369
+ altCoords.top + tooltipRect.height <= vh) {
5370
+ pos = alt;
5371
+ coords = altCoords;
5372
+ break;
5373
+ }
5374
+ }
5375
+ }
5376
+ }
5377
+ return { left: coords.left, top: coords.top, adjustedPosition: pos };
5378
+ }
5379
+ // --- Portal creation ---
5380
+ function createPortal(config) {
5381
+ const portal = document.createElement('div');
5382
+ portal.className = `snice-tooltip snice-tooltip--${config.position}`;
5383
+ portal.setAttribute('role', 'tooltip');
5384
+ portal.style.cssText = `
5385
+ position: fixed;
5386
+ z-index: ${config.zIndex};
5387
+ padding: ${config.padding};
5388
+ background: ${config.bg};
5389
+ color: ${config.color};
5390
+ border-radius: ${config.radius};
5391
+ font-size: ${config.fontSize};
5392
+ line-height: 1.4;
5393
+ max-width: ${config.maxWidth}px;
5394
+ width: max-content;
5395
+ pointer-events: none;
5396
+ opacity: 0;
5397
+ transform: scale(0.95);
5398
+ transition: opacity 0.2s, transform 0.2s;
5399
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
5400
+ display: none;
5401
+ `;
5402
+ const content = document.createElement('div');
5403
+ content.className = 'snice-tooltip__content';
5404
+ portal.appendChild(content);
5405
+ if (config.arrow) {
5406
+ const arrow = document.createElement('div');
5407
+ arrow.className = 'snice-tooltip__arrow';
5408
+ arrow.style.cssText = 'position:absolute;width:0;height:0;border-style:solid;';
5409
+ portal.appendChild(arrow);
5410
+ }
5411
+ document.body.appendChild(portal);
5412
+ return portal;
5413
+ }
5414
+ // --- Show / Hide ---
5415
+ function showTooltip(el) {
5416
+ const text = el.getAttribute('tooltip');
5417
+ if (!text)
5418
+ return;
5419
+ ensurePortalStyles();
5420
+ const config = readConfig(el);
5421
+ let state = stateMap.get(el);
5422
+ if (!state) {
5423
+ state = { portal: null, listeners: [], activePosition: config.position };
5424
+ stateMap.set(el, state);
5425
+ }
5426
+ // Create or update portal
5427
+ if (!state.portal) {
5428
+ state.portal = createPortal(config);
5429
+ }
5430
+ else {
5431
+ // Update styling in case CSS vars changed
5432
+ const p = state.portal;
5433
+ p.style.zIndex = String(config.zIndex);
5434
+ p.style.padding = config.padding;
5435
+ p.style.background = config.bg;
5436
+ p.style.color = config.color;
5437
+ p.style.borderRadius = config.radius;
5438
+ p.style.fontSize = config.fontSize;
5439
+ p.style.maxWidth = `${config.maxWidth}px`;
5440
+ // Update arrow — CSS handles color via class-based rules, but we need
5441
+ // the arrow element to exist/not-exist
5442
+ let arrow = p.querySelector('.snice-tooltip__arrow');
5443
+ if (config.arrow && !arrow) {
5444
+ arrow = document.createElement('div');
5445
+ arrow.className = 'snice-tooltip__arrow';
5446
+ arrow.style.cssText = 'position:absolute;width:0;height:0;border-style:solid;';
5447
+ p.appendChild(arrow);
5448
+ }
5449
+ else if (!config.arrow && arrow) {
5450
+ arrow.style.display = 'none';
5451
+ }
5452
+ else if (config.arrow && arrow) {
5453
+ arrow.style.display = '';
5454
+ }
5455
+ }
5456
+ const portal = state.portal;
5457
+ const contentEl = portal.querySelector('.snice-tooltip__content');
5458
+ if (contentEl)
5459
+ contentEl.textContent = text;
5460
+ portal.style.display = 'block';
5461
+ void portal.offsetHeight; // force reflow
5462
+ // Position
5463
+ portal.style.visibility = 'hidden';
5464
+ portal.style.left = '-9999px';
5465
+ portal.style.top = '-9999px';
5466
+ const triggerRect = el.getBoundingClientRect();
5467
+ const tooltipRect = portal.getBoundingClientRect();
5468
+ portal.style.visibility = '';
5469
+ const arrowSize = config.arrow ? 6 : 0;
5470
+ const result = calculatePosition(triggerRect, tooltipRect, config.position, config.offset, arrowSize, config.strictPositioning);
5471
+ if (result.adjustedPosition !== state.activePosition) {
5472
+ portal.classList.remove(`snice-tooltip--${state.activePosition}`);
5473
+ portal.classList.add(`snice-tooltip--${result.adjustedPosition}`);
5474
+ state.activePosition = result.adjustedPosition;
5475
+ }
5476
+ portal.style.left = `${result.left}px`;
5477
+ portal.style.top = `${result.top}px`;
5478
+ portal.classList.add('snice-tooltip--visible');
5479
+ }
5480
+ function hideTooltip(el) {
5481
+ const state = stateMap.get(el);
5482
+ if (!state?.portal)
5483
+ return;
5484
+ state.portal.classList.remove('snice-tooltip--visible');
5485
+ const p = state.portal;
5486
+ setTimeout(() => {
5487
+ if (p)
5488
+ p.style.display = 'none';
5489
+ }, 200);
5490
+ }
5491
+ function scheduleShow(el) {
5492
+ const state = stateMap.get(el);
5493
+ if (!state)
5494
+ return;
5495
+ clearTimeouts(state);
5496
+ const config = readConfig(el);
5497
+ if (config.delay > 0) {
5498
+ state.showTimeout = window.setTimeout(() => showTooltip(el), config.delay);
5499
+ }
5500
+ else {
5501
+ showTooltip(el);
5502
+ }
5503
+ }
5504
+ function scheduleHide(el) {
5505
+ const state = stateMap.get(el);
5506
+ if (!state)
5507
+ return;
5508
+ clearTimeouts(state);
5509
+ const config = readConfig(el);
5510
+ if (config.hideDelay > 0) {
5511
+ state.hideTimeout = window.setTimeout(() => hideTooltip(el), config.hideDelay);
5512
+ }
5513
+ else {
5514
+ hideTooltip(el);
5515
+ }
5516
+ }
5517
+ function clearTimeouts(state) {
5518
+ if (state.showTimeout !== undefined) {
5519
+ clearTimeout(state.showTimeout);
5520
+ state.showTimeout = undefined;
5521
+ }
5522
+ if (state.hideTimeout !== undefined) {
5523
+ clearTimeout(state.hideTimeout);
5524
+ state.hideTimeout = undefined;
5525
+ }
5526
+ }
5527
+ // --- Attach / Detach ---
5528
+ function attachTooltip(el) {
5529
+ // Skip if already attached
5530
+ if (stateMap.has(el))
5531
+ return;
5532
+ const config = readConfig(el);
5533
+ const state = { portal: null, listeners: [], activePosition: config.position };
5534
+ stateMap.set(el, state);
5535
+ const addListener = (type, fn) => {
5536
+ el.addEventListener(type, fn);
5537
+ state.listeners.push({ type, fn });
5538
+ };
5539
+ switch (config.trigger) {
5540
+ case 'hover':
5541
+ addListener('mouseenter', () => scheduleShow(el));
5542
+ addListener('mouseleave', () => scheduleHide(el));
5543
+ addListener('focusin', () => scheduleShow(el));
5544
+ addListener('focusout', () => scheduleHide(el));
5545
+ break;
5546
+ case 'focus':
5547
+ addListener('focusin', () => scheduleShow(el));
5548
+ addListener('focusout', () => scheduleHide(el));
5549
+ break;
5550
+ case 'click': {
5551
+ const clickOutside = (e) => {
5552
+ if (!el.contains(e.target)) {
5553
+ scheduleHide(el);
5554
+ document.removeEventListener('click', clickOutside);
5555
+ }
5556
+ };
5557
+ addListener('click', () => {
5558
+ const s = stateMap.get(el);
5559
+ const isVisible = s?.portal?.classList.contains('snice-tooltip--visible');
5560
+ if (isVisible) {
5561
+ scheduleHide(el);
5562
+ }
5563
+ else {
5564
+ scheduleShow(el);
5565
+ setTimeout(() => document.addEventListener('click', clickOutside), 0);
5566
+ }
5567
+ });
5568
+ break;
5569
+ }
5570
+ }
5571
+ }
5572
+ function detachTooltip(el) {
5573
+ const state = stateMap.get(el);
5574
+ if (!state)
5575
+ return;
5576
+ clearTimeouts(state);
5577
+ for (const { type, fn } of state.listeners) {
5578
+ el.removeEventListener(type, fn);
5579
+ }
5580
+ if (state.portal) {
5581
+ state.portal.remove();
5582
+ }
5583
+ stateMap.delete(el);
5584
+ }
5585
+ // --- Observer ---
5586
+ function processElement(el) {
5587
+ if (!(el instanceof HTMLElement))
5588
+ return;
5589
+ const tooltip = el.getAttribute('tooltip');
5590
+ if (tooltip) {
5591
+ attachTooltip(el);
5592
+ }
5593
+ }
5594
+ /**
5595
+ * Initialize attribute-based tooltips.
5596
+ * Any element with a `tooltip` attribute will show a tooltip on interaction.
5597
+ * Configure via CSS custom properties (--tooltip-position, --tooltip-delay, etc.).
5598
+ * Idempotent — safe to call multiple times.
5599
+ */
5600
+ function useTooltips() {
5601
+ if (globalThis.sniceTooltipsInitialized)
5602
+ return;
5603
+ globalThis.sniceTooltipsInitialized = true;
5604
+ const observer = new MutationObserver((mutations) => {
5605
+ for (const mutation of mutations) {
5606
+ if (mutation.type === 'attributes' && mutation.attributeName === 'tooltip') {
5607
+ const el = mutation.target;
5608
+ if (el.hasAttribute('tooltip')) {
5609
+ // Attribute added or changed — detach old, re-attach
5610
+ detachTooltip(el);
5611
+ attachTooltip(el);
5612
+ }
5613
+ else {
5614
+ // Attribute removed
5615
+ detachTooltip(el);
5616
+ }
5617
+ }
5618
+ else if (mutation.type === 'childList') {
5619
+ mutation.addedNodes.forEach(node => {
5620
+ if (node instanceof HTMLElement) {
5621
+ processElement(node);
5622
+ node.querySelectorAll('[tooltip]').forEach(processElement);
5623
+ }
5624
+ });
5625
+ mutation.removedNodes.forEach(node => {
5626
+ if (node instanceof HTMLElement) {
5627
+ detachTooltip(node);
5628
+ node.querySelectorAll('[tooltip]').forEach(child => {
5629
+ if (child instanceof HTMLElement)
5630
+ detachTooltip(child);
5631
+ });
5632
+ }
5633
+ });
5634
+ }
5635
+ }
5636
+ });
5637
+ const start = () => {
5638
+ document.querySelectorAll('[tooltip]').forEach(processElement);
5639
+ observer.observe(document.body, {
5640
+ attributes: true,
5641
+ attributeFilter: ['tooltip'],
5642
+ childList: true,
5643
+ subtree: true,
5644
+ });
5645
+ };
5646
+ if (document.readyState === 'loading') {
5647
+ document.addEventListener('DOMContentLoaded', start);
5648
+ }
5649
+ else {
5650
+ start();
5651
+ }
5652
+ globalThis.sniceTooltipObserver = observer;
5653
+ }
5654
+ /**
5655
+ * Disconnect the tooltip observer and remove all portals.
5656
+ */
5657
+ function cleanupTooltips() {
5658
+ const observer = globalThis.sniceTooltipObserver;
5659
+ if (observer) {
5660
+ observer.disconnect();
5661
+ globalThis.sniceTooltipObserver = undefined;
5662
+ }
5663
+ document.querySelectorAll('[tooltip]').forEach(el => {
5664
+ if (el instanceof HTMLElement)
5665
+ detachTooltip(el);
5666
+ });
5667
+ globalThis.sniceTooltipsInitialized = false;
5668
+ }
5669
+
5203
5670
  // @dispatch decorator - auto-dispatches custom events from method return values
5204
5671
  /**
5205
5672
  * Decorator that automatically dispatches a custom event after a method is called.
@@ -5829,7 +6296,7 @@ class ContextAwareFetcher {
5829
6296
  }
5830
6297
 
5831
6298
  /*!
5832
- * snice v4.13.0
6299
+ * snice v4.15.0
5833
6300
  * Imperative TypeScript framework for building vanilla web components with decorators, differential rendering, routing, and controllers. No virtual DOM, no build complexity.
5834
6301
  * (c) 2024
5835
6302
  * Released under the MIT License.
@@ -5930,5 +6397,5 @@ getSymbol('context-timer');
5930
6397
  getSymbol('context-called');
5931
6398
  getSymbol('context-update');
5932
6399
 
5933
- export { Context, ContextAwareFetcher, IS_CONTROLLER_INSTANCE, Router, SimpleArray, adopted, applyElementFunctionality, clearDebounceTimers, clearMemoizeCache, clearThrottleTimers, context$1 as context, context as contextProperty, controller, css, debounce, dispatch, dispose, element, getSymbol$1 as getSymbol, html, layout, memoize, moved, noChange, nothing, observe, on, once, property, query, queryAll, ready, render, request, resetOnce, respond, setDisableElementReadyWarnings, styles, throttle, trackRenders, unsafeHTML, useNativeElementControllers, waitForAllCustomElements, waitForElementDefined, waitForElementReady, watch };
6400
+ export { Context, ContextAwareFetcher, IS_CONTROLLER_INSTANCE, Router, SimpleArray, adopted, applyElementFunctionality, cleanupTooltips, clearDebounceTimers, clearMemoizeCache, clearThrottleTimers, context$1 as context, context as contextProperty, controller, css, debounce, dispatch, dispose, element, getSymbol$1 as getSymbol, html, layout, memoize, moved, noChange, nothing, observe, on, once, property, query, queryAll, ready, render, request, resetOnce, respond, setDisableElementReadyWarnings, styles, throttle, trackRenders, unsafeHTML, useNativeElementControllers, useTooltips, waitForAllCustomElements, waitForElementDefined, waitForElementReady, watch };
5934
6401
  //# sourceMappingURL=snice-runtime.esm.js.map