New design for timeline

This commit is contained in:
DrMint 2024-05-27 15:08:19 +02:00
parent 701d60a0e5
commit 9a8991aa7f
7 changed files with 143 additions and 101 deletions

View File

@ -1,6 +1,7 @@
--- ---
import Card from "components/Card.astro";
import MasoTarget from "components/Maso/MasoTarget.astro"; import MasoTarget from "components/Maso/MasoTarget.astro";
import TimelineEventTranslation from "pages/[locale]/timeline/_components/TimelineEventTranslation.astro"; import RichText from "components/RichText/RichText.astro";
import TimelineLanguageOverride from "pages/[locale]/timeline/_components/TimelineLanguageOverride.astro"; import TimelineLanguageOverride from "pages/[locale]/timeline/_components/TimelineLanguageOverride.astro";
import TimelineNote from "pages/[locale]/timeline/_components/TimelineNote.astro"; import TimelineNote from "pages/[locale]/timeline/_components/TimelineNote.astro";
import TimelineSourcesButton from "pages/[locale]/timeline/_components/TimelineSourcesButton.astro"; import TimelineSourcesButton from "pages/[locale]/timeline/_components/TimelineSourcesButton.astro";
@ -32,20 +33,25 @@ const { title, description, notes, credits } = getLocalizedMatch(translations);
{/* ------------------------------------------- HTML ------------------------------------------- */} {/* ------------------------------------------- HTML ------------------------------------------- */}
<MasoTarget> <MasoTarget>
<div class="event"> <Card>
<TimelineEventTranslation title={title} description={description} /> <div class="event">
<div id="bottom" class="when-js when-no-print"> <div id="content">
<TimelineSourcesButton sources={sources} /> {title && <h4 class="font-xl">{title}</h4>}
{notes && <TimelineNote notes={notes} />} {description && <RichText content={description} />}
<TimelineLanguageOverride </div>
availableLanguages={translations.map(({ language }) => language)} <div id="bottom" class="when-js when-no-print">
currentLang={lang} <TimelineSourcesButton sources={sources} />
credits={credits} {notes && <TimelineNote notes={notes} />}
getPartialUrl={(locale) => <TimelineLanguageOverride
getLocalizedUrl(`/api/timeline/partial?id=${id}&index=${index}&lang=${locale}`)} availableLanguages={translations.map(({ language }) => language)}
/> currentLang={lang}
credits={credits}
getPartialUrl={(locale) =>
getLocalizedUrl(`/api/timeline/partial?id=${id}&index=${index}&lang=${locale}`)}
/>
</div>
</div> </div>
</div> </Card>
</MasoTarget> </MasoTarget>
{/* ------------------------------------------- CSS -------------------------------------------- */} {/* ------------------------------------------- CSS -------------------------------------------- */}
@ -55,12 +61,27 @@ const { title, description, notes, credits } = getLocalizedMatch(translations);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 1em; gap: 1em;
padding: 1em;
& > #content {
padding-left: 0.9em;
padding-right: 1.2em;
padding-top: 0.5em;
display: flex;
flex-direction: column;
gap: 0.5em;
& > h4 {
line-height: 1.2;
max-width: 35rem;
}
}
& > #bottom { & > #bottom {
display: flex; display: flex;
place-items: start; place-items: start;
gap: 0.3em; gap: 0.4em;
font-size: 85%;
} }
} }
</style> </style>

View File

@ -8,23 +8,35 @@ interface Props {
displayDate: boolean; displayDate: boolean;
} }
const { event, displayDate } = Astro.props; const {
event,
event: { date, events },
displayDate,
} = Astro.props;
const { formatTimelineDate, t } = await getI18n(Astro.locals.currentLocale); const { formatTimelineDate, t } = await getI18n(Astro.locals.currentLocale);
const displayedDate = const displayedDate =
!event.date.month && !event.date.day !date.month && !date.day
? t("timeline.year.during", { year: formatTimelineDate(event.date) }) ? t("timeline.year.during", { year: formatTimelineDate(date) })
: formatTimelineDate(event.date); : formatTimelineDate(date);
const multiple = displayDate && events.length > 1;
--- ---
{/* ------------------------------------------- HTML ------------------------------------------- */} {/* ------------------------------------------- HTML ------------------------------------------- */}
<div class="event-container"> <div class="event-container">
{displayDate && <h3>{displayedDate}</h3>} {
displayDate && (
<h3 class="font-xl" class:list={{ multiple }}>
{displayedDate}
</h3>
)
}
<div> <div class="date-container" class:list={{ multiple }}>
{ {
event.events.map((_, index) => ( events.map((_, index) => (
<TimelineEventPartial <TimelineEventPartial
event={event} event={event}
index={index} index={index}
@ -40,24 +52,30 @@ const displayedDate =
<style> <style>
.event-container { .event-container {
&:has(h3) > div {
border-left: 1px solid var(--color-base-600);
padding-left: 1em;
padding-block: 1em;
}
& > div {
display: flex;
flex-direction: column;
gap: 2em;
}
& > h3 { & > h3 {
padding-bottom: 0.3em; color: var(--color-base-600);
padding-inline: 0.2em; line-height: 2;
color: var(--color-base-700); margin-bottom: 0.1em;
border-bottom: 1px solid var(--color-base-600); margin-left: 16px;
width: fit-content;
&.multiple {
margin-left: 16px;
}
}
& > .date-container {
display: flex;
align-items: start;
flex-direction: column;
gap: 1em;
&.multiple {
border-left: 1px solid;
border-top: 1px solid;
border-color: var(--color-base-450);
border-radius: calc(26px);
padding: 1em;
}
} }
} }
</style> </style>

View File

@ -1,33 +0,0 @@
---
import RichText from "components/RichText/RichText.astro";
import type { RichTextContent } from "src/shared/payload/payload-sdk";
interface Props {
title?: string | undefined;
description?: RichTextContent | undefined;
}
const { title, description } = Astro.props;
---
{/* ------------------------------------------- HTML ------------------------------------------- */}
<div>
{title && <h4>{title}</h4>}
{description && <RichText content={description} />}
</div>
{/* ------------------------------------------- CSS -------------------------------------------- */}
<style>
div {
display: flex;
flex-direction: column;
gap: 0.5em;
& > h4 {
font-size: 120%;
max-width: 35rem;
}
}
</style>

View File

@ -35,25 +35,28 @@ const { t } = await getI18n(Astro.locals.currentLocale);
{credits.length > 0 && <InlineCredits credits={credits} />} {credits.length > 0 && <InlineCredits credits={credits} />}
</div> </div>
<div class="pressable-label"> <button class="pressable-label">
<Icon name="material-symbols:translate" /> <Icon name="material-symbols:translate" />
<p> <p class="font-s">
{ {
t("timeline.eventFooter.languages", { t("timeline.eventFooter.languages", {
count: availableLanguages.length, count: availableLanguages.length,
}) })
} }
</p> </p>
</div> </button>
</Tooltip> </Tooltip>
{/* ------------------------------------------- CSS -------------------------------------------- */} {/* ------------------------------------------- CSS -------------------------------------------- */}
<style> <style>
button {
padding-block: 0.5em;
}
#tooltip-content { #tooltip-content {
display: grid; display: grid;
gap: 0.5em; gap: 0.5em;
font-size: 1rem;
& .current { & .current {
color: var(--color-base-750); color: var(--color-base-750);

View File

@ -20,8 +20,16 @@ const { t } = await getI18n(Astro.locals.currentLocale);
<div id="tooltip-content" slot="tooltip-content"> <div id="tooltip-content" slot="tooltip-content">
<RichText content={notes} /> <RichText content={notes} />
</div> </div>
<div class="pressable-label"> <button class="pressable-label">
<Icon name="material-symbols:comment-outline" /> <Icon name="material-symbols:comment-outline" />
<p>{t("timeline.eventFooter.note")}</p> <p class="font-s">{t("timeline.eventFooter.note")}</p>
</div> </button>
</Tooltip> </Tooltip>
{/* ------------------------------------------- CSS -------------------------------------------- */}
<style>
button {
padding-block: 0.5em;
}
</style>

View File

@ -20,7 +20,7 @@ const { t } = await getI18n(Astro.locals.currentLocale);
sources.length === 0 ? ( sources.length === 0 ? (
<div class="no-sources error-message"> <div class="no-sources error-message">
<Icon name="material-symbols:warning-outline" /> <Icon name="material-symbols:warning-outline" />
<p>{t("timeline.eventFooter.sources", { count: sources.length })}</p> <p class="font-s">{t("timeline.eventFooter.sources", { count: sources.length })}</p>
</div> </div>
) : ( ) : (
<Tooltip trigger="click"> <Tooltip trigger="click">
@ -29,10 +29,10 @@ const { t } = await getI18n(Astro.locals.currentLocale);
<SourceRow source={source} /> <SourceRow source={source} />
))} ))}
</div> </div>
<div class="pressable-label"> <button class="pressable-label">
<Icon name="material-symbols:edit-note" /> <Icon name="material-symbols:edit-note" />
<p>{t("timeline.eventFooter.sources", { count: sources.length })}</p> <p class="font-s">{t("timeline.eventFooter.sources", { count: sources.length })}</p>
</div> </button>
</Tooltip> </Tooltip>
) )
} }
@ -40,11 +40,16 @@ const { t } = await getI18n(Astro.locals.currentLocale);
{/* ------------------------------------------- CSS -------------------------------------------- */} {/* ------------------------------------------- CSS -------------------------------------------- */}
<style> <style>
#tooltip-content { button {
display: grid; padding-block: 0.5em;
gap: 0.5em;
font-size: 1rem;
} }
#tooltip-content {
display: flex;
flex-direction: column;
gap: 1em;
}
.no-sources { .no-sources {
flex-shrink: 0; flex-shrink: 0;
display: flex; display: flex;

View File

@ -11,18 +11,28 @@ interface Props {
const { year, events } = Astro.props; const { year, events } = Astro.props;
const { formatTimelineDate } = await getI18n(Astro.locals.currentLocale); const { formatTimelineDate } = await getI18n(Astro.locals.currentLocale);
const eventsHaveDifferentDates = events.some(
({ date }) => JSON.stringify(date) !== JSON.stringify(events[0]?.date)
);
const date = eventsHaveDifferentDates ? { year } : events[0]!.date;
const multiple = events.flatMap(({ events }) => events).length > 1;
if (year === 856) {
console.log({ eventsHaveDifferentDates, events: events.map(({ date }) => date) });
}
--- ---
{/* ------------------------------------------- HTML ------------------------------------------- */} {/* ------------------------------------------- HTML ------------------------------------------- */}
{cache.config.timeline.breaks.includes(year) && <hr id={`hr-${year}`} />} {cache.config.timeline.breaks.includes(year) && <hr id={`hr-${year}`} />}
<h2 id={year.toString()}> <h2 class="font-2xl" class:list={{ multiple }} id={year.toString()}>
{formatTimelineDate(events.length === 1 ? events[0]!.date : { year })} {formatTimelineDate(date)}
</h2> </h2>
<div class="year-container"> <div class="year-container" class:list={{ multiple }}>
{events.map((event) => <TimelineEvent event={event} displayDate={events.length > 1} />)} {events.map((event) => <TimelineEvent event={event} displayDate={eventsHaveDifferentDates} />)}
</div> </div>
{/* ------------------------------------------- CSS -------------------------------------------- */} {/* ------------------------------------------- CSS -------------------------------------------- */}
@ -36,22 +46,32 @@ const { formatTimelineDate } = await getI18n(Astro.locals.currentLocale);
} }
.year-container { .year-container {
border-left: 1px solid var(--color-base-600);
padding-left: 1em;
padding-block: 1em;
margin-bottom: 3em; margin-bottom: 3em;
width: fit-content;
display: flex; &.multiple {
flex-direction: column; display: flex;
gap: 2em; flex-direction: column;
gap: 2.5em;
border-left: 1px solid;
border-top: 1px solid;
border-color: var(--color-base-600);
border-radius: calc(26px);
padding: 1em;
}
} }
h2 { h2 {
padding-bottom: 0.2em;
padding-inline: 0.2em; padding-inline: 0.2em;
color: var(--color-base-700); color: var(--color-base-700);
border-bottom: 1px solid var(--color-base-600);
scroll-margin-block: 1em; scroll-margin-block: 1em;
width: fit-content;
line-height: 2;
margin-left: 12px;
&.multiple {
margin-left: 18px;
}
} }
</style> </style>