Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { BlockEventbrite } from '~content-blocks/BlockEventbrite';
import { BlockHeading } from '~content-blocks/BlockHeading';
import { BlockHetArchiefHeaderSearch } from '~content-blocks/BlockHetArchiefHeaderSearch/BlockHetArchiefHeaderSearch';
import { BlockHetArchiefImageTextBackground } from '~content-blocks/BlockHetArchiefImageTextBackground';
import { BlockHomepageBanner } from '~content-blocks/BlockHomepageBanner';
import { BlockIFrame } from '~content-blocks/BlockIFrame';
import { BlockImage } from '~content-blocks/BlockImage';
import {
Expand Down Expand Up @@ -87,6 +88,7 @@ export function GET_BLOCK_COMPONENT(
[ContentBlockType.Breadcrumbs]: BlockBreadcrumbs,
[ContentBlockType.HetArchiefImageTextBackground]: BlockHetArchiefImageTextBackground,
[ContentBlockType.OverviewWithCarousel]: BlockOverviewWithCarousel,
[ContentBlockType.HomepageBanner]: BlockHomepageBanner,

// Avo specific blocks
[ContentBlockType.MediaGrid]: loadComponentFromConfig(ContentBlockType.MediaGrid),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { BLOCK_FIELD_DEFAULTS, BLOCK_STATE_DEFAULTS, TEXT_FIELD } from '~content-blocks/defaults';
import { GET_ALIGN_OPTIONS } from '~modules/content-page/const/get-align-options.ts';
import { GET_BACKGROUND_COLOR_OPTIONS_ARCHIEF } from '~modules/content-page/const/get-color-options.ts';
import {
Color,
type ContentBlockConfig,
ContentBlockEditor,
ContentBlockType,
type DefaultContentBlockState,
} from '~modules/content-page/types/content-block.types';
import { RICH_TEXT_EDITOR_OPTIONS_FULL } from '~shared/consts/rich-text-editor.consts.ts';
import { tText } from '~shared/helpers/translation-functions';
import { HET_ARCHIEF } from '~shared/types';

export const INITIAL_CONTENT_HOMEPAGE_BANNER_COMPONENTS_STATE = () => ({
title: '',
content: '',
textAlign: 'left',
backgroundColor: Color.Transparent,
bannerColor: Color.OceanGreen,
});

export const INITIAL_CONTENT_HOMEPAGE_BANNER_BLOCK_STATE = (): DefaultContentBlockState => ({
...BLOCK_STATE_DEFAULTS(),
fullWidth: true,
});

export const CONTENT_HOMEPAGE_BANNER_CONFIG = (position = 0): ContentBlockConfig => ({
position,
name: tText(
'modules/content-page/components/blocks/block-homepage-banner/block-homepage-banner___homepage-banner'
),
type: ContentBlockType.HomepageBanner,
components: {
state: INITIAL_CONTENT_HOMEPAGE_BANNER_COMPONENTS_STATE(),
fields: {
title: TEXT_FIELD(
{
label: tText(
'modules/content-page/components/blocks/block-homepage-banner/block-homepage-banner___title',
undefined,
[HET_ARCHIEF]
),
},
tText(
'modules/content-page/components/blocks/block-homepage-banner/block-homepage-banner___titel-is-verplicht',
undefined,
[HET_ARCHIEF]
)
),
content: TEXT_FIELD({
editorType: ContentBlockEditor.RICH_TEXT_EDITOR,
editorProps: {
controls: RICH_TEXT_EDITOR_OPTIONS_FULL,
},
validator: undefined,
}),
textAlign: {
label: tText(
'modules/content-page/components/blocks/block-homepage-banner/block-homepage-banner___text-alignatie',
undefined,
[HET_ARCHIEF]
),
editorType: ContentBlockEditor.Select,
editorProps: {
options: GET_ALIGN_OPTIONS(),
},
},
bannerColor: {
label: tText(
'modules/content-page/components/blocks/block-homepage-banner/block-homepage-banner___kleur-banner',
undefined,
[HET_ARCHIEF]
),
editorType: ContentBlockEditor.ColorSelect,
editorProps: {
options: GET_BACKGROUND_COLOR_OPTIONS_ARCHIEF(),
defaultValue: GET_BACKGROUND_COLOR_OPTIONS_ARCHIEF()[2],
},
},
},
},
block: {
state: INITIAL_CONTENT_HOMEPAGE_BANNER_BLOCK_STATE(),
fields: {
...BLOCK_FIELD_DEFAULTS(),
},
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,226 @@
@use "sass:math";
@use "sass:list";
@use "../../../../shared/styles/settings/variables" as variables;
@use "../../../../shared/styles/settings/colors" as colors;

// Shared shape sizing for the decorative pattern strips (used by --left and --right).
$pattern-height: 8rem;
$pattern-distance-vertical: variables.$g-spacer-unit * 3;
$pattern-distance-horizontal: variables.$g-spacer-unit * 5;

$pattern-rect-width: 4rem;
$pattern-circle-diameter: $pattern-height;
$pattern-circle-radius: math.div($pattern-circle-diameter, 2);
$pattern-circle-antialias-edge: $pattern-circle-radius + 0.02rem;
$pattern-cycle-width: $pattern-rect-width * 2 + $pattern-circle-diameter * 3;
// Must stay a multiple of $pattern-cycle-width (see &__pattern) - generous safety margin
// so the strip always reaches this component's own edge on any realistic viewport.
$pattern-repeat-count: 20;
// How far the mobile pattern slots overshoot &__content's edge, so they can still bleed
// past avo2 Container's (smaller, but non-zero) gutter to the true screen edge.
$pattern-mobile-overshoot: 10rem;

// Renders the repeating tile (3 circles + 2 rects) for one pattern strip. $circle-centers
// is a 3-item list of x-offsets; $rect-ranges is a 2-item list of [start, end] pairs. Both
// sides share this shape/size - only the ORDER (which offsets are passed in) differs.
@mixin pattern-tile($circle-centers, $rect-ranges) {
background-image:
radial-gradient(
circle at list.nth($circle-centers, 1) 50%,
var(--pattern-color, transparent) $pattern-circle-radius,
transparent $pattern-circle-antialias-edge
),
radial-gradient(
circle at list.nth($circle-centers, 2) 50%,
var(--pattern-color, transparent) $pattern-circle-radius,
transparent $pattern-circle-antialias-edge
),
radial-gradient(
circle at list.nth($circle-centers, 3) 50%,
var(--pattern-color, transparent) $pattern-circle-radius,
transparent $pattern-circle-antialias-edge
),
linear-gradient(
to right,
transparent 0 list.nth(list.nth($rect-ranges, 1), 1),
var(--pattern-color, transparent) list.nth(list.nth($rect-ranges, 1), 1) list.nth(list.nth($rect-ranges, 1), 2),
transparent list.nth(list.nth($rect-ranges, 1), 2) list.nth(list.nth($rect-ranges, 2), 1),
var(--pattern-color, transparent) list.nth(list.nth($rect-ranges, 2), 1) list.nth(list.nth($rect-ranges, 2), 2)
);
}

.c-block-homepage-banner {
// The pattern strips escape all the way to this element's edges (and beyond) - clip
// them here. clip-path (not overflow-x: hidden) avoids the overflow-x/y coupling rule
// that would otherwise turn overflow-y into "auto" and risk a vertical scrollbar.
clip-path: inset(0);
width: 100% !important;
max-width: none !important;

&__content {
position: relative;
max-width: 75%;
min-height: $pattern-height;
display: flex;
flex-direction: column;

@media (max-width: variables.$g-bp4) {
// Mobile pattern slots size themselves as a % of this element, so it needs to
// span the full screen width here, not the desktop 75% cap.
max-width: 100%;
// Reserves normal-flow space for the pattern slots above/below the text.
// &__pattern-slot is position: absolute so its height doesn't count towards
// this element's own height - without this padding, .c-block-homepage-banner's
// clip-path would end right at the text and clip the slots away entirely.
padding: calc($pattern-height + $pattern-distance-vertical) 0;
}

&--left {
margin-right: auto;

.c-block-homepage-banner__pattern--right {
left: calc(100% + $pattern-distance-horizontal + $pattern-distance-horizontal);
}
}

&--center {
margin: 0 auto;
}

&--right {
margin-left: auto;

.c-block-homepage-banner__pattern--left{
right: calc(100% + $pattern-distance-horizontal + $pattern-distance-horizontal);
}
}

&-title {
padding-bottom: variables.$g-spacer-unit * 4;
color: colors.$color-gray-1000;

/* H4 */
font-family: "SofiaPro" !important;
font-size: 3.2rem !important;
font-style: normal !important;
font-weight: 800 !important;
line-height: 4rem !important;
width: 100%;
white-space: wrap;
}

&-text {
color: colors.$neutral;

/* H4 */
font-family: "SofiaPro" !important;
font-size: 1.8rem !important;
font-style: normal !important;
font-weight: 500 !important;
line-height: 2.8rem !important;
}
}

// Anchored off the text box's own edge (not Container's), so the $pattern-distance-horizontal gap holds
// regardless of alignment or actual (up to 75%) text width.
//
// width MUST be a multiple of $pattern-cycle-width: Chrome has a rendering bug where a
// repeating multi-layer gradient tears in the middle of the element when its width
// isn't an exact multiple of background-size (100vw reproduces this reliably).
//
// --left/--right are two DIFFERENT tiles (not one tile phase-shifted via
// background-position - that proved unreliable), each built so the desired near-text
// shape sits naturally at the tile's own edge, anchored via a plain
// background-position-x: right / left (no offset):
// - left: rect, circle, rect, [circle, circle, rect, circle, ...]
// - right: circle, rect, circle, circle, [rect, circle, circle, rect, circle, ...]
&__pattern {
position: absolute;
top: 0;
bottom: 0;
width: $pattern-cycle-width * $pattern-repeat-count;
background-repeat: repeat-x;
background-position-y: top;
background-size: $pattern-cycle-width $pattern-height;

&--left {
right: calc(100% + $pattern-distance-horizontal);
background-position-x: right;
@include pattern-tile(
(
$pattern-circle-radius,
$pattern-circle-diameter + $pattern-circle-radius,
$pattern-circle-diameter * 2 + $pattern-rect-width + $pattern-circle-radius,
),
(
($pattern-circle-diameter * 2, $pattern-circle-diameter * 2 + $pattern-rect-width),
($pattern-circle-diameter * 3 + $pattern-rect-width, $pattern-cycle-width),
)
);
}

&--right {
left: calc(100% + $pattern-distance-horizontal);
background-position-x: left;
@include pattern-tile(
(
$pattern-circle-radius,
$pattern-circle-diameter + $pattern-rect-width + $pattern-circle-radius,
$pattern-circle-diameter * 2 + $pattern-rect-width + $pattern-circle-radius,
),
(
($pattern-circle-diameter, $pattern-circle-diameter + $pattern-rect-width),
($pattern-circle-diameter * 3 + $pattern-rect-width, $pattern-cycle-width),
)
);
}

// Below $g-bp4 the patterns move from beside the text to above/below it (see
// &__pattern-slot). Same tile/anchor as desktop - only the anchor's landmark moves
// from "near text" to the slot's inner (1/3 or 2/3) edge; top/bottom: 0 is already
// set above.
@media (max-width: variables.$g-bp4) {
&--left {
right: 0;
left: auto;
}

&--right {
left: 0;
right: auto;
}
}
}

// No-op on desktop (unpositioned - &__pattern's position: absolute reaches past it to
// &__content). Below $g-bp4 it's the positioned, overflow-clipping box that caps
// &__pattern at exactly 1/3 (top) / 2/3 (bottom) of &__content's width. This cap can't
// live on &__pattern itself: capping its width there would make it a non-multiple of
// $pattern-cycle-width again (see the Chrome bug above).
&__pattern-slot {
@media (max-width: variables.$g-bp4) {
position: absolute;
overflow: hidden;
height: $pattern-height;

// top/bottom: 0 land inside &__content's reserved padding, not against its
// content-box - literal zero offsets, so (unlike the desktop calc(100% + $pattern-distance-horizontal)
// trick) they don't need &__content to have a definite height to resolve.
//
// left/right overshoot by $pattern-mobile-overshoot to reach past avo2
// Container's gutter to the true screen edge; width compensates so the INNER
// edge (the anchor landmark) stays exactly at 1/3 / 2/3.
&--top {
top: 0;
left: -$pattern-mobile-overshoot;
width: calc(33.333% + #{$pattern-mobile-overshoot});
}

&--bottom {
bottom: 0;
right: -$pattern-mobile-overshoot;
width: calc(66.667% + #{$pattern-mobile-overshoot});
}
}
}
}
Loading