@orangesk/orange-design-system 3.9.0 → 3.11.0
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/build/components/AnchorNavigation/style.css +1 -1
- package/build/components/AnchorNavigation/style.css.map +1 -1
- package/build/components/Carousel/style.css +1 -1
- package/build/components/Carousel/style.css.map +1 -1
- package/build/components/Megamenu/style.css +1 -1
- package/build/components/Megamenu/style.css.map +1 -1
- package/build/components/index.js +1 -1
- package/build/components/index.js.map +1 -1
- package/build/components/types/index.d.ts +6 -2
- package/build/footer-sprite-dark.svg +1 -0
- package/build/footer-sprite-light.svg +1 -0
- package/build/lib/components.css +1 -1
- package/build/lib/components.css.map +1 -1
- package/build/lib/megamenu.css +1 -1
- package/build/lib/megamenu.css.map +1 -1
- package/build/lib/scripts.js +1 -1
- package/build/lib/scripts.js.map +1 -1
- package/build/lib/style.css +1 -1
- package/build/lib/style.css.map +1 -1
- package/build/megamenu-sprite-dark.svg +1 -0
- package/build/megamenu-sprite-light.svg +1 -0
- package/package.json +27 -27
- package/public/footer-sprite-dark.svg +1 -0
- package/public/footer-sprite-light.svg +1 -0
- package/src/assets/footer/appstore.svg +31 -0
- package/src/assets/footer/googleplay.svg +52 -0
- package/src/assets/footer/logo.svg +33 -0
- package/src/{components/Footer/PlanObnovy.tsx → assets/footer/plan-obnovy.svg} +53 -211
- package/src/assets/megamenu/input-search.svg +1 -0
- package/src/assets/megamenu/input-valid.svg +1 -0
- package/src/assets/megamenu/logo-line.svg +5 -0
- package/src/assets/megamenu/megamenu-logo.svg +61 -0
- package/src/assets/megamenu/store-apple--white.svg +5 -0
- package/src/assets/megamenu/store-apple.svg +4 -0
- package/src/assets/megamenu/store-huawei--white.svg +5 -0
- package/src/assets/megamenu/store-huawei.svg +4 -0
- package/src/assets/megamenu/store-play--white.svg +7 -0
- package/src/assets/megamenu/store-play.svg +7 -0
- package/src/components/AnchorNavigation/styles/mixins.scss +7 -9
- package/src/components/BlockAction/CloneElementWithClassName.tsx +10 -7
- package/src/components/BlockAction/tests/CloneElementWithClassName.unit.test.jsx +28 -1
- package/src/components/Carousel/Carousel.static.ts +111 -14
- package/src/components/Carousel/Carousel.tsx +35 -12
- package/src/components/Carousel/constants.ts +2 -0
- package/src/components/Carousel/styles/mixins.scss +61 -0
- package/src/components/Carousel/styles/style.scss +7 -0
- package/src/components/Carousel/tests/Carousel.lifecycle.test.ts +223 -0
- package/src/components/Footer/Footer.tsx +44 -54
- package/src/components/Footer/FooterIcon.tsx +12 -0
- package/src/components/Footer/data.ts +4 -2
- package/src/components/Footer/tests/Footer.unit.test.jsx +63 -0
- package/src/components/Forms/TextInput/styles/mixins.scss +4 -2
- package/src/components/Megamenu/Logo.tsx +7 -7
- package/src/components/Megamenu/LogoJeTu.tsx +6 -58
- package/src/components/Megamenu/MegaMenuIcon.tsx +20 -11
- package/src/components/Megamenu/Megamenu.tsx +58 -48
- package/src/components/Megamenu/MegamenuBlog.tsx +14 -2
- package/src/components/Megamenu/MegamenuSearchContent.tsx +13 -0
- package/src/components/Megamenu/MyOrangeMobilePanel.tsx +3 -9
- package/src/components/Megamenu/styles/mixins.scss +21 -34
- package/src/components/Megamenu/tests/Megamenu.unit.test.jsx +158 -0
|
@@ -13,12 +13,15 @@ const CloneElementWithClassName: React.FC<CloneElementWithClassNameProps> = ({
|
|
|
13
13
|
children,
|
|
14
14
|
...other
|
|
15
15
|
}) =>
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
// Children.map resolves lazy element references received through RSC payloads.
|
|
17
|
+
React.Children.map(children, (child) =>
|
|
18
|
+
React.cloneElement(child, {
|
|
19
|
+
...(typeof child.props === "object" && child.props !== null
|
|
20
|
+
? child.props
|
|
21
|
+
: {}),
|
|
22
|
+
...other,
|
|
23
|
+
className: cx(child.props && child.props.className, className),
|
|
24
|
+
}),
|
|
25
|
+
);
|
|
23
26
|
|
|
24
27
|
export { CloneElementWithClassName };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { render } from "@testing-library/react";
|
|
1
|
+
import { fireEvent, render } from "@testing-library/react";
|
|
2
2
|
|
|
3
3
|
import { CloneElementWithClassName } from "../CloneElementWithClassName";
|
|
4
4
|
|
|
@@ -31,3 +31,30 @@ describe("rendering CloneElementWithClassName", () => {
|
|
|
31
31
|
});
|
|
32
32
|
});
|
|
33
33
|
});
|
|
34
|
+
|
|
35
|
+
describe("CloneElementWithClassName", () => {
|
|
36
|
+
it("clones a lazy element received through the RSC payload", () => {
|
|
37
|
+
const onClick = vi.fn();
|
|
38
|
+
const element = <button className="original">Open</button>;
|
|
39
|
+
// RSC can wrap repeated elements in lazy references rather than JSX elements.
|
|
40
|
+
const child = {
|
|
41
|
+
$$typeof: Symbol.for("react.lazy"),
|
|
42
|
+
_payload: element,
|
|
43
|
+
_init: (payload) => payload,
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
const { getByRole } = render(
|
|
47
|
+
<CloneElementWithClassName
|
|
48
|
+
className="block-action__control"
|
|
49
|
+
onClick={onClick}
|
|
50
|
+
>
|
|
51
|
+
{child}
|
|
52
|
+
</CloneElementWithClassName>,
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
const button = getByRole("button", { name: "Open" });
|
|
56
|
+
expect(button).toHaveClass("original", "block-action__control");
|
|
57
|
+
fireEvent.click(button);
|
|
58
|
+
expect(onClick).toHaveBeenCalledOnce();
|
|
59
|
+
});
|
|
60
|
+
});
|
|
@@ -18,6 +18,8 @@ import {
|
|
|
18
18
|
CLASS_DOT,
|
|
19
19
|
CLASS_SCROLLBAR_DRAG,
|
|
20
20
|
CLASS_SCROLLBAR_HORIZONTAL,
|
|
21
|
+
CLASS_SIDE_ARROWS,
|
|
22
|
+
CLASS_SIDE_ARROWS_VARIANT,
|
|
21
23
|
CLASS_SLIDE,
|
|
22
24
|
CLASS_SLIDE_NEXT,
|
|
23
25
|
CLASS_SLIDE_PREV,
|
|
@@ -94,8 +96,8 @@ export const defaultConfig: SwiperOptions = {
|
|
|
94
96
|
};
|
|
95
97
|
|
|
96
98
|
export default class Carousel {
|
|
97
|
-
element
|
|
98
|
-
config
|
|
99
|
+
element!: HTMLElement;
|
|
100
|
+
config!: SwiperOptions;
|
|
99
101
|
viewport!: HTMLElement;
|
|
100
102
|
track!: HTMLElement;
|
|
101
103
|
instance!: Swiper;
|
|
@@ -104,8 +106,9 @@ export default class Carousel {
|
|
|
104
106
|
private externalControlsState: ExternalControlsState | null = null;
|
|
105
107
|
private resizeObserver?: ResizeObserver;
|
|
106
108
|
private resizeRafId?: number;
|
|
107
|
-
private boundWindowResizeHandler
|
|
109
|
+
private boundWindowResizeHandler!: () => void;
|
|
108
110
|
private bleedResizeHandler?: () => void;
|
|
111
|
+
private destroyed = false;
|
|
109
112
|
private static readonly OVERFLOW_EPSILON_PX = 1;
|
|
110
113
|
|
|
111
114
|
private getViewportWrapper(): HTMLElement | null {
|
|
@@ -139,6 +142,17 @@ export default class Carousel {
|
|
|
139
142
|
return this.track?.scrollWidth || 0;
|
|
140
143
|
}
|
|
141
144
|
|
|
145
|
+
const sizes = this.instance.slidesSizesGrid;
|
|
146
|
+
const positions = this.instance.slidesGrid;
|
|
147
|
+
if (sizes?.length && positions?.length === sizes.length) {
|
|
148
|
+
const last = sizes.length - 1;
|
|
149
|
+
// Swiper's grid preserves fractional widths and resolved percentage gaps.
|
|
150
|
+
const edgesWidth = this.instance.params.centeredSlides
|
|
151
|
+
? (sizes[0] + sizes[last]) / 2
|
|
152
|
+
: sizes[last];
|
|
153
|
+
return positions[last] - positions[0] + edgesWidth;
|
|
154
|
+
}
|
|
155
|
+
|
|
142
156
|
const slides = Array.from(this.instance.slides) as HTMLElement[];
|
|
143
157
|
const widthsSum = slides.reduce((sum, slide) => sum + slide.offsetWidth, 0);
|
|
144
158
|
const spaceBetween = Number(this.instance.params?.spaceBetween) || 0;
|
|
@@ -153,17 +167,18 @@ export default class Carousel {
|
|
|
153
167
|
return measuredWidth;
|
|
154
168
|
}
|
|
155
169
|
|
|
156
|
-
private getOverflowWidth(viewportWrapper?: HTMLElement): number {
|
|
170
|
+
private getOverflowWidth(viewportWrapper?: HTMLElement): number | null {
|
|
157
171
|
const isBleedRight = this.isBleedRight();
|
|
158
172
|
const containerWidth = isBleedRight
|
|
159
173
|
? this.element.clientWidth || viewportWrapper?.clientWidth || 0
|
|
160
174
|
: this.viewport?.clientWidth || 0;
|
|
161
175
|
|
|
162
176
|
if (containerWidth <= 0) {
|
|
163
|
-
return
|
|
177
|
+
return null;
|
|
164
178
|
}
|
|
165
179
|
|
|
166
180
|
const contentWidth = this.getSlidesContentWidth();
|
|
181
|
+
if (contentWidth <= 0) return null;
|
|
167
182
|
|
|
168
183
|
return contentWidth - containerWidth;
|
|
169
184
|
}
|
|
@@ -174,7 +189,7 @@ export default class Carousel {
|
|
|
174
189
|
}
|
|
175
190
|
|
|
176
191
|
const overflowWidth = this.getOverflowWidth(viewportWrapper);
|
|
177
|
-
if (overflowWidth !==
|
|
192
|
+
if (overflowWidth !== null) {
|
|
178
193
|
return overflowWidth > Carousel.OVERFLOW_EPSILON_PX;
|
|
179
194
|
}
|
|
180
195
|
|
|
@@ -185,6 +200,8 @@ export default class Carousel {
|
|
|
185
200
|
}
|
|
186
201
|
|
|
187
202
|
constructor(element: HTMLElement, config?: Partial<SwiperOptions>) {
|
|
203
|
+
const existing = Carousel.getInstance(element);
|
|
204
|
+
if (existing) return existing;
|
|
188
205
|
const scrollbarEl = element.querySelector(
|
|
189
206
|
SELECTOR_SCROLLBAR,
|
|
190
207
|
) as HTMLElement | null;
|
|
@@ -225,6 +242,7 @@ export default class Carousel {
|
|
|
225
242
|
}
|
|
226
243
|
|
|
227
244
|
init() {
|
|
245
|
+
if (this.destroyed || this.instance) return;
|
|
228
246
|
this.getElements();
|
|
229
247
|
|
|
230
248
|
if (this.element.hasAttribute("data-swiper-options")) {
|
|
@@ -280,7 +298,7 @@ export default class Carousel {
|
|
|
280
298
|
|
|
281
299
|
// Trigger a final update to notify listeners (like SameHeight) that carousel is ready
|
|
282
300
|
requestAnimationFrame(() => {
|
|
283
|
-
if (this.instance) {
|
|
301
|
+
if (!this.destroyed && this.instance) {
|
|
284
302
|
this.instance.update();
|
|
285
303
|
}
|
|
286
304
|
});
|
|
@@ -303,6 +321,7 @@ export default class Carousel {
|
|
|
303
321
|
}
|
|
304
322
|
|
|
305
323
|
this.instance.update();
|
|
324
|
+
this.updateSideArrowGeometry();
|
|
306
325
|
this.updateCarouselEnabledState();
|
|
307
326
|
this.bleedResizeHandler?.();
|
|
308
327
|
this.updateExternalControlsState();
|
|
@@ -316,7 +335,7 @@ export default class Carousel {
|
|
|
316
335
|
*/
|
|
317
336
|
syncScrollbar() {
|
|
318
337
|
requestAnimationFrame(() => {
|
|
319
|
-
if (this.instance?.scrollbar) {
|
|
338
|
+
if (!this.destroyed && this.instance?.scrollbar) {
|
|
320
339
|
this.instance.scrollbar.updateSize();
|
|
321
340
|
}
|
|
322
341
|
});
|
|
@@ -328,8 +347,12 @@ export default class Carousel {
|
|
|
328
347
|
}
|
|
329
348
|
|
|
330
349
|
this.resizeObserver?.disconnect();
|
|
350
|
+
const firstSlide = this.instance?.slides?.[0] as HTMLElement | undefined;
|
|
351
|
+
let viewportWidth = this.viewport.clientWidth;
|
|
352
|
+
let rootWidth = this.element.clientWidth;
|
|
353
|
+
let slideWidth = firstSlide?.offsetWidth;
|
|
331
354
|
this.resizeObserver = new ResizeObserver(() => {
|
|
332
|
-
if (!this.instance || !this.viewport) {
|
|
355
|
+
if (this.destroyed || !this.instance || !this.viewport) {
|
|
333
356
|
return;
|
|
334
357
|
}
|
|
335
358
|
|
|
@@ -337,12 +360,27 @@ export default class Carousel {
|
|
|
337
360
|
return;
|
|
338
361
|
}
|
|
339
362
|
|
|
340
|
-
|
|
363
|
+
const widthChanged =
|
|
364
|
+
viewportWidth !== this.viewport.clientWidth ||
|
|
365
|
+
rootWidth !== this.element.clientWidth ||
|
|
366
|
+
slideWidth !== firstSlide?.offsetWidth;
|
|
367
|
+
if (widthChanged || this.instance.params.autoHeight) {
|
|
368
|
+
this.instance.update();
|
|
369
|
+
this.bleedResizeHandler?.();
|
|
370
|
+
this.instance.scrollbar?.updateSize();
|
|
371
|
+
}
|
|
372
|
+
// A height update from SameHeight must not start another Swiper update.
|
|
341
373
|
this.updateCarouselEnabledState();
|
|
342
|
-
this.
|
|
374
|
+
viewportWidth = this.viewport.clientWidth;
|
|
375
|
+
rootWidth = this.element.clientWidth;
|
|
376
|
+
slideWidth = firstSlide?.offsetWidth;
|
|
343
377
|
});
|
|
344
378
|
|
|
379
|
+
this.resizeObserver.observe(this.element);
|
|
345
380
|
this.resizeObserver.observe(this.viewport);
|
|
381
|
+
if (firstSlide) {
|
|
382
|
+
this.resizeObserver.observe(firstSlide);
|
|
383
|
+
}
|
|
346
384
|
}
|
|
347
385
|
|
|
348
386
|
/**
|
|
@@ -355,7 +393,13 @@ export default class Carousel {
|
|
|
355
393
|
const scrollbar = this.instance?.scrollbar;
|
|
356
394
|
const swiper = this.instance;
|
|
357
395
|
|
|
358
|
-
if (
|
|
396
|
+
if (
|
|
397
|
+
this.destroyed ||
|
|
398
|
+
!viewportWrapper ||
|
|
399
|
+
!scrollbar ||
|
|
400
|
+
!scrollbar.dragEl ||
|
|
401
|
+
!swiper
|
|
402
|
+
) {
|
|
359
403
|
return;
|
|
360
404
|
}
|
|
361
405
|
|
|
@@ -477,9 +521,48 @@ export default class Carousel {
|
|
|
477
521
|
this.instance.disable();
|
|
478
522
|
}
|
|
479
523
|
|
|
524
|
+
this.updateSideArrowGeometry();
|
|
525
|
+
this.updateSideArrowVisibility(hasScrollableContent);
|
|
526
|
+
|
|
480
527
|
this.setScrollbarVisible(this.instance.enabled);
|
|
481
528
|
}
|
|
482
529
|
|
|
530
|
+
private updateSideArrowGeometry(): void {
|
|
531
|
+
if (!this.element.classList.contains(CLASS_SIDE_ARROWS_VARIANT)) {
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
const firstSlide = this.instance?.slides?.[0] as HTMLElement | undefined;
|
|
536
|
+
if (!firstSlide) {
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
this.element.style.setProperty(
|
|
541
|
+
"--carousel-side-arrows-width",
|
|
542
|
+
`${firstSlide.offsetWidth}px`,
|
|
543
|
+
);
|
|
544
|
+
const slidesHeight = this.viewport?.getBoundingClientRect().height;
|
|
545
|
+
if (slidesHeight) {
|
|
546
|
+
this.element.style.setProperty(
|
|
547
|
+
"--carousel-side-arrows-height",
|
|
548
|
+
`${slidesHeight}px`,
|
|
549
|
+
);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
private updateSideArrowVisibility(isScrollable: boolean): void {
|
|
554
|
+
if (!this.element.classList.contains(CLASS_SIDE_ARROWS_VARIANT)) {
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
const sideArrows = this.element.querySelector(
|
|
559
|
+
`.${CLASS_SIDE_ARROWS}`,
|
|
560
|
+
) as HTMLElement | null;
|
|
561
|
+
if (sideArrows) {
|
|
562
|
+
sideArrows.hidden = !isScrollable;
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
483
566
|
private applyBleedInsets(viewportWrapper: HTMLElement): void {
|
|
484
567
|
if (!this.instance || !this.instance.params) {
|
|
485
568
|
return;
|
|
@@ -584,7 +667,7 @@ export default class Carousel {
|
|
|
584
667
|
*/
|
|
585
668
|
adjustConfigForBleedRight() {
|
|
586
669
|
requestAnimationFrame(() => {
|
|
587
|
-
if (!this.instance) return;
|
|
670
|
+
if (this.destroyed || !this.instance) return;
|
|
588
671
|
|
|
589
672
|
const viewportWrapper = this.getViewportWrapper();
|
|
590
673
|
if (!viewportWrapper) return;
|
|
@@ -929,6 +1012,8 @@ export default class Carousel {
|
|
|
929
1012
|
}
|
|
930
1013
|
|
|
931
1014
|
destroy() {
|
|
1015
|
+
if (this.destroyed) return;
|
|
1016
|
+
this.destroyed = true;
|
|
932
1017
|
// Clean up external controls
|
|
933
1018
|
if (this.carouselId) {
|
|
934
1019
|
const controlElements = document.querySelectorAll(
|
|
@@ -943,6 +1028,13 @@ export default class Carousel {
|
|
|
943
1028
|
);
|
|
944
1029
|
delete (htmlControl as any)._carouselClickHandler;
|
|
945
1030
|
}
|
|
1031
|
+
if ((htmlControl as any)._carouselKeydownHandler) {
|
|
1032
|
+
htmlControl.removeEventListener(
|
|
1033
|
+
"keydown",
|
|
1034
|
+
(htmlControl as any)._carouselKeydownHandler,
|
|
1035
|
+
);
|
|
1036
|
+
delete (htmlControl as any)._carouselKeydownHandler;
|
|
1037
|
+
}
|
|
946
1038
|
htmlControl.removeAttribute("data-carousel-initialized");
|
|
947
1039
|
});
|
|
948
1040
|
}
|
|
@@ -967,6 +1059,8 @@ export default class Carousel {
|
|
|
967
1059
|
this.externalControlsState = null;
|
|
968
1060
|
this.resizeObserver?.disconnect();
|
|
969
1061
|
this.resizeObserver = undefined;
|
|
1062
|
+
this.element.style.removeProperty("--carousel-side-arrows-width");
|
|
1063
|
+
this.element.style.removeProperty("--carousel-side-arrows-height");
|
|
970
1064
|
|
|
971
1065
|
if ((this.element as any).ODS_Carousel === this) {
|
|
972
1066
|
delete (this.element as any).ODS_Carousel;
|
|
@@ -974,8 +1068,11 @@ export default class Carousel {
|
|
|
974
1068
|
}
|
|
975
1069
|
|
|
976
1070
|
update() {
|
|
977
|
-
if (this.instance) {
|
|
1071
|
+
if (!this.destroyed && this.instance) {
|
|
978
1072
|
this.instance.update();
|
|
1073
|
+
this.bleedResizeHandler?.();
|
|
1074
|
+
this.updateCarouselEnabledState();
|
|
1075
|
+
this.updateExternalControlsState();
|
|
979
1076
|
}
|
|
980
1077
|
}
|
|
981
1078
|
|
|
@@ -17,6 +17,8 @@ import {
|
|
|
17
17
|
CLASS_ROOT,
|
|
18
18
|
CLASS_SCROLLBAR,
|
|
19
19
|
CLASS_SCROLLBAR_DRAG,
|
|
20
|
+
CLASS_SIDE_ARROWS,
|
|
21
|
+
CLASS_SIDE_ARROWS_VARIANT,
|
|
20
22
|
CLASS_TRACK,
|
|
21
23
|
CLASS_VIEWPORT,
|
|
22
24
|
CLASS_VIEWPORT_WRAPPER,
|
|
@@ -37,6 +39,8 @@ interface CarouselProps<T = ReactNode> extends HTMLAttributes<HTMLDivElement> {
|
|
|
37
39
|
bleedRight?: boolean;
|
|
38
40
|
/** Make carousel bleed right from its root edge without bleeding left */
|
|
39
41
|
bleedRightNoLeft?: boolean;
|
|
42
|
+
/** Show navigation arrows beside the first visible slide */
|
|
43
|
+
showSideArrows?: boolean;
|
|
40
44
|
className?: string;
|
|
41
45
|
}
|
|
42
46
|
|
|
@@ -53,6 +57,7 @@ const Carousel = <T,>({
|
|
|
53
57
|
showScrollbar = false,
|
|
54
58
|
bleedRight = false,
|
|
55
59
|
bleedRightNoLeft = false,
|
|
60
|
+
showSideArrows = false,
|
|
56
61
|
...other
|
|
57
62
|
}: CarouselProps<T>) => {
|
|
58
63
|
const [carouselRef] = useStatic(CarouselStatic);
|
|
@@ -77,6 +82,7 @@ const Carousel = <T,>({
|
|
|
77
82
|
[`${CLASS_ROOT}--scrollbar`]: showScrollbar,
|
|
78
83
|
[`${CLASS_ROOT}--bleed-right`]: bleedRight,
|
|
79
84
|
[CLASS_BLEED_RIGHT_NO_LEFT]: bleedRightNoLeft,
|
|
85
|
+
[CLASS_SIDE_ARROWS_VARIANT]: showSideArrows,
|
|
80
86
|
});
|
|
81
87
|
|
|
82
88
|
const elementClasses = {
|
|
@@ -112,21 +118,38 @@ const Carousel = <T,>({
|
|
|
112
118
|
</div>
|
|
113
119
|
</div>
|
|
114
120
|
|
|
121
|
+
{showSideArrows && (
|
|
122
|
+
<div className={CLASS_SIDE_ARROWS}>
|
|
123
|
+
<Controls
|
|
124
|
+
className={elementClasses.prev}
|
|
125
|
+
icon="chevron-left"
|
|
126
|
+
aria-label="Naspäť"
|
|
127
|
+
/>
|
|
128
|
+
<Controls
|
|
129
|
+
className={elementClasses.next}
|
|
130
|
+
icon="chevron-right"
|
|
131
|
+
aria-label="Ďalej"
|
|
132
|
+
/>
|
|
133
|
+
</div>
|
|
134
|
+
)}
|
|
135
|
+
|
|
115
136
|
{!showScrollbar && (
|
|
116
137
|
<div className={elementClasses.navigation}>
|
|
117
138
|
<div role="tablist" className={elementClasses.dots} />
|
|
118
|
-
|
|
119
|
-
<
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
139
|
+
{!showSideArrows && (
|
|
140
|
+
<div className={elementClasses.controls}>
|
|
141
|
+
<Controls
|
|
142
|
+
className={elementClasses.prev}
|
|
143
|
+
icon="chevron-left"
|
|
144
|
+
aria-label="Naspäť"
|
|
145
|
+
/>
|
|
146
|
+
<Controls
|
|
147
|
+
className={elementClasses.next}
|
|
148
|
+
icon="chevron-right"
|
|
149
|
+
aria-label="Ďalej"
|
|
150
|
+
/>
|
|
151
|
+
</div>
|
|
152
|
+
)}
|
|
130
153
|
</div>
|
|
131
154
|
)}
|
|
132
155
|
|
|
@@ -11,6 +11,7 @@ export const CLASS_NEXT = `${CLASS_ROOT}__next`;
|
|
|
11
11
|
export const CLASS_DOTS = `${CLASS_ROOT}__pagination`;
|
|
12
12
|
export const CLASS_NAVIGATION = `${CLASS_ROOT}__navigation`;
|
|
13
13
|
export const CLASS_CONTROLS = `${CLASS_ROOT}__controls`;
|
|
14
|
+
export const CLASS_SIDE_ARROWS = `${CLASS_ROOT}__side-arrows`;
|
|
14
15
|
export const CLASS_DOT = `${CLASS_ROOT}__pagination-item`;
|
|
15
16
|
export const CLASS_SCROLLBAR = `${CLASS_ROOT}__scrollbar`;
|
|
16
17
|
export const CLASS_SCROLLBAR_HORIZONTAL = `${CLASS_ROOT}__scrollbar-horizontal`;
|
|
@@ -19,6 +20,7 @@ export const CLASS_ACTIVE = "is-active";
|
|
|
19
20
|
export const CLASS_SCROLLBAR_VARIANT = `${CLASS_ROOT}--scrollbar`;
|
|
20
21
|
export const CLASS_BLEED_RIGHT = `${CLASS_ROOT}--bleed-right`;
|
|
21
22
|
export const CLASS_BLEED_RIGHT_NO_LEFT = `${CLASS_ROOT}--bleed-right-no-left`;
|
|
23
|
+
export const CLASS_SIDE_ARROWS_VARIANT = `${CLASS_ROOT}--side-arrows`;
|
|
22
24
|
|
|
23
25
|
export const SELECTOR_VIEWPORT = `.${CLASS_VIEWPORT}`;
|
|
24
26
|
export const SELECTOR_TRACK = `.${CLASS_TRACK}`;
|
|
@@ -70,6 +70,67 @@
|
|
|
70
70
|
gap: convert.to-rem(8px);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
+
@mixin side-arrows {
|
|
74
|
+
position: absolute;
|
|
75
|
+
inset-block-start: 0;
|
|
76
|
+
inset-inline-start: 0;
|
|
77
|
+
z-index: 2;
|
|
78
|
+
display: flex;
|
|
79
|
+
align-items: center;
|
|
80
|
+
justify-content: space-between;
|
|
81
|
+
width: 100%;
|
|
82
|
+
height: min(var(--carousel-side-arrows-height, 100%), 100vh);
|
|
83
|
+
pointer-events: none;
|
|
84
|
+
|
|
85
|
+
&[hidden] {
|
|
86
|
+
display: none;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.controls {
|
|
90
|
+
flex: 0 0 auto;
|
|
91
|
+
pointer-events: auto;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.controls.swiper-button-lock {
|
|
95
|
+
display: inline-flex;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.controls[disabled] {
|
|
99
|
+
display: none;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.carousel__prev {
|
|
103
|
+
position: absolute;
|
|
104
|
+
inset-inline-start: 0;
|
|
105
|
+
top: 50%;
|
|
106
|
+
transform: translate(-50%, -50%);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.carousel__next {
|
|
110
|
+
position: absolute;
|
|
111
|
+
inset-inline-end: 0;
|
|
112
|
+
top: 50%;
|
|
113
|
+
transform: translate(50%, -50%);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
@include breakpoint.get("md", "down") {
|
|
117
|
+
width: var(--carousel-side-arrows-width, 100%);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
@mixin centered-mobile-variant {
|
|
122
|
+
@include breakpoint.get("sm", "down") {
|
|
123
|
+
.carousel__slide {
|
|
124
|
+
width: calc(100% - 40px);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.carousel__side-arrows {
|
|
128
|
+
inset-inline-start: 20px;
|
|
129
|
+
width: calc(100% - 40px);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
73
134
|
@mixin track {
|
|
74
135
|
transform: translateZ(0);
|
|
75
136
|
width: 100%;
|
|
@@ -9,6 +9,13 @@
|
|
|
9
9
|
@include mixins.scrollbar-variant;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
&--side-arrows {
|
|
13
|
+
.carousel__side-arrows {
|
|
14
|
+
@include mixins.side-arrows;
|
|
15
|
+
}
|
|
16
|
+
@include mixins.centered-mobile-variant;
|
|
17
|
+
}
|
|
18
|
+
|
|
12
19
|
&--bleed-right,
|
|
13
20
|
&--bleed-right-no-left {
|
|
14
21
|
@include mixins.bleed-right-variant;
|