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,5 +1,5 @@
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.
@@ -1810,10 +1810,12 @@ var Snice = (function (exports) {
1810
1810
  this.defaultChild = null;
1811
1811
  this.currentChild = null;
1812
1812
  this.caseElement = caseElement;
1813
+ this.caseElement.style.display = 'contents';
1813
1814
  // Build map and store children in fragments initially
1814
1815
  for (const child of Array.from(this.caseElement.children)) {
1815
1816
  const childTag = child.tagName.toLowerCase();
1816
1817
  if (childTag === 'when') {
1818
+ child.style.display = 'contents';
1817
1819
  const whenValue = child.getAttribute('value') || '';
1818
1820
  this.childrenMap.set(whenValue, child);
1819
1821
  const fragment = document.createDocumentFragment();
@@ -1821,6 +1823,7 @@ var Snice = (function (exports) {
1821
1823
  this.fragments.set(child, fragment);
1822
1824
  }
1823
1825
  else if (childTag === 'default') {
1826
+ child.style.display = 'contents';
1824
1827
  this.defaultChild = child;
1825
1828
  const fragment = document.createDocumentFragment();
1826
1829
  fragment.appendChild(child);
@@ -2307,7 +2310,7 @@ var Snice = (function (exports) {
2307
2310
  setupResponseHandlers(controllerInstance, element);
2308
2311
  // Setup @on event handlers for controller
2309
2312
  setupEventHandlers(controllerInstance, element);
2310
- element.dispatchEvent(new CustomEvent('@snice/controller-attached', {
2313
+ element.dispatchEvent(new CustomEvent('controller-attached', {
2311
2314
  detail: { name: controllerName, controller: controllerInstance }
2312
2315
  }));
2313
2316
  }
@@ -2347,7 +2350,7 @@ var Snice = (function (exports) {
2347
2350
  delete element[CONTROLLER_KEY];
2348
2351
  delete element[CONTROLLER_NAME_KEY];
2349
2352
  delete element[CONTROLLER_OPERATIONS];
2350
- element.dispatchEvent(new CustomEvent('@snice/controller-detached', {
2353
+ element.dispatchEvent(new CustomEvent('controller-detached', {
2351
2354
  detail: { name: controllerName, controller: controllerInstance }
2352
2355
  }));
2353
2356
  }
@@ -3189,10 +3192,12 @@ var Snice = (function (exports) {
3189
3192
  if (!observedAttributes.includes('controller')) {
3190
3193
  observedAttributes.push('controller');
3191
3194
  }
3192
- // Add all properties to observed attributes (not just reflected ones)
3195
+ // Add all properties to observed attributes (skip attribute: false)
3193
3196
  const properties = constructor[PROPERTIES];
3194
3197
  if (properties) {
3195
3198
  for (const [propName, propOptions] of properties) {
3199
+ if (propOptions.attribute === false)
3200
+ continue;
3196
3201
  const attributeName = typeof propOptions.attribute === 'string' ? propOptions.attribute : propName.toLowerCase();
3197
3202
  if (!observedAttributes.includes(attributeName)) {
3198
3203
  observedAttributes.push(attributeName);
@@ -3279,6 +3284,9 @@ var Snice = (function (exports) {
3279
3284
  const properties = constructor[PROPERTIES];
3280
3285
  if (properties) {
3281
3286
  for (const [propName, propOptions] of properties) {
3287
+ // Skip properties that opted out of attribute sync
3288
+ if (propOptions.attribute === false)
3289
+ continue;
3282
3290
  // Check for attribute using proper attribute name
3283
3291
  const attributeName = typeof propOptions.attribute === 'string' ? propOptions.attribute : propName.toLowerCase();
3284
3292
  if (this.hasAttribute(attributeName)) {
@@ -3595,6 +3603,16 @@ var Snice = (function (exports) {
3595
3603
  if (!Object.hasOwnProperty.call(this.constructor.prototype, propertyKey)) {
3596
3604
  const descriptor = {
3597
3605
  get() {
3606
+ // attribute: false — use internal storage only, no DOM sync
3607
+ if (finalOptions?.attribute === false) {
3608
+ if (this[PROPERTY_VALUES] && propertyKey in this[PROPERTY_VALUES]) {
3609
+ return this[PROPERTY_VALUES][propertyKey];
3610
+ }
3611
+ if (this[PRE_INIT_PROPERTY_VALUES]?.has(propertyKey)) {
3612
+ return this[PRE_INIT_PROPERTY_VALUES].get(propertyKey);
3613
+ }
3614
+ return initialValue;
3615
+ }
3598
3616
  // Always read from DOM attribute - no internal state
3599
3617
  const attributeName = typeof finalOptions?.attribute === 'string' ? finalOptions?.attribute : propertyKey.toLowerCase();
3600
3618
  const attrValue = this.getAttribute?.(attributeName);
@@ -3632,28 +3650,37 @@ var Snice = (function (exports) {
3632
3650
  this[PRE_INIT_PROPERTY_VALUES].set(propertyKey, newValue);
3633
3651
  return;
3634
3652
  }
3635
- // Reflect to DOM - properties are backed by attributes
3636
- const attributeName = typeof finalOptions.attribute === 'string' ? finalOptions.attribute : propertyKey.toLowerCase();
3637
- const attributeValue = valueToAttribute(newValue, finalOptions, initialValue);
3638
- // Mark as explicitly set for boolean handling
3639
- if (!this[EXPLICITLY_SET_PROPERTIES]) {
3640
- this[EXPLICITLY_SET_PROPERTIES] = new Set();
3641
- }
3642
- this[EXPLICITLY_SET_PROPERTIES].add(propertyKey);
3643
- // Flag to prevent attributeChangedCallback from triggering watchers for this change
3644
- if (!this._settingFromProperty)
3645
- this._settingFromProperty = new Set();
3646
- this._settingFromProperty.add(attributeName.toLowerCase());
3647
- if (attributeValue === null) {
3648
- this.removeAttribute?.(attributeName);
3653
+ // attribute: false store internally, skip DOM reflection
3654
+ if (finalOptions?.attribute === false) {
3655
+ if (!this[PROPERTY_VALUES]) {
3656
+ this[PROPERTY_VALUES] = {};
3657
+ }
3658
+ this[PROPERTY_VALUES][propertyKey] = newValue;
3649
3659
  }
3650
3660
  else {
3651
- this.setAttribute?.(attributeName, attributeValue);
3661
+ // Reflect to DOM - properties are backed by attributes
3662
+ const attributeName = typeof finalOptions.attribute === 'string' ? finalOptions.attribute : propertyKey.toLowerCase();
3663
+ const attributeValue = valueToAttribute(newValue, finalOptions, initialValue);
3664
+ // Mark as explicitly set for boolean handling
3665
+ if (!this[EXPLICITLY_SET_PROPERTIES]) {
3666
+ this[EXPLICITLY_SET_PROPERTIES] = new Set();
3667
+ }
3668
+ this[EXPLICITLY_SET_PROPERTIES].add(propertyKey);
3669
+ // Flag to prevent attributeChangedCallback from triggering watchers for this change
3670
+ if (!this._settingFromProperty)
3671
+ this._settingFromProperty = new Set();
3672
+ this._settingFromProperty.add(attributeName.toLowerCase());
3673
+ if (attributeValue === null) {
3674
+ this.removeAttribute?.(attributeName);
3675
+ }
3676
+ else {
3677
+ this.setAttribute?.(attributeName, attributeValue);
3678
+ }
3679
+ // Remove the flag after a short delay to allow attributeChangedCallback to run
3680
+ setTimeout(() => {
3681
+ this._settingFromProperty?.delete(attributeName.toLowerCase());
3682
+ }, 0);
3652
3683
  }
3653
- // Remove the flag after a short delay to allow attributeChangedCallback to run
3654
- setTimeout(() => {
3655
- this._settingFromProperty?.delete(attributeName.toLowerCase());
3656
- }, 0);
3657
3684
  // Trigger watchers directly with proper parsed values
3658
3685
  const constructor = this.constructor;
3659
3686
  const watchers = constructor[PROPERTY_WATCHERS];
@@ -4796,6 +4823,8 @@ var Snice = (function (exports) {
4796
4823
  * @returns An object containing the router's API methods.
4797
4824
  */
4798
4825
  function Router(options) {
4826
+ const win = options.window ?? window;
4827
+ const doc = options.document ?? document;
4799
4828
  const routes = [];
4800
4829
  let is_sorted = false;
4801
4830
  let placards = []; // Store collected placards
@@ -4859,11 +4888,11 @@ var Snice = (function (exports) {
4859
4888
  delete this[CONTEXT_HANDLER];
4860
4889
  };
4861
4890
  // Define the custom element (skip if already registered)
4862
- if (customElements.get(pageOptions.tag)) {
4891
+ if (win.customElements.get(pageOptions.tag)) {
4863
4892
  console.warn(`[snice] Page "${pageOptions.tag}" is already registered. Skipping duplicate registration.`);
4864
4893
  }
4865
4894
  else {
4866
- customElements.define(pageOptions.tag, constructor);
4895
+ win.customElements.define(pageOptions.tag, constructor);
4867
4896
  }
4868
4897
  // Register the routes with guards, layout, and placard
4869
4898
  pageOptions.routes.forEach(route => register(route, pageOptions.tag, pageOptions.transition, pageOptions.guards, pageOptions.layout, pageOptions.placard));
@@ -4894,8 +4923,8 @@ var Snice = (function (exports) {
4894
4923
  const isHashType = options.type === 'hash';
4895
4924
  const isPushStateType = options.type === 'pushstate';
4896
4925
  if (isHashType) {
4897
- window.addEventListener('hashchange', () => {
4898
- const targetExists = !!document.querySelector(options.target);
4926
+ win.addEventListener('hashchange', () => {
4927
+ const targetExists = !!doc.querySelector(options.target);
4899
4928
  if (!targetExists) {
4900
4929
  return;
4901
4930
  }
@@ -4904,8 +4933,8 @@ var Snice = (function (exports) {
4904
4933
  });
4905
4934
  }
4906
4935
  if (isPushStateType) {
4907
- window.addEventListener('popstate', () => {
4908
- const targetExists = !!document.querySelector(options.target);
4936
+ win.addEventListener('popstate', () => {
4937
+ const targetExists = !!doc.querySelector(options.target);
4909
4938
  if (!targetExists) {
4910
4939
  return;
4911
4940
  }
@@ -4920,7 +4949,7 @@ var Snice = (function (exports) {
4920
4949
  * initialize();
4921
4950
  */
4922
4951
  function initialize() {
4923
- const target = document.querySelector(options.target);
4952
+ const target = doc.querySelector(options.target);
4924
4953
  if (!target) {
4925
4954
  throw new Error(`Target element not found: ${options.target}`);
4926
4955
  }
@@ -4965,20 +4994,20 @@ var Snice = (function (exports) {
4965
4994
  function getPath() {
4966
4995
  switch (options.type) {
4967
4996
  case 'hash':
4968
- return window.location.hash.slice(1);
4997
+ return win.location.hash.slice(1);
4969
4998
  case 'pushstate':
4970
- return window.location.pathname;
4999
+ return win.location.pathname;
4971
5000
  }
4972
5001
  }
4973
5002
  function renderForbiddenPage(target) {
4974
5003
  let newPageElement;
4975
5004
  const has403Page = !!_403;
4976
5005
  if (has403Page) {
4977
- newPageElement = document.createElement(_403);
5006
+ newPageElement = doc.createElement(_403);
4978
5007
  newPageElement[ROUTER_CONTEXT] = context;
4979
5008
  }
4980
5009
  if (!has403Page) {
4981
- const div = document.createElement('div');
5010
+ const div = doc.createElement('div');
4982
5011
  div.className = 'default-403';
4983
5012
  div.innerHTML = /*html*/ `<h1>403</h1><p>Unauthorized</p>`;
4984
5013
  newPageElement = div;
@@ -5004,9 +5033,9 @@ var Snice = (function (exports) {
5004
5033
  return true;
5005
5034
  }
5006
5035
  function createHomeElement() {
5007
- const newPageElement = document.createElement(home);
5036
+ const newPageElement = doc.createElement(home);
5008
5037
  newPageElement[ROUTER_CONTEXT] = context;
5009
- const constructor = customElements.get(home);
5038
+ const constructor = win.customElements.get(home);
5010
5039
  const transition = constructor?.[PAGE_TRANSITION];
5011
5040
  const homeRoute = routes.find(r => r.route.match('/'));
5012
5041
  return { element: newPageElement, transition, layout: homeRoute?.layout };
@@ -5014,13 +5043,13 @@ var Snice = (function (exports) {
5014
5043
  function create404Element() {
5015
5044
  const has404Page = !!_404;
5016
5045
  if (has404Page) {
5017
- const newPageElement = document.createElement(_404);
5046
+ const newPageElement = doc.createElement(_404);
5018
5047
  newPageElement[ROUTER_CONTEXT] = context;
5019
- const constructor = customElements.get(_404);
5048
+ const constructor = win.customElements.get(_404);
5020
5049
  const transition = constructor?.[PAGE_TRANSITION];
5021
5050
  return { element: newPageElement, transition, layout: undefined };
5022
5051
  }
5023
- const div = document.createElement('div');
5052
+ const div = doc.createElement('div');
5024
5053
  div.className = 'default-404';
5025
5054
  div.innerHTML = /*html*/ `<h1>404</h1><p>Page not found</p>`;
5026
5055
  return { element: div, transition: undefined, layout: undefined };
@@ -5036,7 +5065,7 @@ var Snice = (function (exports) {
5036
5065
  if (!guardsAllowed) {
5037
5066
  return { result: RouteResult.GUARDS_FAILED };
5038
5067
  }
5039
- const newPageElement = document.createElement(route.tag);
5068
+ const newPageElement = doc.createElement(route.tag);
5040
5069
  newPageElement[ROUTER_CONTEXT] = context;
5041
5070
  newPageElement[CONTEXT_HANDLER] = navigationContext;
5042
5071
  const routeParams = params;
@@ -5070,7 +5099,7 @@ var Snice = (function (exports) {
5070
5099
  if (shouldCreateLayout) {
5071
5100
  const timestamp = Date.now();
5072
5101
  currentLayoutTimestamp = timestamp;
5073
- const layoutElement = document.createElement(layoutToUse);
5102
+ const layoutElement = doc.createElement(layoutToUse);
5074
5103
  layoutElement[ROUTER_CONTEXT] = context;
5075
5104
  layoutElement[CREATED_AT] = timestamp;
5076
5105
  return { element: layoutElement, needsNewLayout: true };
@@ -5122,13 +5151,13 @@ var Snice = (function (exports) {
5122
5151
  * navigate('/login');
5123
5152
  */
5124
5153
  async function navigate(path) {
5125
- const target = document.querySelector(options.target);
5154
+ const target = doc.querySelector(options.target);
5126
5155
  if (!target) {
5127
5156
  throw new Error(`Target element not found: ${options.target}`);
5128
5157
  }
5129
5158
  // Collect fresh placards before navigation
5130
5159
  collectPlacards();
5131
- window.scrollTo(0, 0);
5160
+ win.scrollTo(0, 0);
5132
5161
  const isHomePath = (path?.trim() === '' || path === '/') && !!home;
5133
5162
  if (isHomePath) {
5134
5163
  const homeRoute = routes.find(r => r.route.match('/'));
@@ -5197,6 +5226,444 @@ var Snice = (function (exports) {
5197
5226
  };
5198
5227
  }
5199
5228
 
5229
+ // Portal CSS inlined (from snice-tooltip-portal.css)
5230
+ 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}`;
5231
+ const stateMap = new WeakMap();
5232
+ let portalStylesInjected = false;
5233
+ function ensurePortalStyles() {
5234
+ if (portalStylesInjected)
5235
+ return;
5236
+ try {
5237
+ if ('adoptedStyleSheets' in document && 'CSSStyleSheet' in window) {
5238
+ const sheet = new CSSStyleSheet();
5239
+ sheet.replaceSync(portalCss);
5240
+ document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet];
5241
+ }
5242
+ else {
5243
+ const style = document.createElement('style');
5244
+ style.textContent = portalCss;
5245
+ document.head.appendChild(style);
5246
+ }
5247
+ portalStylesInjected = true;
5248
+ }
5249
+ catch (error) {
5250
+ console.warn('Failed to inject tooltip portal styles:', error);
5251
+ }
5252
+ }
5253
+ function readConfig(el) {
5254
+ const cs = getComputedStyle(el);
5255
+ const get = (name, fallback) => cs.getPropertyValue(name).trim() || fallback;
5256
+ return {
5257
+ position: get('--tooltip-position', 'top'),
5258
+ trigger: get('--tooltip-trigger', 'hover'),
5259
+ delay: parseInt(get('--tooltip-delay', '0'), 10),
5260
+ hideDelay: parseInt(get('--tooltip-hide-delay', '0'), 10),
5261
+ offset: parseInt(get('--tooltip-offset', '12'), 10),
5262
+ arrow: get('--tooltip-arrow', 'auto') !== 'none',
5263
+ maxWidth: parseInt(get('--tooltip-max-width', '250'), 10),
5264
+ zIndex: parseInt(get('--tooltip-z-index', '10000'), 10),
5265
+ strictPositioning: get('--tooltip-strict-positioning', '') === 'true',
5266
+ bg: get('--tooltip-bg', 'hsl(0 0% 20%)'),
5267
+ color: get('--tooltip-color', 'white'),
5268
+ padding: get('--tooltip-padding', '8px 12px'),
5269
+ radius: get('--tooltip-radius', '6px'),
5270
+ fontSize: get('--tooltip-font-size', '14px'),
5271
+ };
5272
+ }
5273
+ // --- Positioning (ported from snice-tooltip.ts) ---
5274
+ function getPositionCoordinates(triggerRect, tooltipRect, position, offset, arrowSize) {
5275
+ let left = 0;
5276
+ let top = 0;
5277
+ const centerX = triggerRect.left + triggerRect.width / 2;
5278
+ const centerY = triggerRect.top + triggerRect.height / 2;
5279
+ const verticalOffset = offset;
5280
+ const horizontalOffset = offset + arrowSize;
5281
+ switch (position) {
5282
+ case 'top':
5283
+ left = centerX - tooltipRect.width / 2;
5284
+ top = triggerRect.top - tooltipRect.height - verticalOffset;
5285
+ break;
5286
+ case 'top-start':
5287
+ left = triggerRect.left;
5288
+ top = triggerRect.top - tooltipRect.height - verticalOffset;
5289
+ break;
5290
+ case 'top-end':
5291
+ left = triggerRect.right - tooltipRect.width;
5292
+ top = triggerRect.top - tooltipRect.height - verticalOffset;
5293
+ break;
5294
+ case 'bottom':
5295
+ left = centerX - tooltipRect.width / 2;
5296
+ top = triggerRect.bottom + verticalOffset;
5297
+ break;
5298
+ case 'bottom-start':
5299
+ left = triggerRect.left;
5300
+ top = triggerRect.bottom + verticalOffset;
5301
+ break;
5302
+ case 'bottom-end':
5303
+ left = triggerRect.right - tooltipRect.width;
5304
+ top = triggerRect.bottom + verticalOffset;
5305
+ break;
5306
+ case 'left':
5307
+ left = triggerRect.left - tooltipRect.width - horizontalOffset;
5308
+ top = centerY - tooltipRect.height / 2;
5309
+ break;
5310
+ case 'left-start':
5311
+ left = triggerRect.left - tooltipRect.width - horizontalOffset;
5312
+ top = triggerRect.top;
5313
+ break;
5314
+ case 'left-end':
5315
+ left = triggerRect.left - tooltipRect.width - horizontalOffset;
5316
+ top = triggerRect.bottom - tooltipRect.height;
5317
+ break;
5318
+ case 'right':
5319
+ left = triggerRect.right + horizontalOffset;
5320
+ top = centerY - tooltipRect.height / 2;
5321
+ break;
5322
+ case 'right-start':
5323
+ left = triggerRect.right + horizontalOffset;
5324
+ top = triggerRect.top;
5325
+ break;
5326
+ case 'right-end':
5327
+ left = triggerRect.right + horizontalOffset;
5328
+ top = triggerRect.bottom - tooltipRect.height;
5329
+ break;
5330
+ }
5331
+ return { left, top };
5332
+ }
5333
+ function getAlternativePositions(position) {
5334
+ const opposites = {
5335
+ 'top': ['bottom', 'left', 'right'],
5336
+ 'top-start': ['bottom-start', 'left', 'right'],
5337
+ 'top-end': ['bottom-end', 'left', 'right'],
5338
+ 'bottom': ['top', 'left', 'right'],
5339
+ 'bottom-start': ['top-start', 'left', 'right'],
5340
+ 'bottom-end': ['top-end', 'left', 'right'],
5341
+ 'left': ['right', 'top', 'bottom'],
5342
+ 'left-start': ['right-start', 'top', 'bottom'],
5343
+ 'left-end': ['right-end', 'top', 'bottom'],
5344
+ 'right': ['left', 'top', 'bottom'],
5345
+ 'right-start': ['left-start', 'top', 'bottom'],
5346
+ 'right-end': ['left-end', 'top', 'bottom'],
5347
+ };
5348
+ return opposites[position] || ['top', 'bottom', 'left', 'right'];
5349
+ }
5350
+ function calculatePosition(triggerRect, tooltipRect, position, offset, arrowSize, strictPositioning) {
5351
+ const vw = window.innerWidth;
5352
+ const vh = window.innerHeight;
5353
+ let pos = position;
5354
+ let coords = getPositionCoordinates(triggerRect, tooltipRect, pos, offset, arrowSize);
5355
+ if (!strictPositioning) {
5356
+ const fits = coords.left >= 0 &&
5357
+ coords.top >= 0 &&
5358
+ coords.left + tooltipRect.width <= vw &&
5359
+ coords.top + tooltipRect.height <= vh;
5360
+ if (!fits) {
5361
+ for (const alt of getAlternativePositions(pos)) {
5362
+ const altCoords = getPositionCoordinates(triggerRect, tooltipRect, alt, offset, arrowSize);
5363
+ if (altCoords.left >= 0 &&
5364
+ altCoords.top >= 0 &&
5365
+ altCoords.left + tooltipRect.width <= vw &&
5366
+ altCoords.top + tooltipRect.height <= vh) {
5367
+ pos = alt;
5368
+ coords = altCoords;
5369
+ break;
5370
+ }
5371
+ }
5372
+ }
5373
+ }
5374
+ return { left: coords.left, top: coords.top, adjustedPosition: pos };
5375
+ }
5376
+ // --- Portal creation ---
5377
+ function createPortal(config) {
5378
+ const portal = document.createElement('div');
5379
+ portal.className = `snice-tooltip snice-tooltip--${config.position}`;
5380
+ portal.setAttribute('role', 'tooltip');
5381
+ portal.style.cssText = `
5382
+ position: fixed;
5383
+ z-index: ${config.zIndex};
5384
+ padding: ${config.padding};
5385
+ background: ${config.bg};
5386
+ color: ${config.color};
5387
+ border-radius: ${config.radius};
5388
+ font-size: ${config.fontSize};
5389
+ line-height: 1.4;
5390
+ max-width: ${config.maxWidth}px;
5391
+ width: max-content;
5392
+ pointer-events: none;
5393
+ opacity: 0;
5394
+ transform: scale(0.95);
5395
+ transition: opacity 0.2s, transform 0.2s;
5396
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
5397
+ display: none;
5398
+ `;
5399
+ const content = document.createElement('div');
5400
+ content.className = 'snice-tooltip__content';
5401
+ portal.appendChild(content);
5402
+ if (config.arrow) {
5403
+ const arrow = document.createElement('div');
5404
+ arrow.className = 'snice-tooltip__arrow';
5405
+ arrow.style.cssText = 'position:absolute;width:0;height:0;border-style:solid;';
5406
+ portal.appendChild(arrow);
5407
+ }
5408
+ document.body.appendChild(portal);
5409
+ return portal;
5410
+ }
5411
+ // --- Show / Hide ---
5412
+ function showTooltip(el) {
5413
+ const text = el.getAttribute('tooltip');
5414
+ if (!text)
5415
+ return;
5416
+ ensurePortalStyles();
5417
+ const config = readConfig(el);
5418
+ let state = stateMap.get(el);
5419
+ if (!state) {
5420
+ state = { portal: null, listeners: [], activePosition: config.position };
5421
+ stateMap.set(el, state);
5422
+ }
5423
+ // Create or update portal
5424
+ if (!state.portal) {
5425
+ state.portal = createPortal(config);
5426
+ }
5427
+ else {
5428
+ // Update styling in case CSS vars changed
5429
+ const p = state.portal;
5430
+ p.style.zIndex = String(config.zIndex);
5431
+ p.style.padding = config.padding;
5432
+ p.style.background = config.bg;
5433
+ p.style.color = config.color;
5434
+ p.style.borderRadius = config.radius;
5435
+ p.style.fontSize = config.fontSize;
5436
+ p.style.maxWidth = `${config.maxWidth}px`;
5437
+ // Update arrow — CSS handles color via class-based rules, but we need
5438
+ // the arrow element to exist/not-exist
5439
+ let arrow = p.querySelector('.snice-tooltip__arrow');
5440
+ if (config.arrow && !arrow) {
5441
+ arrow = document.createElement('div');
5442
+ arrow.className = 'snice-tooltip__arrow';
5443
+ arrow.style.cssText = 'position:absolute;width:0;height:0;border-style:solid;';
5444
+ p.appendChild(arrow);
5445
+ }
5446
+ else if (!config.arrow && arrow) {
5447
+ arrow.style.display = 'none';
5448
+ }
5449
+ else if (config.arrow && arrow) {
5450
+ arrow.style.display = '';
5451
+ }
5452
+ }
5453
+ const portal = state.portal;
5454
+ const contentEl = portal.querySelector('.snice-tooltip__content');
5455
+ if (contentEl)
5456
+ contentEl.textContent = text;
5457
+ portal.style.display = 'block';
5458
+ void portal.offsetHeight; // force reflow
5459
+ // Position
5460
+ portal.style.visibility = 'hidden';
5461
+ portal.style.left = '-9999px';
5462
+ portal.style.top = '-9999px';
5463
+ const triggerRect = el.getBoundingClientRect();
5464
+ const tooltipRect = portal.getBoundingClientRect();
5465
+ portal.style.visibility = '';
5466
+ const arrowSize = config.arrow ? 6 : 0;
5467
+ const result = calculatePosition(triggerRect, tooltipRect, config.position, config.offset, arrowSize, config.strictPositioning);
5468
+ if (result.adjustedPosition !== state.activePosition) {
5469
+ portal.classList.remove(`snice-tooltip--${state.activePosition}`);
5470
+ portal.classList.add(`snice-tooltip--${result.adjustedPosition}`);
5471
+ state.activePosition = result.adjustedPosition;
5472
+ }
5473
+ portal.style.left = `${result.left}px`;
5474
+ portal.style.top = `${result.top}px`;
5475
+ portal.classList.add('snice-tooltip--visible');
5476
+ }
5477
+ function hideTooltip(el) {
5478
+ const state = stateMap.get(el);
5479
+ if (!state?.portal)
5480
+ return;
5481
+ state.portal.classList.remove('snice-tooltip--visible');
5482
+ const p = state.portal;
5483
+ setTimeout(() => {
5484
+ if (p)
5485
+ p.style.display = 'none';
5486
+ }, 200);
5487
+ }
5488
+ function scheduleShow(el) {
5489
+ const state = stateMap.get(el);
5490
+ if (!state)
5491
+ return;
5492
+ clearTimeouts(state);
5493
+ const config = readConfig(el);
5494
+ if (config.delay > 0) {
5495
+ state.showTimeout = window.setTimeout(() => showTooltip(el), config.delay);
5496
+ }
5497
+ else {
5498
+ showTooltip(el);
5499
+ }
5500
+ }
5501
+ function scheduleHide(el) {
5502
+ const state = stateMap.get(el);
5503
+ if (!state)
5504
+ return;
5505
+ clearTimeouts(state);
5506
+ const config = readConfig(el);
5507
+ if (config.hideDelay > 0) {
5508
+ state.hideTimeout = window.setTimeout(() => hideTooltip(el), config.hideDelay);
5509
+ }
5510
+ else {
5511
+ hideTooltip(el);
5512
+ }
5513
+ }
5514
+ function clearTimeouts(state) {
5515
+ if (state.showTimeout !== undefined) {
5516
+ clearTimeout(state.showTimeout);
5517
+ state.showTimeout = undefined;
5518
+ }
5519
+ if (state.hideTimeout !== undefined) {
5520
+ clearTimeout(state.hideTimeout);
5521
+ state.hideTimeout = undefined;
5522
+ }
5523
+ }
5524
+ // --- Attach / Detach ---
5525
+ function attachTooltip(el) {
5526
+ // Skip if already attached
5527
+ if (stateMap.has(el))
5528
+ return;
5529
+ const config = readConfig(el);
5530
+ const state = { portal: null, listeners: [], activePosition: config.position };
5531
+ stateMap.set(el, state);
5532
+ const addListener = (type, fn) => {
5533
+ el.addEventListener(type, fn);
5534
+ state.listeners.push({ type, fn });
5535
+ };
5536
+ switch (config.trigger) {
5537
+ case 'hover':
5538
+ addListener('mouseenter', () => scheduleShow(el));
5539
+ addListener('mouseleave', () => scheduleHide(el));
5540
+ addListener('focusin', () => scheduleShow(el));
5541
+ addListener('focusout', () => scheduleHide(el));
5542
+ break;
5543
+ case 'focus':
5544
+ addListener('focusin', () => scheduleShow(el));
5545
+ addListener('focusout', () => scheduleHide(el));
5546
+ break;
5547
+ case 'click': {
5548
+ const clickOutside = (e) => {
5549
+ if (!el.contains(e.target)) {
5550
+ scheduleHide(el);
5551
+ document.removeEventListener('click', clickOutside);
5552
+ }
5553
+ };
5554
+ addListener('click', () => {
5555
+ const s = stateMap.get(el);
5556
+ const isVisible = s?.portal?.classList.contains('snice-tooltip--visible');
5557
+ if (isVisible) {
5558
+ scheduleHide(el);
5559
+ }
5560
+ else {
5561
+ scheduleShow(el);
5562
+ setTimeout(() => document.addEventListener('click', clickOutside), 0);
5563
+ }
5564
+ });
5565
+ break;
5566
+ }
5567
+ }
5568
+ }
5569
+ function detachTooltip(el) {
5570
+ const state = stateMap.get(el);
5571
+ if (!state)
5572
+ return;
5573
+ clearTimeouts(state);
5574
+ for (const { type, fn } of state.listeners) {
5575
+ el.removeEventListener(type, fn);
5576
+ }
5577
+ if (state.portal) {
5578
+ state.portal.remove();
5579
+ }
5580
+ stateMap.delete(el);
5581
+ }
5582
+ // --- Observer ---
5583
+ function processElement(el) {
5584
+ if (!(el instanceof HTMLElement))
5585
+ return;
5586
+ const tooltip = el.getAttribute('tooltip');
5587
+ if (tooltip) {
5588
+ attachTooltip(el);
5589
+ }
5590
+ }
5591
+ /**
5592
+ * Initialize attribute-based tooltips.
5593
+ * Any element with a `tooltip` attribute will show a tooltip on interaction.
5594
+ * Configure via CSS custom properties (--tooltip-position, --tooltip-delay, etc.).
5595
+ * Idempotent — safe to call multiple times.
5596
+ */
5597
+ function useTooltips() {
5598
+ if (globalThis.sniceTooltipsInitialized)
5599
+ return;
5600
+ globalThis.sniceTooltipsInitialized = true;
5601
+ const observer = new MutationObserver((mutations) => {
5602
+ for (const mutation of mutations) {
5603
+ if (mutation.type === 'attributes' && mutation.attributeName === 'tooltip') {
5604
+ const el = mutation.target;
5605
+ if (el.hasAttribute('tooltip')) {
5606
+ // Attribute added or changed — detach old, re-attach
5607
+ detachTooltip(el);
5608
+ attachTooltip(el);
5609
+ }
5610
+ else {
5611
+ // Attribute removed
5612
+ detachTooltip(el);
5613
+ }
5614
+ }
5615
+ else if (mutation.type === 'childList') {
5616
+ mutation.addedNodes.forEach(node => {
5617
+ if (node instanceof HTMLElement) {
5618
+ processElement(node);
5619
+ node.querySelectorAll('[tooltip]').forEach(processElement);
5620
+ }
5621
+ });
5622
+ mutation.removedNodes.forEach(node => {
5623
+ if (node instanceof HTMLElement) {
5624
+ detachTooltip(node);
5625
+ node.querySelectorAll('[tooltip]').forEach(child => {
5626
+ if (child instanceof HTMLElement)
5627
+ detachTooltip(child);
5628
+ });
5629
+ }
5630
+ });
5631
+ }
5632
+ }
5633
+ });
5634
+ const start = () => {
5635
+ document.querySelectorAll('[tooltip]').forEach(processElement);
5636
+ observer.observe(document.body, {
5637
+ attributes: true,
5638
+ attributeFilter: ['tooltip'],
5639
+ childList: true,
5640
+ subtree: true,
5641
+ });
5642
+ };
5643
+ if (document.readyState === 'loading') {
5644
+ document.addEventListener('DOMContentLoaded', start);
5645
+ }
5646
+ else {
5647
+ start();
5648
+ }
5649
+ globalThis.sniceTooltipObserver = observer;
5650
+ }
5651
+ /**
5652
+ * Disconnect the tooltip observer and remove all portals.
5653
+ */
5654
+ function cleanupTooltips() {
5655
+ const observer = globalThis.sniceTooltipObserver;
5656
+ if (observer) {
5657
+ observer.disconnect();
5658
+ globalThis.sniceTooltipObserver = undefined;
5659
+ }
5660
+ document.querySelectorAll('[tooltip]').forEach(el => {
5661
+ if (el instanceof HTMLElement)
5662
+ detachTooltip(el);
5663
+ });
5664
+ globalThis.sniceTooltipsInitialized = false;
5665
+ }
5666
+
5200
5667
  // @dispatch decorator - auto-dispatches custom events from method return values
5201
5668
  /**
5202
5669
  * Decorator that automatically dispatches a custom event after a method is called.
@@ -5832,6 +6299,7 @@ var Snice = (function (exports) {
5832
6299
  exports.SimpleArray = SimpleArray;
5833
6300
  exports.adopted = adopted;
5834
6301
  exports.applyElementFunctionality = applyElementFunctionality;
6302
+ exports.cleanupTooltips = cleanupTooltips;
5835
6303
  exports.clearDebounceTimers = clearDebounceTimers;
5836
6304
  exports.clearMemoizeCache = clearMemoizeCache;
5837
6305
  exports.clearThrottleTimers = clearThrottleTimers;
@@ -5867,6 +6335,7 @@ var Snice = (function (exports) {
5867
6335
  exports.trackRenders = trackRenders;
5868
6336
  exports.unsafeHTML = unsafeHTML;
5869
6337
  exports.useNativeElementControllers = useNativeElementControllers;
6338
+ exports.useTooltips = useTooltips;
5870
6339
  exports.waitForAllCustomElements = waitForAllCustomElements;
5871
6340
  exports.waitForElementDefined = waitForElementDefined;
5872
6341
  exports.waitForElementReady = waitForElementReady;