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