@orangesk/orange-design-system 2.0.0-beta.40 → 2.0.0-beta.42

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.
Files changed (30) hide show
  1. package/build/components/AnchorNavigation/style.css +1 -1
  2. package/build/components/AnchorNavigation/style.css.map +1 -1
  3. package/build/components/Buttons/style.css +1 -1
  4. package/build/components/Buttons/style.css.map +1 -1
  5. package/build/components/Grid/style.css +1 -1
  6. package/build/components/Grid/style.css.map +1 -1
  7. package/build/components/Link/style.css +1 -1
  8. package/build/components/Link/style.css.map +1 -1
  9. package/build/components/Modal/style.css +1 -1
  10. package/build/components/Modal/style.css.map +1 -1
  11. package/build/components/index.js +1 -1
  12. package/build/components/index.js.map +1 -1
  13. package/build/components/tsconfig.tsbuildinfo +1 -1
  14. package/build/components/types/src/components/AnchorNavigation/AnchorNavigation.static.d.ts +15 -0
  15. package/build/lib/components.css +1 -1
  16. package/build/lib/components.css.map +1 -1
  17. package/build/lib/scripts.js +1 -1
  18. package/build/lib/scripts.js.map +1 -1
  19. package/build/lib/style.css +1 -1
  20. package/build/lib/style.css.map +1 -1
  21. package/build/sprite.svg +1 -1
  22. package/package.json +20 -20
  23. package/src/assets/icons/youtube.svg +3 -1
  24. package/src/components/AnchorNavigation/AnchorNavigation.static.ts +178 -29
  25. package/src/components/AnchorNavigation/styles/mixins.scss +12 -3
  26. package/src/components/AnchorNavigation/tests/AnchorNavigation.unit.test.jsx +262 -14
  27. package/src/components/Buttons/styles/mixins.scss +8 -13
  28. package/src/components/Grid/styles/mixins.scss +14 -6
  29. package/src/components/Link/styles/mixins.scss +0 -1
  30. package/src/components/Modal/styles/mixins.scss +4 -0
@@ -274,9 +274,63 @@ describe("rendering AnchorNavigation", () => {
274
274
  section.remove();
275
275
  });
276
276
 
277
+ it("prevents mousedown default on non-interactive content-right area", () => {
278
+ const { container } = render(
279
+ <AnchorNavigation items={basicItems}>
280
+ <div className="align-lg-right mb-none">
281
+ <span>16 €</span>
282
+ <span className="text-secondary">S viazanostou 24 mesiacov</span>
283
+ </div>
284
+ <a href="/senior-pausal/chcem-senior">Kupit Senior pausal</a>
285
+ </AnchorNavigation>,
286
+ );
287
+ const anchorNavigationElement = initializeAnchorNavigation(container);
288
+ const anchorNavigation = AnchorNavigationStatic.getInstance(
289
+ anchorNavigationElement,
290
+ );
291
+ const infoBlock = container.querySelector(".align-lg-right");
292
+
293
+ const downEvent = new MouseEvent("mousedown", {
294
+ bubbles: true,
295
+ cancelable: true,
296
+ button: 0,
297
+ });
298
+ infoBlock?.dispatchEvent(downEvent);
299
+
300
+ expect(downEvent.defaultPrevented).toBe(true);
301
+
302
+ anchorNavigation?.destroy();
303
+ });
304
+
305
+ it("does not prevent mousedown default on interactive content-right link", () => {
306
+ const { container } = render(
307
+ <AnchorNavigation items={basicItems}>
308
+ <a href="/senior-pausal/chcem-senior">Kupit Senior pausal</a>
309
+ </AnchorNavigation>,
310
+ );
311
+ const anchorNavigationElement = initializeAnchorNavigation(container);
312
+ const anchorNavigation = AnchorNavigationStatic.getInstance(
313
+ anchorNavigationElement,
314
+ );
315
+ const ctaLink = container.querySelector(
316
+ 'a[href="/senior-pausal/chcem-senior"]',
317
+ );
318
+
319
+ const downEvent = new MouseEvent("mousedown", {
320
+ bubbles: true,
321
+ cancelable: true,
322
+ button: 0,
323
+ });
324
+ ctaLink?.dispatchEvent(downEvent);
325
+
326
+ expect(downEvent.defaultPrevented).toBe(false);
327
+
328
+ anchorNavigation?.destroy();
329
+ });
330
+
277
331
  it("scrolls active item using the left content viewport width", () => {
278
332
  const section = document.createElement("section");
279
- section.id = "contact";
333
+ section.id = "pricing";
280
334
  document.body.appendChild(section);
281
335
 
282
336
  const { container } = render(
@@ -292,29 +346,53 @@ describe("rendering AnchorNavigation", () => {
292
346
  const contentLeft = container.querySelector(
293
347
  ".anchor-navigation__content-left",
294
348
  );
295
- const activeLink = container.querySelector('a[href="#contact"]');
349
+ const activeLink = container.querySelector('a[href="#pricing"]');
296
350
  const scrollToSpy = vi.fn();
297
351
 
298
352
  Object.defineProperty(contentLeft, "clientWidth", {
299
353
  configurable: true,
300
354
  value: 180,
301
355
  });
356
+ Object.defineProperty(contentLeft, "scrollWidth", {
357
+ configurable: true,
358
+ value: 600,
359
+ });
302
360
  Object.defineProperty(contentLeft, "scrollLeft", {
303
361
  configurable: true,
304
362
  value: 0,
305
363
  writable: true,
306
364
  });
307
- Object.defineProperty(activeLink, "offsetLeft", {
365
+ Object.defineProperty(contentLeft, "getBoundingClientRect", {
308
366
  configurable: true,
309
- value: 220,
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
+ }),
310
378
  });
311
- Object.defineProperty(activeLink, "clientWidth", {
379
+ Object.defineProperty(activeLink, "getBoundingClientRect", {
312
380
  configurable: true,
313
- value: 80,
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
+ }),
314
392
  });
315
393
  contentLeft.scrollTo = scrollToSpy;
316
394
 
317
- anchorNavigation.initScrollSpy("contact");
395
+ anchorNavigation.initScrollSpy("pricing");
318
396
 
319
397
  expect(scrollToSpy).toHaveBeenCalledWith({
320
398
  left: 170,
@@ -327,7 +405,7 @@ describe("rendering AnchorNavigation", () => {
327
405
 
328
406
  it("centers clicked active item even when it is already visible", () => {
329
407
  const section = document.createElement("section");
330
- section.id = "contact";
408
+ section.id = "pricing";
331
409
  document.body.appendChild(section);
332
410
 
333
411
  const { container } = render(<AnchorNavigation items={basicItems} />);
@@ -338,29 +416,53 @@ describe("rendering AnchorNavigation", () => {
338
416
  const contentLeft = container.querySelector(
339
417
  ".anchor-navigation__content-left",
340
418
  );
341
- const activeLink = container.querySelector('a[href="#contact"]');
419
+ const activeLink = container.querySelector('a[href="#pricing"]');
342
420
  const scrollToSpy = vi.fn();
343
421
 
344
422
  Object.defineProperty(contentLeft, "clientWidth", {
345
423
  configurable: true,
346
424
  value: 200,
347
425
  });
426
+ Object.defineProperty(contentLeft, "scrollWidth", {
427
+ configurable: true,
428
+ value: 600,
429
+ });
348
430
  Object.defineProperty(contentLeft, "scrollLeft", {
349
431
  configurable: true,
350
432
  value: 180,
351
433
  writable: true,
352
434
  });
353
- Object.defineProperty(activeLink, "offsetLeft", {
435
+ Object.defineProperty(contentLeft, "getBoundingClientRect", {
354
436
  configurable: true,
355
- value: 220,
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
+ }),
356
448
  });
357
- Object.defineProperty(activeLink, "clientWidth", {
449
+ Object.defineProperty(activeLink, "getBoundingClientRect", {
358
450
  configurable: true,
359
- value: 80,
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
+ }),
360
462
  });
361
463
  contentLeft.scrollTo = scrollToSpy;
362
464
 
363
- anchorNavigation.initScrollSpy("contact");
465
+ anchorNavigation.initScrollSpy("pricing");
364
466
 
365
467
  expect(scrollToSpy).toHaveBeenCalledWith({
366
468
  left: 160,
@@ -371,6 +473,71 @@ describe("rendering AnchorNavigation", () => {
371
473
  section.remove();
372
474
  });
373
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
+
374
541
  it("does not duplicate anchor click handling after update", () => {
375
542
  const section = document.createElement("section");
376
543
  section.id = "features";
@@ -436,6 +603,87 @@ describe("rendering AnchorNavigation", () => {
436
603
  section.remove();
437
604
  });
438
605
 
606
+ it("realigns anchor after sticky offset changes during smooth scroll", () => {
607
+ vi.useFakeTimers();
608
+
609
+ const section = document.createElement("section");
610
+ section.id = "pricing";
611
+ Object.defineProperty(section, "getBoundingClientRect", {
612
+ configurable: true,
613
+ value: () => ({
614
+ top: 600 - window.scrollY,
615
+ bottom: 700 - window.scrollY,
616
+ left: 0,
617
+ right: 0,
618
+ width: 0,
619
+ height: 100,
620
+ x: 0,
621
+ y: 600,
622
+ toJSON: () => ({}),
623
+ }),
624
+ });
625
+ document.body.appendChild(section);
626
+
627
+ const megamenu = document.createElement("div");
628
+ megamenu.setAttribute("data-megamenu", "");
629
+ let megamenuHeight = 120;
630
+ Object.defineProperty(megamenu, "offsetHeight", {
631
+ configurable: true,
632
+ get: () => megamenuHeight,
633
+ });
634
+ document.body.appendChild(megamenu);
635
+
636
+ Object.defineProperty(window, "scrollY", {
637
+ configurable: true,
638
+ value: 0,
639
+ writable: true,
640
+ });
641
+
642
+ const scrollToSpy = vi
643
+ .spyOn(window, "scrollTo")
644
+ .mockImplementation((options) => {
645
+ if (typeof options === "object" && typeof options.top === "number") {
646
+ window.scrollY = options.top;
647
+ }
648
+ });
649
+
650
+ const { container } = render(<AnchorNavigation items={basicItems} />);
651
+ const anchorNavigationElement = initializeAnchorNavigation(container);
652
+ const anchorNavigation = AnchorNavigationStatic.getInstance(
653
+ anchorNavigationElement,
654
+ );
655
+ const pricingLink = container.querySelector('a[href="#pricing"]');
656
+
657
+ Object.defineProperty(anchorNavigationElement, "offsetHeight", {
658
+ configurable: true,
659
+ value: 50,
660
+ });
661
+
662
+ fireEvent.click(pricingLink);
663
+
664
+ expect(scrollToSpy).toHaveBeenNthCalledWith(1, {
665
+ top: 430,
666
+ behavior: "smooth",
667
+ });
668
+
669
+ megamenuHeight = 80;
670
+ fireEvent.scroll(window);
671
+ vi.advanceTimersByTime(
672
+ AnchorNavigationStatic.SCROLL_END_DEBOUNCE_MS + 20,
673
+ );
674
+
675
+ expect(scrollToSpy).toHaveBeenNthCalledWith(2, {
676
+ top: 470,
677
+ behavior: "smooth",
678
+ });
679
+
680
+ anchorNavigation?.destroy();
681
+ scrollToSpy.mockRestore();
682
+ megamenu.remove();
683
+ section.remove();
684
+ vi.useRealTimers();
685
+ });
686
+
439
687
  it("toggles left and right overflow classes based on scroll position", () => {
440
688
  const { container } = render(<AnchorNavigation items={moreItems} />);
441
689
  const anchorNavigationElement = initializeAnchorNavigation(container);
@@ -9,31 +9,26 @@
9
9
  ) {
10
10
  display: flex;
11
11
  flex-flow: row wrap;
12
- max-width: calc(100% - #{$spacing});
13
- margin: ($spacing * -1) ($spacing * -1) space.get("large") 0;
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}:last-child,
19
- button#{$link-selector},
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}:not(:last-child),
32
- #{$button-selector}:last-child,
33
- button.link:not(:last-child),
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
  }
@@ -23,11 +23,15 @@
23
23
  }
24
24
  }
25
25
 
26
- @mixin grid-column-gap($size: "default", $column-gap: config.$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($size: "default", $column-gap: config.$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) {
@@ -27,7 +27,6 @@
27
27
 
28
28
  @mixin icon {
29
29
  vertical-align: middle;
30
- transform: translateY(-4%);
31
30
  }
32
31
 
33
32
  @mixin icon-left {
@@ -97,6 +97,10 @@
97
97
  .divider {
98
98
  padding: 0;
99
99
  }
100
+
101
+ &:has(.divider) {
102
+ padding-bottom: 0;
103
+ }
100
104
  }
101
105
 
102
106
  @mixin close {