@binarynoir/vitepress-blog 0.1.1 → 0.3.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 +158 -33
- package/dist/chunk-42Z6H7IN.js +52 -0
- package/dist/chunk-42Z6H7IN.js.map +1 -0
- package/dist/{chunk-DICBXOTS.js → chunk-LYTJBMVK.js} +182 -66
- package/dist/chunk-LYTJBMVK.js.map +1 -0
- package/dist/client.cjs +140 -28
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +35 -4
- package/dist/client.d.ts +35 -4
- package/dist/client.js +136 -26
- package/dist/client.js.map +1 -1
- package/dist/index.cjs +157 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/{plugin-BjbV6nDK.d.cts → plugin-Bb4rRwO8.d.cts} +55 -2
- package/dist/{plugin-BjbV6nDK.d.ts → plugin-Bb4rRwO8.d.ts} +55 -2
- package/dist/style.css +113 -0
- package/dist/vitepress.cjs +294 -98
- package/dist/vitepress.cjs.map +1 -1
- package/dist/vitepress.d.cts +17 -7
- package/dist/vitepress.d.ts +17 -7
- package/dist/vitepress.js +75 -7
- package/dist/vitepress.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-DICBXOTS.js.map +0 -1
|
@@ -16,8 +16,21 @@ interface BlogOptions {
|
|
|
16
16
|
siteUrl?: string;
|
|
17
17
|
/** Locale for dates in bylines and cards. Default: `'en-US'`. */
|
|
18
18
|
locale?: string;
|
|
19
|
-
/** How dates are written. Default: `{ dateStyle: 'long' }
|
|
19
|
+
/** How dates are written. Default: `{ dateStyle: 'long' }`. */
|
|
20
20
|
dateFormat?: Intl.DateTimeFormatOptions;
|
|
21
|
+
/**
|
|
22
|
+
* How times are written, for dates whose frontmatter gives one
|
|
23
|
+
* (`2026-10-20 14:30`). Default: `{ hour: 'numeric', minute: '2-digit', timeZoneName: 'short' }`,
|
|
24
|
+
* as in "2:30 PM EDT".
|
|
25
|
+
*/
|
|
26
|
+
timeFormat?: Intl.DateTimeFormatOptions;
|
|
27
|
+
/**
|
|
28
|
+
* The time zone frontmatter times without an offset are in, and that every
|
|
29
|
+
* date and time is shown in: an IANA name such as `'America/New_York'`.
|
|
30
|
+
* A value with an offset (`2026-10-20T14:30:00-04:00`, `…Z`) is read as
|
|
31
|
+
* written. Default: `'UTC'`.
|
|
32
|
+
*/
|
|
33
|
+
timeZone?: string;
|
|
21
34
|
/** Reading speed for the "5 min read" estimate. `0` hides it. Default: `200`. */
|
|
22
35
|
wordsPerMinute?: number;
|
|
23
36
|
/** Add an author, date and tags line under each post's title. Default: `true`. */
|
|
@@ -68,8 +81,12 @@ interface BlogOptions {
|
|
|
68
81
|
interface BlogLabels {
|
|
69
82
|
/** Before the author names: "By Jane Doe". */
|
|
70
83
|
by: string;
|
|
84
|
+
/** Before a post's `date` in its byline: "Published October 20, 2026". */
|
|
85
|
+
published: string;
|
|
71
86
|
/** Before a post's `updated` date. */
|
|
72
87
|
updated: string;
|
|
88
|
+
/** A date and its time: "{date} at {time}". */
|
|
89
|
+
dateTime: string;
|
|
73
90
|
/** Reading time: "{n} min read". */
|
|
74
91
|
readingTime: string;
|
|
75
92
|
newer: string;
|
|
@@ -79,6 +96,16 @@ interface BlogLabels {
|
|
|
79
96
|
draft: string;
|
|
80
97
|
/** Badge on a sticky post. */
|
|
81
98
|
sticky: string;
|
|
99
|
+
/** Badge on an announcement, and the accessible name of the announcement banner. */
|
|
100
|
+
announcement: string;
|
|
101
|
+
/** Above a blog page filtered to announcements (`?announcements`). */
|
|
102
|
+
announcements: string;
|
|
103
|
+
/** When the blog page has no announcements to show. */
|
|
104
|
+
noAnnouncements: string;
|
|
105
|
+
/** Tooltip of the banner's count badge: "{n} announcements". */
|
|
106
|
+
announcementCount: string;
|
|
107
|
+
/** Accessible name of the banner's close button. */
|
|
108
|
+
dismiss: string;
|
|
82
109
|
noPosts: string;
|
|
83
110
|
/** Year heading for posts without a date, when a blog groups by year. */
|
|
84
111
|
undated: string;
|
|
@@ -138,8 +165,14 @@ interface BlogIndexConfig {
|
|
|
138
165
|
interface BlogPostData {
|
|
139
166
|
title: string;
|
|
140
167
|
summary: string;
|
|
168
|
+
/** When the post was published, from `date`. */
|
|
141
169
|
date: Date | null;
|
|
170
|
+
/** Whether `date` gave a time, not just a day. */
|
|
171
|
+
dateHasTime: boolean;
|
|
172
|
+
/** When the post was last changed, from `updated`. */
|
|
142
173
|
updated: Date | null;
|
|
174
|
+
/** Whether `updated` gave a time, not just a day. */
|
|
175
|
+
updatedHasTime: boolean;
|
|
143
176
|
/** As written: a path relative to the post, a public path (`/x.png`) or a URL. */
|
|
144
177
|
image: string;
|
|
145
178
|
imageAlt: string;
|
|
@@ -153,12 +186,32 @@ interface BlogPostData {
|
|
|
153
186
|
scope: BlogScope;
|
|
154
187
|
sticky: boolean;
|
|
155
188
|
draft: boolean;
|
|
189
|
+
/** Shown in the announcement banner above the nav bar. */
|
|
190
|
+
announcement: boolean;
|
|
191
|
+
/** The banner's text, from `announcement: "…"`. `''` uses the title. */
|
|
192
|
+
announcementText: string;
|
|
156
193
|
/** Per-post overrides of the `byline`, `cover` and `postNav` options. */
|
|
157
194
|
byline?: boolean;
|
|
158
195
|
cover?: boolean;
|
|
159
196
|
postNav?: boolean;
|
|
160
197
|
readingMinutes: number;
|
|
161
198
|
}
|
|
199
|
+
/** One announcement, as the banner shows it. */
|
|
200
|
+
interface BlogAnnouncementItem {
|
|
201
|
+
/** The post's path and date: what a dismissal remembers, so re-dating a post announces it again. */
|
|
202
|
+
id: string;
|
|
203
|
+
text: string;
|
|
204
|
+
/** The post's URL path, without the site's base. */
|
|
205
|
+
link: string;
|
|
206
|
+
}
|
|
207
|
+
/** What the announcement banner reads from VitePress's site data. */
|
|
208
|
+
interface BlogAnnouncementData {
|
|
209
|
+
/** Newest first: the banner shows the first one that hasn't been dismissed. */
|
|
210
|
+
items: BlogAnnouncementItem[];
|
|
211
|
+
/** The blog page filtered to announcements (`/blog/?announcements`), without the base, or `''` when no blog lists them. */
|
|
212
|
+
listLink: string;
|
|
213
|
+
labels: Pick<BlogLabels, 'announcement' | 'announcementCount' | 'dismiss'>;
|
|
214
|
+
}
|
|
162
215
|
|
|
163
216
|
/**
|
|
164
217
|
* A markdown-it plugin that turns pages into a blog.
|
|
@@ -187,4 +240,4 @@ interface BlogPostData {
|
|
|
187
240
|
*/
|
|
188
241
|
declare function blogMarkdown(md: MarkdownIt, options?: BlogOptions): void;
|
|
189
242
|
|
|
190
|
-
export { type
|
|
243
|
+
export { type BlogAnnouncementData as B, DEFAULT_LABELS as D, type BlogAnnouncementItem as a, type BlogAuthor as b, type BlogFeedConfig as c, type BlogIndexConfig as d, type BlogLabels as e, type BlogLayout as f, type BlogOptions as g, type BlogPostData as h, type BlogScope as i, blogMarkdown as j };
|
|
@@ -16,8 +16,21 @@ interface BlogOptions {
|
|
|
16
16
|
siteUrl?: string;
|
|
17
17
|
/** Locale for dates in bylines and cards. Default: `'en-US'`. */
|
|
18
18
|
locale?: string;
|
|
19
|
-
/** How dates are written. Default: `{ dateStyle: 'long' }
|
|
19
|
+
/** How dates are written. Default: `{ dateStyle: 'long' }`. */
|
|
20
20
|
dateFormat?: Intl.DateTimeFormatOptions;
|
|
21
|
+
/**
|
|
22
|
+
* How times are written, for dates whose frontmatter gives one
|
|
23
|
+
* (`2026-10-20 14:30`). Default: `{ hour: 'numeric', minute: '2-digit', timeZoneName: 'short' }`,
|
|
24
|
+
* as in "2:30 PM EDT".
|
|
25
|
+
*/
|
|
26
|
+
timeFormat?: Intl.DateTimeFormatOptions;
|
|
27
|
+
/**
|
|
28
|
+
* The time zone frontmatter times without an offset are in, and that every
|
|
29
|
+
* date and time is shown in: an IANA name such as `'America/New_York'`.
|
|
30
|
+
* A value with an offset (`2026-10-20T14:30:00-04:00`, `…Z`) is read as
|
|
31
|
+
* written. Default: `'UTC'`.
|
|
32
|
+
*/
|
|
33
|
+
timeZone?: string;
|
|
21
34
|
/** Reading speed for the "5 min read" estimate. `0` hides it. Default: `200`. */
|
|
22
35
|
wordsPerMinute?: number;
|
|
23
36
|
/** Add an author, date and tags line under each post's title. Default: `true`. */
|
|
@@ -68,8 +81,12 @@ interface BlogOptions {
|
|
|
68
81
|
interface BlogLabels {
|
|
69
82
|
/** Before the author names: "By Jane Doe". */
|
|
70
83
|
by: string;
|
|
84
|
+
/** Before a post's `date` in its byline: "Published October 20, 2026". */
|
|
85
|
+
published: string;
|
|
71
86
|
/** Before a post's `updated` date. */
|
|
72
87
|
updated: string;
|
|
88
|
+
/** A date and its time: "{date} at {time}". */
|
|
89
|
+
dateTime: string;
|
|
73
90
|
/** Reading time: "{n} min read". */
|
|
74
91
|
readingTime: string;
|
|
75
92
|
newer: string;
|
|
@@ -79,6 +96,16 @@ interface BlogLabels {
|
|
|
79
96
|
draft: string;
|
|
80
97
|
/** Badge on a sticky post. */
|
|
81
98
|
sticky: string;
|
|
99
|
+
/** Badge on an announcement, and the accessible name of the announcement banner. */
|
|
100
|
+
announcement: string;
|
|
101
|
+
/** Above a blog page filtered to announcements (`?announcements`). */
|
|
102
|
+
announcements: string;
|
|
103
|
+
/** When the blog page has no announcements to show. */
|
|
104
|
+
noAnnouncements: string;
|
|
105
|
+
/** Tooltip of the banner's count badge: "{n} announcements". */
|
|
106
|
+
announcementCount: string;
|
|
107
|
+
/** Accessible name of the banner's close button. */
|
|
108
|
+
dismiss: string;
|
|
82
109
|
noPosts: string;
|
|
83
110
|
/** Year heading for posts without a date, when a blog groups by year. */
|
|
84
111
|
undated: string;
|
|
@@ -138,8 +165,14 @@ interface BlogIndexConfig {
|
|
|
138
165
|
interface BlogPostData {
|
|
139
166
|
title: string;
|
|
140
167
|
summary: string;
|
|
168
|
+
/** When the post was published, from `date`. */
|
|
141
169
|
date: Date | null;
|
|
170
|
+
/** Whether `date` gave a time, not just a day. */
|
|
171
|
+
dateHasTime: boolean;
|
|
172
|
+
/** When the post was last changed, from `updated`. */
|
|
142
173
|
updated: Date | null;
|
|
174
|
+
/** Whether `updated` gave a time, not just a day. */
|
|
175
|
+
updatedHasTime: boolean;
|
|
143
176
|
/** As written: a path relative to the post, a public path (`/x.png`) or a URL. */
|
|
144
177
|
image: string;
|
|
145
178
|
imageAlt: string;
|
|
@@ -153,12 +186,32 @@ interface BlogPostData {
|
|
|
153
186
|
scope: BlogScope;
|
|
154
187
|
sticky: boolean;
|
|
155
188
|
draft: boolean;
|
|
189
|
+
/** Shown in the announcement banner above the nav bar. */
|
|
190
|
+
announcement: boolean;
|
|
191
|
+
/** The banner's text, from `announcement: "…"`. `''` uses the title. */
|
|
192
|
+
announcementText: string;
|
|
156
193
|
/** Per-post overrides of the `byline`, `cover` and `postNav` options. */
|
|
157
194
|
byline?: boolean;
|
|
158
195
|
cover?: boolean;
|
|
159
196
|
postNav?: boolean;
|
|
160
197
|
readingMinutes: number;
|
|
161
198
|
}
|
|
199
|
+
/** One announcement, as the banner shows it. */
|
|
200
|
+
interface BlogAnnouncementItem {
|
|
201
|
+
/** The post's path and date: what a dismissal remembers, so re-dating a post announces it again. */
|
|
202
|
+
id: string;
|
|
203
|
+
text: string;
|
|
204
|
+
/** The post's URL path, without the site's base. */
|
|
205
|
+
link: string;
|
|
206
|
+
}
|
|
207
|
+
/** What the announcement banner reads from VitePress's site data. */
|
|
208
|
+
interface BlogAnnouncementData {
|
|
209
|
+
/** Newest first: the banner shows the first one that hasn't been dismissed. */
|
|
210
|
+
items: BlogAnnouncementItem[];
|
|
211
|
+
/** The blog page filtered to announcements (`/blog/?announcements`), without the base, or `''` when no blog lists them. */
|
|
212
|
+
listLink: string;
|
|
213
|
+
labels: Pick<BlogLabels, 'announcement' | 'announcementCount' | 'dismiss'>;
|
|
214
|
+
}
|
|
162
215
|
|
|
163
216
|
/**
|
|
164
217
|
* A markdown-it plugin that turns pages into a blog.
|
|
@@ -187,4 +240,4 @@ interface BlogPostData {
|
|
|
187
240
|
*/
|
|
188
241
|
declare function blogMarkdown(md: MarkdownIt, options?: BlogOptions): void;
|
|
189
242
|
|
|
190
|
-
export { type
|
|
243
|
+
export { type BlogAnnouncementData as B, DEFAULT_LABELS as D, type BlogAnnouncementItem as a, type BlogAuthor as b, type BlogFeedConfig as c, type BlogIndexConfig as d, type BlogLabels as e, type BlogLayout as f, type BlogOptions as g, type BlogPostData as h, type BlogScope as i, blogMarkdown as j };
|
package/dist/style.css
CHANGED
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
--vp-blog-tag-bg: var(--vp-c-default-soft);
|
|
11
11
|
--vp-blog-tag-color: var(--vp-c-text-2);
|
|
12
12
|
--vp-blog-accent: var(--vp-c-brand-1);
|
|
13
|
+
--vp-blog-announcement-height: 40px;
|
|
14
|
+
--vp-blog-announcement-bg: var(--vp-button-brand-bg);
|
|
15
|
+
--vp-blog-announcement-color: var(--vp-button-brand-text);
|
|
13
16
|
}
|
|
14
17
|
|
|
15
18
|
/* Markdown inside the generated blocks is wrapped in <p>; its margins are handled here instead. */
|
|
@@ -201,6 +204,11 @@
|
|
|
201
204
|
color: var(--vp-c-brand-1);
|
|
202
205
|
}
|
|
203
206
|
|
|
207
|
+
.vp-blog-badge--announcement {
|
|
208
|
+
background: var(--vp-c-tip-soft);
|
|
209
|
+
color: var(--vp-c-tip-1);
|
|
210
|
+
}
|
|
211
|
+
|
|
204
212
|
.vp-blog-badge--draft {
|
|
205
213
|
background: var(--vp-c-warning-soft);
|
|
206
214
|
color: var(--vp-c-warning-1);
|
|
@@ -416,3 +424,108 @@
|
|
|
416
424
|
/* The RSS orange, as feed readers expect. */
|
|
417
425
|
color: #f26522;
|
|
418
426
|
}
|
|
427
|
+
|
|
428
|
+
/*
|
|
429
|
+
* The announcement banner, in the theme's `layout-top` slot: fixed across the
|
|
430
|
+
* top of the window, one line high. While it shows, VitePress's
|
|
431
|
+
* --vp-layout-top-height moves the nav bar, sidebar and content down by its
|
|
432
|
+
* height. The class on <html> hides it before hydration once dismissed.
|
|
433
|
+
*/
|
|
434
|
+
:root:not(.vp-blog-announcement-dismissed):has(.vp-blog-announcement) {
|
|
435
|
+
--vp-layout-top-height: var(--vp-blog-announcement-height);
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
.vp-blog-announcement-dismissed .vp-blog-announcement {
|
|
439
|
+
display: none;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
.vp-blog-announcement {
|
|
443
|
+
position: fixed;
|
|
444
|
+
top: 0;
|
|
445
|
+
right: 0;
|
|
446
|
+
left: 0;
|
|
447
|
+
z-index: var(--vp-z-index-layout-top);
|
|
448
|
+
display: flex;
|
|
449
|
+
gap: 8px;
|
|
450
|
+
align-items: center;
|
|
451
|
+
justify-content: center;
|
|
452
|
+
box-sizing: border-box;
|
|
453
|
+
height: var(--vp-blog-announcement-height);
|
|
454
|
+
padding: 0 48px;
|
|
455
|
+
background: var(--vp-blog-announcement-bg);
|
|
456
|
+
color: var(--vp-blog-announcement-color);
|
|
457
|
+
font-size: 14px;
|
|
458
|
+
font-weight: 500;
|
|
459
|
+
line-height: var(--vp-blog-announcement-height);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
.vp-blog-announcement__content {
|
|
463
|
+
display: flex;
|
|
464
|
+
gap: 10px;
|
|
465
|
+
align-items: center;
|
|
466
|
+
min-width: 0;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
.vp-blog-announcement__text {
|
|
470
|
+
overflow: hidden;
|
|
471
|
+
color: inherit;
|
|
472
|
+
text-decoration: none;
|
|
473
|
+
text-overflow: ellipsis;
|
|
474
|
+
white-space: nowrap;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
.vp-blog-announcement__text:hover {
|
|
478
|
+
text-decoration: underline;
|
|
479
|
+
text-underline-offset: 3px;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/* How many announcements there are: a counter pill that opens the list of them. */
|
|
483
|
+
.vp-blog-announcement__count {
|
|
484
|
+
flex: none;
|
|
485
|
+
min-width: 22px;
|
|
486
|
+
padding: 0 7px;
|
|
487
|
+
border-radius: 999px;
|
|
488
|
+
background: var(--vp-blog-announcement-color);
|
|
489
|
+
color: var(--vp-blog-announcement-bg);
|
|
490
|
+
font-size: 12px;
|
|
491
|
+
font-weight: 700;
|
|
492
|
+
font-variant-numeric: tabular-nums;
|
|
493
|
+
line-height: 20px;
|
|
494
|
+
text-align: center;
|
|
495
|
+
text-decoration: none;
|
|
496
|
+
transition: opacity 0.25s;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
a.vp-blog-announcement__count:hover {
|
|
500
|
+
opacity: 0.85;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
.vp-blog-announcement__dismiss {
|
|
504
|
+
position: absolute;
|
|
505
|
+
top: 50%;
|
|
506
|
+
right: 12px;
|
|
507
|
+
display: flex;
|
|
508
|
+
align-items: center;
|
|
509
|
+
justify-content: center;
|
|
510
|
+
width: 28px;
|
|
511
|
+
height: 28px;
|
|
512
|
+
border-radius: 6px;
|
|
513
|
+
color: inherit;
|
|
514
|
+
opacity: 0.8;
|
|
515
|
+
transform: translateY(-50%);
|
|
516
|
+
transition:
|
|
517
|
+
background-color 0.25s,
|
|
518
|
+
opacity 0.25s;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
.vp-blog-announcement__dismiss:hover {
|
|
522
|
+
background: rgba(255, 255, 255, 0.16);
|
|
523
|
+
opacity: 1;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
@media (max-width: 639px) {
|
|
527
|
+
.vp-blog-announcement {
|
|
528
|
+
justify-content: flex-start;
|
|
529
|
+
padding: 0 48px 0 16px;
|
|
530
|
+
}
|
|
531
|
+
}
|