snice 1.14.2 → 2.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 (311) hide show
  1. package/bin/templates/base/tsconfig.json +5 -4
  2. package/components/accordion/demo.html +403 -0
  3. package/components/alert/demo.html +445 -0
  4. package/components/avatar/demo.html +598 -0
  5. package/components/badge/demo.html +523 -0
  6. package/components/breadcrumbs/demo.html +404 -0
  7. package/components/button/demo.html +42 -0
  8. package/components/card/demo.html +525 -0
  9. package/components/checkbox/demo.html +253 -0
  10. package/components/chip/demo.html +383 -0
  11. package/components/date-picker/demo.html +191 -0
  12. package/components/divider/demo.html +233 -0
  13. package/components/drawer/demo.html +328 -0
  14. package/components/input/demo.html +303 -0
  15. package/components/input/test.html +77 -0
  16. package/components/layout/demo.html +538 -0
  17. package/components/login/demo-auth-controller.ts +185 -0
  18. package/components/login/demo.html +470 -0
  19. package/components/login/snice-login.ts +2 -2
  20. package/components/modal/demo.html +291 -0
  21. package/components/pagination/demo.html +395 -0
  22. package/components/progress/demo.html +510 -0
  23. package/components/radio/demo.html +287 -0
  24. package/components/select/demo.html +511 -0
  25. package/components/skeleton/demo.html +514 -0
  26. package/components/switch/demo.html +284 -0
  27. package/components/table/demo-table-controller.ts +100 -0
  28. package/components/table/demo.html +480 -0
  29. package/components/table/snice-table.ts +2 -2
  30. package/components/tabs/demo.html +487 -0
  31. package/components/toast/demo.html +329 -0
  32. package/components/tooltip/demo.html +350 -0
  33. package/dist/index.cjs +441 -329
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.cjs.min.map +1 -1
  36. package/dist/index.esm.js +441 -329
  37. package/dist/index.esm.js.map +1 -1
  38. package/dist/index.esm.min.js +3 -3
  39. package/dist/index.esm.min.js.map +1 -1
  40. package/dist/index.iife.js +441 -329
  41. package/dist/index.iife.js.map +1 -1
  42. package/dist/index.iife.min.js +3 -3
  43. package/dist/index.iife.min.js.map +1 -1
  44. package/dist/symbols.esm.js +1 -1
  45. package/dist/transitions.esm.js +1 -1
  46. package/dist/types/controller.d.ts +1 -1
  47. package/dist/types/element.d.ts +10 -10
  48. package/dist/types/events.d.ts +2 -2
  49. package/dist/types/index.d.ts +1 -1
  50. package/dist/types/observe.d.ts +1 -1
  51. package/dist/types/request-response.d.ts +2 -3
  52. package/dist/types/router.d.ts +1 -1
  53. package/package.json +9 -10
  54. package/dist/components/accordion/snice-accordion-item.d.ts +0 -25
  55. package/dist/components/accordion/snice-accordion-item.js +0 -260
  56. package/dist/components/accordion/snice-accordion-item.js.map +0 -1
  57. package/dist/components/accordion/snice-accordion.d.ts +0 -28
  58. package/dist/components/accordion/snice-accordion.js +0 -221
  59. package/dist/components/accordion/snice-accordion.js.map +0 -1
  60. package/dist/components/accordion/snice-accordion.types.d.ts +0 -29
  61. package/dist/components/accordion/snice-accordion.types.js +0 -2
  62. package/dist/components/accordion/snice-accordion.types.js.map +0 -1
  63. package/dist/components/alert/snice-alert.d.ts +0 -26
  64. package/dist/components/alert/snice-alert.js +0 -191
  65. package/dist/components/alert/snice-alert.js.map +0 -1
  66. package/dist/components/alert/snice-alert.types.d.ts +0 -11
  67. package/dist/components/alert/snice-alert.types.js +0 -2
  68. package/dist/components/alert/snice-alert.types.js.map +0 -1
  69. package/dist/components/avatar/snice-avatar.d.ts +0 -24
  70. package/dist/components/avatar/snice-avatar.js +0 -177
  71. package/dist/components/avatar/snice-avatar.js.map +0 -1
  72. package/dist/components/avatar/snice-avatar.types.d.ts +0 -12
  73. package/dist/components/avatar/snice-avatar.types.js +0 -2
  74. package/dist/components/avatar/snice-avatar.types.js.map +0 -1
  75. package/dist/components/badge/snice-badge.d.ts +0 -25
  76. package/dist/components/badge/snice-badge.js +0 -157
  77. package/dist/components/badge/snice-badge.js.map +0 -1
  78. package/dist/components/badge/snice-badge.types.d.ts +0 -15
  79. package/dist/components/badge/snice-badge.types.js +0 -2
  80. package/dist/components/badge/snice-badge.types.js.map +0 -1
  81. package/dist/components/breadcrumbs/snice-breadcrumbs.d.ts +0 -27
  82. package/dist/components/breadcrumbs/snice-breadcrumbs.js +0 -212
  83. package/dist/components/breadcrumbs/snice-breadcrumbs.js.map +0 -1
  84. package/dist/components/breadcrumbs/snice-breadcrumbs.types.d.ts +0 -23
  85. package/dist/components/breadcrumbs/snice-breadcrumbs.types.js +0 -2
  86. package/dist/components/breadcrumbs/snice-breadcrumbs.types.js.map +0 -1
  87. package/dist/components/breadcrumbs/snice-crumb.d.ts +0 -9
  88. package/dist/components/breadcrumbs/snice-crumb.js +0 -50
  89. package/dist/components/breadcrumbs/snice-crumb.js.map +0 -1
  90. package/dist/components/button/snice-button.d.ts +0 -32
  91. package/dist/components/button/snice-button.js +0 -212
  92. package/dist/components/button/snice-button.js.map +0 -1
  93. package/dist/components/button/snice-button.types.d.ts +0 -23
  94. package/dist/components/button/snice-button.types.js +0 -2
  95. package/dist/components/button/snice-button.types.js.map +0 -1
  96. package/dist/components/card/snice-card.d.ts +0 -19
  97. package/dist/components/card/snice-card.js +0 -132
  98. package/dist/components/card/snice-card.js.map +0 -1
  99. package/dist/components/card/snice-card.types.d.ts +0 -9
  100. package/dist/components/card/snice-card.types.js +0 -2
  101. package/dist/components/card/snice-card.types.js.map +0 -1
  102. package/dist/components/checkbox/snice-checkbox.d.ts +0 -34
  103. package/dist/components/checkbox/snice-checkbox.js +0 -289
  104. package/dist/components/checkbox/snice-checkbox.js.map +0 -1
  105. package/dist/components/checkbox/snice-checkbox.types.d.ts +0 -20
  106. package/dist/components/checkbox/snice-checkbox.types.js +0 -2
  107. package/dist/components/checkbox/snice-checkbox.types.js.map +0 -1
  108. package/dist/components/chip/snice-chip.d.ts +0 -28
  109. package/dist/components/chip/snice-chip.js +0 -203
  110. package/dist/components/chip/snice-chip.js.map +0 -1
  111. package/dist/components/chip/snice-chip.types.d.ts +0 -14
  112. package/dist/components/chip/snice-chip.types.js +0 -2
  113. package/dist/components/chip/snice-chip.types.js.map +0 -1
  114. package/dist/components/date-picker/snice-date-picker.d.ts +0 -82
  115. package/dist/components/date-picker/snice-date-picker.js +0 -880
  116. package/dist/components/date-picker/snice-date-picker.js.map +0 -1
  117. package/dist/components/date-picker/snice-date-picker.types.d.ts +0 -71
  118. package/dist/components/date-picker/snice-date-picker.types.js +0 -2
  119. package/dist/components/date-picker/snice-date-picker.types.js.map +0 -1
  120. package/dist/components/divider/snice-divider.d.ts +0 -17
  121. package/dist/components/divider/snice-divider.js +0 -111
  122. package/dist/components/divider/snice-divider.js.map +0 -1
  123. package/dist/components/divider/snice-divider.types.d.ts +0 -14
  124. package/dist/components/divider/snice-divider.types.js +0 -2
  125. package/dist/components/divider/snice-divider.types.js.map +0 -1
  126. package/dist/components/drawer/snice-drawer.d.ts +0 -37
  127. package/dist/components/drawer/snice-drawer.js +0 -335
  128. package/dist/components/drawer/snice-drawer.js.map +0 -1
  129. package/dist/components/drawer/snice-drawer.types.d.ts +0 -16
  130. package/dist/components/drawer/snice-drawer.types.js +0 -2
  131. package/dist/components/drawer/snice-drawer.types.js.map +0 -1
  132. package/dist/components/input/snice-input.d.ts +0 -65
  133. package/dist/components/input/snice-input.js +0 -603
  134. package/dist/components/input/snice-input.js.map +0 -1
  135. package/dist/components/input/snice-input.types.d.ts +0 -53
  136. package/dist/components/input/snice-input.types.js +0 -2
  137. package/dist/components/input/snice-input.types.js.map +0 -1
  138. package/dist/components/layout/snice-layout-blog.d.ts +0 -4
  139. package/dist/components/layout/snice-layout-blog.js +0 -56
  140. package/dist/components/layout/snice-layout-blog.js.map +0 -1
  141. package/dist/components/layout/snice-layout-card.d.ts +0 -6
  142. package/dist/components/layout/snice-layout-card.js +0 -53
  143. package/dist/components/layout/snice-layout-card.js.map +0 -1
  144. package/dist/components/layout/snice-layout-centered.d.ts +0 -5
  145. package/dist/components/layout/snice-layout-centered.js +0 -38
  146. package/dist/components/layout/snice-layout-centered.js.map +0 -1
  147. package/dist/components/layout/snice-layout-dashboard.d.ts +0 -4
  148. package/dist/components/layout/snice-layout-dashboard.js +0 -53
  149. package/dist/components/layout/snice-layout-dashboard.js.map +0 -1
  150. package/dist/components/layout/snice-layout-fullscreen.d.ts +0 -5
  151. package/dist/components/layout/snice-layout-fullscreen.js +0 -50
  152. package/dist/components/layout/snice-layout-fullscreen.js.map +0 -1
  153. package/dist/components/layout/snice-layout-landing.d.ts +0 -4
  154. package/dist/components/layout/snice-layout-landing.js +0 -55
  155. package/dist/components/layout/snice-layout-landing.js.map +0 -1
  156. package/dist/components/layout/snice-layout-minimal.d.ts +0 -4
  157. package/dist/components/layout/snice-layout-minimal.js +0 -27
  158. package/dist/components/layout/snice-layout-minimal.js.map +0 -1
  159. package/dist/components/layout/snice-layout-sidebar.d.ts +0 -5
  160. package/dist/components/layout/snice-layout-sidebar.js +0 -64
  161. package/dist/components/layout/snice-layout-sidebar.js.map +0 -1
  162. package/dist/components/layout/snice-layout-split.d.ts +0 -6
  163. package/dist/components/layout/snice-layout-split.js +0 -47
  164. package/dist/components/layout/snice-layout-split.js.map +0 -1
  165. package/dist/components/layout/snice-layout.d.ts +0 -4
  166. package/dist/components/layout/snice-layout.js +0 -43
  167. package/dist/components/layout/snice-layout.js.map +0 -1
  168. package/dist/components/layout/snice-layout.types.d.ts +0 -3
  169. package/dist/components/layout/snice-layout.types.js +0 -2
  170. package/dist/components/layout/snice-layout.types.js.map +0 -1
  171. package/dist/components/login/snice-login.d.ts +0 -45
  172. package/dist/components/login/snice-login.js +0 -385
  173. package/dist/components/login/snice-login.js.map +0 -1
  174. package/dist/components/login/snice-login.types.d.ts +0 -31
  175. package/dist/components/login/snice-login.types.js +0 -2
  176. package/dist/components/login/snice-login.types.js.map +0 -1
  177. package/dist/components/modal/snice-modal.d.ts +0 -32
  178. package/dist/components/modal/snice-modal.js +0 -288
  179. package/dist/components/modal/snice-modal.js.map +0 -1
  180. package/dist/components/modal/snice-modal.types.d.ts +0 -18
  181. package/dist/components/modal/snice-modal.types.js +0 -2
  182. package/dist/components/modal/snice-modal.types.js.map +0 -1
  183. package/dist/components/pagination/snice-pagination.d.ts +0 -26
  184. package/dist/components/pagination/snice-pagination.js +0 -373
  185. package/dist/components/pagination/snice-pagination.js.map +0 -1
  186. package/dist/components/pagination/snice-pagination.types.d.ts +0 -18
  187. package/dist/components/pagination/snice-pagination.types.js +0 -2
  188. package/dist/components/pagination/snice-pagination.types.js.map +0 -1
  189. package/dist/components/progress/snice-progress.d.ts +0 -35
  190. package/dist/components/progress/snice-progress.js +0 -295
  191. package/dist/components/progress/snice-progress.js.map +0 -1
  192. package/dist/components/progress/snice-progress.types.d.ts +0 -18
  193. package/dist/components/progress/snice-progress.types.js +0 -2
  194. package/dist/components/progress/snice-progress.types.js.map +0 -1
  195. package/dist/components/radio/snice-radio.d.ts +0 -33
  196. package/dist/components/radio/snice-radio.js +0 -286
  197. package/dist/components/radio/snice-radio.js.map +0 -1
  198. package/dist/components/radio/snice-radio.types.d.ts +0 -19
  199. package/dist/components/radio/snice-radio.types.js +0 -2
  200. package/dist/components/radio/snice-radio.types.js.map +0 -1
  201. package/dist/components/select/snice-option.d.ts +0 -17
  202. package/dist/components/select/snice-option.js +0 -77
  203. package/dist/components/select/snice-option.js.map +0 -1
  204. package/dist/components/select/snice-option.types.d.ts +0 -14
  205. package/dist/components/select/snice-option.types.js +0 -2
  206. package/dist/components/select/snice-option.types.js.map +0 -1
  207. package/dist/components/select/snice-select.d.ts +0 -89
  208. package/dist/components/select/snice-select.js +0 -900
  209. package/dist/components/select/snice-select.js.map +0 -1
  210. package/dist/components/select/snice-select.types.d.ts +0 -49
  211. package/dist/components/select/snice-select.types.js +0 -2
  212. package/dist/components/select/snice-select.types.js.map +0 -1
  213. package/dist/components/skeleton/snice-skeleton.d.ts +0 -16
  214. package/dist/components/skeleton/snice-skeleton.js +0 -159
  215. package/dist/components/skeleton/snice-skeleton.js.map +0 -1
  216. package/dist/components/skeleton/snice-skeleton.types.d.ts +0 -10
  217. package/dist/components/skeleton/snice-skeleton.types.js +0 -2
  218. package/dist/components/skeleton/snice-skeleton.types.js.map +0 -1
  219. package/dist/components/switch/snice-switch.d.ts +0 -38
  220. package/dist/components/switch/snice-switch.js +0 -309
  221. package/dist/components/switch/snice-switch.js.map +0 -1
  222. package/dist/components/switch/snice-switch.types.d.ts +0 -21
  223. package/dist/components/switch/snice-switch.types.js +0 -2
  224. package/dist/components/switch/snice-switch.types.js.map +0 -1
  225. package/dist/components/symbols.d.ts +0 -1
  226. package/dist/components/symbols.js +0 -20
  227. package/dist/components/symbols.js.map +0 -1
  228. package/dist/components/table/snice-cell-boolean.d.ts +0 -21
  229. package/dist/components/table/snice-cell-boolean.js +0 -152
  230. package/dist/components/table/snice-cell-boolean.js.map +0 -1
  231. package/dist/components/table/snice-cell-date.d.ts +0 -24
  232. package/dist/components/table/snice-cell-date.js +0 -240
  233. package/dist/components/table/snice-cell-date.js.map +0 -1
  234. package/dist/components/table/snice-cell-duration.d.ts +0 -16
  235. package/dist/components/table/snice-cell-duration.js +0 -123
  236. package/dist/components/table/snice-cell-duration.js.map +0 -1
  237. package/dist/components/table/snice-cell-filesize.d.ts +0 -16
  238. package/dist/components/table/snice-cell-filesize.js +0 -119
  239. package/dist/components/table/snice-cell-filesize.js.map +0 -1
  240. package/dist/components/table/snice-cell-number.d.ts +0 -23
  241. package/dist/components/table/snice-cell-number.js +0 -202
  242. package/dist/components/table/snice-cell-number.js.map +0 -1
  243. package/dist/components/table/snice-cell-progress.d.ts +0 -17
  244. package/dist/components/table/snice-cell-progress.js +0 -114
  245. package/dist/components/table/snice-cell-progress.js.map +0 -1
  246. package/dist/components/table/snice-cell-rating.d.ts +0 -17
  247. package/dist/components/table/snice-cell-rating.js +0 -113
  248. package/dist/components/table/snice-cell-rating.js.map +0 -1
  249. package/dist/components/table/snice-cell-sparkline.d.ts +0 -29
  250. package/dist/components/table/snice-cell-sparkline.js +0 -290
  251. package/dist/components/table/snice-cell-sparkline.js.map +0 -1
  252. package/dist/components/table/snice-cell-text.d.ts +0 -19
  253. package/dist/components/table/snice-cell-text.js +0 -153
  254. package/dist/components/table/snice-cell-text.js.map +0 -1
  255. package/dist/components/table/snice-cell.d.ts +0 -32
  256. package/dist/components/table/snice-cell.js +0 -451
  257. package/dist/components/table/snice-cell.js.map +0 -1
  258. package/dist/components/table/snice-column.d.ts +0 -62
  259. package/dist/components/table/snice-column.js +0 -440
  260. package/dist/components/table/snice-column.js.map +0 -1
  261. package/dist/components/table/snice-header.d.ts +0 -33
  262. package/dist/components/table/snice-header.js +0 -303
  263. package/dist/components/table/snice-header.js.map +0 -1
  264. package/dist/components/table/snice-progress.d.ts +0 -10
  265. package/dist/components/table/snice-progress.js +0 -91
  266. package/dist/components/table/snice-progress.js.map +0 -1
  267. package/dist/components/table/snice-rating.d.ts +0 -9
  268. package/dist/components/table/snice-rating.js +0 -68
  269. package/dist/components/table/snice-rating.js.map +0 -1
  270. package/dist/components/table/snice-row.d.ts +0 -43
  271. package/dist/components/table/snice-row.js +0 -365
  272. package/dist/components/table/snice-row.js.map +0 -1
  273. package/dist/components/table/snice-table.d.ts +0 -69
  274. package/dist/components/table/snice-table.js +0 -814
  275. package/dist/components/table/snice-table.js.map +0 -1
  276. package/dist/components/table/snice-table.types.d.ts +0 -137
  277. package/dist/components/table/snice-table.types.js +0 -2
  278. package/dist/components/table/snice-table.types.js.map +0 -1
  279. package/dist/components/tabs/snice-tab-panel.d.ts +0 -12
  280. package/dist/components/tabs/snice-tab-panel.js +0 -78
  281. package/dist/components/tabs/snice-tab-panel.js.map +0 -1
  282. package/dist/components/tabs/snice-tab.d.ts +0 -13
  283. package/dist/components/tabs/snice-tab.js +0 -90
  284. package/dist/components/tabs/snice-tab.js.map +0 -1
  285. package/dist/components/tabs/snice-tabs.d.ts +0 -34
  286. package/dist/components/tabs/snice-tabs.js +0 -367
  287. package/dist/components/tabs/snice-tabs.js.map +0 -1
  288. package/dist/components/tabs/snice-tabs.types.d.ts +0 -23
  289. package/dist/components/tabs/snice-tabs.types.js +0 -2
  290. package/dist/components/tabs/snice-tabs.types.js.map +0 -1
  291. package/dist/components/toast/snice-toast-container.d.ts +0 -25
  292. package/dist/components/toast/snice-toast-container.js +0 -251
  293. package/dist/components/toast/snice-toast-container.js.map +0 -1
  294. package/dist/components/toast/snice-toast.d.ts +0 -23
  295. package/dist/components/toast/snice-toast.js +0 -316
  296. package/dist/components/toast/snice-toast.js.map +0 -1
  297. package/dist/components/toast/snice-toast.types.d.ts +0 -30
  298. package/dist/components/toast/snice-toast.types.js +0 -2
  299. package/dist/components/toast/snice-toast.types.js.map +0 -1
  300. package/dist/components/tooltip/snice-tooltip.d.ts +0 -50
  301. package/dist/components/tooltip/snice-tooltip.js +0 -656
  302. package/dist/components/tooltip/snice-tooltip.js.map +0 -1
  303. package/dist/components/tooltip/snice-tooltip.types.d.ts +0 -18
  304. package/dist/components/tooltip/snice-tooltip.types.js +0 -2
  305. package/dist/components/tooltip/snice-tooltip.types.js.map +0 -1
  306. package/dist/components/transitions.d.ts +0 -11
  307. package/dist/components/transitions.js +0 -69
  308. package/dist/components/transitions.js.map +0 -1
  309. package/dist/index.cjs.min +0 -15
  310. package/dist/symbols.cjs +0 -103
  311. package/dist/transitions.cjs +0 -219
@@ -0,0 +1,185 @@
1
+ import { controller, respond } from 'snice';
2
+ import type { LoginCredentials, LoginResult } from './snice-login.types';
3
+
4
+ interface AuthUser {
5
+ id: string;
6
+ username: string;
7
+ email: string;
8
+ role: string;
9
+ lastLogin?: string;
10
+ }
11
+
12
+ @controller('demo-auth-controller')
13
+ export class DemoAuthController {
14
+ element!: HTMLElement;
15
+
16
+ // Mock user database for demo purposes
17
+ private mockUsers: AuthUser[] = [
18
+ {
19
+ id: '1',
20
+ username: 'demo',
21
+ email: 'demo@example.com',
22
+ role: 'user'
23
+ },
24
+ {
25
+ id: '2',
26
+ username: 'admin',
27
+ email: 'admin@example.com',
28
+ role: 'admin'
29
+ },
30
+ {
31
+ id: '3',
32
+ username: 'test',
33
+ email: 'test@example.com',
34
+ role: 'user'
35
+ }
36
+ ];
37
+
38
+ // Valid passwords for demo (in real app, these would be hashed)
39
+ private mockPasswords: Record<string, string> = {
40
+ 'demo': 'password',
41
+ 'admin': 'admin123',
42
+ 'test': 'test123'
43
+ };
44
+
45
+ async attach(element: HTMLElement) {
46
+ this.element = element;
47
+ console.log('Demo Auth Controller attached to', element.tagName);
48
+ }
49
+
50
+ async detach(element: HTMLElement) {
51
+ console.log('Demo Auth Controller detached from', element.tagName);
52
+ }
53
+
54
+ @respond('login-user')
55
+ async handleLogin(credentials: LoginCredentials): Promise<LoginResult> {
56
+ console.log('Auth controller handling login request:', { username: credentials.username });
57
+
58
+ // Simulate network delay
59
+ await this.delay(200 + Math.random() * 200);
60
+
61
+ // Validate credentials
62
+ const result = await this.authenticateUser(credentials);
63
+
64
+ // Store successful login
65
+ if (result.success && result.user) {
66
+ this.storeUserSession(result.user, result.token!);
67
+ }
68
+
69
+ return result;
70
+ }
71
+
72
+ private async authenticateUser(credentials: LoginCredentials): Promise<LoginResult> {
73
+ const { username, password } = credentials;
74
+
75
+ // Basic validation
76
+ if (!username || !password) {
77
+ return {
78
+ success: false,
79
+ error: 'Username and password are required'
80
+ };
81
+ }
82
+
83
+ // Find user
84
+ const user = this.mockUsers.find(u => u.username.toLowerCase() === username.toLowerCase());
85
+
86
+ if (!user) {
87
+ return {
88
+ success: false,
89
+ error: 'Invalid username or password'
90
+ };
91
+ }
92
+
93
+ // Check password
94
+ const expectedPassword = this.mockPasswords[user.username];
95
+ if (password !== expectedPassword) {
96
+ return {
97
+ success: false,
98
+ error: 'Invalid username or password'
99
+ };
100
+ }
101
+
102
+ // Simulate random authentication failure (10% chance)
103
+ if (Math.random() < 0.1) {
104
+ return {
105
+ success: false,
106
+ error: 'Authentication service temporarily unavailable'
107
+ };
108
+ }
109
+
110
+ // Generate mock JWT token
111
+ const token = this.generateMockToken(user);
112
+
113
+ // Update last login
114
+ user.lastLogin = new Date().toISOString();
115
+
116
+ return {
117
+ success: true,
118
+ token,
119
+ user: {
120
+ id: user.id,
121
+ username: user.username,
122
+ email: user.email
123
+ }
124
+ };
125
+ }
126
+
127
+ private generateMockToken(user: AuthUser): string {
128
+ // This is just a demo token - in real apps use proper JWT libraries
129
+ const header = btoa(JSON.stringify({ alg: 'HS256', typ: 'JWT' }));
130
+ const payload = btoa(JSON.stringify({
131
+ sub: user.id,
132
+ username: user.username,
133
+ email: user.email,
134
+ role: user.role,
135
+ iat: Math.floor(Date.now() / 1000),
136
+ exp: Math.floor(Date.now() / 1000) + (60 * 60 * 24) // 24 hours
137
+ }));
138
+ const signature = btoa('demo-signature-' + Math.random().toString(36));
139
+
140
+ return `${header}.${payload}.${signature}`;
141
+ }
142
+
143
+ private storeUserSession(user: AuthUser, token: string): void {
144
+ // In a real app, you might store this in localStorage, sessionStorage, or cookies
145
+ const session = {
146
+ user: {
147
+ id: user.id,
148
+ username: user.username,
149
+ email: user.email
150
+ },
151
+ token,
152
+ loginTime: new Date().toISOString()
153
+ };
154
+
155
+ // Store in sessionStorage for demo
156
+ sessionStorage.setItem('demoUserSession', JSON.stringify(session));
157
+
158
+ console.log('User session stored:', session);
159
+ }
160
+
161
+ private delay(ms: number): Promise<void> {
162
+ return new Promise(resolve => setTimeout(resolve, ms));
163
+ }
164
+
165
+ // Helper method to get current session (for other components to use)
166
+ getCurrentSession(): { user: AuthUser; token: string } | null {
167
+ try {
168
+ const sessionData = sessionStorage.getItem('demoUserSession');
169
+ return sessionData ? JSON.parse(sessionData) : null;
170
+ } catch {
171
+ return null;
172
+ }
173
+ }
174
+
175
+ // Helper method to logout
176
+ logout(): void {
177
+ sessionStorage.removeItem('demoUserSession');
178
+ console.log('User logged out');
179
+ }
180
+
181
+ // Helper method to check if user is authenticated
182
+ isAuthenticated(): boolean {
183
+ return this.getCurrentSession() !== null;
184
+ }
185
+ }
@@ -0,0 +1,470 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Snice Login Component Demo</title>
7
+ <link rel="stylesheet" href="../theme/theme.css">
8
+ <style>
9
+ body {
10
+ font-family: var(--snice-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif);
11
+ margin: 0;
12
+ padding: var(--snice-spacing-xl, 2rem);
13
+ background: var(--snice-color-background-secondary, rgb(250 250 250));
14
+ color: var(--snice-color-text, rgb(23 23 23));
15
+ min-height: 100vh;
16
+ }
17
+
18
+ .demo-container {
19
+ max-width: 1200px;
20
+ margin: 0 auto;
21
+ }
22
+
23
+ .demo-header {
24
+ text-align: center;
25
+ margin-bottom: var(--snice-spacing-3xl, 4rem);
26
+ }
27
+
28
+ .demo-header h1 {
29
+ color: var(--snice-color-text, rgb(23 23 23));
30
+ margin-bottom: var(--snice-spacing-xs, 0.5rem);
31
+ font-size: var(--snice-font-size-3xl, 1.875rem);
32
+ font-weight: var(--snice-font-weight-bold, 700);
33
+ }
34
+
35
+ .demo-header p {
36
+ color: var(--snice-color-text-secondary, rgb(82 82 82));
37
+ font-size: var(--snice-font-size-lg, 1.125rem);
38
+ }
39
+
40
+ .demo-grid {
41
+ display: grid;
42
+ grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
43
+ gap: var(--snice-spacing-xl, 2rem);
44
+ margin-bottom: var(--snice-spacing-3xl, 4rem);
45
+ }
46
+
47
+ .demo-card {
48
+ background: var(--snice-color-background, rgb(255 255 255));
49
+ border-radius: var(--snice-border-radius-lg, 0.5rem);
50
+ border: 1px solid var(--snice-color-border, rgb(226 226 226));
51
+ padding: var(--snice-spacing-xl, 2rem);
52
+ box-shadow: var(--snice-shadow-md, 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1));
53
+ }
54
+
55
+ .demo-card h3 {
56
+ margin: 0 0 var(--snice-spacing-md, 1rem) 0;
57
+ color: var(--snice-color-text, rgb(23 23 23));
58
+ font-size: var(--snice-font-size-xl, 1.25rem);
59
+ font-weight: var(--snice-font-weight-semibold, 600);
60
+ }
61
+
62
+ .demo-card p {
63
+ margin: 0 0 var(--snice-spacing-lg, 1.5rem) 0;
64
+ color: var(--snice-color-text-secondary, rgb(82 82 82));
65
+ font-size: var(--snice-font-size-sm, 0.875rem);
66
+ }
67
+
68
+ .demo-controls {
69
+ background: var(--snice-color-background, rgb(255 255 255));
70
+ border-radius: var(--snice-border-radius-lg, 0.5rem);
71
+ border: 1px solid var(--snice-color-border, rgb(226 226 226));
72
+ padding: var(--snice-spacing-xl, 2rem);
73
+ box-shadow: var(--snice-shadow-md, 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1));
74
+ margin-bottom: var(--snice-spacing-xl, 2rem);
75
+ }
76
+
77
+ .demo-controls h3 {
78
+ margin: 0 0 var(--snice-spacing-md, 1rem) 0;
79
+ color: var(--snice-color-text, rgb(23 23 23));
80
+ font-size: var(--snice-font-size-xl, 1.25rem);
81
+ font-weight: var(--snice-font-weight-semibold, 600);
82
+ }
83
+
84
+ .controls-grid {
85
+ display: grid;
86
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
87
+ gap: var(--snice-spacing-md, 1rem);
88
+ }
89
+
90
+ .control-group {
91
+ display: flex;
92
+ flex-direction: column;
93
+ gap: var(--snice-spacing-xs, 0.5rem);
94
+ }
95
+
96
+ .control-group label {
97
+ font-size: var(--snice-font-size-sm, 0.875rem);
98
+ font-weight: var(--snice-font-weight-medium, 500);
99
+ color: var(--snice-color-text, rgb(23 23 23));
100
+ }
101
+
102
+ .control-group select,
103
+ .control-group input[type="text"] {
104
+ padding: var(--snice-spacing-sm, 0.75rem);
105
+ border: 1px solid var(--snice-color-border, rgb(226 226 226));
106
+ border-radius: var(--snice-border-radius-md, 0.25rem);
107
+ font-size: var(--snice-font-size-sm, 0.875rem);
108
+ font-family: var(--snice-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif);
109
+ background: var(--snice-color-background, rgb(255 255 255));
110
+ color: var(--snice-color-text, rgb(23 23 23));
111
+ transition: border-color var(--snice-transition-fast, 150ms) ease;
112
+ }
113
+
114
+ .control-group select:focus,
115
+ .control-group input[type="text"]:focus {
116
+ outline: none;
117
+ border-color: var(--snice-color-border-focus, rgb(59 130 246));
118
+ box-shadow: 0 0 0 var(--snice-focus-ring-width, 2px) var(--snice-focus-ring-color, rgb(59 130 246 / 0.5));
119
+ }
120
+
121
+ .control-group button {
122
+ padding: var(--snice-spacing-sm, 0.75rem) var(--snice-spacing-md, 1rem);
123
+ background: var(--snice-color-primary, rgb(37 99 235));
124
+ color: var(--snice-color-text-inverse, rgb(250 250 250));
125
+ border: 1px solid var(--snice-color-primary, rgb(37 99 235));
126
+ border-radius: var(--snice-border-radius-md, 0.25rem);
127
+ cursor: pointer;
128
+ font-size: var(--snice-font-size-sm, 0.875rem);
129
+ font-family: var(--snice-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif);
130
+ font-weight: var(--snice-font-weight-medium, 500);
131
+ transition: background-color var(--snice-transition-fast, 150ms) ease;
132
+ }
133
+
134
+ .control-group button:hover {
135
+ background: var(--snice-color-primary-hover, rgb(29 78 216));
136
+ border-color: var(--snice-color-primary-hover, rgb(29 78 216));
137
+ }
138
+
139
+ .demo-events {
140
+ background: var(--snice-color-background, rgb(255 255 255));
141
+ border-radius: var(--snice-border-radius-lg, 0.5rem);
142
+ border: 1px solid var(--snice-color-border, rgb(226 226 226));
143
+ padding: var(--snice-spacing-xl, 2rem);
144
+ box-shadow: var(--snice-shadow-md, 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1));
145
+ }
146
+
147
+ .demo-events h3 {
148
+ margin: 0 0 var(--snice-spacing-md, 1rem) 0;
149
+ color: var(--snice-color-text, rgb(23 23 23));
150
+ font-size: var(--snice-font-size-xl, 1.25rem);
151
+ font-weight: var(--snice-font-weight-semibold, 600);
152
+ }
153
+
154
+ .event-log {
155
+ background: var(--snice-color-background-secondary, rgb(250 250 250));
156
+ border: 1px solid var(--snice-color-border, rgb(226 226 226));
157
+ border-radius: var(--snice-border-radius-md, 0.25rem);
158
+ padding: var(--snice-spacing-md, 1rem);
159
+ max-height: 300px;
160
+ overflow-y: auto;
161
+ font-family: var(--snice-font-family-mono, SFMono-Regular, Consolas, 'Liberation Mono', Menlo, monospace);
162
+ font-size: var(--snice-font-size-xs, 0.75rem);
163
+ }
164
+
165
+ .event-entry {
166
+ margin-bottom: var(--snice-spacing-xs, 0.5rem);
167
+ padding: var(--snice-spacing-2xs, 0.25rem);
168
+ border-radius: var(--snice-border-radius-sm, 0.125rem);
169
+ }
170
+
171
+ .event-success {
172
+ background: rgb(var(--snice-color-green-100, 220 252 231));
173
+ color: rgb(var(--snice-color-green-800, 22 101 52));
174
+ }
175
+
176
+ .event-error {
177
+ background: rgb(var(--snice-color-red-100, 254 226 226));
178
+ color: rgb(var(--snice-color-red-800, 153 27 27));
179
+ }
180
+
181
+ .event-info {
182
+ background: rgb(var(--snice-color-blue-100, 219 234 254));
183
+ color: rgb(var(--snice-color-blue-800, 30 64 175));
184
+ }
185
+
186
+ /* Custom styling for login components */
187
+ snice-login[slot="footer"] {
188
+ text-align: center;
189
+ color: var(--snice-color-text-secondary, rgb(82 82 82));
190
+ font-size: var(--snice-font-size-sm, 0.875rem);
191
+ }
192
+
193
+ .footer-text {
194
+ margin: var(--snice-spacing-xs, 0.5rem) 0;
195
+ }
196
+
197
+ .footer-link {
198
+ color: var(--snice-color-primary, rgb(37 99 235));
199
+ text-decoration: none;
200
+ transition: color var(--snice-transition-fast, 150ms) ease;
201
+ }
202
+
203
+ .footer-link:hover {
204
+ color: var(--snice-color-primary-hover, rgb(29 78 216));
205
+ text-decoration: underline;
206
+ }
207
+
208
+ @media (max-width: 768px) {
209
+ .demo-grid {
210
+ grid-template-columns: 1fr;
211
+ }
212
+
213
+ .controls-grid {
214
+ grid-template-columns: 1fr;
215
+ }
216
+ }
217
+ </style>
218
+ </head>
219
+ <body>
220
+ <div class="demo-container">
221
+ <div class="demo-header">
222
+ <h1>Snice Login Component Demo</h1>
223
+ <p>Interactive examples showcasing different variants, sizes, and configurations</p>
224
+ </div>
225
+
226
+ <div class="demo-controls">
227
+ <h3>Interactive Controls</h3>
228
+ <div class="controls-grid">
229
+ <div class="control-group">
230
+ <label for="variant-select">Variant</label>
231
+ <select id="variant-select">
232
+ <option value="default">Default</option>
233
+ <option value="card" selected>Card</option>
234
+ <option value="minimal">Minimal</option>
235
+ </select>
236
+ </div>
237
+
238
+ <div class="control-group">
239
+ <label for="size-select">Size</label>
240
+ <select id="size-select">
241
+ <option value="small">Small</option>
242
+ <option value="medium" selected>Medium</option>
243
+ <option value="large">Large</option>
244
+ </select>
245
+ </div>
246
+
247
+ <div class="control-group">
248
+ <label for="title-input">Title</label>
249
+ <input type="text" id="title-input" value="Welcome Back" />
250
+ </div>
251
+
252
+ <div class="control-group">
253
+ <label for="action-text-input">Action Text</label>
254
+ <input type="text" id="action-text-input" value="Sign In" />
255
+ </div>
256
+
257
+ <div class="control-group">
258
+ <label>
259
+ <input type="checkbox" id="show-remember" checked /> Show Remember Me
260
+ </label>
261
+ </div>
262
+
263
+ <div class="control-group">
264
+ <label>
265
+ <input type="checkbox" id="show-forgot" checked /> Show Forgot Password
266
+ </label>
267
+ </div>
268
+
269
+ <div class="control-group">
270
+ <label>
271
+ <input type="checkbox" id="disabled-toggle" /> Disabled
272
+ </label>
273
+ </div>
274
+
275
+ <div class="control-group">
276
+ <button id="simulate-error">Simulate Error</button>
277
+ </div>
278
+
279
+ <div class="control-group">
280
+ <button id="clear-log">Clear Event Log</button>
281
+ </div>
282
+ </div>
283
+ </div>
284
+
285
+ <div class="demo-grid">
286
+ <!-- Interactive Login -->
287
+ <div class="demo-card">
288
+ <h3>Interactive Login</h3>
289
+ <p>Use the controls above to modify this login component in real-time.</p>
290
+
291
+ <snice-login
292
+ id="interactive-login"
293
+ variant="card"
294
+ size="medium"
295
+ title="Welcome Back"
296
+ action-text="Sign In"
297
+ show-remember-me
298
+ show-forgot-password
299
+ controller="demo-auth-controller">
300
+
301
+ <p slot="subtitle">Please sign in to your account</p>
302
+
303
+ <div slot="footer">
304
+ <p class="footer-text">Don't have an account?</p>
305
+ <a href="#" class="footer-link">Sign up here</a>
306
+ </div>
307
+ </snice-login>
308
+ </div>
309
+
310
+ <!-- Card Variant Examples -->
311
+ <div class="demo-card">
312
+ <h3>Card Variant (Large)</h3>
313
+ <p>Login form presented in a card layout with shadow and border.</p>
314
+
315
+ <snice-login
316
+ variant="card"
317
+ size="large"
318
+ title="Admin Portal"
319
+ action-text="Access Portal"
320
+ controller="demo-auth-controller">
321
+
322
+ <p slot="subtitle">Administrator access required</p>
323
+ </snice-login>
324
+ </div>
325
+
326
+ <!-- Minimal Variant -->
327
+ <div class="demo-card">
328
+ <h3>Minimal Variant</h3>
329
+ <p>Clean, borderless login form perfect for embedding.</p>
330
+
331
+ <snice-login
332
+ variant="minimal"
333
+ size="small"
334
+ title="Quick Sign In"
335
+ action-text="Continue"
336
+ show-forgot-password="false"
337
+ controller="demo-auth-controller">
338
+
339
+ <p slot="subtitle">Enter your credentials</p>
340
+ </snice-login>
341
+ </div>
342
+
343
+ <!-- Default Variant -->
344
+ <div class="demo-card">
345
+ <h3>Default Variant</h3>
346
+ <p>Standard login form without additional styling.</p>
347
+
348
+ <snice-login
349
+ variant="default"
350
+ size="medium"
351
+ title="User Login"
352
+ action-text="Log In"
353
+ show-remember-me="false"
354
+ controller="demo-auth-controller">
355
+
356
+ <div slot="footer">
357
+ <p class="footer-text">Test credentials: demo / password</p>
358
+ </div>
359
+ </snice-login>
360
+ </div>
361
+ </div>
362
+
363
+ <div class="demo-events">
364
+ <h3>Event Log</h3>
365
+ <div id="event-log" class="event-log">
366
+ <div class="event-entry event-info">
367
+ <strong>[INFO]</strong> Demo loaded. Try logging in with username: "demo" and password: "password"
368
+ </div>
369
+ </div>
370
+ </div>
371
+ </div>
372
+
373
+ <!-- Import the components -->
374
+ <script type="module">
375
+ // Import the controller first, then the login component
376
+ import './demo-auth-controller.ts';
377
+ import './snice-login.ts';
378
+
379
+ // Get references to interactive elements
380
+ const interactiveLogin = document.getElementById('interactive-login');
381
+ const variantSelect = document.getElementById('variant-select');
382
+ const sizeSelect = document.getElementById('size-select');
383
+ const titleInput = document.getElementById('title-input');
384
+ const actionTextInput = document.getElementById('action-text-input');
385
+ const showRememberCheckbox = document.getElementById('show-remember');
386
+ const showForgotCheckbox = document.getElementById('show-forgot');
387
+ const disabledToggle = document.getElementById('disabled-toggle');
388
+ const simulateErrorBtn = document.getElementById('simulate-error');
389
+ const clearLogBtn = document.getElementById('clear-log');
390
+ const eventLog = document.getElementById('event-log');
391
+
392
+ // Update interactive login component
393
+ function updateInteractiveLogin() {
394
+ interactiveLogin.variant = variantSelect.value;
395
+ interactiveLogin.size = sizeSelect.value;
396
+ interactiveLogin.title = titleInput.value;
397
+ interactiveLogin.actionText = actionTextInput.value;
398
+ interactiveLogin.showRememberMe = showRememberCheckbox.checked;
399
+ interactiveLogin.showForgotPassword = showForgotCheckbox.checked;
400
+ interactiveLogin.disabled = disabledToggle.checked;
401
+ }
402
+
403
+ // Add event listeners for controls
404
+ variantSelect.addEventListener('change', updateInteractiveLogin);
405
+ sizeSelect.addEventListener('change', updateInteractiveLogin);
406
+ titleInput.addEventListener('input', updateInteractiveLogin);
407
+ actionTextInput.addEventListener('input', updateInteractiveLogin);
408
+ showRememberCheckbox.addEventListener('change', updateInteractiveLogin);
409
+ showForgotCheckbox.addEventListener('change', updateInteractiveLogin);
410
+ disabledToggle.addEventListener('change', updateInteractiveLogin);
411
+
412
+ // Simulate error
413
+ simulateErrorBtn.addEventListener('click', () => {
414
+ interactiveLogin.setError('Invalid credentials. Please try again.');
415
+ logEvent('error', 'Simulated error set on interactive login component');
416
+ });
417
+
418
+ // Clear event log
419
+ clearLogBtn.addEventListener('click', () => {
420
+ eventLog.innerHTML = '<div class="event-entry event-info"><strong>[INFO]</strong> Event log cleared</div>';
421
+ });
422
+
423
+ // Event logging function
424
+ function logEvent(type, message, data = null) {
425
+ const timestamp = new Date().toLocaleTimeString();
426
+ const entry = document.createElement('div');
427
+ entry.className = `event-entry event-${type}`;
428
+
429
+ let logMessage = `<strong>[${timestamp}]</strong> ${message}`;
430
+ if (data) {
431
+ logMessage += `<br><em>${JSON.stringify(data, null, 2)}</em>`;
432
+ }
433
+
434
+ entry.innerHTML = logMessage;
435
+ eventLog.appendChild(entry);
436
+ eventLog.scrollTop = eventLog.scrollHeight;
437
+ }
438
+
439
+ // Listen for login events on all login components
440
+ document.addEventListener('@snice/login-attempt', (event) => {
441
+ logEvent('info', 'Login attempt started', event.detail);
442
+ });
443
+
444
+ document.addEventListener('@snice/login-success', (event) => {
445
+ logEvent('success', 'Login successful!', event.detail);
446
+ });
447
+
448
+ document.addEventListener('@snice/login-error', (event) => {
449
+ logEvent('error', 'Login failed', event.detail);
450
+ });
451
+
452
+ document.addEventListener('@snice/login-forgot-password', (event) => {
453
+ logEvent('info', 'Forgot password clicked', event.detail);
454
+ });
455
+
456
+ // Demo-specific events
457
+ document.addEventListener('demo-auth-response', (event) => {
458
+ const { success, user, error } = event.detail;
459
+ if (success) {
460
+ logEvent('success', `Authentication successful for user: ${user.username}`, event.detail);
461
+ } else {
462
+ logEvent('error', `Authentication failed: ${error}`, event.detail);
463
+ }
464
+ });
465
+
466
+ // Initialize
467
+ logEvent('info', 'Demo initialized. All login components are ready.');
468
+ </script>
469
+ </body>
470
+ </html>
@@ -1,4 +1,4 @@
1
- import { element, property, query, queryAll, on, dispatch, request, type Response } from 'snice';
1
+ import { element, property, query, queryAll, on, dispatch, request } from 'snice';
2
2
  import css from './snice-login.css?inline';
3
3
  import type { LoginVariant, LoginSize, LoginCredentials, LoginResult, SniceLoginElement } from './snice-login.types';
4
4
  import '../alert/snice-alert';
@@ -137,7 +137,7 @@ export class SniceLogin extends HTMLElement implements SniceLoginElement {
137
137
  }
138
138
 
139
139
  @request('login-user')
140
- async *login(credentials?: LoginCredentials): Response<LoginResult> {
140
+ async *login(credentials?: LoginCredentials): any {
141
141
  if (!credentials) {
142
142
  credentials = this.getFormData();
143
143
  }