@sarimarcus/content-sites-ui 0.41.0 → 0.41.2
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/CHANGELOG.md +8 -0
- package/package.json +2 -2
- package/src/editorial/ChronologyTimeline.astro +30 -18
- package/src/internal/labels.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
All packages in the platform release in lockstep; entries are per release version.
|
|
4
4
|
|
|
5
|
+
## 0.41.2 (2026-10-21)
|
|
6
|
+
|
|
7
|
+
- `editorial`: `ChronologyTimeline`'s era index is now `TableOfContents` (card variant) instead of a row of chips: a collapsed jump list on mobile, a sticky bar once the index scrolls away, and the era in view marked with `data-active` / `aria-current`. The era anchor ids move from the era heading to its `<li>`, so the scrollspy follows the whole era and the sticky bar hides after the last one. Its markup changes on every page that renders the timeline (SLA-3274).
|
|
8
|
+
|
|
9
|
+
## 0.41.1 (2026-10-21)
|
|
10
|
+
|
|
11
|
+
- `editorial`: `ChronologyTimeline` heads an era's entries without a `yearLabel` with a quiet "Undated" label (new `undatedLabel` prop, `LABELS.chronologyTimeline.undatedLabel`) and renders them after the dated ones; an era with only dated or only undated entries keeps its markup, and `undatedLabel=""` keeps one run. The era index is now a single-row, horizontally scrolling strip instead of wrapping chips (SLA-3274).
|
|
12
|
+
|
|
5
13
|
## 0.41.0 (2026-10-20)
|
|
6
14
|
|
|
7
15
|
- `editorial`: new `EraChip`, a Chip link from an article or monument to its era's section on the chronology page (`eraHref`), rendering nothing without an era; new `ChronologyTimeline`, a vertical rail of a site's eras (heading anchor, range, intro, dated entry rows, related dossiers, compact one-line markers for empty eras), with `groupByEra` and the `TimelineItem` type. No change to existing components' markup (SLA-3251).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sarimarcus/content-sites-ui",
|
|
3
|
-
"version": "0.41.
|
|
3
|
+
"version": "0.41.2",
|
|
4
4
|
"description": "Universal Astro UI components, layout shell and design tokens shared by the content sites.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -50,6 +50,6 @@
|
|
|
50
50
|
"@lucide/astro": "^1.23.0",
|
|
51
51
|
"astro": "^7.0.6",
|
|
52
52
|
"tailwindcss": "^4.1.18",
|
|
53
|
-
"@sarimarcus/content-sites-core": "0.41.
|
|
53
|
+
"@sarimarcus/content-sites-core": "0.41.2"
|
|
54
54
|
}
|
|
55
55
|
}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* so eraHref() links never dead-end; 'show' renders every era in full.
|
|
5
5
|
*/
|
|
6
6
|
import type { EraDefinition } from '@sarimarcus/content-sites-core/eras';
|
|
7
|
-
import
|
|
7
|
+
import TableOfContents from '../composed/TableOfContents.astro';
|
|
8
8
|
import LinkArrow from '../primitives/LinkArrow.astro';
|
|
9
9
|
import ResponsivePicture from '../primitives/ResponsivePicture.astro';
|
|
10
10
|
import { LABELS } from '../internal/labels';
|
|
@@ -20,6 +20,8 @@ interface Props {
|
|
|
20
20
|
indexLabel?: string;
|
|
21
21
|
dossiersLabel?: string;
|
|
22
22
|
emptyLabel?: string;
|
|
23
|
+
/** Heads the entries without a `yearLabel` when an era also has dated ones, which then render first (order kept within each run); '' keeps one run in the given order. */
|
|
24
|
+
undatedLabel?: string;
|
|
23
25
|
class?: string;
|
|
24
26
|
}
|
|
25
27
|
|
|
@@ -31,13 +33,19 @@ const {
|
|
|
31
33
|
indexLabel = LABELS.chronologyTimeline.indexLabel,
|
|
32
34
|
dossiersLabel = LABELS.chronologyTimeline.dossiersLabel,
|
|
33
35
|
emptyLabel = LABELS.chronologyTimeline.emptyLabel,
|
|
36
|
+
undatedLabel = LABELS.chronologyTimeline.undatedLabel,
|
|
34
37
|
class: className,
|
|
35
38
|
} = Astro.props;
|
|
36
39
|
|
|
37
40
|
const ordered = [...eras].sort((a, b) => a.startYear - b.startYear);
|
|
38
41
|
const rows = ordered.map((era) => {
|
|
39
42
|
const entries = items[era.id] ?? [];
|
|
40
|
-
|
|
43
|
+
const dated = entries.filter((item) => item.yearLabel);
|
|
44
|
+
const undated = entries.filter((item) => !item.yearLabel);
|
|
45
|
+
const runs = undatedLabel && dated.length && undated.length
|
|
46
|
+
? [{ entries: dated, label: '' }, { entries: undated, label: undatedLabel }]
|
|
47
|
+
: [{ entries, label: '' }];
|
|
48
|
+
return { era, runs, full: entries.length > 0 || emptyEra === 'show' };
|
|
41
49
|
});
|
|
42
50
|
const fullEras = rows.filter((r) => r.full).map((r) => r.era);
|
|
43
51
|
|
|
@@ -52,27 +60,30 @@ const thumbSizes = '(min-width: 640px) 128px, 64px';
|
|
|
52
60
|
|
|
53
61
|
<div class:list={['w-full', className]} data-chronology>
|
|
54
62
|
{index && fullEras.length > 1 && (
|
|
55
|
-
<
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
63
|
+
<TableOfContents
|
|
64
|
+
class="mb-12 md:mb-16"
|
|
65
|
+
showHeader={false}
|
|
66
|
+
ariaLabel={indexLabel}
|
|
67
|
+
items={fullEras.map((era) => ({ label: era.label, href: `#${era.anchor}` }))}
|
|
68
|
+
sectionSelector="[data-chronology-era]"
|
|
69
|
+
hideMiniPastLastSection
|
|
70
|
+
/>
|
|
62
71
|
)}
|
|
63
72
|
<ol class="grid">
|
|
64
|
-
{rows.map(({ era,
|
|
65
|
-
<li class="group/era grid grid-cols-[1.25rem_minmax(0,1fr)] grid-rows-[auto_auto_1fr] gap-x-4 md:grid-cols-[10rem_1.25rem_minmax(0,1fr)] md:grid-rows-[auto_1fr] md:gap-x-6" data-chronology-era={era.id}>
|
|
73
|
+
{rows.map(({ era, runs, full }) => full ? (
|
|
74
|
+
<li class="scroll-mt-28 group/era grid grid-cols-[1.25rem_minmax(0,1fr)] grid-rows-[auto_auto_1fr] gap-x-4 md:grid-cols-[10rem_1.25rem_minmax(0,1fr)] md:grid-rows-[auto_1fr] md:gap-x-6" id={era.anchor} data-chronology-era={era.id}>
|
|
66
75
|
<div class="relative col-start-1 row-span-3 flex justify-center md:col-start-2 md:row-span-2 before:absolute before:inset-y-0 before:left-1/2 before:w-0.5 before:-translate-x-1/2 before:bg-foreground/15 group-first/era:before:top-3 md:group-first/era:before:top-4" aria-hidden="true">
|
|
67
76
|
<span class="relative mt-3 size-3 rotate-45 bg-primary ring-4 ring-background md:mt-4 md:size-3.5"></span>
|
|
68
77
|
</div>
|
|
69
|
-
<h2
|
|
78
|
+
<h2 class="col-start-2 row-start-1 font-display text-3xl leading-tight text-balance text-foreground md:col-start-3 md:text-4xl">{era.label}</h2>
|
|
70
79
|
<p class="col-start-2 row-start-2 mt-1 font-display text-lg tabular-nums text-secondary md:col-start-1 md:row-start-1 md:row-span-2 md:mt-4 md:self-start md:sticky md:top-28 md:text-right md:text-xl md:leading-snug">{era.rangeLabel}</p>
|
|
71
80
|
<div class="col-start-2 row-start-3 pb-16 md:col-start-3 md:row-start-2 md:pb-24 group-last/era:pb-0">
|
|
72
81
|
<p class="mt-4 max-w-measure text-lg leading-relaxed text-foreground">{era.intro}</p>
|
|
73
|
-
{entries.length > 0 && (
|
|
74
|
-
|
|
75
|
-
|
|
82
|
+
{runs.map((run) => run.entries.length > 0 && (
|
|
83
|
+
<>
|
|
84
|
+
{run.label && <p id={`${era.anchor}-undated`} class="mt-8 text-sm font-semibold text-muted-foreground">{run.label}</p>}
|
|
85
|
+
<ol aria-labelledby={run.label ? `${era.anchor}-undated` : undefined} class:list={[run.label ? 'mt-3' : 'mt-8', 'divide-y divide-border border-y border-border']}>
|
|
86
|
+
{run.entries.map((item) => (
|
|
76
87
|
<li class="group/entry relative flex items-start gap-3 py-5 sm:gap-6">
|
|
77
88
|
<div class="min-w-0 flex-1">
|
|
78
89
|
<h3 class="text-lg font-semibold leading-snug text-foreground text-pretty">
|
|
@@ -99,7 +110,8 @@ const thumbSizes = '(min-width: 640px) 128px, 64px';
|
|
|
99
110
|
</li>
|
|
100
111
|
))}
|
|
101
112
|
</ol>
|
|
102
|
-
|
|
113
|
+
</>
|
|
114
|
+
))}
|
|
103
115
|
{era.dossiers && era.dossiers.length > 0 && (
|
|
104
116
|
<div class="mt-8">
|
|
105
117
|
<p id={`${era.anchor}-dossiers`} class="text-sm font-semibold text-foreground">{dossiersLabel}</p>
|
|
@@ -113,11 +125,11 @@ const thumbSizes = '(min-width: 640px) 128px, 64px';
|
|
|
113
125
|
</div>
|
|
114
126
|
</li>
|
|
115
127
|
) : (
|
|
116
|
-
<li class="group/era grid grid-cols-[1.25rem_minmax(0,1fr)] gap-x-4 md:grid-cols-[10rem_1.25rem_minmax(0,1fr)] md:gap-x-6" data-chronology-era={era.id} data-chronology-empty>
|
|
128
|
+
<li class="scroll-mt-28 group/era grid grid-cols-[1.25rem_minmax(0,1fr)] gap-x-4 md:grid-cols-[10rem_1.25rem_minmax(0,1fr)] md:gap-x-6" id={era.anchor} data-chronology-era={era.id} data-chronology-empty>
|
|
117
129
|
<div class="relative col-start-1 flex justify-center md:col-start-2 before:absolute before:inset-y-0 before:left-1/2 before:w-0.5 before:-translate-x-1/2 before:bg-foreground/15 group-first/era:before:top-2" aria-hidden="true">
|
|
118
130
|
<span class="relative mt-2 size-2 rotate-45 border border-muted-foreground bg-background"></span>
|
|
119
131
|
</div>
|
|
120
|
-
<p
|
|
132
|
+
<p class="col-start-2 flex flex-wrap items-baseline gap-x-2 pb-10 text-sm text-muted-foreground md:col-start-3 group-last/era:pb-0">
|
|
121
133
|
<span class="font-display text-base text-foreground">{era.label}</span>
|
|
122
134
|
<span aria-hidden="true">·</span>
|
|
123
135
|
<span class="tabular-nums">{era.rangeLabel}</span>
|