CwCalendarScroll

A vertically scrollable date list with a large content region and an optional actions rail. Use showAllDates when blank days matter, or turn it off to show only populated dates.

Scrollable day agenda

The list owns its own vertical scroll with overscroll-behavior, so wheel and touch input stay inside the control instead of pulling the page around.

2026-03-01 Sunday • March 1, 2026
Data available
Propagation zone inspection
06:00 - 08:30

Verify mist cadence, record tray temperatures, and confirm the overnight alarm cleared.

  • Confirm misting intervals
  • Spot-check tray temperatures
2026-03-02 Monday • March 2, 2026
Data available
Irrigation review
09:00 - 11:00

Compare yesterday’s EC swing against the fertigation recipe before the afternoon feed.

  • Review EC drift
  • Approve next feed recipe
  • Flush line 3
2026-03-03 Tuesday • March 3, 2026
No data
Open day

No scheduled work for this date.

2026-03-04 Wednesday • March 4, 2026
Data available
Labor planning
13:00 - 15:00

Finalize tomorrow’s canopy work and prep the west house handoff.

  • Assign pruning crew
  • Post west-house notes
2026-03-05 Thursday • March 5, 2026
No data
Open day

No scheduled work for this date.

2026-03-06 Friday • March 6, 2026
No data
Open day

No scheduled work for this date.

2026-03-07 Saturday • March 7, 2026
Data available
Nutrient tank reset
07:30 - 09:00

Drain tank B, verify fresh stock, then sign off the mixing checklist.

  • Drain tank B
  • Verify stock concentrate
2026-03-08 Sunday • March 8, 2026
No data
Open day

No scheduled work for this date.

2026-03-09 Monday • March 9, 2026
Data available
Harvest prep
10:30 - 12:00

Stage carts, re-check cooler capacity, and confirm the outbound pickup window.

  • Stage harvest carts
  • Confirm cooler space

Examples

Full range with empty days Copy code
<script lang="ts">
	import { CwCalendarScroll } from '@cropwatchdevelopment/cwui';
	import type { CwCalendarScrollItem } from '@cropwatchdevelopment/cwui';

	interface DayPlan extends CwCalendarScrollItem {
		title: string;
		note: string;
	}

	const plans: DayPlan[] = [
		{ date: '2026-03-01', title: 'Propagation zone inspection', note: 'Check tray temperatures.' },
		{ date: '2026-03-04', title: 'Labor planning', note: 'Finalize tomorrow\'s canopy work.' }
	];
</script>

<CwCalendarScroll
	items={plans}
	startDate={new Date(2026, 2, 1)}
	endDate={new Date(2026, 2, 9)}
	showAllDates={true}
>
	{#snippet content(item)}
		{#if item}
			<h4>{item.title}</h4>
			<p>{item.note}</p>
		{:else}
			<p>No work scheduled.</p>
		{/if}
	{/snippet}

	{#snippet actions(item)}
		{#if item}
			<button type="button">Open day</button>
		{/if}
	{/snippet}
</CwCalendarScroll>
Only populated dates Copy code
<CwCalendarScroll
	items={plans}
	showAllDates={false}
	maxHeight="28rem"
>
	{#snippet content(item)}
		<h4>{item?.title}</h4>
		<p>{item?.note}</p>
	{/snippet}
</CwCalendarScroll>
Documentation Upgrade

Start here

CwCalendarScroll renders a vertically scrollable list of day rows. Each row keeps the date header, a large content region, and an optional actions rail while staying inside its own bounded scroll viewport.

How to think about it

  1. Pick the visibility mode first Set `showAllDates={false}` when sparse data should collapse to only populated dates, or turn it on when blank days must remain visible inside a contiguous range.
  2. Give each item a local date Prefer `YYYY-MM-DD` values in each item’s `date` field so the component can normalize rows without timezone drift.
  3. Keep rendering in snippets Pass an item array and let the page own the `content` and `actions` snippets. That keeps the list shell reusable while each screen decides what belongs in a row.

Props and callbacks

APITypeDetails
items
T[]Array of dated items that supply the row payload for each day.
showAllDates

Default: false

booleanShows all dates in the computed range when true. Otherwise only dates whose values count as present are shown.
startDate
Date | string | numberInclusive first day used when `showAllDates` is enabled.
endDate
Date | string | numberInclusive last day used when `showAllDates` is enabled.
maxHeight

Default: `min(70dvh, 40rem)`

stringCSS size for the internal scroll viewport height cap.
hasData
(item: T, key: string) => booleanOptional custom presence check for deciding whether an item should count as populated.
content
Snippet<[T | null, CwCalendarScrollMeta]>Main body content for each row. The first argument is the original item.
actions
Snippet<[T | null, CwCalendarScrollMeta]>Optional actions column or action row for each day. The first argument is the original item.

Copy-paste examples

These snippets intentionally show the full public API surface the live demo relies on.

Contiguous date range with empty days

Use this when gaps in the schedule still need to remain visible.

Contiguous date range with empty days Copy code
<CwCalendarScroll
	items={plans}
	startDate={new Date(2026, 2, 1)}
	endDate={new Date(2026, 2, 9)}
	showAllDates={true}
>
	{#snippet content(item)}
		{#if item}
			<h4>{item.title}</h4>
			<p>{item.note}</p>
		{:else}
			<p>No work scheduled.</p>
		{/if}
	{/snippet}

	{#snippet actions(item)}
		{#if item}
			<CwButton size="sm" variant="secondary">Open Day</CwButton>
		{/if}
	{/snippet}
</CwCalendarScroll>
Only dates with data

Use this mode for compact activity logs or historical day summaries.

Only dates with data Copy code
<CwCalendarScroll
	items={plans}
	showAllDates={false}
	maxHeight="28rem"
>
	{#snippet content(item)}
		<h4>{item?.title}</h4>
		<p>{item?.note}</p>
	{/snippet}
</CwCalendarScroll>