snice 7.5.0 → 7.7.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 (265) hide show
  1. package/adapters/react/SniceProvider.js +1 -1
  2. package/adapters/react/SniceRouter.js +1 -1
  3. package/adapters/react/avatar.d.ts +1 -0
  4. package/adapters/react/avatar.d.ts.map +1 -1
  5. package/adapters/react/avatar.js +1 -1
  6. package/adapters/react/avatar.js.map +1 -1
  7. package/adapters/react/avatar.tsx +2 -1
  8. package/adapters/react/calendar.d.ts +4 -0
  9. package/adapters/react/calendar.d.ts.map +1 -1
  10. package/adapters/react/calendar.js +1 -1
  11. package/adapters/react/calendar.js.map +1 -1
  12. package/adapters/react/calendar.tsx +5 -1
  13. package/adapters/react/matchRoute.js +68 -2
  14. package/adapters/react/matchRoute.js.map +1 -1
  15. package/adapters/react/route-match.d.ts +7 -0
  16. package/adapters/react/useRequestHandler.js +1 -1
  17. package/bin/analyzer-contracts.js +60 -2
  18. package/bin/project-analyzer.js +1262 -118
  19. package/bin/snice.js +95 -5
  20. package/custom-elements.json +112 -0
  21. package/dist/cdn/accordion/snice-accordion.js +1 -1
  22. package/dist/cdn/action-bar/snice-action-bar.js +1 -1
  23. package/dist/cdn/activity-feed/snice-activity-feed.js +1 -1
  24. package/dist/cdn/alert/snice-alert.js +1 -1
  25. package/dist/cdn/app-tiles/snice-app-tiles.js +1 -1
  26. package/dist/cdn/approval-flow/snice-approval-flow.js +1 -1
  27. package/dist/cdn/audio-recorder/snice-audio-recorder.js +1 -1
  28. package/dist/cdn/availability/snice-availability.js +1 -1
  29. package/dist/cdn/avatar/README.md +1 -1
  30. package/dist/cdn/avatar/snice-avatar.js +9 -3
  31. package/dist/cdn/avatar/snice-avatar.js.map +1 -1
  32. package/dist/cdn/avatar/snice-avatar.min.js +2 -2
  33. package/dist/cdn/avatar/snice-avatar.min.js.map +1 -1
  34. package/dist/cdn/avatar-group/snice-avatar-group.js +1 -1
  35. package/dist/cdn/badge/snice-badge.js +1 -1
  36. package/dist/cdn/banner/snice-banner.js +1 -1
  37. package/dist/cdn/binpack/snice-binpack.js +1 -1
  38. package/dist/cdn/book/snice-book.js +1 -1
  39. package/dist/cdn/booking/snice-booking.js +1 -1
  40. package/dist/cdn/breadcrumbs/snice-breadcrumbs.js +1 -1
  41. package/dist/cdn/button/snice-button.js +2 -2
  42. package/dist/cdn/button/snice-button.js.map +1 -1
  43. package/dist/cdn/button/snice-button.min.js +1 -1
  44. package/dist/cdn/button/snice-button.min.js.map +1 -1
  45. package/dist/cdn/calendar/README.md +2 -2
  46. package/dist/cdn/calendar/snice-calendar.js +562 -40
  47. package/dist/cdn/calendar/snice-calendar.js.map +1 -1
  48. package/dist/cdn/calendar/snice-calendar.min.js +28 -1
  49. package/dist/cdn/calendar/snice-calendar.min.js.map +1 -1
  50. package/dist/cdn/camera/snice-camera.js +1 -1
  51. package/dist/cdn/camera-annotate/snice-camera-annotate.js +1 -1
  52. package/dist/cdn/candlestick/snice-candlestick.js +1 -1
  53. package/dist/cdn/card/snice-card.js +1 -1
  54. package/dist/cdn/carousel/snice-carousel.js +1 -1
  55. package/dist/cdn/cart/snice-cart.js +1 -1
  56. package/dist/cdn/chart/snice-chart.js +1 -1
  57. package/dist/cdn/chat/snice-chat.js +1 -1
  58. package/dist/cdn/checkbox/snice-checkbox.js +1 -1
  59. package/dist/cdn/chip/snice-chip.js +1 -1
  60. package/dist/cdn/code-block/snice-code-block.js +1 -1
  61. package/dist/cdn/color-display/snice-color-display.js +1 -1
  62. package/dist/cdn/color-picker/snice-color-picker.js +1 -1
  63. package/dist/cdn/command-palette/snice-command-palette.js +1 -1
  64. package/dist/cdn/comments/snice-comments.js +1 -1
  65. package/dist/cdn/countdown/snice-countdown.js +1 -1
  66. package/dist/cdn/cropper/snice-cropper.js +1 -1
  67. package/dist/cdn/data-card/snice-data-card.js +1 -1
  68. package/dist/cdn/date-picker/snice-date-picker.js +1 -1
  69. package/dist/cdn/date-range-picker/snice-date-range-picker.js +1 -1
  70. package/dist/cdn/date-time-picker/snice-date-time-picker.js +1 -1
  71. package/dist/cdn/diff/snice-diff.js +1 -1
  72. package/dist/cdn/divider/snice-divider.js +1 -1
  73. package/dist/cdn/doc/snice-doc.js +1 -1
  74. package/dist/cdn/draw/snice-draw.js +1 -1
  75. package/dist/cdn/drawer/snice-drawer.js +1 -1
  76. package/dist/cdn/empty-state/snice-empty-state.js +1 -1
  77. package/dist/cdn/estimate/snice-estimate.js +1 -1
  78. package/dist/cdn/file-gallery/snice-file-gallery.js +1 -1
  79. package/dist/cdn/file-upload/snice-file-upload.js +1 -1
  80. package/dist/cdn/flip-card/snice-flip-card.js +1 -1
  81. package/dist/cdn/flow/snice-flow.js +1 -1
  82. package/dist/cdn/form-layout/snice-form-layout.js +1 -1
  83. package/dist/cdn/funnel/snice-funnel.js +1 -1
  84. package/dist/cdn/gantt/snice-gantt.js +1 -1
  85. package/dist/cdn/gauge/snice-gauge.js +1 -1
  86. package/dist/cdn/grid/snice-grid.js +1 -1
  87. package/dist/cdn/heatmap/snice-heatmap.js +1 -1
  88. package/dist/cdn/image/snice-image.js +1 -1
  89. package/dist/cdn/input/snice-input.js +1 -1
  90. package/dist/cdn/invoice/snice-invoice.js +1 -1
  91. package/dist/cdn/kanban/snice-kanban.js +1 -1
  92. package/dist/cdn/key-value/snice-key-value.js +1 -1
  93. package/dist/cdn/kpi/snice-kpi.js +1 -1
  94. package/dist/cdn/layout/snice-layout.js +1 -1
  95. package/dist/cdn/leaderboard/snice-leaderboard.js +1 -1
  96. package/dist/cdn/link/snice-link.js +1 -1
  97. package/dist/cdn/link-preview/snice-link-preview.js +1 -1
  98. package/dist/cdn/list/snice-list.js +1 -1
  99. package/dist/cdn/location/snice-location.js +1 -1
  100. package/dist/cdn/login/README.md +1 -1
  101. package/dist/cdn/login/snice-login.js +2 -2
  102. package/dist/cdn/login/snice-login.js.map +1 -1
  103. package/dist/cdn/login/snice-login.min.js +1 -1
  104. package/dist/cdn/login/snice-login.min.js.map +1 -1
  105. package/dist/cdn/map/snice-map.js +1 -1
  106. package/dist/cdn/markdown/snice-markdown.js +1 -1
  107. package/dist/cdn/masonry/snice-masonry.js +1 -1
  108. package/dist/cdn/menu/snice-menu.js +1 -1
  109. package/dist/cdn/message-strip/snice-message-strip.js +1 -1
  110. package/dist/cdn/modal/snice-modal.js +1 -1
  111. package/dist/cdn/music-player/snice-music-player.js +1 -1
  112. package/dist/cdn/nav/snice-nav.js +1 -1
  113. package/dist/cdn/network-graph/snice-network-graph.js +1 -1
  114. package/dist/cdn/notification-center/snice-notification-center.js +1 -1
  115. package/dist/cdn/order-tracker/snice-order-tracker.js +1 -1
  116. package/dist/cdn/org-chart/snice-org-chart.js +1 -1
  117. package/dist/cdn/pagination/snice-pagination.js +1 -1
  118. package/dist/cdn/paint/snice-paint.js +1 -1
  119. package/dist/cdn/pdf-viewer/snice-pdf-viewer.js +1 -1
  120. package/dist/cdn/permission-matrix/snice-permission-matrix.js +1 -1
  121. package/dist/cdn/podcast-player/snice-podcast-player.js +1 -1
  122. package/dist/cdn/popover/snice-popover.js +1 -1
  123. package/dist/cdn/pricing-table/snice-pricing-table.js +1 -1
  124. package/dist/cdn/product-card/snice-product-card.js +1 -1
  125. package/dist/cdn/progress/snice-progress.js +1 -1
  126. package/dist/cdn/progress-ring/snice-progress-ring.js +1 -1
  127. package/dist/cdn/qr-code/snice-qr-code.js +1 -1
  128. package/dist/cdn/qr-reader/snice-qr-reader.js +1 -1
  129. package/dist/cdn/radio/snice-radio.js +1 -1
  130. package/dist/cdn/range-slider/snice-range-slider.js +1 -1
  131. package/dist/cdn/rating/snice-rating.js +1 -1
  132. package/dist/cdn/receipt/snice-receipt.js +1 -1
  133. package/dist/cdn/recipe/snice-recipe.js +1 -1
  134. package/dist/cdn/runtime/README.md +2 -2
  135. package/dist/cdn/runtime/snice-runtime.esm.js +706 -267
  136. package/dist/cdn/runtime/snice-runtime.esm.js.map +1 -1
  137. package/dist/cdn/runtime/snice-runtime.esm.min.js +1 -1
  138. package/dist/cdn/runtime/snice-runtime.esm.min.js.map +1 -1
  139. package/dist/cdn/runtime/snice-runtime.js +706 -267
  140. package/dist/cdn/runtime/snice-runtime.js.map +1 -1
  141. package/dist/cdn/runtime/snice-runtime.min.js +1 -1
  142. package/dist/cdn/runtime/snice-runtime.min.js.map +1 -1
  143. package/dist/cdn/sankey/snice-sankey.js +1 -1
  144. package/dist/cdn/segmented-control/snice-segmented-control.js +1 -1
  145. package/dist/cdn/select/snice-select.js +3 -1
  146. package/dist/cdn/select/snice-select.js.map +1 -1
  147. package/dist/cdn/select/snice-select.min.js +2 -2
  148. package/dist/cdn/select/snice-select.min.js.map +1 -1
  149. package/dist/cdn/skeleton/snice-skeleton.js +1 -1
  150. package/dist/cdn/slider/snice-slider.js +1 -1
  151. package/dist/cdn/sortable/snice-sortable.js +1 -1
  152. package/dist/cdn/sparkline/snice-sparkline.js +1 -1
  153. package/dist/cdn/spinner/snice-spinner.js +1 -1
  154. package/dist/cdn/split-button/snice-split-button.js +1 -1
  155. package/dist/cdn/split-pane/snice-split-pane.js +1 -1
  156. package/dist/cdn/spotlight/snice-spotlight.js +1 -1
  157. package/dist/cdn/stat-group/snice-stat-group.js +1 -1
  158. package/dist/cdn/step-input/snice-step-input.js +1 -1
  159. package/dist/cdn/stepper/snice-stepper.js +1 -1
  160. package/dist/cdn/switch/README.md +1 -1
  161. package/dist/cdn/switch/snice-switch.js +8 -4
  162. package/dist/cdn/switch/snice-switch.js.map +1 -1
  163. package/dist/cdn/switch/snice-switch.min.js +8 -4
  164. package/dist/cdn/switch/snice-switch.min.js.map +1 -1
  165. package/dist/cdn/table/README.md +2 -2
  166. package/dist/cdn/table/snice-table.esm.js +77 -5
  167. package/dist/cdn/table/snice-table.esm.js.map +1 -1
  168. package/dist/cdn/table/snice-table.esm.min.js +68 -47
  169. package/dist/cdn/table/snice-table.esm.min.js.map +1 -1
  170. package/dist/cdn/table/snice-table.js +76 -4
  171. package/dist/cdn/table/snice-table.js.map +1 -1
  172. package/dist/cdn/table/snice-table.min.js +53 -32
  173. package/dist/cdn/table/snice-table.min.js.map +1 -1
  174. package/dist/cdn/tabs/snice-tabs.js +1 -1
  175. package/dist/cdn/tag/snice-tag.js +1 -1
  176. package/dist/cdn/tag-input/snice-tag-input.js +1 -1
  177. package/dist/cdn/terminal/snice-terminal.js +1 -1
  178. package/dist/cdn/testimonial/snice-testimonial.js +1 -1
  179. package/dist/cdn/textarea/snice-textarea.js +1 -1
  180. package/dist/cdn/time-picker/snice-time-picker.js +1 -1
  181. package/dist/cdn/time-range-picker/snice-time-range-picker.js +1 -1
  182. package/dist/cdn/timeline/snice-timeline.js +1 -1
  183. package/dist/cdn/timer/snice-timer.js +1 -1
  184. package/dist/cdn/toast/snice-toast.js +1 -1
  185. package/dist/cdn/tooltip/snice-tooltip.js +1 -1
  186. package/dist/cdn/tree/snice-tree.js +1 -1
  187. package/dist/cdn/treemap/snice-treemap.js +1 -1
  188. package/dist/cdn/user-card/snice-user-card.js +1 -1
  189. package/dist/cdn/video-player/snice-video-player.js +1 -1
  190. package/dist/cdn/virtual-scroller/snice-virtual-scroller.js +1 -1
  191. package/dist/cdn/waterfall/snice-waterfall.js +1 -1
  192. package/dist/cdn/weather/snice-weather.js +1 -1
  193. package/dist/cdn/work-order/snice-work-order.js +1 -1
  194. package/dist/components/avatar/snice-avatar.d.ts +1 -0
  195. package/dist/components/avatar/snice-avatar.js +8 -2
  196. package/dist/components/avatar/snice-avatar.js.map +1 -1
  197. package/dist/components/avatar/snice-avatar.types.d.ts +2 -0
  198. package/dist/components/button/snice-button.js +1 -1
  199. package/dist/components/button/snice-button.js.map +1 -1
  200. package/dist/components/calendar/snice-calendar.d.ts +38 -1
  201. package/dist/components/calendar/snice-calendar.js +390 -40
  202. package/dist/components/calendar/snice-calendar.js.map +1 -1
  203. package/dist/components/calendar/snice-calendar.types.d.ts +63 -0
  204. package/dist/components/select/snice-select.js +2 -0
  205. package/dist/components/select/snice-select.js.map +1 -1
  206. package/dist/components/switch/snice-switch.js +7 -3
  207. package/dist/components/switch/snice-switch.js.map +1 -1
  208. package/dist/components/table/snice-table.d.ts +9 -0
  209. package/dist/components/table/snice-table.js +72 -2
  210. package/dist/components/table/snice-table.js.map +1 -1
  211. package/dist/components/table/table-keyboard.js +1 -1
  212. package/dist/components/table/table-keyboard.js.map +1 -1
  213. package/dist/index.cjs +703 -264
  214. package/dist/index.cjs.map +1 -1
  215. package/dist/index.d.ts +3 -1
  216. package/dist/index.esm.js +703 -264
  217. package/dist/index.esm.js.map +1 -1
  218. package/dist/index.iife.js +703 -264
  219. package/dist/index.iife.js.map +1 -1
  220. package/dist/parts.d.ts +14 -4
  221. package/dist/react/SniceProvider.js +1 -1
  222. package/dist/react/SniceRouter.js +1 -1
  223. package/dist/react/index.js +1 -1
  224. package/dist/react/matchRoute.js +68 -2
  225. package/dist/react/matchRoute.js.map +1 -1
  226. package/dist/react/route-match.d.ts +7 -0
  227. package/dist/react/useRequestHandler.js +1 -1
  228. package/dist/render-errors.d.ts +9 -0
  229. package/dist/route-match.d.ts +7 -0
  230. package/dist/symbols.cjs +1 -1
  231. package/dist/symbols.esm.js +1 -1
  232. package/dist/template-marker.d.ts +5 -0
  233. package/dist/testing-dom.cjs +1 -1
  234. package/dist/testing-dom.esm.js +1 -1
  235. package/dist/testing.d.ts +3 -0
  236. package/dist/transitions.cjs +1 -1
  237. package/dist/transitions.esm.js +1 -1
  238. package/dist/types/dispatch-options.d.ts +5 -4
  239. package/dist/types/event-timing.d.ts +7 -0
  240. package/dist/types/index.d.ts +1 -0
  241. package/dist/types/on-options.d.ts +21 -6
  242. package/dist/utils.d.ts +3 -0
  243. package/docs/ai/DEVELOPMENT.md +1 -1
  244. package/docs/ai/api.md +7 -2
  245. package/docs/ai/cli.md +14 -0
  246. package/docs/ai/components/avatar.md +1 -0
  247. package/docs/ai/components/calendar.md +24 -1
  248. package/docs/ai/components/switch.md +3 -0
  249. package/docs/ai/components/table.md +1 -1
  250. package/docs/ai/decorators.md +3 -2
  251. package/docs/ai/events.md +45 -8
  252. package/docs/ai/rendering.md +7 -0
  253. package/docs/ai/routing.md +6 -1
  254. package/docs/ai/testing.md +17 -0
  255. package/docs/cli.md +19 -0
  256. package/docs/components/avatar.md +1 -0
  257. package/docs/components/calendar.md +112 -2
  258. package/docs/components/switch.md +7 -1
  259. package/docs/components/table.md +2 -1
  260. package/docs/events.md +90 -10
  261. package/docs/rendering.md +10 -0
  262. package/docs/routing.md +22 -1
  263. package/docs/testing.md +19 -0
  264. package/package.json +2 -2
  265. package/vscode.html-custom-data.json +28 -0
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * snice v7.5.0
2
+ * snice v7.6.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.
@@ -64,7 +64,180 @@ var SniceCalendar = (function (exports, snice) {
64
64
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
65
65
  };
66
66
 
67
- var cssContent = ":host([hidden]){display:none}:host{display:block;font-family:var(--snice-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif);contain:layout style}.calendar{width:100%;max-width:37.5rem}.calendar__header{font-family:var(--snice-font-family-display, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif);display:flex;align-items:center;justify-content:space-between;padding:var(--snice-spacing-md,1rem);background:var(--snice-color-surface,rgb(255 255 255));border-bottom:1px solid var(--snice-color-border,rgb(226 226 226))}.calendar__title{font-family:var(--snice-font-family-display, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif);font-size:var(--snice-heading-md, 1.125rem);font-weight:var(--snice-font-weight-semibold,600);color:var(--snice-color-text,rgb(23 23 23))}.calendar__nav{display:flex;gap:var(--snice-spacing-xs,.5rem)}.calendar__nav-button{padding:var(--snice-spacing-xs,.5rem) var(--snice-spacing-sm,.75rem);border:1px solid var(--snice-color-border,rgb(226 226 226));background:var(--snice-color-surface,rgb(255 255 255));border-radius:var(--snice-border-radius-md,.25rem);cursor:pointer;transition:background-color var(--snice-transition-fast, 150ms) ease,border-color var(--snice-transition-fast, 150ms) ease;font-size:var(--snice-font-size-sm, .875rem);color:var(--snice-color-text,rgb(23 23 23));font-family:inherit}.calendar__nav-button:hover{background:var(--snice-color-surface-container-low,rgb(250 250 250));border-color:var(--snice-color-border-hover,rgb(204 204 204))}.calendar__nav-button:focus-visible{outline:0;box-shadow:0 0 0 var(--snice-focus-ring-width,2px) var(--snice-focus-ring-color,rgb(59 130 246 / .5))}.calendar__grid{display:grid;grid-template-columns:repeat(7,1fr);background:var(--snice-color-surface,rgb(255 255 255))}.calendar__weekday{padding:var(--snice-spacing-sm,.75rem);text-align:center;font-size:var(--snice-font-size-xs, .75rem);font-weight:var(--snice-font-weight-semibold,600);color:var(--snice-color-text-secondary,rgb(82 82 82));text-transform:uppercase;letter-spacing:var(--snice-tracking-widest, .1em);border-bottom:1px solid var(--snice-color-border,rgb(226 226 226))}.calendar__day{aspect-ratio:1;min-height:3rem;padding:var(--snice-spacing-xs,.5rem);border:1px solid var(--snice-color-border,rgb(226 226 226));border-top:none;border-left:none;cursor:pointer;transition:background-color var(--snice-transition-fast, 150ms) ease;position:relative;background:var(--snice-color-surface,rgb(255 255 255));color:var(--snice-color-text,rgb(23 23 23));overflow:hidden}.calendar__day:hover{background:var(--snice-color-surface-container-low,rgb(250 250 250))}.calendar__day:focus-visible{outline:0;box-shadow:inset 0 0 0 2px var(--snice-focus-ring-color,rgb(59 130 246 / .5))}.calendar__day:nth-child(7n+1){border-left:1px solid var(--snice-color-border,rgb(226 226 226))}.calendar__day--other-month{background:var(--snice-color-surface,rgb(255 255 255));color:var(--snice-color-text-tertiary,rgb(115 115 115));opacity:.5}.calendar__day--other-month:hover{opacity:.7}.calendar__day--today{background:var(--snice-color-primary-subtle,rgb(239 246 255))}.calendar__day--today:hover{background:var(--snice-color-primary-subtle-hover,rgb(219 234 254))}.calendar__day--selected{background:var(--snice-color-primary,rgb(37 99 235));color:var(--snice-color-text-inverse,rgb(250 250 250))}.calendar__day--selected:hover{background:var(--snice-color-primary-hover,rgb(29 78 216))}.calendar__day--disabled{background:var(--snice-color-surface-container,rgb(241 241 241));color:var(--snice-color-text-tertiary,rgb(115 115 115));opacity:.5;cursor:not-allowed}.calendar__day--disabled:hover{background:var(--snice-color-surface-container,rgb(241 241 241))}.calendar__day-number{font-size:var(--snice-font-size-sm, .875rem);font-weight:var(--snice-font-weight-medium,500);margin-bottom:var(--snice-spacing-2xs,.25rem)}.calendar__day--selected .calendar__day-number{color:var(--snice-color-text-inverse,rgb(250 250 250))}.calendar__events{display:flex;flex-direction:column;gap:var(--snice-spacing-3xs,.125rem);margin-top:var(--snice-spacing-2xs,.25rem)}.calendar__event{font-size:var(--snice-font-size-2xs, .625rem);padding:var(--snice-spacing-3xs,.125rem) var(--snice-spacing-2xs,.25rem);border-radius:var(--snice-border-radius-sm,.125rem);background:var(--snice-color-primary,rgb(37 99 235));color:var(--snice-color-text-inverse,rgb(250 250 250));white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:pointer;transition:opacity var(--snice-transition-fast, 150ms) ease}.calendar__event:hover{opacity:.8}.calendar__week-number{padding:var(--snice-spacing-sm,.75rem) var(--snice-spacing-xs,.5rem);text-align:center;font-size:var(--snice-font-size-xs, .75rem);color:var(--snice-color-text-tertiary,rgb(115 115 115));background:var(--snice-color-surface-container-low,rgb(250 250 250));border-right:1px solid var(--snice-color-border,rgb(226 226 226))}.calendar--week .calendar__grid{grid-template-columns:repeat(7,1fr)}.calendar--week .calendar__day{min-height:7.5rem}.calendar--day .calendar__grid{grid-template-columns:1fr}.calendar--day .calendar__day{min-height:25rem}@media (prefers-reduced-motion:reduce){*{transition-duration:0s!important;animation-duration:0s!important}}";
67
+ var cssContent$1 = ":host([hidden]){display:none}:host{display:inline-block;--avatar-size:2.5rem;--avatar-bg:var(--snice-color-text-tertiary, rgb(115 115 115));--avatar-color:var(--snice-color-text-inverse, rgb(255 255 255))}case,default,if,when{display:contents}.avatar{position:relative;width:var(--avatar-size);height:var(--avatar-size);overflow:hidden;background:var(--avatar-bg);color:var(--avatar-color);display:flex;align-items:center;justify-content:center;font-weight:var(--snice-font-weight-semibold,600);user-select:none}:host([shape=circle]) .avatar{border-radius:50%}:host([shape=square]) .avatar{border-radius:0}:host([shape=rounded]) .avatar{border-radius:var(--snice-border-radius-lg,.5rem)}:host([size=xs]){--avatar-size:1.5rem;font-size:.625rem}:host([size=small]){--avatar-size:2rem;font-size:.75rem}:host([size=medium]){--avatar-size:2.5rem;font-size:.875rem}:host([size=large]){--avatar-size:3rem;font-size:1rem}:host([size=xl]){--avatar-size:4rem;font-size:1.25rem}:host([size=xxl]){--avatar-size:6rem;font-size:2rem}.avatar-image{width:100%;height:100%;object-fit:cover;display:block}.avatar-image--error{display:none}.avatar-fallback{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;opacity:0;visibility:hidden;transition:opacity .2s}.avatar-fallback--visible{opacity:1;visibility:visible}.avatar-icon{width:60%;height:60%;opacity:.9;display:block}.avatar--red{background:var(--avatar-palette-red,rgb(239 68 68))}.avatar--orange{background:var(--avatar-palette-orange,rgb(251 146 60))}.avatar--yellow{background:var(--avatar-palette-yellow,rgb(234 179 8))}.avatar--lime{background:var(--avatar-palette-lime,rgb(163 230 53))}.avatar--green{background:var(--avatar-palette-green,rgb(34 197 94))}.avatar--teal{background:var(--avatar-palette-teal,rgb(20 184 166))}.avatar--cyan{background:var(--avatar-palette-cyan,rgb(6 182 212))}.avatar--sky{background:var(--avatar-palette-sky,rgb(14 165 233))}.avatar--blue{background:var(--avatar-palette-blue,rgb(59 130 246))}.avatar--indigo{background:var(--avatar-palette-indigo,rgb(99 102 241))}.avatar--violet{background:var(--avatar-palette-violet,rgb(139 92 246))}.avatar--purple{background:var(--avatar-palette-purple,rgb(168 85 247))}.avatar--fuchsia{background:var(--avatar-palette-fuchsia,rgb(217 70 239))}.avatar--pink{background:var(--avatar-palette-pink,rgb(236 72 153))}.avatar--rose{background:var(--avatar-palette-rose,rgb(244 63 94))}:host(.avatar-group-item){margin-left:-.5rem;border:2px solid var(--snice-color-surface,rgb(255 255 255));border-radius:50%}:host(.avatar-group-item:first-child){margin-left:0}:host(.avatar-group-item) .avatar{border:2px solid var(--snice-color-surface,rgb(255 255 255))}";
68
+
69
+ (() => {
70
+ let _classDecorators = [snice.element('snice-avatar')];
71
+ let _classDescriptor;
72
+ let _classExtraInitializers = [];
73
+ let _classThis;
74
+ let _classSuper = HTMLElement;
75
+ let _instanceExtraInitializers = [];
76
+ let _src_decorators;
77
+ let _src_initializers = [];
78
+ let _src_extraInitializers = [];
79
+ let _alt_decorators;
80
+ let _alt_initializers = [];
81
+ let _alt_extraInitializers = [];
82
+ let _name_decorators;
83
+ let _name_initializers = [];
84
+ let _name_extraInitializers = [];
85
+ let _size_decorators;
86
+ let _size_initializers = [];
87
+ let _size_extraInitializers = [];
88
+ let _shape_decorators;
89
+ let _shape_initializers = [];
90
+ let _shape_extraInitializers = [];
91
+ let _loading_decorators;
92
+ let _loading_initializers = [];
93
+ let _loading_extraInitializers = [];
94
+ let _fallbackColor_decorators;
95
+ let _fallbackColor_initializers = [];
96
+ let _fallbackColor_extraInitializers = [];
97
+ let _fallbackBackground_decorators;
98
+ let _fallbackBackground_initializers = [];
99
+ let _fallbackBackground_extraInitializers = [];
100
+ let _imageElement_decorators;
101
+ let _imageElement_initializers = [];
102
+ let _imageElement_extraInitializers = [];
103
+ let _fallbackElement_decorators;
104
+ let _fallbackElement_initializers = [];
105
+ let _fallbackElement_extraInitializers = [];
106
+ let _imageError_decorators;
107
+ let _imageError_initializers = [];
108
+ let _imageError_extraInitializers = [];
109
+ let _render_decorators;
110
+ let _styles_decorators;
111
+ (class extends _classSuper {
112
+ static { _classThis = this; }
113
+ constructor() {
114
+ super(...arguments);
115
+ this.src = (__runInitializers(this, _instanceExtraInitializers), __runInitializers(this, _src_initializers, ''));
116
+ this.alt = (__runInitializers(this, _src_extraInitializers), __runInitializers(this, _alt_initializers, ''));
117
+ this.name = (__runInitializers(this, _alt_extraInitializers), __runInitializers(this, _name_initializers, ''));
118
+ this.size = (__runInitializers(this, _name_extraInitializers), __runInitializers(this, _size_initializers, 'medium'));
119
+ this.shape = (__runInitializers(this, _size_extraInitializers), __runInitializers(this, _shape_initializers, 'circle'));
120
+ this.loading = (__runInitializers(this, _shape_extraInitializers), __runInitializers(this, _loading_initializers, 'lazy'));
121
+ this.fallbackColor = (__runInitializers(this, _loading_extraInitializers), __runInitializers(this, _fallbackColor_initializers, '#ffffff'));
122
+ this.fallbackBackground = (__runInitializers(this, _fallbackColor_extraInitializers), __runInitializers(this, _fallbackBackground_initializers, ''));
123
+ this.imageElement = (__runInitializers(this, _fallbackBackground_extraInitializers), __runInitializers(this, _imageElement_initializers, void 0));
124
+ this.fallbackElement = (__runInitializers(this, _imageElement_extraInitializers), __runInitializers(this, _fallbackElement_initializers, void 0));
125
+ this.imageError = (__runInitializers(this, _fallbackElement_extraInitializers), __runInitializers(this, _imageError_initializers, false));
126
+ this.handleImageLoad = (__runInitializers(this, _imageError_extraInitializers), () => {
127
+ this.imageError = false;
128
+ });
129
+ this.handleImageError = () => {
130
+ this.imageError = true;
131
+ };
132
+ }
133
+ static {
134
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
135
+ _src_decorators = [snice.property({})];
136
+ _alt_decorators = [snice.property({})];
137
+ _name_decorators = [snice.property({})];
138
+ _size_decorators = [snice.property({})];
139
+ _shape_decorators = [snice.property({})];
140
+ _loading_decorators = [snice.property({})];
141
+ _fallbackColor_decorators = [snice.property({ attribute: 'fallback-color', })];
142
+ _fallbackBackground_decorators = [snice.property({ attribute: 'fallback-background', })];
143
+ _imageElement_decorators = [snice.query('.avatar-image')];
144
+ _fallbackElement_decorators = [snice.query('.avatar-fallback')];
145
+ _imageError_decorators = [snice.property({ type: Boolean, attribute: false })];
146
+ _render_decorators = [snice.render()];
147
+ _styles_decorators = [snice.styles()];
148
+ __esDecorate(this, null, _render_decorators, { kind: "method", name: "render", static: false, private: false, access: { has: obj => "render" in obj, get: obj => obj.render }, metadata: _metadata }, null, _instanceExtraInitializers);
149
+ __esDecorate(this, null, _styles_decorators, { kind: "method", name: "styles", static: false, private: false, access: { has: obj => "styles" in obj, get: obj => obj.styles }, metadata: _metadata }, null, _instanceExtraInitializers);
150
+ __esDecorate(null, null, _src_decorators, { kind: "field", name: "src", static: false, private: false, access: { has: obj => "src" in obj, get: obj => obj.src, set: (obj, value) => { obj.src = value; } }, metadata: _metadata }, _src_initializers, _src_extraInitializers);
151
+ __esDecorate(null, null, _alt_decorators, { kind: "field", name: "alt", static: false, private: false, access: { has: obj => "alt" in obj, get: obj => obj.alt, set: (obj, value) => { obj.alt = value; } }, metadata: _metadata }, _alt_initializers, _alt_extraInitializers);
152
+ __esDecorate(null, null, _name_decorators, { kind: "field", name: "name", static: false, private: false, access: { has: obj => "name" in obj, get: obj => obj.name, set: (obj, value) => { obj.name = value; } }, metadata: _metadata }, _name_initializers, _name_extraInitializers);
153
+ __esDecorate(null, null, _size_decorators, { kind: "field", name: "size", static: false, private: false, access: { has: obj => "size" in obj, get: obj => obj.size, set: (obj, value) => { obj.size = value; } }, metadata: _metadata }, _size_initializers, _size_extraInitializers);
154
+ __esDecorate(null, null, _shape_decorators, { kind: "field", name: "shape", static: false, private: false, access: { has: obj => "shape" in obj, get: obj => obj.shape, set: (obj, value) => { obj.shape = value; } }, metadata: _metadata }, _shape_initializers, _shape_extraInitializers);
155
+ __esDecorate(null, null, _loading_decorators, { kind: "field", name: "loading", static: false, private: false, access: { has: obj => "loading" in obj, get: obj => obj.loading, set: (obj, value) => { obj.loading = value; } }, metadata: _metadata }, _loading_initializers, _loading_extraInitializers);
156
+ __esDecorate(null, null, _fallbackColor_decorators, { kind: "field", name: "fallbackColor", static: false, private: false, access: { has: obj => "fallbackColor" in obj, get: obj => obj.fallbackColor, set: (obj, value) => { obj.fallbackColor = value; } }, metadata: _metadata }, _fallbackColor_initializers, _fallbackColor_extraInitializers);
157
+ __esDecorate(null, null, _fallbackBackground_decorators, { kind: "field", name: "fallbackBackground", static: false, private: false, access: { has: obj => "fallbackBackground" in obj, get: obj => obj.fallbackBackground, set: (obj, value) => { obj.fallbackBackground = value; } }, metadata: _metadata }, _fallbackBackground_initializers, _fallbackBackground_extraInitializers);
158
+ __esDecorate(null, null, _imageElement_decorators, { kind: "field", name: "imageElement", static: false, private: false, access: { has: obj => "imageElement" in obj, get: obj => obj.imageElement, set: (obj, value) => { obj.imageElement = value; } }, metadata: _metadata }, _imageElement_initializers, _imageElement_extraInitializers);
159
+ __esDecorate(null, null, _fallbackElement_decorators, { kind: "field", name: "fallbackElement", static: false, private: false, access: { has: obj => "fallbackElement" in obj, get: obj => obj.fallbackElement, set: (obj, value) => { obj.fallbackElement = value; } }, metadata: _metadata }, _fallbackElement_initializers, _fallbackElement_extraInitializers);
160
+ __esDecorate(null, null, _imageError_decorators, { kind: "field", name: "imageError", static: false, private: false, access: { has: obj => "imageError" in obj, get: obj => obj.imageError, set: (obj, value) => { obj.imageError = value; } }, metadata: _metadata }, _imageError_initializers, _imageError_extraInitializers);
161
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
162
+ _classThis = _classDescriptor.value;
163
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
164
+ __runInitializers(_classThis, _classExtraInitializers);
165
+ }
166
+ render() {
167
+ const colorClass = this.fallbackBackground ? '' : this.getColorClass(this.name);
168
+ const bgStyle = this.fallbackBackground ? `--avatar-bg: ${this.fallbackBackground}; --avatar-color: ${this.fallbackColor}` : '';
169
+ const initials = this.getInitials(this.name);
170
+ const avatarClasses = ['avatar', colorClass].filter(Boolean).join(' ');
171
+ const imageClasses = ['avatar-image', this.imageError ? 'avatar-image--error' : ''].filter(Boolean).join(' ');
172
+ const fallbackClasses = ['avatar-fallback', !this.src || this.imageError ? 'avatar-fallback--visible' : ''].filter(Boolean).join(' ');
173
+ return snice.html /*html*/ `
174
+ <div part="base" class="${avatarClasses}" style="${bgStyle}">
175
+ <if ${this.src}>
176
+ <img part="image" class="${imageClasses}"
177
+ src="${this.src}"
178
+ alt="${this.alt || this.name}"
179
+ loading="${this.loading}"
180
+ @load=${this.handleImageLoad}
181
+ @error=${this.handleImageError}>
182
+ </if>
183
+ <div part="fallback" class="${fallbackClasses}">
184
+ <case ${initials}>
185
+ <when value="">
186
+ <svg class="avatar-icon" viewBox="0 0 24 24" fill="currentColor">
187
+ <path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
188
+ </svg>
189
+ </when>
190
+ <default>
191
+ ${initials}
192
+ </default>
193
+ </case>
194
+ </div>
195
+ </div>
196
+ `;
197
+ }
198
+ styles() {
199
+ return snice.css /*css*/ `${cssContent$1}`;
200
+ }
201
+ getInitials(name) {
202
+ if (!name)
203
+ return '';
204
+ const words = name.trim().split(/\s+/).filter(w => w.length > 0);
205
+ if (words.length === 0)
206
+ return '';
207
+ if (words.length === 1) {
208
+ return words[0][0].toUpperCase();
209
+ }
210
+ // Use first and second word (not first and last)
211
+ return (words[0][0] + words[1][0]).toUpperCase();
212
+ }
213
+ getColorClass(name) {
214
+ if (!name)
215
+ return '';
216
+ const colors = [
217
+ 'red', 'orange', 'yellow', 'lime', 'green',
218
+ 'teal', 'cyan', 'sky', 'blue', 'indigo',
219
+ 'violet', 'purple', 'fuchsia', 'pink', 'rose'
220
+ ];
221
+ // Hash the name to get a consistent index
222
+ let hash = 0;
223
+ for (let i = 0; i < name.length; i++) {
224
+ hash = name.charCodeAt(i) + ((hash << 5) - hash);
225
+ }
226
+ const colorIndex = Math.abs(hash) % colors.length;
227
+ return `avatar--${colors[colorIndex]}`;
228
+ }
229
+ renderIcon() {
230
+ return snice.html /*html*/ `
231
+ <svg class="avatar-icon" viewBox="0 0 24 24" fill="currentColor">
232
+ <path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/>
233
+ </svg>
234
+ `;
235
+ }
236
+ });
237
+ return _classThis;
238
+ })();
239
+
240
+ var cssContent = ":host([hidden]){display:none}:host{display:block;font-family:var(--snice-font-family, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif);contain:layout style}.calendar{width:100%;max-width:37.5rem}.calendar__header{font-family:var(--snice-font-family-display, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif);display:flex;align-items:center;justify-content:space-between;padding:var(--snice-spacing-md,1rem);background:var(--snice-color-surface,rgb(255 255 255));border-bottom:1px solid var(--snice-color-border,rgb(226 226 226))}.calendar__title{font-family:var(--snice-font-family-display, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif);font-size:var(--snice-heading-md, 1.125rem);font-weight:var(--snice-font-weight-semibold,600);color:var(--snice-color-text,rgb(23 23 23))}.calendar__nav{display:flex;gap:var(--snice-spacing-xs,.5rem)}.calendar__nav-button{padding:var(--snice-spacing-xs,.5rem) var(--snice-spacing-sm,.75rem);border:1px solid var(--snice-color-border,rgb(226 226 226));background:var(--snice-color-surface,rgb(255 255 255));border-radius:var(--snice-border-radius-md,.25rem);cursor:pointer;transition:background-color var(--snice-transition-fast, 150ms) ease,border-color var(--snice-transition-fast, 150ms) ease;font-size:var(--snice-font-size-sm, .875rem);color:var(--snice-color-text,rgb(23 23 23));font-family:inherit}.calendar__nav-button:hover{background:var(--snice-color-surface-container-low,rgb(250 250 250));border-color:var(--snice-color-border-hover,rgb(204 204 204))}.calendar__nav-button:focus-visible{outline:0;box-shadow:0 0 0 var(--snice-focus-ring-width,2px) var(--snice-focus-ring-color,rgb(59 130 246 / .5))}.calendar__grid{display:grid;grid-template-columns:repeat(7,1fr);background:var(--snice-color-surface,rgb(255 255 255));container-type:inline-size}.calendar__weekday{padding:var(--snice-spacing-sm,.75rem);text-align:center;font-size:var(--snice-font-size-xs, .75rem);font-weight:var(--snice-font-weight-semibold,600);color:var(--snice-color-text-secondary,rgb(82 82 82));text-transform:uppercase;letter-spacing:var(--snice-tracking-widest, .1em);border-bottom:1px solid var(--snice-color-border,rgb(226 226 226))}.calendar__day{box-sizing:border-box;min-width:0;min-height:max(calc(100cqw / 7),3rem,calc(2.125rem + var(--calendar-week-lanes,0) * 1.375rem + var(--calendar-week-more,0rem)));padding:var(--snice-spacing-xs,.5rem);border:1px solid var(--snice-color-border,rgb(226 226 226));border-top:none;border-left:none;cursor:pointer;transition:background-color var(--snice-transition-fast, 150ms) ease;position:relative;background:var(--snice-color-surface,rgb(255 255 255));color:var(--snice-color-text,rgb(23 23 23));overflow:hidden}.calendar__day:hover{background:var(--snice-color-surface-container-low,rgb(250 250 250))}.calendar__day:focus-visible{outline:0;box-shadow:inset 0 0 0 2px var(--snice-focus-ring-color,rgb(59 130 246 / .5))}.calendar__day:nth-child(7n+1){border-left:1px solid var(--snice-color-border,rgb(226 226 226))}.calendar__day--stretch{min-height:max(3rem,calc(2.125rem + var(--calendar-week-lanes,0) * 1.375rem + var(--calendar-week-more,0rem)))}.calendar__day--static{cursor:default}.calendar__day--static:hover{background:var(--snice-color-surface,rgb(255 255 255))}.calendar__day--static.calendar__day--today:hover{background:var(--snice-color-primary-subtle,rgb(239 246 255))}.calendar__day--other-month{background:var(--snice-color-surface,rgb(255 255 255));color:var(--snice-color-text-tertiary,rgb(115 115 115));opacity:.5}.calendar__day--other-month:hover{opacity:.7}.calendar__day--today{background:var(--snice-color-primary-subtle,rgb(239 246 255))}.calendar__day--today:hover{background:var(--snice-color-primary-subtle-hover,rgb(219 234 254))}.calendar__day--selected{background:var(--snice-color-primary,rgb(37 99 235));color:var(--snice-color-text-inverse,rgb(250 250 250))}.calendar__day--selected:hover{background:var(--snice-color-primary-hover,rgb(29 78 216))}.calendar__day--disabled{background:var(--snice-color-surface-container,rgb(241 241 241));color:var(--snice-color-text-tertiary,rgb(115 115 115));opacity:.5;cursor:not-allowed}.calendar__day--disabled:hover{background:var(--snice-color-surface-container,rgb(241 241 241))}.calendar__day-number{font-size:var(--snice-font-size-sm, .875rem);font-weight:var(--snice-font-weight-medium,500);margin-bottom:var(--snice-spacing-2xs,.25rem)}.calendar__day--selected .calendar__day-number{color:var(--snice-color-text-inverse,rgb(250 250 250))}.calendar__event-bar{display:flex;align-items:center;gap:var(--snice-spacing-3xs,.125rem);align-self:start;margin-top:calc(1.875rem + var(--calendar-event-lane,0) * 1.375rem);margin-inline:var(--snice-spacing-3xs,0.125rem);height:1.125rem;line-height:1.125rem;font-size:var(--snice-font-size-2xs, .625rem);padding:0 var(--snice-spacing-2xs,.25rem);border-radius:var(--snice-border-radius-sm,.125rem);background:var(--snice-color-primary,rgb(37 99 235));color:var(--snice-color-text-inverse,rgb(250 250 250));white-space:nowrap;overflow:hidden;cursor:pointer;z-index:1;transition:opacity var(--snice-transition-fast, 150ms) ease}.calendar__event-title{overflow:hidden;text-overflow:ellipsis;min-width:0}.calendar__event-avatar{flex:none;--avatar-size:0.875rem;font-size:.375rem;border-radius:50%;overflow:hidden}.calendar__popover{position:fixed;z-index:var(--snice-z-floating,1000);min-width:14rem;max-width:22rem;padding:var(--snice-spacing-sm,.75rem);border:1px solid var(--snice-color-border,rgb(226 226 226));border-radius:var(--snice-border-radius-md,.25rem);background:var(--snice-color-surface,rgb(255 255 255));color:var(--snice-color-text,rgb(23 23 23));font-size:var(--snice-font-size-sm, .875rem);line-height:1.5;box-shadow:var(--snice-shadow-lg,0 10px 15px -3px rgb(0 0 0 / .1))}.calendar__popover:focus-visible{outline:0;box-shadow:var(--snice-shadow-lg,0 10px 15px -3px rgb(0 0 0 / .1)),0 0 0 var(--snice-focus-ring-width,2px) var(--snice-focus-ring-color,rgb(59 130 246 / .5))}.calendar__popover-loading{color:var(--snice-color-text-secondary,rgb(82 82 82));font-size:var(--snice-font-size-xs, .75rem)}.calendar__tooltip{position:fixed;z-index:var(--snice-z-floating,1000);max-width:18rem;padding:var(--snice-spacing-2xs,.25rem) var(--snice-spacing-xs,.5rem);border-radius:var(--snice-border-radius-md,.25rem);background:var(--snice-tooltip-bg,rgb(51 51 51));color:var(--snice-color-text-inverse,rgb(250 250 250));font-size:var(--snice-font-size-xs, .75rem);line-height:1.4;box-shadow:var(--snice-shadow-md,0 4px 6px -1px rgb(0 0 0 / .1));pointer-events:none}.calendar__event-bar:hover{opacity:.8}.calendar__event-bar--continues-left{border-top-left-radius:0;border-bottom-left-radius:0;margin-inline-start:0}.calendar__event-bar--continues-right{border-top-right-radius:0;border-bottom-right-radius:0;margin-inline-end:0}.calendar__more{position:absolute;bottom:var(--snice-spacing-3xs,.125rem);left:var(--snice-spacing-2xs,.25rem);font-size:var(--snice-font-size-2xs, .625rem);color:var(--snice-color-text-secondary,rgb(82 82 82))}.calendar__week-number{padding:var(--snice-spacing-sm,.75rem) var(--snice-spacing-xs,.5rem);text-align:center;font-size:var(--snice-font-size-xs, .75rem);color:var(--snice-color-text-tertiary,rgb(115 115 115));background:var(--snice-color-surface-container-low,rgb(250 250 250));border-right:1px solid var(--snice-color-border,rgb(226 226 226))}.calendar--week .calendar__grid{grid-template-columns:repeat(7,1fr)}.calendar--week .calendar__day{min-height:7.5rem}.calendar--day .calendar__grid{grid-template-columns:1fr}.calendar--day .calendar__day{min-height:25rem}@media (prefers-reduced-motion:reduce){*{transition-duration:0s!important;animation-duration:0s!important}}";
68
241
 
69
242
  let SniceCalendar = (() => {
70
243
  let _classDecorators = [snice.element('snice-calendar')];
@@ -103,13 +276,27 @@ var SniceCalendar = (function (exports, snice) {
103
276
  let _locale_decorators;
104
277
  let _locale_initializers = [];
105
278
  let _locale_extraInitializers = [];
279
+ let _noDaySelect_decorators;
280
+ let _noDaySelect_initializers = [];
281
+ let _noDaySelect_extraInitializers = [];
282
+ let _cellSizing_decorators;
283
+ let _cellSizing_initializers = [];
284
+ let _cellSizing_extraInitializers = [];
285
+ let _eventTooltip_decorators;
286
+ let _eventTooltip_initializers = [];
287
+ let _eventTooltip_extraInitializers = [];
288
+ let _eventPopover_decorators;
289
+ let _eventPopover_initializers = [];
290
+ let _eventPopover_extraInitializers = [];
106
291
  let _dispatchChange_decorators;
107
292
  let _dispatchEventClick_decorators;
108
293
  let _styles_decorators;
109
294
  let _initialize_decorators;
295
+ let _requestEventPopoverContent_decorators;
296
+ let _cleanupPopover_decorators;
110
297
  let _handlePropertyChange_decorators;
111
298
  let _handleWeekdayInputsChange_decorators;
112
- (class extends _classSuper {
299
+ var SniceCalendar = class extends _classSuper {
113
300
  static { _classThis = this; }
114
301
  constructor() {
115
302
  super(...arguments);
@@ -123,7 +310,26 @@ var SniceCalendar = (function (exports, snice) {
123
310
  this.showWeekNumbers = (__runInitializers(this, _highlightToday_extraInitializers), __runInitializers(this, _showWeekNumbers_initializers, false));
124
311
  this.firstDayOfWeek = (__runInitializers(this, _showWeekNumbers_extraInitializers), __runInitializers(this, _firstDayOfWeek_initializers, 0)); // 0 = Sunday, 1 = Monday
125
312
  this.locale = (__runInitializers(this, _firstDayOfWeek_extraInitializers), __runInitializers(this, _locale_initializers, 'en-US'));
126
- this.displayDate = (__runInitializers(this, _locale_extraInitializers), new Date());
313
+ this.noDaySelect = (__runInitializers(this, _locale_extraInitializers), __runInitializers(this, _noDaySelect_initializers, false));
314
+ this.cellSizing = (__runInitializers(this, _noDaySelect_extraInitializers), __runInitializers(this, _cellSizing_initializers, 'square'));
315
+ this.eventTooltip = (__runInitializers(this, _cellSizing_extraInitializers), __runInitializers(this, _eventTooltip_initializers, null));
316
+ this.eventPopover = (__runInitializers(this, _eventTooltip_extraInitializers), __runInitializers(this, _eventPopover_initializers, null));
317
+ this.displayDate = (__runInitializers(this, _eventPopover_extraInitializers), new Date());
318
+ this.tooltipToken = 0;
319
+ this.tooltipBar = null;
320
+ this.popoverToken = 0;
321
+ this.popoverBar = null;
322
+ this.boundPopoverEscape = (e) => {
323
+ if (e.key === 'Escape' && this.popoverBar)
324
+ this.closeEventPopover();
325
+ };
326
+ this.boundPopoverOutside = (e) => {
327
+ if (!this.popoverBar)
328
+ return;
329
+ if (e.composedPath().includes(this.popoverEl))
330
+ return;
331
+ this.closeEventPopover({ returnFocus: false });
332
+ };
127
333
  this.dayCells = [];
128
334
  this.focusedDate = null;
129
335
  this.handleGridKeydown = (e) => {
@@ -200,16 +406,24 @@ var SniceCalendar = (function (exports, snice) {
200
406
  _showWeekNumbers_decorators = [snice.property({ type: Boolean, attribute: 'show-week-numbers' })];
201
407
  _firstDayOfWeek_decorators = [snice.property({ type: Number, attribute: 'first-day-of-week' })];
202
408
  _locale_decorators = [snice.property({ attribute: 'locale' })];
409
+ _noDaySelect_decorators = [snice.property({ type: Boolean, attribute: 'no-day-select' })];
410
+ _cellSizing_decorators = [snice.property({ attribute: 'cell-sizing' })];
411
+ _eventTooltip_decorators = [snice.property({ attribute: false })];
412
+ _eventPopover_decorators = [snice.property({ attribute: false })];
203
413
  _dispatchChange_decorators = [snice.dispatch('calendar-change', { bubbles: true, composed: true })];
204
414
  _dispatchEventClick_decorators = [snice.dispatch('calendar-event-click', { bubbles: true, composed: true })];
205
415
  _styles_decorators = [snice.styles()];
206
416
  _initialize_decorators = [snice.ready()];
207
- _handlePropertyChange_decorators = [snice.watch('value'), snice.watch('events')];
417
+ _requestEventPopoverContent_decorators = [snice.request('calendar/event-popover')];
418
+ _cleanupPopover_decorators = [snice.dispose()];
419
+ _handlePropertyChange_decorators = [snice.watch('value'), snice.watch('events'), snice.watch('eventTooltip'), snice.watch('noDaySelect'), snice.watch('cellSizing')];
208
420
  _handleWeekdayInputsChange_decorators = [snice.watch('locale'), snice.watch('firstDayOfWeek')];
209
421
  __esDecorate(this, null, _dispatchChange_decorators, { kind: "method", name: "dispatchChange", static: false, private: false, access: { has: obj => "dispatchChange" in obj, get: obj => obj.dispatchChange }, metadata: _metadata }, null, _instanceExtraInitializers);
210
422
  __esDecorate(this, null, _dispatchEventClick_decorators, { kind: "method", name: "dispatchEventClick", static: false, private: false, access: { has: obj => "dispatchEventClick" in obj, get: obj => obj.dispatchEventClick }, metadata: _metadata }, null, _instanceExtraInitializers);
211
423
  __esDecorate(this, null, _styles_decorators, { kind: "method", name: "styles", static: false, private: false, access: { has: obj => "styles" in obj, get: obj => obj.styles }, metadata: _metadata }, null, _instanceExtraInitializers);
212
424
  __esDecorate(this, null, _initialize_decorators, { kind: "method", name: "initialize", static: false, private: false, access: { has: obj => "initialize" in obj, get: obj => obj.initialize }, metadata: _metadata }, null, _instanceExtraInitializers);
425
+ __esDecorate(this, null, _requestEventPopoverContent_decorators, { kind: "method", name: "requestEventPopoverContent", static: false, private: false, access: { has: obj => "requestEventPopoverContent" in obj, get: obj => obj.requestEventPopoverContent }, metadata: _metadata }, null, _instanceExtraInitializers);
426
+ __esDecorate(this, null, _cleanupPopover_decorators, { kind: "method", name: "cleanupPopover", static: false, private: false, access: { has: obj => "cleanupPopover" in obj, get: obj => obj.cleanupPopover }, metadata: _metadata }, null, _instanceExtraInitializers);
213
427
  __esDecorate(this, null, _handlePropertyChange_decorators, { kind: "method", name: "handlePropertyChange", static: false, private: false, access: { has: obj => "handlePropertyChange" in obj, get: obj => obj.handlePropertyChange }, metadata: _metadata }, null, _instanceExtraInitializers);
214
428
  __esDecorate(this, null, _handleWeekdayInputsChange_decorators, { kind: "method", name: "handleWeekdayInputsChange", static: false, private: false, access: { has: obj => "handleWeekdayInputsChange" in obj, get: obj => obj.handleWeekdayInputsChange }, metadata: _metadata }, null, _instanceExtraInitializers);
215
429
  __esDecorate(null, null, _value_decorators, { kind: "field", name: "value", static: false, private: false, access: { has: obj => "value" in obj, get: obj => obj.value, set: (obj, value) => { obj.value = value; } }, metadata: _metadata }, _value_initializers, _value_extraInitializers);
@@ -222,10 +436,13 @@ var SniceCalendar = (function (exports, snice) {
222
436
  __esDecorate(null, null, _showWeekNumbers_decorators, { kind: "field", name: "showWeekNumbers", static: false, private: false, access: { has: obj => "showWeekNumbers" in obj, get: obj => obj.showWeekNumbers, set: (obj, value) => { obj.showWeekNumbers = value; } }, metadata: _metadata }, _showWeekNumbers_initializers, _showWeekNumbers_extraInitializers);
223
437
  __esDecorate(null, null, _firstDayOfWeek_decorators, { kind: "field", name: "firstDayOfWeek", static: false, private: false, access: { has: obj => "firstDayOfWeek" in obj, get: obj => obj.firstDayOfWeek, set: (obj, value) => { obj.firstDayOfWeek = value; } }, metadata: _metadata }, _firstDayOfWeek_initializers, _firstDayOfWeek_extraInitializers);
224
438
  __esDecorate(null, null, _locale_decorators, { kind: "field", name: "locale", static: false, private: false, access: { has: obj => "locale" in obj, get: obj => obj.locale, set: (obj, value) => { obj.locale = value; } }, metadata: _metadata }, _locale_initializers, _locale_extraInitializers);
439
+ __esDecorate(null, null, _noDaySelect_decorators, { kind: "field", name: "noDaySelect", static: false, private: false, access: { has: obj => "noDaySelect" in obj, get: obj => obj.noDaySelect, set: (obj, value) => { obj.noDaySelect = value; } }, metadata: _metadata }, _noDaySelect_initializers, _noDaySelect_extraInitializers);
440
+ __esDecorate(null, null, _cellSizing_decorators, { kind: "field", name: "cellSizing", static: false, private: false, access: { has: obj => "cellSizing" in obj, get: obj => obj.cellSizing, set: (obj, value) => { obj.cellSizing = value; } }, metadata: _metadata }, _cellSizing_initializers, _cellSizing_extraInitializers);
441
+ __esDecorate(null, null, _eventTooltip_decorators, { kind: "field", name: "eventTooltip", static: false, private: false, access: { has: obj => "eventTooltip" in obj, get: obj => obj.eventTooltip, set: (obj, value) => { obj.eventTooltip = value; } }, metadata: _metadata }, _eventTooltip_initializers, _eventTooltip_extraInitializers);
442
+ __esDecorate(null, null, _eventPopover_decorators, { kind: "field", name: "eventPopover", static: false, private: false, access: { has: obj => "eventPopover" in obj, get: obj => obj.eventPopover, set: (obj, value) => { obj.eventPopover = value; } }, metadata: _metadata }, _eventPopover_initializers, _eventPopover_extraInitializers);
225
443
  __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
226
- _classThis = _classDescriptor.value;
444
+ SniceCalendar = _classThis = _classDescriptor.value;
227
445
  if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
228
- __runInitializers(_classThis, _classExtraInitializers);
229
446
  }
230
447
  computeRovingIndex(days) {
231
448
  // Prefer: focused → selected → today → first in-month day
@@ -299,12 +516,16 @@ var SniceCalendar = (function (exports, snice) {
299
516
  this.grid = document.createElement('div');
300
517
  this.grid.className = 'calendar__grid';
301
518
  this.grid.setAttribute('part', 'grid');
302
- // Add weekday headers
519
+ // Add weekday headers. Every grid child gets an explicit position —
520
+ // event stripe bars are placed explicitly, and mixing explicit items
521
+ // with auto-flow would push auto-placed cells out of their slots.
303
522
  const weekdays = this.getWeekdays();
304
- weekdays.forEach(day => {
523
+ weekdays.forEach((day, i) => {
305
524
  const weekdayEl = document.createElement('div');
306
525
  weekdayEl.className = 'calendar__weekday';
307
526
  weekdayEl.textContent = day;
527
+ weekdayEl.style.gridRow = '1';
528
+ weekdayEl.style.gridColumn = String(i + 1);
308
529
  this.grid.appendChild(weekdayEl);
309
530
  });
310
531
  // Mark grid for a11y
@@ -320,20 +541,147 @@ var SniceCalendar = (function (exports, snice) {
320
541
  // making the first cell tabbable; updateView re-targets the focused
321
542
  // date so today/selected gets the 0.
322
543
  dayCell.setAttribute('tabindex', i === 0 ? '0' : '-1');
544
+ dayCell.style.gridRow = String(Math.floor(i / 7) + 2);
545
+ dayCell.style.gridColumn = String((i % 7) + 1);
323
546
  const dayNumber = document.createElement('div');
324
547
  dayNumber.className = 'calendar__day-number';
325
548
  dayCell.appendChild(dayNumber);
326
- const eventsContainer = document.createElement('div');
327
- eventsContainer.className = 'calendar__events';
328
- eventsContainer.style.display = 'none';
329
- dayCell.appendChild(eventsContainer);
330
549
  this.grid.appendChild(dayCell);
331
550
  this.dayCells.push(dayCell);
332
551
  }
552
+ // Shared tooltip overlay for event bars — one element, repositioned per
553
+ // bar, so rich content can load lazily without a tooltip instance per bar.
554
+ this.tooltipEl = document.createElement('div');
555
+ this.tooltipEl.className = 'calendar__tooltip';
556
+ this.tooltipEl.setAttribute('part', 'event-tooltip');
557
+ this.tooltipEl.setAttribute('role', 'tooltip');
558
+ this.tooltipEl.id = 'calendar-event-tooltip';
559
+ this.tooltipEl.hidden = true;
560
+ // Interactive click-to-open popover for event details. One shared panel,
561
+ // anchored per bar; content may load lazily (provider or the
562
+ // calendar/event-popover request channel).
563
+ this.popoverEl = document.createElement('div');
564
+ this.popoverEl.className = 'calendar__popover';
565
+ this.popoverEl.setAttribute('part', 'event-popover');
566
+ this.popoverEl.setAttribute('role', 'dialog');
567
+ this.popoverEl.setAttribute('aria-label', 'Event details');
568
+ this.popoverEl.tabIndex = -1;
569
+ this.popoverEl.hidden = true;
333
570
  this.container.appendChild(this.header);
334
571
  this.container.appendChild(this.grid);
572
+ this.container.appendChild(this.tooltipEl);
573
+ this.container.appendChild(this.popoverEl);
335
574
  shadow.appendChild(this.container);
336
575
  }
576
+ /**
577
+ * Dynamic popover channel: yields `{ event }` so any
578
+ * `@respond('calendar/event-popover')` controller can return the content.
579
+ */
580
+ async *requestEventPopoverContent(event) {
581
+ return await (yield { event });
582
+ }
583
+ async openEventPopover(bar, event) {
584
+ const token = ++this.popoverToken;
585
+ this.hideEventTooltip();
586
+ // Anchor + loading shell first, so slow content still feels responsive.
587
+ this.popoverBar = bar;
588
+ this.popoverEl.replaceChildren();
589
+ const loading = document.createElement('div');
590
+ loading.className = 'calendar__popover-loading';
591
+ loading.textContent = 'Loading…';
592
+ this.popoverEl.appendChild(loading);
593
+ this.popoverEl.hidden = false;
594
+ this.positionPopover(bar);
595
+ document.addEventListener('keydown', this.boundPopoverEscape, true);
596
+ document.addEventListener('mousedown', this.boundPopoverOutside, true);
597
+ let content;
598
+ try {
599
+ if (event.popover !== true && event.popover) {
600
+ content = typeof event.popover === 'function' ? event.popover() : event.popover;
601
+ }
602
+ else if (this.eventPopover) {
603
+ content = await this.eventPopover(event);
604
+ }
605
+ else {
606
+ content = await this.requestEventPopoverContent(event);
607
+ }
608
+ }
609
+ catch {
610
+ // No responder discovered (or the provider failed) — close quietly.
611
+ content = undefined;
612
+ }
613
+ if (token !== this.popoverToken)
614
+ return; // closed (or replaced) meanwhile
615
+ if (content == null) {
616
+ console.warn(`[snice-calendar] event "${String(event.id)}" enables a popover but no content was provided — set eventPopover, event.popover content, or a @respond('calendar/event-popover') handler.`);
617
+ this.closeEventPopover({ returnFocus: false });
618
+ return;
619
+ }
620
+ if (typeof content === 'string')
621
+ this.popoverEl.textContent = content;
622
+ else
623
+ this.popoverEl.replaceChildren(content);
624
+ this.positionPopover(bar);
625
+ this.popoverEl.focus();
626
+ }
627
+ positionPopover(bar) {
628
+ const rect = bar.getBoundingClientRect();
629
+ this.popoverEl.style.left = `${Math.max(4, rect.left)}px`;
630
+ this.popoverEl.style.top = `${rect.bottom + 6}px`;
631
+ }
632
+ closeEventPopover(options = {}) {
633
+ if (!this.popoverBar)
634
+ return;
635
+ this.popoverToken++;
636
+ const bar = this.popoverBar;
637
+ this.popoverBar = null;
638
+ this.popoverEl.hidden = true;
639
+ this.popoverEl.replaceChildren();
640
+ document.removeEventListener('keydown', this.boundPopoverEscape, true);
641
+ document.removeEventListener('mousedown', this.boundPopoverOutside, true);
642
+ if (options.returnFocus !== false && bar.isConnected)
643
+ bar.focus();
644
+ }
645
+ cleanupPopover() {
646
+ document.removeEventListener('keydown', this.boundPopoverEscape, true);
647
+ document.removeEventListener('mousedown', this.boundPopoverOutside, true);
648
+ }
649
+ async showEventTooltip(bar, event) {
650
+ const token = ++this.tooltipToken;
651
+ const provider = this.eventTooltip;
652
+ let content;
653
+ if (provider) {
654
+ try {
655
+ content = await provider(event);
656
+ }
657
+ catch {
658
+ content = event.tooltip;
659
+ }
660
+ }
661
+ else {
662
+ content = event.tooltip;
663
+ }
664
+ // Pointer already left (or moved to another bar) while loading.
665
+ if (token !== this.tooltipToken || content == null)
666
+ return;
667
+ if (typeof content === 'string')
668
+ this.tooltipEl.textContent = content;
669
+ else
670
+ this.tooltipEl.replaceChildren(content);
671
+ this.tooltipEl.hidden = false;
672
+ this.tooltipBar = bar;
673
+ bar.setAttribute('aria-describedby', this.tooltipEl.id);
674
+ // Fixed positioning above the bar, clamped to the viewport.
675
+ const rect = bar.getBoundingClientRect();
676
+ this.tooltipEl.style.left = `${Math.max(4, rect.left)}px`;
677
+ this.tooltipEl.style.top = `${Math.max(4, rect.top - this.tooltipEl.offsetHeight - 6)}px`;
678
+ }
679
+ hideEventTooltip() {
680
+ this.tooltipToken++;
681
+ this.tooltipEl.hidden = true;
682
+ this.tooltipBar?.removeAttribute('aria-describedby');
683
+ this.tooltipBar = null;
684
+ }
337
685
  updateView() {
338
686
  // Update header title
339
687
  const monthName = this.displayDate.toLocaleDateString(this.locale, { month: 'long', year: 'numeric' });
@@ -351,9 +699,9 @@ var SniceCalendar = (function (exports, snice) {
351
699
  return;
352
700
  const isOtherMonth = date.getMonth() !== currentMonth;
353
701
  const isToday = this.highlightToday && this.isToday(date);
354
- const isSelected = this.isSelected(date);
702
+ // Display-only mode never shows a selection highlight.
703
+ const isSelected = !this.noDaySelect && this.isSelected(date);
355
704
  const isDisabled = this.isDisabled(date);
356
- const dayEvents = this.getEventsForDate(date);
357
705
  // Update classes (preserving role)
358
706
  cell.className = 'calendar__day';
359
707
  if (isOtherMonth)
@@ -364,6 +712,10 @@ var SniceCalendar = (function (exports, snice) {
364
712
  cell.classList.add('calendar__day--selected');
365
713
  if (isDisabled)
366
714
  cell.classList.add('calendar__day--disabled');
715
+ if (this.noDaySelect)
716
+ cell.classList.add('calendar__day--static');
717
+ if (this.cellSizing === 'stretch')
718
+ cell.classList.add('calendar__day--stretch');
367
719
  cell.setAttribute('role', 'gridcell');
368
720
  cell.setAttribute('aria-selected', isSelected ? 'true' : 'false');
369
721
  cell.setAttribute('aria-disabled', isDisabled ? 'true' : 'false');
@@ -377,34 +729,196 @@ var SniceCalendar = (function (exports, snice) {
377
729
  dayNumber.textContent = String(date.getDate());
378
730
  // Update click handler
379
731
  cell.onclick = () => this.handleDayClick(date);
380
- // Update events
381
- const eventsContainer = cell.querySelector('.calendar__events');
382
- if (eventsContainer) {
383
- if (dayEvents.length > 0) {
384
- eventsContainer.style.display = '';
385
- eventsContainer.innerHTML = '';
386
- dayEvents.slice(0, 3).forEach(event => {
387
- const eventEl = document.createElement('div');
388
- eventEl.className = 'calendar__event';
389
- if (event.color)
390
- eventEl.style.background = event.color;
391
- eventEl.textContent = event.title;
392
- eventEl.onclick = (e) => this.handleEventClick(event, e);
393
- eventsContainer.appendChild(eventEl);
394
- });
395
- if (dayEvents.length > 3) {
396
- const moreEl = document.createElement('div');
397
- moreEl.className = 'calendar__event';
398
- moreEl.style.background = '#999';
399
- moreEl.textContent = `+${dayEvents.length - 3} more`;
400
- eventsContainer.appendChild(moreEl);
401
- }
732
+ });
733
+ this.renderEventStripes(days);
734
+ }
735
+ /** Visible stacking depth for event stripes; deeper lanes collapse into a
736
+ * per-day "+N more" chip. */
737
+ static { this.MAX_EVENT_LANES = 3; }
738
+ /**
739
+ * Render events as continuous stripes: one bar per (event × week row),
740
+ * spanning the event's days in that week and chopped at week boundaries
741
+ * with continues-left/right styling. Overlapping events stack into lanes
742
+ * per week — earlier start first, longer event first on ties — like
743
+ * professional calendars.
744
+ */
745
+ renderEventStripes(days) {
746
+ this.closeEventPopover({ returnFocus: false }); // anchors are re-created
747
+ this.grid.querySelectorAll('.calendar__event-bar').forEach(el => el.remove());
748
+ this.dayCells.forEach(cell => {
749
+ cell.querySelector('.calendar__more')?.remove();
750
+ cell.style.removeProperty('--calendar-week-lanes');
751
+ cell.style.removeProperty('--calendar-week-more');
752
+ });
753
+ if (!this.events || this.events.length === 0)
754
+ return;
755
+ // Local-midnight timestamps for the visible grid; events normalize to the
756
+ // same construction so lookups are exact (and DST-safe).
757
+ const dayTimes = days.map(d => new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime());
758
+ const dayIndex = new Map(dayTimes.map((t, i) => [t, i]));
759
+ const gridStart = dayTimes[0];
760
+ const gridEnd = dayTimes[dayTimes.length - 1];
761
+ const normalize = (d) => {
762
+ const date = typeof d === 'string' ? new Date(d) : d;
763
+ return new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();
764
+ };
765
+ const resolved = [];
766
+ this.events.forEach((event, order) => {
767
+ if (!event.start)
768
+ return;
769
+ const startTime = normalize(event.start);
770
+ if (isNaN(startTime))
771
+ return;
772
+ const endTime = event.end ? Math.max(normalize(event.end), startTime) : startTime;
773
+ if (isNaN(endTime) || endTime < gridStart || startTime > gridEnd)
774
+ return;
775
+ const startsBeforeGrid = startTime < gridStart;
776
+ const endsAfterGrid = endTime > gridEnd;
777
+ const startIdx = startsBeforeGrid ? 0 : dayIndex.get(startTime);
778
+ const endIdx = endsAfterGrid ? dayTimes.length - 1 : dayIndex.get(endTime);
779
+ resolved.push({
780
+ event, startIdx, endIdx, startsBeforeGrid, endsAfterGrid,
781
+ startTime, duration: endTime - startTime, order,
782
+ });
783
+ });
784
+ resolved.sort((a, b) => a.startTime - b.startTime || b.duration - a.duration || a.order - b.order);
785
+ const hiddenPerDay = new Array(dayTimes.length).fill(0);
786
+ const weekCount = Math.floor(dayTimes.length / 7);
787
+ const weekLaneCounts = new Array(weekCount).fill(0);
788
+ for (let week = 0; week < weekCount; week++) {
789
+ const weekStart = week * 7;
790
+ const weekEnd = weekStart + 6;
791
+ // lanes[lane] holds the occupied [startCol, endCol] ranges in this week.
792
+ const lanes = [];
793
+ for (const item of resolved) {
794
+ if (item.endIdx < weekStart || item.startIdx > weekEnd)
795
+ continue;
796
+ const segStart = Math.max(item.startIdx, weekStart);
797
+ const segEnd = Math.min(item.endIdx, weekEnd);
798
+ const startCol = segStart - weekStart;
799
+ const endCol = segEnd - weekStart;
800
+ let lane = 0;
801
+ while (lanes[lane]?.some(([s, e]) => startCol <= e && endCol >= s))
802
+ lane++;
803
+ (lanes[lane] ??= []).push([startCol, endCol]);
804
+ weekLaneCounts[week] = Math.min(Math.max(weekLaneCounts[week], lane + 1), SniceCalendar.MAX_EVENT_LANES);
805
+ if (lane >= SniceCalendar.MAX_EVENT_LANES) {
806
+ for (let i = segStart; i <= segEnd; i++)
807
+ hiddenPerDay[i]++;
808
+ continue;
809
+ }
810
+ const continuesLeft = segStart > item.startIdx
811
+ || (segStart === item.startIdx && item.startsBeforeGrid);
812
+ const continuesRight = segEnd < item.endIdx
813
+ || (segEnd === item.endIdx && item.endsAfterGrid);
814
+ const bar = document.createElement('div');
815
+ bar.className = 'calendar__event-bar';
816
+ if (continuesLeft)
817
+ bar.classList.add('calendar__event-bar--continues-left');
818
+ if (continuesRight)
819
+ bar.classList.add('calendar__event-bar--continues-right');
820
+ // A custom className rides along on both the class list and the part
821
+ // attribute, so events are styleable from outside via
822
+ // ::part(<className>).
823
+ const customClasses = item.event.className
824
+ ? item.event.className.split(/\s+/).filter(Boolean)
825
+ : [];
826
+ bar.classList.add(...customClasses);
827
+ bar.setAttribute('part', ['event-bar', ...customClasses].join(' '));
828
+ bar.setAttribute('data-event-id', String(item.event.id));
829
+ bar.setAttribute('data-lane', String(lane));
830
+ bar.style.gridRow = String(week + 2); // row 1 is the weekday header
831
+ bar.style.gridColumn = `${startCol + 1} / ${endCol + 2}`;
832
+ bar.style.setProperty('--calendar-event-lane', String(lane));
833
+ if (item.event.color)
834
+ bar.style.background = item.event.color;
835
+ if (item.event.avatar) {
836
+ const spec = typeof item.event.avatar === 'string'
837
+ ? { src: item.event.avatar }
838
+ : item.event.avatar;
839
+ const avatar = document.createElement('snice-avatar');
840
+ avatar.className = 'calendar__event-avatar';
841
+ avatar.setAttribute('part', 'event-avatar');
842
+ // Attributes, not property assignments: the avatar's shape/size CSS
843
+ // matches on :host([shape])/:host([size]) attribute selectors.
844
+ avatar.setAttribute('size', 'xs');
845
+ avatar.setAttribute('shape', 'circle');
846
+ // Tiny thumbnail — eager: lazy-load buys nothing at this size and
847
+ // stalls on very tall pages.
848
+ avatar.setAttribute('loading', 'eager');
849
+ if (spec.src)
850
+ avatar.src = spec.src;
851
+ if (spec.name)
852
+ avatar.name = spec.name;
853
+ if (spec.alt)
854
+ avatar.alt = spec.alt;
855
+ bar.appendChild(avatar);
856
+ }
857
+ const titleEl = document.createElement('span');
858
+ titleEl.className = 'calendar__event-title';
859
+ titleEl.textContent = item.event.title;
860
+ bar.appendChild(titleEl);
861
+ // Tooltip: static string, or lazy/rich content from eventTooltip.
862
+ // The native title attribute stays only when no tooltip is configured.
863
+ if (item.event.tooltip || this.eventTooltip) {
864
+ bar.onmouseenter = () => this.showEventTooltip(bar, item.event);
865
+ bar.onmouseleave = () => this.hideEventTooltip();
866
+ }
867
+ else {
868
+ bar.title = item.event.title;
869
+ }
870
+ // Popover: strictly per-event opt-in — without `popover`, a click
871
+ // only dispatches calendar-event-click and no request is issued.
872
+ if (item.event.popover) {
873
+ bar.setAttribute('role', 'button');
874
+ bar.setAttribute('tabindex', '0');
875
+ bar.setAttribute('aria-haspopup', 'dialog');
876
+ bar.onkeydown = (e) => {
877
+ if (e.key === 'Enter' || e.key === ' ') {
878
+ e.preventDefault();
879
+ e.stopPropagation();
880
+ this.openEventPopover(bar, item.event);
881
+ }
882
+ };
883
+ bar.onclick = (e) => {
884
+ this.handleEventClick(item.event, e);
885
+ this.openEventPopover(bar, item.event);
886
+ };
402
887
  }
403
888
  else {
404
- eventsContainer.style.display = 'none';
889
+ bar.onclick = (e) => this.handleEventClick(item.event, e);
405
890
  }
891
+ this.grid.appendChild(bar);
406
892
  }
893
+ }
894
+ hiddenPerDay.forEach((count, i) => {
895
+ if (count === 0)
896
+ return;
897
+ const cell = this.dayCells[i];
898
+ if (!cell)
899
+ return;
900
+ const more = document.createElement('div');
901
+ more.className = 'calendar__more';
902
+ more.textContent = `+${count} more`;
903
+ cell.appendChild(more);
407
904
  });
905
+ // Reserve row height for the lane stack (and the "+N more" chip) so
906
+ // stripes never spill past their week row — every cell in a week shares
907
+ // the reservation, since the grid row is as tall as its tallest cell.
908
+ for (let week = 0; week < weekCount; week++) {
909
+ if (weekLaneCounts[week] === 0)
910
+ continue;
911
+ const weekHasMore = hiddenPerDay
912
+ .slice(week * 7, week * 7 + 7).some(count => count > 0);
913
+ for (let i = week * 7; i < week * 7 + 7; i++) {
914
+ const cell = this.dayCells[i];
915
+ if (!cell)
916
+ continue;
917
+ cell.style.setProperty('--calendar-week-lanes', String(weekLaneCounts[week]));
918
+ if (weekHasMore)
919
+ cell.style.setProperty('--calendar-week-more', '1rem');
920
+ }
921
+ }
408
922
  }
409
923
  goToToday() {
410
924
  this.displayDate = new Date();
@@ -496,6 +1010,9 @@ var SniceCalendar = (function (exports, snice) {
496
1010
  });
497
1011
  }
498
1012
  handleDayClick(date) {
1013
+ // Display-only calendars: days are not selectable at all.
1014
+ if (this.noDaySelect)
1015
+ return;
499
1016
  if (this.isDisabled(date))
500
1017
  return;
501
1018
  this.value = date;
@@ -548,13 +1065,18 @@ var SniceCalendar = (function (exports, snice) {
548
1065
  const weekdayEl = document.createElement('div');
549
1066
  weekdayEl.className = 'calendar__weekday';
550
1067
  weekdayEl.textContent = day;
1068
+ weekdayEl.style.gridRow = '1';
1069
+ weekdayEl.style.gridColumn = String(i + 1);
551
1070
  // Insert before the first day cell so header row stays at the top
552
1071
  this.grid.insertBefore(weekdayEl, this.grid.children[i] || null);
553
1072
  });
554
1073
  this.updateView();
555
1074
  }
556
- });
557
- return _classThis;
1075
+ static {
1076
+ __runInitializers(_classThis, _classExtraInitializers);
1077
+ }
1078
+ };
1079
+ return SniceCalendar = _classThis;
558
1080
  })();
559
1081
 
560
1082
  exports.SniceCalendar = SniceCalendar;