@akinon/pz-theme 2.0.149-rc.0 → 2.0.149
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/CHANGELOG.md
CHANGED
|
@@ -1,40 +1,12 @@
|
|
|
1
1
|
# @akinon/pz-theme
|
|
2
2
|
|
|
3
|
-
## 2.0.149
|
|
4
|
-
|
|
5
|
-
### Patch Changes
|
|
6
|
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
-
|
|
10
|
-
- Updated dependencies [51ea06888]
|
|
11
|
-
- Updated dependencies
|
|
12
|
-
- Updated dependencies [2fea41430]
|
|
13
|
-
- Updated dependencies [b55acb768]
|
|
14
|
-
- Updated dependencies [760258c1c]
|
|
15
|
-
- Updated dependencies [143be2b9d]
|
|
16
|
-
- Updated dependencies [7889b08fe]
|
|
17
|
-
- Updated dependencies [9f8cd3bc5]
|
|
18
|
-
- Updated dependencies [bfafa3f49]
|
|
19
|
-
- Updated dependencies [57d7eb305]
|
|
20
|
-
- Updated dependencies [d99a6a7d5]
|
|
21
|
-
- Updated dependencies [9db81a714]
|
|
22
|
-
- Updated dependencies [591e345e1]
|
|
23
|
-
- Updated dependencies [4de5303c5]
|
|
24
|
-
- Updated dependencies [95b139dc1]
|
|
25
|
-
- Updated dependencies [1d00f2d06]
|
|
26
|
-
- Updated dependencies [4ac7b2a1e]
|
|
27
|
-
- Updated dependencies [e9598c71d]
|
|
28
|
-
- Updated dependencies [4998a9631]
|
|
29
|
-
- Updated dependencies [804d2bd6c]
|
|
30
|
-
- Updated dependencies [3909d3224]
|
|
31
|
-
- Updated dependencies [6a3d8a631]
|
|
32
|
-
- Updated dependencies [e18836b20]
|
|
33
|
-
- Updated dependencies [b1111d7b1]
|
|
34
|
-
- Updated dependencies [1595d458e]
|
|
35
|
-
- Updated dependencies [dca128112]
|
|
36
|
-
- @akinon/next@2.0.149-rc.0
|
|
37
|
-
- @akinon/theme-contract@2.0.149-rc.0
|
|
3
|
+
## 2.0.149
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 99eb4f1: ZERO-5221: hide slider block arrows at the widths they are turned off
|
|
8
|
+
- @akinon/next@2.0.149
|
|
9
|
+
- @akinon/theme-contract@2.0.149
|
|
38
10
|
|
|
39
11
|
## 2.0.148
|
|
40
12
|
|
package/package.json
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akinon/pz-theme",
|
|
3
3
|
"description": "Theme package for Project Zero Next — ThemePlaceholder system and theme editor infrastructure",
|
|
4
|
-
"version": "2.0.149
|
|
4
|
+
"version": "2.0.149",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "src/index.ts",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"test": "jest"
|
|
9
9
|
},
|
|
10
10
|
"peerDependencies": {
|
|
11
|
-
"@akinon/next": "2.0.149
|
|
11
|
+
"@akinon/next": "2.0.149",
|
|
12
12
|
"react": "^18.0.0 || ^19.0.0",
|
|
13
13
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@akinon/theme-contract": "2.0.149
|
|
16
|
+
"@akinon/theme-contract": "2.0.149",
|
|
17
17
|
"clsx": "2.1.1",
|
|
18
18
|
"lottie-web": "^5.13.0",
|
|
19
19
|
"react-multi-carousel": "2.8.4",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"zod": "4.4.1"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
|
-
"@akinon/next": "2.0.149
|
|
24
|
+
"@akinon/next": "2.0.149",
|
|
25
25
|
"@testing-library/jest-dom": "5.16.4",
|
|
26
26
|
"@testing-library/react": "16.3.2",
|
|
27
27
|
"@testing-library/user-event": "14.1.1",
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render } from '@testing-library/react';
|
|
3
|
+
|
|
4
|
+
jest.mock('react-multi-carousel', () => ({
|
|
5
|
+
__esModule: true,
|
|
6
|
+
default: (carouselProps: any) => (
|
|
7
|
+
<div data-testid="carousel" className={carouselProps.containerClass}>
|
|
8
|
+
{carouselProps.customLeftArrow}
|
|
9
|
+
{carouselProps.children}
|
|
10
|
+
{carouselProps.customRightArrow}
|
|
11
|
+
</div>
|
|
12
|
+
)
|
|
13
|
+
}));
|
|
14
|
+
|
|
15
|
+
jest.mock('../../theme-block', () => ({
|
|
16
|
+
__esModule: true,
|
|
17
|
+
default: ({ block }: { block: { id: string } }) => (
|
|
18
|
+
<div data-testid="tb" data-id={block.id} />
|
|
19
|
+
)
|
|
20
|
+
}));
|
|
21
|
+
|
|
22
|
+
import SliderBlock from '../slider-block';
|
|
23
|
+
|
|
24
|
+
const child = (id: string, over: Record<string, unknown> = {}): any => ({
|
|
25
|
+
id,
|
|
26
|
+
type: 'text',
|
|
27
|
+
label: id,
|
|
28
|
+
value: '',
|
|
29
|
+
properties: {},
|
|
30
|
+
styles: {},
|
|
31
|
+
order: 0,
|
|
32
|
+
hidden: false,
|
|
33
|
+
...over
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const slides = (count: number) =>
|
|
37
|
+
Array.from({ length: count }, (_unused, index) =>
|
|
38
|
+
child(`slide-${index}`, { order: index })
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
const arrowIcon = (label: string, styles: Record<string, unknown> = {}) =>
|
|
42
|
+
child(label, { type: 'icon', label, value: { url: '/a.svg' }, styles });
|
|
43
|
+
|
|
44
|
+
const sliderBlock = (
|
|
45
|
+
showArrows: unknown,
|
|
46
|
+
arrowStyles: Record<string, unknown> = {},
|
|
47
|
+
over: Record<string, unknown> = {}
|
|
48
|
+
): any => ({
|
|
49
|
+
id: 'slider-1',
|
|
50
|
+
type: 'slider',
|
|
51
|
+
label: 'slider',
|
|
52
|
+
value: '',
|
|
53
|
+
properties: {
|
|
54
|
+
'show-arrows': showArrows,
|
|
55
|
+
'items-per-slide': { desktop: 1, mobile: 1 }
|
|
56
|
+
},
|
|
57
|
+
styles: {},
|
|
58
|
+
order: 0,
|
|
59
|
+
hidden: false,
|
|
60
|
+
blocks: [
|
|
61
|
+
arrowIcon('Left Arrow Icon', arrowStyles),
|
|
62
|
+
...slides(3),
|
|
63
|
+
arrowIcon('Right Arrow Icon', arrowStyles)
|
|
64
|
+
],
|
|
65
|
+
...over
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const renderOnStorefront = (block: any, isDesigner = false) =>
|
|
69
|
+
render(
|
|
70
|
+
<div data-block-id={block.styleSourceId || block.id}>
|
|
71
|
+
<SliderBlock
|
|
72
|
+
{...({
|
|
73
|
+
block,
|
|
74
|
+
placeholderId: 'home-body',
|
|
75
|
+
sectionId: 'section-1',
|
|
76
|
+
isDesigner
|
|
77
|
+
} as any)}
|
|
78
|
+
/>
|
|
79
|
+
</div>
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const arrowRules = (container: HTMLElement) =>
|
|
83
|
+
Array.from(container.querySelectorAll('style'))
|
|
84
|
+
.map((style) => style.textContent || '')
|
|
85
|
+
.filter((css) => css.includes('[data-slider-arrow]'));
|
|
86
|
+
|
|
87
|
+
const hiddenRulesOf = (css: string) =>
|
|
88
|
+
Array.from(
|
|
89
|
+
css.matchAll(/(@media[^{]+)\{([^{]+)\{display:none !important;\}\}/g)
|
|
90
|
+
).map((match) => ({ query: match[1], selectors: match[2] }));
|
|
91
|
+
|
|
92
|
+
const hiddenSelectorsOf = (css: string) =>
|
|
93
|
+
hiddenRulesOf(css).map((rule) => rule.selectors);
|
|
94
|
+
|
|
95
|
+
describe('slider block arrows at the widths they are turned off', () => {
|
|
96
|
+
it('marks every arrow the block draws inside the track', () => {
|
|
97
|
+
const { container } = renderOnStorefront(
|
|
98
|
+
sliderBlock({ desktop: true, mobile: false })
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
expect(container.querySelectorAll('[data-slider-arrow]')).toHaveLength(2);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it('hides below desktop when only mobile is off, and the rules reach both arrows', () => {
|
|
105
|
+
const { container } = renderOnStorefront(
|
|
106
|
+
sliderBlock({ desktop: true, mobile: false })
|
|
107
|
+
);
|
|
108
|
+
const [css] = arrowRules(container);
|
|
109
|
+
const rules = hiddenRulesOf(css);
|
|
110
|
+
|
|
111
|
+
expect(rules.map((rule) => rule.query)).toEqual([
|
|
112
|
+
'@media (min-width:768px) and (max-width:1023px)',
|
|
113
|
+
'@media (max-width:767px)'
|
|
114
|
+
]);
|
|
115
|
+
rules.forEach((rule) => {
|
|
116
|
+
expect(container.querySelectorAll(rule.selectors)).toHaveLength(2);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('honours a tablet value of its own', () => {
|
|
121
|
+
const { container } = renderOnStorefront(
|
|
122
|
+
sliderBlock({ desktop: true, tablet: false, mobile: true })
|
|
123
|
+
);
|
|
124
|
+
const rules = hiddenRulesOf(arrowRules(container)[0]);
|
|
125
|
+
|
|
126
|
+
expect(rules.map((rule) => rule.query)).toEqual([
|
|
127
|
+
'@media (min-width:768px) and (max-width:1023px)'
|
|
128
|
+
]);
|
|
129
|
+
expect(container.querySelectorAll(rules[0].selectors)).toHaveLength(2);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
it('keeps the tablet on when only the phone is turned off', () => {
|
|
133
|
+
const { container } = renderOnStorefront(
|
|
134
|
+
sliderBlock({ desktop: true, tablet: true, mobile: false })
|
|
135
|
+
);
|
|
136
|
+
const rules = hiddenRulesOf(arrowRules(container)[0]);
|
|
137
|
+
|
|
138
|
+
expect(rules.map((rule) => rule.query)).toEqual([
|
|
139
|
+
'@media (max-width:767px)'
|
|
140
|
+
]);
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('reaches arrows placed outside the track just the same', () => {
|
|
144
|
+
const { container } = renderOnStorefront(
|
|
145
|
+
sliderBlock({ desktop: true, mobile: false }, { top: '0px' })
|
|
146
|
+
);
|
|
147
|
+
const [css] = arrowRules(container);
|
|
148
|
+
const [selectors] = hiddenSelectorsOf(css);
|
|
149
|
+
|
|
150
|
+
expect(
|
|
151
|
+
container.querySelector('[data-testid="carousel"] [data-slider-arrow]')
|
|
152
|
+
).toBeNull();
|
|
153
|
+
expect(container.querySelectorAll(selectors)).toHaveLength(2);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
it('hides the desktop band instead when that is the one turned off', () => {
|
|
157
|
+
const { container } = renderOnStorefront(
|
|
158
|
+
sliderBlock({ desktop: false, mobile: true })
|
|
159
|
+
);
|
|
160
|
+
const rules = hiddenRulesOf(arrowRules(container)[0]);
|
|
161
|
+
|
|
162
|
+
expect(rules.map((rule) => rule.query)).toEqual([
|
|
163
|
+
'@media (min-width:1024px) and (max-width:4000px)'
|
|
164
|
+
]);
|
|
165
|
+
expect(container.querySelectorAll(rules[0].selectors)).toHaveLength(2);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
it('ships arrows placed outside the track even when the desktop band is off', () => {
|
|
169
|
+
const { container } = renderOnStorefront(
|
|
170
|
+
sliderBlock({ desktop: false, mobile: true }, { top: '0px' })
|
|
171
|
+
);
|
|
172
|
+
const [css] = arrowRules(container);
|
|
173
|
+
|
|
174
|
+
expect(container.querySelectorAll('[data-slider-arrow]')).toHaveLength(2);
|
|
175
|
+
expect(css).toContain('(min-width:');
|
|
176
|
+
expect(container.querySelectorAll(hiddenSelectorsOf(css)[0])).toHaveLength(
|
|
177
|
+
2
|
|
178
|
+
);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
it('draws no arrows at all when they are off at every width', () => {
|
|
182
|
+
const { container } = renderOnStorefront(
|
|
183
|
+
sliderBlock({ desktop: false, mobile: false }, { top: '0px' })
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
expect(container.querySelectorAll('[data-slider-arrow]')).toHaveLength(0);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
it('writes no hiding rule while the arrows are on everywhere', () => {
|
|
190
|
+
const { container } = renderOnStorefront(sliderBlock(true));
|
|
191
|
+
|
|
192
|
+
expect(arrowRules(container)).toHaveLength(0);
|
|
193
|
+
expect(container.querySelectorAll('[data-slider-arrow]')).toHaveLength(2);
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
it('follows the wrapper of a row clone, which carries the template id', () => {
|
|
197
|
+
const { container } = renderOnStorefront(
|
|
198
|
+
sliderBlock(
|
|
199
|
+
{ desktop: true, mobile: false },
|
|
200
|
+
{},
|
|
201
|
+
{
|
|
202
|
+
id: 'slider-1-row-2',
|
|
203
|
+
styleSourceId: 'slider-1'
|
|
204
|
+
}
|
|
205
|
+
)
|
|
206
|
+
);
|
|
207
|
+
const [css] = arrowRules(container);
|
|
208
|
+
|
|
209
|
+
expect(css).toContain('[data-block-id="slider-1"] [data-slider-arrow]');
|
|
210
|
+
expect(container.querySelectorAll(hiddenSelectorsOf(css)[0])).toHaveLength(
|
|
211
|
+
2
|
|
212
|
+
);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
it('leaves the designer canvas to resolve the breakpoint itself', () => {
|
|
216
|
+
const { container } = renderOnStorefront(
|
|
217
|
+
sliderBlock({ desktop: true, mobile: false }),
|
|
218
|
+
true
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
expect(arrowRules(container)).toHaveLength(0);
|
|
222
|
+
});
|
|
223
|
+
});
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
} from '../utils';
|
|
16
16
|
import {
|
|
17
17
|
DESKTOP_MIN_WIDTH,
|
|
18
|
+
TABLET_MIN_WIDTH,
|
|
18
19
|
isNarrowBreakpoint,
|
|
19
20
|
setAtAnyBreakpoint
|
|
20
21
|
} from '../utils/breakpoints';
|
|
@@ -325,13 +326,30 @@ const SliderBlock: React.FC<BlockRendererProps> = ({
|
|
|
325
326
|
const canOverflow = visibleCount > 1;
|
|
326
327
|
const renderArrows = arrowsAnywhere && canOverflow;
|
|
327
328
|
|
|
328
|
-
const
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
329
|
+
const arrowBands = {
|
|
330
|
+
desktop: carouselResponsive.desktop,
|
|
331
|
+
tablet: {
|
|
332
|
+
breakpoint: { max: DESKTOP_MIN_WIDTH - 1, min: TABLET_MIN_WIDTH },
|
|
333
|
+
items: mobileItems
|
|
334
|
+
},
|
|
335
|
+
mobile: {
|
|
336
|
+
breakpoint: { max: TABLET_MIN_WIDTH - 1, min: 0 },
|
|
337
|
+
items: mobileItems
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
const arrowOwnerId = carouselSsrScopeId(block.styleSourceId || block.id);
|
|
341
|
+
const arrowCss =
|
|
342
|
+
isDesigner || !arrowOwnerId
|
|
343
|
+
? ''
|
|
344
|
+
: buildCarouselArrowCss(
|
|
345
|
+
carouselSsrScopeId(block.id) || '',
|
|
346
|
+
arrowBands,
|
|
347
|
+
(band) =>
|
|
348
|
+
getResponsiveValue(arrowsConfigured, band, true) === true &&
|
|
349
|
+
visibleCount >
|
|
350
|
+
Number(arrowBands[band as keyof typeof arrowBands]?.items || 1),
|
|
351
|
+
`[data-block-id="${arrowOwnerId}"]`
|
|
352
|
+
);
|
|
335
353
|
|
|
336
354
|
const showDots = getResponsiveValue(
|
|
337
355
|
getConfigEntry('show-dots'),
|
|
@@ -1140,6 +1158,7 @@ const SliderBlock: React.FC<BlockRendererProps> = ({
|
|
|
1140
1158
|
* section arrows in `utils/slider-arrows.tsx` already carry this.
|
|
1141
1159
|
*/
|
|
1142
1160
|
data-block-id={iconBlock?.id}
|
|
1161
|
+
data-slider-arrow=""
|
|
1143
1162
|
onClick={onActivate}
|
|
1144
1163
|
className={arrowPlacementClass(
|
|
1145
1164
|
plateStyle,
|
|
@@ -1400,8 +1419,7 @@ const SliderBlock: React.FC<BlockRendererProps> = ({
|
|
|
1400
1419
|
})}
|
|
1401
1420
|
</Carousel>
|
|
1402
1421
|
|
|
1403
|
-
{(isDesigner
|
|
1404
|
-
showArrows &&
|
|
1422
|
+
{(isDesigner ? showArrows : arrowsOutside && arrowsAnywhere) &&
|
|
1405
1423
|
sortedBlocks.length > 0 &&
|
|
1406
1424
|
leftArrowIconBlock &&
|
|
1407
1425
|
rightArrowIconBlock ? (
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render } from '@testing-library/react';
|
|
3
|
+
|
|
4
|
+
jest.mock('../../theme-block', () => ({
|
|
5
|
+
__esModule: true,
|
|
6
|
+
default: ({ block }: { block: { id: string } }) => (
|
|
7
|
+
<div data-testid="slide" data-id={block.id} />
|
|
8
|
+
)
|
|
9
|
+
}));
|
|
10
|
+
|
|
11
|
+
jest.mock('react-multi-carousel', () => ({
|
|
12
|
+
__esModule: true,
|
|
13
|
+
default: ({
|
|
14
|
+
children,
|
|
15
|
+
customLeftArrow,
|
|
16
|
+
customRightArrow
|
|
17
|
+
}: {
|
|
18
|
+
children?: React.ReactNode;
|
|
19
|
+
customLeftArrow?: React.ReactNode;
|
|
20
|
+
customRightArrow?: React.ReactNode;
|
|
21
|
+
}) => (
|
|
22
|
+
<div data-testid="carousel">
|
|
23
|
+
{customLeftArrow}
|
|
24
|
+
{customRightArrow}
|
|
25
|
+
{children}
|
|
26
|
+
</div>
|
|
27
|
+
)
|
|
28
|
+
}));
|
|
29
|
+
|
|
30
|
+
import PostsSliderSection from '../posts-slider-section';
|
|
31
|
+
import {
|
|
32
|
+
LEFT_ARROW_ICON_LABEL,
|
|
33
|
+
RIGHT_ARROW_ICON_LABEL
|
|
34
|
+
} from '../../utils/slider-arrows';
|
|
35
|
+
|
|
36
|
+
const slide = (id: string) => ({
|
|
37
|
+
id,
|
|
38
|
+
type: 'group',
|
|
39
|
+
label: id,
|
|
40
|
+
styles: {},
|
|
41
|
+
order: 0,
|
|
42
|
+
blocks: []
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const arrow = (label: string) => ({
|
|
46
|
+
id: `arrow-${label === LEFT_ARROW_ICON_LABEL ? 'left' : 'right'}`,
|
|
47
|
+
type: 'icon',
|
|
48
|
+
label,
|
|
49
|
+
value: { url: '', alt: label },
|
|
50
|
+
properties: {},
|
|
51
|
+
styles: {},
|
|
52
|
+
order: 9
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const renderSection = (showArrows: unknown) =>
|
|
56
|
+
render(
|
|
57
|
+
<section data-section-id="sec">
|
|
58
|
+
<PostsSliderSection
|
|
59
|
+
{...({
|
|
60
|
+
section: {
|
|
61
|
+
id: 'sec',
|
|
62
|
+
type: 'flash-deals-slider',
|
|
63
|
+
label: 'sec',
|
|
64
|
+
properties: { 'items-per-slide': 1, 'show-arrows': showArrows },
|
|
65
|
+
styles: {},
|
|
66
|
+
blocks: [
|
|
67
|
+
arrow(LEFT_ARROW_ICON_LABEL),
|
|
68
|
+
slide('a'),
|
|
69
|
+
slide('b'),
|
|
70
|
+
arrow(RIGHT_ARROW_ICON_LABEL)
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
currentBreakpoint: 'desktop',
|
|
74
|
+
placeholderId: 'ph',
|
|
75
|
+
isDesigner: false,
|
|
76
|
+
selectedBlockId: null
|
|
77
|
+
} as any)}
|
|
78
|
+
/>
|
|
79
|
+
</section>
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const arrowRules = (container: HTMLElement) =>
|
|
83
|
+
Array.from(container.querySelectorAll('style'))
|
|
84
|
+
.map((style) => style.textContent || '')
|
|
85
|
+
.filter((css) => css.includes('[data-slider-arrow]'));
|
|
86
|
+
|
|
87
|
+
const hiddenSelectorsOf = (css: string) =>
|
|
88
|
+
Array.from(
|
|
89
|
+
css.matchAll(/@media[^{]+\{([^{]+)\{display:none !important;\}\}/g)
|
|
90
|
+
).map((match) => match[1]);
|
|
91
|
+
|
|
92
|
+
describe('posts slider arrows at the widths they are turned off', () => {
|
|
93
|
+
it('hides only below desktop, and every rule reaches both arrows', () => {
|
|
94
|
+
const { container } = renderSection({ desktop: true, mobile: false });
|
|
95
|
+
const [css] = arrowRules(container);
|
|
96
|
+
|
|
97
|
+
const selectors = hiddenSelectorsOf(css);
|
|
98
|
+
|
|
99
|
+
expect(css).toBeDefined();
|
|
100
|
+
expect(selectors.length).toBeGreaterThan(0);
|
|
101
|
+
expect(css).not.toMatch(/@media \(min-width:\d+px\)\{/);
|
|
102
|
+
selectors.forEach((selector) => {
|
|
103
|
+
expect(container.querySelectorAll(selector)).toHaveLength(2);
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('writes no hiding rule while the arrows are on everywhere', () => {
|
|
108
|
+
const { container } = renderSection(true);
|
|
109
|
+
|
|
110
|
+
expect(arrowRules(container)).toHaveLength(0);
|
|
111
|
+
expect(container.querySelectorAll('[data-slider-arrow]')).toHaveLength(2);
|
|
112
|
+
});
|
|
113
|
+
});
|