snice 2.5.4 → 3.1.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 (323) hide show
  1. package/README.md +501 -882
  2. package/bin/templates/base/src/components/counter-button.ts +13 -26
  3. package/bin/templates/base/src/controllers/counter-controller.ts +3 -3
  4. package/dist/components/accordion/snice-accordion-item.d.ts +4 -5
  5. package/dist/components/accordion/snice-accordion-item.js +37 -39
  6. package/dist/components/accordion/snice-accordion-item.js.map +1 -1
  7. package/dist/components/accordion/snice-accordion.d.ts +5 -11
  8. package/dist/components/accordion/snice-accordion.js +51 -52
  9. package/dist/components/accordion/snice-accordion.js.map +1 -1
  10. package/dist/components/alert/snice-alert.d.ts +2 -6
  11. package/dist/components/alert/snice-alert.js +41 -56
  12. package/dist/components/alert/snice-alert.js.map +1 -1
  13. package/dist/components/avatar/snice-avatar.d.ts +2 -6
  14. package/dist/components/avatar/snice-avatar.js +64 -71
  15. package/dist/components/avatar/snice-avatar.js.map +1 -1
  16. package/dist/components/badge/snice-badge.d.ts +2 -3
  17. package/dist/components/badge/snice-badge.js +22 -23
  18. package/dist/components/badge/snice-badge.js.map +1 -1
  19. package/dist/components/breadcrumbs/snice-breadcrumbs.d.ts +5 -12
  20. package/dist/components/breadcrumbs/snice-breadcrumbs.js +88 -89
  21. package/dist/components/breadcrumbs/snice-breadcrumbs.js.map +1 -1
  22. package/dist/components/button/snice-button.d.ts +3 -7
  23. package/dist/components/button/snice-button.js +37 -58
  24. package/dist/components/button/snice-button.js.map +1 -1
  25. package/dist/components/card/snice-card.d.ts +5 -8
  26. package/dist/components/card/snice-card.js +71 -56
  27. package/dist/components/card/snice-card.js.map +1 -1
  28. package/dist/components/checkbox/snice-checkbox.d.ts +4 -13
  29. package/dist/components/checkbox/snice-checkbox.js +66 -137
  30. package/dist/components/checkbox/snice-checkbox.js.map +1 -1
  31. package/dist/components/chip/snice-chip.d.ts +5 -11
  32. package/dist/components/chip/snice-chip.js +44 -47
  33. package/dist/components/chip/snice-chip.js.map +1 -1
  34. package/dist/components/date-picker/snice-date-picker.d.ts +11 -11
  35. package/dist/components/date-picker/snice-date-picker.js +134 -133
  36. package/dist/components/date-picker/snice-date-picker.js.map +1 -1
  37. package/dist/components/divider/snice-divider.d.ts +2 -4
  38. package/dist/components/divider/snice-divider.js +14 -22
  39. package/dist/components/divider/snice-divider.js.map +1 -1
  40. package/dist/components/drawer/snice-drawer.d.ts +4 -4
  41. package/dist/components/drawer/snice-drawer.js +25 -19
  42. package/dist/components/drawer/snice-drawer.js.map +1 -1
  43. package/dist/components/input/snice-input.d.ts +8 -6
  44. package/dist/components/input/snice-input.js +122 -105
  45. package/dist/components/input/snice-input.js.map +1 -1
  46. package/dist/components/layout/snice-layout-blog.d.ts +4 -4
  47. package/dist/components/layout/snice-layout-blog.js +21 -19
  48. package/dist/components/layout/snice-layout-blog.js.map +1 -1
  49. package/dist/components/layout/snice-layout-card.d.ts +2 -2
  50. package/dist/components/layout/snice-layout-card.js +16 -9
  51. package/dist/components/layout/snice-layout-card.js.map +1 -1
  52. package/dist/components/layout/snice-layout-centered.d.ts +2 -2
  53. package/dist/components/layout/snice-layout-centered.js +14 -7
  54. package/dist/components/layout/snice-layout-centered.js.map +1 -1
  55. package/dist/components/layout/snice-layout-dashboard.d.ts +5 -5
  56. package/dist/components/layout/snice-layout-dashboard.js +38 -30
  57. package/dist/components/layout/snice-layout-dashboard.js.map +1 -1
  58. package/dist/components/layout/snice-layout-fullscreen.d.ts +2 -2
  59. package/dist/components/layout/snice-layout-fullscreen.js +17 -10
  60. package/dist/components/layout/snice-layout-fullscreen.js.map +1 -1
  61. package/dist/components/layout/snice-layout-landing.d.ts +4 -4
  62. package/dist/components/layout/snice-layout-landing.js +21 -19
  63. package/dist/components/layout/snice-layout-landing.js.map +1 -1
  64. package/dist/components/layout/snice-layout-minimal.d.ts +2 -2
  65. package/dist/components/layout/snice-layout-minimal.js +17 -6
  66. package/dist/components/layout/snice-layout-minimal.js.map +1 -1
  67. package/dist/components/layout/snice-layout-sidebar.d.ts +5 -4
  68. package/dist/components/layout/snice-layout-sidebar.js +42 -20
  69. package/dist/components/layout/snice-layout-sidebar.js.map +1 -1
  70. package/dist/components/layout/snice-layout-split.d.ts +2 -2
  71. package/dist/components/layout/snice-layout-split.js +14 -7
  72. package/dist/components/layout/snice-layout-split.js.map +1 -1
  73. package/dist/components/layout/snice-layout.d.ts +4 -4
  74. package/dist/components/layout/snice-layout.js +16 -10
  75. package/dist/components/layout/snice-layout.js.map +1 -1
  76. package/dist/components/login/snice-login.d.ts +6 -11
  77. package/dist/components/login/snice-login.js +97 -71
  78. package/dist/components/login/snice-login.js.map +1 -1
  79. package/dist/components/modal/snice-modal.d.ts +5 -9
  80. package/dist/components/modal/snice-modal.js +47 -78
  81. package/dist/components/modal/snice-modal.js.map +1 -1
  82. package/dist/components/nav/snice-nav.d.ts +13 -7
  83. package/dist/components/nav/snice-nav.js +191 -100
  84. package/dist/components/nav/snice-nav.js.map +1 -1
  85. package/dist/components/nav/snice-nav.types.d.ts +3 -3
  86. package/dist/components/pagination/snice-pagination.d.ts +6 -7
  87. package/dist/components/pagination/snice-pagination.js +94 -81
  88. package/dist/components/pagination/snice-pagination.js.map +1 -1
  89. package/dist/components/progress/snice-progress.d.ts +2 -7
  90. package/dist/components/progress/snice-progress.js +41 -98
  91. package/dist/components/progress/snice-progress.js.map +1 -1
  92. package/dist/components/radio/snice-radio.d.ts +4 -4
  93. package/dist/components/radio/snice-radio.js +52 -44
  94. package/dist/components/radio/snice-radio.js.map +1 -1
  95. package/dist/components/select/snice-option.d.ts +2 -1
  96. package/dist/components/select/snice-option.js +12 -5
  97. package/dist/components/select/snice-option.js.map +1 -1
  98. package/dist/components/select/snice-select.d.ts +9 -21
  99. package/dist/components/select/snice-select.js +98 -170
  100. package/dist/components/select/snice-select.js.map +1 -1
  101. package/dist/components/skeleton/snice-skeleton.d.ts +2 -6
  102. package/dist/components/skeleton/snice-skeleton.js +18 -49
  103. package/dist/components/skeleton/snice-skeleton.js.map +1 -1
  104. package/dist/components/snice-cell-BLFVdxPp.js +4 -0
  105. package/dist/components/snice-cell-BLFVdxPp.js.map +1 -0
  106. package/dist/components/switch/snice-switch.d.ts +2 -2
  107. package/dist/components/switch/snice-switch.js +38 -26
  108. package/dist/components/switch/snice-switch.js.map +1 -1
  109. package/dist/components/table/snice-cell-actions.d.ts +24 -0
  110. package/dist/components/table/snice-cell-actions.js +149 -0
  111. package/dist/components/table/snice-cell-actions.js.map +1 -0
  112. package/dist/components/table/snice-cell-boolean.d.ts +2 -2
  113. package/dist/components/table/snice-cell-boolean.js +13 -7
  114. package/dist/components/table/snice-cell-boolean.js.map +1 -1
  115. package/dist/components/table/snice-cell-color.d.ts +18 -0
  116. package/dist/components/table/snice-cell-color.js +149 -0
  117. package/dist/components/table/snice-cell-color.js.map +1 -0
  118. package/dist/components/table/snice-cell-currency.d.ts +24 -0
  119. package/dist/components/table/snice-cell-currency.js +235 -0
  120. package/dist/components/table/snice-cell-currency.js.map +1 -0
  121. package/dist/components/table/snice-cell-date.d.ts +2 -2
  122. package/dist/components/table/snice-cell-date.js +14 -8
  123. package/dist/components/table/snice-cell-date.js.map +1 -1
  124. package/dist/components/table/snice-cell-duration.d.ts +2 -2
  125. package/dist/components/table/snice-cell-duration.js +12 -6
  126. package/dist/components/table/snice-cell-duration.js.map +1 -1
  127. package/dist/components/table/snice-cell-email.d.ts +15 -0
  128. package/dist/components/table/snice-cell-email.js +125 -0
  129. package/dist/components/table/snice-cell-email.js.map +1 -0
  130. package/dist/components/table/snice-cell-filesize.d.ts +2 -2
  131. package/dist/components/table/snice-cell-filesize.js +12 -6
  132. package/dist/components/table/snice-cell-filesize.js.map +1 -1
  133. package/dist/components/table/snice-cell-image.d.ts +20 -0
  134. package/dist/components/table/snice-cell-image.js +162 -0
  135. package/dist/components/table/snice-cell-image.js.map +1 -0
  136. package/dist/components/table/snice-cell-json.d.ts +20 -0
  137. package/dist/components/table/snice-cell-json.js +186 -0
  138. package/dist/components/table/snice-cell-json.js.map +1 -0
  139. package/dist/components/table/snice-cell-link.d.ts +17 -0
  140. package/dist/components/table/snice-cell-link.js +142 -0
  141. package/dist/components/table/snice-cell-link.js.map +1 -0
  142. package/dist/components/table/snice-cell-location.d.ts +19 -0
  143. package/dist/components/table/snice-cell-location.js +185 -0
  144. package/dist/components/table/snice-cell-location.js.map +1 -0
  145. package/dist/components/table/snice-cell-number.d.ts +2 -2
  146. package/dist/components/table/snice-cell-number.js +12 -6
  147. package/dist/components/table/snice-cell-number.js.map +1 -1
  148. package/dist/components/table/snice-cell-percentage.d.ts +22 -0
  149. package/dist/components/table/snice-cell-percentage.js +208 -0
  150. package/dist/components/table/snice-cell-percentage.js.map +1 -0
  151. package/dist/components/table/snice-cell-phone.d.ts +18 -0
  152. package/dist/components/table/snice-cell-phone.js +153 -0
  153. package/dist/components/table/snice-cell-phone.js.map +1 -0
  154. package/dist/components/table/snice-cell-progress.d.ts +2 -2
  155. package/dist/components/table/snice-cell-progress.js +12 -6
  156. package/dist/components/table/snice-cell-progress.js.map +1 -1
  157. package/dist/components/table/snice-cell-rating.d.ts +2 -2
  158. package/dist/components/table/snice-cell-rating.js +12 -6
  159. package/dist/components/table/snice-cell-rating.js.map +1 -1
  160. package/dist/components/table/snice-cell-sparkline.d.ts +2 -2
  161. package/dist/components/table/snice-cell-sparkline.js +13 -7
  162. package/dist/components/table/snice-cell-sparkline.js.map +1 -1
  163. package/dist/components/table/snice-cell-status.d.ts +17 -0
  164. package/dist/components/table/snice-cell-status.js +144 -0
  165. package/dist/components/table/snice-cell-status.js.map +1 -0
  166. package/dist/components/table/snice-cell-tag.d.ts +16 -0
  167. package/dist/components/table/snice-cell-tag.js +131 -0
  168. package/dist/components/table/snice-cell-tag.js.map +1 -0
  169. package/dist/components/table/snice-cell-text.d.ts +2 -2
  170. package/dist/components/table/snice-cell-text.js +14 -8
  171. package/dist/components/table/snice-cell-text.js.map +1 -1
  172. package/dist/components/table/snice-cell.d.ts +2 -2
  173. package/dist/components/table/snice-cell.js +12 -6
  174. package/dist/components/table/snice-cell.js.map +1 -1
  175. package/dist/components/table/snice-column.d.ts +1 -1
  176. package/dist/components/table/snice-column.js +6 -3
  177. package/dist/components/table/snice-column.js.map +1 -1
  178. package/dist/components/table/snice-header.d.ts +5 -5
  179. package/dist/components/table/snice-header.js +60 -50
  180. package/dist/components/table/snice-header.js.map +1 -1
  181. package/dist/components/table/snice-progress.d.ts +2 -2
  182. package/dist/components/table/snice-progress.js +18 -11
  183. package/dist/components/table/snice-progress.js.map +1 -1
  184. package/dist/components/table/snice-rating.d.ts +2 -2
  185. package/dist/components/table/snice-rating.js +15 -8
  186. package/dist/components/table/snice-rating.js.map +1 -1
  187. package/dist/components/table/snice-row.d.ts +17 -6
  188. package/dist/components/table/snice-row.js +95 -44
  189. package/dist/components/table/snice-row.js.map +1 -1
  190. package/dist/components/table/snice-table.d.ts +18 -10
  191. package/dist/components/table/snice-table.js +355 -173
  192. package/dist/components/table/snice-table.js.map +1 -1
  193. package/dist/components/table/snice-table.types.d.ts +101 -2
  194. package/dist/components/tabs/snice-tab-panel.d.ts +2 -2
  195. package/dist/components/tabs/snice-tab-panel.js +12 -6
  196. package/dist/components/tabs/snice-tab-panel.js.map +1 -1
  197. package/dist/components/tabs/snice-tab.d.ts +6 -5
  198. package/dist/components/tabs/snice-tab.js +36 -19
  199. package/dist/components/tabs/snice-tab.js.map +1 -1
  200. package/dist/components/tabs/snice-tabs.d.ts +5 -5
  201. package/dist/components/tabs/snice-tabs.js +38 -28
  202. package/dist/components/tabs/snice-tabs.js.map +1 -1
  203. package/dist/components/toast/snice-toast-container.d.ts +7 -7
  204. package/dist/components/toast/snice-toast-container.js +19 -12
  205. package/dist/components/toast/snice-toast-container.js.map +1 -1
  206. package/dist/components/toast/snice-toast.d.ts +3 -15
  207. package/dist/components/toast/snice-toast.js +49 -108
  208. package/dist/components/toast/snice-toast.js.map +1 -1
  209. package/dist/components/tooltip/snice-tooltip.d.ts +2 -2
  210. package/dist/components/tooltip/snice-tooltip.js +14 -7
  211. package/dist/components/tooltip/snice-tooltip.js.map +1 -1
  212. package/dist/context.d.ts +44 -0
  213. package/dist/element-ready.d.ts +40 -0
  214. package/dist/{types/element.d.ts → element.d.ts} +2 -8
  215. package/dist/{types/events.d.ts → events.d.ts} +0 -4
  216. package/dist/index.cjs +2589 -605
  217. package/dist/index.cjs.map +1 -1
  218. package/dist/index.d.ts +21 -0
  219. package/dist/index.esm.js +2568 -604
  220. package/dist/index.esm.js.map +1 -1
  221. package/dist/index.iife.js +2589 -605
  222. package/dist/index.iife.js.map +1 -1
  223. package/dist/method-decorators.d.ts +121 -0
  224. package/dist/on.d.ts +59 -0
  225. package/dist/parts.d.ts +159 -0
  226. package/dist/render-debug.d.ts +27 -0
  227. package/dist/render-tracker.d.ts +14 -0
  228. package/dist/render.d.ts +96 -0
  229. package/dist/symbols.cjs +163 -0
  230. package/dist/symbols.cjs.map +1 -1
  231. package/dist/{types/symbols.d.ts → symbols.d.ts} +22 -0
  232. package/dist/symbols.esm.js +27 -3
  233. package/dist/symbols.esm.js.map +1 -1
  234. package/dist/template.d.ts +100 -0
  235. package/dist/transitions.cjs +219 -0
  236. package/dist/transitions.esm.js +2 -2
  237. package/dist/types/context.d.ts +48 -0
  238. package/dist/types/element-options.d.ts +26 -0
  239. package/dist/types/index.d.ts +25 -9
  240. package/dist/types/nav-context.d.ts +19 -0
  241. package/dist/types/{types/on-options.d.ts → on-options.d.ts} +2 -0
  242. package/dist/types/{types/placard.d.ts → placard.d.ts} +0 -1
  243. package/docs/ai/README.md +17 -0
  244. package/docs/ai/api.md +175 -0
  245. package/docs/ai/architecture.md +160 -0
  246. package/docs/ai/components/accordion.md +174 -0
  247. package/docs/ai/components/alert.md +77 -0
  248. package/docs/ai/components/avatar.md +61 -0
  249. package/docs/ai/components/badge.md +69 -0
  250. package/docs/ai/components/breadcrumbs.md +74 -0
  251. package/docs/ai/components/button.md +75 -0
  252. package/docs/ai/components/card.md +61 -0
  253. package/docs/ai/components/checkbox.md +74 -0
  254. package/docs/ai/components/chip.md +73 -0
  255. package/docs/ai/components/date-picker.md +75 -0
  256. package/docs/ai/components/divider.md +66 -0
  257. package/docs/ai/components/drawer.md +80 -0
  258. package/docs/ai/components/input.md +111 -0
  259. package/docs/ai/components/login.md +109 -0
  260. package/docs/ai/components/modal.md +67 -0
  261. package/docs/ai/components/nav.md +76 -0
  262. package/docs/ai/components/pagination.md +55 -0
  263. package/docs/ai/components/progress.md +72 -0
  264. package/docs/ai/components/radio.md +79 -0
  265. package/docs/ai/components/select.md +92 -0
  266. package/docs/ai/components/skeleton.md +57 -0
  267. package/docs/ai/components/switch.md +53 -0
  268. package/docs/ai/components/table.md +227 -0
  269. package/docs/ai/components/tabs.md +83 -0
  270. package/docs/ai/components/toast.md +140 -0
  271. package/docs/ai/components/tooltip.md +146 -0
  272. package/docs/ai/patterns.md +244 -0
  273. package/docs/components/accordion.md +558 -0
  274. package/docs/components/drawer.md +602 -0
  275. package/docs/components/modal.md +558 -0
  276. package/docs/components/nav.md +239 -0
  277. package/docs/components/pagination.md +289 -0
  278. package/docs/components/select.md +599 -0
  279. package/docs/components/switch.md +354 -0
  280. package/docs/components/tabs.md +546 -0
  281. package/docs/components/toast.md +506 -0
  282. package/docs/components/tooltip.md +523 -0
  283. package/docs/controllers.md +744 -0
  284. package/docs/elements.md +855 -0
  285. package/docs/events.md +807 -0
  286. package/docs/migration-v2-to-v3.md +569 -0
  287. package/docs/observe.md +588 -0
  288. package/docs/placards.md +401 -0
  289. package/docs/request-response.md +852 -0
  290. package/docs/routing.md +1186 -0
  291. package/package.json +10 -11
  292. package/dist/components/snice-cell-C9N6yGxQ.js +0 -4
  293. package/dist/components/snice-cell-C9N6yGxQ.js.map +0 -1
  294. package/dist/types/types/index.d.ts +0 -23
  295. /package/dist/{types/controller.d.ts → controller.d.ts} +0 -0
  296. /package/dist/{types/global.d.ts → global.d.ts} +0 -0
  297. /package/dist/{types/observe.d.ts → observe.d.ts} +0 -0
  298. /package/dist/{types/request-response.d.ts → request-response.d.ts} +0 -0
  299. /package/dist/{types/router.d.ts → router.d.ts} +0 -0
  300. /package/dist/{types/testing.d.ts → testing.d.ts} +0 -0
  301. /package/dist/{types/transitions.d.ts → transitions.d.ts} +0 -0
  302. /package/dist/types/{types/adopted-options.d.ts → adopted-options.d.ts} +0 -0
  303. /package/dist/types/{types/app-context.d.ts → app-context.d.ts} +0 -0
  304. /package/dist/types/{types/dispatch-options.d.ts → dispatch-options.d.ts} +0 -0
  305. /package/dist/types/{types/guard.d.ts → guard.d.ts} +0 -0
  306. /package/dist/types/{types/i-controller.d.ts → i-controller.d.ts} +0 -0
  307. /package/dist/types/{types/moved-options.d.ts → moved-options.d.ts} +0 -0
  308. /package/dist/types/{types/observe-options.d.ts → observe-options.d.ts} +0 -0
  309. /package/dist/types/{types/page-options.d.ts → page-options.d.ts} +0 -0
  310. /package/dist/types/{types/part-options.d.ts → part-options.d.ts} +0 -0
  311. /package/dist/types/{types/property-converter.d.ts → property-converter.d.ts} +0 -0
  312. /package/dist/types/{types/property-options.d.ts → property-options.d.ts} +0 -0
  313. /package/dist/types/{types/query-options.d.ts → query-options.d.ts} +0 -0
  314. /package/dist/types/{types/request-options.d.ts → request-options.d.ts} +0 -0
  315. /package/dist/types/{types/respond-options.d.ts → respond-options.d.ts} +0 -0
  316. /package/dist/types/{types/route-params.d.ts → route-params.d.ts} +0 -0
  317. /package/dist/types/{types/router-instance.d.ts → router-instance.d.ts} +0 -0
  318. /package/dist/types/{types/router-options.d.ts → router-options.d.ts} +0 -0
  319. /package/dist/types/{types/simple-array.d.ts → simple-array.d.ts} +0 -0
  320. /package/dist/types/{types/snice-element.d.ts → snice-element.d.ts} +0 -0
  321. /package/dist/types/{types/snice-global.d.ts → snice-global.d.ts} +0 -0
  322. /package/dist/types/{types/transition.d.ts → transition.d.ts} +0 -0
  323. /package/dist/{types/utils.d.ts → utils.d.ts} +0 -0
@@ -0,0 +1,558 @@
1
+ # Modal Component
2
+
3
+ The `<snice-modal>` component provides a dialog overlay for displaying content on top of the main page. It includes features like focus trapping, backdrop dismiss, keyboard navigation, and accessibility support.
4
+
5
+ ## Table of Contents
6
+ - [Basic Usage](#basic-usage)
7
+ - [Properties](#properties)
8
+ - [Methods](#methods)
9
+ - [Events](#events)
10
+ - [Slots](#slots)
11
+ - [Examples](#examples)
12
+
13
+ ## Basic Usage
14
+
15
+ ```html
16
+ <snice-modal label="Confirm Action">
17
+ <div slot="header">
18
+ <h2>Confirm</h2>
19
+ </div>
20
+
21
+ <p>Are you sure you want to proceed?</p>
22
+
23
+ <div slot="footer">
24
+ <button>Cancel</button>
25
+ <button>Confirm</button>
26
+ </div>
27
+ </snice-modal>
28
+ ```
29
+
30
+ ```typescript
31
+ import 'snice/components/modal/snice-modal';
32
+
33
+ const modal = document.querySelector('snice-modal');
34
+
35
+ // Open the modal
36
+ modal.show();
37
+
38
+ // Listen for events
39
+ modal.addEventListener('@snice/modal-close', () => {
40
+ console.log('Modal closed');
41
+ });
42
+ ```
43
+
44
+ ## Properties
45
+
46
+ | Property | Type | Default | Description |
47
+ |----------|------|---------|-------------|
48
+ | `open` | `boolean` | `false` | Whether the modal is visible |
49
+ | `size` | `'small' \| 'medium' \| 'large' \| 'fullscreen'` | `'medium'` | Size variant of the modal |
50
+ | `noBackdropDismiss` | `boolean` | `false` | Prevent closing when clicking backdrop |
51
+ | `noEscapeDismiss` | `boolean` | `false` | Prevent closing with Escape key |
52
+ | `noFocusTrap` | `boolean` | `false` | Disable focus trapping |
53
+ | `noCloseButton` | `boolean` | `false` | Hide the close button in header |
54
+ | `label` | `string` | `''` | Accessible label for the modal |
55
+
56
+ ## Methods
57
+
58
+ ### `show(): void`
59
+ Open the modal.
60
+
61
+ ```typescript
62
+ modal.show();
63
+ ```
64
+
65
+ ### `close(): void`
66
+ Close the modal.
67
+
68
+ ```typescript
69
+ modal.close();
70
+ ```
71
+
72
+ ## Events
73
+
74
+ ### `@snice/modal-open`
75
+ Fired when the modal opens.
76
+
77
+ **Event Detail:**
78
+ ```typescript
79
+ {
80
+ modal: SniceModalElement; // Reference to the modal element
81
+ }
82
+ ```
83
+
84
+ **Usage:**
85
+ ```typescript
86
+ modal.addEventListener('@snice/modal-open', (e) => {
87
+ console.log('Modal opened:', e.detail.modal);
88
+ });
89
+ ```
90
+
91
+ ### `@snice/modal-close`
92
+ Fired when the modal closes.
93
+
94
+ **Event Detail:**
95
+ ```typescript
96
+ {
97
+ modal: SniceModalElement; // Reference to the modal element
98
+ }
99
+ ```
100
+
101
+ **Usage:**
102
+ ```typescript
103
+ modal.addEventListener('@snice/modal-close', (e) => {
104
+ console.log('Modal closed:', e.detail.modal);
105
+ });
106
+ ```
107
+
108
+ ## Slots
109
+
110
+ ### `header` (named slot)
111
+ Content for the modal header. Typically used for titles.
112
+
113
+ ```html
114
+ <snice-modal>
115
+ <div slot="header">
116
+ <h2>Modal Title</h2>
117
+ </div>
118
+ </snice-modal>
119
+ ```
120
+
121
+ ### Default slot
122
+ Main content of the modal body.
123
+
124
+ ```html
125
+ <snice-modal>
126
+ <p>This goes in the body</p>
127
+ </snice-modal>
128
+ ```
129
+
130
+ ### `footer` (named slot)
131
+ Content for the modal footer. Typically used for action buttons.
132
+
133
+ ```html
134
+ <snice-modal>
135
+ <div slot="footer">
136
+ <button>Cancel</button>
137
+ <button>OK</button>
138
+ </div>
139
+ </snice-modal>
140
+ ```
141
+
142
+ ## Examples
143
+
144
+ ### Basic Modal
145
+
146
+ ```html
147
+ <button id="openModal">Open Modal</button>
148
+
149
+ <snice-modal id="myModal" label="Example Modal">
150
+ <div slot="header">
151
+ <h2>Hello</h2>
152
+ </div>
153
+
154
+ <p>This is a basic modal example.</p>
155
+
156
+ <div slot="footer">
157
+ <button id="closeModal">Close</button>
158
+ </div>
159
+ </snice-modal>
160
+
161
+ <script type="module">
162
+ import 'snice/components/modal/snice-modal';
163
+
164
+ const modal = document.querySelector('#myModal');
165
+ const openBtn = document.querySelector('#openModal');
166
+ const closeBtn = document.querySelector('#closeModal');
167
+
168
+ openBtn.addEventListener('click', () => modal.show());
169
+ closeBtn.addEventListener('click', () => modal.close());
170
+ </script>
171
+ ```
172
+
173
+ ### Size Variants
174
+
175
+ ```html
176
+ <!-- Small -->
177
+ <snice-modal size="small" label="Small Modal">
178
+ <div slot="header"><h2>Small</h2></div>
179
+ <p>This is a small modal.</p>
180
+ </snice-modal>
181
+
182
+ <!-- Medium (default) -->
183
+ <snice-modal size="medium" label="Medium Modal">
184
+ <div slot="header"><h2>Medium</h2></div>
185
+ <p>This is a medium modal.</p>
186
+ </snice-modal>
187
+
188
+ <!-- Large -->
189
+ <snice-modal size="large" label="Large Modal">
190
+ <div slot="header"><h2>Large</h2></div>
191
+ <p>This is a large modal.</p>
192
+ </snice-modal>
193
+
194
+ <!-- Fullscreen -->
195
+ <snice-modal size="fullscreen" label="Fullscreen Modal">
196
+ <div slot="header"><h2>Fullscreen</h2></div>
197
+ <p>This modal takes up the entire screen.</p>
198
+ </snice-modal>
199
+ ```
200
+
201
+ ### Without Close Button
202
+
203
+ ```html
204
+ <snice-modal no-close-button label="Forced Choice">
205
+ <div slot="header">
206
+ <h2>Choose an Option</h2>
207
+ </div>
208
+
209
+ <p>You must select one of the options below.</p>
210
+
211
+ <div slot="footer">
212
+ <button onclick="this.closest('snice-modal').close()">Option A</button>
213
+ <button onclick="this.closest('snice-modal').close()">Option B</button>
214
+ </div>
215
+ </snice-modal>
216
+ ```
217
+
218
+ ### Prevent Backdrop Dismiss
219
+
220
+ ```html
221
+ <snice-modal no-backdrop-dismiss label="Important">
222
+ <div slot="header">
223
+ <h2>Important Information</h2>
224
+ </div>
225
+
226
+ <p>Click the button to close, clicking outside won't work.</p>
227
+
228
+ <div slot="footer">
229
+ <button onclick="this.closest('snice-modal').close()">I Understand</button>
230
+ </div>
231
+ </snice-modal>
232
+ ```
233
+
234
+ ### Prevent Escape Dismiss
235
+
236
+ ```html
237
+ <snice-modal no-escape-dismiss label="Confirmation Required">
238
+ <div slot="header">
239
+ <h2>Confirm Action</h2>
240
+ </div>
241
+
242
+ <p>Press Escape won't close this modal.</p>
243
+
244
+ <div slot="footer">
245
+ <button onclick="this.closest('snice-modal').close()">Confirm</button>
246
+ </div>
247
+ </snice-modal>
248
+ ```
249
+
250
+ ### Confirmation Dialog
251
+
252
+ ```html
253
+ <button id="deleteBtn">Delete Item</button>
254
+
255
+ <snice-modal id="confirmModal" size="small" label="Confirm Delete">
256
+ <div slot="header">
257
+ <h2>Confirm Delete</h2>
258
+ </div>
259
+
260
+ <p>Are you sure you want to delete this item? This action cannot be undone.</p>
261
+
262
+ <div slot="footer">
263
+ <button id="cancelBtn">Cancel</button>
264
+ <button id="confirmBtn" style="background: #dc2626; color: white;">Delete</button>
265
+ </div>
266
+ </snice-modal>
267
+
268
+ <script type="module">
269
+ import 'snice/components/modal/snice-modal';
270
+
271
+ const deleteBtn = document.querySelector('#deleteBtn');
272
+ const modal = document.querySelector('#confirmModal');
273
+ const cancelBtn = document.querySelector('#cancelBtn');
274
+ const confirmBtn = document.querySelector('#confirmBtn');
275
+
276
+ deleteBtn.addEventListener('click', () => {
277
+ modal.show();
278
+ });
279
+
280
+ cancelBtn.addEventListener('click', () => {
281
+ modal.close();
282
+ });
283
+
284
+ confirmBtn.addEventListener('click', () => {
285
+ // Perform delete action
286
+ console.log('Item deleted');
287
+ modal.close();
288
+ });
289
+ </script>
290
+ ```
291
+
292
+ ### Form in Modal
293
+
294
+ ```html
295
+ <button id="showFormModal">Edit Profile</button>
296
+
297
+ <snice-modal id="formModal" label="Edit Profile">
298
+ <div slot="header">
299
+ <h2>Edit Profile</h2>
300
+ </div>
301
+
302
+ <form id="profileForm">
303
+ <div style="display: flex; flex-direction: column; gap: 1rem;">
304
+ <div>
305
+ <label for="name">Name:</label>
306
+ <input type="text" id="name" name="name" required>
307
+ </div>
308
+ <div>
309
+ <label for="email">Email:</label>
310
+ <input type="email" id="email" name="email" required>
311
+ </div>
312
+ </div>
313
+ </form>
314
+
315
+ <div slot="footer">
316
+ <button type="button" onclick="this.closest('snice-modal').close()">Cancel</button>
317
+ <button type="submit" form="profileForm">Save</button>
318
+ </div>
319
+ </snice-modal>
320
+
321
+ <script type="module">
322
+ import 'snice/components/modal/snice-modal';
323
+
324
+ const showBtn = document.querySelector('#showFormModal');
325
+ const modal = document.querySelector('#formModal');
326
+ const form = document.querySelector('#profileForm');
327
+
328
+ showBtn.addEventListener('click', () => modal.show());
329
+
330
+ form.addEventListener('submit', (e) => {
331
+ e.preventDefault();
332
+ const formData = new FormData(form);
333
+ console.log('Saving:', Object.fromEntries(formData));
334
+ modal.close();
335
+ });
336
+ </script>
337
+ ```
338
+
339
+ ### With Event Handling
340
+
341
+ ```typescript
342
+ import type { SniceModalElement } from 'snice/components/modal/snice-modal.types';
343
+
344
+ const modal = document.querySelector<SniceModalElement>('snice-modal');
345
+
346
+ modal.addEventListener('@snice/modal-open', () => {
347
+ console.log('Modal opened');
348
+ // Pause video, etc.
349
+ });
350
+
351
+ modal.addEventListener('@snice/modal-close', () => {
352
+ console.log('Modal closed');
353
+ // Resume video, etc.
354
+ });
355
+
356
+ // Open programmatically
357
+ modal.show();
358
+
359
+ // Close programmatically
360
+ modal.close();
361
+
362
+ // Toggle based on state
363
+ if (modal.open) {
364
+ modal.close();
365
+ } else {
366
+ modal.show();
367
+ }
368
+ ```
369
+
370
+ ### Dynamic Content
371
+
372
+ ```html
373
+ <button id="showDetails">Show Details</button>
374
+
375
+ <snice-modal id="detailsModal" label="Item Details">
376
+ <div slot="header">
377
+ <h2 id="itemTitle">Loading...</h2>
378
+ </div>
379
+
380
+ <div id="itemContent">
381
+ <p>Loading...</p>
382
+ </div>
383
+
384
+ <div slot="footer">
385
+ <button onclick="this.closest('snice-modal').close()">Close</button>
386
+ </div>
387
+ </snice-modal>
388
+
389
+ <script type="module">
390
+ import 'snice/components/modal/snice-modal';
391
+
392
+ const showBtn = document.querySelector('#showDetails');
393
+ const modal = document.querySelector('#detailsModal');
394
+ const title = document.querySelector('#itemTitle');
395
+ const content = document.querySelector('#itemContent');
396
+
397
+ showBtn.addEventListener('click', async () => {
398
+ modal.show();
399
+
400
+ // Fetch data
401
+ const response = await fetch('/api/item/123');
402
+ const item = await response.json();
403
+
404
+ // Update modal content
405
+ title.textContent = item.name;
406
+ content.innerHTML = `
407
+ <p><strong>ID:</strong> ${item.id}</p>
408
+ <p><strong>Description:</strong> ${item.description}</p>
409
+ <p><strong>Price:</strong> $${item.price}</p>
410
+ `;
411
+ });
412
+ </script>
413
+ ```
414
+
415
+ ### Complete Example
416
+
417
+ ```html
418
+ <!DOCTYPE html>
419
+ <html>
420
+ <head>
421
+ <style>
422
+ .demo-container {
423
+ padding: 2rem;
424
+ display: flex;
425
+ gap: 1rem;
426
+ flex-wrap: wrap;
427
+ }
428
+
429
+ .demo-container button {
430
+ padding: 0.5rem 1rem;
431
+ cursor: pointer;
432
+ }
433
+
434
+ snice-modal h2 {
435
+ margin: 0;
436
+ }
437
+
438
+ snice-modal [slot="footer"] {
439
+ display: flex;
440
+ gap: 0.5rem;
441
+ justify-content: flex-end;
442
+ }
443
+ </style>
444
+
445
+ <script type="module">
446
+ import 'snice/components/modal/snice-modal';
447
+
448
+ document.addEventListener('DOMContentLoaded', () => {
449
+ // Setup all modals
450
+ document.querySelectorAll('[data-modal-trigger]').forEach(btn => {
451
+ const modalId = btn.getAttribute('data-modal-trigger');
452
+ const modal = document.querySelector(`#${modalId}`);
453
+
454
+ btn.addEventListener('click', () => modal?.show());
455
+ });
456
+
457
+ // Setup close buttons
458
+ document.querySelectorAll('[data-modal-close]').forEach(btn => {
459
+ btn.addEventListener('click', () => {
460
+ btn.closest('snice-modal')?.close();
461
+ });
462
+ });
463
+ });
464
+ </script>
465
+ </head>
466
+ <body>
467
+ <div class="demo-container">
468
+ <button data-modal-trigger="modal1">Small Modal</button>
469
+ <button data-modal-trigger="modal2">Medium Modal</button>
470
+ <button data-modal-trigger="modal3">Large Modal</button>
471
+ <button data-modal-trigger="modal4">Fullscreen Modal</button>
472
+ </div>
473
+
474
+ <snice-modal id="modal1" size="small" label="Small Modal">
475
+ <div slot="header"><h2>Small Modal</h2></div>
476
+ <p>This is a small modal with minimal content.</p>
477
+ <div slot="footer">
478
+ <button data-modal-close>Close</button>
479
+ </div>
480
+ </snice-modal>
481
+
482
+ <snice-modal id="modal2" size="medium" label="Medium Modal">
483
+ <div slot="header"><h2>Medium Modal</h2></div>
484
+ <p>This is a medium-sized modal with more content.</p>
485
+ <p>It can hold paragraphs, images, forms, and more.</p>
486
+ <div slot="footer">
487
+ <button data-modal-close>Cancel</button>
488
+ <button data-modal-close>OK</button>
489
+ </div>
490
+ </snice-modal>
491
+
492
+ <snice-modal id="modal3" size="large" label="Large Modal">
493
+ <div slot="header"><h2>Large Modal</h2></div>
494
+ <p>This is a large modal for displaying lots of content.</p>
495
+ <p>Perfect for detailed forms or extensive information.</p>
496
+ <div slot="footer">
497
+ <button data-modal-close>Close</button>
498
+ </div>
499
+ </snice-modal>
500
+
501
+ <snice-modal id="modal4" size="fullscreen" label="Fullscreen Modal">
502
+ <div slot="header"><h2>Fullscreen Modal</h2></div>
503
+ <p>This modal takes up the entire viewport.</p>
504
+ <p>Ideal for immersive experiences or complex workflows.</p>
505
+ <div slot="footer">
506
+ <button data-modal-close>Close</button>
507
+ </div>
508
+ </snice-modal>
509
+ </body>
510
+ </html>
511
+ ```
512
+
513
+ ## Accessibility
514
+
515
+ The modal component includes comprehensive accessibility features:
516
+
517
+ - `role="dialog"` on the modal container
518
+ - `aria-modal="true"` to indicate modal behavior
519
+ - `aria-label` for screen reader context
520
+ - `aria-hidden` reflects visibility state
521
+ - Focus trap keeps keyboard navigation within modal
522
+ - Focus restoration returns focus to trigger element on close
523
+ - Escape key support for closing
524
+ - Close button is keyboard accessible
525
+
526
+ ### Keyboard Support
527
+
528
+ - **Escape**: Close modal (unless `noEscapeDismiss` is true)
529
+ - **Tab**: Cycle through focusable elements within modal (trapped)
530
+ - **Shift + Tab**: Reverse cycle through focusable elements
531
+
532
+ ## Behavior
533
+
534
+ ### Focus Management
535
+
536
+ When a modal opens:
537
+ 1. Current focus is stored
538
+ 2. Body scroll is locked
539
+ 3. Focus moves to first focusable element in modal
540
+ 4. Tab navigation is trapped within the modal
541
+
542
+ When a modal closes:
543
+ 1. Body scroll is restored
544
+ 2. Focus returns to the previously focused element
545
+
546
+ ### Dismissal
547
+
548
+ By default, modals can be dismissed by:
549
+ - Clicking the close button
550
+ - Clicking the backdrop
551
+ - Pressing Escape
552
+
553
+ This behavior can be customized with `noBackdropDismiss`, `noEscapeDismiss`, and `noCloseButton` properties.
554
+
555
+ ## Browser Support
556
+
557
+ - Modern browsers (Chrome, Firefox, Safari, Edge)
558
+ - Requires Custom Elements v1 and Shadow DOM support