@redneckz/wildless-cms-uni-blocks 0.2.73 → 0.2.74
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/bundle/blocks.schema.json +240 -151
- package/bundle/bundle.umd.js +95 -31
- package/bundle/bundle.umd.min.js +1 -1
- package/dist/BaseTile.js +9 -4
- package/dist/BaseTile.js.map +1 -1
- package/dist/BaseTileContent.d.ts +2 -2
- package/dist/BlockContent.d.ts +2 -1
- package/dist/Blocks.d.ts +1 -0
- package/dist/Blocks.js +2 -0
- package/dist/Blocks.js.map +1 -1
- package/dist/ComparisonTable/ComparisonTable.d.ts +5 -0
- package/dist/ComparisonTable/ComparisonTable.js +34 -0
- package/dist/ComparisonTable/ComparisonTable.js.map +1 -0
- package/dist/ComparisonTable/ComparisonTableContent.d.ts +37 -0
- package/dist/{ui-kit/IconButtonProps.js → ComparisonTable/ComparisonTableContent.js} +1 -1
- package/dist/ComparisonTable/ComparisonTableContent.js.map +1 -0
- package/dist/ComparisonTable/HeaderCell.d.ts +10 -0
- package/dist/ComparisonTable/HeaderCell.js +11 -0
- package/dist/ComparisonTable/HeaderCell.js.map +1 -0
- package/dist/ComparisonTable/TableCarouselContainer.d.ts +4 -0
- package/dist/ComparisonTable/TableCarouselContainer.js +7 -0
- package/dist/ComparisonTable/TableCarouselContainer.js.map +1 -0
- package/dist/ComparisonTable/TableCell.d.ts +8 -0
- package/dist/ComparisonTable/TableCell.js +12 -0
- package/dist/ComparisonTable/TableCell.js.map +1 -0
- package/dist/ComparisonTable/TableRow.d.ts +10 -0
- package/dist/ComparisonTable/TableRow.js +10 -0
- package/dist/ComparisonTable/TableRow.js.map +1 -0
- package/dist/ComparisonTable/TableRowContainer.d.ts +4 -0
- package/dist/ComparisonTable/TableRowContainer.js +6 -0
- package/dist/ComparisonTable/TableRowContainer.js.map +1 -0
- package/dist/ComparisonTable/constants.d.ts +6 -0
- package/dist/ComparisonTable/constants.js +9 -0
- package/dist/ComparisonTable/constants.js.map +1 -0
- package/dist/ComparisonTable/index.d.ts +3 -0
- package/dist/ComparisonTable/index.js +5 -0
- package/dist/ComparisonTable/index.js.map +1 -0
- package/dist/ExchangeRateTile.js +1 -0
- package/dist/ExchangeRateTile.js.map +1 -1
- package/dist/Footer/Contacts.js +1 -1
- package/dist/Footer/Contacts.js.map +1 -1
- package/dist/Footer/SocialMedia.js +4 -1
- package/dist/Footer/SocialMedia.js.map +1 -1
- package/dist/Gallery.mobile.js +1 -1
- package/dist/Gallery.mobile.js.map +1 -1
- package/dist/GalleryInner.js +2 -4
- package/dist/GalleryInner.js.map +1 -1
- package/dist/ProductBlockInner.js +3 -3
- package/dist/ProductBlockInner.js.map +1 -1
- package/dist/TextBlock.js +4 -4
- package/dist/TextBlock.js.map +1 -1
- package/dist/ui-kit/ArrowButton.d.ts +2 -6
- package/dist/ui-kit/ArrowButton.js +17 -3
- package/dist/ui-kit/ArrowButton.js.map +1 -1
- package/dist/ui-kit/Button.d.ts +2 -1
- package/dist/ui-kit/Button.js +11 -5
- package/dist/ui-kit/Button.js.map +1 -1
- package/dist/ui-kit/ButtonProps.d.ts +15 -3
- package/dist/ui-kit/IconProps.d.ts +23 -1
- package/dist/ui-kit/IconProps.js +24 -0
- package/dist/ui-kit/IconProps.js.map +1 -1
- package/dist/{Img.d.ts → ui-kit/Img.d.ts} +1 -1
- package/dist/{Img.js → ui-kit/Img.js} +0 -0
- package/dist/ui-kit/Img.js.map +1 -0
- package/dist/ui-kit/SVG.d.ts +2 -0
- package/dist/ui-kit/SVG.js +2 -2
- package/dist/ui-kit/SVG.js.map +1 -1
- package/lib/BaseTile.js +9 -4
- package/lib/BaseTile.js.map +1 -1
- package/lib/BaseTileContent.d.ts +2 -2
- package/lib/BlockContent.d.ts +2 -1
- package/lib/Blocks.d.ts +1 -0
- package/lib/Blocks.js +2 -0
- package/lib/Blocks.js.map +1 -1
- package/lib/ComparisonTable/ComparisonTable.d.ts +5 -0
- package/lib/ComparisonTable/ComparisonTable.js +32 -0
- package/lib/ComparisonTable/ComparisonTable.js.map +1 -0
- package/lib/ComparisonTable/ComparisonTableContent.d.ts +37 -0
- package/lib/ComparisonTable/ComparisonTableContent.js +2 -0
- package/lib/ComparisonTable/ComparisonTableContent.js.map +1 -0
- package/lib/ComparisonTable/HeaderCell.d.ts +10 -0
- package/lib/ComparisonTable/HeaderCell.js +9 -0
- package/lib/ComparisonTable/HeaderCell.js.map +1 -0
- package/lib/ComparisonTable/TableCarouselContainer.d.ts +4 -0
- package/lib/ComparisonTable/TableCarouselContainer.js +5 -0
- package/lib/ComparisonTable/TableCarouselContainer.js.map +1 -0
- package/lib/ComparisonTable/TableCell.d.ts +8 -0
- package/lib/ComparisonTable/TableCell.js +10 -0
- package/lib/ComparisonTable/TableCell.js.map +1 -0
- package/lib/ComparisonTable/TableRow.d.ts +10 -0
- package/lib/ComparisonTable/TableRow.js +8 -0
- package/lib/ComparisonTable/TableRow.js.map +1 -0
- package/lib/ComparisonTable/TableRowContainer.d.ts +4 -0
- package/lib/ComparisonTable/TableRowContainer.js +4 -0
- package/lib/ComparisonTable/TableRowContainer.js.map +1 -0
- package/lib/ComparisonTable/constants.d.ts +6 -0
- package/lib/ComparisonTable/constants.js +7 -0
- package/lib/ComparisonTable/constants.js.map +1 -0
- package/lib/ComparisonTable/index.d.ts +3 -0
- package/lib/ComparisonTable/index.js +2 -0
- package/lib/ComparisonTable/index.js.map +1 -0
- package/lib/ExchangeRateTile.js +1 -0
- package/lib/ExchangeRateTile.js.map +1 -1
- package/lib/Footer/Contacts.js +1 -1
- package/lib/Footer/Contacts.js.map +1 -1
- package/lib/Footer/SocialMedia.js +4 -1
- package/lib/Footer/SocialMedia.js.map +1 -1
- package/lib/Gallery.mobile.js +1 -1
- package/lib/Gallery.mobile.js.map +1 -1
- package/lib/GalleryInner.js +2 -4
- package/lib/GalleryInner.js.map +1 -1
- package/lib/ProductBlockInner.js +3 -3
- package/lib/ProductBlockInner.js.map +1 -1
- package/lib/TextBlock.js +4 -4
- package/lib/TextBlock.js.map +1 -1
- package/lib/common.css +1 -1
- package/lib/ui-kit/ArrowButton.d.ts +2 -6
- package/lib/ui-kit/ArrowButton.js +18 -4
- package/lib/ui-kit/ArrowButton.js.map +1 -1
- package/lib/ui-kit/Button.d.ts +2 -1
- package/lib/ui-kit/Button.js +11 -5
- package/lib/ui-kit/Button.js.map +1 -1
- package/lib/ui-kit/ButtonProps.d.ts +15 -3
- package/lib/ui-kit/IconProps.d.ts +23 -1
- package/lib/ui-kit/IconProps.js +23 -1
- package/lib/ui-kit/IconProps.js.map +1 -1
- package/lib/{Img.d.ts → ui-kit/Img.d.ts} +1 -1
- package/lib/{Img.js → ui-kit/Img.js} +0 -0
- package/lib/ui-kit/Img.js.map +1 -0
- package/lib/ui-kit/SVG.d.ts +2 -0
- package/lib/ui-kit/SVG.js +2 -2
- package/lib/ui-kit/SVG.js.map +1 -1
- package/package.json +1 -1
- package/src/BaseTile.tsx +17 -5
- package/src/BaseTileContent.ts +2 -2
- package/src/BlockContent.ts +3 -1
- package/src/Blocks.ts +2 -0
- package/src/ComparisonTable/ComparisonTable.fixture.tsx +265 -0
- package/src/ComparisonTable/ComparisonTable.tsx +126 -0
- package/src/ComparisonTable/ComparisonTableContent.ts +43 -0
- package/src/ComparisonTable/HeaderCell.tsx +50 -0
- package/src/ComparisonTable/TableCarouselContainer.tsx +19 -0
- package/src/ComparisonTable/TableCell.tsx +43 -0
- package/src/ComparisonTable/TableRow.tsx +44 -0
- package/src/ComparisonTable/TableRowContainer.tsx +7 -0
- package/src/ComparisonTable/constants.ts +6 -0
- package/src/ComparisonTable/index.ts +3 -0
- package/src/ContentPage.page.json +388 -1
- package/src/ExchangeRateTile.tsx +2 -1
- package/src/Footer/Contacts.tsx +1 -0
- package/src/Footer/SocialMedia.tsx +9 -5
- package/src/Gallery.fixture.tsx +1 -1
- package/src/Gallery.mobile.tsx +1 -1
- package/src/GalleryInner.tsx +4 -9
- package/src/ProductBlock.fixture.tsx +1 -1
- package/src/ProductBlockInner.tsx +3 -3
- package/src/ProductTile.fixture.tsx +1 -1
- package/src/TextBlock.fixture.tsx +1 -1
- package/src/TextBlock.tsx +6 -4
- package/src/Tile.fixture.tsx +1 -1
- package/src/common.css +6 -0
- package/src/icons/AppleIcon.svg +1 -13
- package/src/icons/GlassIcon.svg +1 -0
- package/src/icons/PlayMarketIcon.svg +1 -6
- package/src/ui-kit/ArrowButton.tsx +29 -30
- package/src/ui-kit/Button.fixture.tsx +33 -5
- package/src/ui-kit/Button.tsx +41 -17
- package/src/ui-kit/ButtonProps.ts +17 -3
- package/src/ui-kit/Icon.fixture.tsx +22 -0
- package/src/ui-kit/IconProps.ts +24 -21
- package/src/{Img.tsx → ui-kit/Img.tsx} +1 -1
- package/src/ui-kit/SVG.tsx +11 -2
- package/dist/Img.js.map +0 -1
- package/dist/ui-kit/IconButton.d.ts +0 -2
- package/dist/ui-kit/IconButton.js +0 -10
- package/dist/ui-kit/IconButton.js.map +0 -1
- package/dist/ui-kit/IconButtonProps.d.ts +0 -6
- package/dist/ui-kit/IconButtonProps.js.map +0 -1
- package/lib/Img.js.map +0 -1
- package/lib/ui-kit/IconButton.d.ts +0 -2
- package/lib/ui-kit/IconButton.js +0 -8
- package/lib/ui-kit/IconButton.js.map +0 -1
- package/lib/ui-kit/IconButtonProps.d.ts +0 -6
- package/lib/ui-kit/IconButtonProps.js +0 -2
- package/lib/ui-kit/IconButtonProps.js.map +0 -1
- package/src/ui-kit/IconButton.tsx +0 -22
- package/src/ui-kit/IconButtonProps.ts +0 -7
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import type { Picture } from '../model/Picture';
|
|
2
|
+
import { context } from '../setup-fixture';
|
|
3
|
+
import { ComparisonTable } from './ComparisonTable';
|
|
4
|
+
import type { Column } from './ComparisonTableContent';
|
|
5
|
+
|
|
6
|
+
const image1: Picture = {
|
|
7
|
+
src: 'card-1.png',
|
|
8
|
+
format: 'webp',
|
|
9
|
+
size: {
|
|
10
|
+
width: 100,
|
|
11
|
+
height: 63,
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const image2: Picture = {
|
|
16
|
+
src: 'card-2.png',
|
|
17
|
+
format: 'webp',
|
|
18
|
+
size: {
|
|
19
|
+
width: 100,
|
|
20
|
+
height: 63,
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const image3: Picture = {
|
|
25
|
+
src: 'card-3.png',
|
|
26
|
+
format: 'webp',
|
|
27
|
+
size: {
|
|
28
|
+
width: 100,
|
|
29
|
+
height: 63,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
const rowHeaders = [
|
|
34
|
+
{ title: 'Начисление процентов на остаток по счету' },
|
|
35
|
+
{ title: 'Снятие наличных' },
|
|
36
|
+
{ title: 'Оформление онлайн' },
|
|
37
|
+
{ title: 'Кэшбэк баллами' },
|
|
38
|
+
{ title: 'Стоимость обслуживания' },
|
|
39
|
+
{ title: 'Стоимость SMS-сервиса' },
|
|
40
|
+
{ title: 'Дополнительная информация' },
|
|
41
|
+
];
|
|
42
|
+
const rowHeaders2 = [
|
|
43
|
+
{ title: 'Срок вклада (дней)' },
|
|
44
|
+
{ title: 'Ставка по вкладу' },
|
|
45
|
+
{ title: 'Минимальная сумма' },
|
|
46
|
+
{ title: 'Максимальная сумма' },
|
|
47
|
+
];
|
|
48
|
+
const columns: Column[] = [
|
|
49
|
+
{
|
|
50
|
+
header: {
|
|
51
|
+
title: 'Россельхоз-Росснефть',
|
|
52
|
+
image: image1,
|
|
53
|
+
link: {
|
|
54
|
+
text: 'Подробнее',
|
|
55
|
+
href: '/credits',
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
data: [
|
|
59
|
+
[{ label: 'Нет' }],
|
|
60
|
+
[
|
|
61
|
+
{
|
|
62
|
+
label: 'Бесплатно',
|
|
63
|
+
description: 'В банкоматах и кассах Россельхозбанка и банков-партнеров',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
label: 'Бесплатно',
|
|
67
|
+
description: 'В сторонних банкоматах - 1 раз в месяц, далее 1% минимум 150 руб',
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
[{ label: 'Нет' }],
|
|
71
|
+
[{ label: 'До 7%' }],
|
|
72
|
+
[
|
|
73
|
+
{
|
|
74
|
+
label: 'Бесплатно',
|
|
75
|
+
description: 'При обороте по карте от 10000 ₽ в месяц',
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
[{ label: '69 рублей в месяц' }],
|
|
79
|
+
[{ description: 'Оплачивайте покупки картой и заправляйтесь за баллы в сети АЗС Роснефть' }],
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
header: {
|
|
84
|
+
title: 'Panasonic',
|
|
85
|
+
image: image2,
|
|
86
|
+
link: {
|
|
87
|
+
text: 'Подробнее',
|
|
88
|
+
href: '/credits',
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
data: [
|
|
92
|
+
[{ label: 'Нет' }],
|
|
93
|
+
[
|
|
94
|
+
{
|
|
95
|
+
label: 'Бесплатно',
|
|
96
|
+
description: 'В банкоматах и кассах Россельхозбанка и банков-партнеров',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
label: '1%',
|
|
100
|
+
description: 'В сторонних банкоматах, минимум 150 руб',
|
|
101
|
+
},
|
|
102
|
+
],
|
|
103
|
+
[{ label: 'Нет' }],
|
|
104
|
+
[{ label: 'До 20%' }],
|
|
105
|
+
[
|
|
106
|
+
{
|
|
107
|
+
label: 'Бесплатно',
|
|
108
|
+
description: 'При обороте по карте от 10000 ₽ в месяц',
|
|
109
|
+
},
|
|
110
|
+
],
|
|
111
|
+
[{ label: '69 рублей в месяц' }],
|
|
112
|
+
[
|
|
113
|
+
{
|
|
114
|
+
description:
|
|
115
|
+
'Копите баллы каждый день и обменивайте их на скидки на электронику и бытовую технику Panasonic',
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
],
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
header: {
|
|
122
|
+
title: 'Профсоюзная',
|
|
123
|
+
image: image3,
|
|
124
|
+
link: {
|
|
125
|
+
text: 'Подробнее',
|
|
126
|
+
href: '/credits',
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
data: [
|
|
130
|
+
[{ label: 'Нет' }],
|
|
131
|
+
[{ label: 'Бесплатно' }],
|
|
132
|
+
[{ label: 'Есть' }],
|
|
133
|
+
[{ label: 'До 20%' }],
|
|
134
|
+
[
|
|
135
|
+
{
|
|
136
|
+
label: 'Бесплатно',
|
|
137
|
+
description: 'При обороте по карте от 10000 ₽ в месяц',
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
[{ label: '69 рублей в месяц' }],
|
|
141
|
+
[{ description: 'Для членов профсоюзных организаций' }],
|
|
142
|
+
],
|
|
143
|
+
},
|
|
144
|
+
];
|
|
145
|
+
const columns2: Column[] = [
|
|
146
|
+
{
|
|
147
|
+
header: {
|
|
148
|
+
title: '«Пополняемый»',
|
|
149
|
+
icon: 'GlassIcon',
|
|
150
|
+
link: {
|
|
151
|
+
text: 'Подробнее',
|
|
152
|
+
href: '/credits',
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
data: [
|
|
156
|
+
[{ label: 'от 91 до 1095' }],
|
|
157
|
+
[{ label: 'до 8,2% ₽' }, { label: 'до 0,01% USD' }],
|
|
158
|
+
[{ label: 'От 3000 ₽' }, { label: 'От 50 USD' }],
|
|
159
|
+
[{ label: 'до 10 млн ₽' }, { label: 'до 300 тыс. USD' }],
|
|
160
|
+
],
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
header: {
|
|
164
|
+
title: '«Комфортный»',
|
|
165
|
+
icon: 'ComfortableCompIcon',
|
|
166
|
+
link: {
|
|
167
|
+
text: 'Подробнее',
|
|
168
|
+
href: '/credits',
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
data: [
|
|
172
|
+
[{ label: 'от 91 до 1095' }],
|
|
173
|
+
[{ label: 'до 7,2% ₽' }, { label: 'до 0,01% USD' }],
|
|
174
|
+
[{ label: 'От 10 000 ₽' }, { label: 'От 150 USD' }],
|
|
175
|
+
[{ label: 'до 10 млн ₽' }, { label: 'до 300 тыс. USD' }],
|
|
176
|
+
],
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
header: {
|
|
180
|
+
title: '«Доходный пенсионный»',
|
|
181
|
+
icon: 'ClockIcon',
|
|
182
|
+
link: {
|
|
183
|
+
text: 'Подробнее',
|
|
184
|
+
href: '/credits',
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
data: [
|
|
188
|
+
[{ label: 'от 91 до 1460' }],
|
|
189
|
+
[{ label: 'до 9,5% ₽' }],
|
|
190
|
+
[{ label: 'От 500 ₽' }],
|
|
191
|
+
[{ label: 'Без ограничений' }],
|
|
192
|
+
],
|
|
193
|
+
},
|
|
194
|
+
];
|
|
195
|
+
|
|
196
|
+
export default {
|
|
197
|
+
'with images': (
|
|
198
|
+
<div className="w-[1280px]">
|
|
199
|
+
<div className="grid grid-cols-12">
|
|
200
|
+
<ComparisonTable
|
|
201
|
+
className="col-span-12"
|
|
202
|
+
title="Другие дебетовые карты Россельхозбанка"
|
|
203
|
+
context={context}
|
|
204
|
+
rowHeaders={rowHeaders}
|
|
205
|
+
columns={Array(2).fill(columns).flat()}
|
|
206
|
+
/>
|
|
207
|
+
</div>
|
|
208
|
+
</div>
|
|
209
|
+
),
|
|
210
|
+
'with images and hidden rows': (
|
|
211
|
+
<div className="w-[1280px]">
|
|
212
|
+
<div className="grid grid-cols-12">
|
|
213
|
+
<ComparisonTable
|
|
214
|
+
className="col-span-12"
|
|
215
|
+
title="Другие дебетовые карты Россельхозбанка"
|
|
216
|
+
visibleRowLength={3}
|
|
217
|
+
context={context}
|
|
218
|
+
rowHeaders={rowHeaders}
|
|
219
|
+
columns={Array(2).fill(columns).flat()}
|
|
220
|
+
/>
|
|
221
|
+
</div>
|
|
222
|
+
</div>
|
|
223
|
+
),
|
|
224
|
+
'with images and colored first column': (
|
|
225
|
+
<div className="w-[1280px]">
|
|
226
|
+
<div className="grid grid-cols-12">
|
|
227
|
+
<ComparisonTable
|
|
228
|
+
className="col-span-12"
|
|
229
|
+
title="Другие дебетовые карты Россельхозбанка"
|
|
230
|
+
visibleRowLength={3}
|
|
231
|
+
isColoredFirstColumn={true}
|
|
232
|
+
context={context}
|
|
233
|
+
rowHeaders={rowHeaders}
|
|
234
|
+
columns={Array(2).fill(columns).flat()}
|
|
235
|
+
/>
|
|
236
|
+
</div>
|
|
237
|
+
</div>
|
|
238
|
+
),
|
|
239
|
+
'with icons': (
|
|
240
|
+
<div className="w-[1280px]">
|
|
241
|
+
<div className="grid grid-cols-12">
|
|
242
|
+
<ComparisonTable
|
|
243
|
+
className="col-span-12"
|
|
244
|
+
title="Другие вклады и сбережения"
|
|
245
|
+
context={context}
|
|
246
|
+
rowHeaders={rowHeaders2}
|
|
247
|
+
columns={Array(2).fill(columns2).flat()}
|
|
248
|
+
/>
|
|
249
|
+
</div>
|
|
250
|
+
</div>
|
|
251
|
+
),
|
|
252
|
+
'with icons and two cols': (
|
|
253
|
+
<div className="w-[1280px]">
|
|
254
|
+
<div className="grid grid-cols-12">
|
|
255
|
+
<ComparisonTable
|
|
256
|
+
className="col-span-12"
|
|
257
|
+
title="Другие вклады и сбережения"
|
|
258
|
+
context={context}
|
|
259
|
+
rowHeaders={rowHeaders2}
|
|
260
|
+
columns={columns2.slice(0, 2)}
|
|
261
|
+
/>
|
|
262
|
+
</div>
|
|
263
|
+
</div>
|
|
264
|
+
),
|
|
265
|
+
};
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { JSX } from '@redneckz/uni-jsx';
|
|
2
|
+
import type { UniBlockProps } from '../types';
|
|
3
|
+
import { ArrowButton } from '../ui-kit/ArrowButton';
|
|
4
|
+
import { Title } from '../ui-kit/Title';
|
|
5
|
+
import { TableRowContainer } from './TableRowContainer';
|
|
6
|
+
import { TableCarouselContainer } from './TableCarouselContainer';
|
|
7
|
+
import { useLink } from '../useLink';
|
|
8
|
+
import type { ComparisonTableContent, RowData } from './ComparisonTableContent';
|
|
9
|
+
import { HeaderCell } from './HeaderCell';
|
|
10
|
+
import { TableRow } from './TableRow';
|
|
11
|
+
import { COLS_LENGTH_FOR_SCROLL, FIRST_CELL_CLASSES } from './constants';
|
|
12
|
+
|
|
13
|
+
export interface ComparisonTableProps extends ComparisonTableContent, UniBlockProps {}
|
|
14
|
+
|
|
15
|
+
export const ComparisonTable = JSX<ComparisonTableProps>(
|
|
16
|
+
({
|
|
17
|
+
className,
|
|
18
|
+
context,
|
|
19
|
+
title,
|
|
20
|
+
rowHeaders,
|
|
21
|
+
columns,
|
|
22
|
+
visibleRowLength = 0,
|
|
23
|
+
isColoredFirstColumn = false,
|
|
24
|
+
}) => {
|
|
25
|
+
const router = context.useRouter();
|
|
26
|
+
const { handlerDecorator } = context;
|
|
27
|
+
const [activeCardIndex, setActiveCardIndex] = context.useState(0);
|
|
28
|
+
const [isShowAllRow, setIsShowAllRow] = context.useState(!visibleRowLength);
|
|
29
|
+
|
|
30
|
+
const colHeaders = columns?.map(({ header }) => header || {});
|
|
31
|
+
const colData = columns?.map(({ data }) => data) || [];
|
|
32
|
+
const rowData: RowData = rowHeaders
|
|
33
|
+
?.map((header, i) => ({
|
|
34
|
+
header,
|
|
35
|
+
data: colData.map((col) => col?.[i] || [{}]),
|
|
36
|
+
}))
|
|
37
|
+
.slice(0, isShowAllRow ? rowHeaders.length : visibleRowLength);
|
|
38
|
+
|
|
39
|
+
const nextClick = () => setActiveCardIndex(activeCardIndex + 1);
|
|
40
|
+
const prevClick = () => setActiveCardIndex(activeCardIndex - 1);
|
|
41
|
+
const showToggle = () => setIsShowAllRow(!isShowAllRow);
|
|
42
|
+
|
|
43
|
+
const isScrollAvailable = colData?.length && colData.length > COLS_LENGTH_FOR_SCROLL;
|
|
44
|
+
const showNextButton =
|
|
45
|
+
isScrollAvailable && colData?.length - activeCardIndex > COLS_LENGTH_FOR_SCROLL;
|
|
46
|
+
const showPrevButton = isScrollAvailable && activeCardIndex > 0;
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<section
|
|
50
|
+
className={`bg-white font-sans py-[50px] pl-[50px] overflow-hidden text-primary-text relative ${
|
|
51
|
+
className || ''
|
|
52
|
+
}`}
|
|
53
|
+
>
|
|
54
|
+
<Title className="font-medium m-0 max-w-[47rem] text-center mb-9 mx-auto">{title}</Title>
|
|
55
|
+
<div role="table">
|
|
56
|
+
{colHeaders?.length ? (
|
|
57
|
+
<TableRowContainer>
|
|
58
|
+
<div className={FIRST_CELL_CLASSES} role="columnheader" scope="col" />
|
|
59
|
+
<TableCarouselContainer activeCardIndex={activeCardIndex}>
|
|
60
|
+
{colHeaders.map((header, i) => (
|
|
61
|
+
<HeaderCell
|
|
62
|
+
key={String(i)}
|
|
63
|
+
{...header}
|
|
64
|
+
link={header.link && useLink({ router, handlerDecorator }, header.link)}
|
|
65
|
+
/>
|
|
66
|
+
))}
|
|
67
|
+
</TableCarouselContainer>
|
|
68
|
+
</TableRowContainer>
|
|
69
|
+
) : null}
|
|
70
|
+
|
|
71
|
+
{rowData?.length ? (
|
|
72
|
+
<div className="relative">
|
|
73
|
+
{rowData.map((row, i, { length }) => (
|
|
74
|
+
<TableRow
|
|
75
|
+
key={String(i)}
|
|
76
|
+
row={row}
|
|
77
|
+
isFirstRow={i === 0}
|
|
78
|
+
isLastRow={i + 1 === length}
|
|
79
|
+
activeCardIndex={activeCardIndex}
|
|
80
|
+
isColoredFirstColumn={isColoredFirstColumn}
|
|
81
|
+
/>
|
|
82
|
+
))}
|
|
83
|
+
{isScrollAvailable ? (
|
|
84
|
+
<div>
|
|
85
|
+
<div className="absolute top-7 right-7 z-10">
|
|
86
|
+
<ArrowButton
|
|
87
|
+
onClick={nextClick}
|
|
88
|
+
disabled={!showNextButton}
|
|
89
|
+
ariaLabel="Пролистать вправо"
|
|
90
|
+
/>
|
|
91
|
+
<ArrowButton
|
|
92
|
+
className="mt-4 rotate-180"
|
|
93
|
+
onClick={prevClick}
|
|
94
|
+
disabled={!showPrevButton}
|
|
95
|
+
ariaLabel="Пролистать влево"
|
|
96
|
+
/>
|
|
97
|
+
</div>
|
|
98
|
+
</div>
|
|
99
|
+
) : null}
|
|
100
|
+
</div>
|
|
101
|
+
) : null}
|
|
102
|
+
</div>
|
|
103
|
+
|
|
104
|
+
{isScrollAvailable ? (
|
|
105
|
+
<div className="absolute top-0 right-0 bottom-0 w-[84px] bg-opacity-to-white" />
|
|
106
|
+
) : null}
|
|
107
|
+
|
|
108
|
+
{visibleRowLength ? (
|
|
109
|
+
<div className="pr-[50px]">
|
|
110
|
+
<div className="flex w-full">
|
|
111
|
+
<div className={FIRST_CELL_CLASSES} />
|
|
112
|
+
<button
|
|
113
|
+
onClick={showToggle}
|
|
114
|
+
className="mt-5 flex-1 border-main-stroke border-solid border text-primary-text bg-white hover:border-primary-main hover:text-primary-main"
|
|
115
|
+
>
|
|
116
|
+
<div className="font-sans font-medium text-xs py-[11px]">
|
|
117
|
+
{!isShowAllRow ? 'Показать все параметры' : 'Скрыть'}
|
|
118
|
+
</div>
|
|
119
|
+
</button>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
) : null}
|
|
123
|
+
</section>
|
|
124
|
+
);
|
|
125
|
+
},
|
|
126
|
+
);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { LinkContent } from '../model/LinkContent';
|
|
2
|
+
import type { Picture } from '../model/Picture';
|
|
3
|
+
import type { ButtonProps } from '../ui-kit/ButtonProps';
|
|
4
|
+
import type { IconName } from '../ui-kit/IconProps';
|
|
5
|
+
|
|
6
|
+
export type Row = {
|
|
7
|
+
header: RowHeader;
|
|
8
|
+
data: CellData[][];
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export type RowData = Row[] | undefined;
|
|
12
|
+
|
|
13
|
+
export interface CellData {
|
|
14
|
+
label?: string;
|
|
15
|
+
description?: string;
|
|
16
|
+
icons?: IconName[];
|
|
17
|
+
image?: Picture;
|
|
18
|
+
buttons?: ButtonProps[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface ColumnHeader {
|
|
22
|
+
title?: string;
|
|
23
|
+
icon?: IconName;
|
|
24
|
+
image?: Picture;
|
|
25
|
+
link?: LinkContent;
|
|
26
|
+
}
|
|
27
|
+
export interface Column {
|
|
28
|
+
header?: ColumnHeader;
|
|
29
|
+
data?: CellData[][];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface RowHeader {
|
|
33
|
+
title?: string;
|
|
34
|
+
icon?: IconName;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface ComparisonTableContent {
|
|
38
|
+
title?: string;
|
|
39
|
+
rowHeaders?: RowHeader[];
|
|
40
|
+
columns?: Column[];
|
|
41
|
+
visibleRowLength?: number;
|
|
42
|
+
isColoredFirstColumn?: boolean;
|
|
43
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { JSX } from '@redneckz/uni-jsx';
|
|
2
|
+
import type { LinkContent } from '../model/LinkContent';
|
|
3
|
+
import type { Picture } from '../model/Picture';
|
|
4
|
+
import { Button } from '../ui-kit/Button';
|
|
5
|
+
import { Icon } from '../ui-kit/Icon';
|
|
6
|
+
import type { IconName } from '../ui-kit/IconProps';
|
|
7
|
+
import { Img } from '../ui-kit/Img';
|
|
8
|
+
import { Title } from '../ui-kit/Title';
|
|
9
|
+
import { BORDER_CLASSES, GRADIENT } from './constants';
|
|
10
|
+
|
|
11
|
+
export interface HeaderCellProps {
|
|
12
|
+
icon?: IconName;
|
|
13
|
+
image?: Picture;
|
|
14
|
+
title?: string;
|
|
15
|
+
link?: LinkContent;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const HeaderCell = JSX<HeaderCellProps>(({ icon, image, title, link }) => (
|
|
19
|
+
<div
|
|
20
|
+
className={`w-80 box-border flex flex-col items-center rounded-t-md border-b-0 px-7 pt-7 pb-12 ${BORDER_CLASSES} ${GRADIENT}`}
|
|
21
|
+
role="columnheader"
|
|
22
|
+
scope="col"
|
|
23
|
+
>
|
|
24
|
+
{icon && !image?.src && (
|
|
25
|
+
<Icon
|
|
26
|
+
className="h-[63px] w-[63px] min-w-[63px] min-h-[63px] mb-4"
|
|
27
|
+
name={icon}
|
|
28
|
+
width="63"
|
|
29
|
+
height="63"
|
|
30
|
+
/>
|
|
31
|
+
)}
|
|
32
|
+
{image?.src && <Img className="mb-4" image={image} />}
|
|
33
|
+
{title && (
|
|
34
|
+
<Title size="S" className="font-medium m-0 text-center text-white">
|
|
35
|
+
{title}
|
|
36
|
+
</Title>
|
|
37
|
+
)}
|
|
38
|
+
{link?.text && (
|
|
39
|
+
<div className="mt-auto w-full">
|
|
40
|
+
<Button
|
|
41
|
+
href={link.href}
|
|
42
|
+
target={link.target}
|
|
43
|
+
className="mt-4 w-full text-primary-main bg-white hover:bg-secondary-hover active:bg-secondary-active"
|
|
44
|
+
>
|
|
45
|
+
<div className="text-xs py-[11px]">{link.text}</div>
|
|
46
|
+
</Button>
|
|
47
|
+
</div>
|
|
48
|
+
)}
|
|
49
|
+
</div>
|
|
50
|
+
));
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { JSX } from '@redneckz/uni-jsx';
|
|
2
|
+
import { COLUMN_WIDTH } from './constants';
|
|
3
|
+
|
|
4
|
+
export interface TableCarouselContainerProps {
|
|
5
|
+
activeCardIndex: number;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const TableCarouselContainer = JSX<TableCarouselContainerProps>(
|
|
9
|
+
({ children, activeCardIndex }) => (
|
|
10
|
+
<div className="flex flex-1 overflow-hidden">
|
|
11
|
+
<div
|
|
12
|
+
className="flex gap-4 duration-1000"
|
|
13
|
+
style={{ transform: `translateX(-${activeCardIndex * COLUMN_WIDTH}px)` }}
|
|
14
|
+
>
|
|
15
|
+
{children}
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
),
|
|
19
|
+
);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { JSX } from '@redneckz/uni-jsx';
|
|
2
|
+
import type { CellData } from './ComparisonTableContent';
|
|
3
|
+
import { BORDER_CLASSES, DIVIDER_CLASSES, GRADIENT } from './constants';
|
|
4
|
+
|
|
5
|
+
export interface TableCellProps {
|
|
6
|
+
cell: CellData[];
|
|
7
|
+
isLastRow: boolean;
|
|
8
|
+
isFirstRow: boolean;
|
|
9
|
+
isFillGradient: boolean;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const TableCell = JSX<TableCellProps>(({ cell, isFirstRow, isLastRow, isFillGradient }) => {
|
|
13
|
+
const cellWrapperClasses = `w-80 box-border flex flex-col ${BORDER_CLASSES} ${
|
|
14
|
+
!isLastRow ? 'border-y-0' : 'border-t-0 rounded-b-md'
|
|
15
|
+
} ${isFillGradient ? GRADIENT : ''}`;
|
|
16
|
+
|
|
17
|
+
const cellClasses = `mx-7 h-full ${DIVIDER_CLASSES} ${
|
|
18
|
+
isFillGradient && isFirstRow ? 'border-t' : ''
|
|
19
|
+
} ${!isLastRow ? 'border-solid' : ''}`;
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<div className={cellWrapperClasses} role="cell">
|
|
23
|
+
<div className={cellClasses}>
|
|
24
|
+
{cell.map((item, i) => renderCellInner(item, i, isFillGradient))}
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
const renderCellInner = ({ label, description }: CellData, i: number, isFillGradient: boolean) => (
|
|
31
|
+
<div key={String(i)} className="first:pt-7 pt-6 last:pb-7">
|
|
32
|
+
{label && (
|
|
33
|
+
<h5 className={`text-xl font-medium m-0 ${isFillGradient ? 'text-white' : ''}`}>{label}</h5>
|
|
34
|
+
)}
|
|
35
|
+
{description && (
|
|
36
|
+
<div
|
|
37
|
+
className={`text-sm opacity-80 ${isFillGradient ? 'text-white' : 'text-secondary-text'}`}
|
|
38
|
+
>
|
|
39
|
+
{description}
|
|
40
|
+
</div>
|
|
41
|
+
)}
|
|
42
|
+
</div>
|
|
43
|
+
);
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { JSX } from '@redneckz/uni-jsx';
|
|
2
|
+
import type { Row } from './ComparisonTableContent';
|
|
3
|
+
import { DIVIDER_CLASSES, FIRST_CELL_CLASSES } from './constants';
|
|
4
|
+
import { TableCarouselContainer } from './TableCarouselContainer';
|
|
5
|
+
import { TableCell } from './TableCell';
|
|
6
|
+
import { TableRowContainer } from './TableRowContainer';
|
|
7
|
+
|
|
8
|
+
export interface TableRowProps {
|
|
9
|
+
className?: string;
|
|
10
|
+
row: Row;
|
|
11
|
+
activeCardIndex: number;
|
|
12
|
+
isColoredFirstColumn: boolean;
|
|
13
|
+
isFirstRow: boolean;
|
|
14
|
+
isLastRow: boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const TableRow = JSX<TableRowProps>(
|
|
18
|
+
({ row: { header, data }, activeCardIndex, isColoredFirstColumn, isFirstRow, isLastRow }) => (
|
|
19
|
+
<TableRowContainer>
|
|
20
|
+
{header?.title ? (
|
|
21
|
+
<div
|
|
22
|
+
className={`text-sm py-7 ${DIVIDER_CLASSES} ${FIRST_CELL_CLASSES} ${
|
|
23
|
+
!isLastRow ? 'border-solid' : ''
|
|
24
|
+
}`}
|
|
25
|
+
>
|
|
26
|
+
{header.title}
|
|
27
|
+
</div>
|
|
28
|
+
) : null}
|
|
29
|
+
{data?.length ? (
|
|
30
|
+
<TableCarouselContainer activeCardIndex={activeCardIndex}>
|
|
31
|
+
{data.map((cell, i) => (
|
|
32
|
+
<TableCell
|
|
33
|
+
key={String(i)}
|
|
34
|
+
cell={cell}
|
|
35
|
+
isFirstRow={isFirstRow}
|
|
36
|
+
isLastRow={isLastRow}
|
|
37
|
+
isFillGradient={isColoredFirstColumn && i === 0}
|
|
38
|
+
/>
|
|
39
|
+
))}
|
|
40
|
+
</TableCarouselContainer>
|
|
41
|
+
) : null}
|
|
42
|
+
</TableRowContainer>
|
|
43
|
+
),
|
|
44
|
+
);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const GRADIENT = 'bg-gradient-to-r from-main-gradient-start to-main-gradient-end';
|
|
2
|
+
export const BORDER_CLASSES = 'border-main-stroke border-solid border';
|
|
3
|
+
export const DIVIDER_CLASSES = 'border-main-divider border border-t-0 border-x-0';
|
|
4
|
+
export const FIRST_CELL_CLASSES = 'w-[200px] mr-6';
|
|
5
|
+
export const COLS_LENGTH_FOR_SCROLL = 2;
|
|
6
|
+
export const COLUMN_WIDTH = 4 * 80 + 4 * 4; // w-80 + gap-4 = 336px
|