feat: add ImageSliderBlock for image galleries and sliders

Layouts:
- Slider, Grid, Masonry, Single, Thumbnails, Filmstrip

Images Array (1-50):
- Upload with caption, alt text, optional link
- Localized captions

Slider Options:
- Effects: slide, fade, zoom, flip, coverflow, cube
- Speed, slides per view, gap, autoplay, loop, centered

Navigation:
- Arrows with 4 styles
- Dots with 4 styles (dots, lines, numbers, progress)
- Counter, swipe, keyboard support

Lightbox:
- Zoom, download, share buttons
- Captions, thumbnails
- Background styles (dark, light, blur)

Styling:
- Height options (auto to fullscreen)
- Image fit, rounded corners, shadows, borders
- Hover effects (zoom, brighten, darken, overlay)
- Caption positions (below, overlay, hover, hidden)
- Background and padding options

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Martin Porwoll 2025-12-13 20:58:32 +00:00
parent 8116180955
commit f0424a4abf
5 changed files with 934 additions and 0 deletions

View file

@ -0,0 +1,549 @@
import type { Block } from 'payload'
/**
* ImageSliderBlock / GalleryBlock
*
* Vielseitiger Bild-Slider und Galerie-Block mit:
* - Mehreren Layouts (Slider, Grid, Masonry)
* - Lightbox-Funktion
* - Thumbnail-Navigation
* - Bildunterschriften
* - Verschiedenen Animationen
*/
export const ImageSliderBlock: Block = {
slug: 'image-slider-block',
labels: {
singular: 'Bildergalerie',
plural: 'Bildergalerien',
},
imageURL: '/assets/blocks/image-slider.png',
fields: [
// Titel & Beschreibung
{
name: 'title',
type: 'text',
label: 'Titel',
localized: true,
admin: {
description: 'Optionaler Titel über der Galerie',
},
},
{
name: 'description',
type: 'textarea',
label: 'Beschreibung',
localized: true,
},
// Bilder Array
{
name: 'images',
type: 'array',
required: true,
minRows: 1,
maxRows: 50,
label: 'Bilder',
labels: {
singular: 'Bild',
plural: 'Bilder',
},
admin: {
description: 'Mindestens 1 Bild, maximal 50 Bilder',
initCollapsed: false,
},
fields: [
{
name: 'image',
type: 'upload',
relationTo: 'media',
required: true,
label: 'Bild',
},
{
name: 'caption',
type: 'text',
label: 'Bildunterschrift',
localized: true,
},
{
name: 'alt',
type: 'text',
label: 'Alt-Text',
localized: true,
admin: {
description: 'Alternativer Text für Barrierefreiheit (falls abweichend vom Media Alt)',
},
},
{
name: 'link',
type: 'text',
label: 'Link',
admin: {
description: 'Optionaler Link beim Klick (statt Lightbox)',
},
},
],
},
// Layout
{
name: 'layout',
type: 'select',
defaultValue: 'slider',
label: 'Layout',
options: [
{ label: 'Slider', value: 'slider' },
{ label: 'Grid', value: 'grid' },
{ label: 'Masonry', value: 'masonry' },
{ label: 'Einzelbild (Featured)', value: 'single' },
{ label: 'Thumbnails unten', value: 'thumbs' },
{ label: 'Filmstreifen', value: 'filmstrip' },
],
},
// Grid/Masonry Optionen
{
name: 'grid',
type: 'group',
label: 'Grid-Einstellungen',
admin: {
condition: (_, siblingData) =>
siblingData?.layout === 'grid' || siblingData?.layout === 'masonry',
},
fields: [
{
name: 'cols',
type: 'select',
defaultValue: '3',
label: 'Spalten',
options: [
{ label: '2 Spalten', value: '2' },
{ label: '3 Spalten', value: '3' },
{ label: '4 Spalten', value: '4' },
{ label: '5 Spalten', value: '5' },
{ label: '6 Spalten', value: '6' },
],
},
{
name: 'gap',
type: 'select',
defaultValue: '16',
label: 'Abstand',
options: [
{ label: 'Kein Abstand', value: '0' },
{ label: 'Klein (8px)', value: '8' },
{ label: 'Normal (16px)', value: '16' },
{ label: 'Groß (24px)', value: '24' },
{ label: 'Sehr groß (32px)', value: '32' },
],
},
{
name: 'aspectRatio',
type: 'select',
defaultValue: 'square',
label: 'Seitenverhältnis',
options: [
{ label: 'Quadratisch (1:1)', value: 'square' },
{ label: 'Querformat (4:3)', value: '4-3' },
{ label: 'Breit (16:9)', value: '16-9' },
{ label: 'Hochformat (3:4)', value: '3-4' },
{ label: 'Original', value: 'auto' },
],
admin: {
condition: (_, siblingData) => siblingData?.layout !== 'masonry',
},
},
],
},
// Slider-Einstellungen
{
name: 'slider',
type: 'group',
label: 'Slider-Einstellungen',
admin: {
condition: (_, siblingData) =>
siblingData?.layout === 'slider' ||
siblingData?.layout === 'thumbs' ||
siblingData?.layout === 'filmstrip',
},
fields: [
{
name: 'effect',
type: 'select',
defaultValue: 'slide',
label: 'Animation',
options: [
{ label: 'Schieben (Slide)', value: 'slide' },
{ label: 'Überblenden (Fade)', value: 'fade' },
{ label: 'Zoom', value: 'zoom' },
{ label: 'Flip', value: 'flip' },
{ label: 'Coverflow', value: 'coverflow' },
{ label: 'Cube', value: 'cube' },
],
},
{
name: 'speed',
type: 'select',
defaultValue: '500',
label: 'Geschwindigkeit',
options: [
{ label: 'Schnell (300ms)', value: '300' },
{ label: 'Normal (500ms)', value: '500' },
{ label: 'Langsam (800ms)', value: '800' },
],
},
{
name: 'perView',
type: 'select',
defaultValue: '1',
label: 'Sichtbare Bilder',
options: [
{ label: '1', value: '1' },
{ label: '2', value: '2' },
{ label: '3', value: '3' },
{ label: '4', value: '4' },
{ label: 'Auto', value: 'auto' },
],
},
{
name: 'gap',
type: 'select',
defaultValue: '0',
label: 'Abstand',
options: [
{ label: 'Kein Abstand', value: '0' },
{ label: 'Klein (8px)', value: '8' },
{ label: 'Normal (16px)', value: '16' },
{ label: 'Groß (24px)', value: '24' },
],
},
{
name: 'auto',
type: 'checkbox',
defaultValue: false,
label: 'Autoplay',
},
{
name: 'delay',
type: 'select',
defaultValue: '4000',
label: 'Intervall',
options: [
{ label: '3 Sekunden', value: '3000' },
{ label: '4 Sekunden', value: '4000' },
{ label: '5 Sekunden', value: '5000' },
{ label: '6 Sekunden', value: '6000' },
{ label: '8 Sekunden', value: '8000' },
],
admin: {
condition: (_, siblingData) => siblingData?.auto,
},
},
{
name: 'pauseHover',
type: 'checkbox',
defaultValue: true,
label: 'Bei Hover pausieren',
admin: {
condition: (_, siblingData) => siblingData?.auto,
},
},
{
name: 'loop',
type: 'checkbox',
defaultValue: true,
label: 'Endlosschleife',
},
{
name: 'centered',
type: 'checkbox',
defaultValue: false,
label: 'Aktives Bild zentrieren',
},
],
},
// Navigation
{
name: 'nav',
type: 'group',
label: 'Navigation',
admin: {
condition: (_, siblingData) =>
siblingData?.layout === 'slider' ||
siblingData?.layout === 'thumbs' ||
siblingData?.layout === 'filmstrip',
},
fields: [
{
name: 'arrows',
type: 'checkbox',
defaultValue: true,
label: 'Pfeile anzeigen',
},
{
name: 'arrowStyle',
type: 'select',
defaultValue: 'default',
label: 'Pfeil-Stil',
options: [
{ label: 'Standard', value: 'default' },
{ label: 'Minimal', value: 'minimal' },
{ label: 'Eckig', value: 'square' },
{ label: 'Nur bei Hover', value: 'hover' },
],
admin: {
condition: (_, siblingData) => siblingData?.arrows,
},
},
{
name: 'dots',
type: 'checkbox',
defaultValue: true,
label: 'Punkte anzeigen',
},
{
name: 'dotStyle',
type: 'select',
defaultValue: 'dots',
label: 'Punkte-Stil',
options: [
{ label: 'Punkte', value: 'dots' },
{ label: 'Striche', value: 'lines' },
{ label: 'Nummern', value: 'numbers' },
{ label: 'Fortschritt', value: 'progress' },
],
admin: {
condition: (_, siblingData) => siblingData?.dots,
},
},
{
name: 'counter',
type: 'checkbox',
defaultValue: false,
label: 'Zähler anzeigen (1/10)',
},
{
name: 'swipe',
type: 'checkbox',
defaultValue: true,
label: 'Touch-Swipe',
},
{
name: 'keys',
type: 'checkbox',
defaultValue: true,
label: 'Tastaturnavigation',
},
],
},
// Lightbox
{
name: 'lightbox',
type: 'group',
label: 'Lightbox',
fields: [
{
name: 'enabled',
type: 'checkbox',
defaultValue: true,
label: 'Lightbox aktivieren',
admin: {
description: 'Bilder bei Klick in Vollansicht öffnen',
},
},
{
name: 'zoom',
type: 'checkbox',
defaultValue: true,
label: 'Zoom erlauben',
admin: {
condition: (_, siblingData) => siblingData?.enabled,
},
},
{
name: 'download',
type: 'checkbox',
defaultValue: false,
label: 'Download-Button',
admin: {
condition: (_, siblingData) => siblingData?.enabled,
},
},
{
name: 'share',
type: 'checkbox',
defaultValue: false,
label: 'Teilen-Button',
admin: {
condition: (_, siblingData) => siblingData?.enabled,
},
},
{
name: 'captions',
type: 'checkbox',
defaultValue: true,
label: 'Bildunterschriften anzeigen',
admin: {
condition: (_, siblingData) => siblingData?.enabled,
},
},
{
name: 'thumbs',
type: 'checkbox',
defaultValue: true,
label: 'Thumbnails anzeigen',
admin: {
condition: (_, siblingData) => siblingData?.enabled,
},
},
{
name: 'bg',
type: 'select',
defaultValue: 'dark',
label: 'Hintergrund',
options: [
{ label: 'Dunkel', value: 'dark' },
{ label: 'Hell', value: 'light' },
{ label: 'Blur', value: 'blur' },
],
admin: {
condition: (_, siblingData) => siblingData?.enabled,
},
},
],
},
// Darstellung
{
name: 'style',
type: 'group',
label: 'Darstellung',
fields: [
{
name: 'height',
type: 'select',
defaultValue: 'auto',
label: 'Höhe',
options: [
{ label: 'Auto (Bildverhältnis)', value: 'auto' },
{ label: 'Klein (300px)', value: '300' },
{ label: 'Mittel (400px)', value: '400' },
{ label: 'Groß (500px)', value: '500' },
{ label: 'Sehr groß (600px)', value: '600' },
{ label: 'Vollbild (100vh)', value: 'full' },
],
},
{
name: 'imgFit',
type: 'select',
defaultValue: 'cover',
label: 'Bildanpassung',
options: [
{ label: 'Ausfüllen (cover)', value: 'cover' },
{ label: 'Einpassen (contain)', value: 'contain' },
{ label: 'Strecken (fill)', value: 'fill' },
],
},
{
name: 'rounded',
type: 'select',
defaultValue: 'none',
label: 'Ecken',
options: [
{ label: 'Keine', value: 'none' },
{ label: 'Klein', value: 'sm' },
{ label: 'Mittel', value: 'md' },
{ label: 'Groß', value: 'lg' },
{ label: 'Rund', value: 'full' },
],
},
{
name: 'shadow',
type: 'checkbox',
defaultValue: false,
label: 'Schatten',
},
{
name: 'border',
type: 'checkbox',
defaultValue: false,
label: 'Rahmen',
},
{
name: 'hoverEffect',
type: 'select',
defaultValue: 'none',
label: 'Hover-Effekt',
options: [
{ label: 'Keiner', value: 'none' },
{ label: 'Zoom', value: 'zoom' },
{ label: 'Aufhellen', value: 'brighten' },
{ label: 'Abdunkeln', value: 'darken' },
{ label: 'Overlay', value: 'overlay' },
],
},
{
name: 'captionPos',
type: 'select',
defaultValue: 'below',
label: 'Bildunterschrift-Position',
options: [
{ label: 'Unterhalb', value: 'below' },
{ label: 'Overlay unten', value: 'overlay' },
{ label: 'Bei Hover', value: 'hover' },
{ label: 'Versteckt', value: 'hidden' },
],
},
{
name: 'bg',
type: 'select',
defaultValue: 'none',
label: 'Hintergrund',
options: [
{ label: 'Keiner', value: 'none' },
{ label: 'Weiß', value: 'white' },
{ label: 'Grau', value: 'light' },
{ label: 'Dunkel', value: 'dark' },
],
},
{
name: 'padding',
type: 'select',
defaultValue: 'none',
label: 'Außenabstand',
options: [
{ label: 'Keiner', value: 'none' },
{ label: 'Klein', value: 'sm' },
{ label: 'Normal', value: 'md' },
{ label: 'Groß', value: 'lg' },
],
},
],
},
// Accessibility
{
name: 'a11y',
type: 'group',
label: 'Barrierefreiheit',
fields: [
{
name: 'label',
type: 'text',
defaultValue: 'Bildergalerie',
label: 'ARIA Label',
localized: true,
},
{
name: 'reducedMotion',
type: 'checkbox',
defaultValue: true,
label: 'Reduzierte Bewegung respektieren',
},
],
},
],
}

View file

@ -1,5 +1,6 @@
export { HeroBlock } from './HeroBlock'
export { HeroSliderBlock } from './HeroSliderBlock'
export { ImageSliderBlock } from './ImageSliderBlock'
export { TextBlock } from './TextBlock'
export { ImageTextBlock } from './ImageTextBlock'
export { CardGridBlock } from './CardGridBlock'

View file

@ -2,6 +2,7 @@ import type { CollectionConfig } from 'payload'
import {
HeroBlock,
HeroSliderBlock,
ImageSliderBlock,
TextBlock,
ImageTextBlock,
CardGridBlock,
@ -75,6 +76,7 @@ export const Pages: CollectionConfig = {
// Bestehende Blocks
HeroBlock,
HeroSliderBlock,
ImageSliderBlock,
TextBlock,
ImageTextBlock,
CardGridBlock,

View file

@ -0,0 +1,224 @@
import { MigrateUpArgs, MigrateDownArgs, sql } from '@payloadcms/db-postgres'
/**
* Migration: ImageSliderBlock
*
* Erstellt den ImageSliderBlock für Bildergalerien mit:
* - Verschiedenen Layouts (Slider, Grid, Masonry)
* - Lightbox-Funktion
* - Flexible Slider-Optionen
* - Styling und Navigation
*/
export async function up({ db }: MigrateUpArgs): Promise<void> {
// Create enums
await db.execute(sql`
-- Layout
CREATE TYPE "enum_pages_blocks_image_slider_block_layout" AS ENUM('slider', 'grid', 'masonry', 'single', 'thumbs', 'filmstrip');
-- Grid
CREATE TYPE "enum_pages_blocks_image_slider_block_grid_cols" AS ENUM('2', '3', '4', '5', '6');
CREATE TYPE "enum_pages_blocks_image_slider_block_grid_gap" AS ENUM('0', '8', '16', '24', '32');
CREATE TYPE "enum_pages_blocks_image_slider_block_grid_aspect" AS ENUM('square', '4-3', '16-9', '3-4', 'auto');
-- Slider
CREATE TYPE "enum_pages_blocks_image_slider_block_slider_effect" AS ENUM('slide', 'fade', 'zoom', 'flip', 'coverflow', 'cube');
CREATE TYPE "enum_pages_blocks_image_slider_block_slider_speed" AS ENUM('300', '500', '800');
CREATE TYPE "enum_pages_blocks_image_slider_block_slider_per_view" AS ENUM('1', '2', '3', '4', 'auto');
CREATE TYPE "enum_pages_blocks_image_slider_block_slider_gap" AS ENUM('0', '8', '16', '24');
CREATE TYPE "enum_pages_blocks_image_slider_block_slider_delay" AS ENUM('3000', '4000', '5000', '6000', '8000');
-- Navigation
CREATE TYPE "enum_pages_blocks_image_slider_block_nav_arrow_style" AS ENUM('default', 'minimal', 'square', 'hover');
CREATE TYPE "enum_pages_blocks_image_slider_block_nav_dot_style" AS ENUM('dots', 'lines', 'numbers', 'progress');
-- Lightbox
CREATE TYPE "enum_pages_blocks_image_slider_block_lightbox_bg" AS ENUM('dark', 'light', 'blur');
-- Style
CREATE TYPE "enum_pages_blocks_image_slider_block_style_height" AS ENUM('auto', '300', '400', '500', '600', 'full');
CREATE TYPE "enum_pages_blocks_image_slider_block_style_img_fit" AS ENUM('cover', 'contain', 'fill');
CREATE TYPE "enum_pages_blocks_image_slider_block_style_rounded" AS ENUM('none', 'sm', 'md', 'lg', 'full');
CREATE TYPE "enum_pages_blocks_image_slider_block_style_hover" AS ENUM('none', 'zoom', 'brighten', 'darken', 'overlay');
CREATE TYPE "enum_pages_blocks_image_slider_block_style_caption" AS ENUM('below', 'overlay', 'hover', 'hidden');
CREATE TYPE "enum_pages_blocks_image_slider_block_style_bg" AS ENUM('none', 'white', 'light', 'dark');
CREATE TYPE "enum_pages_blocks_image_slider_block_style_padding" AS ENUM('none', 'sm', 'md', 'lg');
`)
// Create images array table
await db.execute(sql`
CREATE TABLE "pages_blocks_image_slider_block_images" (
"_order" integer NOT NULL,
"_parent_id" varchar NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
"image_id" integer NOT NULL,
"link" varchar
);
`)
// Create images locales table
await db.execute(sql`
CREATE TABLE "pages_blocks_image_slider_block_images_locales" (
"caption" varchar,
"alt" varchar,
"id" serial PRIMARY KEY NOT NULL,
"_locale" "_locales" NOT NULL,
"_parent_id" varchar NOT NULL
);
`)
// Create main block table
await db.execute(sql`
CREATE TABLE "pages_blocks_image_slider_block" (
"_order" integer NOT NULL,
"_parent_id" integer NOT NULL,
"_path" text NOT NULL,
"id" varchar PRIMARY KEY NOT NULL,
-- Layout
"layout" "enum_pages_blocks_image_slider_block_layout" DEFAULT 'slider',
-- Grid settings
"grid_cols" "enum_pages_blocks_image_slider_block_grid_cols" DEFAULT '3',
"grid_gap" "enum_pages_blocks_image_slider_block_grid_gap" DEFAULT '16',
"grid_aspect_ratio" "enum_pages_blocks_image_slider_block_grid_aspect" DEFAULT 'square',
-- Slider settings
"slider_effect" "enum_pages_blocks_image_slider_block_slider_effect" DEFAULT 'slide',
"slider_speed" "enum_pages_blocks_image_slider_block_slider_speed" DEFAULT '500',
"slider_per_view" "enum_pages_blocks_image_slider_block_slider_per_view" DEFAULT '1',
"slider_gap" "enum_pages_blocks_image_slider_block_slider_gap" DEFAULT '0',
"slider_auto" boolean DEFAULT false,
"slider_delay" "enum_pages_blocks_image_slider_block_slider_delay" DEFAULT '4000',
"slider_pause_hover" boolean DEFAULT true,
"slider_loop" boolean DEFAULT true,
"slider_centered" boolean DEFAULT false,
-- Navigation
"nav_arrows" boolean DEFAULT true,
"nav_arrow_style" "enum_pages_blocks_image_slider_block_nav_arrow_style" DEFAULT 'default',
"nav_dots" boolean DEFAULT true,
"nav_dot_style" "enum_pages_blocks_image_slider_block_nav_dot_style" DEFAULT 'dots',
"nav_counter" boolean DEFAULT false,
"nav_swipe" boolean DEFAULT true,
"nav_keys" boolean DEFAULT true,
-- Lightbox
"lightbox_enabled" boolean DEFAULT true,
"lightbox_zoom" boolean DEFAULT true,
"lightbox_download" boolean DEFAULT false,
"lightbox_share" boolean DEFAULT false,
"lightbox_captions" boolean DEFAULT true,
"lightbox_thumbs" boolean DEFAULT true,
"lightbox_bg" "enum_pages_blocks_image_slider_block_lightbox_bg" DEFAULT 'dark',
-- Style
"style_height" "enum_pages_blocks_image_slider_block_style_height" DEFAULT 'auto',
"style_img_fit" "enum_pages_blocks_image_slider_block_style_img_fit" DEFAULT 'cover',
"style_rounded" "enum_pages_blocks_image_slider_block_style_rounded" DEFAULT 'none',
"style_shadow" boolean DEFAULT false,
"style_border" boolean DEFAULT false,
"style_hover_effect" "enum_pages_blocks_image_slider_block_style_hover" DEFAULT 'none',
"style_caption_pos" "enum_pages_blocks_image_slider_block_style_caption" DEFAULT 'below',
"style_bg" "enum_pages_blocks_image_slider_block_style_bg" DEFAULT 'none',
"style_padding" "enum_pages_blocks_image_slider_block_style_padding" DEFAULT 'none',
-- Accessibility
"a11y_reduced_motion" boolean DEFAULT true,
"block_name" varchar
);
`)
// Create locales table
await db.execute(sql`
CREATE TABLE "pages_blocks_image_slider_block_locales" (
"title" varchar,
"description" varchar,
"a11y_label" varchar DEFAULT 'Bildergalerie',
"id" serial PRIMARY KEY NOT NULL,
"_locale" "_locales" NOT NULL,
"_parent_id" varchar NOT NULL
);
`)
// Add foreign keys and indexes
await db.execute(sql`
-- Images table
ALTER TABLE "pages_blocks_image_slider_block_images"
ADD CONSTRAINT "pages_blocks_image_slider_block_images_image_id_fk"
FOREIGN KEY ("image_id") REFERENCES "public"."media"("id") ON DELETE set null ON UPDATE no action;
ALTER TABLE "pages_blocks_image_slider_block_images"
ADD CONSTRAINT "pages_blocks_image_slider_block_images_parent_id_fk"
FOREIGN KEY ("_parent_id") REFERENCES "public"."pages_blocks_image_slider_block"("id") ON DELETE cascade ON UPDATE no action;
CREATE INDEX "pages_blocks_image_slider_block_images_order_idx"
ON "pages_blocks_image_slider_block_images" USING btree ("_order");
CREATE INDEX "pages_blocks_image_slider_block_images_parent_id_idx"
ON "pages_blocks_image_slider_block_images" USING btree ("_parent_id");
CREATE INDEX "pages_blocks_image_slider_block_images_image_idx"
ON "pages_blocks_image_slider_block_images" USING btree ("image_id");
-- Images locales table
ALTER TABLE "pages_blocks_image_slider_block_images_locales"
ADD CONSTRAINT "pages_blocks_image_slider_block_images_locales_parent_fk"
FOREIGN KEY ("_parent_id") REFERENCES "public"."pages_blocks_image_slider_block_images"("id") ON DELETE cascade ON UPDATE no action;
CREATE UNIQUE INDEX "pages_blocks_image_slider_block_images_locales_uniq"
ON "pages_blocks_image_slider_block_images_locales" USING btree ("_locale", "_parent_id");
-- Main block table
ALTER TABLE "pages_blocks_image_slider_block"
ADD CONSTRAINT "pages_blocks_image_slider_block_parent_id_fk"
FOREIGN KEY ("_parent_id") REFERENCES "public"."pages"("id") ON DELETE cascade ON UPDATE no action;
CREATE INDEX "pages_blocks_image_slider_block_order_idx"
ON "pages_blocks_image_slider_block" USING btree ("_order");
CREATE INDEX "pages_blocks_image_slider_block_parent_id_idx"
ON "pages_blocks_image_slider_block" USING btree ("_parent_id");
CREATE INDEX "pages_blocks_image_slider_block_path_idx"
ON "pages_blocks_image_slider_block" USING btree ("_path");
-- Locales table
ALTER TABLE "pages_blocks_image_slider_block_locales"
ADD CONSTRAINT "pages_blocks_image_slider_block_locales_parent_id_fk"
FOREIGN KEY ("_parent_id") REFERENCES "public"."pages_blocks_image_slider_block"("id") ON DELETE cascade ON UPDATE no action;
CREATE UNIQUE INDEX "pages_blocks_image_slider_block_locales_locale_parent_uniq"
ON "pages_blocks_image_slider_block_locales" USING btree ("_locale", "_parent_id");
`)
}
export async function down({ db }: MigrateDownArgs): Promise<void> {
// Drop tables
await db.execute(sql`
DROP TABLE IF EXISTS "pages_blocks_image_slider_block_images_locales" CASCADE;
DROP TABLE IF EXISTS "pages_blocks_image_slider_block_images" CASCADE;
DROP TABLE IF EXISTS "pages_blocks_image_slider_block_locales" CASCADE;
DROP TABLE IF EXISTS "pages_blocks_image_slider_block" CASCADE;
`)
// Drop enums
await db.execute(sql`
DROP TYPE IF EXISTS "enum_pages_blocks_image_slider_block_layout";
DROP TYPE IF EXISTS "enum_pages_blocks_image_slider_block_grid_cols";
DROP TYPE IF EXISTS "enum_pages_blocks_image_slider_block_grid_gap";
DROP TYPE IF EXISTS "enum_pages_blocks_image_slider_block_grid_aspect";
DROP TYPE IF EXISTS "enum_pages_blocks_image_slider_block_slider_effect";
DROP TYPE IF EXISTS "enum_pages_blocks_image_slider_block_slider_speed";
DROP TYPE IF EXISTS "enum_pages_blocks_image_slider_block_slider_per_view";
DROP TYPE IF EXISTS "enum_pages_blocks_image_slider_block_slider_gap";
DROP TYPE IF EXISTS "enum_pages_blocks_image_slider_block_slider_delay";
DROP TYPE IF EXISTS "enum_pages_blocks_image_slider_block_nav_arrow_style";
DROP TYPE IF EXISTS "enum_pages_blocks_image_slider_block_nav_dot_style";
DROP TYPE IF EXISTS "enum_pages_blocks_image_slider_block_lightbox_bg";
DROP TYPE IF EXISTS "enum_pages_blocks_image_slider_block_style_height";
DROP TYPE IF EXISTS "enum_pages_blocks_image_slider_block_style_img_fit";
DROP TYPE IF EXISTS "enum_pages_blocks_image_slider_block_style_rounded";
DROP TYPE IF EXISTS "enum_pages_blocks_image_slider_block_style_hover";
DROP TYPE IF EXISTS "enum_pages_blocks_image_slider_block_style_caption";
DROP TYPE IF EXISTS "enum_pages_blocks_image_slider_block_style_bg";
DROP TYPE IF EXISTS "enum_pages_blocks_image_slider_block_style_padding";
`)
}

View file

@ -536,6 +536,85 @@ export interface Page {
blockName?: string | null;
blockType: 'hero-slider-block';
}
| {
/**
* Optionaler Titel über der Galerie
*/
title?: string | null;
description?: string | null;
/**
* Mindestens 1 Bild, maximal 50 Bilder
*/
images: {
image: number | Media;
caption?: string | null;
/**
* Alternativer Text für Barrierefreiheit (falls abweichend vom Media Alt)
*/
alt?: string | null;
/**
* Optionaler Link beim Klick (statt Lightbox)
*/
link?: string | null;
id?: string | null;
}[];
layout?: ('slider' | 'grid' | 'masonry' | 'single' | 'thumbs' | 'filmstrip') | null;
grid?: {
cols?: ('2' | '3' | '4' | '5' | '6') | null;
gap?: ('0' | '8' | '16' | '24' | '32') | null;
aspectRatio?: ('square' | '4-3' | '16-9' | '3-4' | 'auto') | null;
};
slider?: {
effect?: ('slide' | 'fade' | 'zoom' | 'flip' | 'coverflow' | 'cube') | null;
speed?: ('300' | '500' | '800') | null;
perView?: ('1' | '2' | '3' | '4' | 'auto') | null;
gap?: ('0' | '8' | '16' | '24') | null;
auto?: boolean | null;
delay?: ('3000' | '4000' | '5000' | '6000' | '8000') | null;
pauseHover?: boolean | null;
loop?: boolean | null;
centered?: boolean | null;
};
nav?: {
arrows?: boolean | null;
arrowStyle?: ('default' | 'minimal' | 'square' | 'hover') | null;
dots?: boolean | null;
dotStyle?: ('dots' | 'lines' | 'numbers' | 'progress') | null;
counter?: boolean | null;
swipe?: boolean | null;
keys?: boolean | null;
};
lightbox?: {
/**
* Bilder bei Klick in Vollansicht öffnen
*/
enabled?: boolean | null;
zoom?: boolean | null;
download?: boolean | null;
share?: boolean | null;
captions?: boolean | null;
thumbs?: boolean | null;
bg?: ('dark' | 'light' | 'blur') | null;
};
style?: {
height?: ('auto' | '300' | '400' | '500' | '600' | 'full') | null;
imgFit?: ('cover' | 'contain' | 'fill') | null;
rounded?: ('none' | 'sm' | 'md' | 'lg' | 'full') | null;
shadow?: boolean | null;
border?: boolean | null;
hoverEffect?: ('none' | 'zoom' | 'brighten' | 'darken' | 'overlay') | null;
captionPos?: ('below' | 'overlay' | 'hover' | 'hidden') | null;
bg?: ('none' | 'white' | 'light' | 'dark') | null;
padding?: ('none' | 'sm' | 'md' | 'lg') | null;
};
a11y?: {
label?: string | null;
reducedMotion?: boolean | null;
};
id?: string | null;
blockName?: string | null;
blockType: 'image-slider-block';
}
| {
content: {
root: {
@ -3419,6 +3498,85 @@ export interface PagesSelect<T extends boolean = true> {
id?: T;
blockName?: T;
};
'image-slider-block'?:
| T
| {
title?: T;
description?: T;
images?:
| T
| {
image?: T;
caption?: T;
alt?: T;
link?: T;
id?: T;
};
layout?: T;
grid?:
| T
| {
cols?: T;
gap?: T;
aspectRatio?: T;
};
slider?:
| T
| {
effect?: T;
speed?: T;
perView?: T;
gap?: T;
auto?: T;
delay?: T;
pauseHover?: T;
loop?: T;
centered?: T;
};
nav?:
| T
| {
arrows?: T;
arrowStyle?: T;
dots?: T;
dotStyle?: T;
counter?: T;
swipe?: T;
keys?: T;
};
lightbox?:
| T
| {
enabled?: T;
zoom?: T;
download?: T;
share?: T;
captions?: T;
thumbs?: T;
bg?: T;
};
style?:
| T
| {
height?: T;
imgFit?: T;
rounded?: T;
shadow?: T;
border?: T;
hoverEffect?: T;
captionPos?: T;
bg?: T;
padding?: T;
};
a11y?:
| T
| {
label?: T;
reducedMotion?: T;
};
id?: T;
blockName?: T;
};
'text-block'?:
| T
| {