@orangesk/orange-design-system 2.0.0-beta.45 → 2.0.0-beta.47
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/Breadcrumbs/style.css +1 -1
- package/build/components/Breadcrumbs/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/Footer/style.css +1 -1
- package/build/components/Footer/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/Stepbar/style.css +1 -1
- package/build/components/Stepbar/style.css.map +1 -1
- package/build/components/Tabs/style.css +1 -1
- package/build/components/Tabs/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/index.d.ts +1 -4
- package/build/components/types/src/components/CarouselHero/CarouselHero.d.ts +1 -0
- package/build/components/types/src/components/Preview/CodeExample.d.ts +1 -0
- package/build/components/types/src/components/Preview/PreviewGenerator.d.ts +1 -0
- package/build/components/types/src/components/Preview/getElementDisplayName.d.ts +1 -0
- package/build/components/types/src/components/Tabs/Tabs.d.ts +0 -4
- package/build/components/types/src/components/Tabs/Tabs.static.d.ts +12 -0
- package/build/lib/base.css +1 -1
- package/build/lib/base.css.map +1 -1
- package/build/lib/components.css +1 -1
- package/build/lib/components.css.map +1 -1
- package/build/lib/footer.css +1 -1
- package/build/lib/footer.css.map +1 -1
- package/build/lib/megamenu.css +1 -1
- package/build/lib/megamenu.css.map +1 -1
- package/build/lib/scripts.js +1 -1
- package/build/lib/scripts.js.map +1 -1
- package/build/lib/style.css +1 -1
- package/build/lib/style.css.map +1 -1
- package/build/lib/utilities.css +1 -1
- package/build/lib/utilities.css.map +1 -1
- package/build/search-index.json +5 -5
- package/package.json +18 -18
- package/src/components/Breadcrumbs/styles/mixins.scss +14 -3
- package/src/components/Carousel/styles/mixins.scss +22 -2
- package/src/components/CarouselHero/CarouselHero.tsx +20 -6
- package/src/components/CarouselHero/tests/CarouselHero.conformance.test.jsx +2 -0
- package/src/components/CarouselHero/tests/CarouselHero.unit.test.jsx +78 -9
- package/src/components/Footer/styles/mixins.scss +2 -1
- package/src/components/Forms/Checkbox/styles/style.scss +13 -6
- package/src/components/Forms/InputStepper/InputStepper.tsx +2 -0
- package/src/components/Forms/InputStepper/styles/style.scss +25 -8
- package/src/components/Forms/InputStepper/tests/InputStepper.unit.test.jsx +8 -0
- package/src/components/Link/styles/mixins.scss +0 -1
- package/src/components/Megamenu/Megamenu.tsx +2 -2
- package/src/components/Megamenu/MegamenuBlog.tsx +2 -2
- package/src/components/Megamenu/styles/mixins.scss +20 -12
- package/src/components/Preview/CodeExample.tsx +66 -25
- package/src/components/Preview/Preview.tsx +26 -13
- package/src/components/Preview/PreviewGenerator.tsx +57 -32
- package/src/components/Preview/getElementDisplayName.ts +25 -0
- package/src/components/Stepbar/styles/config.scss +34 -17
- package/src/components/Stepbar/styles/mixins.scss +5 -3
- package/src/components/Tabs/Tabs.static.ts +157 -30
- package/src/components/Tabs/Tabs.tsx +62 -67
- package/src/components/Tabs/styles/config.scss +18 -25
- package/src/components/Tabs/styles/mixins.scss +93 -28
- package/src/components/Tabs/styles/style.scss +4 -15
- package/src/components/Tabs/tests/Tabs.unit.test.jsx +111 -0
- package/src/styles/base/globals.scss +2 -0
- package/src/styles/shame.scss +16 -3
- package/src/styles/tools/convert.scss +8 -0
- package/src/styles/utilities/horizontal-scroll.scss +7 -2
- package/src/styles/utilities/text.scss +0 -1
|
@@ -188,13 +188,32 @@
|
|
|
188
188
|
|
|
189
189
|
@mixin scrollbar-base {
|
|
190
190
|
position: relative;
|
|
191
|
+
overflow: visible;
|
|
191
192
|
}
|
|
192
193
|
|
|
193
194
|
@mixin scrollbar-horizontal {
|
|
194
|
-
height: convert.to-rem(
|
|
195
|
+
height: convert.to-rem(8px);
|
|
195
196
|
appearance: none;
|
|
196
|
-
background-color:
|
|
197
|
+
background-color: transparent;
|
|
197
198
|
border-radius: 99px;
|
|
199
|
+
|
|
200
|
+
&::before {
|
|
201
|
+
content: "";
|
|
202
|
+
position: absolute;
|
|
203
|
+
top: convert.to-rem(1px);
|
|
204
|
+
right: 0;
|
|
205
|
+
bottom: convert.to-rem(1px);
|
|
206
|
+
left: 0;
|
|
207
|
+
background-color: var(--color-surface-moderate);
|
|
208
|
+
border-radius: 99px;
|
|
209
|
+
pointer-events: none;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
&:hover .carousel__scrollbar-drag,
|
|
213
|
+
.carousel__scrollbar-drag:hover {
|
|
214
|
+
height: convert.to-rem(8px);
|
|
215
|
+
margin-top: 0;
|
|
216
|
+
}
|
|
198
217
|
}
|
|
199
218
|
|
|
200
219
|
@mixin scrollbar-drag {
|
|
@@ -202,6 +221,7 @@
|
|
|
202
221
|
background-color: var(--color-fill-contrast);
|
|
203
222
|
border-radius: 99px;
|
|
204
223
|
height: convert.to-rem(6px);
|
|
224
|
+
margin-top: convert.to-rem(1px);
|
|
205
225
|
|
|
206
226
|
&:hover {
|
|
207
227
|
background-color: var(--color-fill-secondary) !important;
|
|
@@ -32,6 +32,7 @@ interface CarouselHeroProps {
|
|
|
32
32
|
children?: ReactNode;
|
|
33
33
|
tabs?: TabItem[];
|
|
34
34
|
interval?: number;
|
|
35
|
+
enableAutoplay?: boolean;
|
|
35
36
|
[key: string]: any;
|
|
36
37
|
}
|
|
37
38
|
|
|
@@ -41,6 +42,7 @@ const CarouselHero: React.FC<CarouselHeroProps> = ({
|
|
|
41
42
|
children,
|
|
42
43
|
tabs = [],
|
|
43
44
|
interval,
|
|
45
|
+
enableAutoplay = false,
|
|
44
46
|
...other
|
|
45
47
|
}) => {
|
|
46
48
|
const [carouselRef] = useStatic(CarouselHeroStatic);
|
|
@@ -56,11 +58,21 @@ const CarouselHero: React.FC<CarouselHeroProps> = ({
|
|
|
56
58
|
pagination: CLASS_PAGINATION,
|
|
57
59
|
};
|
|
58
60
|
|
|
61
|
+
const forwardedSwiperOptions = (() => {
|
|
62
|
+
if (!swiperOptions) return undefined;
|
|
63
|
+
if (enableAutoplay || !("autoplay" in swiperOptions)) return swiperOptions;
|
|
64
|
+
|
|
65
|
+
const { autoplay: _autoplay, ...rest } = swiperOptions;
|
|
66
|
+
|
|
67
|
+
return Object.keys(rest).length > 0 ? rest : undefined;
|
|
68
|
+
})();
|
|
69
|
+
|
|
59
70
|
const hasAutoplay =
|
|
60
|
-
|
|
71
|
+
enableAutoplay &&
|
|
72
|
+
(((swiperOptions?.autoplay &&
|
|
61
73
|
typeof swiperOptions.autoplay === "object" &&
|
|
62
|
-
(swiperOptions.autoplay as any).delay >= 1000) ||
|
|
63
|
-
|
|
74
|
+
(swiperOptions.autoplay as any).delay >= 1000) as boolean) ||
|
|
75
|
+
!!(interval && interval >= 1000));
|
|
64
76
|
|
|
65
77
|
const playPauseIcon = "pause";
|
|
66
78
|
|
|
@@ -69,9 +81,11 @@ const CarouselHero: React.FC<CarouselHeroProps> = ({
|
|
|
69
81
|
className={classes}
|
|
70
82
|
ref={carouselRef}
|
|
71
83
|
data-carousel-hero
|
|
72
|
-
{...(interval && interval >= 1000
|
|
73
|
-
|
|
74
|
-
|
|
84
|
+
{...(enableAutoplay && interval && interval >= 1000
|
|
85
|
+
? { "data-interval": interval }
|
|
86
|
+
: {})}
|
|
87
|
+
{...(forwardedSwiperOptions
|
|
88
|
+
? { "data-swiper-options": JSON.stringify(forwardedSwiperOptions) }
|
|
75
89
|
: {})}
|
|
76
90
|
{...other}
|
|
77
91
|
>
|
|
@@ -41,6 +41,7 @@ const exampleWithTabs = (
|
|
|
41
41
|
|
|
42
42
|
const exampleWithAutoplay = (
|
|
43
43
|
<CarouselHero
|
|
44
|
+
enableAutoplay
|
|
44
45
|
interval={3000}
|
|
45
46
|
tabs={[{ label: "Auto Tab 1" }, { label: "Auto Tab 2" }]}
|
|
46
47
|
>
|
|
@@ -57,6 +58,7 @@ const exampleWithAutoplay = (
|
|
|
57
58
|
|
|
58
59
|
const exampleWithComplexContent = (
|
|
59
60
|
<CarouselHero
|
|
61
|
+
enableAutoplay
|
|
60
62
|
tabs={[{ label: "Product 1" }, { label: "Product 2" }]}
|
|
61
63
|
interval={5000}
|
|
62
64
|
swiperOptions={{ speed: 300 }}
|
|
@@ -79,7 +79,9 @@ describe("rendering CarouselHero", () => {
|
|
|
79
79
|
});
|
|
80
80
|
|
|
81
81
|
it("play/pause button has proper ARIA label when displayed", () => {
|
|
82
|
-
const { container } = render(
|
|
82
|
+
const { container } = render(
|
|
83
|
+
<CarouselHero enableAutoplay interval={3000} />,
|
|
84
|
+
);
|
|
83
85
|
|
|
84
86
|
const playPauseButton = container.querySelector(
|
|
85
87
|
".carousel-hero__play-pause",
|
|
@@ -171,9 +173,11 @@ describe("rendering CarouselHero", () => {
|
|
|
171
173
|
expect(tabButtons[2]).toHaveAttribute("tabIndex", "-1");
|
|
172
174
|
});
|
|
173
175
|
|
|
174
|
-
it("shows play/pause button when interval is provided", () => {
|
|
176
|
+
it("shows play/pause button when autoplay is enabled and interval is provided", () => {
|
|
175
177
|
const { container } = render(
|
|
176
|
-
<CarouselHero interval={3000}>
|
|
178
|
+
<CarouselHero enableAutoplay interval={3000}>
|
|
179
|
+
{children}
|
|
180
|
+
</CarouselHero>,
|
|
177
181
|
);
|
|
178
182
|
|
|
179
183
|
expect(
|
|
@@ -181,6 +185,16 @@ describe("rendering CarouselHero", () => {
|
|
|
181
185
|
).toBe(1);
|
|
182
186
|
});
|
|
183
187
|
|
|
188
|
+
it("does not show play/pause button when autoplay is not enabled", () => {
|
|
189
|
+
const { container } = render(
|
|
190
|
+
<CarouselHero interval={3000}>{children}</CarouselHero>,
|
|
191
|
+
);
|
|
192
|
+
|
|
193
|
+
expect(
|
|
194
|
+
container.getElementsByClassName("carousel-hero__play-pause").length,
|
|
195
|
+
).toBe(0);
|
|
196
|
+
});
|
|
197
|
+
|
|
184
198
|
it("does not show play/pause button when interval is not provided", () => {
|
|
185
199
|
const { container } = render(<CarouselHero>{children}</CarouselHero>);
|
|
186
200
|
|
|
@@ -199,15 +213,26 @@ describe("rendering CarouselHero", () => {
|
|
|
199
213
|
).toBe(0);
|
|
200
214
|
});
|
|
201
215
|
|
|
202
|
-
it("sets data-interval attribute when interval is provided", () => {
|
|
216
|
+
it("sets data-interval attribute when autoplay is enabled and interval is provided", () => {
|
|
203
217
|
const { container } = render(
|
|
204
|
-
<CarouselHero interval={5000}>
|
|
218
|
+
<CarouselHero enableAutoplay interval={5000}>
|
|
219
|
+
{children}
|
|
220
|
+
</CarouselHero>,
|
|
205
221
|
);
|
|
206
222
|
|
|
207
223
|
const carousel = container.querySelector(".carousel-hero");
|
|
208
224
|
expect(carousel).toHaveAttribute("data-interval", "5000");
|
|
209
225
|
});
|
|
210
226
|
|
|
227
|
+
it("does not set data-interval attribute when autoplay is not enabled", () => {
|
|
228
|
+
const { container } = render(
|
|
229
|
+
<CarouselHero interval={5000}>{children}</CarouselHero>,
|
|
230
|
+
);
|
|
231
|
+
|
|
232
|
+
const carousel = container.querySelector(".carousel-hero");
|
|
233
|
+
expect(carousel).not.toHaveAttribute("data-interval");
|
|
234
|
+
});
|
|
235
|
+
|
|
211
236
|
it("does not set data-interval attribute when interval is not provided", () => {
|
|
212
237
|
const { container } = render(<CarouselHero>{children}</CarouselHero>);
|
|
213
238
|
|
|
@@ -243,7 +268,7 @@ describe("rendering CarouselHero", () => {
|
|
|
243
268
|
expect(carousel.hasAttribute("data-swiper-options")).toBe(false);
|
|
244
269
|
});
|
|
245
270
|
|
|
246
|
-
it("shows play/pause button when swiperOptions has autoplay with delay >= 1000ms", () => {
|
|
271
|
+
it("shows play/pause button when autoplay is enabled and swiperOptions has autoplay with delay >= 1000ms", () => {
|
|
247
272
|
const swiperOptions = {
|
|
248
273
|
autoplay: {
|
|
249
274
|
delay: 3000,
|
|
@@ -251,7 +276,9 @@ describe("rendering CarouselHero", () => {
|
|
|
251
276
|
},
|
|
252
277
|
};
|
|
253
278
|
const { container } = render(
|
|
254
|
-
<CarouselHero swiperOptions={swiperOptions}>
|
|
279
|
+
<CarouselHero enableAutoplay swiperOptions={swiperOptions}>
|
|
280
|
+
{children}
|
|
281
|
+
</CarouselHero>,
|
|
255
282
|
);
|
|
256
283
|
|
|
257
284
|
expect(
|
|
@@ -259,6 +286,28 @@ describe("rendering CarouselHero", () => {
|
|
|
259
286
|
).toBe(1);
|
|
260
287
|
});
|
|
261
288
|
|
|
289
|
+
it("does not show play/pause button when autoplay is not enabled, even if swiperOptions includes autoplay", () => {
|
|
290
|
+
const swiperOptions = {
|
|
291
|
+
autoplay: {
|
|
292
|
+
delay: 3000,
|
|
293
|
+
disableOnInteraction: false,
|
|
294
|
+
},
|
|
295
|
+
};
|
|
296
|
+
const { container } = render(
|
|
297
|
+
<CarouselHero swiperOptions={swiperOptions}>{children}</CarouselHero>,
|
|
298
|
+
);
|
|
299
|
+
|
|
300
|
+
expect(
|
|
301
|
+
container.getElementsByClassName("carousel-hero__play-pause").length,
|
|
302
|
+
).toBe(0);
|
|
303
|
+
|
|
304
|
+
const carousel = container.querySelector(".carousel-hero");
|
|
305
|
+
expect(carousel).not.toHaveAttribute(
|
|
306
|
+
"data-swiper-options",
|
|
307
|
+
JSON.stringify(swiperOptions),
|
|
308
|
+
);
|
|
309
|
+
});
|
|
310
|
+
|
|
262
311
|
it("does not show play/pause button when swiperOptions autoplay delay < 1000ms", () => {
|
|
263
312
|
const swiperOptions = {
|
|
264
313
|
autoplay: {
|
|
@@ -266,7 +315,9 @@ describe("rendering CarouselHero", () => {
|
|
|
266
315
|
},
|
|
267
316
|
};
|
|
268
317
|
const { container } = render(
|
|
269
|
-
<CarouselHero swiperOptions={swiperOptions}>
|
|
318
|
+
<CarouselHero enableAutoplay swiperOptions={swiperOptions}>
|
|
319
|
+
{children}
|
|
320
|
+
</CarouselHero>,
|
|
270
321
|
);
|
|
271
322
|
|
|
272
323
|
expect(
|
|
@@ -279,13 +330,31 @@ describe("rendering CarouselHero", () => {
|
|
|
279
330
|
autoplay: true,
|
|
280
331
|
};
|
|
281
332
|
const { container } = render(
|
|
282
|
-
<CarouselHero swiperOptions={swiperOptions}>
|
|
333
|
+
<CarouselHero enableAutoplay swiperOptions={swiperOptions}>
|
|
334
|
+
{children}
|
|
335
|
+
</CarouselHero>,
|
|
283
336
|
);
|
|
284
337
|
|
|
285
338
|
expect(
|
|
286
339
|
container.getElementsByClassName("carousel-hero__play-pause").length,
|
|
287
340
|
).toBe(0);
|
|
288
341
|
});
|
|
342
|
+
it("removes autoplay from forwarded swiperOptions until autoplay is enabled", () => {
|
|
343
|
+
const swiperOptions = {
|
|
344
|
+
autoplay: {
|
|
345
|
+
delay: 3000,
|
|
346
|
+
},
|
|
347
|
+
speed: 500,
|
|
348
|
+
};
|
|
349
|
+
const { container } = render(
|
|
350
|
+
<CarouselHero swiperOptions={swiperOptions}>{children}</CarouselHero>,
|
|
351
|
+
);
|
|
352
|
+
|
|
353
|
+
const carousel = container.querySelector(".carousel-hero");
|
|
354
|
+
expect(carousel.getAttribute("data-swiper-options")).toBe(
|
|
355
|
+
JSON.stringify({ speed: 500 }),
|
|
356
|
+
);
|
|
357
|
+
});
|
|
289
358
|
});
|
|
290
359
|
|
|
291
360
|
describe("Swiper integration", () => {
|
|
@@ -37,11 +37,17 @@
|
|
|
37
37
|
|
|
38
38
|
.checkbox--toggle .checkbox + .checkbox-display {
|
|
39
39
|
position: relative;
|
|
40
|
-
background: color
|
|
41
|
-
border-color: color
|
|
40
|
+
background: var(--color-fill-contrast);
|
|
41
|
+
border-color: var(--color-fill-contrast);
|
|
42
42
|
background-image:
|
|
43
|
-
url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M3 7L1 9l5 5L16 4l-2-2-8 8-3-3z' fill='%
|
|
43
|
+
url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M3 7L1 9l5 5L16 4l-2-2-8 8-3-3z' fill='%23fff'/%3E%3C/svg%3E"),
|
|
44
44
|
url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12'%3E%3Cpath d='M12 2L10 0L6 4L2 0L0 2L4 6L0 10L2 12L6 8L10 12L12 10L8 6L12 2Z' fill='%23fff'/%3E%3C/svg%3E");
|
|
45
|
+
|
|
46
|
+
.is-dark & {
|
|
47
|
+
background-image:
|
|
48
|
+
url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16'%3E%3Cpath d='M3 7L1 9l5 5L16 4l-2-2-8 8-3-3z' fill='%23fff'/%3E%3C/svg%3E"),
|
|
49
|
+
url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12'%3E%3Cpath d='M12 2L10 0L6 4L2 0L0 2L4 6L0 10L2 12L6 8L10 12L12 10L8 6L12 2Z' fill='%23000'/%3E%3C/svg%3E");
|
|
50
|
+
}
|
|
45
51
|
background-position:
|
|
46
52
|
5px center,
|
|
47
53
|
right 7px center;
|
|
@@ -51,19 +57,20 @@
|
|
|
51
57
|
content: "";
|
|
52
58
|
pointer-events: none;
|
|
53
59
|
position: absolute;
|
|
54
|
-
background: color
|
|
60
|
+
background: var(--color-fill-primary);
|
|
55
61
|
top: 0;
|
|
56
62
|
left: 0;
|
|
57
63
|
width: 50%;
|
|
58
64
|
height: 100%;
|
|
59
65
|
transform: translateX(0);
|
|
60
66
|
transition: transform 200ms ease-out;
|
|
67
|
+
border-radius: convert.to-rem(3px);
|
|
61
68
|
}
|
|
62
69
|
}
|
|
63
70
|
|
|
64
71
|
.checkbox--toggle .checkbox:checked + .checkbox-display {
|
|
65
|
-
background-color: var(--color-surface-
|
|
66
|
-
border-color: var(--color-surface-
|
|
72
|
+
background-color: var(--color-surface-tertiary);
|
|
73
|
+
border-color: var(--color-surface-tertiary);
|
|
67
74
|
|
|
68
75
|
&::after {
|
|
69
76
|
transform: translateX(100%);
|
|
@@ -52,6 +52,7 @@ const InputStepper: React.FC<InputStepperProps> = ({
|
|
|
52
52
|
<div
|
|
53
53
|
className={cx(CLASS_ROOT, className, {
|
|
54
54
|
[`${CLASS_ROOT}--disabled`]: isDisabled,
|
|
55
|
+
[`${CLASS_ROOT}--invalid`]: isInvalid,
|
|
55
56
|
})}
|
|
56
57
|
ref={elementRef}
|
|
57
58
|
data-inputstepper={config ? JSON.stringify(config) : true}
|
|
@@ -70,6 +71,7 @@ const InputStepper: React.FC<InputStepperProps> = ({
|
|
|
70
71
|
id={id}
|
|
71
72
|
name={name}
|
|
72
73
|
disabled={isDisabled}
|
|
74
|
+
isInvalid={isInvalid}
|
|
73
75
|
htmlType="number"
|
|
74
76
|
inputMode="numeric"
|
|
75
77
|
/>
|
|
@@ -14,8 +14,7 @@
|
|
|
14
14
|
appearance: textfield;
|
|
15
15
|
z-index: 0;
|
|
16
16
|
border-radius: 0;
|
|
17
|
-
padding: space.get("xsmall")
|
|
18
|
-
space.get("xsmall");
|
|
17
|
+
padding: space.get("xsmall");
|
|
19
18
|
text-align: center;
|
|
20
19
|
border-left: 0;
|
|
21
20
|
border-right: 0;
|
|
@@ -109,6 +108,22 @@
|
|
|
109
108
|
z-index: 1;
|
|
110
109
|
}
|
|
111
110
|
|
|
111
|
+
&--invalid {
|
|
112
|
+
.input-stepper__button,
|
|
113
|
+
.input-stepper__number,
|
|
114
|
+
.input-stepper__button--minus:active:not(:disabled),
|
|
115
|
+
.input-stepper__button--plus:active:not(:disabled) {
|
|
116
|
+
border-color: var(--color-border-negative);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
@media (hover: hover) and (pointer: fine) {
|
|
120
|
+
.input-stepper__button--minus:hover:not(:disabled),
|
|
121
|
+
.input-stepper__button--plus:hover:not(:disabled) {
|
|
122
|
+
border-color: var(--color-border-negative);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
112
127
|
&__button--minus:disabled,
|
|
113
128
|
&__button--plus:disabled {
|
|
114
129
|
&::before {
|
|
@@ -116,13 +131,15 @@
|
|
|
116
131
|
}
|
|
117
132
|
}
|
|
118
133
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
134
|
+
@media (hover: hover) and (pointer: fine) {
|
|
135
|
+
&__button--minus:hover:not(:disabled),
|
|
136
|
+
&__button--plus:hover:not(:disabled) {
|
|
137
|
+
background-color: var(--color-fill-contrast);
|
|
138
|
+
border-color: var(--color-fill-contrast);
|
|
123
139
|
|
|
124
|
-
|
|
125
|
-
|
|
140
|
+
&::before {
|
|
141
|
+
background-color: var(--color-fill-primary);
|
|
142
|
+
}
|
|
126
143
|
}
|
|
127
144
|
}
|
|
128
145
|
|
|
@@ -28,6 +28,14 @@ describe("rendering InputStepper", () => {
|
|
|
28
28
|
expect(getByLabelText("zvýšiť počet")).toBeDisabled();
|
|
29
29
|
expect(getByRole("spinbutton")).toBeDisabled();
|
|
30
30
|
});
|
|
31
|
+
it("has invalid classes when isInvalid prop is passed", () => {
|
|
32
|
+
const { getByTestId, getByRole } = render(
|
|
33
|
+
<InputStepper data-testid="test-id" id="id" isInvalid />,
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
expect(getByTestId("test-id")).toHaveClass("input-stepper--invalid");
|
|
37
|
+
expect(getByRole("spinbutton")).toHaveClass("is-invalid");
|
|
38
|
+
});
|
|
31
39
|
it("has InputStepper removed input field, replaced it with text number and set defaultValue with when config prop is passed", () => {
|
|
32
40
|
const { getByText } = render(
|
|
33
41
|
<InputStepper
|
|
@@ -414,9 +414,9 @@ export const Megamenu = ({
|
|
|
414
414
|
aria-labelledby={ids.mobileMainTitleId}
|
|
415
415
|
aria-hidden="true"
|
|
416
416
|
>
|
|
417
|
-
<
|
|
417
|
+
<span id={ids.mobileMainTitleId} className="sr-only">
|
|
418
418
|
Hlavné menu
|
|
419
|
-
</
|
|
419
|
+
</span>
|
|
420
420
|
<button
|
|
421
421
|
aria-label="Zatvoriť menu"
|
|
422
422
|
className={CLASS_MOBILE_OVERLAY}
|
|
@@ -325,9 +325,9 @@ export const MegamenuBlog = ({
|
|
|
325
325
|
aria-labelledby={ids.mobileMainTitleId}
|
|
326
326
|
aria-hidden="true"
|
|
327
327
|
>
|
|
328
|
-
<
|
|
328
|
+
<span id={ids.mobileMainTitleId} className="sr-only">
|
|
329
329
|
Hlavné menu
|
|
330
|
-
</
|
|
330
|
+
</span>
|
|
331
331
|
<button
|
|
332
332
|
aria-label="Zatvoriť menu"
|
|
333
333
|
className={CLASS_MOBILE_OVERLAY}
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
font-size: inherit;
|
|
60
60
|
text-decoration: underline;
|
|
61
61
|
text-underline-offset: convert.to-rem(2px);
|
|
62
|
-
text-decoration-thickness:
|
|
62
|
+
text-decoration-thickness: auto;
|
|
63
63
|
|
|
64
64
|
&:hover,
|
|
65
65
|
&:focus,
|
|
@@ -630,7 +630,8 @@
|
|
|
630
630
|
@mixin mobile-account-logout {
|
|
631
631
|
display: inline-block;
|
|
632
632
|
text-decoration: underline;
|
|
633
|
-
text-underline-offset: convert.to-rem(
|
|
633
|
+
text-underline-offset: convert.to-rem(2px);
|
|
634
|
+
text-decoration-thickness: auto;
|
|
634
635
|
margin-bottom: convert.to-rem(20px);
|
|
635
636
|
font-weight: 400 !important;
|
|
636
637
|
}
|
|
@@ -665,8 +666,15 @@
|
|
|
665
666
|
}
|
|
666
667
|
|
|
667
668
|
@mixin mobile-account-link {
|
|
668
|
-
text-decoration:
|
|
669
|
-
|
|
669
|
+
text-decoration: none !important;
|
|
670
|
+
|
|
671
|
+
&:hover,
|
|
672
|
+
&:focus,
|
|
673
|
+
&:active {
|
|
674
|
+
text-decoration: underline !important;
|
|
675
|
+
text-underline-offset: convert.to-rem(2px);
|
|
676
|
+
text-decoration-thickness: auto;
|
|
677
|
+
}
|
|
670
678
|
}
|
|
671
679
|
|
|
672
680
|
@mixin container {
|
|
@@ -696,7 +704,7 @@
|
|
|
696
704
|
a:focus {
|
|
697
705
|
text-decoration: underline;
|
|
698
706
|
text-underline-offset: convert.to-rem(2px);
|
|
699
|
-
text-decoration-thickness:
|
|
707
|
+
text-decoration-thickness: auto;
|
|
700
708
|
}
|
|
701
709
|
|
|
702
710
|
@include breakpoint.get("md", "down") {
|
|
@@ -709,19 +717,15 @@
|
|
|
709
717
|
}
|
|
710
718
|
|
|
711
719
|
@mixin text-large {
|
|
712
|
-
font-size: convert.to-rem(
|
|
720
|
+
font-size: convert.to-rem(28px) !important;
|
|
721
|
+
line-height: convert.to-rem(32px);
|
|
713
722
|
font-weight: 700;
|
|
714
|
-
line-height: convert.to-rem(22px);
|
|
715
|
-
|
|
716
|
-
@include breakpoint.get("md", "down") {
|
|
717
|
-
font-size: convert.to-rem(24px) !important;
|
|
718
|
-
line-height: convert.to-rem(28px);
|
|
719
|
-
}
|
|
720
723
|
}
|
|
721
724
|
|
|
722
725
|
@mixin caption {
|
|
723
726
|
@include generate.css-map(typographyConfig.$caption, "default");
|
|
724
727
|
margin-top: 0;
|
|
728
|
+
margin-bottom: convert.to-rem(20px);
|
|
725
729
|
}
|
|
726
730
|
|
|
727
731
|
@mixin caption-large {
|
|
@@ -817,6 +821,10 @@
|
|
|
817
821
|
@mixin accordion {
|
|
818
822
|
@include accordion.base;
|
|
819
823
|
margin-bottom: 0px !important;
|
|
824
|
+
|
|
825
|
+
a {
|
|
826
|
+
text-decoration: none !important;
|
|
827
|
+
}
|
|
820
828
|
}
|
|
821
829
|
|
|
822
830
|
@mixin accordion-item {
|
|
@@ -6,16 +6,78 @@ import unescape from "unescape-html";
|
|
|
6
6
|
import { formatHTML } from "../../utils/formatCode";
|
|
7
7
|
import { Button } from "../Button";
|
|
8
8
|
import Code from "../Code/";
|
|
9
|
+
import { getElementDisplayName } from "./getElementDisplayName";
|
|
9
10
|
|
|
10
11
|
interface CodeExampleProps {
|
|
11
12
|
codeJSXOptions?: Record<string, any>;
|
|
12
13
|
codeTypes?: string[];
|
|
13
14
|
children?: ReactNode;
|
|
15
|
+
htmlThemeClass?: string;
|
|
14
16
|
jsxCode?: string; // Pre-generated JSX string (from server-side PreviewAuto)
|
|
15
17
|
htmlCode?: ReactNode; // Code for HTML rendering
|
|
16
18
|
[key: string]: any;
|
|
17
19
|
}
|
|
18
20
|
|
|
21
|
+
const addClassToOpeningTag = (tag: string, className: string): string => {
|
|
22
|
+
if (tag.includes(' class="')) {
|
|
23
|
+
return tag.replace(/ class="([^"]*)"/, (_, existingClassName) => {
|
|
24
|
+
const mergedClassName = [existingClassName, className]
|
|
25
|
+
.filter(Boolean)
|
|
26
|
+
.join(" ");
|
|
27
|
+
return ` class="${mergedClassName}"`;
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return tag.replace(/^<([\w-]+)/, `<$1 class="${className}"`);
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const applyThemeClassToMarkup = (
|
|
35
|
+
markup: string,
|
|
36
|
+
themeClass?: string,
|
|
37
|
+
wrapMultipleRoots = false,
|
|
38
|
+
): string => {
|
|
39
|
+
if (!themeClass || !markup.trim()) {
|
|
40
|
+
return markup;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (wrapMultipleRoots) {
|
|
44
|
+
return `<div class="${themeClass}">${markup}</div>`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return markup.replace(/^<[^>]+>/, (openingTag) =>
|
|
48
|
+
addClassToOpeningTag(openingTag, themeClass),
|
|
49
|
+
);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const renderMarkupToHtml = (markup: ReactNode, themeClass?: string): string => {
|
|
53
|
+
if (!markup) {
|
|
54
|
+
return "";
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (typeof markup === "string") {
|
|
58
|
+
return markup;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (Array.isArray(markup)) {
|
|
62
|
+
const renderedMarkup = markup
|
|
63
|
+
.map((markupItem) =>
|
|
64
|
+
renderToStaticMarkup(markupItem as React.ReactElement),
|
|
65
|
+
)
|
|
66
|
+
.join("");
|
|
67
|
+
|
|
68
|
+
return applyThemeClassToMarkup(
|
|
69
|
+
renderedMarkup,
|
|
70
|
+
themeClass,
|
|
71
|
+
markup.length > 1,
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return applyThemeClassToMarkup(
|
|
76
|
+
renderToStaticMarkup(markup as React.ReactElement),
|
|
77
|
+
themeClass,
|
|
78
|
+
);
|
|
79
|
+
};
|
|
80
|
+
|
|
19
81
|
/**
|
|
20
82
|
* Remove props that are undefined or null
|
|
21
83
|
* Don't show React.Fragment in code example
|
|
@@ -68,25 +130,7 @@ const getJSXAsStringFromMarkup = (
|
|
|
68
130
|
showDefaultProps: false,
|
|
69
131
|
showFunctions: true,
|
|
70
132
|
functionValue: (fn: any) => fn.name,
|
|
71
|
-
displayName:
|
|
72
|
-
// Try to get display name from various sources
|
|
73
|
-
if (ReactElement.props && ReactElement.props.mdxType) {
|
|
74
|
-
return ReactElement.props.mdxType;
|
|
75
|
-
}
|
|
76
|
-
if (ReactElement.type && ReactElement.type.displayName) {
|
|
77
|
-
return ReactElement.type.displayName;
|
|
78
|
-
}
|
|
79
|
-
if (ReactElement.type && ReactElement.type.name) {
|
|
80
|
-
return ReactElement.type.name;
|
|
81
|
-
}
|
|
82
|
-
if (typeof ReactElement.type === "string") {
|
|
83
|
-
return ReactElement.type;
|
|
84
|
-
}
|
|
85
|
-
// Fallback to type name or 'Component'
|
|
86
|
-
return (
|
|
87
|
-
ReactElement.type?.displayName || ReactElement.type?.name || "Component"
|
|
88
|
-
);
|
|
89
|
-
},
|
|
133
|
+
displayName: getElementDisplayName,
|
|
90
134
|
filterProps: ["mdxType", "originalType", ...filterProps],
|
|
91
135
|
...otherOptions,
|
|
92
136
|
};
|
|
@@ -124,6 +168,7 @@ const CodeExample: React.FC<CodeExampleProps> = ({
|
|
|
124
168
|
children,
|
|
125
169
|
codeJSXOptions,
|
|
126
170
|
codeTypes = ["html", "jsx"],
|
|
171
|
+
htmlThemeClass,
|
|
127
172
|
jsxCode,
|
|
128
173
|
htmlCode,
|
|
129
174
|
...other
|
|
@@ -184,18 +229,14 @@ const CodeExample: React.FC<CodeExampleProps> = ({
|
|
|
184
229
|
typeof htmlCode === "string"
|
|
185
230
|
? unescape(htmlCode)
|
|
186
231
|
: unescape(
|
|
187
|
-
formatHTML(
|
|
188
|
-
renderToStaticMarkup(htmlCode as React.ReactElement),
|
|
189
|
-
),
|
|
232
|
+
formatHTML(renderMarkupToHtml(htmlCode, htmlThemeClass)),
|
|
190
233
|
);
|
|
191
234
|
} else {
|
|
192
235
|
codeToShow =
|
|
193
236
|
typeof children === "string"
|
|
194
237
|
? unescape(children)
|
|
195
238
|
: unescape(
|
|
196
|
-
formatHTML(
|
|
197
|
-
renderToStaticMarkup(children as React.ReactElement),
|
|
198
|
-
),
|
|
239
|
+
formatHTML(renderMarkupToHtml(children, htmlThemeClass)),
|
|
199
240
|
);
|
|
200
241
|
}
|
|
201
242
|
break;
|