snice 7.8.0 → 7.9.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.
- package/README.md +1 -1
- package/adapters/react/SniceProvider.js +1 -1
- package/adapters/react/SniceRouter.js +1 -1
- package/adapters/react/matchRoute.js +1 -1
- package/adapters/react/table.d.ts +1 -0
- package/adapters/react/table.d.ts.map +1 -1
- package/adapters/react/table.js +1 -1
- package/adapters/react/table.js.map +1 -1
- package/adapters/react/table.tsx +2 -1
- package/adapters/react/useRequestHandler.js +1 -1
- package/bin/analyzer-contracts.js +17 -1
- package/custom-elements.json +57 -3
- package/dist/cdn/accordion/snice-accordion.js +1 -1
- package/dist/cdn/action-bar/snice-action-bar.js +1 -1
- package/dist/cdn/activity-feed/snice-activity-feed.js +1 -1
- package/dist/cdn/alert/snice-alert.js +1 -1
- package/dist/cdn/app-tiles/snice-app-tiles.js +1 -1
- package/dist/cdn/approval-flow/snice-approval-flow.js +1 -1
- package/dist/cdn/audio-recorder/snice-audio-recorder.js +1 -1
- package/dist/cdn/availability/snice-availability.js +1 -1
- package/dist/cdn/avatar/snice-avatar.js +1 -1
- package/dist/cdn/avatar-group/snice-avatar-group.js +1 -1
- package/dist/cdn/badge/snice-badge.js +1 -1
- package/dist/cdn/banner/snice-banner.js +1 -1
- package/dist/cdn/binpack/snice-binpack.js +1 -1
- package/dist/cdn/book/snice-book.js +1 -1
- package/dist/cdn/booking/snice-booking.js +1 -1
- package/dist/cdn/breadcrumbs/snice-breadcrumbs.js +1 -1
- package/dist/cdn/button/snice-button.js +1 -1
- package/dist/cdn/calendar/README.md +2 -2
- package/dist/cdn/calendar/snice-calendar.js +537 -44
- package/dist/cdn/calendar/snice-calendar.js.map +1 -1
- package/dist/cdn/calendar/snice-calendar.min.js +2 -2
- package/dist/cdn/calendar/snice-calendar.min.js.map +1 -1
- package/dist/cdn/camera/snice-camera.js +1 -1
- package/dist/cdn/camera-annotate/snice-camera-annotate.js +1 -1
- package/dist/cdn/candlestick/snice-candlestick.js +1 -1
- package/dist/cdn/card/snice-card.js +1 -1
- package/dist/cdn/carousel/snice-carousel.js +1 -1
- package/dist/cdn/cart/snice-cart.js +1 -1
- package/dist/cdn/chart/snice-chart.js +1 -1
- package/dist/cdn/chat/snice-chat.js +1 -1
- package/dist/cdn/checkbox/snice-checkbox.js +1 -1
- package/dist/cdn/chip/snice-chip.js +1 -1
- package/dist/cdn/code-block/README.md +2 -2
- package/dist/cdn/code-block/snice-code-block.js +177 -167
- package/dist/cdn/code-block/snice-code-block.js.map +1 -1
- package/dist/cdn/code-block/snice-code-block.min.js +2 -2
- package/dist/cdn/code-block/snice-code-block.min.js.map +1 -1
- package/dist/cdn/color-display/snice-color-display.js +1 -1
- package/dist/cdn/color-picker/snice-color-picker.js +1 -1
- package/dist/cdn/command-palette/README.md +1 -1
- package/dist/cdn/command-palette/snice-command-palette.js +2 -2
- package/dist/cdn/command-palette/snice-command-palette.js.map +1 -1
- package/dist/cdn/command-palette/snice-command-palette.min.js +1 -1
- package/dist/cdn/command-palette/snice-command-palette.min.js.map +1 -1
- package/dist/cdn/comments/snice-comments.js +1 -1
- package/dist/cdn/countdown/snice-countdown.js +1 -1
- package/dist/cdn/cropper/snice-cropper.js +1 -1
- package/dist/cdn/data-card/snice-data-card.js +1 -1
- package/dist/cdn/date-picker/snice-date-picker.js +1 -1
- package/dist/cdn/date-range-picker/snice-date-range-picker.js +1 -1
- package/dist/cdn/date-time-picker/snice-date-time-picker.js +1 -1
- package/dist/cdn/diff/snice-diff.js +1 -1
- package/dist/cdn/divider/snice-divider.js +1 -1
- package/dist/cdn/doc/snice-doc.js +1 -1
- package/dist/cdn/draw/snice-draw.js +1 -1
- package/dist/cdn/drawer/snice-drawer.js +1 -1
- package/dist/cdn/empty-state/snice-empty-state.js +1 -1
- package/dist/cdn/estimate/snice-estimate.js +1 -1
- package/dist/cdn/file-gallery/snice-file-gallery.js +1 -1
- package/dist/cdn/file-upload/snice-file-upload.js +1 -1
- package/dist/cdn/flip-card/snice-flip-card.js +1 -1
- package/dist/cdn/flow/snice-flow.js +1 -1
- package/dist/cdn/form-layout/snice-form-layout.js +1 -1
- package/dist/cdn/funnel/snice-funnel.js +1 -1
- package/dist/cdn/gantt/snice-gantt.js +1 -1
- package/dist/cdn/gauge/snice-gauge.js +1 -1
- package/dist/cdn/grid/snice-grid.js +1 -1
- package/dist/cdn/heatmap/snice-heatmap.js +1 -1
- package/dist/cdn/image/snice-image.js +1 -1
- package/dist/cdn/input/snice-input.js +1 -1
- package/dist/cdn/invoice/snice-invoice.js +1 -1
- package/dist/cdn/kanban/snice-kanban.js +1 -1
- package/dist/cdn/key-value/snice-key-value.js +1 -1
- package/dist/cdn/kpi/snice-kpi.js +1 -1
- package/dist/cdn/layout/snice-layout.js +1 -1
- package/dist/cdn/leaderboard/snice-leaderboard.js +1 -1
- package/dist/cdn/link/snice-link.js +1 -1
- package/dist/cdn/link-preview/snice-link-preview.js +1 -1
- package/dist/cdn/list/snice-list.js +1 -1
- package/dist/cdn/location/snice-location.js +1 -1
- package/dist/cdn/login/snice-login.js +1 -1
- package/dist/cdn/map/snice-map.js +1 -1
- package/dist/cdn/markdown/snice-markdown.js +1 -1
- package/dist/cdn/masonry/snice-masonry.js +1 -1
- package/dist/cdn/menu/snice-menu.js +1 -1
- package/dist/cdn/message-strip/snice-message-strip.js +1 -1
- package/dist/cdn/modal/snice-modal.js +1 -1
- package/dist/cdn/music-player/snice-music-player.js +1 -1
- package/dist/cdn/nav/snice-nav.js +1 -1
- package/dist/cdn/network-graph/snice-network-graph.js +1 -1
- package/dist/cdn/notification-center/snice-notification-center.js +1 -1
- package/dist/cdn/order-tracker/snice-order-tracker.js +1 -1
- package/dist/cdn/org-chart/snice-org-chart.js +1 -1
- package/dist/cdn/pagination/snice-pagination.js +1 -1
- package/dist/cdn/paint/snice-paint.js +1 -1
- package/dist/cdn/pdf-viewer/snice-pdf-viewer.js +1 -1
- package/dist/cdn/permission-matrix/snice-permission-matrix.js +1 -1
- package/dist/cdn/podcast-player/snice-podcast-player.js +1 -1
- package/dist/cdn/popover/snice-popover.js +1 -1
- package/dist/cdn/pricing-table/snice-pricing-table.js +1 -1
- package/dist/cdn/product-card/snice-product-card.js +1 -1
- package/dist/cdn/progress/snice-progress.js +2 -2
- package/dist/cdn/progress/snice-progress.js.map +1 -1
- package/dist/cdn/progress/snice-progress.min.js +1 -1
- package/dist/cdn/progress/snice-progress.min.js.map +1 -1
- package/dist/cdn/progress-ring/snice-progress-ring.js +1 -1
- package/dist/cdn/qr-code/README.md +2 -2
- package/dist/cdn/qr-code/snice-qr-code.js +19 -3
- package/dist/cdn/qr-code/snice-qr-code.js.map +1 -1
- package/dist/cdn/qr-code/snice-qr-code.min.js +2 -2
- package/dist/cdn/qr-code/snice-qr-code.min.js.map +1 -1
- package/dist/cdn/qr-reader/snice-qr-reader.js +1 -1
- package/dist/cdn/radio/snice-radio.js +1 -1
- package/dist/cdn/range-slider/snice-range-slider.js +1 -1
- package/dist/cdn/rating/snice-rating.js +1 -1
- package/dist/cdn/receipt/snice-receipt.js +5 -2
- package/dist/cdn/receipt/snice-receipt.js.map +1 -1
- package/dist/cdn/receipt/snice-receipt.min.js +1 -1
- package/dist/cdn/receipt/snice-receipt.min.js.map +1 -1
- package/dist/cdn/recipe/snice-recipe.js +1 -1
- package/dist/cdn/runtime/snice-runtime.esm.js +4 -4
- package/dist/cdn/runtime/snice-runtime.esm.js.map +1 -1
- package/dist/cdn/runtime/snice-runtime.esm.min.js.map +1 -1
- package/dist/cdn/runtime/snice-runtime.js +4 -4
- package/dist/cdn/runtime/snice-runtime.js.map +1 -1
- package/dist/cdn/runtime/snice-runtime.min.js.map +1 -1
- package/dist/cdn/sankey/snice-sankey.js +1 -1
- package/dist/cdn/segmented-control/snice-segmented-control.js +1 -1
- package/dist/cdn/select/README.md +2 -2
- package/dist/cdn/select/snice-select.js +6 -9
- package/dist/cdn/select/snice-select.js.map +1 -1
- package/dist/cdn/select/snice-select.min.js +2 -2
- package/dist/cdn/select/snice-select.min.js.map +1 -1
- package/dist/cdn/skeleton/snice-skeleton.js +1 -1
- package/dist/cdn/slider/snice-slider.js +1 -1
- package/dist/cdn/sortable/snice-sortable.js +1 -1
- package/dist/cdn/sparkline/snice-sparkline.js +1 -1
- package/dist/cdn/spinner/snice-spinner.js +1 -1
- package/dist/cdn/split-button/snice-split-button.js +1 -1
- package/dist/cdn/split-pane/snice-split-pane.js +1 -1
- package/dist/cdn/spotlight/snice-spotlight.js +1 -1
- package/dist/cdn/stat-group/snice-stat-group.js +1 -1
- package/dist/cdn/step-input/snice-step-input.js +1 -1
- package/dist/cdn/stepper/snice-stepper.js +1 -1
- package/dist/cdn/switch/snice-switch.js +1 -1
- package/dist/cdn/table/README.md +2 -2
- package/dist/cdn/table/snice-table.esm.js +1940 -407
- package/dist/cdn/table/snice-table.esm.js.map +1 -1
- package/dist/cdn/table/snice-table.esm.min.js +242 -53
- package/dist/cdn/table/snice-table.esm.min.js.map +1 -1
- package/dist/cdn/table/snice-table.js +1940 -407
- package/dist/cdn/table/snice-table.js.map +1 -1
- package/dist/cdn/table/snice-table.min.js +234 -45
- package/dist/cdn/table/snice-table.min.js.map +1 -1
- package/dist/cdn/tabs/snice-tabs.js +1 -1
- package/dist/cdn/tag/snice-tag.js +1 -1
- package/dist/cdn/tag-input/snice-tag-input.js +1 -1
- package/dist/cdn/terminal/snice-terminal.js +1 -1
- package/dist/cdn/testimonial/snice-testimonial.js +1 -1
- package/dist/cdn/textarea/snice-textarea.js +1 -1
- package/dist/cdn/time-picker/snice-time-picker.js +1 -1
- package/dist/cdn/time-range-picker/snice-time-range-picker.js +1 -1
- package/dist/cdn/timeline/snice-timeline.js +1 -1
- package/dist/cdn/timer/snice-timer.js +1 -1
- package/dist/cdn/toast/snice-toast.js +1 -1
- package/dist/cdn/tooltip/snice-tooltip.js +1 -1
- package/dist/cdn/tree/snice-tree.js +1 -1
- package/dist/cdn/treemap/snice-treemap.js +1 -1
- package/dist/cdn/user-card/snice-user-card.js +1 -1
- package/dist/cdn/video-player/snice-video-player.js +1 -1
- package/dist/cdn/virtual-scroller/snice-virtual-scroller.js +1 -1
- package/dist/cdn/waterfall/snice-waterfall.js +1 -1
- package/dist/cdn/weather/snice-weather.js +1 -1
- package/dist/cdn/work-order/snice-work-order.js +1 -1
- package/dist/components/calendar/snice-calendar.d.ts +187 -5
- package/dist/components/calendar/snice-calendar.js +537 -44
- package/dist/components/calendar/snice-calendar.js.map +1 -1
- package/dist/components/calendar/snice-calendar.types.d.ts +2 -1
- package/dist/components/code-block/formatter.d.ts +6 -0
- package/dist/components/code-block/formatter.js +174 -164
- package/dist/components/code-block/formatter.js.map +1 -1
- package/dist/components/code-block/grammars/snice.json +1 -1
- package/dist/components/code-block/grammars/typescript.json +1 -1
- package/dist/components/command-palette/snice-command-palette.js +1 -1
- package/dist/components/command-palette/snice-command-palette.js.map +1 -1
- package/dist/components/progress/snice-progress.js +1 -1
- package/dist/components/progress/snice-progress.js.map +1 -1
- package/dist/components/qr-code/qrcode.d.ts +1 -1
- package/dist/components/qr-code/qrcode.js +18 -2
- package/dist/components/qr-code/qrcode.js.map +1 -1
- package/dist/components/receipt/snice-receipt.js +4 -1
- package/dist/components/receipt/snice-receipt.js.map +1 -1
- package/dist/components/select/snice-select.d.ts +1 -1
- package/dist/components/select/snice-select.js +5 -8
- package/dist/components/select/snice-select.js.map +1 -1
- package/dist/components/table/snice-cell-actions.js +1 -1
- package/dist/components/table/snice-cell-actions.js.map +1 -1
- package/dist/components/table/snice-cell-color.js +1 -1
- package/dist/components/table/snice-cell-color.js.map +1 -1
- package/dist/components/table/snice-cell-date.js +20 -8
- package/dist/components/table/snice-cell-date.js.map +1 -1
- package/dist/components/table/snice-cell-email.js +1 -1
- package/dist/components/table/snice-cell-email.js.map +1 -1
- package/dist/components/table/snice-cell-image.js +1 -1
- package/dist/components/table/snice-cell-image.js.map +1 -1
- package/dist/components/table/snice-cell-json.js +1 -1
- package/dist/components/table/snice-cell-json.js.map +1 -1
- package/dist/components/table/snice-cell-link.js +1 -1
- package/dist/components/table/snice-cell-link.js.map +1 -1
- package/dist/components/table/snice-cell-location.js +1 -1
- package/dist/components/table/snice-cell-location.js.map +1 -1
- package/dist/components/table/snice-cell-phone.js +1 -1
- package/dist/components/table/snice-cell-phone.js.map +1 -1
- package/dist/components/table/snice-cell-status.js +1 -1
- package/dist/components/table/snice-cell-status.js.map +1 -1
- package/dist/components/table/snice-cell.d.ts +10 -0
- package/dist/components/table/snice-cell.js +59 -13
- package/dist/components/table/snice-cell.js.map +1 -1
- package/dist/components/table/snice-row.d.ts +0 -1
- package/dist/components/table/snice-row.js +4 -10
- package/dist/components/table/snice-row.js.map +1 -1
- package/dist/components/table/snice-table.d.ts +170 -2
- package/dist/components/table/snice-table.js +868 -189
- package/dist/components/table/snice-table.js.map +1 -1
- package/dist/components/table/snice-table.types.d.ts +17 -0
- package/dist/components/table/table-cell-presentation.d.ts +17 -4
- package/dist/components/table/table-cell-presentation.js +37 -11
- package/dist/components/table/table-cell-presentation.js.map +1 -1
- package/dist/components/table/table-column-manager.d.ts +153 -2
- package/dist/components/table/table-column-manager.js +364 -43
- package/dist/components/table/table-column-manager.js.map +1 -1
- package/dist/components/table/table-date.d.ts +29 -0
- package/dist/components/table/table-date.js +78 -0
- package/dist/components/table/table-date.js.map +1 -0
- package/dist/components/table/table-export.js +6 -2
- package/dist/components/table/table-export.js.map +1 -1
- package/dist/components/table/table-filter-engine.d.ts +9 -0
- package/dist/components/table/table-filter-engine.js +58 -14
- package/dist/components/table/table-filter-engine.js.map +1 -1
- package/dist/components/table/table-keyboard.d.ts +8 -0
- package/dist/components/table/table-keyboard.js +14 -3
- package/dist/components/table/table-keyboard.js.map +1 -1
- package/dist/components/table/table-toolbar.js +1 -0
- package/dist/components/table/table-toolbar.js.map +1 -1
- package/dist/components/table/table-tree-data.d.ts +2 -0
- package/dist/components/table/table-tree-data.js +35 -9
- package/dist/components/table/table-tree-data.js.map +1 -1
- package/dist/components/table/table-virtualizer.d.ts +44 -7
- package/dist/components/table/table-virtualizer.js +101 -54
- package/dist/components/table/table-virtualizer.js.map +1 -1
- package/dist/components/theme/theme.css +9 -0
- package/dist/index.cjs +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.iife.js +1 -1
- package/dist/react/SniceProvider.js +1 -1
- package/dist/react/SniceRouter.js +1 -1
- package/dist/react/index.js +1 -1
- package/dist/react/matchRoute.js +1 -1
- package/dist/react/useRequestHandler.js +1 -1
- package/dist/symbols.cjs +1 -1
- package/dist/symbols.esm.js +1 -1
- package/dist/testing-dom.cjs +1 -1
- package/dist/testing-dom.esm.js +1 -1
- package/dist/transitions.cjs +1 -1
- package/dist/transitions.esm.js +1 -1
- package/docs/ai/DEVELOPMENT.md +93 -2
- package/docs/ai/components/calendar.md +113 -10
- package/docs/ai/components/code-block.md +4 -0
- package/docs/ai/components/doc.md +1 -1
- package/docs/ai/components/progress.md +1 -0
- package/docs/ai/components/receipt.md +1 -1
- package/docs/ai/components/table.md +29 -30
- package/docs/ai/components/theme.md +1 -0
- package/docs/ai/events.md +30 -0
- package/docs/ai/theme.md +1 -0
- package/docs/components/calendar.md +171 -11
- package/docs/components/code-block.md +2 -0
- package/docs/components/doc.md +1 -1
- package/docs/components/progress.md +13 -0
- package/docs/components/receipt.md +1 -0
- package/docs/components/table.md +274 -15
- package/docs/components/theme.md +5 -0
- package/docs/events.md +49 -0
- package/docs/plans/2026-03-06-date-range-picker-plan.md +4 -4
- package/docs/plans/2026-03-07-table-mui-parity-design.md +1 -1
- package/docs/plans/2026-03-09-action-bar-plan.md +11 -11
- package/docs/superpowers/specs/2026-07-09-table-incredible-design.md +1 -1
- package/docs/superpowers/specs/2026-07-09-table-phase0-implementation.md +2 -2
- package/package.json +3 -1
- package/vscode.html-custom-data.json +13 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* snice v7.
|
|
2
|
+
* snice v7.8.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.
|
|
@@ -237,7 +237,7 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
237
237
|
return _classThis;
|
|
238
238
|
})();
|
|
239
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-xs, .75rem);font-weight:var(--snice-font-weight-medium,500);color:var(--snice-color-text,rgb(23 23 23));cursor:pointer}.calendar__more:hover{text-decoration:underline}.calendar__more: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__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}}";
|
|
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}:host([overlay-open]){position:relative;z-index:var(--snice-z-floating,1000)}.calendar{width:100%;max-width:37.5rem;position:relative;height:100%;display:flex;flex-direction:column}.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,minmax(0,1fr));grid-template-rows:min-content repeat(6,var(--calendar-row-cap,auto));flex:1 1 auto;position:relative;background:var(--snice-color-surface,rgb(255 255 255));container-type:inline-size}.calendar__weekday{box-sizing:border-box;min-width:0;overflow:hidden;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:min(max(calc(100cqw / 7),3rem,calc(2.125rem + var(--calendar-week-lanes,0) * 1.375rem + var(--calendar-week-more,0rem))),var(--calendar-row-cap,100000px));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--week-start{border-left:1px solid var(--snice-color-border,rgb(226 226 226))}.calendar--week-numbers .calendar__day--week-start{border-left:none}.calendar__day--stretch{min-height:min(max(3rem,calc(2.125rem + var(--calendar-week-lanes,0) * 1.375rem + var(--calendar-week-more,0rem))),var(--calendar-row-cap,100000px))}.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);position:absolute;inset:0 0 auto 0;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-bar--compact{padding-inline:var(--snice-spacing-3xs,0.125rem)}.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:absolute;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__more-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--snice-spacing-3xs,.125rem);max-height:15rem;overflow-y:auto}.calendar__more-item{display:flex;align-items:center;gap:var(--snice-spacing-xs,.5rem);width:100%;padding:var(--snice-spacing-2xs,.25rem) var(--snice-spacing-xs,.5rem);border:none;border-radius:var(--snice-border-radius-sm,.125rem);background:0 0;color:var(--snice-color-text,rgb(23 23 23));font-family:inherit;font-size:var(--snice-font-size-sm, .875rem);text-align:start;cursor:pointer;transition:background-color var(--snice-transition-fast, 150ms) ease}.calendar__more-item:hover{background:var(--snice-color-surface-container-low,rgb(250 250 250))}.calendar__more-item: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__more-dot{flex:none;width:.5rem;height:.5rem;border-radius:50%;background:var(--snice-color-primary,rgb(37 99 235))}.calendar__more-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.calendar__more-date{margin:0 0 var(--snice-spacing-2xs,.25rem);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))}.calendar__tooltip{position:absolute;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-tooltip-color,rgb(255 255 255));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-xs, .75rem);font-weight:var(--snice-font-weight-medium,500);color:var(--snice-color-text,rgb(23 23 23));cursor:pointer}.calendar__more:hover{text-decoration:underline}.calendar__more: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--week-numbers .calendar__grid{grid-template-columns:var(--calendar-week-number-width,2.25rem) repeat(7,minmax(0,1fr))}.calendar--week-numbers .calendar__weekday{padding-inline:var(--snice-spacing-2xs,0.25rem)}.calendar--week-numbers .calendar__day{min-height:min(max(calc((100cqw - var(--calendar-week-number-width,2.25rem))/ 7),3rem,calc(2.125rem + var(--calendar-week-lanes,0) * 1.375rem + var(--calendar-week-more,0rem))),var(--calendar-row-cap,100000px))}.calendar__week-number{box-sizing:border-box;display:flex;align-items:flex-start;justify-content:center;padding:var(--snice-spacing-xs,.5rem) var(--snice-spacing-2xs,.25rem);text-align:center;font-size:var(--snice-font-size-xs, .75rem);font-variant-numeric:tabular-nums;color:var(--snice-color-text-tertiary,rgb(115 115 115));background:var(--snice-color-surface-container-low,rgb(250 250 250));border:1px solid var(--snice-color-border,rgb(226 226 226));border-top:none}.calendar__week-number--header{background:var(--snice-color-surface,rgb(255 255 255));border:none;border-bottom: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}}";
|
|
241
241
|
|
|
242
242
|
let SniceCalendar = (() => {
|
|
243
243
|
let _classDecorators = [snice.element('snice-calendar')];
|
|
@@ -290,18 +290,24 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
290
290
|
let _eventPopover_extraInitializers = [];
|
|
291
291
|
let _dispatchChange_decorators;
|
|
292
292
|
let _dispatchEventClick_decorators;
|
|
293
|
-
let _dispatchMoreClick_decorators;
|
|
294
293
|
let _styles_decorators;
|
|
295
294
|
let _initialize_decorators;
|
|
296
295
|
let _requestEventPopoverContent_decorators;
|
|
297
296
|
let _cleanupPopover_decorators;
|
|
298
297
|
let _handlePropertyChange_decorators;
|
|
298
|
+
let _handleCalendarResize_decorators;
|
|
299
299
|
let _handleWeekdayInputsChange_decorators;
|
|
300
300
|
var SniceCalendar = class extends _classSuper {
|
|
301
301
|
static { _classThis = this; }
|
|
302
302
|
constructor() {
|
|
303
303
|
super(...arguments);
|
|
304
|
-
|
|
304
|
+
/**
|
|
305
|
+
* The selected day, or `null` for "nothing selected yet" — the state a
|
|
306
|
+
* calendar starts in. A default of today would paint the selected
|
|
307
|
+
* background over today's own highlight, making `highlight-today` invisible
|
|
308
|
+
* and announcing `aria-selected` for a choice the user never made.
|
|
309
|
+
*/
|
|
310
|
+
this.value = (__runInitializers(this, _instanceExtraInitializers), __runInitializers(this, _value_initializers, null));
|
|
305
311
|
this.view = (__runInitializers(this, _value_extraInitializers), __runInitializers(this, _view_initializers, 'month'));
|
|
306
312
|
this.events = (__runInitializers(this, _view_extraInitializers), __runInitializers(this, _events_initializers, []));
|
|
307
313
|
this.minDate = (__runInitializers(this, _events_extraInitializers), __runInitializers(this, _minDate_initializers, ''));
|
|
@@ -332,6 +338,7 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
332
338
|
this.closeEventPopover({ returnFocus: false });
|
|
333
339
|
};
|
|
334
340
|
this.dayCells = [];
|
|
341
|
+
this.weekNumberCells = [];
|
|
335
342
|
this.focusedDate = null;
|
|
336
343
|
this.handleGridKeydown = (e) => {
|
|
337
344
|
const target = e.target;
|
|
@@ -394,6 +401,12 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
394
401
|
cell?.focus();
|
|
395
402
|
});
|
|
396
403
|
};
|
|
404
|
+
/** True while `--calendar-row-cap` is holding the week rows below the size
|
|
405
|
+
* they would take of their own accord. */
|
|
406
|
+
this.rowCapped = false;
|
|
407
|
+
/** Box the stripes were last laid out against, so a resize that changes
|
|
408
|
+
* nothing (including the one the render itself causes) is a no-op. */
|
|
409
|
+
this.laidOutFor = '';
|
|
397
410
|
}
|
|
398
411
|
static {
|
|
399
412
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
@@ -413,21 +426,21 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
413
426
|
_eventPopover_decorators = [snice.property({ attribute: false })];
|
|
414
427
|
_dispatchChange_decorators = [snice.dispatch('calendar-change', { bubbles: true, composed: true })];
|
|
415
428
|
_dispatchEventClick_decorators = [snice.dispatch('calendar-event-click', { bubbles: true, composed: true })];
|
|
416
|
-
_dispatchMoreClick_decorators = [snice.dispatch('calendar-more-click', { bubbles: true, composed: true })];
|
|
417
429
|
_styles_decorators = [snice.styles()];
|
|
418
430
|
_initialize_decorators = [snice.ready()];
|
|
419
431
|
_requestEventPopoverContent_decorators = [snice.request('calendar/event-popover')];
|
|
420
432
|
_cleanupPopover_decorators = [snice.dispose()];
|
|
421
|
-
_handlePropertyChange_decorators = [snice.watch('value'), snice.watch('events'), snice.watch('eventTooltip'), snice.watch('noDaySelect'), snice.watch('cellSizing')];
|
|
433
|
+
_handlePropertyChange_decorators = [snice.watch('value'), snice.watch('events'), snice.watch('eventTooltip'), snice.watch('noDaySelect'), snice.watch('cellSizing'), snice.watch('showWeekNumbers'), snice.watch('highlightToday')];
|
|
434
|
+
_handleCalendarResize_decorators = [snice.observe('resize', { throttle: 100 })];
|
|
422
435
|
_handleWeekdayInputsChange_decorators = [snice.watch('locale'), snice.watch('firstDayOfWeek')];
|
|
423
436
|
__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);
|
|
424
437
|
__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);
|
|
425
|
-
__esDecorate(this, null, _dispatchMoreClick_decorators, { kind: "method", name: "dispatchMoreClick", static: false, private: false, access: { has: obj => "dispatchMoreClick" in obj, get: obj => obj.dispatchMoreClick }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
426
438
|
__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);
|
|
427
439
|
__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);
|
|
428
440
|
__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);
|
|
429
441
|
__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);
|
|
430
442
|
__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);
|
|
443
|
+
__esDecorate(this, null, _handleCalendarResize_decorators, { kind: "method", name: "handleCalendarResize", static: false, private: false, access: { has: obj => "handleCalendarResize" in obj, get: obj => obj.handleCalendarResize }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
431
444
|
__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);
|
|
432
445
|
__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);
|
|
433
446
|
__esDecorate(null, null, _view_decorators, { kind: "field", name: "view", static: false, private: false, access: { has: obj => "view" in obj, get: obj => obj.view, set: (obj, value) => { obj.view = value; } }, metadata: _metadata }, _view_initializers, _view_extraInitializers);
|
|
@@ -447,6 +460,14 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
447
460
|
SniceCalendar = _classThis = _classDescriptor.value;
|
|
448
461
|
if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
449
462
|
}
|
|
463
|
+
/**
|
|
464
|
+
* Columns the day grid is shifted by. The week-number column occupies the
|
|
465
|
+
* grid's first column, so every explicitly-placed child — weekday headers,
|
|
466
|
+
* day cells, event stripes — moves one column right while it is shown.
|
|
467
|
+
*/
|
|
468
|
+
get columnOffset() {
|
|
469
|
+
return this.showWeekNumbers ? 1 : 0;
|
|
470
|
+
}
|
|
450
471
|
computeRovingIndex(days) {
|
|
451
472
|
// Prefer: focused → selected → today → first in-month day
|
|
452
473
|
const same = (a, b) => a.getFullYear() === b.getFullYear() &&
|
|
@@ -477,8 +498,24 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
477
498
|
dispatchEventClick(event) {
|
|
478
499
|
return { event, calendar: this };
|
|
479
500
|
}
|
|
501
|
+
/**
|
|
502
|
+
* `calendar-more-click` carries a default action (the built-in day panel),
|
|
503
|
+
* so it is cancelable and the component has to read the result of the
|
|
504
|
+
* dispatch. `@dispatch` accepts `cancelable` — it is EventInit passthrough —
|
|
505
|
+
* but the decorated method returns the detail, not `dispatchEvent`'s
|
|
506
|
+
* boolean, so a cancelable default action cannot be observed through it.
|
|
507
|
+
* Dispatched by hand for that reason, the same way `snice-link`'s `navigate`
|
|
508
|
+
* and `snice-stepper`'s `step-change` are.
|
|
509
|
+
*
|
|
510
|
+
* @returns `false` when a listener called `preventDefault()`.
|
|
511
|
+
*/
|
|
480
512
|
dispatchMoreClick(date, count) {
|
|
481
|
-
return
|
|
513
|
+
return this.dispatchEvent(new CustomEvent('calendar-more-click', {
|
|
514
|
+
detail: { date, count, calendar: this },
|
|
515
|
+
bubbles: true,
|
|
516
|
+
composed: true,
|
|
517
|
+
cancelable: true,
|
|
518
|
+
}));
|
|
482
519
|
}
|
|
483
520
|
styles() {
|
|
484
521
|
return snice.css /*css*/ `${cssContent}`;
|
|
@@ -531,7 +568,7 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
531
568
|
weekdayEl.className = 'calendar__weekday';
|
|
532
569
|
weekdayEl.textContent = day;
|
|
533
570
|
weekdayEl.style.gridRow = '1';
|
|
534
|
-
weekdayEl.style.gridColumn = String(i + 1);
|
|
571
|
+
weekdayEl.style.gridColumn = String(i + 1 + this.columnOffset);
|
|
535
572
|
this.grid.appendChild(weekdayEl);
|
|
536
573
|
});
|
|
537
574
|
// Mark grid for a11y
|
|
@@ -548,13 +585,33 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
548
585
|
// date so today/selected gets the 0.
|
|
549
586
|
dayCell.setAttribute('tabindex', i === 0 ? '0' : '-1');
|
|
550
587
|
dayCell.style.gridRow = String(Math.floor(i / 7) + 2);
|
|
551
|
-
dayCell.style.gridColumn = String((i % 7) + 1);
|
|
588
|
+
dayCell.style.gridColumn = String((i % 7) + 1 + this.columnOffset);
|
|
552
589
|
const dayNumber = document.createElement('div');
|
|
553
590
|
dayNumber.className = 'calendar__day-number';
|
|
554
591
|
dayCell.appendChild(dayNumber);
|
|
555
592
|
this.grid.appendChild(dayCell);
|
|
556
593
|
this.dayCells.push(dayCell);
|
|
557
594
|
}
|
|
595
|
+
// Week-number column: a header corner cell plus one row header per week
|
|
596
|
+
// row, all in the reserved first column. Built once here and attached only
|
|
597
|
+
// while `show-week-numbers` is on, so a calendar without it carries no
|
|
598
|
+
// extra nodes.
|
|
599
|
+
this.weekNumberHeader = document.createElement('div');
|
|
600
|
+
this.weekNumberHeader.className =
|
|
601
|
+
'calendar__week-number calendar__week-number--header';
|
|
602
|
+
this.weekNumberHeader.setAttribute('part', 'week-number-header');
|
|
603
|
+
this.weekNumberHeader.setAttribute('aria-hidden', 'true');
|
|
604
|
+
this.weekNumberHeader.style.gridRow = '1';
|
|
605
|
+
this.weekNumberHeader.style.gridColumn = '1';
|
|
606
|
+
for (let week = 0; week < 6; week++) {
|
|
607
|
+
const weekCell = document.createElement('div');
|
|
608
|
+
weekCell.className = 'calendar__week-number';
|
|
609
|
+
weekCell.setAttribute('part', 'week-number');
|
|
610
|
+
weekCell.setAttribute('role', 'rowheader');
|
|
611
|
+
weekCell.style.gridRow = String(week + 2);
|
|
612
|
+
weekCell.style.gridColumn = '1';
|
|
613
|
+
this.weekNumberCells.push(weekCell);
|
|
614
|
+
}
|
|
558
615
|
// Shared tooltip overlay for event bars — one element, repositioned per
|
|
559
616
|
// bar, so rich content can load lazily without a tooltip instance per bar.
|
|
560
617
|
this.tooltipEl = document.createElement('div');
|
|
@@ -586,20 +643,40 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
586
643
|
async *requestEventPopoverContent(event) {
|
|
587
644
|
return await (yield { event });
|
|
588
645
|
}
|
|
589
|
-
|
|
646
|
+
/**
|
|
647
|
+
* Opens the shared overlay, empty, anchored on `anchor`, and arms its
|
|
648
|
+
* Escape / outside-press dismissal. Both panels the calendar owns — the
|
|
649
|
+
* event popover and the "+N more" day list — go through here, so they share
|
|
650
|
+
* one dismissal contract and one focus-return target.
|
|
651
|
+
*
|
|
652
|
+
* @returns the token identifying this opening; async content must check it
|
|
653
|
+
* against `popoverToken` before painting.
|
|
654
|
+
*/
|
|
655
|
+
beginPopover(anchor, label) {
|
|
590
656
|
const token = ++this.popoverToken;
|
|
591
657
|
this.hideEventTooltip();
|
|
592
|
-
//
|
|
593
|
-
this
|
|
658
|
+
// A trigger that advertises aria-haspopup owes the reader the panel's
|
|
659
|
+
// state too — and the previous anchor is stale the moment this one opens
|
|
660
|
+
// (an entry in the day panel re-anchors the overlay on the same chip).
|
|
661
|
+
this.setAnchorExpanded(this.popoverBar, false);
|
|
662
|
+
this.setAnchorExpanded(anchor, true);
|
|
663
|
+
this.popoverBar = anchor;
|
|
664
|
+
this.popoverEl.setAttribute('aria-label', label);
|
|
594
665
|
this.popoverEl.replaceChildren();
|
|
666
|
+
this.popoverEl.hidden = false;
|
|
667
|
+
this.syncOverlayLift();
|
|
668
|
+
document.addEventListener('keydown', this.boundPopoverEscape, true);
|
|
669
|
+
document.addEventListener('mousedown', this.boundPopoverOutside, true);
|
|
670
|
+
return token;
|
|
671
|
+
}
|
|
672
|
+
async openEventPopover(bar, event) {
|
|
673
|
+
// Anchor + loading shell first, so slow content still feels responsive.
|
|
674
|
+
const token = this.beginPopover(bar, event.title || 'Event details');
|
|
595
675
|
const loading = document.createElement('div');
|
|
596
676
|
loading.className = 'calendar__popover-loading';
|
|
597
677
|
loading.textContent = 'Loading…';
|
|
598
678
|
this.popoverEl.appendChild(loading);
|
|
599
|
-
this.popoverEl.hidden = false;
|
|
600
679
|
this.positionPopover(bar);
|
|
601
|
-
document.addEventListener('keydown', this.boundPopoverEscape, true);
|
|
602
|
-
document.addEventListener('mousedown', this.boundPopoverOutside, true);
|
|
603
680
|
let content;
|
|
604
681
|
try {
|
|
605
682
|
if (event.popover !== true && event.popover) {
|
|
@@ -630,24 +707,133 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
630
707
|
this.positionPopover(bar);
|
|
631
708
|
this.popoverEl.focus();
|
|
632
709
|
}
|
|
710
|
+
/**
|
|
711
|
+
* The "+N more" chip's built-in default action: the day's hidden events,
|
|
712
|
+
* listed in the shared overlay.
|
|
713
|
+
*
|
|
714
|
+
* Wiring `calendar-more-click` is an application concern, but a chip that
|
|
715
|
+
* visibly does nothing when clicked reads as broken, so the component owns a
|
|
716
|
+
* sensible default. It is only a default — the event is cancelable, and
|
|
717
|
+
* `preventDefault()` leaves the day to the app.
|
|
718
|
+
*/
|
|
719
|
+
openMorePanel(chip, date, hidden) {
|
|
720
|
+
const dayLabel = date.toLocaleDateString(this.locale, { dateStyle: 'full' });
|
|
721
|
+
this.beginPopover(chip, `${hidden.length} more event${hidden.length === 1 ? '' : 's'} on ${dayLabel}`);
|
|
722
|
+
const heading = document.createElement('p');
|
|
723
|
+
heading.className = 'calendar__more-date';
|
|
724
|
+
heading.setAttribute('part', 'more-panel-date');
|
|
725
|
+
heading.textContent = dayLabel;
|
|
726
|
+
const list = document.createElement('ul');
|
|
727
|
+
list.className = 'calendar__more-list';
|
|
728
|
+
list.setAttribute('part', 'more-list');
|
|
729
|
+
// Explicit: `list-style: none` drops the implicit list role in WebKit.
|
|
730
|
+
list.setAttribute('role', 'list');
|
|
731
|
+
for (const event of hidden) {
|
|
732
|
+
const item = document.createElement('li');
|
|
733
|
+
const entry = document.createElement('button');
|
|
734
|
+
entry.type = 'button';
|
|
735
|
+
entry.className = 'calendar__more-item';
|
|
736
|
+
entry.setAttribute('part', 'more-item');
|
|
737
|
+
const dot = document.createElement('span');
|
|
738
|
+
dot.className = 'calendar__more-dot';
|
|
739
|
+
dot.setAttribute('part', 'more-dot');
|
|
740
|
+
dot.setAttribute('aria-hidden', 'true');
|
|
741
|
+
if (event.color)
|
|
742
|
+
dot.style.background = event.color;
|
|
743
|
+
const title = document.createElement('span');
|
|
744
|
+
title.className = 'calendar__more-title';
|
|
745
|
+
title.textContent = event.title;
|
|
746
|
+
entry.append(dot, title);
|
|
747
|
+
entry.onclick = (e) => this.handleMorePanelEntry(chip, event, e);
|
|
748
|
+
item.appendChild(entry);
|
|
749
|
+
list.appendChild(item);
|
|
750
|
+
}
|
|
751
|
+
this.popoverEl.append(heading, list);
|
|
752
|
+
this.positionPopover(chip);
|
|
753
|
+
this.popoverEl.focus();
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* A panel entry behaves like the event's own stripe: it reports the click,
|
|
757
|
+
* and drills into the event's popover when it has one. Without popover
|
|
758
|
+
* content there is nothing further to show, so the panel closes and hands
|
|
759
|
+
* focus back to the chip.
|
|
760
|
+
*/
|
|
761
|
+
handleMorePanelEntry(chip, event, e) {
|
|
762
|
+
this.handleEventClick(event, e);
|
|
763
|
+
if (event.popover)
|
|
764
|
+
this.openEventPopover(chip, event);
|
|
765
|
+
else
|
|
766
|
+
this.closeEventPopover();
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* Places an overlay at a point given in viewport coordinates.
|
|
770
|
+
*
|
|
771
|
+
* `:host` declares `contain: layout`, which makes the host — not the
|
|
772
|
+
* viewport — the containing block for its `position: fixed` descendants, so
|
|
773
|
+
* viewport coordinates written straight into `left`/`top` land the overlay a
|
|
774
|
+
* whole host-offset down the page. The overlays are `position: absolute`
|
|
775
|
+
* inside `.calendar` instead, and the target is converted into that box
|
|
776
|
+
* here, which is correct with or without the containment.
|
|
777
|
+
*/
|
|
778
|
+
placeOverlay(el, viewportX, viewportY) {
|
|
779
|
+
// The containing block is the container's PADDING box, while the rect is
|
|
780
|
+
// its border box — `clientLeft`/`clientTop` are the border widths between
|
|
781
|
+
// them. They are 0 by default and non-zero only when a consumer borders
|
|
782
|
+
// the documented `::part(base)`, which would otherwise shift both overlays
|
|
783
|
+
// off their bar by that width.
|
|
784
|
+
const origin = this.container.getBoundingClientRect();
|
|
785
|
+
el.style.left = `${viewportX - origin.left - this.container.clientLeft}px`;
|
|
786
|
+
el.style.top = `${viewportY - origin.top - this.container.clientTop}px`;
|
|
787
|
+
}
|
|
788
|
+
/** Gap between a bar and its overlay, and the minimum viewport margin. */
|
|
789
|
+
static { this.OVERLAY_GAP = 6; }
|
|
790
|
+
static { this.OVERLAY_EDGE = 4; }
|
|
791
|
+
/** Clamps an overlay's left edge into the viewport. */
|
|
792
|
+
clampOverlayX(left, width) {
|
|
793
|
+
const edge = SniceCalendar.OVERLAY_EDGE;
|
|
794
|
+
const vw = window.innerWidth || 0;
|
|
795
|
+
return Math.max(edge, vw > 0 ? Math.min(left, vw - width - edge) : left);
|
|
796
|
+
}
|
|
633
797
|
positionPopover(bar) {
|
|
634
798
|
const rect = bar.getBoundingClientRect();
|
|
635
|
-
|
|
636
|
-
this.popoverEl.
|
|
799
|
+
const width = this.popoverEl.offsetWidth;
|
|
800
|
+
const height = this.popoverEl.offsetHeight;
|
|
801
|
+
const gap = SniceCalendar.OVERLAY_GAP;
|
|
802
|
+
const edge = SniceCalendar.OVERLAY_EDGE;
|
|
803
|
+
const vh = window.innerHeight || 0;
|
|
804
|
+
let y = rect.bottom + gap;
|
|
805
|
+
if (vh > 0 && y + height > vh - edge) {
|
|
806
|
+
// No room under the bar — flip above it, or pin to the bottom margin
|
|
807
|
+
// when the panel is taller than either side.
|
|
808
|
+
const above = rect.top - gap - height;
|
|
809
|
+
y = above >= edge ? above : Math.max(edge, vh - height - edge);
|
|
810
|
+
}
|
|
811
|
+
this.placeOverlay(this.popoverEl, this.clampOverlayX(rect.left, width), y);
|
|
637
812
|
}
|
|
638
813
|
closeEventPopover(options = {}) {
|
|
639
814
|
if (!this.popoverBar)
|
|
640
815
|
return;
|
|
641
816
|
this.popoverToken++;
|
|
642
817
|
const bar = this.popoverBar;
|
|
818
|
+
this.setAnchorExpanded(bar, false);
|
|
643
819
|
this.popoverBar = null;
|
|
644
820
|
this.popoverEl.hidden = true;
|
|
645
821
|
this.popoverEl.replaceChildren();
|
|
822
|
+
this.syncOverlayLift();
|
|
646
823
|
document.removeEventListener('keydown', this.boundPopoverEscape, true);
|
|
647
824
|
document.removeEventListener('mousedown', this.boundPopoverOutside, true);
|
|
648
825
|
if (options.returnFocus !== false && bar.isConnected)
|
|
649
826
|
bar.focus();
|
|
650
827
|
}
|
|
828
|
+
/** Keeps a popup trigger's `aria-expanded` in step with the overlay. Guarded
|
|
829
|
+
* on `aria-haspopup` so only the anchors that actually advertise a popup —
|
|
830
|
+
* the "+N more" chip and an event bar carrying popover content — claim the
|
|
831
|
+
* state; a plain bar is not a trigger and must not report one. */
|
|
832
|
+
setAnchorExpanded(anchor, expanded) {
|
|
833
|
+
if (!anchor?.hasAttribute('aria-haspopup'))
|
|
834
|
+
return;
|
|
835
|
+
anchor.setAttribute('aria-expanded', String(expanded));
|
|
836
|
+
}
|
|
651
837
|
cleanupPopover() {
|
|
652
838
|
document.removeEventListener('keydown', this.boundPopoverEscape, true);
|
|
653
839
|
document.removeEventListener('mousedown', this.boundPopoverOutside, true);
|
|
@@ -677,16 +863,34 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
677
863
|
this.tooltipEl.hidden = false;
|
|
678
864
|
this.tooltipBar = bar;
|
|
679
865
|
bar.setAttribute('aria-describedby', this.tooltipEl.id);
|
|
680
|
-
|
|
866
|
+
this.syncOverlayLift();
|
|
867
|
+
this.positionTooltip(bar);
|
|
868
|
+
}
|
|
869
|
+
positionTooltip(bar) {
|
|
681
870
|
const rect = bar.getBoundingClientRect();
|
|
682
|
-
|
|
683
|
-
|
|
871
|
+
const gap = SniceCalendar.OVERLAY_GAP;
|
|
872
|
+
const edge = SniceCalendar.OVERLAY_EDGE;
|
|
873
|
+
// Above the bar, or under it when the top of the viewport is in the way.
|
|
874
|
+
let y = rect.top - this.tooltipEl.offsetHeight - gap;
|
|
875
|
+
if (y < edge)
|
|
876
|
+
y = rect.bottom + gap;
|
|
877
|
+
this.placeOverlay(this.tooltipEl, this.clampOverlayX(rect.left, this.tooltipEl.offsetWidth), y);
|
|
684
878
|
}
|
|
685
879
|
hideEventTooltip() {
|
|
686
880
|
this.tooltipToken++;
|
|
687
881
|
this.tooltipEl.hidden = true;
|
|
688
882
|
this.tooltipBar?.removeAttribute('aria-describedby');
|
|
689
883
|
this.tooltipBar = null;
|
|
884
|
+
this.syncOverlayLift();
|
|
885
|
+
}
|
|
886
|
+
/**
|
|
887
|
+
* Marks the host while a tooltip or popover is showing. Layout containment
|
|
888
|
+
* makes the host a stacking context, so an overlay can only paint above what
|
|
889
|
+
* follows the calendar if the host itself is lifted — see
|
|
890
|
+
* `:host([overlay-open])` in the stylesheet.
|
|
891
|
+
*/
|
|
892
|
+
syncOverlayLift() {
|
|
893
|
+
this.toggleAttribute('overlay-open', !!this.popoverBar || !!this.tooltipBar);
|
|
690
894
|
}
|
|
691
895
|
updateView() {
|
|
692
896
|
// Update header title
|
|
@@ -697,6 +901,9 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
697
901
|
// Update day cells
|
|
698
902
|
const days = this.getMonthDays();
|
|
699
903
|
const currentMonth = this.displayDate.getMonth();
|
|
904
|
+
// The week-number column shifts every explicitly-placed grid child, so it
|
|
905
|
+
// is resolved before the cells are positioned.
|
|
906
|
+
this.syncWeekNumberColumn(days);
|
|
700
907
|
// Resolve which cell should be tab-stoppable (roving tabindex).
|
|
701
908
|
const rovingIndex = this.computeRovingIndex(days);
|
|
702
909
|
days.forEach((date, i) => {
|
|
@@ -710,6 +917,11 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
710
917
|
const isDisabled = this.isDisabled(date);
|
|
711
918
|
// Update classes (preserving role)
|
|
712
919
|
cell.className = 'calendar__day';
|
|
920
|
+
// The week's first cell draws the grid's left edge. A class, not
|
|
921
|
+
// :nth-child — the week-number column adds siblings that would shift
|
|
922
|
+
// any positional selector.
|
|
923
|
+
if (i % 7 === 0)
|
|
924
|
+
cell.classList.add('calendar__day--week-start');
|
|
713
925
|
if (isOtherMonth)
|
|
714
926
|
cell.classList.add('calendar__day--other-month');
|
|
715
927
|
if (isToday)
|
|
@@ -738,15 +950,221 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
738
950
|
});
|
|
739
951
|
this.renderEventStripes(days);
|
|
740
952
|
}
|
|
741
|
-
/**
|
|
742
|
-
*
|
|
743
|
-
|
|
953
|
+
/**
|
|
954
|
+
* Attaches or detaches the week-number column and re-places every
|
|
955
|
+
* explicitly-positioned grid child for the resulting column offset.
|
|
956
|
+
*/
|
|
957
|
+
syncWeekNumberColumn(days) {
|
|
958
|
+
const show = this.showWeekNumbers;
|
|
959
|
+
this.container.classList.toggle('calendar--week-numbers', show);
|
|
960
|
+
if (show) {
|
|
961
|
+
// Inserted in reading order — the corner cell ahead of the weekday
|
|
962
|
+
// strip, each row header ahead of its week's day cells.
|
|
963
|
+
if (!this.weekNumberHeader.isConnected) {
|
|
964
|
+
this.grid.insertBefore(this.weekNumberHeader, this.grid.firstChild);
|
|
965
|
+
}
|
|
966
|
+
this.weekNumberCells.forEach((cell, week) => {
|
|
967
|
+
if (!cell.isConnected)
|
|
968
|
+
this.grid.insertBefore(cell, this.dayCells[week * 7]);
|
|
969
|
+
const weekNumber = this.getWeekNumber(days[week * 7]);
|
|
970
|
+
cell.textContent = String(weekNumber);
|
|
971
|
+
cell.setAttribute('aria-label', `Week ${weekNumber}`);
|
|
972
|
+
});
|
|
973
|
+
}
|
|
974
|
+
else {
|
|
975
|
+
this.weekNumberHeader.remove();
|
|
976
|
+
this.weekNumberCells.forEach(cell => cell.remove());
|
|
977
|
+
}
|
|
978
|
+
const offset = this.columnOffset;
|
|
979
|
+
const weekdays = this.grid.querySelectorAll('.calendar__weekday');
|
|
980
|
+
weekdays.forEach((el, i) => {
|
|
981
|
+
el.style.gridColumn = String(i + 1 + offset);
|
|
982
|
+
});
|
|
983
|
+
this.dayCells.forEach((cell, i) => {
|
|
984
|
+
cell.style.gridColumn = String((i % 7) + 1 + offset);
|
|
985
|
+
});
|
|
986
|
+
}
|
|
987
|
+
/**
|
|
988
|
+
* Number of the week that starts on `weekStart`.
|
|
989
|
+
*
|
|
990
|
+
* Monday-start calendars use ISO-8601 (week 1 is the week holding the year's
|
|
991
|
+
* first Thursday). Every other start-of-week uses the common civil rule —
|
|
992
|
+
* the week containing January 1 is week 1 — anchored on the year the week
|
|
993
|
+
* ends in, so the turn-of-year week is numbered once, not twice.
|
|
994
|
+
*/
|
|
995
|
+
getWeekNumber(weekStart) {
|
|
996
|
+
const WEEK_MS = 7 * 24 * 60 * 60 * 1000;
|
|
997
|
+
const midnight = (y, m, d) => new Date(y, m, d).getTime();
|
|
998
|
+
if (this.firstDayOfWeek === 1) {
|
|
999
|
+
// The ISO week is named by its Thursday.
|
|
1000
|
+
const thursday = new Date(weekStart.getFullYear(), weekStart.getMonth(), weekStart.getDate() + 3);
|
|
1001
|
+
const isoYear = thursday.getFullYear();
|
|
1002
|
+
// January 4 is always in ISO week 1; walk back to that week's Monday.
|
|
1003
|
+
const jan4 = new Date(isoYear, 0, 4);
|
|
1004
|
+
const week1Monday = midnight(isoYear, 0, 4 - ((jan4.getDay() + 6) % 7));
|
|
1005
|
+
return 1 + Math.round((thursday.getTime() - week1Monday) / WEEK_MS);
|
|
1006
|
+
}
|
|
1007
|
+
const weekEnd = new Date(weekStart.getFullYear(), weekStart.getMonth(), weekStart.getDate() + 6);
|
|
1008
|
+
const year = weekEnd.getFullYear();
|
|
1009
|
+
const jan1 = new Date(year, 0, 1);
|
|
1010
|
+
const week1Start = midnight(year, 0, 1 - ((jan1.getDay() - this.firstDayOfWeek + 7) % 7));
|
|
1011
|
+
return 1 + Math.round((midnight(weekStart.getFullYear(), weekStart.getMonth(), weekStart.getDate())
|
|
1012
|
+
- week1Start) / WEEK_MS);
|
|
1013
|
+
}
|
|
1014
|
+
/** Event-lane geometry in rem — mirrors snice-calendar.css. */
|
|
1015
|
+
static { this.LANE_HEIGHT_REM = 1.375; }
|
|
1016
|
+
/** Day-number strip above the first lane (the constant in the cell's
|
|
1017
|
+
* min-height reservation). */
|
|
1018
|
+
static { this.LANE_STACK_TOP_REM = 2.125; }
|
|
1019
|
+
/** Strip the "+N more" chip claims when a stack overflows. */
|
|
1020
|
+
static { this.MORE_CHIP_REM = 1; }
|
|
1021
|
+
/** Intrinsic floor of a `cell-sizing="stretch"` cell. */
|
|
1022
|
+
static { this.STRETCH_FLOOR_REM = 3; }
|
|
1023
|
+
/** Lane depth used when there is no layout to measure (headless DOM,
|
|
1024
|
+
* detached, `display: none`). */
|
|
1025
|
+
static { this.DEFAULT_EVENT_LANES = 3; }
|
|
1026
|
+
/**
|
|
1027
|
+
* Height a single lane physically occupies, measured from the top of the
|
|
1028
|
+
* cell: the bar sits 1.875rem down and is 1.125rem tall.
|
|
1029
|
+
*
|
|
1030
|
+
* LANE_STACK_TOP_REM + LANE_HEIGHT_REM (3.5rem) is the *budgeted* cost of a
|
|
1031
|
+
* lane — it carries a bottom gap so the next lane has somewhere to go. This
|
|
1032
|
+
* is the smaller number the budget falls back to when the row cannot grow:
|
|
1033
|
+
* the point below which a drawn lane would be clipped by its own cell.
|
|
1034
|
+
*/
|
|
1035
|
+
static { this.LANE_MIN_FIT_REM = 3; }
|
|
1036
|
+
/** Height the "+N more" chip itself occupies at the bottom of the cell. */
|
|
1037
|
+
static { this.MORE_CHIP_FIT_REM = 1.125; }
|
|
1038
|
+
/**
|
|
1039
|
+
* Narrowest segment, in rem, that still carries an event avatar.
|
|
1040
|
+
*
|
|
1041
|
+
* A one-day chip in a 400px month grid is ~57px wide; the avatar, its gap,
|
|
1042
|
+
* and the bar padding leave the title three characters ("Des…"). The title
|
|
1043
|
+
* is the payload and the avatar is an adornment, so — like every
|
|
1044
|
+
* professional calendar — a segment that cannot carry both keeps the title
|
|
1045
|
+
* and drops the adornment. 4.5rem is the width at which a default-size
|
|
1046
|
+
* title still reads next to the avatar.
|
|
1047
|
+
*/
|
|
1048
|
+
static { this.AVATAR_MIN_SEGMENT_REM = 4.5; }
|
|
1049
|
+
/**
|
|
1050
|
+
* How many event lanes fit in a day cell, and how many still fit once the
|
|
1051
|
+
* "+N more" chip claims its strip.
|
|
1052
|
+
*
|
|
1053
|
+
* Measured from the cell's own height with every lane reservation cleared,
|
|
1054
|
+
* so the budget follows whatever sizes the cell — the square baseline
|
|
1055
|
+
* (`100cqw / 7`), a height the host imposes on the calendar, or the stretch
|
|
1056
|
+
* floor — and never feeds back on itself. A `cell-sizing="stretch"` cell the
|
|
1057
|
+
* host does not constrain has no budget at all: its row grows to fit every
|
|
1058
|
+
* lane, which is what "collapse to content" means.
|
|
1059
|
+
*/
|
|
1060
|
+
laneBudget() {
|
|
1061
|
+
const rem = parseFloat(getComputedStyle(document.documentElement).fontSize) || 16;
|
|
1062
|
+
const height = this.dayCells[0]?.getBoundingClientRect().height ?? 0;
|
|
1063
|
+
if (!height) {
|
|
1064
|
+
const depth = SniceCalendar.DEFAULT_EVENT_LANES;
|
|
1065
|
+
return { fit: depth, withMore: depth, height: 0, rem };
|
|
1066
|
+
}
|
|
1067
|
+
if (this.cellSizing === 'stretch' && !this.rowCapped
|
|
1068
|
+
&& height <= SniceCalendar.STRETCH_FLOOR_REM * rem + 1) {
|
|
1069
|
+
return { fit: Infinity, withMore: Infinity, height, rem };
|
|
1070
|
+
}
|
|
1071
|
+
const lanesIn = (reserve) => {
|
|
1072
|
+
const budgeted = Math.floor((height / rem - SniceCalendar.LANE_STACK_TOP_REM - reserve)
|
|
1073
|
+
/ SniceCalendar.LANE_HEIGHT_REM);
|
|
1074
|
+
if (budgeted >= 1)
|
|
1075
|
+
return budgeted;
|
|
1076
|
+
// Below the budgeted floor a row that can still grow always draws one
|
|
1077
|
+
// lane — the reservation at the end of renderEventStripes buys it the
|
|
1078
|
+
// height. A capped row has no such recourse, so the lane is drawn only
|
|
1079
|
+
// when it already fits; otherwise the day collapses entirely into its
|
|
1080
|
+
// chip rather than painting a stripe its cell will clip.
|
|
1081
|
+
if (!this.rowCapped)
|
|
1082
|
+
return 1;
|
|
1083
|
+
const needed = SniceCalendar.LANE_MIN_FIT_REM
|
|
1084
|
+
+ (reserve > 0 ? SniceCalendar.MORE_CHIP_FIT_REM : 0);
|
|
1085
|
+
return height / rem >= needed ? 1 : 0;
|
|
1086
|
+
};
|
|
1087
|
+
return {
|
|
1088
|
+
fit: lanesIn(0),
|
|
1089
|
+
withMore: lanesIn(SniceCalendar.MORE_CHIP_REM),
|
|
1090
|
+
height,
|
|
1091
|
+
rem,
|
|
1092
|
+
};
|
|
1093
|
+
}
|
|
1094
|
+
/**
|
|
1095
|
+
* Fits the six week rows inside a host that constrains the calendar's
|
|
1096
|
+
* height.
|
|
1097
|
+
*
|
|
1098
|
+
* The square baseline sizes a week row from the *column width*
|
|
1099
|
+
* (`100cqw / 7`), which says nothing about how much height the host has
|
|
1100
|
+
* given the grid. A host that hands down a definite height — the components
|
|
1101
|
+
* page's `aspect-ratio: 1` card is the reported case — therefore gets a grid
|
|
1102
|
+
* whose min-content height exceeds its box: the grid overflows, and whatever
|
|
1103
|
+
* clips it (that card's `overflow: hidden`) takes the bottom weeks of the
|
|
1104
|
+
* month with it.
|
|
1105
|
+
*
|
|
1106
|
+
* The room the grid has and the room it wants are both measurable, so the
|
|
1107
|
+
* fix is to compare them and publish the per-row ceiling when they disagree.
|
|
1108
|
+
* With no constraint the container's height IS its content height, the two
|
|
1109
|
+
* agree, and nothing is published — square cells and the growable lane
|
|
1110
|
+
* reservation are untouched. Measured with the cap cleared, so it never
|
|
1111
|
+
* feeds back on itself.
|
|
1112
|
+
*
|
|
1113
|
+
* Month view only. The cap divides the room into WEEK_ROWS equal shares and
|
|
1114
|
+
* lands as a definite `grid-template-rows` track; the week and day views
|
|
1115
|
+
* carry their own taller `min-height` at higher specificity, so a definite
|
|
1116
|
+
* track there would leave every cell overflowing its own row and painting
|
|
1117
|
+
* over the next one. They keep the pre-cap behaviour — the var stays unset,
|
|
1118
|
+
* the tracks stay `auto`.
|
|
1119
|
+
*/
|
|
1120
|
+
syncRowCap() {
|
|
1121
|
+
this.grid.style.removeProperty('--calendar-row-cap');
|
|
1122
|
+
this.rowCapped = false;
|
|
1123
|
+
if (this.view !== 'month')
|
|
1124
|
+
return;
|
|
1125
|
+
// The host's own content box, not just the container's: `.calendar`'s
|
|
1126
|
+
// `height: 100%` resolves to auto against a host sized by `max-height`,
|
|
1127
|
+
// so the container reports the height it WANTED and only the host box is
|
|
1128
|
+
// actually clamped. Whichever is smaller is the room there really is.
|
|
1129
|
+
const hostStyle = getComputedStyle(this);
|
|
1130
|
+
const hostRoom = this.clientHeight
|
|
1131
|
+
- parseFloat(hostStyle.paddingTop) - parseFloat(hostStyle.paddingBottom);
|
|
1132
|
+
const room = Math.min(this.container.clientHeight, hostRoom)
|
|
1133
|
+
- this.header.getBoundingClientRect().height;
|
|
1134
|
+
const wanted = this.grid.getBoundingClientRect().height;
|
|
1135
|
+
// No layout to measure (headless, detached, display:none) — or the rows
|
|
1136
|
+
// already fit, which is every unconstrained calendar.
|
|
1137
|
+
if (!(room > 0) || !(wanted > 0) || wanted <= room + 0.5)
|
|
1138
|
+
return;
|
|
1139
|
+
const weekdayHeight = this.grid.querySelector('.calendar__weekday')?.getBoundingClientRect().height ?? 0;
|
|
1140
|
+
// A cell cannot be shorter than its own padding and rules, so a cap below
|
|
1141
|
+
// that floor buys no height — it only detaches the rows from their tracks
|
|
1142
|
+
// and stacks each week on top of the next. Below the floor the calendar
|
|
1143
|
+
// has compressed as far as it physically can: it overflows a host that
|
|
1144
|
+
// short, the way it always did, rather than rendering weeks over weeks.
|
|
1145
|
+
const cell = this.dayCells[0];
|
|
1146
|
+
const cellStyle = cell ? getComputedStyle(cell) : null;
|
|
1147
|
+
const cellFloor = cellStyle
|
|
1148
|
+
? parseFloat(cellStyle.paddingTop) + parseFloat(cellStyle.paddingBottom)
|
|
1149
|
+
+ parseFloat(cellStyle.borderTopWidth)
|
|
1150
|
+
+ parseFloat(cellStyle.borderBottomWidth)
|
|
1151
|
+
: 0;
|
|
1152
|
+
const cap = Math.max((room - weekdayHeight) / SniceCalendar.WEEK_ROWS, cellFloor);
|
|
1153
|
+
if (!(cap > 0))
|
|
1154
|
+
return;
|
|
1155
|
+
this.rowCapped = true;
|
|
1156
|
+
this.grid.style.setProperty('--calendar-row-cap', `${cap}px`);
|
|
1157
|
+
}
|
|
1158
|
+
/** Week rows in a month grid. */
|
|
1159
|
+
static { this.WEEK_ROWS = 6; }
|
|
744
1160
|
/**
|
|
745
1161
|
* Render events as continuous stripes: one bar per (event × week row),
|
|
746
1162
|
* spanning the event's days in that week and chopped at week boundaries
|
|
747
1163
|
* with continues-left/right styling. Overlapping events stack into lanes
|
|
748
1164
|
* per week — earlier start first, longer event first on ties — like
|
|
749
|
-
* professional calendars.
|
|
1165
|
+
* professional calendars. How many of those lanes are drawn is the week's
|
|
1166
|
+
* share of the day cell's height (see laneBudget); the rest collapse into
|
|
1167
|
+
* the day's "+N more" chip.
|
|
750
1168
|
*/
|
|
751
1169
|
renderEventStripes(days) {
|
|
752
1170
|
this.closeEventPopover({ returnFocus: false }); // anchors are re-created
|
|
@@ -756,6 +1174,9 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
756
1174
|
cell.style.removeProperty('--calendar-week-lanes');
|
|
757
1175
|
cell.style.removeProperty('--calendar-week-more');
|
|
758
1176
|
});
|
|
1177
|
+
// Before anything is measured and regardless of whether this month has
|
|
1178
|
+
// events: an empty calendar in a short host overflows too.
|
|
1179
|
+
this.syncRowCap();
|
|
759
1180
|
if (!this.events || this.events.length === 0)
|
|
760
1181
|
return;
|
|
761
1182
|
// Local-midnight timestamps for the visible grid; events normalize to the
|
|
@@ -788,14 +1209,28 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
788
1209
|
});
|
|
789
1210
|
});
|
|
790
1211
|
resolved.sort((a, b) => a.startTime - b.startTime || b.duration - a.duration || a.order - b.order);
|
|
791
|
-
|
|
1212
|
+
// The events each day dropped, in the order they stack — the chip reports
|
|
1213
|
+
// the count, and its built-in panel lists them.
|
|
1214
|
+
const hiddenPerDay = Array.from({ length: dayTimes.length }, () => []);
|
|
792
1215
|
const weekCount = Math.floor(dayTimes.length / 7);
|
|
793
1216
|
const weekLaneCounts = new Array(weekCount).fill(0);
|
|
1217
|
+
// Measured before a single bar or reservation goes back in, so the budget
|
|
1218
|
+
// reflects the room the row has of its own.
|
|
1219
|
+
const budget = this.laneBudget();
|
|
1220
|
+
// Segment width comes from the same measured cell the lane budget uses, so
|
|
1221
|
+
// the avatar decision follows the calendar's real box and is re-taken by
|
|
1222
|
+
// the resize observer. No layout to measure → nothing is dropped.
|
|
1223
|
+
const cellWidth = this.dayCells[0]?.getBoundingClientRect().width ?? 0;
|
|
1224
|
+
const avatarMinWidth = SniceCalendar.AVATAR_MIN_SEGMENT_REM * budget.rem;
|
|
794
1225
|
for (let week = 0; week < weekCount; week++) {
|
|
795
1226
|
const weekStart = week * 7;
|
|
796
1227
|
const weekEnd = weekStart + 6;
|
|
797
1228
|
// lanes[lane] holds the occupied [startCol, endCol] ranges in this week.
|
|
798
1229
|
const lanes = [];
|
|
1230
|
+
const placed = [];
|
|
1231
|
+
let stackDepth = 0;
|
|
1232
|
+
// Lane assignment first: how deep this week stacks decides whether the
|
|
1233
|
+
// "+N more" chip is needed at all, and the chip costs a strip of height.
|
|
799
1234
|
for (const item of resolved) {
|
|
800
1235
|
if (item.endIdx < weekStart || item.startIdx > weekEnd)
|
|
801
1236
|
continue;
|
|
@@ -807,22 +1242,35 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
807
1242
|
while (lanes[lane]?.some(([s, e]) => startCol <= e && endCol >= s))
|
|
808
1243
|
lane++;
|
|
809
1244
|
(lanes[lane] ??= []).push([startCol, endCol]);
|
|
810
|
-
|
|
811
|
-
|
|
1245
|
+
placed.push({ item, lane, segStart, segEnd });
|
|
1246
|
+
stackDepth = Math.max(stackDepth, lane + 1);
|
|
1247
|
+
}
|
|
1248
|
+
const visibleLanes = stackDepth <= budget.fit ? stackDepth : budget.withMore;
|
|
1249
|
+
weekLaneCounts[week] = Math.min(stackDepth, visibleLanes);
|
|
1250
|
+
for (const { item, lane, segStart, segEnd } of placed) {
|
|
1251
|
+
if (lane >= visibleLanes) {
|
|
812
1252
|
for (let i = segStart; i <= segEnd; i++)
|
|
813
|
-
hiddenPerDay[i]
|
|
1253
|
+
hiddenPerDay[i].push(item.event);
|
|
814
1254
|
continue;
|
|
815
1255
|
}
|
|
1256
|
+
const startCol = segStart - weekStart;
|
|
1257
|
+
const endCol = segEnd - weekStart;
|
|
816
1258
|
const continuesLeft = segStart > item.startIdx
|
|
817
1259
|
|| (segStart === item.startIdx && item.startsBeforeGrid);
|
|
818
1260
|
const continuesRight = segEnd < item.endIdx
|
|
819
1261
|
|| (segEnd === item.endIdx && item.endsAfterGrid);
|
|
1262
|
+
// A segment too narrow for an avatar plus a legible title runs
|
|
1263
|
+
// compact: title only, tighter inline padding.
|
|
1264
|
+
const compact = cellWidth > 0
|
|
1265
|
+
&& cellWidth * (endCol - startCol + 1) < avatarMinWidth;
|
|
820
1266
|
const bar = document.createElement('div');
|
|
821
1267
|
bar.className = 'calendar__event-bar';
|
|
822
1268
|
if (continuesLeft)
|
|
823
1269
|
bar.classList.add('calendar__event-bar--continues-left');
|
|
824
1270
|
if (continuesRight)
|
|
825
1271
|
bar.classList.add('calendar__event-bar--continues-right');
|
|
1272
|
+
if (compact)
|
|
1273
|
+
bar.classList.add('calendar__event-bar--compact');
|
|
826
1274
|
// A custom className rides along on both the class list and the part
|
|
827
1275
|
// attribute, so events are styleable from outside via
|
|
828
1276
|
// ::part(<className>).
|
|
@@ -834,11 +1282,12 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
834
1282
|
bar.setAttribute('data-event-id', String(item.event.id));
|
|
835
1283
|
bar.setAttribute('data-lane', String(lane));
|
|
836
1284
|
bar.style.gridRow = String(week + 2); // row 1 is the weekday header
|
|
837
|
-
bar.style.gridColumn =
|
|
1285
|
+
bar.style.gridColumn =
|
|
1286
|
+
`${startCol + 1 + this.columnOffset} / ${endCol + 2 + this.columnOffset}`;
|
|
838
1287
|
bar.style.setProperty('--calendar-event-lane', String(lane));
|
|
839
1288
|
if (item.event.color)
|
|
840
1289
|
bar.style.background = item.event.color;
|
|
841
|
-
if (item.event.avatar) {
|
|
1290
|
+
if (item.event.avatar && !compact) {
|
|
842
1291
|
const spec = typeof item.event.avatar === 'string'
|
|
843
1292
|
? { src: item.event.avatar }
|
|
844
1293
|
: item.event.avatar;
|
|
@@ -897,7 +1346,8 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
897
1346
|
this.grid.appendChild(bar);
|
|
898
1347
|
}
|
|
899
1348
|
}
|
|
900
|
-
hiddenPerDay.forEach((
|
|
1349
|
+
hiddenPerDay.forEach((hidden, i) => {
|
|
1350
|
+
const count = hidden.length;
|
|
901
1351
|
if (count === 0)
|
|
902
1352
|
return;
|
|
903
1353
|
const cell = this.dayCells[i];
|
|
@@ -908,35 +1358,49 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
908
1358
|
more.className = 'calendar__more';
|
|
909
1359
|
more.setAttribute('part', 'more-chip');
|
|
910
1360
|
more.textContent = `+${count} more`;
|
|
911
|
-
// The chip is its own control: it reports its day and hidden count,
|
|
912
|
-
//
|
|
1361
|
+
// The chip is its own control: it reports its day and hidden count,
|
|
1362
|
+
// opens the day panel unless the app cancels it, and its clicks never
|
|
1363
|
+
// fall through to the day cell's selection handler.
|
|
913
1364
|
more.setAttribute('role', 'button');
|
|
914
1365
|
more.setAttribute('tabindex', '0');
|
|
1366
|
+
more.setAttribute('aria-haspopup', 'dialog');
|
|
1367
|
+
more.setAttribute('aria-expanded', 'false');
|
|
915
1368
|
more.setAttribute('aria-label', `${count} more event${count === 1 ? '' : 's'} on ${date.toLocaleDateString(this.locale, { dateStyle: 'full' })}`);
|
|
916
|
-
more.onclick = (e) => this.handleMoreClick(date,
|
|
1369
|
+
more.onclick = (e) => this.handleMoreClick(date, more, hidden, e);
|
|
917
1370
|
more.onkeydown = (e) => {
|
|
918
1371
|
if (e.key !== 'Enter' && e.key !== ' ')
|
|
919
1372
|
return;
|
|
920
1373
|
e.preventDefault();
|
|
921
|
-
this.handleMoreClick(date,
|
|
1374
|
+
this.handleMoreClick(date, more, hidden, e);
|
|
922
1375
|
};
|
|
923
1376
|
cell.appendChild(more);
|
|
924
1377
|
});
|
|
925
1378
|
// Reserve row height for the lane stack (and the "+N more" chip) so
|
|
926
1379
|
// stripes never spill past their week row — every cell in a week shares
|
|
927
1380
|
// the reservation, since the grid row is as tall as its tallest cell.
|
|
1381
|
+
// The reservation is only a floor: when the row already has the room it is
|
|
1382
|
+
// left off, so the busy week's row stays level with the rest. That covers
|
|
1383
|
+
// every cell tall enough for the stack it shows; the floor still bites
|
|
1384
|
+
// below 3.5rem (the one lane always drawn) or 4.5rem once the chip claims
|
|
1385
|
+
// its strip — square cells are that short on calendars under ~500px wide.
|
|
928
1386
|
for (let week = 0; week < weekCount; week++) {
|
|
929
1387
|
if (weekLaneCounts[week] === 0)
|
|
930
1388
|
continue;
|
|
931
1389
|
const weekHasMore = hiddenPerDay
|
|
932
|
-
.slice(week * 7, week * 7 + 7).some(
|
|
1390
|
+
.slice(week * 7, week * 7 + 7).some(hidden => hidden.length > 0);
|
|
1391
|
+
const needed = (SniceCalendar.LANE_STACK_TOP_REM
|
|
1392
|
+
+ weekLaneCounts[week] * SniceCalendar.LANE_HEIGHT_REM
|
|
1393
|
+
+ (weekHasMore ? SniceCalendar.MORE_CHIP_REM : 0)) * budget.rem;
|
|
1394
|
+
if (budget.height && needed <= budget.height + 0.5)
|
|
1395
|
+
continue;
|
|
933
1396
|
for (let i = week * 7; i < week * 7 + 7; i++) {
|
|
934
1397
|
const cell = this.dayCells[i];
|
|
935
1398
|
if (!cell)
|
|
936
1399
|
continue;
|
|
937
1400
|
cell.style.setProperty('--calendar-week-lanes', String(weekLaneCounts[week]));
|
|
938
|
-
if (weekHasMore)
|
|
939
|
-
cell.style.setProperty('--calendar-week-more',
|
|
1401
|
+
if (weekHasMore) {
|
|
1402
|
+
cell.style.setProperty('--calendar-week-more', `${SniceCalendar.MORE_CHIP_REM}rem`);
|
|
1403
|
+
}
|
|
940
1404
|
}
|
|
941
1405
|
}
|
|
942
1406
|
}
|
|
@@ -1010,7 +1474,13 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
1010
1474
|
return this.isSameDay(date, new Date());
|
|
1011
1475
|
}
|
|
1012
1476
|
isSelected(date) {
|
|
1477
|
+
// No value means no selection at all — and an unparseable one selects
|
|
1478
|
+
// nothing rather than throwing out of the render.
|
|
1479
|
+
if (!this.value)
|
|
1480
|
+
return false;
|
|
1013
1481
|
const valueDate = typeof this.value === 'string' ? new Date(this.value) : this.value;
|
|
1482
|
+
if (!(valueDate instanceof Date) || isNaN(valueDate.getTime()))
|
|
1483
|
+
return false;
|
|
1014
1484
|
return this.isSameDay(date, valueDate);
|
|
1015
1485
|
}
|
|
1016
1486
|
isDisabled(date) {
|
|
@@ -1043,9 +1513,13 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
1043
1513
|
e.stopPropagation();
|
|
1044
1514
|
this.dispatchEventClick(event);
|
|
1045
1515
|
}
|
|
1046
|
-
handleMoreClick(date,
|
|
1516
|
+
handleMoreClick(date, chip, hidden, e) {
|
|
1047
1517
|
e.stopPropagation();
|
|
1048
|
-
|
|
1518
|
+
// The app gets first refusal: preventDefault() means it is opening its own
|
|
1519
|
+
// day view and the built-in panel must stay out of the way.
|
|
1520
|
+
if (!this.dispatchMoreClick(date, hidden.length))
|
|
1521
|
+
return;
|
|
1522
|
+
this.openMorePanel(chip, date, hidden);
|
|
1049
1523
|
}
|
|
1050
1524
|
getMonthDays() {
|
|
1051
1525
|
const year = this.displayDate.getFullYear();
|
|
@@ -1078,6 +1552,20 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
1078
1552
|
this.updateView();
|
|
1079
1553
|
}
|
|
1080
1554
|
}
|
|
1555
|
+
/**
|
|
1556
|
+
* The lane budget comes from the cell's height, and that height follows the
|
|
1557
|
+
* calendar's own box — column width in square mode, the host's height when
|
|
1558
|
+
* it has one. Re-stripe when the box actually changes.
|
|
1559
|
+
*/
|
|
1560
|
+
handleCalendarResize(entry) {
|
|
1561
|
+
if (!this.grid)
|
|
1562
|
+
return;
|
|
1563
|
+
const box = `${Math.round(entry.contentRect.width)}x${Math.round(entry.contentRect.height)}`;
|
|
1564
|
+
if (box === this.laidOutFor)
|
|
1565
|
+
return;
|
|
1566
|
+
this.laidOutFor = box;
|
|
1567
|
+
this.updateView();
|
|
1568
|
+
}
|
|
1081
1569
|
handleWeekdayInputsChange() {
|
|
1082
1570
|
if (!this.grid)
|
|
1083
1571
|
return;
|
|
@@ -1085,14 +1573,19 @@ var SniceCalendar = (function (exports, snice) {
|
|
|
1085
1573
|
const existing = this.grid.querySelectorAll('.calendar__weekday');
|
|
1086
1574
|
existing.forEach(el => el.remove());
|
|
1087
1575
|
const weekdays = this.getWeekdays();
|
|
1576
|
+
// Anchor on the first day cell rather than a child index: the week-number
|
|
1577
|
+
// column adds siblings ahead of it, so a positional index would interleave
|
|
1578
|
+
// the strip with the grid's other children.
|
|
1579
|
+
const firstRow = this.weekNumberCells[0]?.isConnected
|
|
1580
|
+
? this.weekNumberCells[0] : this.dayCells[0];
|
|
1581
|
+
const anchor = firstRow ?? null;
|
|
1088
1582
|
weekdays.forEach((day, i) => {
|
|
1089
1583
|
const weekdayEl = document.createElement('div');
|
|
1090
1584
|
weekdayEl.className = 'calendar__weekday';
|
|
1091
1585
|
weekdayEl.textContent = day;
|
|
1092
1586
|
weekdayEl.style.gridRow = '1';
|
|
1093
|
-
weekdayEl.style.gridColumn = String(i + 1);
|
|
1094
|
-
|
|
1095
|
-
this.grid.insertBefore(weekdayEl, this.grid.children[i] || null);
|
|
1587
|
+
weekdayEl.style.gridColumn = String(i + 1 + this.columnOffset);
|
|
1588
|
+
this.grid.insertBefore(weekdayEl, anchor);
|
|
1096
1589
|
});
|
|
1097
1590
|
this.updateView();
|
|
1098
1591
|
}
|