@orangesk/orange-design-system 3.4.0 → 3.5.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.
Files changed (45) hide show
  1. package/build/components/Carousel/style.css +1 -1
  2. package/build/components/Carousel/style.css.map +1 -1
  3. package/build/components/Footer/style.css +1 -1
  4. package/build/components/Footer/style.css.map +1 -1
  5. package/build/components/Megamenu/style.css +1 -1
  6. package/build/components/Megamenu/style.css.map +1 -1
  7. package/build/components/Table/style.css +1 -1
  8. package/build/components/Table/style.css.map +1 -1
  9. package/build/components/Tooltip/style.css +1 -1
  10. package/build/components/Tooltip/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/index.d.ts +9 -3
  15. package/build/components/types/src/components/Carousel/Carousel.d.ts +3 -1
  16. package/build/components/types/src/components/Carousel/Carousel.static.d.ts +1 -0
  17. package/build/components/types/src/components/Carousel/constants.d.ts +1 -0
  18. package/build/components/types/src/components/Megamenu/Megamenu.d.ts +6 -2
  19. package/build/components/types/src/components/Megamenu/MyOrangeMobilePanel.d.ts +2 -1
  20. package/build/lib/base.css.map +1 -1
  21. package/build/lib/components.css +1 -1
  22. package/build/lib/components.css.map +1 -1
  23. package/build/lib/footer.css +1 -1
  24. package/build/lib/footer.css.map +1 -1
  25. package/build/lib/megamenu.css +1 -1
  26. package/build/lib/megamenu.css.map +1 -1
  27. package/build/lib/scripts.js +1 -1
  28. package/build/lib/scripts.js.map +1 -1
  29. package/build/lib/style.css +1 -1
  30. package/build/lib/style.css.map +1 -1
  31. package/package.json +10 -10
  32. package/src/components/Carousel/Carousel.static.ts +25 -9
  33. package/src/components/Carousel/Carousel.tsx +5 -0
  34. package/src/components/Carousel/constants.ts +1 -0
  35. package/src/components/Carousel/styles/style.scss +2 -1
  36. package/src/components/Carousel/tests/Carousel.static.test.jsx +85 -0
  37. package/src/components/Carousel/tests/Carousel.unit.test.jsx +9 -0
  38. package/src/components/Footer/styles/style.scss +2 -0
  39. package/src/components/Megamenu/Megamenu.tsx +15 -3
  40. package/src/components/Megamenu/MyOrangeMobilePanel.tsx +24 -11
  41. package/src/components/Megamenu/styles/mixins.scss +6 -1
  42. package/src/components/Megamenu/tests/Megamenu.unit.test.jsx +33 -2
  43. package/src/components/Table/styles/config.scss +1 -0
  44. package/src/components/Table/styles/style.scss +6 -0
  45. package/src/components/Tooltip/styles/style.scss +5 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orangesk/orange-design-system",
3
- "version": "3.4.0",
3
+ "version": "3.5.0",
4
4
  "private": false,
5
5
  "engines": {
6
6
  "node": ">=20.x"
@@ -56,7 +56,7 @@
56
56
  "@cloudfour/transition-hidden-element": "^2.0.2",
57
57
  "@mdx-js/loader": "^3.1.1",
58
58
  "@mdx-js/react": "^3.1.1",
59
- "@next/mdx": "16.3.0",
59
+ "@next/mdx": "16.3.1",
60
60
  "@orangesk/accessible-autocomplete": "3.2.2",
61
61
  "@popperjs/core": "^2.11.8",
62
62
  "@types/mdx": "^2.0.14",
@@ -65,14 +65,14 @@
65
65
  "daypickr": "^0.3.4",
66
66
  "diff2html": "^3.4.56",
67
67
  "dompurify": "^3.4.13",
68
- "html-react-parser": "6.1.5",
68
+ "html-react-parser": "6.1.7",
69
69
  "lorem-ipsum": "3.0.0",
70
70
  "minisearch": "7.2.0",
71
- "next": "16.3.0",
71
+ "next": "16.3.1",
72
72
  "normalize.css": "^8.0.1",
73
73
  "nouislider": "^15.8.1",
74
74
  "prism-react-renderer": "^2.4.1",
75
- "query-string": "^9.4.1",
75
+ "query-string": "^9.5.0",
76
76
  "react": "^19.2.8",
77
77
  "react-dom": "^19.2.8",
78
78
  "react-element-to-jsx-string": "^17.0.1",
@@ -81,7 +81,7 @@
81
81
  "rehype-slug": "^6.0.0",
82
82
  "remark-gemoji": "^8.0.0",
83
83
  "remark-gfm": "^4.0.1",
84
- "swiper": "14.0.7",
84
+ "swiper": "14.1.0",
85
85
  "tabbable": "^6.5.0",
86
86
  "unescape-html": "^1.1.0",
87
87
  "wnumb": "^1.2.0"
@@ -102,10 +102,10 @@
102
102
  "@rollup/plugin-url": "^8.0.2",
103
103
  "@rollup/rollup-darwin-arm64": "^4.62.4",
104
104
  "@testing-library/dom": "^10.4.1",
105
- "@testing-library/jest-dom": "7.0.0",
105
+ "@testing-library/jest-dom": "7.0.1",
106
106
  "@testing-library/react": "^16.3.2",
107
- "@testing-library/user-event": "^14.6.3",
108
- "@types/node": "26.1.2",
107
+ "@testing-library/user-event": "^14.6.5",
108
+ "@types/node": "26.2.0",
109
109
  "@types/react": "19.2.18",
110
110
  "@types/react-dom": "19.2.4",
111
111
  "@types/wnumb": "^1.2.3",
@@ -117,7 +117,7 @@
117
117
  "canvas": "^3.2.3",
118
118
  "fs-extra": "^11.4.0",
119
119
  "glob": "13.0.6",
120
- "html-validate": "11.6.2",
120
+ "html-validate": "11.8.0",
121
121
  "husky": "^9.1.7",
122
122
  "identity-obj-proxy": "^3.0.0",
123
123
  "jsdom": "30.0.1",
@@ -14,6 +14,7 @@ import Tooltip from "../Tooltip/Tooltip.static";
14
14
  import {
15
15
  CLASS_ACTIVE,
16
16
  CLASS_BLEED_RIGHT,
17
+ CLASS_BLEED_RIGHT_NO_LEFT,
17
18
  CLASS_DOT,
18
19
  CLASS_SCROLLBAR_DRAG,
19
20
  CLASS_SCROLLBAR_HORIZONTAL,
@@ -113,6 +114,13 @@ export default class Carousel {
113
114
  ) as HTMLElement | null;
114
115
  }
115
116
 
117
+ private isBleedRight(): boolean {
118
+ return (
119
+ this.element.classList.contains(CLASS_BLEED_RIGHT) ||
120
+ this.element.classList.contains(CLASS_BLEED_RIGHT_NO_LEFT)
121
+ );
122
+ }
123
+
116
124
  private getSlidesPerView(): number {
117
125
  return Number(this.instance?.params?.slidesPerView) || 1;
118
126
  }
@@ -146,7 +154,7 @@ export default class Carousel {
146
154
  }
147
155
 
148
156
  private getOverflowWidth(viewportWrapper?: HTMLElement): number {
149
- const isBleedRight = this.element.classList.contains(CLASS_BLEED_RIGHT);
157
+ const isBleedRight = this.isBleedRight();
150
158
  const containerWidth = isBleedRight
151
159
  ? this.element.clientWidth || viewportWrapper?.clientWidth || 0
152
160
  : this.viewport?.clientWidth || 0;
@@ -223,7 +231,7 @@ export default class Carousel {
223
231
  this.getCustomOptions();
224
232
  }
225
233
 
226
- const isBleedRight = this.element.classList.contains(CLASS_BLEED_RIGHT);
234
+ const isBleedRight = this.isBleedRight();
227
235
 
228
236
  this.instance = new Swiper(this.viewport, {
229
237
  ...this.config,
@@ -248,7 +256,7 @@ export default class Carousel {
248
256
 
249
257
  this.updateCarouselEnabledState();
250
258
 
251
- if (this.element.classList.contains(CLASS_BLEED_RIGHT)) {
259
+ if (this.isBleedRight()) {
252
260
  this.adjustConfigForBleedRight();
253
261
  this.fixBleedRightScrollbar();
254
262
  }
@@ -480,13 +488,18 @@ export default class Carousel {
480
488
  document.documentElement?.clientWidth || window.innerWidth || 0;
481
489
  const wrapperRect = viewportWrapper.getBoundingClientRect();
482
490
  const rootRect = this.element.getBoundingClientRect();
491
+ const isBleedRightNoLeft = this.element.classList.contains(
492
+ CLASS_BLEED_RIGHT_NO_LEFT,
493
+ );
483
494
  const stableLeftInsetSource =
484
495
  rootRect.left > 0 ? rootRect.left : wrapperRect.left;
485
496
  const leftInset = Math.max(Math.floor(stableLeftInsetSource), 0);
486
- const shellWidth = Math.max(Math.floor(viewportWidth), containerWidth, 0);
487
- const shellMarginLeft = -leftInset;
497
+ const shellWidth = isBleedRightNoLeft
498
+ ? Math.max(Math.floor(viewportWidth - leftInset), containerWidth, 0)
499
+ : Math.max(Math.floor(viewportWidth), containerWidth, 0);
500
+ const shellMarginLeft = isBleedRightNoLeft ? 0 : -leftInset;
488
501
  const bleedViewportWidth = Math.max(
489
- shellWidth - leftInset,
502
+ isBleedRightNoLeft ? shellWidth : shellWidth - leftInset,
490
503
  containerWidth,
491
504
  0,
492
505
  );
@@ -501,11 +514,12 @@ export default class Carousel {
501
514
  : slidesCount > slidesPerView;
502
515
  const shouldDisableBleed = !hasIntrinsicOverflow;
503
516
  const shouldEnableBleedClass = !shouldDisableBleed;
504
- const hadBleedClass = this.element.classList.contains(CLASS_BLEED_RIGHT);
517
+ const hadBleedClass = this.isBleedRight();
505
518
  const nextBleedViewportWidth = shouldDisableBleed
506
519
  ? "100%"
507
520
  : `${bleedViewportWidth}px`;
508
- const nextBleedMarginLeft = shouldDisableBleed ? "0px" : `${leftInset}px`;
521
+ const nextBleedMarginLeft =
522
+ shouldDisableBleed || isBleedRightNoLeft ? "0px" : `${leftInset}px`;
509
523
  const nextBleedShellWidth = shouldDisableBleed ? "100%" : `${shellWidth}px`;
510
524
  const nextBleedShellMarginLeft = shouldDisableBleed
511
525
  ? "0px"
@@ -524,7 +538,9 @@ export default class Carousel {
524
538
  "--carousel-bleed-shell-margin-left",
525
539
  ) !== nextBleedShellMarginLeft;
526
540
 
527
- this.element.classList.toggle(CLASS_BLEED_RIGHT, shouldEnableBleedClass);
541
+ if (!isBleedRightNoLeft) {
542
+ this.element.classList.toggle(CLASS_BLEED_RIGHT, shouldEnableBleedClass);
543
+ }
528
544
 
529
545
  const baseWidth = shouldDisableBleed ? undefined : containerWidth;
530
546
  this.instance.params.width = baseWidth;
@@ -7,6 +7,7 @@ import { Controls } from "../Controls";
7
7
  import CarouselStatic from "./Carousel.static";
8
8
  import { CarouselItem } from "./CarouselItem";
9
9
  import {
10
+ CLASS_BLEED_RIGHT_NO_LEFT,
10
11
  CLASS_CONTROLS,
11
12
  CLASS_DOTS,
12
13
  CLASS_NAVIGATION,
@@ -33,6 +34,8 @@ interface CarouselProps<T = ReactNode> extends HTMLAttributes<HTMLDivElement> {
33
34
  showScrollbar?: boolean;
34
35
  /** Make carousel bleed to the right edge of screen while keeping left aligned with container */
35
36
  bleedRight?: boolean;
37
+ /** Make carousel bleed right from its root edge without bleeding left */
38
+ bleedRightNoLeft?: boolean;
36
39
  className?: string;
37
40
  }
38
41
 
@@ -48,6 +51,7 @@ const Carousel = <T,>({
48
51
  renderItems,
49
52
  showScrollbar = false,
50
53
  bleedRight = false,
54
+ bleedRightNoLeft = false,
51
55
  ...other
52
56
  }: CarouselProps<T>) => {
53
57
  const [carouselRef] = useStatic(CarouselStatic);
@@ -71,6 +75,7 @@ const Carousel = <T,>({
71
75
  const classes = cx(CLASS_ROOT, className, {
72
76
  [`${CLASS_ROOT}--scrollbar`]: showScrollbar,
73
77
  [`${CLASS_ROOT}--bleed-right`]: bleedRight,
78
+ [CLASS_BLEED_RIGHT_NO_LEFT]: bleedRightNoLeft,
74
79
  });
75
80
 
76
81
  const elementClasses = {
@@ -18,6 +18,7 @@ export const CLASS_SCROLLBAR_DRAG = `${CLASS_ROOT}__scrollbar-drag`;
18
18
  export const CLASS_ACTIVE = "is-active";
19
19
  export const CLASS_SCROLLBAR_VARIANT = `${CLASS_ROOT}--scrollbar`;
20
20
  export const CLASS_BLEED_RIGHT = `${CLASS_ROOT}--bleed-right`;
21
+ export const CLASS_BLEED_RIGHT_NO_LEFT = `${CLASS_ROOT}--bleed-right-no-left`;
21
22
 
22
23
  export const SELECTOR_VIEWPORT = `.${CLASS_VIEWPORT}`;
23
24
  export const SELECTOR_TRACK = `.${CLASS_TRACK}`;
@@ -9,7 +9,8 @@
9
9
  @include mixins.scrollbar-variant;
10
10
  }
11
11
 
12
- &--bleed-right {
12
+ &--bleed-right,
13
+ &--bleed-right-no-left {
13
14
  @include mixins.bleed-right-variant;
14
15
  }
15
16
 
@@ -901,6 +901,91 @@ describe("Carousel Static - Auto-Disable Feature", () => {
901
901
  });
902
902
  });
903
903
 
904
+ it("should keep the left edge fixed for no-left bleed geometry", () => {
905
+ const originalInnerWidth = window.innerWidth;
906
+ Object.defineProperty(window, "innerWidth", {
907
+ configurable: true,
908
+ writable: true,
909
+ value: 1000,
910
+ });
911
+
912
+ mockSwiperInstance.slides = [
913
+ document.createElement("div"),
914
+ document.createElement("div"),
915
+ document.createElement("div"),
916
+ ];
917
+ mockSwiperInstance.params.slidesPerView = 1.2;
918
+
919
+ document.body.innerHTML = `
920
+ <div class="carousel carousel--bleed-right-no-left" data-carousel-id="test-carousel" id="test-carousel">
921
+ <div class="carousel__viewport-wrapper">
922
+ <div class="carousel__viewport">
923
+ <div class="carousel__track">
924
+ <div class="carousel__slide">Slide 1</div>
925
+ <div class="carousel__slide">Slide 2</div>
926
+ <div class="carousel__slide">Slide 3</div>
927
+ </div>
928
+ </div>
929
+ </div>
930
+ <div class="carousel__pagination"></div>
931
+ </div>
932
+ `;
933
+
934
+ carouselElement = document.querySelector(".carousel");
935
+ const viewportWrapper = carouselElement.querySelector(
936
+ ".carousel__viewport-wrapper",
937
+ );
938
+ const track = carouselElement.querySelector(".carousel__track");
939
+
940
+ Object.defineProperty(viewportWrapper, "clientWidth", {
941
+ configurable: true,
942
+ value: 800,
943
+ });
944
+ Object.defineProperty(track, "scrollWidth", {
945
+ configurable: true,
946
+ value: 1200,
947
+ });
948
+ Object.defineProperty(viewportWrapper, "getBoundingClientRect", {
949
+ configurable: true,
950
+ value: () => ({
951
+ top: 0,
952
+ right: 920,
953
+ bottom: 200,
954
+ left: 120,
955
+ width: 800,
956
+ height: 200,
957
+ x: 120,
958
+ y: 0,
959
+ toJSON: () => ({}),
960
+ }),
961
+ });
962
+
963
+ carouselInstance = new Carousel(carouselElement);
964
+
965
+ expect(
966
+ carouselElement.style.getPropertyValue(
967
+ "--carousel-bleed-viewport-width",
968
+ ),
969
+ ).toBe("880px");
970
+ expect(
971
+ carouselElement.style.getPropertyValue("--carousel-bleed-margin-left"),
972
+ ).toBe("0px");
973
+ expect(
974
+ carouselElement.style.getPropertyValue("--carousel-bleed-shell-width"),
975
+ ).toBe("880px");
976
+ expect(
977
+ carouselElement.style.getPropertyValue(
978
+ "--carousel-bleed-shell-margin-left",
979
+ ),
980
+ ).toBe("0px");
981
+
982
+ Object.defineProperty(window, "innerWidth", {
983
+ configurable: true,
984
+ writable: true,
985
+ value: originalInnerWidth,
986
+ });
987
+ });
988
+
904
989
  it("should calculate bleed-right scrollbar drag from logical viewport, not shell width", () => {
905
990
  mockSwiperInstance.slides = [
906
991
  document.createElement("div"),
@@ -365,6 +365,15 @@ describe("rendering Carousel", () => {
365
365
  expect(carousel).toHaveClass("carousel--bleed-right");
366
366
  });
367
367
 
368
+ it("should support right bleed without left bleed", () => {
369
+ const { container } = render(
370
+ <Carousel items={items} bleedRightNoLeft showScrollbar />,
371
+ );
372
+ const carousel = container.querySelector(".carousel");
373
+ expect(carousel).toHaveClass("carousel--bleed-right-no-left");
374
+ expect(carousel).not.toHaveClass("carousel--bleed-right");
375
+ });
376
+
368
377
  it("should support minimal slides for testing auto-disable", () => {
369
378
  const minimalItems = [<p key="item1">item1</p>];
370
379
  const { container } = render(<Carousel items={minimalItems} />);
@@ -9,10 +9,12 @@
9
9
  }
10
10
 
11
11
  #{config.$class-root},
12
+ .is-light #{config.$class-root},
12
13
  #{config.$class-root}.is-light {
13
14
  @include megamenuMixins.light-vars;
14
15
  }
15
16
 
17
+ .is-dark #{config.$class-root},
16
18
  #{config.$class-root}.is-dark {
17
19
  @include megamenuMixins.dark-vars;
18
20
  }
@@ -81,8 +81,12 @@ export type MegamenuProps = {
81
81
  searchFilled?: boolean;
82
82
  compactLogoOnly?: boolean;
83
83
  isB2B?: boolean;
84
- /** Optional number of items displayed on the cart badge. */
84
+ /** Controls whether My Orange panel shows logged-in or logged-out content. */
85
+ isLoggedIn?: boolean;
86
+ /** Number of items displayed on the cart badge. Empty cart when omitted or zero. */
85
87
  cartItems?: number;
88
+ /** Shows an orange dot for a non-empty cart when item count is unavailable. */
89
+ cartHasItems?: boolean;
86
90
  /** Tiles displayed below every desktop and mobile menu section. */
87
91
  tiles?: MegamenuTile[];
88
92
  };
@@ -228,13 +232,16 @@ export const Megamenu = ({
228
232
  searchFilled,
229
233
  compactLogoOnly = false,
230
234
  isB2B = false,
235
+ isLoggedIn = true,
231
236
  cartItems,
237
+ cartHasItems = false,
232
238
  tiles = megamenuTiles,
233
239
  }: MegamenuProps) => {
234
240
  const ids = getMegamenuIds("main");
235
241
  const { hasSearchEmpty, hasSearchFilled, showSearchState, searchValue } =
236
242
  getMegamenuSearchState(searchEmpty, searchFilled);
237
- const hasCartItems = cartItems !== undefined;
243
+ const hasCartItems = cartItems !== undefined && cartItems > 0;
244
+ const showCartDot = cartHasItems && !hasCartItems;
238
245
 
239
246
  return (
240
247
  <header>
@@ -440,7 +447,11 @@ export const Megamenu = ({
440
447
  />
441
448
  </span>
442
449
  ) : (
443
- <span className={CLASS_NAV_CART_ICON} aria-hidden="true">
450
+ <span
451
+ className={CLASS_NAV_CART_ICON}
452
+ data-cart-has-items={showCartDot ? "true" : undefined}
453
+ aria-hidden="true"
454
+ >
444
455
  <MegamenuIcon
445
456
  width={24}
446
457
  height={24}
@@ -745,6 +756,7 @@ export const Megamenu = ({
745
756
  panelId={ids.myOrangePanelId}
746
757
  titleId={ids.myOrangeTitleId}
747
758
  isB2B={isB2B}
759
+ isLoggedIn={isLoggedIn}
748
760
  />
749
761
 
750
762
  <button
@@ -31,12 +31,14 @@ type MyOrangeMobilePanelProps = {
31
31
  titleId: string;
32
32
  panelId?: string;
33
33
  isB2B?: boolean;
34
+ isLoggedIn?: boolean;
34
35
  };
35
36
 
36
37
  export const MyOrangeMobilePanel = ({
37
38
  titleId,
38
39
  panelId,
39
40
  isB2B = false,
41
+ isLoggedIn = true,
40
42
  }: MyOrangeMobilePanelProps) => {
41
43
  return (
42
44
  <MegamenuMobilePanel
@@ -65,18 +67,29 @@ export const MyOrangeMobilePanel = ({
65
67
  <div className={CLASS_MOBILE_ACCOUNT_AVATAR} aria-hidden="true">
66
68
  <MegamenuIcon name="user" width={72} height={72} />
67
69
  </div>
68
- <p className={CLASS_MOBILE_ACCOUNT_PHONE}>0905 123 456</p>
69
- <a href="#" className={CLASS_MOBILE_ACCOUNT_LOGOUT}>
70
- Odhlásiť
71
- </a>
72
- <a href="#" className={CLASS_BUTTON}>
73
- Orange Business
74
- </a>
75
- {isB2B ? (
76
- <a href="#" className={cx(CLASS_BUTTON, CLASS_BUTTON_SECONDARY)}>
77
- My Orange
70
+ {isLoggedIn ? (
71
+ <>
72
+ <p className={CLASS_MOBILE_ACCOUNT_PHONE}>0905 123 456</p>
73
+ <a href="#" className={CLASS_MOBILE_ACCOUNT_LOGOUT}>
74
+ Odhlásiť
75
+ </a>
76
+ <a href="#" className={CLASS_BUTTON}>
77
+ Orange Business
78
+ </a>
79
+ {isB2B ? (
80
+ <a
81
+ href="#"
82
+ className={cx(CLASS_BUTTON, CLASS_BUTTON_SECONDARY)}
83
+ >
84
+ My Orange
85
+ </a>
86
+ ) : null}
87
+ </>
88
+ ) : (
89
+ <a href="#" className={CLASS_BUTTON}>
90
+ Prihlásenie
78
91
  </a>
79
- ) : null}
92
+ )}
80
93
  </div>
81
94
  </div>
82
95
 
@@ -461,7 +461,7 @@
461
461
  @mixin nav-cart-icon {
462
462
  position: relative;
463
463
 
464
- &:after {
464
+ &::after {
465
465
  content: "";
466
466
  position: absolute;
467
467
  right: -2px;
@@ -470,6 +470,11 @@
470
470
  height: convert.to-rem(8px);
471
471
  background-color: var(--color-icon-brand);
472
472
  border-radius: 50%;
473
+ display: none;
474
+ }
475
+
476
+ &[data-cart-has-items]::after {
477
+ display: block;
473
478
  }
474
479
 
475
480
  &[data-items-in-cart]::after {
@@ -85,11 +85,11 @@ describe("Megamenu logo markup", () => {
85
85
  ).toHaveTextContent("Chcem nové číslo");
86
86
  });
87
87
 
88
- it("renders orange cart dot by default", () => {
88
+ it("renders empty cart by default", () => {
89
89
  const { container } = render(<Megamenu notSticky />);
90
90
 
91
91
  const cart = container.querySelector(
92
- ".megamenu__nav-cart-icon:not([data-items-in-cart])",
92
+ ".megamenu__nav-cart-icon:not([data-items-in-cart]):not([data-cart-has-items])",
93
93
  );
94
94
 
95
95
  expect(cart).toBeInTheDocument();
@@ -97,6 +97,25 @@ describe("Megamenu logo markup", () => {
97
97
  expect(cart?.nextElementSibling).not.toBeInTheDocument();
98
98
  });
99
99
 
100
+ it("renders optional orange cart dot", () => {
101
+ const { container } = render(<Megamenu cartHasItems notSticky />);
102
+
103
+ const cart = container.querySelector(
104
+ ".megamenu__nav-cart-icon[data-cart-has-items]",
105
+ );
106
+
107
+ expect(cart).toBeInTheDocument();
108
+ expect(cart).toHaveAttribute("data-cart-has-items", "true");
109
+ });
110
+
111
+ it("renders logged-out My Orange panel content", () => {
112
+ const { container } = render(<Megamenu isLoggedIn={false} notSticky />);
113
+
114
+ expect(container).toHaveTextContent("Prihlásenie");
115
+ expect(container).not.toHaveTextContent("Odhlásiť");
116
+ expect(container).not.toHaveTextContent("0905 123 456");
117
+ });
118
+
100
119
  it("renders optional cart item count", () => {
101
120
  const { container } = render(<Megamenu cartItems={3} notSticky />);
102
121
 
@@ -111,4 +130,16 @@ describe("Megamenu logo markup", () => {
111
130
  );
112
131
  expect(cart?.nextElementSibling).toHaveTextContent("3 položka v košíku");
113
132
  });
133
+
134
+ it("renders empty cart without a badge", () => {
135
+ const { container } = render(<Megamenu cartItems={0} notSticky />);
136
+
137
+ const cart = container.querySelector(
138
+ ".megamenu__nav-cart-icon:not([data-items-in-cart])",
139
+ );
140
+
141
+ expect(cart).toBeInTheDocument();
142
+ expect(cart?.parentElement).toHaveAttribute("aria-label", "Košík");
143
+ expect(cart?.nextElementSibling).not.toBeInTheDocument();
144
+ });
114
145
  });
@@ -1,4 +1,5 @@
1
1
  $arrow-size: 5px;
2
2
  $striped-color: var(--color-background-secondary);
3
+ $striped-color-on-secondary: var(--color-background-primary);
3
4
  $normal-border-size: 1px;
4
5
  $fat-border-size: 2px;
@@ -1,4 +1,5 @@
1
1
  @use "./mixins";
2
+ @use "./config";
2
3
  @use "../../../styles/tokens/breakpoint";
3
4
  @use "../../../styles/tools/generate";
4
5
 
@@ -39,6 +40,11 @@
39
40
  @include mixins.odd-row;
40
41
  }
41
42
 
43
+ &--striped.background-secondary tbody tr:nth-of-type(odd),
44
+ .background-secondary &--striped tbody tr:nth-of-type(odd) {
45
+ background-color: config.$striped-color-on-secondary;
46
+ }
47
+
42
48
  &--compact {
43
49
  @include mixins.compact;
44
50
  }
@@ -22,6 +22,11 @@
22
22
  .info-tooltip {
23
23
  @include mixins.info-tooltip;
24
24
 
25
+ .background-contrast &,
26
+ .surface-contrast & {
27
+ color: var(--color-text-inverse);
28
+ }
29
+
25
30
  &.is-active &__icon,
26
31
  &:focus &__icon {
27
32
  @include mixins.info-tooltip-active-icon;