@kitconcept/volto-light-theme 7.0.0-alpha.19 → 7.0.0-alpha.20
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.draft +5 -7
- package/CHANGELOG.md +10 -0
- package/package.json +4 -2
- package/src/components/Blocks/Slider/DefaultBody.jsx +1 -0
- package/src/components/Blocks/Slider/SliderVariants.jsx +152 -0
- package/src/components/Blocks/Slider/View.jsx +179 -0
- package/src/components/StickyMenu/StickyMenu.tsx +2 -0
- package/src/config/blocks.tsx +36 -0
- package/src/customizations/@kitconcept/volto-slider-block/components/View.jsx +11 -0
- package/src/primitives/IconLinkList.tsx +1 -4
- package/src/theme/blocks/_slider.scss +264 -15
package/.changelog.draft
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
## 7.0.0-alpha.
|
|
1
|
+
## 7.0.0-alpha.20 (2025-07-29)
|
|
2
2
|
|
|
3
|
-
###
|
|
3
|
+
### Feature
|
|
4
4
|
|
|
5
|
-
-
|
|
5
|
+
- Added Slider Variations @Tishasoumya-02
|
|
6
6
|
|
|
7
|
-
###
|
|
7
|
+
### Bugfix
|
|
8
8
|
|
|
9
|
-
-
|
|
10
|
-
- Fix alt tag fallback to title if srcAlt is missing in IconLinkList @iRohitSingh [#620](https://github.com/kitconcept/volto-light-theme/pull/620)
|
|
11
|
-
- Use volto-dsgvo-banner 2.5.1 @sneridagh
|
|
9
|
+
- Fix alt tag fallback in IconLinkList @iRohitSingh [#621](https://github.com/kitconcept/volto-light-theme/pull/621)
|
|
12
10
|
|
|
13
11
|
|
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,16 @@
|
|
|
8
8
|
|
|
9
9
|
<!-- towncrier release notes start -->
|
|
10
10
|
|
|
11
|
+
## 7.0.0-alpha.20 (2025-07-29)
|
|
12
|
+
|
|
13
|
+
### Feature
|
|
14
|
+
|
|
15
|
+
- Added Slider Variations @Tishasoumya-02
|
|
16
|
+
|
|
17
|
+
### Bugfix
|
|
18
|
+
|
|
19
|
+
- Fix alt tag fallback in IconLinkList @iRohitSingh [#621](https://github.com/kitconcept/volto-light-theme/pull/621)
|
|
20
|
+
|
|
11
21
|
## 7.0.0-alpha.19 (2025-07-25)
|
|
12
22
|
|
|
13
23
|
### Bugfix
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kitconcept/volto-light-theme",
|
|
3
|
-
"version": "7.0.0-alpha.
|
|
3
|
+
"version": "7.0.0-alpha.20",
|
|
4
4
|
"description": "Volto Light Theme by kitconcept",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"types": "src/index.ts",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"typescript": "^5.7.3",
|
|
43
43
|
"release-it": "^19.0.3",
|
|
44
44
|
"vitest": "^3.1.2",
|
|
45
|
-
"@plone/types": "1.4.
|
|
45
|
+
"@plone/types": "1.4.1"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
48
|
"@dnd-kit/core": "6.0.8",
|
|
@@ -52,6 +52,8 @@
|
|
|
52
52
|
"react-aria-components": "^1.7.0",
|
|
53
53
|
"react-colorful": "^5.6.1",
|
|
54
54
|
"uuid": "^11.0.0",
|
|
55
|
+
"embla-carousel-autoplay": "^8.0.0",
|
|
56
|
+
"embla-carousel-react": "^8.0.0",
|
|
55
57
|
"@plone/components": "^3.0.2"
|
|
56
58
|
},
|
|
57
59
|
"peerDependencies": {
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { useIntl, defineMessages } from 'react-intl';
|
|
3
|
+
import Icon from '@plone/volto/components/theme/Icon/Icon';
|
|
4
|
+
import MaybeWrap from '@plone/volto/components/manage/MaybeWrap/MaybeWrap';
|
|
5
|
+
import UniversalLink from '@plone/volto/components/manage/UniversalLink/UniversalLink';
|
|
6
|
+
import { Input, Button, Message } from 'semantic-ui-react';
|
|
7
|
+
import { isInternalURL } from '@plone/volto/helpers/Url/Url';
|
|
8
|
+
import cx from 'classnames';
|
|
9
|
+
import navTreeSVG from '@plone/volto/icons/nav.svg';
|
|
10
|
+
import imageBlockSVG from '@plone/volto/components/manage/Blocks/Image/block-image.svg';
|
|
11
|
+
import config from '@plone/volto/registry';
|
|
12
|
+
|
|
13
|
+
const messages = defineMessages({
|
|
14
|
+
PleaseChooseContent: {
|
|
15
|
+
id: 'Please choose an existing content as source for this element',
|
|
16
|
+
defaultMessage:
|
|
17
|
+
'Please choose an existing content as source for this element',
|
|
18
|
+
},
|
|
19
|
+
moreInfo: {
|
|
20
|
+
id: 'moreInfo',
|
|
21
|
+
defaultMessage: 'More info',
|
|
22
|
+
},
|
|
23
|
+
source: {
|
|
24
|
+
id: 'Source',
|
|
25
|
+
defaultMessage: 'Source',
|
|
26
|
+
},
|
|
27
|
+
ButtonText: {
|
|
28
|
+
id: 'Continue reading',
|
|
29
|
+
defaultMessage: 'Continue reading',
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const DefaultImage = (props) => <img {...props} alt={props.alt || ''} />;
|
|
34
|
+
|
|
35
|
+
const SliderVariants = ({
|
|
36
|
+
index,
|
|
37
|
+
onChangeBlock,
|
|
38
|
+
block,
|
|
39
|
+
data,
|
|
40
|
+
dataBlock,
|
|
41
|
+
isEditMode,
|
|
42
|
+
openObjectBrowser,
|
|
43
|
+
}) => {
|
|
44
|
+
const intl = useIntl();
|
|
45
|
+
const href = data.href?.[0];
|
|
46
|
+
const image = data.preview_image?.[0];
|
|
47
|
+
|
|
48
|
+
const Image = config.getComponent('Image').component || DefaultImage;
|
|
49
|
+
const { openExternalLinkInNewTab } = config.settings;
|
|
50
|
+
|
|
51
|
+
const handleClick = () => {
|
|
52
|
+
openObjectBrowser({
|
|
53
|
+
onSelectItem: (url, document) => {
|
|
54
|
+
dataBlock.slides[index].title = document.Title;
|
|
55
|
+
dataBlock.slides[index].description = document.Description;
|
|
56
|
+
dataBlock.slides[index].href = [
|
|
57
|
+
{
|
|
58
|
+
'@id': document['@id'],
|
|
59
|
+
Title: document.Title,
|
|
60
|
+
Description: document.Description,
|
|
61
|
+
title: document.Title,
|
|
62
|
+
image_field: document.image_field,
|
|
63
|
+
hasPreviewImage: document.hasPreviewImage,
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
onChangeBlock(block, dataBlock);
|
|
67
|
+
},
|
|
68
|
+
mode: 'link',
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<div
|
|
74
|
+
className={cx('grid-teaser-item top', {
|
|
75
|
+
'empty-slide': !href && isEditMode,
|
|
76
|
+
})}
|
|
77
|
+
>
|
|
78
|
+
{!href && isEditMode && (
|
|
79
|
+
<Message>
|
|
80
|
+
<div className="grid-teaser-item default">
|
|
81
|
+
<img src={imageBlockSVG} alt="" />
|
|
82
|
+
<p>{intl.formatMessage(messages.PleaseChooseContent)}</p>
|
|
83
|
+
<div className="toolbar-inner">
|
|
84
|
+
<Button.Group>
|
|
85
|
+
<Button onClick={handleClick} icon basic>
|
|
86
|
+
<Icon name={navTreeSVG} size="24px" />
|
|
87
|
+
</Button>
|
|
88
|
+
</Button.Group>
|
|
89
|
+
<Input
|
|
90
|
+
placeholder={`${intl.formatMessage(messages.source)}...`}
|
|
91
|
+
onClick={handleClick}
|
|
92
|
+
onFocus={(e) => e.target.blur()}
|
|
93
|
+
/>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
</Message>
|
|
97
|
+
)}
|
|
98
|
+
{href && (
|
|
99
|
+
<MaybeWrap
|
|
100
|
+
condition={!isEditMode}
|
|
101
|
+
as={UniversalLink}
|
|
102
|
+
href={href['@id']}
|
|
103
|
+
className="link-container"
|
|
104
|
+
target={
|
|
105
|
+
data.openLinkInNewTab ||
|
|
106
|
+
(openExternalLinkInNewTab && !isInternalURL(href['@id']))
|
|
107
|
+
? '_blank'
|
|
108
|
+
: null
|
|
109
|
+
}
|
|
110
|
+
tabIndex="-1"
|
|
111
|
+
>
|
|
112
|
+
<div
|
|
113
|
+
className={cx(
|
|
114
|
+
'teaser-item top',
|
|
115
|
+
`has--slider--flagAlign--${data.flagAlign}`,
|
|
116
|
+
dataBlock.variation,
|
|
117
|
+
)}
|
|
118
|
+
>
|
|
119
|
+
{(href?.hasPreviewImage || href.image_field || image) && (
|
|
120
|
+
<div className="highlight-image-wrapper gradient">
|
|
121
|
+
<Image
|
|
122
|
+
item={image || href}
|
|
123
|
+
imageField={image ? image.image_field : href.image_field}
|
|
124
|
+
alt=""
|
|
125
|
+
loading="lazy"
|
|
126
|
+
responsive={true}
|
|
127
|
+
/>
|
|
128
|
+
</div>
|
|
129
|
+
)}
|
|
130
|
+
<div className="teaser-item-title fix-width-issue">
|
|
131
|
+
<div className="title">
|
|
132
|
+
{data?.head_title && (
|
|
133
|
+
<span className="supertitle">{data?.head_title}</span>
|
|
134
|
+
)}
|
|
135
|
+
<h2>{data?.nav_title || data?.title}</h2>
|
|
136
|
+
</div>
|
|
137
|
+
<p>{data?.description}</p>
|
|
138
|
+
|
|
139
|
+
{!data.hideButton && (
|
|
140
|
+
<Button tabIndex={'-1'}>
|
|
141
|
+
{data.buttonText || intl.formatMessage(messages.ButtonText)}
|
|
142
|
+
</Button>
|
|
143
|
+
)}
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
</MaybeWrap>
|
|
147
|
+
)}
|
|
148
|
+
</div>
|
|
149
|
+
);
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
export default SliderVariants;
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import React, { useCallback, useEffect, useState } from 'react';
|
|
2
|
+
import { Message } from 'semantic-ui-react';
|
|
3
|
+
import useEmblaCarousel from 'embla-carousel-react';
|
|
4
|
+
import Autoplay from 'embla-carousel-autoplay';
|
|
5
|
+
import cx from 'classnames';
|
|
6
|
+
import { defineMessages, useIntl } from 'react-intl';
|
|
7
|
+
import Body from '@kitconcept/volto-slider-block/components/Body';
|
|
8
|
+
import withBlockExtensions from '@plone/volto/helpers/Extensions/withBlockExtensions';
|
|
9
|
+
import {
|
|
10
|
+
DotButton,
|
|
11
|
+
NextButton,
|
|
12
|
+
PrevButton,
|
|
13
|
+
} from '@kitconcept/volto-slider-block/components/DotsAndArrows';
|
|
14
|
+
import teaserTemplate from '@kitconcept/volto-slider-block/icons/teaser-template.svg';
|
|
15
|
+
|
|
16
|
+
const messages = defineMessages({
|
|
17
|
+
PleaseChooseContent: {
|
|
18
|
+
id: 'Please choose an existing content as source for this element',
|
|
19
|
+
defaultMessage:
|
|
20
|
+
'Please choose an existing content as source for this element',
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
const SliderView = (props) => {
|
|
25
|
+
const {
|
|
26
|
+
className,
|
|
27
|
+
data,
|
|
28
|
+
isEditMode = false,
|
|
29
|
+
block,
|
|
30
|
+
openObjectBrowser,
|
|
31
|
+
onChangeBlock,
|
|
32
|
+
slideIndex,
|
|
33
|
+
setSlideIndex,
|
|
34
|
+
} = props;
|
|
35
|
+
const intl = useIntl();
|
|
36
|
+
|
|
37
|
+
const [prevBtnDisabled, setPrevBtnDisabled] = useState(true);
|
|
38
|
+
const [nextBtnDisabled, setNextBtnDisabled] = useState(true);
|
|
39
|
+
const [selectedIndex, setSelectedIndex] = useState(0);
|
|
40
|
+
const [scrollSnaps, setScrollSnaps] = useState([]);
|
|
41
|
+
const autoplay =
|
|
42
|
+
data.autoplayEnabled !== undefined ? data.autoplayEnabled : false;
|
|
43
|
+
const autoplayOptions = {
|
|
44
|
+
delay: data.autoplayDelay,
|
|
45
|
+
jump: data.autoplayJump,
|
|
46
|
+
};
|
|
47
|
+
const plugins = isEditMode ? [] : autoplay ? [Autoplay(autoplayOptions)] : [];
|
|
48
|
+
|
|
49
|
+
const [emblaRef, emblaApi] = useEmblaCarousel({ loop: true }, plugins);
|
|
50
|
+
|
|
51
|
+
const scrollPrev = useCallback(() => {
|
|
52
|
+
if (emblaApi) {
|
|
53
|
+
emblaApi.scrollPrev();
|
|
54
|
+
setSlideIndex && setSlideIndex(selectedIndex - 1);
|
|
55
|
+
}
|
|
56
|
+
}, [emblaApi, selectedIndex, setSlideIndex]);
|
|
57
|
+
|
|
58
|
+
const scrollNext = useCallback(() => {
|
|
59
|
+
if (emblaApi) {
|
|
60
|
+
emblaApi.scrollNext();
|
|
61
|
+
setSlideIndex && setSlideIndex(selectedIndex + 1);
|
|
62
|
+
}
|
|
63
|
+
}, [emblaApi, selectedIndex, setSlideIndex]);
|
|
64
|
+
|
|
65
|
+
const scrollTo = useCallback(
|
|
66
|
+
(index) => {
|
|
67
|
+
if (emblaApi) {
|
|
68
|
+
emblaApi.scrollTo(index);
|
|
69
|
+
setSlideIndex && setSlideIndex(index);
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
[emblaApi, setSlideIndex],
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
const onInit = useCallback((emblaApi) => {
|
|
76
|
+
setScrollSnaps(emblaApi.scrollSnapList());
|
|
77
|
+
}, []);
|
|
78
|
+
|
|
79
|
+
const onSelect = useCallback((emblaApi) => {
|
|
80
|
+
setSelectedIndex(emblaApi.selectedScrollSnap());
|
|
81
|
+
setPrevBtnDisabled(!emblaApi.canScrollPrev());
|
|
82
|
+
setNextBtnDisabled(!emblaApi.canScrollNext());
|
|
83
|
+
}, []);
|
|
84
|
+
|
|
85
|
+
useEffect(() => {
|
|
86
|
+
if (!emblaApi) return;
|
|
87
|
+
|
|
88
|
+
onInit(emblaApi);
|
|
89
|
+
onSelect(emblaApi);
|
|
90
|
+
emblaApi.on('reInit', onInit);
|
|
91
|
+
emblaApi.on('reInit', onSelect);
|
|
92
|
+
emblaApi.on('select', onSelect);
|
|
93
|
+
}, [emblaApi, onInit, onSelect]);
|
|
94
|
+
|
|
95
|
+
useEffect(() => {
|
|
96
|
+
// This syncs the current slide with the objectwidget (or other sources
|
|
97
|
+
// able to access the slider context)
|
|
98
|
+
// that can modify the SliderContext (and come here via props slideIndex)
|
|
99
|
+
if (isEditMode) {
|
|
100
|
+
scrollTo(slideIndex);
|
|
101
|
+
}
|
|
102
|
+
}, [slideIndex, scrollTo, isEditMode]);
|
|
103
|
+
|
|
104
|
+
const sliderContainerWidth = emblaApi
|
|
105
|
+
?.rootNode()
|
|
106
|
+
.getBoundingClientRect().width;
|
|
107
|
+
|
|
108
|
+
return (
|
|
109
|
+
<>
|
|
110
|
+
{/* START CUSTOMIZATION */}
|
|
111
|
+
<div
|
|
112
|
+
className={cx('block slider', data.variation || 'default', className)}
|
|
113
|
+
style={{ '--slider-container-width': `${sliderContainerWidth}px` }}
|
|
114
|
+
>
|
|
115
|
+
{/* END CUSTOMIZATION */}
|
|
116
|
+
{(data.slides?.length === 0 || !data.slides) && isEditMode && (
|
|
117
|
+
<Message>
|
|
118
|
+
<div className="teaser-item default">
|
|
119
|
+
<img src={teaserTemplate} alt="" />
|
|
120
|
+
<p>{intl.formatMessage(messages.PleaseChooseContent)}</p>
|
|
121
|
+
</div>
|
|
122
|
+
</Message>
|
|
123
|
+
)}
|
|
124
|
+
{data.slides?.length > 0 && (
|
|
125
|
+
<>
|
|
126
|
+
<div className="slider-wrapper">
|
|
127
|
+
{!data.hideArrows && data.slides?.length > 1 && (
|
|
128
|
+
<>
|
|
129
|
+
<PrevButton onClick={scrollPrev} disabled={prevBtnDisabled} />
|
|
130
|
+
<NextButton onClick={scrollNext} disabled={nextBtnDisabled} />
|
|
131
|
+
</>
|
|
132
|
+
)}
|
|
133
|
+
|
|
134
|
+
<div className="slider-viewport" ref={emblaRef}>
|
|
135
|
+
<div className="slider-container">
|
|
136
|
+
{data.slides &&
|
|
137
|
+
data.slides.map((item, index) => {
|
|
138
|
+
return (
|
|
139
|
+
<div key={item['@id']} className="slider-slide">
|
|
140
|
+
<Body
|
|
141
|
+
{...props}
|
|
142
|
+
key={item['@id']}
|
|
143
|
+
data={item}
|
|
144
|
+
isEditMode={isEditMode}
|
|
145
|
+
dataBlock={data}
|
|
146
|
+
index={index}
|
|
147
|
+
block={block}
|
|
148
|
+
openObjectBrowser={openObjectBrowser}
|
|
149
|
+
onChangeBlock={onChangeBlock}
|
|
150
|
+
isActive={selectedIndex === index}
|
|
151
|
+
/>
|
|
152
|
+
</div>
|
|
153
|
+
);
|
|
154
|
+
})}
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
{data.slides?.length > 1 && (
|
|
159
|
+
<div className="slider-dots">
|
|
160
|
+
{scrollSnaps.map((_, index) => (
|
|
161
|
+
<DotButton
|
|
162
|
+
key={index}
|
|
163
|
+
index={index}
|
|
164
|
+
onClick={() => scrollTo(index)}
|
|
165
|
+
className={'slider-dot'.concat(
|
|
166
|
+
index === selectedIndex ? ' slider-dot--selected' : '',
|
|
167
|
+
)}
|
|
168
|
+
/>
|
|
169
|
+
))}
|
|
170
|
+
</div>
|
|
171
|
+
)}
|
|
172
|
+
</>
|
|
173
|
+
)}
|
|
174
|
+
</div>
|
|
175
|
+
</>
|
|
176
|
+
);
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
export default withBlockExtensions(SliderView);
|
package/src/config/blocks.tsx
CHANGED
|
@@ -45,6 +45,8 @@ import SearchBlockViewEvent from '../components/Blocks/EventCalendar/Search/Sear
|
|
|
45
45
|
import SearchBlockEditEvent from '../components/Blocks/EventCalendar/Search/SearchBlockEdit';
|
|
46
46
|
import SearchBlockSchemaEvent from '../components/Blocks/EventCalendar/Search/schema';
|
|
47
47
|
import EventCalenderTemplate from '../components/Blocks/EventCalendar/Search/components/EventTemplate';
|
|
48
|
+
import SliderVariants from '../components/Blocks/Slider/SliderVariants';
|
|
49
|
+
import DefaultBody from '../customizations/@kitconcept/volto-slider-block/components/DefaultBody';
|
|
48
50
|
|
|
49
51
|
declare module '@plone/types' {
|
|
50
52
|
export interface BlocksConfigData {
|
|
@@ -414,6 +416,40 @@ export default function install(config: ConfigType) {
|
|
|
414
416
|
// Slider Block
|
|
415
417
|
config.blocks.blocksConfig.slider = {
|
|
416
418
|
...config.blocks.blocksConfig.slider,
|
|
419
|
+
variations: [
|
|
420
|
+
{
|
|
421
|
+
id: 'default',
|
|
422
|
+
title: 'Default',
|
|
423
|
+
isDefault: true,
|
|
424
|
+
view: DefaultBody,
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
id: 'full-height',
|
|
428
|
+
title: 'Full Height',
|
|
429
|
+
view: SliderVariants,
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
id: 'side',
|
|
433
|
+
title: 'Side',
|
|
434
|
+
view: SliderVariants,
|
|
435
|
+
},
|
|
436
|
+
/* Why do we have two full-side variations?
|
|
437
|
+
because in listings we don't want to show the eventCalender variation and we dont
|
|
438
|
+
have any way to remove it from the list of variations in listing blocks because
|
|
439
|
+
in eventCaledarblock we use listingbody component for showing the variation.
|
|
440
|
+
you can see the css in listing.scss where we are hiding the option 3 using css
|
|
441
|
+
line no.6 */
|
|
442
|
+
{
|
|
443
|
+
id: 'full-side',
|
|
444
|
+
title: 'Full Side',
|
|
445
|
+
view: SliderVariants,
|
|
446
|
+
},
|
|
447
|
+
{
|
|
448
|
+
id: 'full-side',
|
|
449
|
+
title: 'Full Side',
|
|
450
|
+
view: SliderVariants,
|
|
451
|
+
},
|
|
452
|
+
],
|
|
417
453
|
schemaEnhancer: sliderBlockSchemaEnhancer,
|
|
418
454
|
};
|
|
419
455
|
|
|
@@ -59,10 +59,7 @@ const IconLinkList = (props: IconLinkListProps) => {
|
|
|
59
59
|
openLinkInNewTab={item.openInNewTab}
|
|
60
60
|
>
|
|
61
61
|
<div className="image-wrapper">
|
|
62
|
-
<img
|
|
63
|
-
src={itemInfo.src}
|
|
64
|
-
alt={itemInfo.srcAlt || itemInfo.title}
|
|
65
|
-
/>
|
|
62
|
+
<img src={itemInfo.src} alt={itemInfo.srcAlt || ''} />
|
|
66
63
|
</div>
|
|
67
64
|
<span>{itemInfo.title}</span>
|
|
68
65
|
</ConditionalLink>
|
|
@@ -8,32 +8,41 @@ $sliderImagesAspectRatio: var(--slider-images-aspect-ratio, 16/9);
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
.slider-viewport {
|
|
11
|
-
margin-bottom:
|
|
11
|
+
margin-bottom: $spacing-medium;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
.slider-dots {
|
|
15
|
-
padding-bottom:
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
.highlight-image-wrapper {
|
|
19
|
-
display: flex; // Small gap was appearing between the wrapper and the image (??)
|
|
20
|
-
|
|
21
|
-
img {
|
|
22
|
-
// Override Volto's Image Component inline style aspect ratio.
|
|
23
|
-
aspect-ratio: var(
|
|
24
|
-
--image-aspect-ratio,
|
|
25
|
-
$sliderImagesAspectRatio
|
|
26
|
-
) !important;
|
|
27
|
-
}
|
|
15
|
+
padding-bottom: $spacing-medium;
|
|
28
16
|
}
|
|
29
17
|
|
|
30
18
|
.teaser-item,
|
|
31
19
|
.grid-teaser-item {
|
|
32
20
|
flex-direction: column;
|
|
21
|
+
@media only screen and (max-width: $computer-width) {
|
|
22
|
+
height: 100%;
|
|
23
|
+
}
|
|
33
24
|
}
|
|
25
|
+
.link-container {
|
|
26
|
+
@media only screen and (max-width: $computer-width) {
|
|
27
|
+
height: 100%;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
34
31
|
.teaser-item {
|
|
35
|
-
|
|
32
|
+
.highlight-image-wrapper {
|
|
33
|
+
display: flex; // Small gap was appearing between the wrapper and the image (??)
|
|
36
34
|
|
|
35
|
+
img {
|
|
36
|
+
// Override Volto's Image Component inline style aspect ratio.
|
|
37
|
+
aspect-ratio: var(
|
|
38
|
+
--image-aspect-ratio,
|
|
39
|
+
$sliderImagesAspectRatio
|
|
40
|
+
) !important;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
@media only screen and (max-width: $computer-width) {
|
|
44
|
+
display: flex;
|
|
45
|
+
}
|
|
37
46
|
.teaser-item-title {
|
|
38
47
|
position: absolute;
|
|
39
48
|
top: 50%;
|
|
@@ -51,6 +60,7 @@ $sliderImagesAspectRatio: var(--slider-images-aspect-ratio, 16/9);
|
|
|
51
60
|
@media only screen and (max-width: $computer-width) {
|
|
52
61
|
position: static;
|
|
53
62
|
width: 100%;
|
|
63
|
+
height: 100%;
|
|
54
64
|
padding: 60px 20px;
|
|
55
65
|
background: $black;
|
|
56
66
|
transform: none;
|
|
@@ -112,4 +122,243 @@ $sliderImagesAspectRatio: var(--slider-images-aspect-ratio, 16/9);
|
|
|
112
122
|
line-height: 20px;
|
|
113
123
|
text-align: center;
|
|
114
124
|
}
|
|
125
|
+
|
|
126
|
+
&.side {
|
|
127
|
+
.teaser-item {
|
|
128
|
+
display: grid;
|
|
129
|
+
align-items: center;
|
|
130
|
+
padding: 0 130px;
|
|
131
|
+
aspect-ratio: 16/9;
|
|
132
|
+
background: rgba(0, 0, 0, 0.75);
|
|
133
|
+
gap: 70px;
|
|
134
|
+
grid-template-areas: 'images content';
|
|
135
|
+
grid-template-columns: 1fr 1fr;
|
|
136
|
+
grid-template-rows: auto;
|
|
137
|
+
@media only screen and (max-width: $computer-width) {
|
|
138
|
+
display: flex;
|
|
139
|
+
padding: 0 0;
|
|
140
|
+
aspect-ratio: auto;
|
|
141
|
+
gap: 0;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
&.has--slider--flagAlign--right {
|
|
145
|
+
grid-template-areas: 'images content';
|
|
146
|
+
}
|
|
147
|
+
&.has--slider--flagAlign--left {
|
|
148
|
+
grid-template-areas: 'content images';
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.highlight-image-wrapper {
|
|
152
|
+
grid-area: images;
|
|
153
|
+
|
|
154
|
+
img {
|
|
155
|
+
aspect-ratio: var(
|
|
156
|
+
--image-aspect-ratio,
|
|
157
|
+
$sliderImagesAspectRatio
|
|
158
|
+
) !important;
|
|
159
|
+
|
|
160
|
+
@media only screen and (max-width: $computer-width) {
|
|
161
|
+
width: 100%;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
.teaser-item-title {
|
|
166
|
+
position: relative;
|
|
167
|
+
top: 0;
|
|
168
|
+
width: 100%;
|
|
169
|
+
align-content: center;
|
|
170
|
+
padding: 0;
|
|
171
|
+
background: none;
|
|
172
|
+
color: white;
|
|
173
|
+
grid-area: content;
|
|
174
|
+
transform: none;
|
|
175
|
+
|
|
176
|
+
@media only screen and (max-width: $computer-width) {
|
|
177
|
+
position: relative;
|
|
178
|
+
width: 100%;
|
|
179
|
+
height: 100%;
|
|
180
|
+
padding: 60px 20px;
|
|
181
|
+
background: $black;
|
|
182
|
+
transform: none;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
.slider-button {
|
|
187
|
+
width: 130px;
|
|
188
|
+
background: rgba(0, 0, 0, 0);
|
|
189
|
+
|
|
190
|
+
svg.icon {
|
|
191
|
+
width: 50px !important;
|
|
192
|
+
height: 50px !important;
|
|
193
|
+
padding: 40px;
|
|
194
|
+
background: rgba(0, 0, 0, 0.15);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
&.full-side {
|
|
199
|
+
.teaser-item {
|
|
200
|
+
display: grid;
|
|
201
|
+
align-items: center;
|
|
202
|
+
aspect-ratio: 16/9;
|
|
203
|
+
background: rgba(0, 0, 0, 0.75);
|
|
204
|
+
gap: 60px;
|
|
205
|
+
grid-template-areas: 'images content';
|
|
206
|
+
grid-template-columns: 3fr 2fr;
|
|
207
|
+
grid-template-rows: auto;
|
|
208
|
+
|
|
209
|
+
@media only screen and (max-width: $computer-width) {
|
|
210
|
+
display: flex;
|
|
211
|
+
padding-right: 0;
|
|
212
|
+
padding-left: 0;
|
|
213
|
+
aspect-ratio: auto;
|
|
214
|
+
gap: 0;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
&.has--slider--flagAlign--right {
|
|
218
|
+
padding-right: 130px;
|
|
219
|
+
grid-template-areas: 'images content';
|
|
220
|
+
grid-template-columns: 3fr 2fr;
|
|
221
|
+
@media only screen and (max-width: $computer-width) {
|
|
222
|
+
padding-right: 0;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
&.has--slider--flagAlign--left {
|
|
226
|
+
padding-left: 130px;
|
|
227
|
+
grid-template-areas: 'content images';
|
|
228
|
+
grid-template-columns: 2fr 3fr;
|
|
229
|
+
@media only screen and (max-width: $computer-width) {
|
|
230
|
+
padding-left: 0;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.highlight-image-wrapper {
|
|
235
|
+
grid-area: images;
|
|
236
|
+
img {
|
|
237
|
+
aspect-ratio: var(
|
|
238
|
+
--image-aspect-ratio,
|
|
239
|
+
$sliderImagesAspectRatio
|
|
240
|
+
) !important;
|
|
241
|
+
|
|
242
|
+
@media only screen and (max-width: $computer-width) {
|
|
243
|
+
width: 100%;
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.teaser-item-title {
|
|
249
|
+
position: relative;
|
|
250
|
+
top: 0;
|
|
251
|
+
width: 100%;
|
|
252
|
+
align-self: center;
|
|
253
|
+
padding: 0;
|
|
254
|
+
background: none;
|
|
255
|
+
color: white;
|
|
256
|
+
grid-area: content;
|
|
257
|
+
transform: none;
|
|
258
|
+
|
|
259
|
+
@media only screen and (max-width: $computer-width) {
|
|
260
|
+
position: relative;
|
|
261
|
+
width: 100%;
|
|
262
|
+
height: 100%;
|
|
263
|
+
padding: 60px 20px;
|
|
264
|
+
background: $black;
|
|
265
|
+
transform: none;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
.slider-button {
|
|
270
|
+
width: 130px;
|
|
271
|
+
background: rgba(0, 0, 0, 0);
|
|
272
|
+
svg.icon {
|
|
273
|
+
width: 50px !important;
|
|
274
|
+
height: 50px !important;
|
|
275
|
+
padding: 40px;
|
|
276
|
+
background: rgba(0, 0, 0, 0.15);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
&.full-height {
|
|
282
|
+
.teaser-item {
|
|
283
|
+
display: grid;
|
|
284
|
+
aspect-ratio: 16/9;
|
|
285
|
+
background: rgba(0, 0, 0, 0.75);
|
|
286
|
+
grid-template-areas: 'images content';
|
|
287
|
+
grid-template-columns: 1fr 1fr;
|
|
288
|
+
grid-template-rows: auto;
|
|
289
|
+
|
|
290
|
+
@media only screen and (max-width: $computer-width) {
|
|
291
|
+
display: flex;
|
|
292
|
+
padding-right: 0;
|
|
293
|
+
padding-left: 0;
|
|
294
|
+
aspect-ratio: auto;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
&.has--slider--flagAlign--right {
|
|
298
|
+
grid-template-areas: 'images content';
|
|
299
|
+
.teaser-item-title {
|
|
300
|
+
padding-left: 74px; //Adding gap between the image & content
|
|
301
|
+
@media only screen and (max-width: $computer-width) {
|
|
302
|
+
padding-left: 20px;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
&.has--slider--flagAlign--left {
|
|
307
|
+
grid-template-areas: 'content images';
|
|
308
|
+
.teaser-item-title {
|
|
309
|
+
padding-right: 74px; //Adding gap between the image & content
|
|
310
|
+
@media only screen and (max-width: $computer-width) {
|
|
311
|
+
padding-right: 20px;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
.highlight-image-wrapper {
|
|
317
|
+
grid-area: images;
|
|
318
|
+
|
|
319
|
+
img {
|
|
320
|
+
aspect-ratio: var(
|
|
321
|
+
--image-aspect-ratio,
|
|
322
|
+
$sliderImagesAspectRatio
|
|
323
|
+
) !important;
|
|
324
|
+
|
|
325
|
+
@media only screen and (max-width: $computer-width) {
|
|
326
|
+
width: 100%;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
.teaser-item-title {
|
|
331
|
+
position: relative;
|
|
332
|
+
top: 0;
|
|
333
|
+
width: 100%;
|
|
334
|
+
align-self: center;
|
|
335
|
+
padding: $spacing-medium 130px;
|
|
336
|
+
background: none;
|
|
337
|
+
color: white;
|
|
338
|
+
grid-area: content;
|
|
339
|
+
|
|
340
|
+
transform: translateY(0);
|
|
341
|
+
|
|
342
|
+
@media only screen and (max-width: $computer-width) {
|
|
343
|
+
position: relative;
|
|
344
|
+
width: 100%;
|
|
345
|
+
height: 100%;
|
|
346
|
+
padding: 60px 20px;
|
|
347
|
+
background: $black;
|
|
348
|
+
transform: none;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
.slider-button {
|
|
353
|
+
width: 130px;
|
|
354
|
+
background: rgba(0, 0, 0, 0);
|
|
355
|
+
|
|
356
|
+
svg.icon {
|
|
357
|
+
width: 50px !important;
|
|
358
|
+
height: 50px !important;
|
|
359
|
+
padding: 40px;
|
|
360
|
+
background: rgba(0, 0, 0, 0.15);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
115
364
|
}
|