@sberbusiness/triplex-next-mcp-server 1.50.0-beta → 1.53.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +1 -0
  2. package/bundle/components/AlertProcess.md +6 -3
  3. package/bundle/components/AlertProcessSpoiler.md +216 -0
  4. package/bundle/components/Badge.md +4 -3
  5. package/bundle/components/ButtonDropdown.md +5 -3
  6. package/bundle/components/Carousel.md +671 -0
  7. package/bundle/components/CarouselExtended.md +7 -5
  8. package/bundle/components/CarouselIndicators.md +666 -0
  9. package/bundle/components/CarouselItem.md +579 -0
  10. package/bundle/components/CarouselNextButton.md +633 -0
  11. package/bundle/components/CarouselPrevButton.md +633 -0
  12. package/bundle/components/CarouselViewport.md +631 -0
  13. package/bundle/components/CheckboxTreeExtended.md +21 -7
  14. package/bundle/components/CheckboxTreeExtendedCheckbox.md +591 -0
  15. package/bundle/components/CheckboxTreeExtendedNode.md +577 -0
  16. package/bundle/components/Chip.md +1 -0
  17. package/bundle/components/ChipDatePicker.md +332 -0
  18. package/bundle/components/ChipDatePickerTarget.md +316 -0
  19. package/bundle/components/ChipMonthYearPicker.md +4 -3
  20. package/bundle/components/ChipMonthYearPickerTarget.md +318 -0
  21. package/bundle/components/ChipMultiselect.md +63 -73
  22. package/bundle/components/ChipSelect.md +385 -0
  23. package/bundle/components/ChipSelectTarget.md +388 -0
  24. package/bundle/components/ChipSuggest.md +10 -16
  25. package/bundle/components/ChipSuggestTarget.md +506 -0
  26. package/bundle/components/CollapsibleTree.md +2 -1
  27. package/bundle/components/CollapsibleTreeExtended.md +2 -1
  28. package/bundle/components/DateField.md +4 -2
  29. package/bundle/components/DatePickerExtended.md +16 -14
  30. package/bundle/components/DateRange.md +17 -10
  31. package/bundle/components/Dropdown.md +36 -63
  32. package/bundle/components/EmptyView.md +9 -4
  33. package/bundle/components/ExpandAnimation.md +9 -5
  34. package/bundle/components/FormField.md +1 -1
  35. package/bundle/components/ImageGallery.md +19 -52
  36. package/bundle/components/ImageGalleryExtended.md +123 -139
  37. package/bundle/components/ListItemControlsButtonDropdown.md +3 -2
  38. package/bundle/components/LoaderSmall.md +5 -4
  39. package/bundle/components/MonthYearRange.md +334 -0
  40. package/bundle/components/MultiselectField.md +81 -143
  41. package/bundle/components/Notification.md +2 -1
  42. package/bundle/components/NotificationGrouped.md +174 -0
  43. package/bundle/components/NumberField.md +259 -116
  44. package/bundle/components/OrderedList.md +149 -112
  45. package/bundle/components/Overlay.md +3 -2
  46. package/bundle/components/PageIndicators.md +306 -0
  47. package/bundle/components/Pagination.md +81 -3
  48. package/bundle/components/PaginationExtended.md +160 -0
  49. package/bundle/components/Portal.md +5 -2
  50. package/bundle/components/Puller.md +375 -0
  51. package/bundle/components/SMSField.md +277 -102
  52. package/bundle/components/SelectExtendedField.md +11 -7
  53. package/bundle/components/SelectField.md +7 -4
  54. package/bundle/components/SmartSpot.md +259 -0
  55. package/bundle/components/Step.md +2 -1
  56. package/bundle/components/Stepper.md +7 -7
  57. package/bundle/components/Suggest.md +7 -6
  58. package/bundle/components/SuggestField.md +8 -6
  59. package/bundle/components/TableBasic.md +12 -14
  60. package/bundle/components/Tooltip.md +9 -8
  61. package/bundle/guides/commits.md +4 -1
  62. package/bundle/guides/context.md +5 -5
  63. package/bundle/guides/stories.md +29 -21
  64. package/bundle/manifest.json +145 -13
  65. package/bundle/release-notes/1.50.0.mdx +4 -0
  66. package/bundle/release-notes/1.51.0.mdx +57 -0
  67. package/bundle/release-notes/1.52.0.mdx +55 -0
  68. package/bundle/release-notes/1.53.0.mdx +60 -0
  69. package/bundle/release-notes/1.54.0.mdx +45 -0
  70. package/bundle/release-notes/1.55.0.mdx +7 -0
  71. package/bundle/tokens.json +377 -222
  72. package/dist/index.js +39 -1
  73. package/dist/index.js.map +1 -1
  74. package/package.json +1 -1
@@ -0,0 +1,579 @@
1
+ ---
2
+ component: CarouselItem
3
+ category: Carousel
4
+ related: [Carousel]
5
+ tokens: []
6
+ stories: stories/Carousel/Carousel.stories.tsx
7
+ version: "1.0"
8
+ ---
9
+
10
+ # CarouselItem
11
+
12
+ ## Назначение
13
+
14
+ Слайд составного `Carousel`. Регистрирует свой DOM-узел по `index`, по этим
15
+ узлам родитель измеряет слайды и рассчитывает страницы и границы прокрутки.
16
+
17
+ Используй внутри `Carousel.Track`, вложенного в `Carousel.Viewport`.
18
+ Не используй вне `Carousel`: без родителя слайд не измеряется и не участвует
19
+ в навигации.
20
+
21
+ Доступен только как `Carousel.Item`: именованного экспорта `CarouselItem`
22
+ из пакета нет, `ICarouselItemProps` экспортируется.
23
+
24
+ ```tsx
25
+ import { Carousel } from "@sberbusiness/triplex-next";
26
+
27
+ <Carousel style={{ width: 320, height: 180 }}>
28
+ <Carousel.Viewport>
29
+ <Carousel.Track>
30
+ {items.map((item, index) => (
31
+ <Carousel.Item key={item.id} index={index} aria-label={item.title} style={{ width: 280 }}>
32
+ {item.title}
33
+ </Carousel.Item>
34
+ ))}
35
+ </Carousel.Track>
36
+ </Carousel.Viewport>
37
+ </Carousel>
38
+ ```
39
+
40
+ ---
41
+
42
+ ## Варианты и props
43
+
44
+ ### Обязательные props
45
+
46
+ | Prop | Тип | Описание |
47
+ |---|---|---|
48
+ | `index` | `number` | Позиция слайда с нуля. Ключ регистрации для геометрии, не HTML-атрибут |
49
+
50
+ Остальные props — атрибуты `<div>`, передаются на корень слайда.
51
+
52
+ ### Индексы
53
+
54
+ - Индексы уникальны, идут подряд (`0, 1, 2, …`) и совпадают с DOM-порядком.
55
+ Пропуск, дубликат или несовпадение с порядком ломают расчёт страниц;
56
+ компонент такой ввод не проверяет.
57
+ - `index` берётся из позиции в `map`, `key` — из стабильного id данных. После
58
+ удаления, вставки или перестановки потребитель пересчитывает индексы.
59
+ - Регистрация не запускает пересчёт геометрии. Кэш размеров слайдов
60
+ сбрасывается при изменении размеров `Viewport` или `Track`
61
+ (`ResizeObserver`) и при смене `gap`, `scrollMode` или `orientation`:
62
+ после перестановки слайдов без этих изменений в кэше остаются прежние
63
+ размеры по индексам.
64
+ - Размер слайда задаёт потребитель или содержимое; родитель измеряет ширину
65
+ в горизонтальной карусели и высоту в вертикальной.
66
+
67
+ ---
68
+
69
+ ## Дизайн-токены
70
+
71
+ Собственных токенов нет.
72
+
73
+ ---
74
+
75
+ ## Инварианты
76
+
77
+ - `forwardRef` указывает на корневой `<div>` слайда; внешний ref объединяется
78
+ с регистрационным callback.
79
+ - `displayName` — `"Carousel.Item"`, CSS-класс — `slide`.
80
+ - При смене `index` и размонтировании прежняя запись удаляется из реестра:
81
+ родитель считает слайды по числу записей, а не по `children`.
82
+ - `role="group"` задан до spread, потребитель может его переопределить.
83
+
84
+ ---
85
+
86
+ ## Accessibility
87
+
88
+ - Роль по умолчанию — `group`; доступное имя задаёт потребитель через
89
+ `aria-label` или `aria-labelledby`.
90
+ - `index` не даёт `aria-posinset` / `aria-setsize` и связей с индикаторами.
91
+ - Слайды за пределами видимой области не получают `aria-hidden`, `inert`
92
+ или `tabIndex={-1}`: их содержимое остаётся в Tab-порядке.
93
+
94
+ ---
95
+
96
+ ## Связанные компоненты
97
+
98
+ - `Carousel` — владелец контекста, геометрии и навигации.
99
+ - `Carousel.Track` — лента слайдов, задаёт `gap` и смещение.
100
+ - `Carousel.Viewport` — видимая область и touch-жесты.
101
+
102
+ ---
103
+
104
+ ## Stories
105
+
106
+ Основные истории: `stories/Carousel/Carousel.stories.tsx`
107
+ Файлы примеров: `stories/Carousel/examples/`
108
+
109
+ | Story | Example file | Что демонстрирует |
110
+ |---|---|---|
111
+ | `Playground` | `Playground.tsx` | Слайды при смене ориентации, режима прокрутки и зазора |
112
+ | `Default` | `Default.tsx` | Слайды разной ширины |
113
+ | `ScrollModes` | `ScrollModes.tsx` | Слайды в режимах `ITEM` и `PAGE` |
114
+ | `Orientations` | `Orientations.tsx` | Ширина горизонтальных и высота вертикальных слайдов |
115
+ | `Production` | `Production.tsx` | Слайды с карточками и вложенными кнопками |
116
+ | `DynamicIndicators` | `DynamicIndicators.tsx` | Длинная лента слайдов |
117
+
118
+ ---
119
+
120
+ ## История изменений
121
+
122
+ | Дата | Изменение |
123
+ |---|---|
124
+ | 2026-10-20 | Создан документ |
125
+
126
+ ---
127
+
128
+ ## Примеры использования
129
+
130
+ ### Default
131
+
132
+ `stories/Carousel/examples/Default.tsx`
133
+
134
+ ```tsx
135
+ import React from "react";
136
+ import { Carousel } from "@sberbusiness/triplex-next";
137
+
138
+ const BASE_ITEM_STYLE: React.CSSProperties = {
139
+ display: "flex",
140
+ alignItems: "center",
141
+ justifyContent: "center",
142
+ boxSizing: "border-box",
143
+ borderRadius: "8px",
144
+ color: "#ffffff",
145
+ fontSize: "24px",
146
+ fontWeight: "bold",
147
+ userSelect: "none",
148
+ };
149
+
150
+ export const Default = () => {
151
+ const itemSizes = [92, 168, 220, 244, 252, 256, 252, 244, 220, 168, 92];
152
+ const items = itemSizes.map((size, index) => {
153
+ const totalItems = itemSizes.length;
154
+ const hue = (index / (totalItems - 1)) * 280;
155
+
156
+ return {
157
+ id: index + 1,
158
+ size,
159
+ backgroundColor: `hsl(${hue}, 50%, 50%)`,
160
+ };
161
+ });
162
+
163
+ const boxStyle: React.CSSProperties = {
164
+ width: "100%",
165
+ height: "256px",
166
+ maxWidth: "512px",
167
+ };
168
+
169
+ return (
170
+ <div style={boxStyle}>
171
+ <Carousel>
172
+ <Carousel.Viewport>
173
+ <Carousel.Track>
174
+ {items.map((item, index) => (
175
+ <Carousel.Item
176
+ key={item.id}
177
+ index={index}
178
+ style={{
179
+ ...BASE_ITEM_STYLE,
180
+ width: item.size,
181
+ height: "100%",
182
+ backgroundColor: item.backgroundColor,
183
+ }}
184
+ >
185
+ {item.id}
186
+ </Carousel.Item>
187
+ ))}
188
+ </Carousel.Track>
189
+ <Carousel.PrevButton aria-label="Previous slide" />
190
+ <Carousel.NextButton aria-label="Next slide" />
191
+ </Carousel.Viewport>
192
+ </Carousel>
193
+ </div>
194
+ );
195
+ };
196
+ ```
197
+
198
+ ### ScrollModes
199
+
200
+ `stories/Carousel/examples/ScrollModes.tsx`
201
+
202
+ ```tsx
203
+ import React from "react";
204
+ import { Carousel, ECarouselScrollMode } from "@sberbusiness/triplex-next";
205
+
206
+ interface ScrollModeItemProps {
207
+ scrollMode: ECarouselScrollMode;
208
+ }
209
+
210
+ const BASE_ITEM_STYLE: React.CSSProperties = {
211
+ display: "flex",
212
+ alignItems: "center",
213
+ justifyContent: "center",
214
+ boxSizing: "border-box",
215
+ height: "256px",
216
+ borderRadius: "8px",
217
+ color: "#ffffff",
218
+ fontSize: "24px",
219
+ fontWeight: "bold",
220
+ userSelect: "none",
221
+ };
222
+
223
+ const ScrollModeItem = ({ scrollMode }: ScrollModeItemProps) => {
224
+ const itemSizes = [92, 168, 220, 244, 252, 256, 252, 244, 220, 168, 92];
225
+ const items = itemSizes.map((size, index) => {
226
+ const totalItems = itemSizes.length;
227
+ const hue = (index / (totalItems - 1)) * 280;
228
+
229
+ return {
230
+ id: index + 1,
231
+ size,
232
+ backgroundColor: `hsl(${hue}, 50%, 50%)`,
233
+ };
234
+ });
235
+
236
+ const containerStyle: React.CSSProperties = {
237
+ maxWidth: "512px",
238
+ };
239
+
240
+ return (
241
+ <div style={containerStyle}>
242
+ <div style={{ marginBottom: 8, fontSize: 16, fontWeight: 700 }}>{scrollMode.toUpperCase()}</div>
243
+ <Carousel scrollMode={scrollMode}>
244
+ <Carousel.Viewport>
245
+ <Carousel.Track>
246
+ {items.map((item, index) => (
247
+ <Carousel.Item
248
+ key={item.id}
249
+ index={index}
250
+ style={{
251
+ ...BASE_ITEM_STYLE,
252
+ width: item.size,
253
+ backgroundColor: item.backgroundColor,
254
+ }}
255
+ >
256
+ {item.id}
257
+ </Carousel.Item>
258
+ ))}
259
+ </Carousel.Track>
260
+ <Carousel.PrevButton aria-label="Previous slide" />
261
+ <Carousel.NextButton aria-label="Next slide" />
262
+ </Carousel.Viewport>
263
+ <Carousel.Indicators />
264
+ </Carousel>
265
+ </div>
266
+ );
267
+ };
268
+
269
+ const SCROLL_MODES = Object.values(ECarouselScrollMode);
270
+
271
+ export const ScrollModes = () => (
272
+ <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
273
+ {SCROLL_MODES.map((scrollMode) => (
274
+ <ScrollModeItem key={scrollMode} scrollMode={scrollMode} />
275
+ ))}
276
+ </div>
277
+ );
278
+ ```
279
+
280
+ ### Orientations
281
+
282
+ `stories/Carousel/examples/Orientations.tsx`
283
+
284
+ ```tsx
285
+ import React from "react";
286
+ import { Carousel, EOrientation } from "@sberbusiness/triplex-next";
287
+
288
+ interface OrientationItemProps {
289
+ orientation: EOrientation;
290
+ }
291
+
292
+ const BASE_ITEM_STYLE: React.CSSProperties = {
293
+ display: "flex",
294
+ alignItems: "center",
295
+ justifyContent: "center",
296
+ boxSizing: "border-box",
297
+ borderRadius: "8px",
298
+ color: "#ffffff",
299
+ fontSize: "24px",
300
+ fontWeight: "bold",
301
+ userSelect: "none",
302
+ };
303
+
304
+ const ORIENTATION_TO_ITEM_DIMENSIONS_MAP: Record<EOrientation, (size: number) => React.CSSProperties> = {
305
+ [EOrientation.HORIZONTAL]: (size) => ({
306
+ width: size,
307
+ height: "100%",
308
+ }),
309
+ [EOrientation.VERTICAL]: (size) => ({
310
+ width: "100%",
311
+ height: size / 2,
312
+ }),
313
+ };
314
+
315
+ const ORIENTATION_TO_GAP_MAP: Record<EOrientation, number> = {
316
+ [EOrientation.HORIZONTAL]: 16,
317
+ [EOrientation.VERTICAL]: 8,
318
+ };
319
+
320
+ const OrientationItem = ({ orientation }: OrientationItemProps) => {
321
+ const itemSizes = [92, 168, 220, 244, 252, 256, 252, 244, 220, 168, 92];
322
+ const items = itemSizes.map((size, index) => {
323
+ const totalItems = itemSizes.length;
324
+ const hue = (index / (totalItems - 1)) * 280;
325
+
326
+ return {
327
+ id: index + 1,
328
+ size,
329
+ backgroundColor: `hsl(${hue}, 50%, 50%)`,
330
+ };
331
+ });
332
+
333
+ const containerStyle: React.CSSProperties = {
334
+ maxWidth: "512px",
335
+ };
336
+
337
+ const viewportStyle: React.CSSProperties = {
338
+ height: "256px",
339
+ };
340
+
341
+ return (
342
+ <div style={containerStyle}>
343
+ <div style={{ marginBottom: 8, fontSize: 16, fontWeight: 700 }}>{orientation.toUpperCase()}</div>
344
+ <Carousel orientation={orientation} gap={ORIENTATION_TO_GAP_MAP[orientation]}>
345
+ <Carousel.Viewport style={viewportStyle}>
346
+ <Carousel.Track>
347
+ {items.map((item, index) => {
348
+ const itemStyle: React.CSSProperties = {
349
+ ...BASE_ITEM_STYLE,
350
+ ...ORIENTATION_TO_ITEM_DIMENSIONS_MAP[orientation](item.size),
351
+ backgroundColor: item.backgroundColor,
352
+ };
353
+
354
+ return (
355
+ <Carousel.Item key={item.id} index={index} style={itemStyle}>
356
+ {item.id}
357
+ </Carousel.Item>
358
+ );
359
+ })}
360
+ </Carousel.Track>
361
+ <Carousel.PrevButton aria-label="Previous slide" />
362
+ <Carousel.NextButton aria-label="Next slide" />
363
+ </Carousel.Viewport>
364
+ <Carousel.Indicators />
365
+ </Carousel>
366
+ </div>
367
+ );
368
+ };
369
+
370
+ const ORIENTATIONS = Object.values(EOrientation);
371
+
372
+ export const Orientations = () => (
373
+ <div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
374
+ {ORIENTATIONS.map((orientation) => (
375
+ <OrientationItem key={orientation} orientation={orientation} />
376
+ ))}
377
+ </div>
378
+ );
379
+ ```
380
+
381
+ ### Production
382
+
383
+ `stories/Carousel/examples/Production.tsx`
384
+
385
+ ```tsx
386
+ import React, { useState } from "react";
387
+ import {
388
+ Carousel,
389
+ CardAction,
390
+ ECardRoundingSize,
391
+ ECardTheme,
392
+ ECardContentPaddingSize,
393
+ Title,
394
+ ETitleSize,
395
+ EFontWeightTitle,
396
+ Text,
397
+ ETextSize,
398
+ EFontType,
399
+ Gap,
400
+ Link,
401
+ Button,
402
+ EButtonTheme,
403
+ EComponentSize,
404
+ } from "@sberbusiness/triplex-next";
405
+ import { DefaulticonStrokePrdIcon20 } from "@sberbusiness/icons-next";
406
+
407
+ const CARDS_IDS = Array.from({ length: 6 }, (_, i) => i);
408
+
409
+ const CardBody = () => (
410
+ <CardAction.Content.Body>
411
+ {[1, 2, 3].map((item) => (
412
+ <div key={item} style={{ display: "flex", alignItems: "center", marginTop: item > 1 ? "16px" : "0" }}>
413
+ <DefaulticonStrokePrdIcon20 paletteIndex={5} />
414
+ <Text size={ETextSize.B3} style={{ marginLeft: "8px" }}>
415
+ List item text
416
+ </Text>
417
+ </div>
418
+ ))}
419
+ <Gap size={8} />
420
+ <Text tag="div" type={EFontType.SECONDARY} size={ETextSize.B4}>
421
+ This message provides additional context or highlights important information to note.
422
+ </Text>
423
+ <Gap size={8} />
424
+ <Text tag="div" type={EFontType.PRIMARY} size={ETextSize.B3}>
425
+ <Link onKeyDown={(event) => event.stopPropagation()} onClick={(event) => event.stopPropagation()}>
426
+ Link text
427
+ </Link>
428
+ </Text>
429
+ </CardAction.Content.Body>
430
+ );
431
+
432
+ export const Production = () => {
433
+ const [selectedId, setSelectedId] = useState<number | null>(null);
434
+
435
+ return (
436
+ <div style={{ width: "100%", maxWidth: "752px" }}>
437
+ <Carousel viewportPadding={8}>
438
+ <Carousel.Viewport>
439
+ <Carousel.Track>
440
+ {CARDS_IDS.map((id, index) => {
441
+ const selected = selectedId === id;
442
+
443
+ return (
444
+ <Carousel.Item
445
+ key={id}
446
+ index={index}
447
+ style={{
448
+ width: "216px",
449
+ height: "100%",
450
+ boxSizing: "border-box",
451
+ }}
452
+ >
453
+ <CardAction
454
+ roundingSize={ECardRoundingSize.MD}
455
+ theme={ECardTheme.GENERAL}
456
+ selected={selected}
457
+ toggle={() => setSelectedId(selected ? null : id)}
458
+ >
459
+ <CardAction.Media
460
+ style={{
461
+ backgroundImage: "url(assets/images/evotor.png)",
462
+ height: "129px",
463
+ }}
464
+ />
465
+ <CardAction.Content paddingSize={ECardContentPaddingSize.SM}>
466
+ <CardAction.Content.Header>
467
+ <Title tag="div" size={ETitleSize.H3} weight={EFontWeightTitle.REGULAR}>
468
+ Title Text
469
+ </Title>
470
+ </CardAction.Content.Header>
471
+
472
+ <CardBody />
473
+
474
+ <CardAction.Content.Footer>
475
+ <Button
476
+ theme={
477
+ selected ? EButtonTheme.SECONDARY_LIGHT : EButtonTheme.SECONDARY
478
+ }
479
+ size={EComponentSize.SM}
480
+ onKeyDown={(event) => event.stopPropagation()}
481
+ onClick={(event) => event.stopPropagation()}
482
+ >
483
+ Button text
484
+ </Button>
485
+ </CardAction.Content.Footer>
486
+ </CardAction.Content>
487
+ </CardAction>
488
+ </Carousel.Item>
489
+ );
490
+ })}
491
+ </Carousel.Track>
492
+ <Carousel.PrevButton aria-label="Previous slide" />
493
+ <Carousel.NextButton aria-label="Next slide" />
494
+ </Carousel.Viewport>
495
+ </Carousel>
496
+ </div>
497
+ );
498
+ };
499
+ ```
500
+
501
+ ### DynamicIndicators
502
+
503
+ `stories/Carousel/examples/DynamicIndicators.tsx`
504
+
505
+ ```tsx
506
+ import React from "react";
507
+ import { Carousel, ECarouselScrollMode } from "@sberbusiness/triplex-next";
508
+
509
+ const BASE_ITEM_STYLE: React.CSSProperties = {
510
+ display: "flex",
511
+ alignItems: "center",
512
+ justifyContent: "center",
513
+ boxSizing: "border-box",
514
+ borderRadius: "8px",
515
+ color: "#ffffff",
516
+ fontSize: "24px",
517
+ fontWeight: "bold",
518
+ userSelect: "none",
519
+ };
520
+
521
+ export const DynamicIndicators = () => {
522
+ const itemSizes = Array.from({ length: 20 }, () => 128);
523
+
524
+ const items = itemSizes.map((size, index) => {
525
+ const totalItems = itemSizes.length;
526
+ const hue = (index / (totalItems - 1)) * 280;
527
+
528
+ return {
529
+ id: index + 1,
530
+ size,
531
+ backgroundColor: `hsl(${hue}, 50%, 50%)`,
532
+ };
533
+ });
534
+
535
+ const boxStyle: React.CSSProperties = {
536
+ display: "flex",
537
+ flexDirection: "column",
538
+ gap: "16px",
539
+ width: "100%",
540
+ maxWidth: "512px",
541
+ };
542
+
543
+ const containerStyle: React.CSSProperties = {
544
+ width: "100%",
545
+ height: "256px",
546
+ };
547
+
548
+ return (
549
+ <div style={boxStyle}>
550
+ <div style={containerStyle}>
551
+ <Carousel scrollMode={ECarouselScrollMode.PAGE}>
552
+ <Carousel.Viewport>
553
+ <Carousel.Track>
554
+ {items.map((item, index) => (
555
+ <Carousel.Item
556
+ key={item.id}
557
+ index={index}
558
+ style={{
559
+ ...BASE_ITEM_STYLE,
560
+ width: item.size,
561
+ height: "100%",
562
+ backgroundColor: item.backgroundColor,
563
+ }}
564
+ >
565
+ {item.id}
566
+ </Carousel.Item>
567
+ ))}
568
+ </Carousel.Track>
569
+ <Carousel.PrevButton aria-label="Previous slide" />
570
+ <Carousel.NextButton aria-label="Next slide" />
571
+ </Carousel.Viewport>
572
+ <Carousel.Indicators />
573
+ </Carousel>
574
+ </div>
575
+ </div>
576
+ );
577
+ };
578
+ ```
579
+