Skip to content

Commit a0534fa

Browse files
committed
add: Time component
1 parent a814dea commit a0534fa

File tree

3 files changed

+64
-23
lines changed

3 files changed

+64
-23
lines changed

src/components/common/README.md

+22-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ Extends the default `<a>` HTML element to add custom styles. Should be used on a
8080
| `url` | `string` | The url to link to |
8181
| `newTab` | `boolean?` | Whether the linked page should be opened in another tab. Defaults to `true`. |
8282
| `refer` | `boolean?` | Whether to [refer](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) when navigating away. Defaults to `false`. |
83-
| `icon` | `boolean?` | Whether or not to display the "external" icon next to the link. Defaults to `true`. |
83+
| `icon` | `boolean?` | Whether or not to display the "external" icon next to the link. Defaults to `true`. |
8484
| `class` | `string?` | Allows you to pass in a class to be applied to the link. |
8585

8686
### Slots
@@ -212,6 +212,27 @@ A group of tabs where the content of only one tab is visible at a time.
212212
</Tabs>
213213
```
214214

215+
## [Time](./Time.astro)
216+
217+
An extension of the [`<time>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/time) element that can display a datetime in the user's local timezone or as a relative time.
218+
219+
### Arguments
220+
221+
| Name | Type | Description |
222+
| -------- | ------- | ------------------------------------------------------------ |
223+
| datetime | string | The datetime stamp, e.g. `2024-01-14T01:50:27-04:00`. |
224+
| relative | boolean | Whether to display the time relatively, e.g. `2 months ago`. |
225+
226+
### Slots
227+
228+
`default` - Default time to display before being overridden on page load
229+
230+
### Examples
231+
232+
```HTML
233+
<Time datetime="2024-04-05T01:50:27-04:00" relative>Some time ago</Time>
234+
```
235+
215236
## [Tooltip](./Tooltip.astro)
216237

217238
A [tippy.js](https://atomiks.github.io/tippyjs/) tooltip that can be placed around other elements.

src/components/common/Time.astro

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
---
2+
const { datetime, relative } = Astro.props;
3+
4+
export interface Props {
5+
datetime: string;
6+
relative?: boolean;
7+
}
8+
---
9+
10+
<time datetime={datetime} data-relative={relative ? "true" : null}
11+
><slot /></time
12+
>
13+
14+
<script>
15+
import dayjs from "dayjs";
16+
import relativeTime from "dayjs/plugin/relativeTime";
17+
import localizedFormat from "dayjs/plugin/localizedFormat";
18+
19+
dayjs.extend(relativeTime);
20+
dayjs.extend(localizedFormat);
21+
22+
const timeElements = document.querySelectorAll("time");
23+
24+
for (const element of timeElements) {
25+
const dateTime = element.getAttribute("datetime");
26+
27+
if (!dateTime) {
28+
console.warn(element, "is missing datetime attribute");
29+
continue;
30+
}
31+
32+
const date = dayjs(dateTime);
33+
if (element.getAttribute("data-relative") === "true") {
34+
element.innerText = date.fromNow();
35+
} else {
36+
element.innerText = date.format("lll");
37+
}
38+
}
39+
</script>

src/pages/wiki/[...slug].astro

+3-22
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import H5 from "~/components/wiki/headings/H5.astro";
1313
import H6 from "~/components/wiki/headings/H6.astro";
1414
import dayjs from "~/services/time";
1515
import Tooltip from "~/components/common/Tooltip.astro";
16+
import Time from "~/components/common/Time.astro";
1617
1718
export const getStaticPaths = async () => {
1819
const articles = await getCollection("wiki");
@@ -53,30 +54,10 @@ const modifiedTime = remarkPluginFrontmatter.lastModified
5354
<p>
5455
Last Modified:
5556
<Tooltip content={modifiedTime}>
56-
<time datetime={remarkPluginFrontmatter.lastModified} data-localize
57-
>{modifiedTime}</time
57+
<Time datetime={remarkPluginFrontmatter.lastModified}
58+
>{modifiedTime}</Time
5859
>
5960
</Tooltip>
6061
</p>
6162
</div>
6263
</Layout>
63-
64-
<script>
65-
const times = document.querySelectorAll("time[data-localize]");
66-
67-
const formatter = new Intl.DateTimeFormat(undefined, {
68-
hour: "numeric",
69-
minute: "2-digit",
70-
day: "numeric",
71-
month: "long",
72-
year: "numeric",
73-
second: "2-digit",
74-
timeZoneName: "short",
75-
});
76-
77-
times.forEach((el) => {
78-
const timestamp = el.getAttribute("datetime");
79-
if (!timestamp) return;
80-
el.textContent = formatter.format(new Date(timestamp));
81-
});
82-
</script>

0 commit comments

Comments
 (0)