diff options
Diffstat (limited to 'src/components/DateSelector.astro')
-rw-r--r-- | src/components/DateSelector.astro | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/src/components/DateSelector.astro b/src/components/DateSelector.astro new file mode 100644 index 0000000..324bc41 --- /dev/null +++ b/src/components/DateSelector.astro @@ -0,0 +1,141 @@ +--- +interface Props { + date: Date; + years: number[]; + months: number[]; + days?: number[]; +} + +const { date, years, months, days } = Astro.props; + +const y = date.getFullYear(); +const m = date.getMonth() + 1; +const d = date.getDate(); +let yI = 0; +let mI = 0; +let dI = 0; + +const list = new Intl.ListFormat("pt-PT", { type: "unit", style: "narrow" }); + +const pad = (n: number) => String(n).padStart(2, "0"); +--- +<nav> + <span role="list"> + Anos:{" "} + { + list.formatToParts(years.map((y) => + new Intl.DateTimeFormat("pt-PT", { year: "2-digit" }).format( + new Date( + Date.UTC( + y, + 0, + 1, + date.getTimezoneOffset() / 60, + date.getTimezoneOffset() % 60, + ), + ), + ) + )).map(({ type, value }: { type: string; value: string }) => { + switch (type) { + case "element": { + const year = years[yI++]; + return ( + <span role="listitem"><a + class:list={[{ active: year === y }]} + href={`/blog/${year}`} + >{value}</a></span> + ); + } + case "literal": { + return ( + <span>{value}</span> + ); + } + } + }) + } + </span> + <br /> + <span role="list"> + Meses:{" "} + { + list.formatToParts(months.map((m) => + new Intl.DateTimeFormat("pt-PT", { month: "short" }).format( + new Date( + Date.UTC( + y, + m - 1, + 1, + date.getTimezoneOffset() / 60, + date.getTimezoneOffset() % 60, + ), + ), + ) + )).map(({ type, value }: { type: string; value: string }) => { + switch (type) { + case "element": { + const month = months[mI++]; + return ( + <span role="listitem"><a + class:list={[{ active: month === m }]} + href={`/blog/${y}/${pad(month)}`} + >{value}</a></span> + ); + } + case "literal": { + return ( + <span>{value}</span> + ); + } + } + }) + } + </span> + { + days && + ( + <><br /><span role="list"> + Dias:{" "} + { + list.formatToParts(days.map((d) => { + return new Intl.DateTimeFormat("pt-PT", { day: "numeric" }) + .format( + new Date( + Date.UTC( + y, + m - 1, + d, + date.getTimezoneOffset() / 60, + date.getTimezoneOffset() % 60, + ), + ), + ); + })).map(({ type, value }: { type: string; value: string }) => { + switch (type) { + case "element": { + const day = days[dI++]; + return ( + <span role="listitem"><a + class:list={[{ active: day === d }]} + href={`/blog/${y}/${pad(m)}/${pad(d)}`} + >{value}</a></span> + ); + } + case "literal": { + return ( + <span>{value}</span> + ); + } + } + }) + } + </span></> + ) + } +</nav> + +<style> + a.active { + font-weight: bolder; + } +</style> |