Files
windwiderstand/src/lib/block-types.ts
T
Peter Meier 1d75610cd3
Deploy / verify (push) Successful in 37s
Deploy / deploy (push) Successful in 58s
feat(organisations-block): enhance OrganisationsBlock with carousel presentation option and improved layout
- Added "carousel" option to the presentation property in OrganisationsBlockData for horizontal slider functionality.
- Updated OrganisationsBlock.svelte to support carousel layout with smooth scrolling feature.
- Refined Badge component styling for better visual consistency.
- Improved overall structure and responsiveness of the organisations display.
2026-04-19 13:13:12 +02:00

297 lines
8.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Gemeinsame Typen für Content-Blöcke (Rows, Markdown, …).
* Wird von SvelteKit-Seiten und Svelte-Komponenten genutzt.
* Kalender-Typen basieren auf der OpenAPI-Spec (cms-api.generated).
*/
import type { BlockLayout } from "./block-layout";
import type { components } from "./cms-api.generated";
/** Aufgelöster Block vom CMS (mit _type, _slug + typ-spezifische Felder). */
export type ResolvedBlock = {
_type?: string;
_slug?: string;
[key: string]: unknown;
};
/** Gemeinsames Row-Layout (page, post, footer erben content_layout). */
export interface RowContentLayout {
row1Content?: unknown[];
row1JustifyContent?: string;
row1AlignItems?: string;
row2Content?: unknown[];
row2JustifyContent?: string;
row2AlignItems?: string;
row3Content?: unknown[];
row3JustifyContent?: string;
row3AlignItems?: string;
}
/** Resolved Markdown-Block vom CMS (_type: "markdown"). resolvedContent = HTML mit transformierten Bildern (von resolveContentImages). */
export interface MarkdownBlockData {
_type?: "markdown";
_slug?: string;
name?: string;
content?: string;
/** Gesetzt von resolveContentImages: HTML (Bilder transformiert, in Links eingewickelt). */
resolvedContent?: string;
alignment?: "left" | "center" | "right";
layout?: BlockLayout;
}
/** Headline (_type: "headline"). */
export interface HeadlineBlockData {
_type?: "headline";
_slug?: string;
tag?: "h1" | "h2" | "h3" | "h4" | "h5" | "h6";
text?: string;
align?: "left" | "center" | "right";
layout?: BlockLayout;
}
/** HTML (_type: "html"). */
export interface HtmlBlockData {
_type?: "html";
_slug?: string;
html?: string;
layout?: BlockLayout;
}
/** Iframe (_type: "iframe"). */
export interface IframeBlockData {
_type?: "iframe";
_slug?: string;
iframe?: string;
content?: string;
layout?: BlockLayout;
}
/** Image (_type: "image"). image oder img: Slug, URL-String oder aufgelöstes Objekt (src/description oder file.url). */
export interface ImageBlockData {
_type?: "image";
_slug?: string;
image?:
| string
| {
_type?: "img";
_slug?: string;
src?: string;
description?: string;
file?: { url?: string };
title?: string;
};
/** Alternative zu image (manche CMS-Responses liefern img). */
img?:
| string
| {
_type?: "img";
_slug?: string;
src?: string;
description?: string;
file?: { url?: string };
title?: string;
};
/** Nach resolveContentImages: Proxy-URL zum transformierten Bild. */
resolvedImageSrc?: string;
caption?: string;
aspectRatio?: number;
layout?: BlockLayout;
}
/** Eintrag in einer image_gallery (img mit src/description). */
export interface ImageGalleryImage {
_type?: "img";
_slug?: string;
src?: string;
description?: string;
file?: { url?: string };
/** Nach resolveContentImages: Proxy-URL zum transformierten Bild (16:9). */
resolvedSrc?: string;
}
/** Bildergalerie (_type: "image_gallery"). images: Array von img-Objekten (src, description). */
export interface ImageGalleryBlockData {
_type?: "image_gallery";
_slug?: string;
/** Optionaler Einleitungstext (Markdown). */
description?: string;
images?: ImageGalleryImage[];
layout?: BlockLayout;
}
/** YouTube-Video (_type: "youtube_video"). */
export interface YoutubeVideoBlockData {
_type?: "youtube_video";
_slug?: string;
youtubeId?: string;
title?: string;
description?: string;
params?: string;
layout?: BlockLayout;
}
/** Zitat (_type: "quote"). */
export interface QuoteBlockData {
_type?: "quote";
_slug?: string;
quote?: string;
author?: string;
variant?: "left" | "right" | "center";
layout?: BlockLayout;
}
/** Zitat-Karussell (_type: "quote_carousel"). Rotiert durch aufgelöste quote-Einträge. */
export interface QuoteCarouselBlockData {
_type?: "quote_carousel";
_slug?: string;
headline?: string;
quotes?: Array<
| string
| {
_slug?: string;
quote?: string;
author?: string;
variant?: "left" | "right" | "center";
}
>;
autoRotate?: boolean;
intervalSeconds?: number;
showArrows?: boolean;
layout?: BlockLayout;
}
/** Link-Liste (_type: "link_list"). links können Slugs oder aufgelöste link-Objekte sein. */
export interface LinkListBlockData {
_type?: "link_list";
_slug?: string;
headline?: string;
links?: Array<string | { url?: string; linkName?: string; newTab?: boolean }>;
layout?: BlockLayout;
}
/** Post-Übersicht (_type: "post_overview"). Nach resolvePostOverviewBlocks: postsResolved gesetzt. */
export interface PostOverviewBlockData {
_type?: "post_overview";
_slug?: string;
headline?: string;
/** Einleitungstext (Markdown). */
text?: string;
/** true = alle Posts laden; false = posts (Slugs/Objekte) aus dem Block nutzen. */
allPosts?: boolean;
/** Nur wenn allPosts false: feste Post-Liste (Slugs oder aufgelöste Einträge). */
posts?: unknown[];
/** Tag-Slugs, nach denen gefiltert wird (nur bei allPosts true). */
filterByTag?: string[];
/** Max. Anzahl Einträge. */
numberItems?: number;
/** "list" | "cards". */
design?: "list" | "cards";
layout?: BlockLayout;
/** Nach resolvePostOverviewBlocks: geladene/gefilterte Posts (PostEntry[]). */
postsResolved?: unknown[];
}
/** Deadline-Banner (_type: "deadline_banner"). Schmaler Balken unter Hero. */
export interface DeadlineBannerBlockData {
_type?: "deadline_banner";
_slug?: string;
mode?: "manual" | "auto";
label?: string;
text?: string;
date?: string;
items?: Array<
| string
| {
_slug?: string;
title?: string;
terminZeit?: string;
description?: string;
link?: string | { url?: string; linkName?: string; newTab?: boolean; _slug?: string };
}
>;
link?: string | { url?: string; linkName?: string; newTab?: boolean; _slug?: string };
variant?: "accent" | "urgent" | "info";
showCountdown?: boolean;
layout?: BlockLayout;
}
/** Tag-Referenz (API liefert oft { _slug, _type, name }). */
export type SearchableTextTagRef = string | { _slug?: string; name?: string };
/** Ein Text-Fragment (aus text_fragment), für SearchableTextBlock. */
export interface SearchableTextFragment {
_slug?: string;
title?: string;
text?: string;
tags?: SearchableTextTagRef[];
}
/** Durchsuchbarer Text (_type: "searchable_text"). textFragments können Slugs oder aufgelöste Objekte sein. */
export interface SearchableTextBlockData {
_type?: "searchable_text";
_slug?: string;
/** Titel der Suchkomponente. */
title?: string;
/** Einleitung (Markdown). */
description?: string;
/** Slugs oder aufgelöste text_fragment-Einträge. */
textFragments?: (string | SearchableTextFragment)[];
layout?: BlockLayout;
}
/** OpnForm embed (_type: "opnform"). */
export interface OpnFormBlockData {
_type?: "opnform";
_slug?: string;
id?: string;
formId?: string;
baseUrl?: string;
iframeTitle?: string;
layout?: BlockLayout;
}
/** Einzelne Organisation (aufgelöst aus organisation-Collection). */
export interface OrganisationEntry {
_type?: "organisation";
_slug?: string;
name?: string;
logo?: string | { src?: string; description?: string };
/** Nach resolveContentImages: Proxy-URL zum Logo (WebP). */
resolvedLogoSrc?: string;
description?: string;
link?: string | { url?: string; linkName?: string; newTab?: boolean };
badge?: string | { label?: string; color?: string };
}
/** Organisations-Block (_type: "organisations"). */
export interface OrganisationsBlockData {
_type?: "organisations";
_slug?: string;
headline?: string;
description?: string;
/** default = Karten-Grid; compact = engere Karten, Logo links; carousel = horizontaler Slider (3 Desktop / 2 Mobile) */
presentation?: "default" | "compact" | "carousel";
addOrganisationTitle?: string;
addOrganisationMarkdown?: string;
/** Referenz auf link-Collection (aufgelöst: url, linkName, newTab) */
addOrganisationLink?: string | { url?: string; linkName?: string; newTab?: boolean };
organisations?: (string | OrganisationEntry)[];
layout?: BlockLayout;
}
/** Kalender-Item (calendar_item) aus OpenAPI; terminZeit = ISO date-time. */
export type CalendarItemData = components["schemas"]["calendar_item"];
/** Kalender-Block (_type: "calendar"). items nach Resolve: CalendarItemData[]. Basis aus OpenAPI (calendar). */
export type CalendarBlockData = Omit<
components["schemas"]["calendar"],
"items"
> & {
_type?: "calendar";
/** Optionaler Titel über dem Kalender. */
title?: string;
/** Slugs oder aufgelöste calendar_item-Einträge. */
items?: (string | CalendarItemData)[];
layout?: BlockLayout;
};