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
@@ -103,3 +103,10 @@ Only the newly selected radio emits. The old member is silently unchecked. Direc
103
103
  Slot: `suffix`.
104
104
 
105
105
  CSS parts: `input`, `radio`, `dot`, `spinner`, `content`, `label`, `description`.
106
+
107
+ ## Accessibility
108
+
109
+ - Native radio input drives keyboard and AT behavior; one roving tab stop per named group
110
+ - Visible label text associated with the native control; external `<label for>` supports association, focus, activation, cancellation
111
+ - Required group validity and native labels exposed through `ElementInternals`
112
+ - Visible keyboard focus indicator; `aria-invalid` reflects explicit or calculated group invalidity
@@ -7,7 +7,7 @@ Interactive star rating input with full/half precision, custom icons, and keyboa
7
7
  ```typescript
8
8
  value: number = 0;
9
9
  max: number = 5;
10
- icon: string = '';
10
+ icon: string = 'star'; // catalogue name, emoji, URL, or image file
11
11
  emptyIcon: string = ''; // attr empty-icon; empty falls back to icon
12
12
  size: 'small'|'medium'|'large' = 'medium';
13
13
  readonly: boolean = false;
@@ -20,8 +20,8 @@ precision: 'full'|'half' = 'full';
20
20
 
21
21
  ## CSS Custom Properties
22
22
 
23
- - `--rating-color` - Filled star color (`var(--snice-color-warning)`)
24
- - `--rating-color-empty` - Empty star color (`var(--snice-color-border)`)
23
+ - `--rating-color` - Filled star color (`rgb(245 158 11)`; not theme-derived)
24
+ - `--rating-color-empty` - Empty star color (`var(--snice-color-text-tertiary)`)
25
25
  - `--rating-size` - Star size (auto-set by `size`: small=1rem, medium=1.5rem, large=2rem)
26
26
 
27
27
  ## CSS Parts
@@ -14,14 +14,8 @@ Customizable dropdown selection with single/multiple, search, editable input, an
14
14
  ```typescript
15
15
  value: string = ''; // Live; comma-separated for multiple
16
16
  defaultValue: string = ''; // attr: value; authored/reset default
17
- disabled: boolean = false;
18
- required: boolean = false;
19
- invalid: boolean = false;
20
- readonly: boolean = false;
21
- loading: boolean = false;
22
- multiple: boolean = false;
23
- searchable: boolean = false;
24
- clearable: boolean = false;
17
+ disabled | required | invalid | readonly | loading: boolean = false;
18
+ multiple | searchable | clearable: boolean = false;
25
19
  editable: boolean = false; // Text input trigger instead of button
26
20
  allowFreeText: boolean = false; // attr: allow-free-text
27
21
  remote: boolean = false; // Remote search via @request('select/search')
@@ -37,11 +31,8 @@ placeholder: string = 'Select an option';
37
31
  maxHeight: string = '200px'; // attr: max-height
38
32
  options: SelectOption[] = []; // JS only, works alongside <snice-option> children
39
33
  readonly labels: NodeList | null; // Current explicit/wrapping external labels
40
- readonly type: 'select-one' | 'select-multiple';
41
- readonly form: HTMLFormElement | null;
42
- readonly validity: ValidityState;
43
- readonly validationMessage: string;
44
- readonly willValidate: boolean;
34
+ readonly type: 'select-one' | 'select-multiple'; form: HTMLFormElement | null;
35
+ readonly validity: ValidityState; validationMessage: string; willValidate: boolean;
45
36
  ```
46
37
 
47
38
  ### snice-option
@@ -29,6 +29,7 @@ interface SpotlightStep {
29
29
  - `spotlight-step` → `{ index, step }`
30
30
  - `spotlight-end` → `void`
31
31
  - `spotlight-skip` → `{ index }`
32
+ - `spotlight-target-missing` → `{ index, step }` — step target gone (e.g. route change); popover stops instead of pointing at nothing
32
33
 
33
34
  ## CSS Custom Properties
34
35
 
@@ -55,6 +56,7 @@ spotlight.start();
55
56
 
56
57
  spotlight.addEventListener('spotlight-end', () => console.log('Tour completed'));
57
58
  spotlight.addEventListener('spotlight-skip', (e) => console.log(`Skipped at ${e.detail.index}`));
59
+ spotlight.addEventListener('spotlight-target-missing', (e) => console.warn('Missing target', e.detail.step.target));
58
60
  ```
59
61
 
60
62
  ## CSS Parts
@@ -124,10 +124,7 @@ type CellStyle={backgroundColor?:string;color?:string;fontWeight?:'normal'|'bold
124
124
 
125
125
  ## CSS Parts
126
126
 
127
- - `body` - Table body
128
- - `filter-button` - Column filter trigger
129
- - `sort-indicator` - Column sort direction indicator
130
- - `<snice-table>`: `superheader`, `controls`, `toolbar`, `pagination` (no native header/body/cell parts); `<snice-row>`: `container`, `checkbox-cell`, `cell`; cells: `content`; actions: `action-button`; JSON: `toggle`; tag: `tag`; link/email/phone/location: `link`
127
+ - `<snice-table>`: `body`, `superheader`, `controls`, `toolbar`, `pagination`, `filter-button` (column filter trigger), `sort-indicator` (sort direction); `<snice-row>`: `container`, `checkbox-cell`, `cell`; cells: `content`; actions: `action-button`; JSON: `toggle`; tag: `tag`; link/email/phone/location: `link`
131
128
 
132
129
  ## CSS Custom Properties
133
130
 
@@ -87,3 +87,9 @@ tagInput.addEventListener('tag-change', (e) => {
87
87
  console.log('Tags:', e.detail.value);
88
88
  });
89
89
  ```
90
+
91
+ ## Accessibility
92
+
93
+ - `label` supplies the input's accessible name
94
+ - Adding, removing, and selecting tags are all reachable by keyboard (see Keyboard Navigation)
95
+ - Focus returns to the input after a tag is added or removed
@@ -23,6 +23,12 @@ showTimestamps: boolean = false; // attr: show-timestamps
23
23
  - `getHistory()` - Get command history
24
24
  - `clearHistory()` - Clear command history
25
25
 
26
+ Streaming API — feed raw chunks without splitting on newlines; a trailing partial line stays live and grows until a newline commits it:
27
+
28
+ - `appendChunk(chunk, type?)` - Append a raw chunk
29
+ - `pipeFrom(source, type?)` - Stream an `AsyncIterable<string>` or `ReadableStream<string|Uint8Array>`; returns `Promise<void>`
30
+ - `commitLiveLine()` - Force the live buffer to become a finished line
31
+
26
32
  ## Events
27
33
 
28
34
  - `terminal-command` -> `{ command, args }` - Command entered
@@ -90,19 +90,13 @@ Observer for `tooltip` attribute on any element. No wrapper element -- safe insi
90
90
 
91
91
  ### CSS Variable API
92
92
 
93
- | Variable | Default | Description |
94
- |---|---|---|
95
- | `--tooltip-position` | `top` | top/bottom/left/right + -start/-end |
96
- | `--tooltip-trigger` | `hover` | hover, click, focus |
97
- | `--tooltip-delay` | `0` | Show delay (ms) |
98
- | `--tooltip-hide-delay` | `0` | Hide delay (ms) |
99
- | `--tooltip-offset` | `12` | Distance from trigger (px) |
100
- | `--tooltip-arrow` | (shown) | `none` to hide |
101
- | `--tooltip-max-width` | `250` | Max width (px) |
102
- | `--tooltip-z-index` | `10000` | Z-index |
103
- | `--tooltip-strict-positioning` | (false) | `true` to disable auto-flip |
104
- | `--tooltip-bg` | `hsl(0 0% 20%)` | Background color |
105
- | `--tooltip-color` | `white` | Text color |
106
- | `--tooltip-padding` | `8px 12px` | Content padding |
107
- | `--tooltip-radius` | `6px` | Border radius |
108
- | `--tooltip-font-size` | `14px` | Font size |
93
+ - `--tooltip-position` (`top`) top/bottom/left/right + `-start`/`-end`
94
+ - `--tooltip-trigger` (`hover`) — hover, click, focus
95
+ - `--tooltip-delay` (`0`) / `--tooltip-hide-delay` (`0`) show / hide delay (ms)
96
+ - `--tooltip-offset` (`12`) distance from trigger (px)
97
+ - `--tooltip-arrow` (shown) `none` to hide; `--tooltip-arrow-size` (`6px`) sizes it
98
+ - `--tooltip-max-width` (`250`) max width (px)
99
+ - `--tooltip-z-index` (`10000`)
100
+ - `--tooltip-strict-positioning` (false) `true` disables auto-flip
101
+ - `--tooltip-bg` (`hsl(0 0% 20%)`) background / `--tooltip-color` (`white`) text color
102
+ - `--tooltip-padding` (`8px 12px`) content padding, `--tooltip-radius` (`6px`), `--tooltip-font-size` (`14px`)
@@ -11,8 +11,8 @@ showCheckboxes: boolean = false; // attr: show-checkboxes
11
11
  showIcons: boolean = true; // attr: show-icons
12
12
  expandOnClick: boolean = false; // attr: expand-on-click
13
13
  nodes: TreeNode[] = [];
14
- selectedNodes: string[] = []; // attr: selected-nodes
15
- checkedNodes: string[] = []; // attr: checked-nodes
14
+ selectedNodes: string[] = []; // JS-only; no attribute
15
+ checkedNodes: string[] = []; // JS-only; no attribute
16
16
 
17
17
  interface TreeNode {
18
18
  id: string;
@@ -78,6 +78,11 @@ duration: number; // read-only
78
78
  - ArrowRight/ArrowLeft: Seek forward/backward 5s
79
79
  - ArrowUp/ArrowDown: Volume up/down 10%
80
80
 
81
+ ## Accessibility
82
+
83
+ - Controls carry ARIA labels; current time, duration, and playback state are exposed to AT
84
+ - Transitions respect `prefers-reduced-motion`
85
+
81
86
  ## Basic Usage
82
87
 
83
88
  ```html
@@ -58,3 +58,10 @@ chart.addEventListener('bar-click', (e) => {
58
58
  console.log(`Clicked: ${e.detail.item.label} (${e.detail.item.value})`);
59
59
  });
60
60
  ```
61
+
62
+ ## Accessibility
63
+
64
+ - Bars carry data-visualization roles, are focusable, and activate by keyboard
65
+ - `showValues` exposes value labels as screen-reader text
66
+ - Bar types distinguishable by color *and* value label, not color alone
67
+ - Animations respect `prefers-reduced-motion`
@@ -0,0 +1,80 @@
1
+ # Daemons
2
+
3
+ Human reference: `docs/daemons.md`.
4
+
5
+ Ordinary explicitly constructed stateful objects with app-owned lifecycles.
6
+ `@daemon` adds per-instance Snice communication; it never constructs, caches,
7
+ globally registers, starts, or stops an instance.
8
+
9
+ ```typescript
10
+ @daemon
11
+ class SessionDaemon {
12
+ session: Session | null = null;
13
+
14
+ @respond('get-session')
15
+ getSession() { return this.session; }
16
+
17
+ @on('set-session')
18
+ setSession(e: CustomEvent<Session>) {
19
+ this.session = e.detail;
20
+ this.changed();
21
+ }
22
+
23
+ @dispatch('session-changed')
24
+ changed() { return this.session; }
25
+ }
26
+
27
+ const session = new SessionDaemon();
28
+ const release = provideContext(appRoot, { daemons: { session } });
29
+ ```
30
+
31
+ Context contract:
32
+
33
+ ```typescript
34
+ type DaemonMap = Readonly<Record<string, object>>;
35
+
36
+ interface AppContext {
37
+ readonly daemons?: DaemonMap;
38
+ [key: string]: unknown;
39
+ }
40
+ ```
41
+
42
+ Extend `AppContext` to type application-specific fields; Snice assigns meaning
43
+ only to `daemons`.
44
+
45
+ Router automatically provides its `context` beneath `target`. Non-router apps
46
+ call `provideContext(root, context)`. `getContext(elementOrController)` returns
47
+ the raw visible app context.
48
+
49
+ Consumer; no daemon implementation import:
50
+
51
+ ```typescript
52
+ @request<Session | null>('get-session', { daemon: 'session' })
53
+ async *load(): Response<Session | null> { return yield {}; }
54
+
55
+ @dispatch('set-session', { daemon: 'session' })
56
+ set(session: Session) { return session; }
57
+
58
+ @on('session-changed', { daemon: 'session' })
59
+ changed(e: CustomEvent<Session | null>) {}
60
+
61
+ @respond('confirm-logout', { daemon: 'session' })
62
+ confirm() { return true; }
63
+ ```
64
+
65
+ Daemon methods without `{ daemon }` use that instance's private target.
66
+ Controllers resolve through their attached host.
67
+
68
+ Resolution: participant -> nearest provided app context ->
69
+ `context.daemons[name]` -> instance target. No globals, implicit construction,
70
+ fallback, scanning, or late binding.
71
+
72
+ Rules:
73
+ - Provide before element connect/controller attach (`@on`/`@respond` bind then).
74
+ - `@request`/`@dispatch` resolve at invocation.
75
+ - `daemon` and `scope` are mutually exclusive.
76
+ - No selector delegation on daemon targets.
77
+ - Release function is idempotent and makes daemon traffic inert.
78
+ - Multiple instances of the same class and same address under different roots
79
+ are independent.
80
+ - Missing/undecorated/inactive entries fail explicitly.
@@ -4,6 +4,7 @@
4
4
  - `@element('tag-name', options?)` - Custom element. Options: `{ formAssociated?, renderRoot?: 'shadow'|'light', shadow?: 'open'|'closed'|false, delegatesFocus? }`
5
5
  - `@page({ tag, routes, guards?, placard? })` - Routable page
6
6
  - `@controller('name')` - Swappable behavior. Required on every controller class. Attach by class (preferred): `controller=${MyController}` in templates, `attachController(el, MyController)`, or `el.controller = MyController`; by string in raw HTML: `controller="name"`
7
+ - `@daemon` - Marks an explicitly constructed app-context daemon. No name argument; context key is address. Never constructs/registers globally.
7
8
  - `@layout('tag-name')` - Page wrapper for routing system
8
9
 
9
10
  ## Rendering
@@ -30,8 +31,8 @@
30
31
  - `@queryAll('selector', { light? })` - NodeList
31
32
 
32
33
  ## Events
33
- - `@on('event', 'selector?', options?)` - Delegation, auto-bound. Options: `{ capture?, once?, passive?, preventDefault?, stopPropagation?, debounce?, throttle?, scope? }`
34
- - `@dispatch('event-name', options?)` - Emit CustomEvent, detail = return value. Supports async. Options: `{ debounce?, throttle?, dispatchOnUndefined?, scope?, ...EventInit }`
34
+ - `@on('event', 'selector?', options?)` - Delegation, auto-bound. Options: `{ capture?, once?, passive?, preventDefault?, stopPropagation?, debounce?, throttle?, scope?, daemon? }`
35
+ - `@dispatch('event-name', options?)` - Emit CustomEvent, detail = return value. Supports async. Options: `{ debounce?, throttle?, dispatchOnUndefined?, scope?, daemon?, ...EventInit }`
35
36
 
36
37
  ### scope (on both `@on` and `@dispatch`)
37
38
 
@@ -63,9 +64,10 @@ Unresolved scope → `console.warn`, listener not attached / event not dispatche
63
64
  Resolver re-runs on reconnect — listeners track DOM moves.
64
65
 
65
66
  ## Communication
66
- - `@request(channel, options?)` - Async generator request pattern
67
- - `@respond(channel, options?)` - Handle requests from `@request`
67
+ - `@request(channel, options?)` - Async generator request pattern; `{ daemon: 'name' }` targets an app-context daemon
68
+ - `@respond(channel, options?)` - Handle requests from `@request`; `{ daemon: 'name' }` installs on that daemon target
68
69
  - `@context(options?)` - Receive router navigation context updates
70
+ - `provideContext(root, context)` / `getContext(participant)` - Explicit raw app-context provisioning and lookup
69
71
 
70
72
  ## Observers
71
73
  - `@observe(target, selector?, options?)` - Watch intersection, resize, media query, mutation
package/docs/ai/events.md CHANGED
@@ -342,6 +342,41 @@ changeColor(color: string) { this.color = color; return { color }; }
342
342
  confirm() { return { color: this.color }; }
343
343
  ```
344
344
 
345
+ ## Event bus
346
+
347
+ No bus object, no singleton. Bus = `@dispatch` publishing upward + `@on` subscribing at a chosen ancestor. Scope is a DOM node, so it lives and dies with the DOM.
348
+
349
+ Two publish paths — the choice decides who can hear it:
350
+ - **Bubble from host** — `@dispatch` defaults to `bubbles: true, composed: true`, so it crosses shadow boundaries and passes every ancestor up to `document`. For "this element did something".
351
+ - **Dispatch on a scope** — `@dispatch` takes the same `scope` option as `@on`, firing *on* that target instead of bubbling. For subscribers that are not ancestors (sibling subtree, or a detached host).
352
+
353
+ ```typescript
354
+ @dispatch('bus:cart-added') // bubbles from host
355
+ @dispatch('bus:cart-added', { scope: 'global' }) // dispatched on document
356
+
357
+ @on('bus:cart-added', { scope: 'global' }) // document — app-wide
358
+ @on('bus:cart-added', { scope: 'cart-shell' }) // nearest <cart-shell> — per-instance
359
+ ```
360
+
361
+ Match the halves: a bubbling publish only reaches subscribers on the host's ancestor chain. Sibling subtree → scope the dispatch too, so both meet on the same node. See [scope on @dispatch](#scope-dispatch-target).
362
+
363
+ Scope choice:
364
+ - `'global'` — genuinely app-wide (auth expiry, theme change, save shortcut)
365
+ - selector string — feature subtree; a second shell elsewhere keeps its own traffic
366
+ - `EventTarget` / resolver — you hold the node, or it moves and must re-resolve
367
+
368
+ Prefer the narrowest scope that works; `'global'` means every instance hears every message.
369
+
370
+ `bus:` is a naming convention, not a framework feature. Teardown is automatic — removed on disconnect from the resolved target, re-resolved on reconnect. Unresolvable selector → listener skipped + `console.warn`, never bound to the wrong node. Full table: [scope](#scope-listener-attachment-target).
371
+
372
+ Need a reply rather than a broadcast → [@request / @respond](./request-response.md).
373
+
374
+ For stateful objects explicitly supplied by an application context, use
375
+ `{ daemon: 'name' }`. Both halves must target the same daemon address; daemon
376
+ methods themselves default to their own private target. See
377
+ [daemons](./daemons.md). Daemon targets are not DOM scopes: `scope` and
378
+ `daemon` cannot be combined, and selector delegation is unavailable.
379
+
345
380
  ## Custom events
346
381
 
347
382
  Dispatching manually:
@@ -94,6 +94,50 @@ Enabled automatically when Snice loads — no setup needed.
94
94
  // <table controller="table-loader"></table>
95
95
  ```
96
96
 
97
+ ## Daemon
98
+
99
+ Ordinary state/lifecycle object owned by the application. Construction and
100
+ teardown stay explicit; consumers use a context address instead of importing
101
+ the implementation class.
102
+
103
+ ```typescript
104
+ @daemon
105
+ class SessionDaemon {
106
+ session: Session | null = null;
107
+
108
+ @respond('session/get')
109
+ getSession() { return this.session; }
110
+
111
+ @on('session/set')
112
+ setSession(event: CustomEvent<Session>) {
113
+ this.session = event.detail;
114
+ this.changed();
115
+ }
116
+
117
+ @dispatch('session/changed')
118
+ changed() { return this.session; }
119
+ }
120
+
121
+ const session = new SessionDaemon();
122
+ const release = provideContext(appRoot, { daemons: { session } });
123
+
124
+ @request('session/get', { daemon: 'session' })
125
+ async *getSession(): Response<Session | null> { return yield {}; }
126
+
127
+ @dispatch('session/set', { daemon: 'session' })
128
+ setSession(session: Session) { return session; }
129
+
130
+ @on('session/changed', { daemon: 'session' })
131
+ sessionChanged(event: CustomEvent<Session | null>) {}
132
+ ```
133
+
134
+ - Provide before element connection/controller attachment.
135
+ - Router `context.daemons` uses the same provider automatically.
136
+ - `@request`/`@respond` = one reply; `@dispatch`/`@on` = notifications.
137
+ - `daemon` cannot be combined with DOM `scope`; daemon listeners cannot delegate selectors.
138
+ - Call `release()` during app/test teardown.
139
+ - See `docs/ai/daemons.md`.
140
+
97
141
  ## Page + Router
98
142
 
99
143
  **Module Structure (avoids circular imports):**
@@ -185,7 +229,7 @@ class API {
185
229
  @element('user-profile')
186
230
  class UserProfile extends HTMLElement {
187
231
  @request('fetch-user')
188
- async *fetchUser(id: string): any {
232
+ async *fetchUser(id: string): Response<User> {
189
233
  const user = await (yield { id }); // yield = send request, await = get response
190
234
  return user;
191
235
  }
@@ -2,7 +2,7 @@
2
2
 
3
3
  Mirrors `docs/request-response.md`.
4
4
 
5
- Request/response communication between elements and controllers using async generators.
5
+ Request/response communication between elements, controllers, and provided daemons using async generators.
6
6
 
7
7
  ## Why
8
8
 
@@ -27,6 +27,7 @@ function request(requestName: string, options?: RequestOptions): MethodDecorator
27
27
  function respond(requestName: string, options?: RespondOptions): MethodDecorator
28
28
 
29
29
  interface RequestOptions extends EventInit {
30
+ daemon?: string; // named daemon from nearest provided app context
30
31
  timeout?: number; // response timeout ms, default 120000 (2 min)
31
32
  discoveryTimeout?: number; // handler discovery timeout ms, default 50
32
33
  debounce?: number;
@@ -36,14 +37,20 @@ interface RequestOptions extends EventInit {
36
37
  }
37
38
 
38
39
  interface RespondOptions {
40
+ daemon?: string; // install responder on named daemon target
39
41
  debounce?: number;
40
42
  throttle?: number;
41
43
  }
42
44
 
43
- // Recommended type helper for request generator return types (define in your project):
44
- type RequestResult<T> = AsyncGenerator<any, T, any> | Promise<T>;
45
+ // Public return type for methods decorated with @request:
46
+ type Response<T = any> = T | any;
45
47
  ```
46
48
 
49
+ TypeScript cannot model a method decorator changing an async generator into a
50
+ promise-returning method. This is a deliberate pragmatic annotation: it keeps
51
+ strict consumers usable and documents `T`; the decorated runtime method
52
+ returns a promise for `T`.
53
+
47
54
  ### Response debounce/throttle
48
55
 
49
56
  ```typescript
@@ -65,6 +72,16 @@ class ProcessingController implements IController {
65
72
  }
66
73
  ```
67
74
 
75
+ Daemon communication uses the same protocol without DOM bubbling:
76
+
77
+ ```typescript
78
+ @request('get-session', { daemon: 'session' })
79
+ async *getSession() { return yield {}; }
80
+ ```
81
+
82
+ The daemon's plain `@respond('get-session')` handles it. See
83
+ [daemons](./daemons.md).
84
+
68
85
  ## Element-Side Requests
69
86
 
70
87
  ```typescript
@@ -75,7 +92,7 @@ class ProductCard extends HTMLElement {
75
92
  @property() price = '';
76
93
 
77
94
  @request('fetch-product')
78
- async *loadProduct(): RequestResult<void> {
95
+ async *loadProduct(): Response<void> {
79
96
  const product = await (yield { id: this.productId });
80
97
  this.name = product.name;
81
98
  this.price = product.price;
@@ -121,17 +138,17 @@ Elements never call `fetch()` or manage data directly — they yield requests up
121
138
 
122
139
  ```typescript
123
140
  @request('heavy-computation', { discoveryTimeout: 50, timeout: 30000 })
124
- async *compute(): RequestResult<any> { return await (yield data); }
141
+ async *compute(): Response<any> { return await (yield data); }
125
142
  ```
126
143
 
127
144
  ### Debounce/Throttle
128
145
 
129
146
  ```typescript
130
147
  @request('search', { debounce: 300 })
131
- async *search(): RequestResult<any[]> { return await (yield { query: this.searchTerm }); }
148
+ async *search(): Response<any[]> { return await (yield { query: this.searchTerm }); }
132
149
 
133
150
  @request('track', { throttle: 1000 })
134
- async *trackEvent(): RequestResult<void> { await (yield { event: 'scroll', position: window.scrollY }); }
151
+ async *trackEvent(): Response<void> { await (yield { event: 'scroll', position: window.scrollY }); }
135
152
  ```
136
153
 
137
154
  ## Error Handling
@@ -140,7 +157,7 @@ async *trackEvent(): RequestResult<void> { await (yield { event: 'scroll', posit
140
157
 
141
158
  ```typescript
142
159
  @request('load-data', { timeout: 5000 })
143
- async *loadData(): RequestResult<void> {
160
+ async *loadData(): Response<void> {
144
161
  try {
145
162
  this.data = await (yield { id: this.dataId });
146
163
  this.error = '';
@@ -201,7 +218,7 @@ class LiveTicker extends HTMLElement {
201
218
  @property() symbol = 'BTC';
202
219
 
203
220
  @request('subscribe-ticker')
204
- async *subscribe(): RequestResult<void> { await (yield { symbol: this.symbol }); }
221
+ async *subscribe(): Response<void> { await (yield { symbol: this.symbol }); }
205
222
 
206
223
  @on('ticker-update')
207
224
  onUpdate(e: CustomEvent) { this.price = e.detail.price; }
@@ -25,7 +25,7 @@ interface RouterOptions {
25
25
  document?: Document; // override document object (testing)
26
26
  transition?: Transition; // global transition config
27
27
  layout?: string; // default layout tag for all pages
28
- context?: any; // shared context object across pages/layouts
28
+ context?: any; // app context; may expose daemons
29
29
  fetcher?: Fetcher; // optional fetch middleware — see docs/ai/fetcher.md
30
30
  }
31
31
  ```
@@ -45,6 +45,19 @@ class AppContext {
45
45
  const { page, initialize } = Router({ target: '#app', type: 'hash', context: new AppContext() });
46
46
  ```
47
47
 
48
+ Router also provides the raw app context beneath `target`, using the same
49
+ `provideContext()` mechanism available to non-router applications. Explicitly
50
+ constructed `@daemon` instances may be addressed through `context.daemons`:
51
+
52
+ ```typescript
53
+ const session = new SessionDaemon();
54
+ Router({
55
+ target: '#app',
56
+ type: 'hash',
57
+ context: { daemons: { session } }
58
+ });
59
+ ```
60
+
48
61
  ### Module structure (avoids circular imports)
49
62
 
50
63
  ```typescript
@@ -176,4 +189,6 @@ function Router(options: RouterOptions): {
176
189
 
177
190
  - `navigate(path: string): Promise<void>` — navigates to `path`; uses hash or pushstate depending on router `type`.
178
191
  - `initialize(): void` — starts listening for route changes; must be called after all pages are defined.
192
+ - Do not add `@element` to an `@page` class. The Router-returned page decorator
193
+ already registers the custom element and applies Snice element behavior.
179
194
  - `register(route: string, tag: string, transition?: Transition, guards?: Guard | Guard[], layout?: string | false, placard?: Placard | ((ctx: AppContext) => Placard)): void` — manually registers a route without the `@page` decorator. Note: the return-type shape above lists `register` with 4 params; this fuller 6-param signature (adding `layout`, `placard`) is documented separately in the source.
package/docs/cli.md CHANGED
@@ -50,6 +50,13 @@ npx snice validate # source analyzer only
50
50
 
51
51
  - an `@element`-decorated class that does not extend `HTMLElement` (or a Snice element subclass) — Snice registers and renders only element subclasses
52
52
  - deep imports that were never released package paths, such as `snice/decorators`
53
+ - a Router without `target`, `type`, or a project-wide `initialize()` call
54
+ - a routed class combining `@page` with redundant `@element`
55
+
56
+ It also gives non-blocking architecture suggestions: keep `@page`, `@element`,
57
+ `@controller`, and `@daemon` classes under `src/pages`, `src/components`,
58
+ `src/controllers`, and `src/daemons`; extract clearly service-heavy or repeated
59
+ page logic into a controller. Small route orchestration remains valid page code.
53
60
 
54
61
  Both accept `--json` for CI.
55
62
 
@@ -32,9 +32,10 @@ Individual breadcrumb item (data element, no shadow DOM).
32
32
  | Property | Attribute | Type | Default | Description |
33
33
  |----------|-----------|------|---------|-------------|
34
34
  | `items` | -- | `BreadcrumbItem[]` | `[]` | Array of breadcrumb items (JS property only) |
35
- | `separator` | `separator` | `'/' \| '>' \| '>>' \| '.' \| '\|'` | `'/'` | Separator between items |
35
+ | `separator` | `separator` | `'/' \| '>' \| '»' \| '' \| '\|'` | `'/'` | Separator between items |
36
36
  | `size` | `size` | `'small' \| 'medium' \| 'large'` | `'medium'` | Breadcrumb size |
37
37
  | `maxItems` | `max-items` | `number` | `0` | Max items to show (0 = show all). Collapsed items show an ellipsis. |
38
+ | `collapsed` | `collapsed` | `boolean` | `true` | Whether the trail is collapsed behind the ellipsis. Clicking the ellipsis sets it `false`; it resets to `true` when `items`, `separator`, or `maxItems` change. Only has an effect once `maxItems` is exceeded. |
38
39
 
39
40
  ### BreadcrumbItem Interface
40
41
 
@@ -23,7 +23,7 @@ Display and select dates with event support, date restrictions, and locale-aware
23
23
  | `events` | `CalendarEvent[]` | `[]` | Calendar events |
24
24
  | `minDate` (attr: `min-date`) | `Date \| string` | `''` | Minimum selectable date |
25
25
  | `maxDate` (attr: `max-date`) | `Date \| string` | `''` | Maximum selectable date |
26
- | `disabledDates` (attr: `disabled-dates`) | `(Date \| string)[]` | `[]` | Disabled dates |
26
+ | `disabledDates` | `(Date \| string)[]` | `[]` | Disabled dates (JS-only; no attribute) |
27
27
  | `highlightToday` (attr: `highlight-today`) | `boolean` | `true` | Highlight today's date |
28
28
  | `showWeekNumbers` (attr: `show-week-numbers`) | `boolean` | `false` | Show week numbers |
29
29
  | `firstDayOfWeek` (attr: `first-day-of-week`) | `number` | `0` | First day of week (0=Sun, 1=Mon) |
@@ -19,7 +19,7 @@ Live camera feed with built-in mobile-style controls, flexible positioning, aspe
19
19
 
20
20
  | Property | Type | Default | Description |
21
21
  |----------|------|---------|-------------|
22
- | `autoStart` (attr: `auto-start`) | `boolean` | `true` | Auto-start camera on load |
22
+ | `autoStart` (attr: `auto-start`) | `boolean` | `false` | Auto-start camera on load |
23
23
  | `facingMode` (attr: `facing-mode`) | `'user' \| 'environment'` | `'user'` | Front or back camera |
24
24
  | `mirror` | `boolean` | `true` | Mirror video for front camera |
25
25
  | `controlsPosition` (attr: `controls-position`) | `ControlsPosition` | `'auto'` | Control button positioning |
@@ -19,7 +19,7 @@ General-purpose charting component supporting 10 chart types with animations, in
19
19
  | `type` | `ChartType` | `'line'` | Chart type: `'line'`, `'bar'`, `'horizontal-bar'`, `'area'`, `'pie'`, `'donut'`, `'scatter'`, `'bubble'`, `'radar'`, `'mixed'` |
20
20
  | `datasets` | `ChartDataset[]` | `[]` | Chart datasets (property only) |
21
21
  | `labels` | `string[]` | `[]` | X-axis labels (property only) |
22
- | `options` | `ChartOptions` | `{}` | Chart options (property only) |
22
+ | `options` | `ChartOptions` | see description | Chart options (property only). Defaults: responsive, no fixed aspect ratio, clickable legend on top, hover tooltip, 500ms ease-out animation, x/y grids on |
23
23
  | `width` | `number` | `0` | Chart width (0 = auto) |
24
24
  | `height` | `number` | `0` | Chart height (0 = auto) |
25
25
 
@@ -13,6 +13,10 @@ Display code with syntax highlighting, line numbers, and copy functionality. Use
13
13
  - [Basic Usage](#basic-usage)
14
14
  - [Examples](#examples)
15
15
  - [Accessibility](#accessibility)
16
+ - [Fetch Mode](#fetch-mode)
17
+ - [Grammar System](#grammar-system)
18
+ - [Highlighter API](#highlighter-api)
19
+ - [Token CSS Classes](#token-css-classes)
16
20
 
17
21
  ## Properties
18
22
 
@@ -20,10 +24,10 @@ Display code with syntax highlighting, line numbers, and copy functionality. Use
20
24
  |----------|------|---------|-------------|
21
25
  | `code` | `string` | `''` | Code content (set via slot or property) |
22
26
  | `language` | `CodeLanguage` | `'plaintext'` | Programming language |
23
- | `grammar` | `Grammar \| string \| null` | `null` | Grammar object or URL to grammar JSON |
27
+ | `grammar` | `Grammar \| string \| null` | `''` | Grammar object or URL to grammar JSON |
24
28
  | `showLineNumbers` (attr: `show-line-numbers`) | `boolean` | `false` | Show line numbers |
25
29
  | `startLine` (attr: `start-line`) | `number` | `1` | Starting line number |
26
- | `highlightLines` (attr: `highlight-lines`) | `number[]` | `[]` | Lines to highlight |
30
+ | `highlightLines` | `number[]` | `[]` | Lines to highlight (JS-only; no attribute) |
27
31
  | `copyable` | `boolean` | `true` | Show copy button |
28
32
  | `filename` | `string` | `''` | File name to display in header |
29
33
  | `format` | `string` | `''` | Formatter name from grammar (e.g. `"pretty"`), or any truthy string with `setFormatter()` |
@@ -104,10 +108,11 @@ console.log(greeting);
104
108
 
105
109
  ### Highlight Specific Lines
106
110
 
107
- Use `highlight-lines` to draw attention to specific lines.
111
+ Set `highlightLines` in JavaScript to draw attention to specific lines. There is no
112
+ `highlight-lines` attribute -- the property is JS-only.
108
113
 
109
114
  ```html
110
- <snice-code-block grammar="grammars/python.json" language="python" highlight-lines="[2,3,4]">
115
+ <snice-code-block id="snippet" grammar="grammars/python.json" language="python">
111
116
  def hello():
112
117
  name = "World"
113
118
  greeting = f"Hello {name}"
@@ -115,6 +120,10 @@ def hello():
115
120
  </snice-code-block>
116
121
  ```
117
122
 
123
+ ```typescript
124
+ document.getElementById('snippet').highlightLines = [2, 3, 4];
125
+ ```
126
+
118
127
  ### Programmatic Code
119
128
 
120
129
  Set code via the `code` property for dynamic content.