@orangesk/orange-design-system 2.0.0-beta.3 → 2.0.0-beta.4

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 (89) hide show
  1. package/build/components/Accordion/tsconfig.tsbuildinfo +1 -1
  2. package/build/components/Alert/tsconfig.tsbuildinfo +1 -1
  3. package/build/components/AnchorNavigation/tsconfig.tsbuildinfo +1 -1
  4. package/build/components/Bar/tsconfig.tsbuildinfo +1 -1
  5. package/build/components/BlockAction/tsconfig.tsbuildinfo +1 -1
  6. package/build/components/BodyBanner/tsconfig.tsbuildinfo +1 -1
  7. package/build/components/Breadcrumbs/tsconfig.tsbuildinfo +1 -1
  8. package/build/components/Button/tsconfig.tsbuildinfo +1 -1
  9. package/build/components/Buttons/tsconfig.tsbuildinfo +1 -1
  10. package/build/components/Card/tsconfig.tsbuildinfo +1 -1
  11. package/build/components/Carousel/tsconfig.tsbuildinfo +1 -1
  12. package/build/components/CarouselHero/index.js +16 -0
  13. package/build/components/CarouselHero/index.js.map +1 -0
  14. package/build/components/CarouselHero/tsconfig.tsbuildinfo +1 -0
  15. package/build/components/CarouselPromotions/tsconfig.tsbuildinfo +1 -1
  16. package/build/components/CartTable/tsconfig.tsbuildinfo +1 -1
  17. package/build/components/Code/tsconfig.tsbuildinfo +1 -1
  18. package/build/components/Container/tsconfig.tsbuildinfo +1 -1
  19. package/build/components/Controls/tsconfig.tsbuildinfo +1 -1
  20. package/build/components/Cover/tsconfig.tsbuildinfo +1 -1
  21. package/build/components/Divider/tsconfig.tsbuildinfo +1 -1
  22. package/build/components/DocumentationSidebar/index.js +1 -1
  23. package/build/components/DocumentationSidebar/tsconfig.tsbuildinfo +1 -1
  24. package/build/components/Dropdown/tsconfig.tsbuildinfo +1 -1
  25. package/build/components/Expander/tsconfig.tsbuildinfo +1 -1
  26. package/build/components/FeatureAccordion/tsconfig.tsbuildinfo +1 -1
  27. package/build/components/Footer/tsconfig.tsbuildinfo +1 -1
  28. package/build/components/Forms/tsconfig.tsbuildinfo +1 -1
  29. package/build/components/Gauge/tsconfig.tsbuildinfo +1 -1
  30. package/build/components/Grid/tsconfig.tsbuildinfo +1 -1
  31. package/build/components/Hero/tsconfig.tsbuildinfo +1 -1
  32. package/build/components/Icon/tsconfig.tsbuildinfo +1 -1
  33. package/build/components/IconList/tsconfig.tsbuildinfo +1 -1
  34. package/build/components/Image/tsconfig.tsbuildinfo +1 -1
  35. package/build/components/Link/tsconfig.tsbuildinfo +1 -1
  36. package/build/components/List/tsconfig.tsbuildinfo +1 -1
  37. package/build/components/Loader/tsconfig.tsbuildinfo +1 -1
  38. package/build/components/Megamenu/tsconfig.tsbuildinfo +1 -1
  39. package/build/components/Modal/tsconfig.tsbuildinfo +1 -1
  40. package/build/components/Pagination/tsconfig.tsbuildinfo +1 -1
  41. package/build/components/Pill/tsconfig.tsbuildinfo +1 -1
  42. package/build/components/Preview/tsconfig.tsbuildinfo +1 -1
  43. package/build/components/Progress/tsconfig.tsbuildinfo +1 -1
  44. package/build/components/PromoBanner/tsconfig.tsbuildinfo +1 -1
  45. package/build/components/PromotionCard/tsconfig.tsbuildinfo +1 -1
  46. package/build/components/Section/tsconfig.tsbuildinfo +1 -1
  47. package/build/components/Skeleton/tsconfig.tsbuildinfo +1 -1
  48. package/build/components/SkipLink/tsconfig.tsbuildinfo +1 -1
  49. package/build/components/Stepbar/tsconfig.tsbuildinfo +1 -1
  50. package/build/components/Sticker/tsconfig.tsbuildinfo +1 -1
  51. package/build/components/Table/tsconfig.tsbuildinfo +1 -1
  52. package/build/components/Tabs/tsconfig.tsbuildinfo +1 -1
  53. package/build/components/Tag/tsconfig.tsbuildinfo +1 -1
  54. package/build/components/Testimonial/tsconfig.tsbuildinfo +1 -1
  55. package/build/components/Tile/tsconfig.tsbuildinfo +1 -1
  56. package/build/components/Tooltip/tsconfig.tsbuildinfo +1 -1
  57. package/build/components/index.js +6 -6
  58. package/build/components/index.js.map +1 -1
  59. package/build/components/static.js +4 -4
  60. package/build/components/static.js.map +1 -1
  61. package/build/components/tsconfig.tsbuildinfo +1 -1
  62. package/build/components/types/src/components/CarouselHero/CarouselHero.d.ts +18 -0
  63. package/build/components/types/src/components/CarouselHero/CarouselHero.static.d.ts +47 -0
  64. package/build/components/types/src/components/CarouselHero/CarouselHeroItem.d.ts +9 -0
  65. package/build/components/types/src/components/CarouselHero/constants.d.ts +34 -0
  66. package/build/components/types/src/components/CarouselHero/index.d.ts +2 -0
  67. package/build/components/types/src/components/index.d.ts +2 -1
  68. package/build/components/types/src/scripts/index.d.ts +5 -0
  69. package/build/lib/components.css +1 -1
  70. package/build/lib/components.css.map +1 -1
  71. package/build/lib/scripts.js +4 -4
  72. package/build/lib/scripts.js.map +1 -1
  73. package/build/lib/style.css +1 -1
  74. package/build/lib/style.css.map +1 -1
  75. package/package.json +1 -1
  76. package/src/components/CarouselHero/CarouselHero.static.ts +528 -0
  77. package/src/components/CarouselHero/CarouselHero.tsx +148 -0
  78. package/src/components/CarouselHero/CarouselHeroItem.tsx +41 -0
  79. package/src/components/CarouselHero/constants.ts +37 -0
  80. package/src/components/CarouselHero/index.ts +2 -0
  81. package/src/components/CarouselHero/styles/config.scss +54 -0
  82. package/src/components/CarouselHero/styles/mixins.scss +289 -0
  83. package/src/components/CarouselHero/styles/style.scss +67 -0
  84. package/src/components/CarouselHero/tests/CarouselHero.conformance.test.js +148 -0
  85. package/src/components/CarouselHero/tests/CarouselHero.unit.test.js +289 -0
  86. package/src/components/CarouselHero/tests/CarouselHeroItem.conformance.test.js +142 -0
  87. package/src/components/CarouselHero/tests/CarouselHeroItem.unit.test.js +210 -0
  88. package/src/components/Controls/styles/config.scss +2 -2
  89. package/src/components/index.ts +2 -0
@@ -0,0 +1,289 @@
1
+ import { render } from "@testing-library/react";
2
+
3
+ import { CarouselHero } from "../CarouselHero";
4
+ import { CarouselHeroItem } from "../CarouselHeroItem";
5
+
6
+ describe("rendering CarouselHero", () => {
7
+ describe("initial state", () => {
8
+ it("has default class carousel-hero", () => {
9
+ const { getByTestId } = render(<CarouselHero data-testid="test-id" />);
10
+ expect(getByTestId("test-id")).toHaveClass("carousel-hero");
11
+ });
12
+
13
+ it("has data-carousel-hero attribute", () => {
14
+ const { container } = render(<CarouselHero />);
15
+ expect(container.querySelector(".carousel-hero")).toHaveAttribute(
16
+ "data-carousel-hero",
17
+ );
18
+ });
19
+
20
+ it("has default class carousel-hero__viewport-wrapper", () => {
21
+ const { container } = render(<CarouselHero />);
22
+ expect(
23
+ container.getElementsByClassName("carousel-hero__viewport-wrapper")
24
+ .length,
25
+ ).toBe(1);
26
+ });
27
+
28
+ it("has default class carousel-hero__viewport", () => {
29
+ const { container } = render(<CarouselHero />);
30
+ expect(
31
+ container.getElementsByClassName("carousel-hero__viewport").length,
32
+ ).toBe(1);
33
+ });
34
+
35
+ it("has default class carousel-hero__track", () => {
36
+ const { container } = render(<CarouselHero />);
37
+ expect(
38
+ container.getElementsByClassName("carousel-hero__track").length,
39
+ ).toBe(1);
40
+ });
41
+
42
+ it("has default class carousel-hero__controls", () => {
43
+ const { container } = render(<CarouselHero />);
44
+ expect(
45
+ container.getElementsByClassName("carousel-hero__controls").length,
46
+ ).toBe(1);
47
+ });
48
+
49
+ it("has default class carousel-hero__navigation", () => {
50
+ const { container } = render(<CarouselHero />);
51
+ expect(
52
+ container.getElementsByClassName("carousel-hero__navigation").length,
53
+ ).toBe(1);
54
+ });
55
+
56
+ it("has default class carousel-hero__pagination", () => {
57
+ const { container } = render(<CarouselHero />);
58
+ expect(
59
+ container.getElementsByClassName("carousel-hero__pagination").length,
60
+ ).toBe(1);
61
+ });
62
+
63
+ it("renders navigation controls (prev/next)", () => {
64
+ const { container } = render(<CarouselHero />);
65
+ expect(
66
+ container.getElementsByClassName("carousel-hero__prev").length,
67
+ ).toBe(1);
68
+ expect(
69
+ container.getElementsByClassName("carousel-hero__next").length,
70
+ ).toBe(1);
71
+ });
72
+ });
73
+
74
+ describe("passed props", () => {
75
+ const tabs = [{ label: "Tab 1" }, { label: "Tab 2" }, { label: "Tab 3" }];
76
+
77
+ const children = (
78
+ <>
79
+ <CarouselHeroItem
80
+ key="slide-1"
81
+ title="Test Title 1"
82
+ image="https://placehold.co/720x560"
83
+ >
84
+ <p>Test content 1</p>
85
+ </CarouselHeroItem>
86
+ <CarouselHeroItem
87
+ key="slide-2"
88
+ title="Test Title 2"
89
+ image="https://placehold.co/720x560"
90
+ >
91
+ <p>Test content 2</p>
92
+ </CarouselHeroItem>
93
+ </>
94
+ );
95
+
96
+ it("renders children slides", () => {
97
+ const { container } = render(<CarouselHero>{children}</CarouselHero>);
98
+ const slides = container.getElementsByClassName("carousel-hero__slide");
99
+ expect(slides.length).toBe(2);
100
+ expect(slides[0]).toHaveTextContent("Test Title 1");
101
+ expect(slides[1]).toHaveTextContent("Test Title 2");
102
+ });
103
+
104
+ it("has additional class when className is set", () => {
105
+ const { getByTestId } = render(
106
+ <CarouselHero data-testid="test-id" className="test-class" />,
107
+ );
108
+ expect(getByTestId("test-id")).toHaveClass("carousel-hero");
109
+ expect(getByTestId("test-id")).toHaveClass("test-class");
110
+ });
111
+
112
+ it("has is-light class when colorScheme is light", () => {
113
+ const { getByTestId } = render(
114
+ <CarouselHero data-testid="test-id" colorScheme="light" />,
115
+ );
116
+ expect(getByTestId("test-id")).toHaveClass("is-light");
117
+ });
118
+
119
+ it("does not have is-light class by default", () => {
120
+ const { getByTestId } = render(<CarouselHero data-testid="test-id" />);
121
+ expect(getByTestId("test-id")).not.toHaveClass("is-light");
122
+ });
123
+
124
+ it("renders tabs when tabs prop is provided", () => {
125
+ const { container } = render(
126
+ <CarouselHero tabs={tabs}>{children}</CarouselHero>,
127
+ );
128
+
129
+ const tabsContainer = container.querySelector(".carousel-hero__tabs");
130
+ expect(tabsContainer).toBeInTheDocument();
131
+ expect(tabsContainer).toHaveAttribute("role", "tablist");
132
+
133
+ const tabButtons = container.querySelectorAll(".carousel-hero__tab");
134
+ expect(tabButtons.length).toBe(3);
135
+ expect(tabButtons[0]).toHaveTextContent("Tab 1");
136
+ expect(tabButtons[1]).toHaveTextContent("Tab 2");
137
+ expect(tabButtons[2]).toHaveTextContent("Tab 3");
138
+ });
139
+
140
+ it("does not render tabs when tabs prop is empty", () => {
141
+ const { container } = render(<CarouselHero>{children}</CarouselHero>);
142
+
143
+ const tabsContainer = container.querySelector(".carousel-hero__tabs");
144
+ expect(tabsContainer).not.toBeInTheDocument();
145
+ });
146
+
147
+ it("sets proper ARIA attributes on tabs", () => {
148
+ const { container } = render(
149
+ <CarouselHero tabs={tabs}>{children}</CarouselHero>,
150
+ );
151
+
152
+ const tabButtons = container.querySelectorAll(".carousel-hero__tab");
153
+
154
+ // First tab should be active
155
+ expect(tabButtons[0]).toHaveAttribute("role", "tab");
156
+ expect(tabButtons[0]).toHaveAttribute("aria-selected", "true");
157
+ expect(tabButtons[0]).toHaveAttribute("tabIndex", "0");
158
+
159
+ // Other tabs should not be active
160
+ expect(tabButtons[1]).toHaveAttribute("aria-selected", "false");
161
+ expect(tabButtons[1]).toHaveAttribute("tabIndex", "-1");
162
+ expect(tabButtons[2]).toHaveAttribute("aria-selected", "false");
163
+ expect(tabButtons[2]).toHaveAttribute("tabIndex", "-1");
164
+ });
165
+
166
+ it("shows play/pause button when interval is provided", () => {
167
+ const { container } = render(
168
+ <CarouselHero interval={3000}>{children}</CarouselHero>,
169
+ );
170
+
171
+ expect(
172
+ container.getElementsByClassName("carousel-hero__play-pause").length,
173
+ ).toBe(1);
174
+ });
175
+
176
+ it("does not show play/pause button when interval is not provided", () => {
177
+ const { container } = render(<CarouselHero>{children}</CarouselHero>);
178
+
179
+ expect(
180
+ container.getElementsByClassName("carousel-hero__play-pause").length,
181
+ ).toBe(0);
182
+ });
183
+
184
+ it("does not show play/pause button when interval is 0", () => {
185
+ const { container } = render(
186
+ <CarouselHero interval={0}>{children}</CarouselHero>,
187
+ );
188
+
189
+ expect(
190
+ container.getElementsByClassName("carousel-hero__play-pause").length,
191
+ ).toBe(0);
192
+ });
193
+
194
+ it("sets data-interval attribute when interval is provided", () => {
195
+ const { container } = render(
196
+ <CarouselHero interval={5000}>{children}</CarouselHero>,
197
+ );
198
+
199
+ const carousel = container.querySelector(".carousel-hero");
200
+ expect(carousel).toHaveAttribute("data-interval", "5000");
201
+ });
202
+
203
+ it("does not set data-interval attribute when interval is not provided", () => {
204
+ const { container } = render(<CarouselHero>{children}</CarouselHero>);
205
+
206
+ const carousel = container.querySelector(".carousel-hero");
207
+ expect(carousel).not.toHaveAttribute("data-interval");
208
+ });
209
+ });
210
+
211
+ describe("swiperOptions prop", () => {
212
+ const children = (
213
+ <CarouselHeroItem
214
+ key="slide-1"
215
+ title="Test Title"
216
+ image="https://placehold.co/720x560"
217
+ >
218
+ <p>Test content</p>
219
+ </CarouselHeroItem>
220
+ );
221
+
222
+ it("sets data-swiper-options attribute when swiperOptions prop is provided", () => {
223
+ const swiperOptions = { speed: 500, loop: true };
224
+ const { container } = render(
225
+ <CarouselHero swiperOptions={swiperOptions}>{children}</CarouselHero>,
226
+ );
227
+
228
+ const carousel = container.querySelector(".carousel-hero");
229
+ expect(carousel.getAttribute("data-swiper-options")).toBe(
230
+ JSON.stringify(swiperOptions),
231
+ );
232
+ });
233
+
234
+ it("does not set data-swiper-options attribute when swiperOptions prop is not provided", () => {
235
+ const { container } = render(<CarouselHero>{children}</CarouselHero>);
236
+
237
+ const carousel = container.querySelector(".carousel-hero");
238
+ expect(carousel.hasAttribute("data-swiper-options")).toBe(false);
239
+ });
240
+ });
241
+
242
+ describe("Swiper integration", () => {
243
+ const children = (
244
+ <>
245
+ <CarouselHeroItem
246
+ key="slide-1"
247
+ title="Test Title 1"
248
+ image="https://placehold.co/720x560"
249
+ >
250
+ <p>Test content 1</p>
251
+ </CarouselHeroItem>
252
+ <CarouselHeroItem
253
+ key="slide-2"
254
+ title="Test Title 2"
255
+ image="https://placehold.co/720x560"
256
+ >
257
+ <p>Test content 2</p>
258
+ </CarouselHeroItem>
259
+ </>
260
+ );
261
+
262
+ it("track element uses carousel-hero__track class which maps to swiper-wrapper", () => {
263
+ const { container } = render(<CarouselHero>{children}</CarouselHero>);
264
+ expect(
265
+ container.querySelector(".carousel-hero__track"),
266
+ ).toBeInTheDocument();
267
+ });
268
+
269
+ it("slide elements use carousel-hero__slide class which maps to swiper-slide", () => {
270
+ const { container } = render(<CarouselHero>{children}</CarouselHero>);
271
+ const slides = container.getElementsByClassName("carousel-hero__slide");
272
+ expect(slides.length).toBe(2);
273
+ });
274
+
275
+ it("viewport element uses carousel-hero__viewport class which maps to swiper-container", () => {
276
+ const { container } = render(<CarouselHero>{children}</CarouselHero>);
277
+ expect(
278
+ container.querySelector(".carousel-hero__viewport"),
279
+ ).toBeInTheDocument();
280
+ });
281
+
282
+ it("pagination element uses carousel-hero__pagination class which maps to swiper-pagination", () => {
283
+ const { container } = render(<CarouselHero>{children}</CarouselHero>);
284
+ expect(
285
+ container.querySelector(".carousel-hero__pagination"),
286
+ ).toBeInTheDocument();
287
+ });
288
+ });
289
+ });
@@ -0,0 +1,142 @@
1
+ import { render } from "@testing-library/react";
2
+ import { axe } from "jest-axe";
3
+
4
+ import { CarouselHeroItem } from "../";
5
+
6
+ const basicExample = (
7
+ <CarouselHeroItem
8
+ title="Basic Slide Title"
9
+ image="https://placehold.co/720x560?text=Basic"
10
+ >
11
+ <p>Basic slide content</p>
12
+ </CarouselHeroItem>
13
+ );
14
+
15
+ const exampleWithButton = (
16
+ <CarouselHeroItem
17
+ title="Slide with Button"
18
+ image="https://placehold.co/720x560?text=Button"
19
+ >
20
+ <p>This slide has interactive content.</p>
21
+ <button type="button">Click me</button>
22
+ </CarouselHeroItem>
23
+ );
24
+
25
+ const exampleWithComplexContent = (
26
+ <CarouselHeroItem
27
+ title="Complex Content Slide"
28
+ image="https://placehold.co/720x560?text=Complex"
29
+ >
30
+ <p>This slide contains various content types:</p>
31
+ <ul>
32
+ <li>List item 1</li>
33
+ <li>List item 2</li>
34
+ <li>List item 3</li>
35
+ </ul>
36
+ <div>
37
+ <button type="button">Primary Action</button>
38
+ <button type="button">Secondary Action</button>
39
+ </div>
40
+ </CarouselHeroItem>
41
+ );
42
+
43
+ const exampleWithLongTitle = (
44
+ <CarouselHeroItem
45
+ title="This is a Very Long Title That Should Still Be Accessible and Properly Rendered"
46
+ image="https://placehold.co/720x560?text=Long+Title"
47
+ >
48
+ <p>Content for slide with long title.</p>
49
+ </CarouselHeroItem>
50
+ );
51
+
52
+ const exampleWithSpecialCharacters = (
53
+ <CarouselHeroItem
54
+ title="Špeciálny Titul s Diakritikou & Symbolmi €"
55
+ image="https://placehold.co/720x560?text=Special+Chars"
56
+ >
57
+ <p>Obsah so špeciálnymi znakmi: áéíóúôäňľščťžý.</p>
58
+ <p>Mathematical symbols: ∑ ∞ ± × ÷</p>
59
+ </CarouselHeroItem>
60
+ );
61
+
62
+ const exampleWithCustomClassName = (
63
+ <CarouselHeroItem
64
+ className="custom-slide-class"
65
+ title="Custom Styled Slide"
66
+ image="https://placehold.co/720x560?text=Custom"
67
+ >
68
+ <p>This slide has custom styling.</p>
69
+ </CarouselHeroItem>
70
+ );
71
+
72
+ describe("CarouselHeroItem conformance", () => {
73
+ it("is valid html", () => {
74
+ const { container } = render(basicExample);
75
+ expect(container).toHTMLValidate();
76
+ });
77
+
78
+ it("is accessible", async () => {
79
+ const { container } = render(basicExample);
80
+ expect(await axe(container)).toHaveNoViolations();
81
+ });
82
+ });
83
+
84
+ describe("CarouselHeroItem with button conformance", () => {
85
+ it("is valid html", () => {
86
+ const { container } = render(exampleWithButton);
87
+ expect(container).toHTMLValidate();
88
+ });
89
+
90
+ it("is accessible", async () => {
91
+ const { container } = render(exampleWithButton);
92
+ expect(await axe(container)).toHaveNoViolations();
93
+ });
94
+ });
95
+
96
+ describe("CarouselHeroItem with complex content conformance", () => {
97
+ it("is valid html", () => {
98
+ const { container } = render(exampleWithComplexContent);
99
+ expect(container).toHTMLValidate();
100
+ });
101
+
102
+ it("is accessible", async () => {
103
+ const { container } = render(exampleWithComplexContent);
104
+ expect(await axe(container)).toHaveNoViolations();
105
+ });
106
+ });
107
+
108
+ describe("CarouselHeroItem with long title conformance", () => {
109
+ it("is valid html", () => {
110
+ const { container } = render(exampleWithLongTitle);
111
+ expect(container).toHTMLValidate();
112
+ });
113
+
114
+ it("is accessible", async () => {
115
+ const { container } = render(exampleWithLongTitle);
116
+ expect(await axe(container)).toHaveNoViolations();
117
+ });
118
+ });
119
+
120
+ describe("CarouselHeroItem with special characters conformance", () => {
121
+ it("is valid html", () => {
122
+ const { container } = render(exampleWithSpecialCharacters);
123
+ expect(container).toHTMLValidate();
124
+ });
125
+
126
+ it("is accessible", async () => {
127
+ const { container } = render(exampleWithSpecialCharacters);
128
+ expect(await axe(container)).toHaveNoViolations();
129
+ });
130
+ });
131
+
132
+ describe("CarouselHeroItem with custom class conformance", () => {
133
+ it("is valid html", () => {
134
+ const { container } = render(exampleWithCustomClassName);
135
+ expect(container).toHTMLValidate();
136
+ });
137
+
138
+ it("is accessible", async () => {
139
+ const { container } = render(exampleWithCustomClassName);
140
+ expect(await axe(container)).toHaveNoViolations();
141
+ });
142
+ });
@@ -0,0 +1,210 @@
1
+ import { render } from "@testing-library/react";
2
+
3
+ import { CarouselHeroItem } from "../CarouselHeroItem";
4
+
5
+ describe("rendering CarouselHeroItem", () => {
6
+ describe("initial state", () => {
7
+ it("has default class carousel-hero__slide", () => {
8
+ const { getByTestId } = render(
9
+ <CarouselHeroItem
10
+ data-testid="test-id"
11
+ title="Test Title"
12
+ image="https://placehold.co/720x560"
13
+ />,
14
+ );
15
+ expect(getByTestId("test-id")).toHaveClass("carousel-hero__slide");
16
+ });
17
+
18
+ it("has bg-black class by default", () => {
19
+ const { getByTestId } = render(
20
+ <CarouselHeroItem
21
+ data-testid="test-id"
22
+ title="Test Title"
23
+ image="https://placehold.co/720x560"
24
+ />,
25
+ );
26
+ expect(getByTestId("test-id")).toHaveClass("bg-black");
27
+ });
28
+
29
+ it("renders slide content container", () => {
30
+ const { container } = render(
31
+ <CarouselHeroItem
32
+ title="Test Title"
33
+ image="https://placehold.co/720x560"
34
+ />,
35
+ );
36
+ expect(
37
+ container.getElementsByClassName("carousel-hero__slide-content").length,
38
+ ).toBe(1);
39
+ });
40
+
41
+ it("renders slide title", () => {
42
+ const { container } = render(
43
+ <CarouselHeroItem
44
+ title="Test Title"
45
+ image="https://placehold.co/720x560"
46
+ />,
47
+ );
48
+ const titleElement = container.querySelector(
49
+ ".carousel-hero__slide-title",
50
+ );
51
+ expect(titleElement).toBeInTheDocument();
52
+ expect(titleElement).toHaveTextContent("Test Title");
53
+ expect(titleElement.tagName).toBe("H1");
54
+ expect(titleElement).toHaveClass("h1");
55
+ expect(titleElement).toHaveClass("thin");
56
+ });
57
+
58
+ it("renders image with proper attributes", () => {
59
+ const imageUrl = "https://placehold.co/720x560";
60
+ const title = "Test Title";
61
+ const { container } = render(
62
+ <CarouselHeroItem title={title} image={imageUrl} />,
63
+ );
64
+
65
+ const imageElement = container.querySelector(
66
+ ".carousel-hero__slide-image",
67
+ );
68
+ expect(imageElement).toBeInTheDocument();
69
+ expect(imageElement).toHaveAttribute("src", imageUrl);
70
+ expect(imageElement).toHaveAttribute("alt", `Obrázok ${title}`);
71
+ });
72
+ });
73
+
74
+ describe("passed props", () => {
75
+ it("renders children content", () => {
76
+ const { getByText } = render(
77
+ <CarouselHeroItem
78
+ title="Test Title"
79
+ image="https://placehold.co/720x560"
80
+ >
81
+ <p>Test content</p>
82
+ <button>Test button</button>
83
+ </CarouselHeroItem>,
84
+ );
85
+ expect(getByText("Test content")).toBeInTheDocument();
86
+ expect(getByText("Test button")).toBeInTheDocument();
87
+ });
88
+
89
+ it("has additional class when className is set", () => {
90
+ const { getByTestId } = render(
91
+ <CarouselHeroItem
92
+ data-testid="test-id"
93
+ className="test-class"
94
+ title="Test Title"
95
+ image="https://placehold.co/720x560"
96
+ />,
97
+ );
98
+ expect(getByTestId("test-id")).toHaveClass("carousel-hero__slide");
99
+ expect(getByTestId("test-id")).toHaveClass("bg-black");
100
+ expect(getByTestId("test-id")).toHaveClass("test-class");
101
+ });
102
+
103
+ it("passes through other HTML attributes", () => {
104
+ const { getByTestId } = render(
105
+ <CarouselHeroItem
106
+ data-testid="test-id"
107
+ id="custom-id"
108
+ role="tabpanel"
109
+ title="Test Title"
110
+ image="https://placehold.co/720x560"
111
+ />,
112
+ );
113
+ expect(getByTestId("test-id")).toHaveAttribute("id", "custom-id");
114
+ expect(getByTestId("test-id")).toHaveAttribute("role", "tabpanel");
115
+ });
116
+
117
+ it("renders with different title text", () => {
118
+ const customTitle = "Custom Hero Title";
119
+ const { container } = render(
120
+ <CarouselHeroItem
121
+ title={customTitle}
122
+ image="https://placehold.co/720x560"
123
+ />,
124
+ );
125
+
126
+ const titleElement = container.querySelector(
127
+ ".carousel-hero__slide-title",
128
+ );
129
+ expect(titleElement).toHaveTextContent(customTitle);
130
+ });
131
+
132
+ it("renders with different image source", () => {
133
+ const customImage = "https://example.com/custom-image.jpg";
134
+ const title = "Test Title";
135
+ const { container } = render(
136
+ <CarouselHeroItem title={title} image={customImage} />,
137
+ );
138
+
139
+ const imageElement = container.querySelector(
140
+ ".carousel-hero__slide-image",
141
+ );
142
+ expect(imageElement).toHaveAttribute("src", customImage);
143
+ expect(imageElement).toHaveAttribute("alt", `Obrázok ${title}`);
144
+ });
145
+
146
+ it("handles special characters in title for image alt text", () => {
147
+ const titleWithSpecialChars = "Špeciálny Titul s Diakritikou & Symbolmi";
148
+ const { container } = render(
149
+ <CarouselHeroItem
150
+ title={titleWithSpecialChars}
151
+ image="https://placehold.co/720x560"
152
+ />,
153
+ );
154
+
155
+ const imageElement = container.querySelector(
156
+ ".carousel-hero__slide-image",
157
+ );
158
+ expect(imageElement).toHaveAttribute(
159
+ "alt",
160
+ `Obrázok ${titleWithSpecialChars}`,
161
+ );
162
+ });
163
+
164
+ it("renders children in proper content container", () => {
165
+ const { container } = render(
166
+ <CarouselHeroItem
167
+ title="Test Title"
168
+ image="https://placehold.co/720x560"
169
+ >
170
+ <p data-testid="child-content">Child content</p>
171
+ </CarouselHeroItem>,
172
+ );
173
+
174
+ const contentContainer = container.querySelector(
175
+ ".carousel-hero__slide-content",
176
+ );
177
+ const childContent = container.querySelector(
178
+ "[data-testid='child-content']",
179
+ );
180
+
181
+ expect(contentContainer).toContainElement(childContent);
182
+ });
183
+
184
+ it("maintains proper DOM structure", () => {
185
+ const { container } = render(
186
+ <CarouselHeroItem
187
+ title="Test Title"
188
+ image="https://placehold.co/720x560"
189
+ >
190
+ <p>Content</p>
191
+ </CarouselHeroItem>,
192
+ );
193
+
194
+ const slide = container.querySelector(".carousel-hero__slide");
195
+ const slideContent = container.querySelector(
196
+ ".carousel-hero__slide-content",
197
+ );
198
+ const slideTitle = container.querySelector(".carousel-hero__slide-title");
199
+ const slideImage = container.querySelector(".carousel-hero__slide-image");
200
+
201
+ // Check that slide contains both content and image
202
+ expect(slide).toContainElement(slideContent);
203
+ expect(slide).toContainElement(slideImage);
204
+
205
+ // Check that slide content contains title and children
206
+ expect(slideContent).toContainElement(slideTitle);
207
+ expect(slideContent).toHaveTextContent("Content");
208
+ });
209
+ });
210
+ });
@@ -22,8 +22,8 @@ $base: (
22
22
  $states: (
23
23
  default: (
24
24
  color: var(--color-text-default),
25
- background-color: var(--color-fill-disabled),
26
- border-color: var(--color-fill-disabled),
25
+ background-color: var(--color-fill-moderate),
26
+ border-color: var(--color-fill-moderate),
27
27
  ),
28
28
  hover: (
29
29
  color: var(--color-text-inverse),
@@ -20,6 +20,7 @@ import {
20
20
  } from "./Button";
21
21
  import { Buttons } from "./Buttons";
22
22
  import { Carousel } from "./Carousel";
23
+ import { CarouselHero } from "./CarouselHero";
23
24
  import { CarouselPromotions } from "./CarouselPromotions";
24
25
  import { CartTable } from "./CartTable";
25
26
  import { Container } from "./Container";
@@ -114,6 +115,7 @@ export {
114
115
  CardProductHeader,
115
116
  CardSection,
116
117
  Carousel,
118
+ CarouselHero,
117
119
  CarouselPromotions,
118
120
  CartTable,
119
121
  Checkbox,