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