snice 7.0.2 → 7.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 (304) hide show
  1. package/.agents/skills/snice/SKILL.md +4 -0
  2. package/.agents/skills/snice/references/core-kitchen-sink.ts +39 -1
  3. package/README.md +59 -14
  4. package/adapters/react/SniceProvider.js +2 -2
  5. package/adapters/react/SniceRouter.js +2 -2
  6. package/adapters/react/matchRoute.js +2 -2
  7. package/adapters/react/useRequestHandler.js +2 -2
  8. package/bin/analyzer-contracts.js +6 -1
  9. package/bin/postinstall.js +59 -0
  10. package/bin/project-analyzer.js +466 -5
  11. package/bin/snice.js +3 -0
  12. package/dist/app-context.d.ts +11 -0
  13. package/dist/cdn/accordion/snice-accordion.js +2 -2
  14. package/dist/cdn/action-bar/snice-action-bar.js +2 -2
  15. package/dist/cdn/activity-feed/snice-activity-feed.js +2 -2
  16. package/dist/cdn/alert/snice-alert.js +2 -2
  17. package/dist/cdn/app-tiles/snice-app-tiles.js +2 -2
  18. package/dist/cdn/approval-flow/snice-approval-flow.js +2 -2
  19. package/dist/cdn/audio-recorder/snice-audio-recorder.js +2 -2
  20. package/dist/cdn/availability/snice-availability.js +2 -2
  21. package/dist/cdn/avatar/snice-avatar.js +2 -2
  22. package/dist/cdn/avatar-group/snice-avatar-group.js +2 -2
  23. package/dist/cdn/badge/snice-badge.js +2 -2
  24. package/dist/cdn/banner/snice-banner.js +2 -2
  25. package/dist/cdn/binpack/snice-binpack.js +2 -2
  26. package/dist/cdn/book/snice-book.js +2 -2
  27. package/dist/cdn/booking/snice-booking.js +2 -2
  28. package/dist/cdn/breadcrumbs/snice-breadcrumbs.js +2 -2
  29. package/dist/cdn/button/snice-button.js +2 -2
  30. package/dist/cdn/calendar/snice-calendar.js +2 -2
  31. package/dist/cdn/camera/snice-camera.js +2 -2
  32. package/dist/cdn/camera-annotate/snice-camera-annotate.js +2 -2
  33. package/dist/cdn/candlestick/snice-candlestick.js +2 -2
  34. package/dist/cdn/card/snice-card.js +2 -2
  35. package/dist/cdn/carousel/snice-carousel.js +2 -2
  36. package/dist/cdn/cart/snice-cart.js +2 -2
  37. package/dist/cdn/chart/snice-chart.js +2 -2
  38. package/dist/cdn/chat/snice-chat.js +2 -2
  39. package/dist/cdn/checkbox/snice-checkbox.js +2 -2
  40. package/dist/cdn/chip/snice-chip.js +2 -2
  41. package/dist/cdn/code-block/snice-code-block.js +2 -2
  42. package/dist/cdn/color-display/snice-color-display.js +2 -2
  43. package/dist/cdn/color-picker/snice-color-picker.js +2 -2
  44. package/dist/cdn/command-palette/snice-command-palette.js +2 -2
  45. package/dist/cdn/comments/snice-comments.js +2 -2
  46. package/dist/cdn/countdown/snice-countdown.js +2 -2
  47. package/dist/cdn/cropper/snice-cropper.js +2 -2
  48. package/dist/cdn/data-card/snice-data-card.js +2 -2
  49. package/dist/cdn/date-picker/snice-date-picker.js +2 -2
  50. package/dist/cdn/date-range-picker/snice-date-range-picker.js +2 -2
  51. package/dist/cdn/date-time-picker/snice-date-time-picker.js +2 -2
  52. package/dist/cdn/diff/snice-diff.js +2 -2
  53. package/dist/cdn/divider/snice-divider.js +2 -2
  54. package/dist/cdn/doc/snice-doc.js +2 -2
  55. package/dist/cdn/draw/snice-draw.js +2 -2
  56. package/dist/cdn/drawer/snice-drawer.js +2 -2
  57. package/dist/cdn/empty-state/snice-empty-state.js +2 -2
  58. package/dist/cdn/estimate/snice-estimate.js +2 -2
  59. package/dist/cdn/file-gallery/snice-file-gallery.js +2 -2
  60. package/dist/cdn/file-upload/snice-file-upload.js +2 -2
  61. package/dist/cdn/flip-card/snice-flip-card.js +2 -2
  62. package/dist/cdn/flow/snice-flow.js +2 -2
  63. package/dist/cdn/form-layout/snice-form-layout.js +2 -2
  64. package/dist/cdn/funnel/snice-funnel.js +2 -2
  65. package/dist/cdn/gantt/snice-gantt.js +2 -2
  66. package/dist/cdn/gauge/snice-gauge.js +2 -2
  67. package/dist/cdn/grid/snice-grid.js +2 -2
  68. package/dist/cdn/heatmap/snice-heatmap.js +2 -2
  69. package/dist/cdn/image/snice-image.js +2 -2
  70. package/dist/cdn/input/snice-input.js +2 -2
  71. package/dist/cdn/invoice/snice-invoice.js +2 -2
  72. package/dist/cdn/kanban/snice-kanban.js +2 -2
  73. package/dist/cdn/key-value/snice-key-value.js +2 -2
  74. package/dist/cdn/kpi/snice-kpi.js +2 -2
  75. package/dist/cdn/layout/README.md +17 -2
  76. package/dist/cdn/layout/snice-layout.js +1656 -11
  77. package/dist/cdn/layout/snice-layout.js.map +1 -1
  78. package/dist/cdn/layout/snice-layout.min.js +379 -2
  79. package/dist/cdn/layout/snice-layout.min.js.map +1 -1
  80. package/dist/cdn/leaderboard/snice-leaderboard.js +2 -2
  81. package/dist/cdn/link/snice-link.js +2 -2
  82. package/dist/cdn/link-preview/snice-link-preview.js +2 -2
  83. package/dist/cdn/list/snice-list.js +2 -2
  84. package/dist/cdn/location/snice-location.js +2 -2
  85. package/dist/cdn/login/snice-login.js +2 -2
  86. package/dist/cdn/map/snice-map.js +2 -2
  87. package/dist/cdn/markdown/snice-markdown.js +2 -2
  88. package/dist/cdn/masonry/snice-masonry.js +2 -2
  89. package/dist/cdn/menu/snice-menu.js +2 -2
  90. package/dist/cdn/message-strip/snice-message-strip.js +2 -2
  91. package/dist/cdn/modal/snice-modal.js +2 -2
  92. package/dist/cdn/music-player/snice-music-player.js +2 -2
  93. package/dist/cdn/nav/snice-nav.js +2 -2
  94. package/dist/cdn/network-graph/snice-network-graph.js +2 -2
  95. package/dist/cdn/notification-center/snice-notification-center.js +2 -2
  96. package/dist/cdn/order-tracker/snice-order-tracker.js +2 -2
  97. package/dist/cdn/org-chart/snice-org-chart.js +2 -2
  98. package/dist/cdn/pagination/snice-pagination.js +2 -2
  99. package/dist/cdn/paint/snice-paint.js +2 -2
  100. package/dist/cdn/pdf-viewer/snice-pdf-viewer.js +2 -2
  101. package/dist/cdn/permission-matrix/snice-permission-matrix.js +2 -2
  102. package/dist/cdn/podcast-player/snice-podcast-player.js +2 -2
  103. package/dist/cdn/popover/snice-popover.js +2 -2
  104. package/dist/cdn/pricing-table/snice-pricing-table.js +2 -2
  105. package/dist/cdn/product-card/snice-product-card.js +2 -2
  106. package/dist/cdn/progress/snice-progress.js +2 -2
  107. package/dist/cdn/progress-ring/snice-progress-ring.js +2 -2
  108. package/dist/cdn/qr-code/snice-qr-code.js +2 -2
  109. package/dist/cdn/qr-reader/snice-qr-reader.js +2 -2
  110. package/dist/cdn/radio/snice-radio.js +2 -2
  111. package/dist/cdn/range-slider/snice-range-slider.js +2 -2
  112. package/dist/cdn/rating/snice-rating.js +2 -2
  113. package/dist/cdn/receipt/snice-receipt.js +2 -2
  114. package/dist/cdn/recipe/snice-recipe.js +3 -3
  115. package/dist/cdn/recipe/snice-recipe.js.map +1 -1
  116. package/dist/cdn/recipe/snice-recipe.min.js +1 -1
  117. package/dist/cdn/recipe/snice-recipe.min.js.map +1 -1
  118. package/dist/cdn/runtime/README.md +2 -2
  119. package/dist/cdn/runtime/snice-runtime.esm.js +3725 -3336
  120. package/dist/cdn/runtime/snice-runtime.esm.js.map +1 -1
  121. package/dist/cdn/runtime/snice-runtime.esm.min.js +1 -1
  122. package/dist/cdn/runtime/snice-runtime.esm.min.js.map +1 -1
  123. package/dist/cdn/runtime/snice-runtime.js +3727 -3335
  124. package/dist/cdn/runtime/snice-runtime.js.map +1 -1
  125. package/dist/cdn/runtime/snice-runtime.min.js +1 -1
  126. package/dist/cdn/runtime/snice-runtime.min.js.map +1 -1
  127. package/dist/cdn/sankey/snice-sankey.js +2 -2
  128. package/dist/cdn/segmented-control/snice-segmented-control.js +2 -2
  129. package/dist/cdn/select/snice-select.js +2 -2
  130. package/dist/cdn/skeleton/snice-skeleton.js +2 -2
  131. package/dist/cdn/slider/snice-slider.js +2 -2
  132. package/dist/cdn/sortable/snice-sortable.js +2 -2
  133. package/dist/cdn/sparkline/snice-sparkline.js +2 -2
  134. package/dist/cdn/spinner/snice-spinner.js +2 -2
  135. package/dist/cdn/split-button/snice-split-button.js +2 -2
  136. package/dist/cdn/split-pane/snice-split-pane.js +2 -2
  137. package/dist/cdn/spotlight/snice-spotlight.js +2 -2
  138. package/dist/cdn/stat-group/snice-stat-group.js +2 -2
  139. package/dist/cdn/step-input/snice-step-input.js +2 -2
  140. package/dist/cdn/stepper/snice-stepper.js +2 -2
  141. package/dist/cdn/switch/snice-switch.js +2 -2
  142. package/dist/cdn/table/README.md +6 -2
  143. package/dist/cdn/table/snice-table.esm.js +366 -56
  144. package/dist/cdn/table/snice-table.esm.js.map +1 -1
  145. package/dist/cdn/table/snice-table.esm.min.js +107 -46
  146. package/dist/cdn/table/snice-table.esm.min.js.map +1 -1
  147. package/dist/cdn/table/snice-table.js +367 -59
  148. package/dist/cdn/table/snice-table.js.map +1 -1
  149. package/dist/cdn/table/snice-table.min.js +155 -94
  150. package/dist/cdn/table/snice-table.min.js.map +1 -1
  151. package/dist/cdn/tabs/snice-tabs.js +2 -2
  152. package/dist/cdn/tag/snice-tag.js +2 -2
  153. package/dist/cdn/tag-input/snice-tag-input.js +2 -2
  154. package/dist/cdn/terminal/snice-terminal.js +3 -2
  155. package/dist/cdn/terminal/snice-terminal.js.map +1 -1
  156. package/dist/cdn/terminal/snice-terminal.min.js +1 -0
  157. package/dist/cdn/terminal/snice-terminal.min.js.map +1 -1
  158. package/dist/cdn/testimonial/snice-testimonial.js +2 -2
  159. package/dist/cdn/textarea/snice-textarea.js +2 -2
  160. package/dist/cdn/time-picker/snice-time-picker.js +2 -2
  161. package/dist/cdn/time-range-picker/snice-time-range-picker.js +2 -2
  162. package/dist/cdn/timeline/snice-timeline.js +2 -2
  163. package/dist/cdn/timer/snice-timer.js +2 -2
  164. package/dist/cdn/toast/snice-toast.js +2 -2
  165. package/dist/cdn/tooltip/snice-tooltip.js +2 -2
  166. package/dist/cdn/tree/snice-tree.js +2 -2
  167. package/dist/cdn/treemap/snice-treemap.js +2 -2
  168. package/dist/cdn/user-card/snice-user-card.js +2 -2
  169. package/dist/cdn/video-player/README.md +1 -1
  170. package/dist/cdn/video-player/snice-video-player.js +3 -2
  171. package/dist/cdn/video-player/snice-video-player.js.map +1 -1
  172. package/dist/cdn/video-player/snice-video-player.min.js +1 -0
  173. package/dist/cdn/video-player/snice-video-player.min.js.map +1 -1
  174. package/dist/cdn/virtual-scroller/snice-virtual-scroller.js +2 -2
  175. package/dist/cdn/waterfall/snice-waterfall.js +2 -2
  176. package/dist/cdn/weather/snice-weather.js +2 -2
  177. package/dist/cdn/work-order/snice-work-order.js +2 -2
  178. package/dist/components/recipe/snice-recipe.js +1 -1
  179. package/dist/components/recipe/snice-recipe.js.map +1 -1
  180. package/dist/components/table/snice-table.d.ts +1 -0
  181. package/dist/components/table/snice-table.js +18 -2
  182. package/dist/components/table/snice-table.js.map +1 -1
  183. package/dist/components/table/table-tree-data.js +1 -0
  184. package/dist/components/table/table-tree-data.js.map +1 -1
  185. package/dist/components/terminal/snice-terminal.js +1 -0
  186. package/dist/components/terminal/snice-terminal.js.map +1 -1
  187. package/dist/components/video-player/snice-video-player.js +1 -0
  188. package/dist/components/video-player/snice-video-player.js.map +1 -1
  189. package/dist/context-provider.d.ts +16 -0
  190. package/dist/daemon-target.d.ts +10 -0
  191. package/dist/daemon.d.ts +10 -0
  192. package/dist/index.cjs +3721 -3329
  193. package/dist/index.cjs.map +1 -1
  194. package/dist/index.d.ts +3 -0
  195. package/dist/index.esm.js +3719 -3330
  196. package/dist/index.esm.js.map +1 -1
  197. package/dist/index.iife.js +3721 -3329
  198. package/dist/index.iife.js.map +1 -1
  199. package/dist/keyboard-filter.d.ts +25 -0
  200. package/dist/on.d.ts +1 -1
  201. package/dist/parts.d.ts +0 -17
  202. package/dist/react/SniceProvider.js +2 -2
  203. package/dist/react/SniceRouter.js +2 -2
  204. package/dist/react/index.js +2 -2
  205. package/dist/react/matchRoute.js +2 -2
  206. package/dist/react/useRequestHandler.js +2 -2
  207. package/dist/request-response.d.ts +9 -1
  208. package/dist/symbols.cjs +11 -2
  209. package/dist/symbols.cjs.map +1 -1
  210. package/dist/symbols.d.ts +3 -0
  211. package/dist/symbols.esm.js +9 -3
  212. package/dist/symbols.esm.js.map +1 -1
  213. package/dist/testing.d.ts +1 -1
  214. package/dist/transitions.cjs +2 -2
  215. package/dist/transitions.esm.js +2 -2
  216. package/dist/types/app-context.d.ts +9 -58
  217. package/dist/types/daemon.d.ts +8 -0
  218. package/dist/types/dispatch-options.d.ts +2 -0
  219. package/dist/types/index.d.ts +1 -0
  220. package/dist/types/on-options.d.ts +5 -0
  221. package/dist/types/request-options.d.ts +2 -0
  222. package/dist/types/respond-options.d.ts +2 -0
  223. package/docs/ai/DEVELOPMENT.md +15 -1
  224. package/docs/ai/README.md +5 -1
  225. package/docs/ai/api.md +13 -4
  226. package/docs/ai/architecture.md +50 -1
  227. package/docs/ai/cli.md +9 -0
  228. package/docs/ai/components/avatar.md +8 -8
  229. package/docs/ai/components/breadcrumbs.md +2 -1
  230. package/docs/ai/components/button.md +2 -7
  231. package/docs/ai/components/calendar.md +1 -1
  232. package/docs/ai/components/camera.md +1 -1
  233. package/docs/ai/components/chart.md +3 -1
  234. package/docs/ai/components/code-block.md +2 -2
  235. package/docs/ai/components/date-picker.md +5 -19
  236. package/docs/ai/components/date-range-picker.md +4 -12
  237. package/docs/ai/components/draw.md +5 -5
  238. package/docs/ai/components/drawer.md +4 -4
  239. package/docs/ai/components/form-layout.md +2 -0
  240. package/docs/ai/components/icons.md +7 -16
  241. package/docs/ai/components/key-value.md +3 -22
  242. package/docs/ai/components/layout.md +8 -12
  243. package/docs/ai/components/leaderboard.md +2 -2
  244. package/docs/ai/components/link-preview.md +4 -3
  245. package/docs/ai/components/login.md +11 -0
  246. package/docs/ai/components/markdown.md +7 -0
  247. package/docs/ai/components/masonry.md +6 -0
  248. package/docs/ai/components/menu.md +1 -1
  249. package/docs/ai/components/modal.md +7 -0
  250. package/docs/ai/components/notification-center.md +5 -4
  251. package/docs/ai/components/radio.md +7 -0
  252. package/docs/ai/components/rating.md +3 -3
  253. package/docs/ai/components/select.md +4 -13
  254. package/docs/ai/components/spotlight.md +2 -0
  255. package/docs/ai/components/table.md +1 -4
  256. package/docs/ai/components/tag-input.md +6 -0
  257. package/docs/ai/components/terminal.md +6 -0
  258. package/docs/ai/components/tooltip.md +10 -16
  259. package/docs/ai/components/tree.md +2 -2
  260. package/docs/ai/components/video-player.md +5 -0
  261. package/docs/ai/components/waterfall.md +7 -0
  262. package/docs/ai/daemons.md +80 -0
  263. package/docs/ai/decorators.md +6 -4
  264. package/docs/ai/events.md +35 -0
  265. package/docs/ai/patterns.md +45 -1
  266. package/docs/ai/request-response.md +26 -9
  267. package/docs/ai/routing.md +16 -1
  268. package/docs/cli.md +7 -0
  269. package/docs/components/breadcrumbs.md +2 -1
  270. package/docs/components/calendar.md +1 -1
  271. package/docs/components/camera.md +1 -1
  272. package/docs/components/chart.md +1 -1
  273. package/docs/components/code-block.md +13 -4
  274. package/docs/components/color-picker.md +6 -5
  275. package/docs/components/date-time-picker.md +14 -0
  276. package/docs/components/diff.md +2 -1
  277. package/docs/components/draw.md +5 -5
  278. package/docs/components/drawer.md +4 -4
  279. package/docs/components/input.md +1 -0
  280. package/docs/components/layout.md +20 -22
  281. package/docs/components/leaderboard.md +10 -3
  282. package/docs/components/link-preview.md +11 -9
  283. package/docs/components/login.md +4 -0
  284. package/docs/components/menu.md +1 -1
  285. package/docs/components/modal.md +1 -0
  286. package/docs/components/nav.md +1 -0
  287. package/docs/components/network-graph.md +1 -0
  288. package/docs/components/notification-center.md +2 -1
  289. package/docs/components/product-card.md +1 -0
  290. package/docs/components/qr-reader.md +1 -0
  291. package/docs/components/rating.md +4 -4
  292. package/docs/components/select.md +1 -0
  293. package/docs/components/spotlight.md +2 -0
  294. package/docs/components/tabs.md +1 -0
  295. package/docs/components/terminal.md +3 -0
  296. package/docs/components/textarea.md +1 -1
  297. package/docs/components/time-picker.md +14 -0
  298. package/docs/components/tooltip.md +2 -0
  299. package/docs/components/tree.md +2 -2
  300. package/docs/daemons.md +200 -0
  301. package/docs/events.md +92 -2
  302. package/docs/request-response.md +20 -13
  303. package/docs/routing.md +25 -1
  304. package/package.json +6 -4
package/docs/ai/api.md CHANGED
@@ -15,6 +15,7 @@
15
15
  // attachController(el, MyController) | el.controller = MyController
16
16
  // controller="name" string attr (only channel in raw HTML; still supported everywhere)
17
17
  // Class binding: reference-deduped, removes controller attr, attr writes ignored while bound
18
+ @daemon // Explicitly constructed app-context state/lifecycle object; no name or global registration
18
19
  @layout('name') // Define page wrapper
19
20
  ```
20
21
 
@@ -112,13 +113,13 @@ html`
112
113
  ```typescript
113
114
  @on(event: string | string[], selector?: string, options?: OnOptions)
114
115
  // Works in elements + controllers
115
- // Options: { debounce?, throttle?, preventDefault?, stopPropagation?, once?, capture?, passive?, target?, scope? }
116
+ // Options: { debounce?, throttle?, preventDefault?, stopPropagation?, once?, capture?, passive?, target?, scope?, daemon? }
116
117
  // target: CSS selector for shadow DOM event delegation
117
118
  // scope: 'global' | selector | EventTarget | () => EventTarget | null — redirects listener attachment
118
119
  // Keyboard: 'keydown:Enter', 'keydown.escape', 'keydown:ctrl+s', 'keydown:~Space'
119
120
  // Supports both ':' and '.' notation
120
121
 
121
- @dispatch(eventName: string, options?: { debounce?, throttle?, dispatchOnUndefined?, scope?, ...EventInit })
122
+ @dispatch(eventName: string, options?: { debounce?, throttle?, dispatchOnUndefined?, scope?, daemon?, ...EventInit })
122
123
  // Fires CustomEvent after method, detail = return value
123
124
  // Supports async methods (dispatches after promise resolves)
124
125
  // dispatchOnUndefined: false (default) — skips dispatch if method returns undefined
@@ -142,7 +143,7 @@ html`
142
143
  ## Communication
143
144
 
144
145
  ```typescript
145
- @request(channel: string, options?: { timeout?, discoveryTimeout?, debounce?, throttle?, bubbles?, cancelable? })
146
+ @request(channel: string, options?: { daemon?, timeout?, discoveryTimeout?, debounce?, throttle?, bubbles?, cancelable? })
146
147
  // Request pattern using async generator syntax
147
148
  // Method must be async generator that yields payload and receives response
148
149
  // Returns Promise<T>
@@ -166,7 +167,7 @@ html`
166
167
  // }
167
168
  // // Usage: const user = await this.fetchUser('123');
168
169
 
169
- @respond(channel: string, options?: { debounce?, throttle? })
170
+ @respond(channel: string, options?: { daemon?, debounce?, throttle? })
170
171
  // Respond to requests from @request decorators
171
172
  // Method receives payload and returns response
172
173
  // Works in both elements and controllers
@@ -182,6 +183,14 @@ html`
182
183
  // }
183
184
  ```
184
185
 
186
+ Daemon addressing:
187
+ ```typescript
188
+ const release = provideContext(appRoot, { daemons: { session: new SessionDaemon() } });
189
+ const context = getContext(elementOrController);
190
+ // Consumers use { daemon: 'session' }; daemon methods default to their own private target.
191
+ // Provide before connect/attach. Call release() during app/test teardown.
192
+ ```
193
+
185
194
  ## Observers
186
195
 
187
196
  ```typescript
@@ -7,6 +7,7 @@
7
7
  - **Pages:** Orchestrate elements, handle URLs
8
8
  - **Elements:** Generic visual building blocks — no fetch(), no API calls, no business logic
9
9
  - **Controllers:** Specific behavior (data, APIs, business rules) — swappable per element
10
+ - **Daemons:** Explicitly constructed app-owned state/lifecycle objects — addressable through context, never global singletons
10
11
 
11
12
  **Generic vs Specific:** Elements say *what* they need, controllers decide *how*.
12
13
  Swap controllers to change behavior without touching the component.
@@ -16,6 +17,26 @@ Mock controller for tests, real API controller in production — same element.
16
17
  - Down: Properties
17
18
  - Up: Events
18
19
  - Sideways: Request/Response channels
20
+ - App services: daemon-addressed request/response or dispatch/on
21
+
22
+ ## Project Structure
23
+
24
+ Conventional application layout:
25
+
26
+ ```text
27
+ src/
28
+ main.ts
29
+ router.ts
30
+ pages/ # @page classes; route orchestration and presentation
31
+ components/ # reusable @element visual components
32
+ controllers/ # @controller data, API, and reusable business behavior
33
+ daemons/ # explicitly constructed @daemon state/lifecycle services
34
+ ```
35
+
36
+ Pages may coordinate a route and perform a small one-off load. Move behavior to
37
+ a controller when a page owns several storage/server/timer operations or when
38
+ substantial non-visual logic is copied across pages. `snice check` reports these
39
+ as architecture suggestions, not errors.
19
40
 
20
41
  ## Rendering System
21
42
 
@@ -74,6 +95,15 @@ Mock controller for tests, real API controller in production — same element.
74
95
  - Class bindings own the element: attribute writes ignored while a class is bound
75
96
  - Native elements: class bindings attach via ControllerPart; string attrs via MutationObserver
76
97
 
98
+ **Daemon lifecycle:**
99
+ 1. Application constructs an `@daemon` class with `new`
100
+ 2. `provideContext(root, { daemons })` activates its private communication target
101
+ 3. Elements/controllers resolve the nearest context by string address
102
+ 4. Provider release removes daemon handlers and deactivates that target
103
+ - Router provides its `context` through the same mechanism
104
+ - Multiple instances of the same class remain independent
105
+ - No implicit construction, registry scan, singleton, start, or stop hook
106
+
77
107
  ## Router System
78
108
 
79
109
  **Registration:**
@@ -136,7 +166,7 @@ onChange() { return { value: this.value }; }
136
166
  ```typescript
137
167
  // Element requests (async generator: yield sends, await receives)
138
168
  @request('fetch-data')
139
- async *fetchData(): any {
169
+ async *fetchData(): Response<Data> {
140
170
  return await (yield { id: this.dataId }); // single yield per call
141
171
  }
142
172
 
@@ -148,6 +178,25 @@ async handleFetch(payload: { id: string }) {
148
178
  // Wiring: html`<my-element controller=${MyController}></my-element>` (or controller="my-controller" in raw HTML)
149
179
  ```
150
180
 
181
+ **Element/Controller ↔ Daemon:** Addressed communication
182
+ ```typescript
183
+ @daemon
184
+ class SessionDaemon {
185
+ @respond('session/get') get() { return this.session; }
186
+ @dispatch('session/changed') changed() { return this.session; }
187
+ }
188
+
189
+ const session = new SessionDaemon();
190
+ const release = provideContext(appRoot, { daemons: { session } });
191
+
192
+ // Consumer imports no daemon implementation class.
193
+ @request('session/get', { daemon: 'session' })
194
+ async *getSession(): Response<Session | null> { return yield {}; }
195
+
196
+ @on('session/changed', { daemon: 'session' })
197
+ sessionChanged(event: CustomEvent<Session | null>) {}
198
+ ```
199
+
151
200
  **Global State:** Context
152
201
  ```typescript
153
202
  @context() handleContext(ctx: Context) {
package/docs/ai/cli.md CHANGED
@@ -44,6 +44,15 @@ npx snice validate # source analyzer only
44
44
  `validate` runs the analyzer over source. Catches mistakes that compile but never work:
45
45
  - an `@element`-decorated class that does not extend `HTMLElement` (or a Snice element subclass) — Snice registers/renders only element subclasses
46
46
  - deep imports that were never released package paths, e.g. `snice/decorators`
47
+ - Router missing `target`, `type`, or a project-wide `initialize()` call
48
+ - a routed class combining `@page` with redundant `@element`
49
+
50
+ Non-blocking architecture suggestions:
51
+ - `@page` -> `src/pages/`
52
+ - `@element` -> `src/components/`
53
+ - `@controller` -> `src/controllers/`
54
+ - `@daemon` -> `src/daemons/`
55
+ - several external-effect methods or substantial logic repeated across pages -> extract a controller
47
56
 
48
57
  Both `doctor` and `validate` accept `--json`.
49
58
 
@@ -72,11 +72,11 @@ fallbackBackground: string = ''; // attr: fallback-background — overrides
72
72
 
73
73
  ### Size Reference
74
74
 
75
- | Size | Dimensions | Font Size |
76
- |------|-----------|-----------|
77
- | `xs` | 1.5rem (24px) | 0.625rem |
78
- | `small` | 2rem (32px) | 0.75rem |
79
- | `medium` | 2.5rem (40px) | 0.875rem |
80
- | `large` | 3rem (48px) | 1rem |
81
- | `xl` | 4rem (64px) | 1.25rem |
82
- | `xxl` | 6rem (96px) | 2rem |
75
+ Size dimension / font-size:
76
+
77
+ - `xs` 1.5rem (24px) / 0.625rem
78
+ - `small` 2rem (32px) / 0.75rem
79
+ - `medium` 2.5rem (40px) / 0.875rem
80
+ - `large` 3rem (48px) / 1rem
81
+ - `xl` 4rem (64px) / 1.25rem
82
+ - `xxl` 6rem (96px) / 2rem
@@ -13,9 +13,10 @@ Navigation breadcrumb trail.
13
13
 
14
14
  ```typescript
15
15
  items: BreadcrumbItem[] = []; // JS property only
16
- separator: '/'|'>'|'>>'|'.'|'|' = '/';
16
+ separator: '/'|'>'|'»'|''|'|' = '/';
17
17
  size: 'small'|'medium'|'large' = 'medium';
18
18
  maxItems: number = 0; // 0 = show all, attr: max-items
19
+ collapsed: boolean = true; // ellipsis state; ellipsis click sets false, resets on items/separator/maxItems change
19
20
  ```
20
21
 
21
22
  ### snice-crumb
@@ -53,16 +53,11 @@ readonly labels: NodeList | null;
53
53
  ```html
54
54
  <snice-button>Click me</snice-button>
55
55
 
56
- <!-- Variants -->
56
+ <!-- Variants: default|primary|success|warning|danger|text -->
57
57
  <snice-button variant="primary">Primary</snice-button>
58
- <snice-button variant="success">Success</snice-button>
59
- <snice-button variant="warning">Warning</snice-button>
60
- <snice-button variant="danger">Danger</snice-button>
61
- <snice-button variant="text">Text</snice-button>
62
58
 
63
- <!-- Sizes -->
59
+ <!-- Sizes: small|medium|large -->
64
60
  <snice-button size="small">Small</snice-button>
65
- <snice-button size="large">Large</snice-button>
66
61
 
67
62
  <!-- States -->
68
63
  <snice-button disabled>Disabled</snice-button>
@@ -10,7 +10,7 @@ view: 'month'|'week'|'day' = 'month';
10
10
  events: CalendarEvent[] = [];
11
11
  minDate: Date | string = ''; // attribute: min-date
12
12
  maxDate: Date | string = ''; // attribute: max-date
13
- disabledDates: (Date | string)[] = []; // attribute: disabled-dates
13
+ disabledDates: (Date | string)[] = []; // JS-only; no attribute
14
14
  highlightToday: boolean = true; // attribute: highlight-today
15
15
  showWeekNumbers: boolean = false; // attribute: show-week-numbers
16
16
  firstDayOfWeek: number = 0; // attribute: first-day-of-week (0=Sun, 1=Mon)
@@ -5,7 +5,7 @@ Live camera feed with built-in mobile-style controls.
5
5
  ## Properties
6
6
 
7
7
  ```typescript
8
- autoStart: boolean = true; // attribute: auto-start
8
+ autoStart: boolean = false; // attribute: auto-start
9
9
  facingMode: 'user'|'environment' = 'user'; // attribute: facing-mode
10
10
  mirror: boolean = true;
11
11
  controlsPosition: ControlsPosition = 'auto'; // attribute: controls-position
@@ -8,7 +8,9 @@ General-purpose chart component with 10 chart types and animations.
8
8
  type: 'line'|'bar'|'horizontal-bar'|'area'|'pie'|'donut'|'scatter'|'bubble'|'radar'|'mixed' = 'line';
9
9
  datasets: ChartDataset[] = []; // property only
10
10
  labels: string[] = []; // property only
11
- options: ChartOptions = {}; // property only
11
+ options: ChartOptions = { responsive: true, maintainAspectRatio: false, legend: {position:'top', clickable:true},
12
+ tooltip: {trigger:'hover'}, animation: {enabled:true, duration:500, easing:'ease-out'},
13
+ xAxis: {grid:true}, yAxis: {grid:true} }; // property only
12
14
  width: number = 0; // 0 = auto
13
15
  height: number = 0; // 0 = auto
14
16
  ```
@@ -7,10 +7,10 @@ Code display with syntax highlighting, line numbers, copy, and grammar-based for
7
7
  ```typescript
8
8
  code: string = ''; // Set via slot or property
9
9
  language: 'javascript'|'typescript'|'html'|'css'|'json'|'python'|'bash'|'plaintext' = 'plaintext';
10
- grammar: GrammarDefinition | string | null = null; // Grammar object or URL to JSON
10
+ grammar: GrammarDefinition | string | null = ''; // Grammar object or URL to JSON
11
11
  showLineNumbers: boolean = false; // attribute: show-line-numbers
12
12
  startLine: number = 1; // attribute: start-line
13
- highlightLines: number[] = []; // attribute: highlight-lines
13
+ highlightLines: number[] = []; // JS-only; no attribute
14
14
  copyable: boolean = true;
15
15
  filename: string = '';
16
16
  format: string = ''; // Formatter name (e.g. "pretty"), or truthy string with setFormatter()
@@ -17,11 +17,8 @@ value: string = '';
17
17
  // Maps to the value content attribute and is restored by form reset.
18
18
  defaultValue: string = '';
19
19
 
20
- format:
21
- | 'mm/dd/yyyy' | 'dd/mm/yyyy'
22
- | 'yyyy-mm-dd' | 'yyyy/mm/dd'
23
- | 'dd-mm-yyyy' | 'mm-dd-yyyy'
24
- | 'mmmm dd, yyyy' = 'mm/dd/yyyy';
20
+ format: 'mm/dd/yyyy' | 'dd/mm/yyyy' | 'yyyy-mm-dd' | 'yyyy/mm/dd'
21
+ | 'dd-mm-yyyy' | 'mm-dd-yyyy' | 'mmmm dd, yyyy' = 'mm/dd/yyyy';
25
22
 
26
23
  variant: 'outlined' | 'filled' | 'underlined' = 'outlined';
27
24
  size: 'small' | 'medium' | 'large' = 'medium';
@@ -29,14 +26,9 @@ placeholder: string = '';
29
26
  label: string = '';
30
27
  helperText: string = ''; // helper-text
31
28
  errorText: string = ''; // error-text
32
- disabled: boolean = false;
33
- readonly: boolean = false;
34
- loading: boolean = false;
35
- required: boolean = false;
29
+ disabled | readonly | loading | required | clearable: boolean = false;
36
30
  invalid: boolean = false; // presentation only, not constraint validity
37
- clearable: boolean = false;
38
- min: string = ''; // canonical YYYY-MM-DD recommended
39
- max: string = ''; // canonical YYYY-MM-DD recommended
31
+ min: string = ''; max: string = ''; // canonical YYYY-MM-DD recommended
40
32
  name: string = '';
41
33
  open: boolean = false;
42
34
  firstDayOfWeek: number = 0; // first-day-of-week; 0=Sunday
@@ -140,13 +132,7 @@ All component events bubble and are composed. Direct property/default changes, r
140
132
 
141
133
  ## CSS Parts
142
134
 
143
- - `input`
144
- - `calendar-toggle`
145
- - `clear`
146
- - `spinner`
147
- - `calendar`
148
- - `helper-text`
149
- - `error-text`
135
+ `input`, `calendar-toggle`, `clear`, `spinner`, `calendar`, `helper-text`, `error-text`
150
136
 
151
137
  ## Keyboard/accessibility
152
138
 
@@ -20,11 +20,8 @@ end: string = '';
20
20
  defaultStart: string = '';
21
21
  defaultEnd: string = '';
22
22
 
23
- format:
24
- | 'mm/dd/yyyy' | 'dd/mm/yyyy'
25
- | 'yyyy-mm-dd' | 'yyyy/mm/dd'
26
- | 'dd-mm-yyyy' | 'mm-dd-yyyy'
27
- | 'mmmm dd, yyyy' = 'mm/dd/yyyy';
23
+ format: 'mm/dd/yyyy' | 'dd/mm/yyyy' | 'yyyy-mm-dd' | 'yyyy/mm/dd'
24
+ | 'dd-mm-yyyy' | 'mm-dd-yyyy' | 'mmmm dd, yyyy' = 'mm/dd/yyyy';
28
25
 
29
26
  size: 'small' | 'medium' | 'large' = 'medium';
30
27
  variant: 'outlined' | 'filled' | 'underlined' = 'outlined';
@@ -32,14 +29,9 @@ placeholder: string = '';
32
29
  label: string = '';
33
30
  helperText: string = ''; // helper-text
34
31
  errorText: string = ''; // error-text
35
- disabled: boolean = false;
36
- readonly: boolean = false;
37
- loading: boolean = false;
38
- required: boolean = false;
32
+ disabled | readonly | loading | required | clearable: boolean = false;
39
33
  invalid: boolean = false; // presentation only, not constraint validity
40
- clearable: boolean = false;
41
- min: string = ''; // canonical YYYY-MM-DD recommended
42
- max: string = ''; // canonical YYYY-MM-DD recommended
34
+ min: string = ''; max: string = ''; // canonical YYYY-MM-DD recommended
43
35
  name: string = ''; // base name for {name}-start and {name}-end
44
36
  columns: number = 1; // supported layouts: 1 or 2
45
37
  firstDayOfWeek: number = 0; // first-day-of-week; 0=Sunday
@@ -48,11 +48,11 @@ interface DrawStroke {
48
48
 
49
49
  ## Events
50
50
 
51
- - `draw-start` - Drawing started
52
- - `draw-end` → `{ stroke }` - Stroke completed
53
- - `draw-clear` - Canvas cleared
54
- - `draw-undo` - Undo performed
55
- - `draw-redo` - Redo performed
51
+ - `draw-start` → `{ draw, point }` - Drawing started
52
+ - `draw-end` → `{ draw, stroke }` - Stroke completed
53
+ - `draw-clear` → `{ draw }` - Canvas cleared
54
+ - `draw-undo` → `{ draw }` - Undo performed
55
+ - `draw-redo` → `{ draw }` - Redo performed
56
56
 
57
57
  ## CSS Parts
58
58
 
@@ -44,10 +44,10 @@ contained: boolean = false; // Position relative to parent
44
44
  - `--snice-drawer-control-size` - Drawer control size
45
45
  - `--drawer-width-small` through `--drawer-width-xxxl` - Width per size
46
46
  - `--drawer-height-small` through `--drawer-height-xxxl` - Height per size (top/bottom)
47
- - `--drawer-bg` - Background (default: `var(--snice-color-surface, white)`)
48
- - `--drawer-shadow` - Shadow (default: `var(--snice-shadow-lg)`)
49
- - `--drawer-backdrop` - Backdrop color (default: `rgba(0, 0, 0, 0.5)`)
50
- - `--drawer-transition` - Transition timing
47
+ - `--drawer-bg` - Background (default: `var(--snice-color-surface-container-highest, var(--snice-color-surface, white))`)
48
+ - `--drawer-shadow` - Shadow (default: `var(--snice-shadow-2xl, ...)`)
49
+ - `--drawer-backdrop` - Backdrop color (default: `var(--snice-drawer-backdrop, rgb(0 0 0 / 0.6))`)
50
+ - `--drawer-transition` - Transition timing (default: `transform 320ms var(--snice-ease-out, cubic-bezier(0.22, 1, 0.36, 1))`)
51
51
  - `--drawer-z-index` - Z-index (default: `1050`)
52
52
 
53
53
  ## CSS Parts
@@ -59,4 +59,6 @@ import 'snice/components/form-layout/snice-form-layout';
59
59
  </snice-form-layout>
60
60
  ```
61
61
 
62
+ Span columns with CSS `grid-column` on a slotted child: `<snice-textarea style="grid-column: 1 / -1">`.
63
+
62
64
  No events -- layout-only component. Responsive: collapses to single column on mobile (<640px).
@@ -35,22 +35,13 @@ Snice embeds a small set of Heroicons (MIT © Tailwind Labs) as defaults. Consum
35
35
 
36
36
  ## Components with built-in defaults
37
37
 
38
- | Component | Where used |
39
- |-----------|------------|
40
- | `<snice-alert>` | variant status icon |
41
- | `<snice-banner>` | variant status icon |
42
- | `<snice-timeline>` | marker icon (per item variant) |
43
- | `<snice-image>` | placeholder (no `src`) |
44
- | `<snice-cell-image>` (table) | placeholder |
45
- | `<snice-approval-flow>` | step status (pending/approved/rejected/skipped) |
46
- | `<snice-data-card>` | Edit/Done button |
47
- | `<snice-kpi>` | trend indicator |
48
- | `<snice-cell-percentage>` (table) | trend indicator |
49
- | `<snice-cell-json>` (table) | expand/collapse chevron |
50
- | `<snice-header>` (table) | sort direction |
51
- | `<snice-modal>` | close button |
52
- | `<snice-drawer>` | close button |
53
- | `<snice-toast>` | close button |
38
+ - Variant status icon: `<snice-alert>`, `<snice-banner>`; `<snice-timeline>` marker (per item variant)
39
+ - Placeholder: `<snice-image>` (no `src`), `<snice-cell-image>` (table)
40
+ - `<snice-approval-flow>` step status (pending/approved/rejected/skipped)
41
+ - Trend indicator: `<snice-kpi>`, `<snice-cell-percentage>` (table)
42
+ - `<snice-cell-json>` expand/collapse chevron; `<snice-header>` sort direction (both table)
43
+ - Close button: `<snice-modal>`, `<snice-drawer>`, `<snice-toast>`
44
+ - `<snice-data-card>` Edit/Done button
54
45
 
55
46
  ## Importing built-in glyphs directly
56
47
 
@@ -2,19 +2,6 @@
2
2
 
3
3
  Form-associated ordered string-pair editor. Preserves duplicates, descriptions, Unicode, and row order. Direct `<snice-kv-pair>` children or imperative data API.
4
4
 
5
- ## Table of Contents
6
-
7
- - [Components](#components)
8
- - [Properties](#properties)
9
- - [Methods](#methods)
10
- - [Events](#events)
11
- - [Slots](#slots)
12
- - [CSS Parts](#css-parts)
13
- - [Basic Usage](#basic-usage)
14
- - [Examples](#examples)
15
- - [Keyboard Navigation](#keyboard-navigation)
16
- - [Accessibility](#accessibility)
17
-
18
5
  ## Components
19
6
 
20
7
  - `snice-key-value` - Editor/display/FACE control.
@@ -32,19 +19,13 @@ showDescription: boolean = false; // attr: show-description
32
19
  keyPlaceholder: string = 'Key'; // attr: key-placeholder
33
20
  valuePlaceholder: string = 'Value'; // attr: value-placeholder
34
21
  placeholders: Array<{key:string;value:string}> = []; // JS only
35
- disabled: boolean = false;
36
- readonly: boolean = false;
37
- required: boolean = false;
22
+ disabled | readonly | required: boolean = false;
38
23
  name: string = '';
39
24
  variant: 'default'|'compact' = 'default';
40
25
  mode: 'edit'|'view' = 'edit';
41
26
  showCopy: boolean = false; // attr: show-copy
42
- readonly type: 'key-value';
43
- readonly form: HTMLFormElement|null;
44
- readonly validity: ValidityState;
45
- readonly validationMessage: string;
46
- readonly willValidate: boolean;
47
- readonly labels: NodeList|null;
27
+ readonly type: 'key-value'; form: HTMLFormElement|null; validity: ValidityState;
28
+ readonly validationMessage: string; willValidate: boolean; labels: NodeList|null;
48
29
  ```
49
30
 
50
31
  ```ts
@@ -59,12 +59,12 @@ Siblings of `snice-layout` for the other standard page shapes. All regions are s
59
59
  - `snice-layout-sidebar` — app shell: `brand`, `header`, `sidebar`, `page`, `footer`
60
60
  - `snice-layout-dashboard` — app shell + toolbar + right rail: `brand`, `header`, `toolbar`, `sidebar`, `page`, `right-sidebar`
61
61
  - `snice-layout-blog` — article measure: `brand`, `nav`, `page`, `sidebar`, `footer`
62
- - `snice-layout-centered` — auth card: `brand`, `page`, `footer`
63
- - `snice-layout-split` — two panes: `left`, `right` (`direction`, `ratio`)
64
- - `snice-layout-landing` — marketing bands: `brand`, `nav`, `cta`, `hero`, `page`, `footer` (`use-nav`)
65
- - `snice-layout-card` — card grid: `header`, `page`, `footer` (`columns`, `gap`)
62
+ - `snice-layout-centered` — auth card: `brand`, `page`, `footer` (`width`: `sm`|`md`|`lg`|`xl`, default `md`)
63
+ - `snice-layout-split` — two panes: `left`, `right` (`direction`: `horizontal` default|`vertical`; `ratio`: `50-50` default|`60-40`|`70-30`|`33-67`|`67-33`)
64
+ - `snice-layout-landing` — marketing bands: `brand`, `nav`, `cta`, `hero`, `page`, `footer` (`use-nav` boolean, default false)
65
+ - `snice-layout-card` — card grid: `header`, `page`, `footer` (`columns`: `1`|`2`|`3` default|`4`|`6`; `gap`: `sm`|`md` default|`lg`|`xl`)
66
66
  - `snice-layout-minimal` — `page` only
67
- - `snice-layout-fullscreen` — layers: `background`, `overlay`, `page`, `controls` (`overlay`)
67
+ - `snice-layout-fullscreen` — layers: `background`, `overlay`, `page`, `controls` (`overlay` boolean, default false)
68
68
  - `snice-layout-master-detail` — list + detail: `brand`, `header`, `list`, `detail`, `empty` (`selected`); <641px single pane, back emits `detail-closed`
69
69
  - `snice-layout-docs` — three panes: `brand`, `header`, `sidebar`, `page`, `toc`, `footer`; rail drops at 1152px, tree → drawer at 996px; skip link + heading scroll-margin
70
70
  - `snice-layout-auth-split` — form + decorative panel: `brand`, `page`, `footer`, `panel` (`panel-position`: `end` default | `start`); panel hidden <768px
@@ -104,13 +104,9 @@ Layouts own the screen. App shells (`sidebar`, `dashboard`, `fullscreen`) are `p
104
104
 
105
105
  ## CSS Custom Properties
106
106
 
107
- - `--snice-layout-auth-panel-bg` - Layout auth panel background
108
- - `--snice-layout-control-size` - Layout control size
109
- - `--snice-layout-docs-header-height` - Layout docs header height
110
- - `--snice-layout-docs-header-height-compact` - Layout docs header height compact
111
-
112
- ## Sizing hooks
113
-
114
107
  - `--snice-layout-sidebar-width` (`16rem`), `--snice-layout-rail-collapsed-width` (`3rem`)
115
108
  - `--snice-layout-rail-width` (`18rem`), `--snice-layout-measure` (`65ch`), `--snice-layout-container` (`80rem`)
116
109
  - `--snice-layout-list-width` (`20rem`), `--snice-layout-docs-nav-width` / `--snice-layout-docs-toc-width` (`18.75rem`), `--snice-layout-auth-width` (`24rem`)
110
+ - `--snice-layout-docs-header-height` (`4rem`), `--snice-layout-docs-header-height-compact` (`3.5rem`) — docs sticky header, compact below 768px
111
+ - `--snice-layout-auth-panel-bg` (`var(--snice-color-surface-container)`) — auth split panel
112
+ - `--snice-layout-control-size` (`2rem`) — sidebar / drawer toggle buttons
@@ -12,7 +12,7 @@ Ranked list with podium variant, avatars, change indicators. Dual API: declarati
12
12
  ```ts
13
13
  variant: 'default'|'podium'|'compact' = 'default';
14
14
  size: 'small'|'medium'|'large' = 'medium';
15
- title: string = '';
15
+ title: string = ''; // JS-only; a title attribute is the native tooltip, not this
16
16
  ```
17
17
 
18
18
  ## Methods
@@ -62,7 +62,7 @@ interface LeaderboardEntry {
62
62
  ## Basic Usage
63
63
 
64
64
  ```html
65
- <snice-leaderboard variant="podium" title="Top Players">
65
+ <snice-leaderboard id="board" variant="podium"> <!-- title is JS-only: board.title = 'Top Players' -->
66
66
  <snice-leaderboard-entry rank="1" name="Alice" score="2500" change="3" highlighted></snice-leaderboard-entry>
67
67
  <snice-leaderboard-entry rank="2" name="Bob" score="2100" change="-1"></snice-leaderboard-entry>
68
68
  </snice-leaderboard>
@@ -6,7 +6,7 @@ Rich URL preview card with image, title, description, and site info.
6
6
 
7
7
  ```ts
8
8
  url: string = '';
9
- title: string = '';
9
+ title: string = ''; // JS-only; a title attribute is the native tooltip, not this
10
10
  description: string = '';
11
11
  image: string = '';
12
12
  siteName: string = ''; // attr: site-name
@@ -34,16 +34,17 @@ import 'snice/components/link-preview/snice-link-preview';
34
34
  ```html
35
35
  <!-- Vertical (default) -->
36
36
  <snice-link-preview
37
+ id="preview"
37
38
  url="https://example.com"
38
- title="Article Title"
39
39
  description="Brief summary."
40
40
  image="/images/og.jpg"
41
41
  site-name="example.com"
42
42
  favicon="/icons/favicon.ico">
43
43
  </snice-link-preview>
44
+ <script>document.getElementById('preview').title = 'Article Title';</script>
44
45
 
45
46
  <!-- Horizontal, small -->
46
47
  <snice-link-preview variant="horizontal" size="small"
47
- url="https://example.com" title="Quick Link" description="Short.">
48
+ url="https://example.com" description="Short.">
48
49
  </snice-link-preview>
49
50
  ```
@@ -13,6 +13,8 @@ loading: boolean = false;
13
13
  showRememberMe: boolean = true; // attr: show-remember-me
14
14
  showForgotPassword: boolean = true; // attr: show-forgot-password
15
15
  actionText: string = 'Sign In'; // attr: action-text
16
+ alertMessage: string = ''; // JS only; inline alert above the form
17
+ alertVariant: 'error'|'success'|'' = ''; // JS only; styles alertMessage
16
18
  ```
17
19
 
18
20
  ## Methods
@@ -22,6 +24,8 @@ actionText: string = 'Sign In'; // attr: action-text
22
24
  - `reset()` → Clear form, alert, loading
23
25
  - `setError(message)` → Show error alert
24
26
  - `clearError()` → Clear alert
27
+ - `showAlert(message, 'error'|'success')` → Show inline alert; `setError` is the error-only shorthand
28
+ - `clearAlert()` → Remove inline alert
25
29
 
26
30
  ## Requests
27
31
 
@@ -107,3 +111,10 @@ class AuthController {
107
111
  // Event fallback
108
112
  login.addEventListener('login-success', () => location.href = '/dashboard');
109
113
  ```
114
+
115
+ ## Accessibility
116
+
117
+ - Inputs use `<label for>`; `autocomplete="username"` / `"current-password"`
118
+ - Required fields carry `required`
119
+ - Enter on the password field submits
120
+ - Loading and disabled states propagate to every input and the submit button
@@ -70,3 +70,10 @@ md.addEventListener('link-click', (e) => {
70
70
  console.log('Navigating to:', e.detail.href);
71
71
  });
72
72
  ```
73
+
74
+ ## Accessibility
75
+
76
+ - Rendered HTML keeps the semantic heading hierarchy (h1-h6) for screen readers
77
+ - Links in rendered content are keyboard accessible
78
+ - Tables render real `<thead>`/`<tbody>` structure for assistive technology
79
+ - `link-click` lets you take over navigation without losing that behavior
@@ -44,3 +44,9 @@ import 'snice/components/masonry/snice-masonry';
44
44
  <div>Card 2</div>
45
45
  </snice-masonry>
46
46
  ```
47
+
48
+ ## Accessibility
49
+
50
+ - Container carries `role="list"` for screen readers
51
+ - Items flow top-to-bottom, left-to-right within CSS columns
52
+ - `break-inside: avoid` keeps an item from splitting across columns
@@ -75,7 +75,7 @@ selected: boolean = false;
75
75
  --menu-border: var(--snice-color-border, #e5e7eb);
76
76
  --menu-shadow: var(--snice-shadow-lg);
77
77
  --menu-z-index: var(--snice-z-floating, 1000);
78
- --menu-border-radius: var(--snice-radius-md, 0.375rem);
78
+ --menu-border-radius: var(--snice-border-radius-md, 0.25rem);
79
79
  --menu-min-width: 10rem;
80
80
  ```
81
81
 
@@ -72,3 +72,10 @@ modal.addEventListener('modal-close', () => console.log('Closed'));
72
72
 
73
73
  - Escape closes (unless `no-escape-dismiss`)
74
74
  - Tab/Shift+Tab cycle focus within modal
75
+
76
+ ## Accessibility
77
+
78
+ - `role="dialog"` + `aria-modal="true"` + `aria-label`
79
+ - Focus trapped by default (`no-focus-trap` disables); first focusable element focused on open, previous focus restored on close
80
+ - Body scroll locked while open
81
+ - Close button labelled `Close modal`
@@ -8,6 +8,7 @@ Bell icon with dropdown notification panel. Shows unread badge, supports dismiss
8
8
  notifications: NotificationItem[] = []; // attr: none (JS only)
9
9
  open: boolean = false; // Panel visibility
10
10
  icon: string = ''; // Custom bell icon (URL, image, emoji)
11
+ placement: 'start'|'end' = 'end'; // Panel alignment side
11
12
  ```
12
13
 
13
14
  ## Methods
@@ -37,15 +38,15 @@ icon: string = ''; // Custom bell icon (URL, image, emoji)
37
38
 
38
39
  ```css
39
40
  --snice-color-primary /* Mark all read link, unread highlight */
40
- --snice-color-primary-subtle /* Unread item background */
41
+ --snice-color-primary-subtle-hover /* Unread item hover (base tint derives from --snice-color-primary) */
41
42
  --snice-color-danger /* Badge background, dismiss hover */
42
- --snice-color-text-inverse /* Badge text */
43
+ --snice-color-surface /* Badge text, via the nested snice-badge */
43
44
  --snice-color-text-secondary /* Message text */
44
45
  --snice-color-text-tertiary /* Timestamp, empty state, dismiss icon */
45
46
  --snice-color-border /* Panel, item borders */
46
47
  --snice-color-surface /* Panel background */
47
- --snice-color-surface-container-high /* Item hover, bell hover */
48
- --snice-shadow-lg /* Panel shadow */
48
+ --snice-color-surface-hover /* Item hover, bell hover */
49
+ --snice-shadow-xl /* Panel shadow */
49
50
  ```
50
51
 
51
52
  ## Basic Usage