@orangesk/orange-design-system 2.0.0-alpha.5 → 2.0.0-beta.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.
- package/build/components/Accordion/tsconfig.tsbuildinfo +1 -1
- package/build/components/Alert/tsconfig.tsbuildinfo +1 -1
- package/build/components/AnchorNavigation/tsconfig.tsbuildinfo +1 -1
- package/build/components/Bar/tsconfig.tsbuildinfo +1 -1
- package/build/components/BlockAction/tsconfig.tsbuildinfo +1 -1
- package/build/components/BodyBanner/tsconfig.tsbuildinfo +1 -1
- package/build/components/Breadcrumbs/tsconfig.tsbuildinfo +1 -1
- package/build/components/Button/tsconfig.tsbuildinfo +1 -1
- package/build/components/Buttons/tsconfig.tsbuildinfo +1 -1
- package/build/components/Card/tsconfig.tsbuildinfo +1 -1
- package/build/components/Carousel/tsconfig.tsbuildinfo +1 -1
- package/build/components/CarouselPromotions/tsconfig.tsbuildinfo +1 -1
- package/build/components/CartTable/tsconfig.tsbuildinfo +1 -1
- package/build/components/Code/tsconfig.tsbuildinfo +1 -1
- package/build/components/Container/tsconfig.tsbuildinfo +1 -1
- package/build/components/Controls/tsconfig.tsbuildinfo +1 -1
- package/build/components/Cover/tsconfig.tsbuildinfo +1 -1
- package/build/components/Divider/tsconfig.tsbuildinfo +1 -1
- package/build/components/DocumentationSidebar/index.js +1 -1
- package/build/components/DocumentationSidebar/index.js.map +1 -1
- package/build/components/DocumentationSidebar/tsconfig.tsbuildinfo +1 -1
- package/build/components/Dropdown/tsconfig.tsbuildinfo +1 -1
- package/build/components/Expander/tsconfig.tsbuildinfo +1 -1
- package/build/components/FeatureAccordion/tsconfig.tsbuildinfo +1 -1
- package/build/components/Footer/tsconfig.tsbuildinfo +1 -1
- package/build/components/Forms/index.js +1 -1
- package/build/components/Forms/index.js.map +1 -1
- package/build/components/Forms/tsconfig.tsbuildinfo +1 -1
- package/build/components/Gauge/tsconfig.tsbuildinfo +1 -1
- package/build/components/Grid/tsconfig.tsbuildinfo +1 -1
- package/build/components/Hero/tsconfig.tsbuildinfo +1 -1
- package/build/components/Icon/tsconfig.tsbuildinfo +1 -1
- package/build/components/IconList/tsconfig.tsbuildinfo +1 -1
- package/build/components/Image/tsconfig.tsbuildinfo +1 -1
- package/build/components/Link/tsconfig.tsbuildinfo +1 -1
- package/build/components/List/tsconfig.tsbuildinfo +1 -1
- package/build/components/Loader/tsconfig.tsbuildinfo +1 -1
- package/build/components/Megamenu/index.js +6 -6
- package/build/components/Megamenu/index.js.map +1 -1
- package/build/components/Megamenu/style.css +1 -1
- package/build/components/Megamenu/style.css.map +1 -1
- package/build/components/Megamenu/tsconfig.tsbuildinfo +1 -1
- package/build/components/Modal/index.js +4 -4
- package/build/components/Modal/index.js.map +1 -1
- package/build/components/Modal/tsconfig.tsbuildinfo +1 -1
- package/build/components/Pagination/tsconfig.tsbuildinfo +1 -1
- package/build/components/Pill/tsconfig.tsbuildinfo +1 -1
- package/build/components/Preview/tsconfig.tsbuildinfo +1 -1
- package/build/components/Progress/tsconfig.tsbuildinfo +1 -1
- package/build/components/PromoBanner/tsconfig.tsbuildinfo +1 -1
- package/build/components/PromotionCard/tsconfig.tsbuildinfo +1 -1
- package/build/components/Section/tsconfig.tsbuildinfo +1 -1
- package/build/components/Skeleton/tsconfig.tsbuildinfo +1 -1
- package/build/components/SkipLink/tsconfig.tsbuildinfo +1 -1
- package/build/components/Stepbar/tsconfig.tsbuildinfo +1 -1
- package/build/components/Sticker/tsconfig.tsbuildinfo +1 -1
- package/build/components/Table/tsconfig.tsbuildinfo +1 -1
- package/build/components/Tabs/tsconfig.tsbuildinfo +1 -1
- package/build/components/Tag/tsconfig.tsbuildinfo +1 -1
- package/build/components/Testimonial/tsconfig.tsbuildinfo +1 -1
- package/build/components/Tile/tsconfig.tsbuildinfo +1 -1
- package/build/components/Tooltip/tsconfig.tsbuildinfo +1 -1
- package/build/components/index.css +1 -1
- package/build/components/index.css.map +1 -1
- package/build/components/index.js +7 -7
- package/build/components/index.js.map +1 -1
- package/build/components/static.js +1 -1
- package/build/components/static.js.map +1 -1
- package/build/components/tsconfig.tsbuildinfo +1 -1
- package/build/components/types/src/components/Forms/Message/Message.d.ts +1 -1
- package/build/components/types/src/components/Megamenu/index.d.ts +2 -0
- package/build/components/types/src/components/Modal/Modal.d.ts +2 -0
- package/build/components/types/src/components/Modal/ModalBody.d.ts +1 -0
- package/build/components/types/src/components/Modal/ModalProductHeader.d.ts +9 -0
- package/build/components/types/src/components/Modal/index.d.ts +1 -0
- package/build/components/types/src/components/index.d.ts +3 -2
- package/build/lib/before-components.css +1 -1
- package/build/lib/before-components.css.map +1 -1
- package/build/lib/components.css +1 -1
- package/build/lib/components.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/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/components/CarouselPromotions/styles/mixins.scss +6 -8
- package/src/components/Forms/Message/Message.tsx +6 -2
- package/src/components/Forms/Message/styles/style.scss +6 -0
- package/src/components/Megamenu/index.ts +3 -0
- package/src/components/Megamenu/styles/mixins.scss +4 -0
- package/src/components/Megamenu/styles/style.scss +2 -1
- package/src/components/Modal/Modal.mdx +119 -3
- package/src/components/Modal/Modal.static.ts +4 -1
- package/src/components/Modal/Modal.tsx +22 -4
- package/src/components/Modal/ModalBody.tsx +3 -0
- package/src/components/Modal/ModalProductHeader.tsx +36 -0
- package/src/components/Modal/index.ts +1 -0
- package/src/components/Modal/styles/mixins.scss +38 -4
- package/src/components/Modal/styles/style.scss +24 -0
- package/src/components/Modal/tests/Modal.conformance.test.js +8 -1
- package/src/components/Modal/tests/ModalProductHeader.unit.test.js +73 -0
- package/src/components/Pagination/styles/mixins.scss +1 -0
- package/src/components/index.ts +11 -1
- package/src/styles/typography/mixins.scss +23 -0
- package/src/styles/typography/style.scss +4 -0
|
@@ -15,7 +15,15 @@ import Grid, { GridCol } from "../Grid";
|
|
|
15
15
|
import Icon from "../Icon";
|
|
16
16
|
import IconList from "../IconList";
|
|
17
17
|
import { Image } from "../Image";
|
|
18
|
-
import Modal, {
|
|
18
|
+
import Modal, {
|
|
19
|
+
ModalHeader,
|
|
20
|
+
ModalBody,
|
|
21
|
+
ModalFooter,
|
|
22
|
+
ModalProductHeader, ModalCloseButton
|
|
23
|
+
} from ".";
|
|
24
|
+
import { Divider } from "../Divider";
|
|
25
|
+
import { Bar, BarItem } from "../Bar";
|
|
26
|
+
import { Tag } from "../Tag";
|
|
19
27
|
|
|
20
28
|
export const actionButtons = [
|
|
21
29
|
<Button type="primary" data-a11y-dialog-hide key="1">
|
|
@@ -181,6 +189,112 @@ Customize the footer. Should be primary used for specific action button cases.
|
|
|
181
189
|
</Modal>
|
|
182
190
|
</Preview>
|
|
183
191
|
|
|
192
|
+
## Product header
|
|
193
|
+
|
|
194
|
+
Use the product header to display product information with an optional image, similar to the Card component's product header.
|
|
195
|
+
|
|
196
|
+
<Preview>
|
|
197
|
+
<Button data-a11y-dialog-show="modal-product-header">
|
|
198
|
+
Open Modal with product header
|
|
199
|
+
</Button>
|
|
200
|
+
<Modal
|
|
201
|
+
id="modal-product-header"
|
|
202
|
+
actions={actionButtons}
|
|
203
|
+
renderHeader={() => (
|
|
204
|
+
<>
|
|
205
|
+
<ModalCloseButton />
|
|
206
|
+
<ModalProductHeader
|
|
207
|
+
image={<img src="/images/product-1.svg" alt="Product" />}
|
|
208
|
+
>
|
|
209
|
+
<p className="bold color-orange">Odporúčame</p>
|
|
210
|
+
<Bar space="small" className="mb-none">
|
|
211
|
+
<BarItem>
|
|
212
|
+
<h2 className="h4 mb-none">Prémiový paušál</h2>
|
|
213
|
+
</BarItem>
|
|
214
|
+
<BarItem>
|
|
215
|
+
<Tag color="black">5G</Tag>
|
|
216
|
+
</BarItem>
|
|
217
|
+
</Bar>
|
|
218
|
+
<p className="h2 color-orange mb-none thin">∞ GB</p>
|
|
219
|
+
</ModalProductHeader>
|
|
220
|
+
<Divider thinLine />
|
|
221
|
+
</>
|
|
222
|
+
)}
|
|
223
|
+
>
|
|
224
|
+
<p className="h5 mb">
|
|
225
|
+
V paušále získate 200 GB plnou rýchlosťou, potom 20 Mbit/s
|
|
226
|
+
</p>
|
|
227
|
+
<h3 className="h4">S paušálom</h3>
|
|
228
|
+
<ul className="list--marker-orange">
|
|
229
|
+
<li>
|
|
230
|
+
nekonečné dáta, po prečerpaní 200 GB pokračujete s rýchlosťou 20
|
|
231
|
+
Mbit/s, dáta v EÚ podliehajú regulácii
|
|
232
|
+
</li>
|
|
233
|
+
<li>
|
|
234
|
+
nekonečné volania v SR a v EÚ (Zóna 1), medzinárodné volania do EÚ
|
|
235
|
+
a do Zóny 1 sú spoplatnené sumou 0,03 € za minútu
|
|
236
|
+
</li>
|
|
237
|
+
<li>nekonečné SMS/MMS v SR/EÚ/Zóna 1</li>
|
|
238
|
+
<li>prístup do 5G siete</li>
|
|
239
|
+
<li>možnosť dokúpiť ďalších 5 GB len za 5,13 €</li>
|
|
240
|
+
<li>možnosť bezplatnej aktivácie služby Online ochrana Basic</li>
|
|
241
|
+
<li>bezplatné založenie skupiny Navzájom zadarmo</li>
|
|
242
|
+
</ul>
|
|
243
|
+
{parse(loremIpsum({ count: 2, units: "paragraph", format: "html" }))}
|
|
244
|
+
</Modal>
|
|
245
|
+
</Preview>
|
|
246
|
+
|
|
247
|
+
<Preview>
|
|
248
|
+
<Button data-a11y-dialog-show="modal-product-header-small">
|
|
249
|
+
Open Modal with compact product header
|
|
250
|
+
</Button>
|
|
251
|
+
<Modal
|
|
252
|
+
id="modal-product-header-small"
|
|
253
|
+
actions={actionButtons}
|
|
254
|
+
renderHeader={() => (
|
|
255
|
+
<>
|
|
256
|
+
<ModalCloseButton />
|
|
257
|
+
<ModalProductHeader
|
|
258
|
+
space="small"
|
|
259
|
+
image={<img src="/images/product-2.svg" alt="Product" />}
|
|
260
|
+
>
|
|
261
|
+
<Bar space="small" className="mb-none">
|
|
262
|
+
<BarItem>
|
|
263
|
+
<h2 className="h3 mb-none">Veľký paušál</h2>
|
|
264
|
+
</BarItem>
|
|
265
|
+
<BarItem>
|
|
266
|
+
<Tag color="black">5G</Tag>
|
|
267
|
+
</BarItem>
|
|
268
|
+
</Bar>
|
|
269
|
+
<p className="h2 color-orange mb-none thin">∞ GB</p>
|
|
270
|
+
</ModalProductHeader>
|
|
271
|
+
<Divider thinLine />
|
|
272
|
+
</>
|
|
273
|
+
)}
|
|
274
|
+
>
|
|
275
|
+
<p className="h5 mb">
|
|
276
|
+
V paušále získate 200 GB plnou rýchlosťou, potom 20 Mbit/s
|
|
277
|
+
</p>
|
|
278
|
+
<h3 className="h4">S paušálom</h3>
|
|
279
|
+
<ul className="list--marker-orange">
|
|
280
|
+
<li>
|
|
281
|
+
nekonečné dáta, po prečerpaní 200 GB pokračujete s rýchlosťou 20
|
|
282
|
+
Mbit/s, dáta v EÚ podliehajú regulácii
|
|
283
|
+
</li>
|
|
284
|
+
<li>
|
|
285
|
+
nekonečné volania v SR a v EÚ (Zóna 1), medzinárodné volania do EÚ
|
|
286
|
+
a do Zóny 1 sú spoplatnené sumou 0,03 € za minútu
|
|
287
|
+
</li>
|
|
288
|
+
<li>nekonečné SMS/MMS v SR/EÚ/Zóna 1</li>
|
|
289
|
+
<li>prístup do 5G siete</li>
|
|
290
|
+
<li>možnosť dokúpiť ďalších 5 GB len za 5,13 €</li>
|
|
291
|
+
<li>možnosť bezplatnej aktivácie služby Online ochrana Basic</li>
|
|
292
|
+
<li>bezplatné založenie skupiny Navzájom zadarmo</li>
|
|
293
|
+
</ul>
|
|
294
|
+
{parse(loremIpsum({ count: 1, units: "paragraph", format: "html" }))}
|
|
295
|
+
</Modal>
|
|
296
|
+
</Preview>
|
|
297
|
+
|
|
184
298
|
## Full height on XS
|
|
185
299
|
|
|
186
300
|
On XS screens (mobile devices), the modal will take the full height of the viewport to maintain a consistent height when the modal contains a flow or multiple steps.
|
|
@@ -332,6 +446,8 @@ when the first/last body element is using default color (white).
|
|
|
332
446
|
|
|
333
447
|
<ComponentDocs title="<Modal />" component={Modal} />
|
|
334
448
|
|
|
449
|
+
<ComponentDocs title="<ModalProductHeader />" component={ModalProductHeader} />
|
|
450
|
+
|
|
335
451
|
## JS module reference
|
|
336
452
|
|
|
337
453
|
Modal is backed with [a11y-dialog | see docs](https://github.com/edenspiekermann/a11y-dialog)
|
|
@@ -442,8 +558,8 @@ instance.method();
|
|
|
442
558
|
|
|
443
559
|
- Modals should only be opened by activating a `button` element.
|
|
444
560
|
- Opening a modal sets focus on element with `data-a11y-modal-initial-focus`
|
|
445
|
-
|
|
446
|
-
|
|
561
|
+
attribute (modal title by default). When not present, focus is set on first
|
|
562
|
+
focusable element, usually the close button.
|
|
447
563
|
- An open modal traps focus. It must always contain a close button.
|
|
448
564
|
- Pressing ESC or clicking the overlay closes the modal.
|
|
449
565
|
- Closing a modal sets focus back on the activating `button` element.
|
|
@@ -98,10 +98,13 @@ export default class Modal {
|
|
|
98
98
|
*/
|
|
99
99
|
const modalHeader = this.element.querySelector(".modal__header");
|
|
100
100
|
if (modalHeader) {
|
|
101
|
+
const hasNoSpacingClass = modalHeader.classList.contains(
|
|
102
|
+
"modal__header--no-spacing",
|
|
103
|
+
);
|
|
101
104
|
const firstNonBtnElement = Array.from(modalHeader.children).find(
|
|
102
105
|
(child) => !child.classList.contains("btn"),
|
|
103
106
|
);
|
|
104
|
-
if (firstNonBtnElement) {
|
|
107
|
+
if (firstNonBtnElement && !hasNoSpacingClass) {
|
|
105
108
|
(firstNonBtnElement as HTMLElement).style.marginRight = "40px";
|
|
106
109
|
}
|
|
107
110
|
}
|
|
@@ -33,6 +33,8 @@ interface ModalProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
33
33
|
isActive?: boolean;
|
|
34
34
|
/** Disable plugin initialization. */
|
|
35
35
|
noInit?: boolean;
|
|
36
|
+
/** Custom header renderer. Receives id as function param. Returned element(s) must contain a header with close button. */
|
|
37
|
+
renderHeader?: (id: string) => React.ReactNode;
|
|
36
38
|
/** Custom body renderer. Receives title as function param. Returned element(s) must contain a title. */
|
|
37
39
|
renderBody?: () => React.ReactNode;
|
|
38
40
|
/** Custom footer renderer. Receives actions as function param. Returned element(s) must contain the actions. */
|
|
@@ -70,6 +72,7 @@ const Modal: React.FC<ModalProps> = ({
|
|
|
70
72
|
isActive,
|
|
71
73
|
size,
|
|
72
74
|
title,
|
|
75
|
+
renderHeader,
|
|
73
76
|
renderBody,
|
|
74
77
|
renderTitle,
|
|
75
78
|
renderFooter,
|
|
@@ -119,11 +122,26 @@ const Modal: React.FC<ModalProps> = ({
|
|
|
119
122
|
>
|
|
120
123
|
<div className="modal__overlay" tabIndex={-1} data-a11y-dialog-hide />
|
|
121
124
|
<div className={dialogClasses} role="document" {...other}>
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
{
|
|
125
|
+
{}
|
|
126
|
+
<div
|
|
127
|
+
className={cx(`${CLASS_ROOT}__header`, {
|
|
128
|
+
[`${CLASS_ROOT}__header--no-spacing`]: !!renderHeader,
|
|
129
|
+
})}
|
|
130
|
+
>
|
|
131
|
+
{renderHeader ? (
|
|
132
|
+
renderHeader(id)
|
|
133
|
+
) : (
|
|
134
|
+
<>
|
|
135
|
+
<ModalCloseButton />
|
|
136
|
+
{dialogTitle}
|
|
137
|
+
</>
|
|
138
|
+
)}
|
|
125
139
|
</div>
|
|
126
|
-
{renderBody ?
|
|
140
|
+
{renderBody ? (
|
|
141
|
+
renderBody()
|
|
142
|
+
) : (
|
|
143
|
+
<ModalBody withTopPadding={!!renderHeader}>{children}</ModalBody>
|
|
144
|
+
)}
|
|
127
145
|
<div
|
|
128
146
|
className={cx(`${CLASS_ROOT}__footer`, {
|
|
129
147
|
[`${CLASS_ROOT}__footer--sticky`]: hasStickyFooter,
|
|
@@ -20,6 +20,7 @@ interface ModalBodyProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
|
20
20
|
color?: BodyColor;
|
|
21
21
|
className?: string;
|
|
22
22
|
children?: React.ReactNode;
|
|
23
|
+
withTopPadding?: boolean;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
const CLASS_ROOT = "modal__body";
|
|
@@ -28,12 +29,14 @@ const ModalBody: React.FC<ModalBodyProps> = ({
|
|
|
28
29
|
color,
|
|
29
30
|
className,
|
|
30
31
|
children,
|
|
32
|
+
withTopPadding,
|
|
31
33
|
...other
|
|
32
34
|
}) => (
|
|
33
35
|
<div
|
|
34
36
|
className={cx(CLASS_ROOT, className, {
|
|
35
37
|
[`bg-${color}`]: color,
|
|
36
38
|
[`${CLASS_ROOT}--colorful`]: color,
|
|
39
|
+
[`${CLASS_ROOT}--with-top-padding`]: withTopPadding,
|
|
37
40
|
})}
|
|
38
41
|
{...other}
|
|
39
42
|
>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import cx from "classnames";
|
|
3
|
+
|
|
4
|
+
interface ModalProductHeaderProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
5
|
+
image?: React.ReactNode;
|
|
6
|
+
/** Use small spacing */
|
|
7
|
+
space?: "small";
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const CLASS_ROOT = "modal__product";
|
|
11
|
+
|
|
12
|
+
const ModalProductHeader = React.forwardRef<
|
|
13
|
+
HTMLDivElement,
|
|
14
|
+
ModalProductHeaderProps
|
|
15
|
+
>(({ className, children, image, space, ...other }, ref) => {
|
|
16
|
+
const classes = cx(
|
|
17
|
+
`${CLASS_ROOT}-header`,
|
|
18
|
+
{
|
|
19
|
+
[`${CLASS_ROOT}-header--space-small`]: space === "small",
|
|
20
|
+
},
|
|
21
|
+
className,
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const contentClasses = `${CLASS_ROOT}-content`;
|
|
25
|
+
|
|
26
|
+
return (
|
|
27
|
+
<div className={classes} ref={ref} {...other}>
|
|
28
|
+
<div className={contentClasses}>{children}</div>
|
|
29
|
+
{image}
|
|
30
|
+
</div>
|
|
31
|
+
);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
ModalProductHeader.displayName = "ModalProductHeader";
|
|
35
|
+
|
|
36
|
+
export { ModalProductHeader };
|
|
@@ -33,9 +33,8 @@
|
|
|
33
33
|
z-index: config.$overlay-z-index;
|
|
34
34
|
opacity: 0;
|
|
35
35
|
transform: scale(1.1, 1.1);
|
|
36
|
-
transition:
|
|
37
|
-
|
|
38
|
-
transform config.$overlay-e;
|
|
36
|
+
transition: opacity config.$overlay-e,
|
|
37
|
+
transform config.$overlay-e;
|
|
39
38
|
backface-visibility: hidden;
|
|
40
39
|
}
|
|
41
40
|
|
|
@@ -93,6 +92,10 @@
|
|
|
93
92
|
> *:last-child {
|
|
94
93
|
margin-bottom: 0;
|
|
95
94
|
}
|
|
95
|
+
|
|
96
|
+
.divider {
|
|
97
|
+
padding: 0;
|
|
98
|
+
}
|
|
96
99
|
}
|
|
97
100
|
|
|
98
101
|
@mixin close {
|
|
@@ -110,9 +113,20 @@
|
|
|
110
113
|
@mixin header-spacing($size, $sizes: config.$spacing) {
|
|
111
114
|
$spacing: map.get($sizes, $size);
|
|
112
115
|
|
|
116
|
+
&:not(.modal__header--no-spacing) {
|
|
117
|
+
@each $breakpoint, $space in $spacing {
|
|
118
|
+
@include breakpoint.get($breakpoint) {
|
|
119
|
+
padding: $space;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
@mixin body-spacing-top($size, $sizes: config.$spacing) {
|
|
126
|
+
$spacing: map.get($sizes, $size);
|
|
113
127
|
@each $breakpoint, $space in $spacing {
|
|
114
128
|
@include breakpoint.get($breakpoint) {
|
|
115
|
-
padding: $space;
|
|
129
|
+
padding-top: $space;
|
|
116
130
|
}
|
|
117
131
|
}
|
|
118
132
|
}
|
|
@@ -198,3 +212,23 @@
|
|
|
198
212
|
background-color: var(--color-surface-primary);
|
|
199
213
|
}
|
|
200
214
|
}
|
|
215
|
+
|
|
216
|
+
@mixin modal-product-header($spacing) {
|
|
217
|
+
flex: 0 1 auto;
|
|
218
|
+
|
|
219
|
+
@if ($spacing == null) {
|
|
220
|
+
@each $breakpoint, $value in map.get(config.$spacing, "default") {
|
|
221
|
+
@include breakpoint.get($breakpoint) {
|
|
222
|
+
padding: $value;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
} @else {
|
|
226
|
+
padding: $spacing;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
@mixin modal-product-image() {
|
|
231
|
+
object-fit: cover;
|
|
232
|
+
object-position: left;
|
|
233
|
+
max-width: convert.to-rem(125px);
|
|
234
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
@use "sass:map";
|
|
2
2
|
@use "../../../styles/tools/generate";
|
|
3
|
+
@use "../../../styles/tokens/space";
|
|
3
4
|
@use "../../../styles/tokens/breakpoint";
|
|
4
5
|
@use "./config";
|
|
5
6
|
@use "./mixins";
|
|
@@ -54,6 +55,10 @@
|
|
|
54
55
|
.modal__dialog#{generate.variant-name($size)} & {
|
|
55
56
|
@include mixins.body-spacing($size);
|
|
56
57
|
}
|
|
58
|
+
|
|
59
|
+
.modal__dialog#{generate.variant-name($size)} > &--with-top-padding {
|
|
60
|
+
@include mixins.body-spacing-top($size);
|
|
61
|
+
}
|
|
57
62
|
}
|
|
58
63
|
|
|
59
64
|
&--colorful {
|
|
@@ -96,4 +101,23 @@
|
|
|
96
101
|
}
|
|
97
102
|
}
|
|
98
103
|
}
|
|
104
|
+
|
|
105
|
+
.modal__product {
|
|
106
|
+
&-header {
|
|
107
|
+
display: flex;
|
|
108
|
+
justify-content: space-between;
|
|
109
|
+
|
|
110
|
+
> img {
|
|
111
|
+
@include mixins.modal-product-image;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
&-content {
|
|
116
|
+
@include mixins.modal-product-header(null);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.modal__product-header--space-small .modal__product-content {
|
|
121
|
+
@include mixins.modal-product-header(space.get());
|
|
122
|
+
}
|
|
99
123
|
}
|
|
@@ -3,7 +3,7 @@ import { render, fireEvent } from "@testing-library/react";
|
|
|
3
3
|
import { axe } from "jest-axe";
|
|
4
4
|
|
|
5
5
|
import { Button } from "../../Button";
|
|
6
|
-
import { Modal } from "../";
|
|
6
|
+
import { Modal, ModalProductHeader } from "../";
|
|
7
7
|
|
|
8
8
|
const example = (
|
|
9
9
|
<>
|
|
@@ -20,6 +20,13 @@ const example = (
|
|
|
20
20
|
interdum. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
|
21
21
|
</p>
|
|
22
22
|
</Modal>
|
|
23
|
+
<Modal id="modal-with-product-header" title="Modal with Product Header">
|
|
24
|
+
<ModalProductHeader image={<div>Product Image</div>}>
|
|
25
|
+
<h3>Product Title</h3>
|
|
26
|
+
<p>Product description</p>
|
|
27
|
+
</ModalProductHeader>
|
|
28
|
+
<p>Modal content</p>
|
|
29
|
+
</Modal>
|
|
23
30
|
</div>
|
|
24
31
|
<div id="root-modals" />
|
|
25
32
|
</>
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { render } from "@testing-library/react";
|
|
3
|
+
|
|
4
|
+
import { ModalProductHeader } from "../ModalProductHeader";
|
|
5
|
+
|
|
6
|
+
describe("rendering ModalProductHeader", () => {
|
|
7
|
+
it("has default class modal__product-header", () => {
|
|
8
|
+
const { getByTestId } = render(
|
|
9
|
+
<ModalProductHeader data-testid="test-id">Header</ModalProductHeader>,
|
|
10
|
+
);
|
|
11
|
+
expect(getByTestId("test-id")).toHaveClass("modal__product-header");
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("renders children", () => {
|
|
15
|
+
const { getByText } = render(
|
|
16
|
+
<ModalProductHeader>Product Header</ModalProductHeader>,
|
|
17
|
+
);
|
|
18
|
+
expect(getByText("Product Header")).toBeInTheDocument();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("renders image if provided", () => {
|
|
22
|
+
const { getByTestId } = render(
|
|
23
|
+
<ModalProductHeader
|
|
24
|
+
image={<div data-testid="test-image">Test Image</div>}
|
|
25
|
+
>
|
|
26
|
+
Header
|
|
27
|
+
</ModalProductHeader>,
|
|
28
|
+
);
|
|
29
|
+
expect(getByTestId("test-image")).toBeInTheDocument();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("has additional class when className is set", () => {
|
|
33
|
+
const { getByTestId } = render(
|
|
34
|
+
<ModalProductHeader data-testid="test-id" className="test-class">
|
|
35
|
+
Header
|
|
36
|
+
</ModalProductHeader>,
|
|
37
|
+
);
|
|
38
|
+
expect(getByTestId("test-id")).toHaveClass("modal__product-header");
|
|
39
|
+
expect(getByTestId("test-id")).toHaveClass("test-class");
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('has modal__product-header--space-small class when space="small"', () => {
|
|
43
|
+
const { getByTestId } = render(
|
|
44
|
+
<ModalProductHeader data-testid="test-id" space="small">
|
|
45
|
+
Header
|
|
46
|
+
</ModalProductHeader>,
|
|
47
|
+
);
|
|
48
|
+
expect(getByTestId("test-id")).toHaveClass(
|
|
49
|
+
"modal__product-header--space-small",
|
|
50
|
+
);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("does not have modal__product-header--space-small class when space is not set", () => {
|
|
54
|
+
const { getByTestId } = render(
|
|
55
|
+
<ModalProductHeader data-testid="test-id">Header</ModalProductHeader>,
|
|
56
|
+
);
|
|
57
|
+
expect(getByTestId("test-id")).not.toHaveClass(
|
|
58
|
+
"modal__product-header--space-small",
|
|
59
|
+
);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("has content wrapper with modal__product-content class", () => {
|
|
63
|
+
const { container } = render(
|
|
64
|
+
<ModalProductHeader>Product Header</ModalProductHeader>,
|
|
65
|
+
);
|
|
66
|
+
expect(
|
|
67
|
+
container.querySelector(".modal__product-content"),
|
|
68
|
+
).toBeInTheDocument();
|
|
69
|
+
expect(
|
|
70
|
+
container.querySelector(".modal__product-content"),
|
|
71
|
+
).toHaveTextContent("Product Header");
|
|
72
|
+
});
|
|
73
|
+
});
|
package/src/components/index.ts
CHANGED
|
@@ -41,7 +41,14 @@ import { Grid, GridCol } from "./Grid";
|
|
|
41
41
|
import { Image } from "./Image";
|
|
42
42
|
import { Link } from "./Link";
|
|
43
43
|
import { Loader } from "./Loader";
|
|
44
|
-
import {
|
|
44
|
+
import { MegamenuDropdown } from "./Megamenu";
|
|
45
|
+
import {
|
|
46
|
+
Modal,
|
|
47
|
+
ModalBody,
|
|
48
|
+
ModalCloseButton,
|
|
49
|
+
ModalTitle,
|
|
50
|
+
ModalProductHeader,
|
|
51
|
+
} from "./Modal";
|
|
45
52
|
import { Section } from "./Section";
|
|
46
53
|
import { Sticker } from "./Sticker";
|
|
47
54
|
import { SkipLink } from "./SkipLink";
|
|
@@ -85,6 +92,7 @@ import { Cover } from "./Cover";
|
|
|
85
92
|
import { Testimonial } from "./Testimonial";
|
|
86
93
|
import { Hero } from "./Hero";
|
|
87
94
|
import { IconList, Item } from "./IconList";
|
|
95
|
+
|
|
88
96
|
export {
|
|
89
97
|
Accordion,
|
|
90
98
|
AccordionItem,
|
|
@@ -144,10 +152,12 @@ export {
|
|
|
144
152
|
List,
|
|
145
153
|
ListItem,
|
|
146
154
|
Loader,
|
|
155
|
+
MegamenuDropdown,
|
|
147
156
|
Message,
|
|
148
157
|
Modal,
|
|
149
158
|
ModalBody,
|
|
150
159
|
ModalCloseButton,
|
|
160
|
+
ModalProductHeader,
|
|
151
161
|
ModalTitle,
|
|
152
162
|
Pagination,
|
|
153
163
|
Pictogram,
|
|
@@ -55,6 +55,11 @@
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
// Default štýly pre všetky a elementy
|
|
59
|
+
a {
|
|
60
|
+
@include generate.responsive-css-map($config);
|
|
61
|
+
}
|
|
62
|
+
|
|
58
63
|
// Generovanie variantov pre p elementy s triedami
|
|
59
64
|
@each $variant, $breakpoints in $config {
|
|
60
65
|
@if $variant != default {
|
|
@@ -64,6 +69,15 @@
|
|
|
64
69
|
}
|
|
65
70
|
}
|
|
66
71
|
|
|
72
|
+
// Generovanie variantov pre a elementy s triedami
|
|
73
|
+
@each $variant, $breakpoints in $config {
|
|
74
|
+
@if $variant != default {
|
|
75
|
+
a#{generate.variant-name($variant, ".")} {
|
|
76
|
+
@include generate.responsive-css-map($breakpoints);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
67
81
|
cite {
|
|
68
82
|
font-style: normal;
|
|
69
83
|
}
|
|
@@ -164,3 +178,12 @@
|
|
|
164
178
|
}
|
|
165
179
|
}
|
|
166
180
|
}
|
|
181
|
+
|
|
182
|
+
@mixin list-marker-orange() {
|
|
183
|
+
> li {
|
|
184
|
+
|
|
185
|
+
&::marker {
|
|
186
|
+
color: var(--color-icon-accent);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|