@orangesk/orange-design-system 2.0.0-beta.41 → 2.0.0-beta.43
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/BlockAction/style.css +1 -1
- package/build/components/BlockAction/style.css.map +1 -1
- package/build/components/Buttons/style.css +1 -1
- package/build/components/Buttons/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/Grid/style.css +1 -1
- package/build/components/Grid/style.css.map +1 -1
- package/build/components/Link/style.css +1 -1
- package/build/components/Link/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/Modal/style.css +1 -1
- package/build/components/Modal/style.css.map +1 -1
- package/build/components/index.js +1 -1
- package/build/components/index.js.map +1 -1
- package/build/components/tsconfig.tsbuildinfo +1 -1
- package/build/components/types/src/components/AnchorNavigation/AnchorNavigation.static.d.ts +40 -0
- package/build/components/types/src/components/Carousel/Carousel.static.d.ts +0 -5
- package/build/components/types/src/components/Megamenu/Megamenu.static.d.ts +3 -0
- package/build/components/types/src/components/Modal/Modal.static.d.ts +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/megamenu.js +1 -1
- package/build/lib/megamenu.js.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/lib/tsconfig.tsbuildinfo +1 -1
- package/build/sprite.svg +1 -1
- package/package.json +23 -23
- package/src/assets/icons/youtube.svg +3 -1
- package/src/components/AnchorNavigation/AnchorNavigation.static.ts +385 -77
- package/src/components/AnchorNavigation/styles/mixins.scss +18 -2
- package/src/components/AnchorNavigation/tests/AnchorNavigation.unit.test.jsx +266 -8
- package/src/components/BlockAction/styles/mixins.scss +1 -1
- package/src/components/Buttons/styles/mixins.scss +8 -13
- package/src/components/Carousel/Carousel.static.ts +5 -26
- package/src/components/Carousel/styles/mixins.scss +1 -1
- package/src/components/Carousel/tests/Carousel.static.test.jsx +117 -0
- package/src/components/Grid/styles/mixins.scss +14 -6
- package/src/components/Link/styles/mixins.scss +0 -1
- package/src/components/Megamenu/Megamenu.static.ts +27 -1
- package/src/components/Megamenu/styles/mixins.scss +4 -0
- package/src/components/Modal/Modal.static.ts +29 -7
- package/src/components/Modal/styles/mixins.scss +4 -0
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
margin-bottom: 0 !important;
|
|
33
33
|
padding: convert.to-rem(25px) 0 !important;
|
|
34
34
|
white-space: nowrap;
|
|
35
|
+
color: inherit;
|
|
35
36
|
text-decoration: none !important;
|
|
36
37
|
display: inline-block;
|
|
37
38
|
cursor: pointer;
|
|
@@ -39,6 +40,13 @@
|
|
|
39
40
|
line-height: convert.to-rem(20px) !important;
|
|
40
41
|
font-weight: 700 !important;
|
|
41
42
|
|
|
43
|
+
&:link,
|
|
44
|
+
&:visited,
|
|
45
|
+
&:active {
|
|
46
|
+
color: inherit;
|
|
47
|
+
text-decoration: none !important;
|
|
48
|
+
}
|
|
49
|
+
|
|
42
50
|
&:last-child {
|
|
43
51
|
margin-right: 0;
|
|
44
52
|
}
|
|
@@ -48,15 +56,23 @@
|
|
|
48
56
|
padding: convert.to-rem(15px) 0 !important;
|
|
49
57
|
}
|
|
50
58
|
|
|
51
|
-
&:hover,
|
|
52
59
|
&:focus-visible,
|
|
53
|
-
&:active,
|
|
54
60
|
&.is-active {
|
|
55
61
|
box-shadow: megamenuConfig.$active-line;
|
|
56
62
|
color: inherit;
|
|
57
63
|
text-decoration: none !important;
|
|
58
64
|
outline: none;
|
|
59
65
|
}
|
|
66
|
+
|
|
67
|
+
@media (hover: hover) and (pointer: fine) {
|
|
68
|
+
&:hover,
|
|
69
|
+
&:active {
|
|
70
|
+
box-shadow: megamenuConfig.$active-line;
|
|
71
|
+
color: inherit;
|
|
72
|
+
text-decoration: none !important;
|
|
73
|
+
outline: none;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
60
76
|
}
|
|
61
77
|
|
|
62
78
|
@mixin anchor-navigation-content() {
|
|
@@ -362,13 +362,33 @@ describe("rendering AnchorNavigation", () => {
|
|
|
362
362
|
value: 0,
|
|
363
363
|
writable: true,
|
|
364
364
|
});
|
|
365
|
-
Object.defineProperty(
|
|
365
|
+
Object.defineProperty(contentLeft, "getBoundingClientRect", {
|
|
366
366
|
configurable: true,
|
|
367
|
-
value:
|
|
367
|
+
value: () => ({
|
|
368
|
+
top: 0,
|
|
369
|
+
bottom: 0,
|
|
370
|
+
left: 0,
|
|
371
|
+
right: 180,
|
|
372
|
+
width: 180,
|
|
373
|
+
height: 0,
|
|
374
|
+
x: 0,
|
|
375
|
+
y: 0,
|
|
376
|
+
toJSON: () => ({}),
|
|
377
|
+
}),
|
|
368
378
|
});
|
|
369
|
-
Object.defineProperty(activeLink, "
|
|
379
|
+
Object.defineProperty(activeLink, "getBoundingClientRect", {
|
|
370
380
|
configurable: true,
|
|
371
|
-
value:
|
|
381
|
+
value: () => ({
|
|
382
|
+
top: 0,
|
|
383
|
+
bottom: 0,
|
|
384
|
+
left: 220,
|
|
385
|
+
right: 300,
|
|
386
|
+
width: 80,
|
|
387
|
+
height: 0,
|
|
388
|
+
x: 220,
|
|
389
|
+
y: 0,
|
|
390
|
+
toJSON: () => ({}),
|
|
391
|
+
}),
|
|
372
392
|
});
|
|
373
393
|
contentLeft.scrollTo = scrollToSpy;
|
|
374
394
|
|
|
@@ -412,13 +432,33 @@ describe("rendering AnchorNavigation", () => {
|
|
|
412
432
|
value: 180,
|
|
413
433
|
writable: true,
|
|
414
434
|
});
|
|
415
|
-
Object.defineProperty(
|
|
435
|
+
Object.defineProperty(contentLeft, "getBoundingClientRect", {
|
|
416
436
|
configurable: true,
|
|
417
|
-
value:
|
|
437
|
+
value: () => ({
|
|
438
|
+
top: 0,
|
|
439
|
+
bottom: 0,
|
|
440
|
+
left: 0,
|
|
441
|
+
right: 200,
|
|
442
|
+
width: 200,
|
|
443
|
+
height: 0,
|
|
444
|
+
x: 0,
|
|
445
|
+
y: 0,
|
|
446
|
+
toJSON: () => ({}),
|
|
447
|
+
}),
|
|
418
448
|
});
|
|
419
|
-
Object.defineProperty(activeLink, "
|
|
449
|
+
Object.defineProperty(activeLink, "getBoundingClientRect", {
|
|
420
450
|
configurable: true,
|
|
421
|
-
value:
|
|
451
|
+
value: () => ({
|
|
452
|
+
top: 0,
|
|
453
|
+
bottom: 0,
|
|
454
|
+
left: 40,
|
|
455
|
+
right: 120,
|
|
456
|
+
width: 80,
|
|
457
|
+
height: 0,
|
|
458
|
+
x: 40,
|
|
459
|
+
y: 0,
|
|
460
|
+
toJSON: () => ({}),
|
|
461
|
+
}),
|
|
422
462
|
});
|
|
423
463
|
contentLeft.scrollTo = scrollToSpy;
|
|
424
464
|
|
|
@@ -433,6 +473,71 @@ describe("rendering AnchorNavigation", () => {
|
|
|
433
473
|
section.remove();
|
|
434
474
|
});
|
|
435
475
|
|
|
476
|
+
it("centers scroll-spy active item even when it is already visible", () => {
|
|
477
|
+
const { container } = render(<AnchorNavigation items={basicItems} />);
|
|
478
|
+
const anchorNavigationElement = initializeAnchorNavigation(container);
|
|
479
|
+
const anchorNavigation = AnchorNavigationStatic.getInstance(
|
|
480
|
+
anchorNavigationElement,
|
|
481
|
+
);
|
|
482
|
+
const contentLeft = container.querySelector(
|
|
483
|
+
".anchor-navigation__content-left",
|
|
484
|
+
);
|
|
485
|
+
const activeLink = container.querySelector('a[href="#pricing"]');
|
|
486
|
+
const scrollToSpy = vi.fn();
|
|
487
|
+
|
|
488
|
+
Object.defineProperty(contentLeft, "clientWidth", {
|
|
489
|
+
configurable: true,
|
|
490
|
+
value: 200,
|
|
491
|
+
});
|
|
492
|
+
Object.defineProperty(contentLeft, "scrollWidth", {
|
|
493
|
+
configurable: true,
|
|
494
|
+
value: 600,
|
|
495
|
+
});
|
|
496
|
+
Object.defineProperty(contentLeft, "scrollLeft", {
|
|
497
|
+
configurable: true,
|
|
498
|
+
value: 180,
|
|
499
|
+
writable: true,
|
|
500
|
+
});
|
|
501
|
+
Object.defineProperty(contentLeft, "getBoundingClientRect", {
|
|
502
|
+
configurable: true,
|
|
503
|
+
value: () => ({
|
|
504
|
+
top: 0,
|
|
505
|
+
bottom: 0,
|
|
506
|
+
left: 0,
|
|
507
|
+
right: 200,
|
|
508
|
+
width: 200,
|
|
509
|
+
height: 0,
|
|
510
|
+
x: 0,
|
|
511
|
+
y: 0,
|
|
512
|
+
toJSON: () => ({}),
|
|
513
|
+
}),
|
|
514
|
+
});
|
|
515
|
+
Object.defineProperty(activeLink, "getBoundingClientRect", {
|
|
516
|
+
configurable: true,
|
|
517
|
+
value: () => ({
|
|
518
|
+
top: 0,
|
|
519
|
+
bottom: 0,
|
|
520
|
+
left: 40,
|
|
521
|
+
right: 120,
|
|
522
|
+
width: 80,
|
|
523
|
+
height: 0,
|
|
524
|
+
x: 40,
|
|
525
|
+
y: 0,
|
|
526
|
+
toJSON: () => ({}),
|
|
527
|
+
}),
|
|
528
|
+
});
|
|
529
|
+
contentLeft.scrollTo = scrollToSpy;
|
|
530
|
+
|
|
531
|
+
anchorNavigation.scrollActiveLinkIntoView(contentLeft, activeLink, false);
|
|
532
|
+
|
|
533
|
+
expect(scrollToSpy).toHaveBeenCalledWith({
|
|
534
|
+
left: 160,
|
|
535
|
+
behavior: "smooth",
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
anchorNavigation?.destroy();
|
|
539
|
+
});
|
|
540
|
+
|
|
436
541
|
it("does not duplicate anchor click handling after update", () => {
|
|
437
542
|
const section = document.createElement("section");
|
|
438
543
|
section.id = "features";
|
|
@@ -498,6 +603,159 @@ describe("rendering AnchorNavigation", () => {
|
|
|
498
603
|
section.remove();
|
|
499
604
|
});
|
|
500
605
|
|
|
606
|
+
it("prefers document scroll-padding-top over internal sticky offset", () => {
|
|
607
|
+
const section = document.createElement("section");
|
|
608
|
+
section.id = "pricing";
|
|
609
|
+
Object.defineProperty(section, "getBoundingClientRect", {
|
|
610
|
+
configurable: true,
|
|
611
|
+
value: () => ({
|
|
612
|
+
top: 600 - window.scrollY,
|
|
613
|
+
bottom: 700 - window.scrollY,
|
|
614
|
+
left: 0,
|
|
615
|
+
right: 0,
|
|
616
|
+
width: 0,
|
|
617
|
+
height: 100,
|
|
618
|
+
x: 0,
|
|
619
|
+
y: 600,
|
|
620
|
+
toJSON: () => ({}),
|
|
621
|
+
}),
|
|
622
|
+
});
|
|
623
|
+
document.body.appendChild(section);
|
|
624
|
+
|
|
625
|
+
const megamenu = document.createElement("div");
|
|
626
|
+
megamenu.setAttribute("data-megamenu", "");
|
|
627
|
+
Object.defineProperty(megamenu, "offsetHeight", {
|
|
628
|
+
configurable: true,
|
|
629
|
+
value: 120,
|
|
630
|
+
});
|
|
631
|
+
document.body.appendChild(megamenu);
|
|
632
|
+
|
|
633
|
+
Object.defineProperty(window, "scrollY", {
|
|
634
|
+
configurable: true,
|
|
635
|
+
value: 0,
|
|
636
|
+
writable: true,
|
|
637
|
+
});
|
|
638
|
+
|
|
639
|
+
const previousScrollPaddingTop =
|
|
640
|
+
document.documentElement.style.scrollPaddingTop;
|
|
641
|
+
document.documentElement.style.scrollPaddingTop = "210px";
|
|
642
|
+
|
|
643
|
+
const scrollToSpy = vi
|
|
644
|
+
.spyOn(window, "scrollTo")
|
|
645
|
+
.mockImplementation((options) => {
|
|
646
|
+
if (typeof options === "object" && typeof options.top === "number") {
|
|
647
|
+
window.scrollY = options.top;
|
|
648
|
+
}
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
const { container } = render(<AnchorNavigation items={basicItems} />);
|
|
652
|
+
const anchorNavigationElement = initializeAnchorNavigation(container);
|
|
653
|
+
const anchorNavigation = AnchorNavigationStatic.getInstance(
|
|
654
|
+
anchorNavigationElement,
|
|
655
|
+
);
|
|
656
|
+
const pricingLink = container.querySelector('a[href="#pricing"]');
|
|
657
|
+
|
|
658
|
+
Object.defineProperty(anchorNavigationElement, "offsetHeight", {
|
|
659
|
+
configurable: true,
|
|
660
|
+
value: 50,
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
fireEvent.click(pricingLink);
|
|
664
|
+
|
|
665
|
+
expect(scrollToSpy).toHaveBeenNthCalledWith(1, {
|
|
666
|
+
top: 390,
|
|
667
|
+
behavior: "smooth",
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
anchorNavigation?.destroy();
|
|
671
|
+
scrollToSpy.mockRestore();
|
|
672
|
+
document.documentElement.style.scrollPaddingTop =
|
|
673
|
+
previousScrollPaddingTop;
|
|
674
|
+
megamenu.remove();
|
|
675
|
+
section.remove();
|
|
676
|
+
});
|
|
677
|
+
|
|
678
|
+
it("realigns anchor after sticky offset changes during smooth scroll", () => {
|
|
679
|
+
vi.useFakeTimers();
|
|
680
|
+
|
|
681
|
+
const section = document.createElement("section");
|
|
682
|
+
section.id = "pricing";
|
|
683
|
+
Object.defineProperty(section, "getBoundingClientRect", {
|
|
684
|
+
configurable: true,
|
|
685
|
+
value: () => ({
|
|
686
|
+
top: 600 - window.scrollY,
|
|
687
|
+
bottom: 700 - window.scrollY,
|
|
688
|
+
left: 0,
|
|
689
|
+
right: 0,
|
|
690
|
+
width: 0,
|
|
691
|
+
height: 100,
|
|
692
|
+
x: 0,
|
|
693
|
+
y: 600,
|
|
694
|
+
toJSON: () => ({}),
|
|
695
|
+
}),
|
|
696
|
+
});
|
|
697
|
+
document.body.appendChild(section);
|
|
698
|
+
|
|
699
|
+
const megamenu = document.createElement("div");
|
|
700
|
+
megamenu.setAttribute("data-megamenu", "");
|
|
701
|
+
let megamenuHeight = 120;
|
|
702
|
+
Object.defineProperty(megamenu, "offsetHeight", {
|
|
703
|
+
configurable: true,
|
|
704
|
+
get: () => megamenuHeight,
|
|
705
|
+
});
|
|
706
|
+
document.body.appendChild(megamenu);
|
|
707
|
+
|
|
708
|
+
Object.defineProperty(window, "scrollY", {
|
|
709
|
+
configurable: true,
|
|
710
|
+
value: 0,
|
|
711
|
+
writable: true,
|
|
712
|
+
});
|
|
713
|
+
|
|
714
|
+
const scrollToSpy = vi
|
|
715
|
+
.spyOn(window, "scrollTo")
|
|
716
|
+
.mockImplementation((options) => {
|
|
717
|
+
if (typeof options === "object" && typeof options.top === "number") {
|
|
718
|
+
window.scrollY = options.top;
|
|
719
|
+
}
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
const { container } = render(<AnchorNavigation items={basicItems} />);
|
|
723
|
+
const anchorNavigationElement = initializeAnchorNavigation(container);
|
|
724
|
+
const anchorNavigation = AnchorNavigationStatic.getInstance(
|
|
725
|
+
anchorNavigationElement,
|
|
726
|
+
);
|
|
727
|
+
const pricingLink = container.querySelector('a[href="#pricing"]');
|
|
728
|
+
|
|
729
|
+
Object.defineProperty(anchorNavigationElement, "offsetHeight", {
|
|
730
|
+
configurable: true,
|
|
731
|
+
value: 50,
|
|
732
|
+
});
|
|
733
|
+
|
|
734
|
+
fireEvent.click(pricingLink);
|
|
735
|
+
|
|
736
|
+
expect(scrollToSpy).toHaveBeenNthCalledWith(1, {
|
|
737
|
+
top: 430,
|
|
738
|
+
behavior: "smooth",
|
|
739
|
+
});
|
|
740
|
+
|
|
741
|
+
megamenuHeight = 80;
|
|
742
|
+
fireEvent.scroll(window);
|
|
743
|
+
vi.advanceTimersByTime(
|
|
744
|
+
AnchorNavigationStatic.SCROLL_END_DEBOUNCE_MS + 20,
|
|
745
|
+
);
|
|
746
|
+
|
|
747
|
+
expect(scrollToSpy).toHaveBeenNthCalledWith(2, {
|
|
748
|
+
top: 470,
|
|
749
|
+
behavior: "smooth",
|
|
750
|
+
});
|
|
751
|
+
|
|
752
|
+
anchorNavigation?.destroy();
|
|
753
|
+
scrollToSpy.mockRestore();
|
|
754
|
+
megamenu.remove();
|
|
755
|
+
section.remove();
|
|
756
|
+
vi.useRealTimers();
|
|
757
|
+
});
|
|
758
|
+
|
|
501
759
|
it("toggles left and right overflow classes based on scroll position", () => {
|
|
502
760
|
const { container } = render(<AnchorNavigation items={moreItems} />);
|
|
503
761
|
const anchorNavigationElement = initializeAnchorNavigation(container);
|
|
@@ -9,31 +9,26 @@
|
|
|
9
9
|
) {
|
|
10
10
|
display: flex;
|
|
11
11
|
flex-flow: row wrap;
|
|
12
|
-
|
|
13
|
-
margin:
|
|
12
|
+
gap: $spacing;
|
|
13
|
+
margin: 0 0 space.get("large") 0;
|
|
14
14
|
|
|
15
15
|
#{$button-selector},
|
|
16
|
-
#{$button-selector}:last-child,
|
|
17
16
|
#{$link-selector},
|
|
18
|
-
#{$link-selector}
|
|
19
|
-
|
|
20
|
-
button#{$link-selector}:last-child {
|
|
21
|
-
margin: $spacing $spacing 0 0;
|
|
17
|
+
button#{$link-selector} {
|
|
18
|
+
margin: 0;
|
|
22
19
|
}
|
|
23
20
|
}
|
|
24
21
|
|
|
25
22
|
@mixin stack-on-xs($spacing: config.$spacing, $button-selector: ".btn") {
|
|
26
23
|
@include breakpoint.get("xs", "down") {
|
|
27
24
|
flex-flow: column;
|
|
25
|
+
gap: $spacing;
|
|
28
26
|
max-width: 100%;
|
|
29
27
|
margin: 0 0 $spacing 0;
|
|
30
28
|
|
|
31
|
-
#{$button-selector}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
button.link:last-child {
|
|
35
|
-
margin-right: 0;
|
|
36
|
-
margin-bottom: 0;
|
|
29
|
+
#{$button-selector},
|
|
30
|
+
button.link {
|
|
31
|
+
margin: 0;
|
|
37
32
|
}
|
|
38
33
|
}
|
|
39
34
|
}
|
|
@@ -54,6 +54,7 @@ export const defaultConfig: SwiperOptions = {
|
|
|
54
54
|
hide: false,
|
|
55
55
|
},
|
|
56
56
|
slidesPerView: 1.2,
|
|
57
|
+
spaceBetween: 20,
|
|
57
58
|
mousewheel: {
|
|
58
59
|
forceToAxis: true,
|
|
59
60
|
sensitivity: 1,
|
|
@@ -362,25 +363,6 @@ export default class Carousel {
|
|
|
362
363
|
if (scrollbarEl) {
|
|
363
364
|
scrollbarEl.style.display = this.instance.enabled ? "" : "none";
|
|
364
365
|
}
|
|
365
|
-
|
|
366
|
-
this.applyTrackMarginCompensation();
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
/**
|
|
370
|
-
* Apply negative margin-right to carousel track when all slides fit on screen.
|
|
371
|
-
* This compensates for the 20px padding-right on each slide, ensuring proper grid alignment.
|
|
372
|
-
*/
|
|
373
|
-
private applyTrackMarginCompensation(): void {
|
|
374
|
-
if (!this.instance || !this.instance.params || !this.viewport) return;
|
|
375
|
-
|
|
376
|
-
const slidesPerView = Number(this.instance.params.slidesPerView) || 1;
|
|
377
|
-
const slidesCount = this.instance.slides.length;
|
|
378
|
-
|
|
379
|
-
if (slidesCount <= slidesPerView) {
|
|
380
|
-
this.viewport.style.setProperty("margin-right", "-20px", "important");
|
|
381
|
-
} else {
|
|
382
|
-
this.viewport.style.removeProperty("margin-right");
|
|
383
|
-
}
|
|
384
366
|
}
|
|
385
367
|
|
|
386
368
|
private applyBleedInsets(viewportWrapper: HTMLElement): void {
|
|
@@ -395,8 +377,8 @@ export default class Carousel {
|
|
|
395
377
|
|
|
396
378
|
const rect = viewportWrapper.getBoundingClientRect();
|
|
397
379
|
const insetLeft = Math.max(Math.round(rect.left), 0);
|
|
398
|
-
const
|
|
399
|
-
const insetAfter =
|
|
380
|
+
const insetRight = Math.max(Math.round(viewportWidth - rect.right), 0);
|
|
381
|
+
const insetAfter = insetRight;
|
|
400
382
|
|
|
401
383
|
const slidesPerView = Number(this.instance.params.slidesPerView) || 1;
|
|
402
384
|
const slidesCount = this.instance.slides.length;
|
|
@@ -415,11 +397,11 @@ export default class Carousel {
|
|
|
415
397
|
this.instance.params.slidesOffsetAfter = insetAfter;
|
|
416
398
|
this.element.style.setProperty(
|
|
417
399
|
"--carousel-bleed-viewport-width",
|
|
418
|
-
|
|
400
|
+
`${Math.round(viewportWidth)}px`,
|
|
419
401
|
);
|
|
420
402
|
this.element.style.setProperty(
|
|
421
403
|
"--carousel-bleed-margin-left",
|
|
422
|
-
|
|
404
|
+
`${-insetLeft}px`,
|
|
423
405
|
);
|
|
424
406
|
}
|
|
425
407
|
|
|
@@ -443,9 +425,6 @@ export default class Carousel {
|
|
|
443
425
|
|
|
444
426
|
const updateBleedState = () => {
|
|
445
427
|
this.applyBleedInsets(viewportWrapper);
|
|
446
|
-
|
|
447
|
-
// Update margin compensation on resize
|
|
448
|
-
this.applyTrackMarginCompensation();
|
|
449
428
|
};
|
|
450
429
|
|
|
451
430
|
this.bleedResizeHandler = updateBleedState;
|
|
@@ -644,5 +644,122 @@ describe("Carousel Static - Auto-Disable Feature", () => {
|
|
|
644
644
|
carouselInstance.updateCarouselEnabledState();
|
|
645
645
|
}).not.toThrow();
|
|
646
646
|
});
|
|
647
|
+
|
|
648
|
+
it("should not apply negative viewport margin on mobile when slides fit", () => {
|
|
649
|
+
const originalInnerWidth = window.innerWidth;
|
|
650
|
+
Object.defineProperty(window, "innerWidth", {
|
|
651
|
+
configurable: true,
|
|
652
|
+
writable: true,
|
|
653
|
+
value: 375,
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
mockSwiperInstance.slides = [document.createElement("div")];
|
|
657
|
+
mockSwiperInstance.params.slidesPerView = 1;
|
|
658
|
+
|
|
659
|
+
carouselInstance = new Carousel(carouselElement);
|
|
660
|
+
|
|
661
|
+
const viewport = carouselElement.querySelector(".carousel__viewport");
|
|
662
|
+
expect(viewport.style.getPropertyValue("margin-right")).toBe("");
|
|
663
|
+
|
|
664
|
+
Object.defineProperty(window, "innerWidth", {
|
|
665
|
+
configurable: true,
|
|
666
|
+
writable: true,
|
|
667
|
+
value: originalInnerWidth,
|
|
668
|
+
});
|
|
669
|
+
});
|
|
670
|
+
|
|
671
|
+
it("should not apply negative viewport margin on desktop when slides fit", () => {
|
|
672
|
+
const originalInnerWidth = window.innerWidth;
|
|
673
|
+
Object.defineProperty(window, "innerWidth", {
|
|
674
|
+
configurable: true,
|
|
675
|
+
writable: true,
|
|
676
|
+
value: 1240,
|
|
677
|
+
});
|
|
678
|
+
|
|
679
|
+
mockSwiperInstance.slides = [document.createElement("div")];
|
|
680
|
+
mockSwiperInstance.params.slidesPerView = 1;
|
|
681
|
+
|
|
682
|
+
carouselInstance = new Carousel(carouselElement);
|
|
683
|
+
|
|
684
|
+
const viewport = carouselElement.querySelector(".carousel__viewport");
|
|
685
|
+
expect(viewport.style.getPropertyValue("margin-right")).toBe("");
|
|
686
|
+
|
|
687
|
+
Object.defineProperty(window, "innerWidth", {
|
|
688
|
+
configurable: true,
|
|
689
|
+
writable: true,
|
|
690
|
+
value: originalInnerWidth,
|
|
691
|
+
});
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
it("should use right inset for bleed-right trailing offset", () => {
|
|
695
|
+
const originalInnerWidth = window.innerWidth;
|
|
696
|
+
Object.defineProperty(window, "innerWidth", {
|
|
697
|
+
configurable: true,
|
|
698
|
+
writable: true,
|
|
699
|
+
value: 1000,
|
|
700
|
+
});
|
|
701
|
+
|
|
702
|
+
mockSwiperInstance.slides = [
|
|
703
|
+
document.createElement("div"),
|
|
704
|
+
document.createElement("div"),
|
|
705
|
+
document.createElement("div"),
|
|
706
|
+
];
|
|
707
|
+
mockSwiperInstance.params.slidesPerView = 1.2;
|
|
708
|
+
mockSwiperInstance.params.spaceBetween = 20;
|
|
709
|
+
|
|
710
|
+
document.body.innerHTML = `
|
|
711
|
+
<div class="carousel carousel--bleed-right" data-carousel-id="test-carousel" id="test-carousel">
|
|
712
|
+
<div class="carousel__viewport-wrapper">
|
|
713
|
+
<div class="carousel__viewport">
|
|
714
|
+
<div class="carousel__track">
|
|
715
|
+
<div class="carousel__slide">Slide 1</div>
|
|
716
|
+
<div class="carousel__slide">Slide 2</div>
|
|
717
|
+
<div class="carousel__slide">Slide 3</div>
|
|
718
|
+
</div>
|
|
719
|
+
</div>
|
|
720
|
+
</div>
|
|
721
|
+
<div class="carousel__pagination"></div>
|
|
722
|
+
</div>
|
|
723
|
+
`;
|
|
724
|
+
|
|
725
|
+
carouselElement = document.querySelector(".carousel");
|
|
726
|
+
const viewportWrapper = carouselElement.querySelector(
|
|
727
|
+
".carousel__viewport-wrapper",
|
|
728
|
+
);
|
|
729
|
+
|
|
730
|
+
Object.defineProperty(viewportWrapper, "getBoundingClientRect", {
|
|
731
|
+
configurable: true,
|
|
732
|
+
value: () => ({
|
|
733
|
+
top: 0,
|
|
734
|
+
right: 920,
|
|
735
|
+
bottom: 200,
|
|
736
|
+
left: 120,
|
|
737
|
+
width: 800,
|
|
738
|
+
height: 200,
|
|
739
|
+
x: 120,
|
|
740
|
+
y: 0,
|
|
741
|
+
toJSON: () => ({}),
|
|
742
|
+
}),
|
|
743
|
+
});
|
|
744
|
+
|
|
745
|
+
carouselInstance = new Carousel(carouselElement);
|
|
746
|
+
|
|
747
|
+
expect(mockSwiperInstance.params.slidesOffsetBefore).toBe(120);
|
|
748
|
+
expect(mockSwiperInstance.params.slidesOffsetAfter).toBe(80);
|
|
749
|
+
expect(
|
|
750
|
+
carouselElement.style.getPropertyValue(
|
|
751
|
+
"--carousel-bleed-viewport-width",
|
|
752
|
+
),
|
|
753
|
+
).toBe("1000px");
|
|
754
|
+
expect(
|
|
755
|
+
carouselElement.style.getPropertyValue("--carousel-bleed-margin-left"),
|
|
756
|
+
).toBe("-120px");
|
|
757
|
+
|
|
758
|
+
Object.defineProperty(window, "innerWidth", {
|
|
759
|
+
configurable: true,
|
|
760
|
+
writable: true,
|
|
761
|
+
value: originalInnerWidth,
|
|
762
|
+
});
|
|
763
|
+
});
|
|
647
764
|
});
|
|
648
765
|
});
|
|
@@ -23,11 +23,15 @@
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
@mixin grid-column-gap(
|
|
26
|
+
@mixin grid-column-gap(
|
|
27
|
+
$size: "default",
|
|
28
|
+
$column-gap: config.$column-gap,
|
|
29
|
+
$force-important: false
|
|
30
|
+
) {
|
|
27
31
|
$gap: map.get($column-gap, $size);
|
|
28
32
|
|
|
29
33
|
@if ($size == "default" or $size == "small") {
|
|
30
|
-
@if ($size == "default") {
|
|
34
|
+
@if ($size == "default" and not $force-important) {
|
|
31
35
|
margin-left: -$gap;
|
|
32
36
|
margin-right: -$gap;
|
|
33
37
|
} @else {
|
|
@@ -46,7 +50,7 @@
|
|
|
46
50
|
$size: "default",
|
|
47
51
|
$column-gap: config.$column-gap
|
|
48
52
|
) {
|
|
49
|
-
@include grid-column-gap($size, $column-gap);
|
|
53
|
+
@include grid-column-gap($size, $column-gap, true);
|
|
50
54
|
}
|
|
51
55
|
|
|
52
56
|
@mixin grid-with-equal-height-content(
|
|
@@ -89,10 +93,14 @@
|
|
|
89
93
|
max-width: 100%;
|
|
90
94
|
}
|
|
91
95
|
|
|
92
|
-
@mixin grid-col-column-gap(
|
|
96
|
+
@mixin grid-col-column-gap(
|
|
97
|
+
$size: "default",
|
|
98
|
+
$column-gap: config.$column-gap,
|
|
99
|
+
$force-important: false
|
|
100
|
+
) {
|
|
93
101
|
$gap: map.get($column-gap, $size);
|
|
94
102
|
|
|
95
|
-
@if ($size == "default") {
|
|
103
|
+
@if ($size == "default" and not $force-important) {
|
|
96
104
|
padding-left: $gap;
|
|
97
105
|
padding-right: $gap;
|
|
98
106
|
} @else if ($size == "small") {
|
|
@@ -110,7 +118,7 @@
|
|
|
110
118
|
$size: "default",
|
|
111
119
|
$column-gap: config.$column-gap
|
|
112
120
|
) {
|
|
113
|
-
@include grid-col-column-gap($size, $column-gap);
|
|
121
|
+
@include grid-col-column-gap($size, $column-gap, true);
|
|
114
122
|
}
|
|
115
123
|
|
|
116
124
|
@mixin column-size($width: config.$grid-base, $grid-base: config.$grid-base) {
|