snice 7.6.0 → 7.8.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 (228) hide show
  1. package/adapters/react/SniceProvider.js +1 -1
  2. package/adapters/react/SniceRouter.js +1 -1
  3. package/adapters/react/calendar.d.ts +1 -0
  4. package/adapters/react/calendar.d.ts.map +1 -1
  5. package/adapters/react/calendar.js +1 -1
  6. package/adapters/react/calendar.js.map +1 -1
  7. package/adapters/react/calendar.tsx +2 -1
  8. package/adapters/react/matchRoute.js +1 -1
  9. package/adapters/react/useRequestHandler.js +1 -1
  10. package/bin/analyzer-contracts.js +8 -2
  11. package/custom-elements.json +15 -1
  12. package/dist/cdn/accordion/snice-accordion.js +1 -1
  13. package/dist/cdn/action-bar/snice-action-bar.js +1 -1
  14. package/dist/cdn/activity-feed/snice-activity-feed.js +1 -1
  15. package/dist/cdn/alert/snice-alert.js +1 -1
  16. package/dist/cdn/app-tiles/snice-app-tiles.js +1 -1
  17. package/dist/cdn/approval-flow/snice-approval-flow.js +1 -1
  18. package/dist/cdn/audio-recorder/snice-audio-recorder.js +1 -1
  19. package/dist/cdn/availability/snice-availability.js +1 -1
  20. package/dist/cdn/avatar/snice-avatar.js +1 -1
  21. package/dist/cdn/avatar-group/snice-avatar-group.js +1 -1
  22. package/dist/cdn/badge/snice-badge.js +1 -1
  23. package/dist/cdn/banner/snice-banner.js +1 -1
  24. package/dist/cdn/binpack/snice-binpack.js +1 -1
  25. package/dist/cdn/book/snice-book.js +1 -1
  26. package/dist/cdn/booking/snice-booking.js +1 -1
  27. package/dist/cdn/breadcrumbs/snice-breadcrumbs.js +1 -1
  28. package/dist/cdn/button/snice-button.js +2 -2
  29. package/dist/cdn/button/snice-button.js.map +1 -1
  30. package/dist/cdn/button/snice-button.min.js +1 -1
  31. package/dist/cdn/button/snice-button.min.js.map +1 -1
  32. package/dist/cdn/calendar/README.md +2 -2
  33. package/dist/cdn/calendar/snice-calendar.js +26 -2
  34. package/dist/cdn/calendar/snice-calendar.js.map +1 -1
  35. package/dist/cdn/calendar/snice-calendar.min.js +2 -2
  36. package/dist/cdn/calendar/snice-calendar.min.js.map +1 -1
  37. package/dist/cdn/camera/snice-camera.js +1 -1
  38. package/dist/cdn/camera-annotate/snice-camera-annotate.js +1 -1
  39. package/dist/cdn/candlestick/snice-candlestick.js +1 -1
  40. package/dist/cdn/card/snice-card.js +1 -1
  41. package/dist/cdn/carousel/snice-carousel.js +1 -1
  42. package/dist/cdn/cart/snice-cart.js +1 -1
  43. package/dist/cdn/chart/snice-chart.js +1 -1
  44. package/dist/cdn/chat/snice-chat.js +1 -1
  45. package/dist/cdn/checkbox/snice-checkbox.js +1 -1
  46. package/dist/cdn/chip/snice-chip.js +1 -1
  47. package/dist/cdn/code-block/snice-code-block.js +1 -1
  48. package/dist/cdn/color-display/snice-color-display.js +1 -1
  49. package/dist/cdn/color-picker/snice-color-picker.js +1 -1
  50. package/dist/cdn/command-palette/snice-command-palette.js +1 -1
  51. package/dist/cdn/comments/snice-comments.js +1 -1
  52. package/dist/cdn/countdown/snice-countdown.js +1 -1
  53. package/dist/cdn/cropper/snice-cropper.js +1 -1
  54. package/dist/cdn/data-card/snice-data-card.js +1 -1
  55. package/dist/cdn/date-picker/snice-date-picker.js +1 -1
  56. package/dist/cdn/date-range-picker/snice-date-range-picker.js +1 -1
  57. package/dist/cdn/date-time-picker/snice-date-time-picker.js +1 -1
  58. package/dist/cdn/diff/snice-diff.js +1 -1
  59. package/dist/cdn/divider/snice-divider.js +1 -1
  60. package/dist/cdn/doc/snice-doc.js +1 -1
  61. package/dist/cdn/draw/snice-draw.js +1 -1
  62. package/dist/cdn/drawer/snice-drawer.js +1 -1
  63. package/dist/cdn/empty-state/snice-empty-state.js +1 -1
  64. package/dist/cdn/estimate/snice-estimate.js +1 -1
  65. package/dist/cdn/file-gallery/snice-file-gallery.js +1 -1
  66. package/dist/cdn/file-upload/snice-file-upload.js +1 -1
  67. package/dist/cdn/flip-card/snice-flip-card.js +1 -1
  68. package/dist/cdn/flow/snice-flow.js +1 -1
  69. package/dist/cdn/form-layout/snice-form-layout.js +1 -1
  70. package/dist/cdn/funnel/snice-funnel.js +1 -1
  71. package/dist/cdn/gantt/snice-gantt.js +1 -1
  72. package/dist/cdn/gauge/snice-gauge.js +1 -1
  73. package/dist/cdn/grid/snice-grid.js +1 -1
  74. package/dist/cdn/heatmap/snice-heatmap.js +1 -1
  75. package/dist/cdn/image/snice-image.js +1 -1
  76. package/dist/cdn/input/snice-input.js +1 -1
  77. package/dist/cdn/invoice/snice-invoice.js +1 -1
  78. package/dist/cdn/kanban/snice-kanban.js +1 -1
  79. package/dist/cdn/key-value/snice-key-value.js +1 -1
  80. package/dist/cdn/kpi/snice-kpi.js +1 -1
  81. package/dist/cdn/layout/snice-layout.js +1 -1
  82. package/dist/cdn/leaderboard/snice-leaderboard.js +1 -1
  83. package/dist/cdn/link/snice-link.js +1 -1
  84. package/dist/cdn/link-preview/snice-link-preview.js +1 -1
  85. package/dist/cdn/list/snice-list.js +1 -1
  86. package/dist/cdn/location/snice-location.js +1 -1
  87. package/dist/cdn/login/README.md +1 -1
  88. package/dist/cdn/login/snice-login.js +2 -2
  89. package/dist/cdn/login/snice-login.js.map +1 -1
  90. package/dist/cdn/login/snice-login.min.js +1 -1
  91. package/dist/cdn/login/snice-login.min.js.map +1 -1
  92. package/dist/cdn/map/snice-map.js +1 -1
  93. package/dist/cdn/markdown/snice-markdown.js +1 -1
  94. package/dist/cdn/masonry/snice-masonry.js +1 -1
  95. package/dist/cdn/menu/snice-menu.js +1 -1
  96. package/dist/cdn/message-strip/snice-message-strip.js +1 -1
  97. package/dist/cdn/modal/snice-modal.js +1 -1
  98. package/dist/cdn/music-player/snice-music-player.js +1 -1
  99. package/dist/cdn/nav/snice-nav.js +1 -1
  100. package/dist/cdn/network-graph/snice-network-graph.js +1 -1
  101. package/dist/cdn/notification-center/snice-notification-center.js +1 -1
  102. package/dist/cdn/order-tracker/snice-order-tracker.js +1 -1
  103. package/dist/cdn/org-chart/snice-org-chart.js +1 -1
  104. package/dist/cdn/pagination/snice-pagination.js +1 -1
  105. package/dist/cdn/paint/snice-paint.js +1 -1
  106. package/dist/cdn/pdf-viewer/snice-pdf-viewer.js +1 -1
  107. package/dist/cdn/permission-matrix/snice-permission-matrix.js +1 -1
  108. package/dist/cdn/podcast-player/snice-podcast-player.js +1 -1
  109. package/dist/cdn/popover/snice-popover.js +1 -1
  110. package/dist/cdn/pricing-table/snice-pricing-table.js +1 -1
  111. package/dist/cdn/product-card/snice-product-card.js +1 -1
  112. package/dist/cdn/progress/snice-progress.js +1 -1
  113. package/dist/cdn/progress-ring/snice-progress-ring.js +1 -1
  114. package/dist/cdn/qr-code/snice-qr-code.js +1 -1
  115. package/dist/cdn/qr-reader/snice-qr-reader.js +1 -1
  116. package/dist/cdn/radio/snice-radio.js +1 -1
  117. package/dist/cdn/range-slider/snice-range-slider.js +1 -1
  118. package/dist/cdn/rating/snice-rating.js +1 -1
  119. package/dist/cdn/receipt/snice-receipt.js +1 -1
  120. package/dist/cdn/recipe/snice-recipe.js +1 -1
  121. package/dist/cdn/runtime/README.md +2 -2
  122. package/dist/cdn/runtime/snice-runtime.esm.js +130 -31
  123. package/dist/cdn/runtime/snice-runtime.esm.js.map +1 -1
  124. package/dist/cdn/runtime/snice-runtime.esm.min.js +1 -1
  125. package/dist/cdn/runtime/snice-runtime.esm.min.js.map +1 -1
  126. package/dist/cdn/runtime/snice-runtime.js +130 -31
  127. package/dist/cdn/runtime/snice-runtime.js.map +1 -1
  128. package/dist/cdn/runtime/snice-runtime.min.js +1 -1
  129. package/dist/cdn/runtime/snice-runtime.min.js.map +1 -1
  130. package/dist/cdn/sankey/snice-sankey.js +1 -1
  131. package/dist/cdn/segmented-control/snice-segmented-control.js +1 -1
  132. package/dist/cdn/select/snice-select.js +1 -1
  133. package/dist/cdn/skeleton/snice-skeleton.js +1 -1
  134. package/dist/cdn/slider/snice-slider.js +1 -1
  135. package/dist/cdn/sortable/snice-sortable.js +1 -1
  136. package/dist/cdn/sparkline/snice-sparkline.js +1 -1
  137. package/dist/cdn/spinner/snice-spinner.js +1 -1
  138. package/dist/cdn/split-button/snice-split-button.js +1 -1
  139. package/dist/cdn/split-pane/snice-split-pane.js +1 -1
  140. package/dist/cdn/spotlight/snice-spotlight.js +1 -1
  141. package/dist/cdn/stat-group/snice-stat-group.js +1 -1
  142. package/dist/cdn/step-input/snice-step-input.js +1 -1
  143. package/dist/cdn/stepper/snice-stepper.js +1 -1
  144. package/dist/cdn/switch/snice-switch.js +1 -1
  145. package/dist/cdn/table/README.md +2 -2
  146. package/dist/cdn/table/snice-table.esm.js +227 -36
  147. package/dist/cdn/table/snice-table.esm.js.map +1 -1
  148. package/dist/cdn/table/snice-table.esm.min.js +69 -48
  149. package/dist/cdn/table/snice-table.esm.min.js.map +1 -1
  150. package/dist/cdn/table/snice-table.js +226 -35
  151. package/dist/cdn/table/snice-table.js.map +1 -1
  152. package/dist/cdn/table/snice-table.min.js +47 -26
  153. package/dist/cdn/table/snice-table.min.js.map +1 -1
  154. package/dist/cdn/tabs/snice-tabs.js +1 -1
  155. package/dist/cdn/tag/snice-tag.js +1 -1
  156. package/dist/cdn/tag-input/README.md +2 -2
  157. package/dist/cdn/tag-input/snice-tag-input.js +10 -16
  158. package/dist/cdn/tag-input/snice-tag-input.js.map +1 -1
  159. package/dist/cdn/tag-input/snice-tag-input.min.js +2 -2
  160. package/dist/cdn/tag-input/snice-tag-input.min.js.map +1 -1
  161. package/dist/cdn/terminal/snice-terminal.js +1 -1
  162. package/dist/cdn/testimonial/snice-testimonial.js +1 -1
  163. package/dist/cdn/textarea/snice-textarea.js +1 -1
  164. package/dist/cdn/time-picker/snice-time-picker.js +1 -1
  165. package/dist/cdn/time-range-picker/snice-time-range-picker.js +1 -1
  166. package/dist/cdn/timeline/snice-timeline.js +1 -1
  167. package/dist/cdn/timer/snice-timer.js +1 -1
  168. package/dist/cdn/toast/snice-toast.js +1 -1
  169. package/dist/cdn/tooltip/snice-tooltip.js +1 -1
  170. package/dist/cdn/tree/snice-tree.js +1 -1
  171. package/dist/cdn/treemap/snice-treemap.js +1 -1
  172. package/dist/cdn/user-card/snice-user-card.js +1 -1
  173. package/dist/cdn/video-player/snice-video-player.js +1 -1
  174. package/dist/cdn/virtual-scroller/snice-virtual-scroller.js +1 -1
  175. package/dist/cdn/waterfall/snice-waterfall.js +1 -1
  176. package/dist/cdn/weather/snice-weather.js +1 -1
  177. package/dist/cdn/work-order/snice-work-order.js +1 -1
  178. package/dist/components/button/snice-button.js +1 -1
  179. package/dist/components/button/snice-button.js.map +1 -1
  180. package/dist/components/calendar/snice-calendar.d.ts +2 -0
  181. package/dist/components/calendar/snice-calendar.js +25 -1
  182. package/dist/components/calendar/snice-calendar.js.map +1 -1
  183. package/dist/components/table/snice-row.d.ts +6 -0
  184. package/dist/components/table/snice-row.js +11 -3
  185. package/dist/components/table/snice-row.js.map +1 -1
  186. package/dist/components/table/snice-table.d.ts +40 -3
  187. package/dist/components/table/snice-table.js +157 -17
  188. package/dist/components/table/snice-table.js.map +1 -1
  189. package/dist/components/table/table-cell-presentation.d.ts +11 -0
  190. package/dist/components/table/table-cell-presentation.js +25 -8
  191. package/dist/components/table/table-cell-presentation.js.map +1 -1
  192. package/dist/components/table/table-export.d.ts +6 -0
  193. package/dist/components/table/table-export.js +11 -2
  194. package/dist/components/table/table-export.js.map +1 -1
  195. package/dist/components/table/table-keyboard.js +1 -1
  196. package/dist/components/table/table-keyboard.js.map +1 -1
  197. package/dist/components/table/table-master-detail.d.ts +11 -2
  198. package/dist/components/table/table-master-detail.js +20 -3
  199. package/dist/components/table/table-master-detail.js.map +1 -1
  200. package/dist/components/tag-input/snice-tag-input.d.ts +2 -2
  201. package/dist/components/tag-input/snice-tag-input.js +9 -15
  202. package/dist/components/tag-input/snice-tag-input.js.map +1 -1
  203. package/dist/index.cjs +127 -28
  204. package/dist/index.cjs.map +1 -1
  205. package/dist/index.esm.js +127 -28
  206. package/dist/index.esm.js.map +1 -1
  207. package/dist/index.iife.js +127 -28
  208. package/dist/index.iife.js.map +1 -1
  209. package/dist/react/SniceProvider.js +1 -1
  210. package/dist/react/SniceRouter.js +1 -1
  211. package/dist/react/index.js +1 -1
  212. package/dist/react/matchRoute.js +1 -1
  213. package/dist/react/useRequestHandler.js +1 -1
  214. package/dist/request-response.d.ts +24 -1
  215. package/dist/symbols.cjs +1 -1
  216. package/dist/symbols.esm.js +1 -1
  217. package/dist/testing-dom.cjs +1 -1
  218. package/dist/testing-dom.esm.js +1 -1
  219. package/dist/transitions.cjs +1 -1
  220. package/dist/transitions.esm.js +1 -1
  221. package/docs/ai/DEVELOPMENT.md +1 -1
  222. package/docs/ai/components/calendar.md +8 -0
  223. package/docs/ai/components/tag-input.md +4 -0
  224. package/docs/ai/controllers.md +22 -6
  225. package/docs/components/calendar.md +24 -0
  226. package/docs/components/tag-input.md +6 -1
  227. package/docs/controllers.md +57 -6
  228. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.5.1
2
+ * snice v7.7.0
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.5.1
2
+ * snice v7.7.0
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.5.1
2
+ * snice v7.7.0
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.5.1
2
+ * snice v7.7.0
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.5.1
2
+ * snice v7.7.0
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -23,5 +23,28 @@ export declare function request<T = any>(requestName: string, options?: RequestO
23
23
  * @param options Optional configuration
24
24
  */
25
25
  export declare function respond(requestName: string, options?: RespondOptions): (target: any, context: ClassMethodDecoratorContext) => void;
26
- export declare function setupResponseHandlers(instance: any, element: EventTarget): void;
26
+ export interface SetupResponseHandlerOptions {
27
+ /**
28
+ * Runs on every incoming request and must settle before the responder method
29
+ * is invoked. Controllers use it to accept requests that arrive while their
30
+ * host is still becoming ready: discovery resolves at once, the answer
31
+ * follows as soon as the controller is attached.
32
+ */
33
+ claim?: () => Promise<void>;
34
+ /**
35
+ * Keep a `@respond({ daemon })` handler unregistered — and silent — when its
36
+ * daemon is not resolvable yet, instead of warning and dropping it. A caller
37
+ * that registers early (before the host is connected or ready) passes this
38
+ * and calls `setupResponseHandlers` again later; the second call registers
39
+ * whatever was deferred and warns then if it is still unresolvable.
40
+ */
41
+ deferUnresolvableDaemons?: boolean;
42
+ }
43
+ /**
44
+ * Helper to setup response handlers for elements and controllers.
45
+ *
46
+ * Safe to call more than once for the same instance: a handler already
47
+ * registered is skipped rather than double-bound.
48
+ */
49
+ export declare function setupResponseHandlers(instance: any, element: EventTarget, options?: SetupResponseHandlerOptions): void;
27
50
  export declare function cleanupResponseHandlers(instance: any): void;
package/dist/symbols.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.5.1
2
+ * snice v7.7.0
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.5.1
2
+ * snice v7.7.0
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.5.1
2
+ * snice v7.7.0
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.5.1
2
+ * snice v7.7.0
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.5.1
2
+ * snice v7.7.0
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.5.1
2
+ * snice v7.7.0
3
3
  * A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.
4
4
  * (c) 2024
5
5
  * Released under the MIT License.
@@ -140,7 +140,7 @@ All CDN builds use the shared runtime (external `snice` imports). Load `snice-ru
140
140
  - IIFE: `.js` + `.min.js`
141
141
  - Sourcemaps + README
142
142
 
143
- **Size:** Runtime ~34KB gzip, components ~1-110KB each
143
+ **Size:** Runtime ~34KB gzip, components ~1-111KB each
144
144
 
145
145
  **Features:**
146
146
  - Shared runtime (external snice imports)
@@ -33,12 +33,15 @@ cellSizing: 'square'|'stretch' = 'square'; // attribute: cell-sizing — square:
33
33
 
34
34
  - `calendar-change` -> `{ value: Date, calendar: SniceCalendarElement }`
35
35
  - `calendar-event-click` -> `{ event: CalendarEvent, calendar: SniceCalendarElement }`
36
+ - `calendar-more-click` -> `{ date: Date, count: number, calendar: SniceCalendarElement }` — "+N more" chip clicked; does NOT fire `calendar-change`
36
37
 
37
38
  ## CSS Parts
38
39
 
39
40
  - `base` - Main calendar container
40
41
  - `header` - Header with title and navigation buttons
41
42
  - `grid` - Day cells grid
43
+ - `more-chip` - Per-day "+N more" overflow chip
44
+ - `event-bar` / `event-avatar` / `event-tooltip` / `event-popover` - Event bar internals
42
45
 
43
46
  ## Basic Usage
44
47
 
@@ -57,6 +60,11 @@ calendar.events = [
57
60
  // at week boundaries (squared corners on the continuing side, title repeats).
58
61
  // Concurrent events stack into lanes (start asc, longer first on ties);
59
62
  // max 3 lanes, deeper stacks collapse to a per-day "+N more" chip.
63
+ // Chip: part="more-chip", role="button" tabindex=0 (Enter/Space), click ->
64
+ // calendar-more-click { date, count }; the click never falls through to day
65
+ // selection. Use it to open your own day/agenda view:
66
+ // calendar.addEventListener('calendar-more-click',
67
+ // (e) => showDay(e.detail.date, e.detail.count));
60
68
  // Bars: part="event-bar", click -> calendar-event-click.
61
69
  // Styling: color -> background; avatar?: string | {src?,name?,alt?} ->
62
70
  // <snice-avatar> on each bar (part="event-avatar"; name -> initials fallback);
@@ -51,6 +51,10 @@ readonly labels: NodeList | null;
51
51
  - `tag-remove` -> `{ tag: string; index: number; value: string[] }`
52
52
  - `tag-change` -> `{ value: string[] }`
53
53
 
54
+ Emitted only by tag edits (`addTag()`, `removeTag()`, and the user actions that
55
+ call them). Assigning `value`, `clear()`, reset, and restoration are silent, so a
56
+ `.value` binding fed from `tag-change` cannot loop.
57
+
54
58
  ## CSS Parts
55
59
 
56
60
  - `base` - Outer wrapper div
@@ -78,21 +78,37 @@ el.controller = UserController; // snice elements
78
78
  1. Controller instance created
79
79
  2. `element` property set
80
80
  3. Router application context passed (if available)
81
- 4. Element's `ready` promise awaited
82
- 5. `attach()` called
83
- 6. `@context` handlers registered and caught up with the current Router context
84
- 7. Observers set up
85
- 8. Channel/response handlers set up
81
+ 4. Channel/response handlers (`@respond`) set up
82
+ 5. Element's `ready` promise awaited
83
+ 6. `attach()` called
84
+ 7. `@context` handlers registered and caught up with the current Router context
85
+ 8. Observers set up
86
86
  9. Event handlers set up
87
87
  10. `controller-attached` event dispatched
88
88
 
89
- Exception to step 4: `await attachController(this, ControllerClass)` inside the
89
+ Exception to step 5: `await attachController(this, ControllerClass)` inside the
90
90
  host's own `@ready` handler attaches immediately because initial render is
91
91
  already complete. Awaiting that same host's `ready` would self-deadlock. An
92
92
  attachment targeting any other element still waits for the target's `ready`.
93
93
  This runtime safeguard does not make attaching a controller to a routed page a
94
94
  good architecture; pages should orchestrate directly.
95
95
 
96
+ `@respond` is installed at step 4, before the wait — the same ordering elements
97
+ use (an element installs `@respond` on connection, not at `ready`). A child's
98
+ mount-time `@request` therefore finds the controller even while the host is
99
+ still becoming ready: discovery resolves immediately, the request releases the
100
+ step-5 wait, and the handler runs once `attach()` and the remaining setup are
101
+ done. Without that ordering, a host whose `@ready` awaits a child that requests
102
+ on mount would deadlock — the child waits for a responder that is waiting for
103
+ the host's `ready` — and the attachment would fail. The responder body still
104
+ never runs before `attach()`, so state built there is safe to use.
105
+
106
+ `@respond('name', { daemon })` needs the host's app context to resolve its
107
+ target, and that context is unreachable while the host is still disconnected
108
+ (`attachController(el, C)` before `appendChild`). Resolvable → registered at
109
+ step 4 like the rest; not resolvable → registered after step 6 instead of being
110
+ dropped.
111
+
96
112
  **Detachment flow:**
97
113
  1. `detach()` called
98
114
  2. `element` property set to null
@@ -75,6 +75,7 @@ interface CalendarEventAvatar {
75
75
  |-------|--------|-------------|
76
76
  | `calendar-change` | `{ value: Date, calendar: SniceCalendarElement }` | Fired when selected date changes |
77
77
  | `calendar-event-click` | `{ event: CalendarEvent, calendar: SniceCalendarElement }` | Fired when an event is clicked |
78
+ | `calendar-more-click` | `{ date: Date, count: number, calendar: SniceCalendarElement }` | Fired when a day's `+N more` chip is clicked (or activated with Enter/Space). The day is not selected and `calendar-change` does not fire |
78
79
 
79
80
  ## CSS Parts
80
81
 
@@ -85,6 +86,11 @@ Style internal elements from outside the shadow DOM using `::part()`.
85
86
  | `base` | The main calendar container |
86
87
  | `header` | The header with month title and navigation buttons |
87
88
  | `grid` | The day cells grid |
89
+ | `more-chip` | A day's `+N more` overflow chip |
90
+ | `event-bar` | An event stripe (plus any `className` you set on the event) |
91
+ | `event-avatar` | The `<snice-avatar>` rendered at the start of an event bar |
92
+ | `event-tooltip` | The shared tooltip overlay shown on event hover |
93
+ | `event-popover` | The popover opened by a `popover`-enabled event |
88
94
 
89
95
  ```css
90
96
  snice-calendar::part(base) {
@@ -135,6 +141,24 @@ shown; days with deeper stacks get a `+N more` chip. Each bar exposes a
135
141
  `part="event-bar"` for styling and dispatches `calendar-event-click` when
136
142
  clicked.
137
143
 
144
+ The `+N more` chip is a control of its own: it exposes `part="more-chip"`, is
145
+ keyboard-reachable (`role="button"`, Enter/Space), and dispatches
146
+ `calendar-more-click` with the day it belongs to and how many events are
147
+ hidden there. Its click never falls through to day selection, so opening a
148
+ day view does not change the selected date:
149
+
150
+ ```typescript
151
+ calendar.addEventListener('calendar-more-click', (e) => {
152
+ // e.detail.date -> the day whose events overflowed
153
+ // e.detail.count -> how many events are hidden on that day
154
+ showDayAgenda(e.detail.date, calendar.getEventsForDate(e.detail.date));
155
+ });
156
+ ```
157
+
158
+ ```css
159
+ snice-calendar::part(more-chip) { color: #2563eb; }
160
+ ```
161
+
138
162
  Bars are styleable per event: `color` sets the background, `avatar` renders a
139
163
  small `<snice-avatar>` at the start of each bar (`part="event-avatar"`) — an
140
164
  image when `src` is given, initials from `name` otherwise — and `className` is
@@ -55,7 +55,12 @@ A chip/tag-style input field where users can add tags by typing and pressing Ent
55
55
  |-------|--------|-------------|
56
56
  | `tag-add` | `{ tag: string, value: string[] }` | A new tag was added |
57
57
  | `tag-remove` | `{ tag: string, index: number, value: string[] }` | A tag was removed |
58
- | `tag-change` | `{ value: string[] }` | The tag list changed (add or remove) |
58
+ | `tag-change` | `{ value: string[] }` | A tag was added or removed |
59
+
60
+ `tag-add`, `tag-remove`, and `tag-change` describe tag edits: typing, removing a
61
+ tag, selecting a suggestion, `addTag()`, and `removeTag()`. Assigning `value`,
62
+ calling `clear()`, form reset, and form restoration change the tags silently, so
63
+ binding `value` to the `tag-change` payload never re-enters.
59
64
 
60
65
  ## CSS Parts
61
66
 
@@ -128,15 +128,15 @@ through the element's reactive properties or events.
128
128
  1. Controller instance is created
129
129
  2. `element` property is set
130
130
  3. Router application context is passed (if available)
131
- 4. Element's `ready` promise is awaited
132
- 5. `attach()` method is called
133
- 6. `@context` handlers are registered and caught up with the current Router context
134
- 7. Observers are set up
135
- 8. Channel/response handlers are set up
131
+ 4. Channel/response handlers (`@respond`) are set up
132
+ 5. Element's `ready` promise is awaited
133
+ 6. `attach()` method is called
134
+ 7. `@context` handlers are registered and caught up with the current Router context
135
+ 8. Observers are set up
136
136
  9. Event handlers are set up
137
137
  10. `controller-attached` event is dispatched
138
138
 
139
- The step-4 wait has one safe exception: when an element calls
139
+ The step-5 wait has one safe exception: when an element calls
140
140
  `await attachController(this, ControllerClass)` from its own `@ready` handler,
141
141
  Snice attaches immediately. Initial rendering has already completed at that
142
142
  point, and waiting for `ready` would otherwise create a self-deadlock because
@@ -145,6 +145,57 @@ other element still awaits that element's `ready` promise.
145
145
  This runtime safeguard does not make attaching a controller to a routed page a
146
146
  good architecture; pages should orchestrate directly.
147
147
 
148
+ #### Responders Are Reachable Before the Host Is Ready
149
+
150
+ `@respond` handlers are installed at step 4, *before* the wait — the same
151
+ ordering elements use, where `@respond` is installed on connection rather than
152
+ at `ready`. This matters for the common shape where a host's `@ready` waits on
153
+ a child that makes a request as it mounts:
154
+
155
+ ```typescript
156
+ @element('report-host')
157
+ class ReportHost extends HTMLElement {
158
+ @ready()
159
+ async onReady() {
160
+ // The host cannot finish becoming ready until the child does...
161
+ await this.chart.ready;
162
+ }
163
+
164
+ @render()
165
+ renderContent() { return html`<report-chart></report-chart>`; }
166
+ }
167
+
168
+ @element('report-chart')
169
+ class ReportChart extends HTMLElement {
170
+ @request('report-data')
171
+ async *load(): Response<void> {
172
+ // ...and the child cannot finish until something answers this.
173
+ this.data = await (yield { range: '30d' });
174
+ }
175
+
176
+ @ready()
177
+ async onReady() { await this.load(); }
178
+ }
179
+ ```
180
+
181
+ With `<report-host controller="report-controller">` answering `report-data`, the
182
+ child's request reaches the controller while the host's `ready` is still
183
+ pending: discovery resolves immediately, the request releases the step-5 wait,
184
+ and the responder runs once `attach()` and the remaining setup have completed.
185
+ If the responder were only installed after `ready`, the two sides would wait on
186
+ each other until a timeout fired and the attachment would fail outright.
187
+
188
+ The responder *body* still never runs before `attach()`, so anything the
189
+ controller builds in `attach()` is safe to use inside a `@respond` method.
190
+
191
+ `@respond('name', { daemon: 'x' })` has one extra condition. A daemon target is
192
+ resolved through the host's app context, which is unreachable while the host is
193
+ still disconnected — the shape where `attachController(el, Controller)` runs
194
+ before `el` is appended. When the context already resolves, the daemon-scoped
195
+ responder registers at step 4 with every other responder; when it does not, it
196
+ registers after `attach()` instead of being dropped, exactly where it registered
197
+ before.
198
+
148
199
  ### Detachment Flow
149
200
 
150
201
  1. `detach()` method is called
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "snice",
3
- "version": "7.6.0",
3
+ "version": "7.8.0",
4
4
  "type": "module",
5
5
  "description": "A decorator-driven web component library with routing, controllers, daemons, and 130+ UI components. For better coding-agent results, run npx snice init-ai.",
6
6
  "main": "dist/index.cjs",