{% props year: i64, month: i64, selected: i64 = 0, range_start: i64 = 0, range_end: i64 = 0, name: String = "", nav_path: String = "" %}
{#- Days of this month: `selected`, or `range_start`..`range_end`. With `name`, days submit their ISO date under it; with `nav_path`, the arrows link to `?month=YYYY-MM`. -#}
{%- let (caption, prev_month, next_month, weeks) = {
use ::glacier::chrono::{Datelike, Days, Months, NaiveDate};
let first = NaiveDate::from_ymd_opt(year as i32, month as u32, 1).expect("a valid year and month");
let next = first + Months::new(1);
let start = first - Days::new(first.weekday().num_days_from_monday() as u64);
let count = ((next - start).num_days() + 6) / 7 * 7;
let today = ::glacier::time::today();
let days: Vec<_> = (0..count as u64).map(|n| {
let date = start + Days::new(n);
let inside = date.month() as i64 == month;
let day = date.day() as i64;
let range = if !inside || range_start == 0 { "" } else if day == range_start { "start" } else if day == range_end { "end" } else if day > range_start && day < range_end { "middle" } else { "" };
(date.format("%-d %B %Y").to_string(), date.format("%Y-%m-%d").to_string(), day, !inside, date == today, inside && day == selected, range)
}).collect();
let weeks: Vec<Vec<_>> = days.chunks(7).map(|week| week.to_vec()).collect();
(first.format("%B %Y").to_string(), (first - Months::new(1)).format("%Y-%m").to_string(), next.format("%Y-%m").to_string(), weeks)
} %}
<div class="ui-calendar" data-ui="calendar" data-mode="{% if range_start > 0 %}range{% else %}single{% end %}" data-week-start="1">
<div class="ui-calendar-head">
{%- if nav_path.is_empty() %}
<button class="ui-calendar-nav" type="button" data-dir="prev" aria-label="Previous month"><svg class="ui-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="m15 18-6-6 6-6"/></svg></button>
{%- else %}
<a class="ui-calendar-nav" data-dir="prev" aria-label="Previous month" href="{{ nav_path }}?month={{ prev_month }}"><svg class="ui-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="m15 18-6-6 6-6"/></svg></a>
{%- end %}
<div class="ui-calendar-caption" aria-live="polite">{{ caption }}</div>
{%- if nav_path.is_empty() %}
<button class="ui-calendar-nav" type="button" data-dir="next" aria-label="Next month"><svg class="ui-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="m9 18 6-6-6-6"/></svg></button>
{%- else %}
<a class="ui-calendar-nav" data-dir="next" aria-label="Next month" href="{{ nav_path }}?month={{ next_month }}"><svg class="ui-icon" viewBox="0 0 24 24" aria-hidden="true"><path d="m9 18 6-6-6-6"/></svg></a>
{%- end %}
</div>
<table role="grid" aria-label="{{ caption }}">
<thead><tr><th scope="col" abbr="Monday">Mo</th><th scope="col" abbr="Tuesday">Tu</th><th scope="col" abbr="Wednesday">We</th><th scope="col" abbr="Thursday">Th</th><th scope="col" abbr="Friday">Fr</th><th scope="col" abbr="Saturday">Sa</th><th scope="col" abbr="Sunday">Su</th></tr></thead>
<tbody>
{%- for week in weeks.iter() %}
<tr>
{%- for (label, iso, day, outside, today, chosen, range) in week.iter() %}
<td{% if !range.is_empty() %} data-range="{{ range }}"{% end %}><button class="ui-day"{% if name.is_empty() %} type="button"{% else %} type="submit" name="{{ name }}" value="{{ iso }}"{% end %} aria-label="{{ label }}"{% if *outside %} data-outside{% end %}{% if *today %} data-today{% end %}{% if *chosen %} aria-selected="true"{% end %}{% if *range == "start" || *range == "end" %} data-range="{{ range }}"{% end %}>{{ day }}</button></td>
{%- end %}
</tr>
{%- end %}
</tbody>
</table>
</div>