@gravity-ui/page-constructor 8.15.0 → 8.17.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/README.md +31 -9
- package/build/cjs/constructor-items.d.ts +1 -1
- package/build/cjs/demo/ComponentMap/ComponentMap.css +55 -0
- package/build/cjs/demo/ComponentMap/ComponentMap.d.ts +6 -0
- package/build/cjs/demo/ComponentMap/ComponentMap.js +286 -0
- package/build/cjs/demo/ComponentMap/ComponentMap.js.map +1 -0
- package/build/cjs/demo/ComponentMap/draw.d.ts +23 -0
- package/build/cjs/demo/ComponentMap/draw.js +134 -0
- package/build/cjs/demo/ComponentMap/draw.js.map +1 -0
- package/build/cjs/demo/ComponentMap/edgeGeometry.d.ts +20 -0
- package/build/cjs/demo/ComponentMap/edgeGeometry.js +146 -0
- package/build/cjs/demo/ComponentMap/edgeGeometry.js.map +1 -0
- package/build/cjs/demo/ComponentMap/graph.d.ts +9 -0
- package/build/cjs/demo/ComponentMap/graph.js +68 -0
- package/build/cjs/demo/ComponentMap/graph.js.map +1 -0
- package/build/cjs/demo/ComponentMap/layout.d.ts +12 -0
- package/build/cjs/demo/ComponentMap/layout.js +149 -0
- package/build/cjs/demo/ComponentMap/layout.js.map +1 -0
- package/build/cjs/demo/ComponentMap/model.d.ts +55 -0
- package/build/cjs/demo/ComponentMap/model.js +3 -0
- package/build/cjs/demo/ComponentMap/model.js.map +1 -0
- package/build/cjs/demo/ComponentMap/viewport.d.ts +7 -0
- package/build/cjs/demo/ComponentMap/viewport.js +41 -0
- package/build/cjs/demo/ComponentMap/viewport.js.map +1 -0
- package/build/cjs/demo/HeroAndMedia.stories.js +12 -23
- package/build/cjs/demo/HeroAndMedia.stories.js.map +1 -1
- package/build/cjs/demo/TokenizationHeader.stories.d.ts +13 -0
- package/build/cjs/demo/TokenizationHeader.stories.js +47 -0
- package/build/cjs/demo/TokenizationHeader.stories.js.map +1 -0
- package/build/cjs/demo/TokenizationHero.stories.d.ts +9 -0
- package/build/cjs/demo/TokenizationHero.stories.js +20 -0
- package/build/cjs/demo/TokenizationHero.stories.js.map +1 -0
- package/build/cjs/demo/tokenizationLanding.d.ts +2 -0
- package/build/cjs/demo/tokenizationLanding.js +21 -0
- package/build/cjs/demo/tokenizationLanding.js.map +1 -0
- package/build/cjs/models/constructor-items/sub-blocks.d.ts +3 -0
- package/build/cjs/models/constructor-items/sub-blocks.js.map +1 -1
- package/build/cjs/sub-blocks/LayoutItem/LayoutItem.css +15 -0
- package/build/cjs/sub-blocks/LayoutItem/LayoutItem.d.ts +1 -1
- package/build/cjs/sub-blocks/LayoutItem/LayoutItem.js +12 -2
- package/build/cjs/sub-blocks/LayoutItem/LayoutItem.js.map +1 -1
- package/build/cjs/sub-blocks/LayoutItem/schema.d.ts +10 -0
- package/build/cjs/sub-blocks/LayoutItem/schema.js +10 -0
- package/build/cjs/sub-blocks/LayoutItem/schema.js.map +1 -1
- package/build/docs/INDEX.md +191 -0
- package/build/docs/blocks/Banner.md +59 -0
- package/build/docs/blocks/CardLayout.md +79 -0
- package/build/docs/blocks/Companies.md +67 -0
- package/build/docs/blocks/ContentLayout.md +54 -0
- package/build/docs/blocks/ExtendedFeatures.md +74 -0
- package/build/docs/blocks/FilterBlock.md +112 -0
- package/build/docs/blocks/FoldableList.md +78 -0
- package/build/docs/blocks/Footer.md +110 -0
- package/build/docs/blocks/Form.md +89 -0
- package/build/docs/blocks/Header.md +70 -0
- package/build/docs/blocks/HeaderSlider.md +70 -0
- package/build/docs/blocks/Hero.md +67 -0
- package/build/docs/blocks/Icons.md +61 -0
- package/build/docs/blocks/Info.md +73 -0
- package/build/docs/blocks/Map.md +81 -0
- package/build/docs/blocks/Media.md +63 -0
- package/build/docs/blocks/PromoFeaturesBlock.md +74 -0
- package/build/docs/blocks/Questions.md +78 -0
- package/build/docs/blocks/Share.md +45 -0
- package/build/docs/blocks/Slider.md +89 -0
- package/build/docs/blocks/SliderOld.md +63 -0
- package/build/docs/blocks/Table.md +64 -0
- package/build/docs/blocks/Tabs.md +92 -0
- package/build/docs/guides/data-preparation-ru.md +257 -0
- package/build/docs/guides/data-preparation.md +259 -0
- package/build/docs/sub-blocks/BackgroundCard.md +63 -0
- package/build/docs/sub-blocks/BannerCard.md +57 -0
- package/build/docs/sub-blocks/BasicCard.md +60 -0
- package/build/docs/sub-blocks/Content.md +58 -0
- package/build/docs/sub-blocks/Divider.md +47 -0
- package/build/docs/sub-blocks/HubspotForm.md +47 -0
- package/build/docs/sub-blocks/ImageCard.md +59 -0
- package/build/docs/sub-blocks/LayoutItem.md +75 -0
- package/build/docs/sub-blocks/MediaCard.md +66 -0
- package/build/docs/sub-blocks/PriceCard.md +60 -0
- package/build/docs/sub-blocks/PriceDetailed.md +74 -0
- package/build/docs/sub-blocks/Quote.md +74 -0
- package/build/esm/constructor-items.d.ts +1 -1
- package/build/esm/demo/ComponentMap/ComponentMap.css +55 -0
- package/build/esm/demo/ComponentMap/ComponentMap.d.ts +7 -0
- package/build/esm/demo/ComponentMap/ComponentMap.js +283 -0
- package/build/esm/demo/ComponentMap/ComponentMap.js.map +1 -0
- package/build/esm/demo/ComponentMap/draw.d.ts +23 -0
- package/build/esm/demo/ComponentMap/draw.js +130 -0
- package/build/esm/demo/ComponentMap/draw.js.map +1 -0
- package/build/esm/demo/ComponentMap/edgeGeometry.d.ts +20 -0
- package/build/esm/demo/ComponentMap/edgeGeometry.js +136 -0
- package/build/esm/demo/ComponentMap/edgeGeometry.js.map +1 -0
- package/build/esm/demo/ComponentMap/graph.d.ts +9 -0
- package/build/esm/demo/ComponentMap/graph.js +62 -0
- package/build/esm/demo/ComponentMap/graph.js.map +1 -0
- package/build/esm/demo/ComponentMap/layout.d.ts +12 -0
- package/build/esm/demo/ComponentMap/layout.js +144 -0
- package/build/esm/demo/ComponentMap/layout.js.map +1 -0
- package/build/esm/demo/ComponentMap/model.d.ts +55 -0
- package/build/esm/demo/ComponentMap/model.js +2 -0
- package/build/esm/demo/ComponentMap/model.js.map +1 -0
- package/build/esm/demo/ComponentMap/viewport.d.ts +7 -0
- package/build/esm/demo/ComponentMap/viewport.js +34 -0
- package/build/esm/demo/ComponentMap/viewport.js.map +1 -0
- package/build/esm/demo/HeroAndMedia.stories.js +1 -12
- package/build/esm/demo/HeroAndMedia.stories.js.map +1 -1
- package/build/esm/demo/TokenizationHeader.stories.d.ts +13 -0
- package/build/esm/demo/TokenizationHeader.stories.js +43 -0
- package/build/esm/demo/TokenizationHeader.stories.js.map +1 -0
- package/build/esm/demo/TokenizationHero.stories.d.ts +9 -0
- package/build/esm/demo/TokenizationHero.stories.js +16 -0
- package/build/esm/demo/TokenizationHero.stories.js.map +1 -0
- package/build/esm/demo/tokenizationLanding.d.ts +2 -0
- package/build/esm/demo/tokenizationLanding.js +16 -0
- package/build/esm/demo/tokenizationLanding.js.map +1 -0
- package/build/esm/models/constructor-items/sub-blocks.d.ts +3 -0
- package/build/esm/models/constructor-items/sub-blocks.js.map +1 -1
- package/build/esm/sub-blocks/LayoutItem/LayoutItem.css +15 -0
- package/build/esm/sub-blocks/LayoutItem/LayoutItem.d.ts +1 -1
- package/build/esm/sub-blocks/LayoutItem/LayoutItem.js +14 -4
- package/build/esm/sub-blocks/LayoutItem/LayoutItem.js.map +1 -1
- package/build/esm/sub-blocks/LayoutItem/schema.d.ts +10 -0
- package/build/esm/sub-blocks/LayoutItem/schema.js +10 -0
- package/build/esm/sub-blocks/LayoutItem/schema.js.map +1 -1
- package/package.json +4 -2
- package/schema/index.js +1 -1
- package/server/models/constructor-items/sub-blocks.d.ts +3 -0
- package/widget/index.js +1 -1
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Tabs
|
|
2
|
+
|
|
3
|
+
Renders a set of tab buttons that switch between rich content panels. Each tab panel pairs a content column (title, text, lists, buttons, links) with an optional media column (image, video, YouTube, iframe, DataLens), with control over column order, sizing, and border treatment.
|
|
4
|
+
|
|
5
|
+
## Block type
|
|
6
|
+
|
|
7
|
+
`type: 'tabs-block'`
|
|
8
|
+
|
|
9
|
+
## When to use
|
|
10
|
+
|
|
11
|
+
- Grouping several feature/explainer panels under a single heading where only one is visible at a time.
|
|
12
|
+
- Product or capability overviews that share the same layout but differ in text and media.
|
|
13
|
+
- Sections needing media + content panels with light/dark artwork variants per tab.
|
|
14
|
+
|
|
15
|
+
## Example
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"type": "tabs-block",
|
|
20
|
+
"title": {"text": "Lorem ipsum"},
|
|
21
|
+
"description": "**Ut enim ad minim veniam** [quis nostrud](https://example.com) exercitation.",
|
|
22
|
+
"direction": "media-content",
|
|
23
|
+
"centered": false,
|
|
24
|
+
"contentSize": "s",
|
|
25
|
+
"tabsColSizes": {"all": 12, "md": 12},
|
|
26
|
+
"items": [
|
|
27
|
+
{
|
|
28
|
+
"tabName": "Dolor sit amet",
|
|
29
|
+
"title": "Dolor sit amet",
|
|
30
|
+
"text": "**Ut enim ad minim veniam** exercitation.",
|
|
31
|
+
"buttons": [{"text": "Button", "theme": "action", "url": "https://example.com"}],
|
|
32
|
+
"media": {
|
|
33
|
+
"light": {"image": "/images/panel-light.png"},
|
|
34
|
+
"dark": {"image": "/images/panel-dark.png"}
|
|
35
|
+
},
|
|
36
|
+
"border": "shadow"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"tabName": "Lorem ipsum",
|
|
40
|
+
"title": "Lorem ipsum",
|
|
41
|
+
"caption": "Dolor sit amet",
|
|
42
|
+
"text": "* Ut enim ad minim veniam",
|
|
43
|
+
"links": [{"url": "https://example.com", "text": "Link", "theme": "normal", "arrow": true}],
|
|
44
|
+
"media": {"light": {"youtube": "https://youtu.be/0Qd3T6skprA"}},
|
|
45
|
+
"border": "shadow"
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Properties
|
|
52
|
+
|
|
53
|
+
| Property | Type | Default | Description |
|
|
54
|
+
| ------------------ | --------------------------------------------------------------- | ----------------- | ----------------------------------------------- |
|
|
55
|
+
| `items` _required_ | `TabsItem[]` | — | Array of tab panels. See below. |
|
|
56
|
+
| `title` | `string \| TitleProps` | — | Block heading (string or `TitleProps`). |
|
|
57
|
+
| `description` | `string` | — | YFM subtitle rendered under the title. |
|
|
58
|
+
| `direction` | `'media-content' \| 'content-media'` | `'media-content'` | Column order within each tab panel on desktop. |
|
|
59
|
+
| `centered` | `boolean` | — | Centers the title and the tab buttons row. |
|
|
60
|
+
| `contentSize` | `'s' \| 'm' \| 'l' \| 'xl'` | `'s'` | Content/media scale used inside each tab panel. |
|
|
61
|
+
| `tabsColSizes` | `{sm?, md?, lg?, xl?, all?}` (values are column numbers `1–12`) | — | Grid column sizes for the tab buttons row. |
|
|
62
|
+
| `animated` | `boolean` | — | Enables an entrance/scroll animation. |
|
|
63
|
+
|
|
64
|
+
### `items[]` (`TabsItem`)
|
|
65
|
+
|
|
66
|
+
| Property | Type | Default | Description |
|
|
67
|
+
| -------------------- | ------------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
68
|
+
| `tabName` _required_ | `string` | — | Label displayed on the tab button; also used as the tab identifier. |
|
|
69
|
+
| `title` | `string \| TitleProps` | — | Panel heading. |
|
|
70
|
+
| `text` | `string` | — | YFM body text. |
|
|
71
|
+
| `additionalInfo` | `string` | — | YFM supplementary text below the body. |
|
|
72
|
+
| `links` | `LinkProps[]` | — | Inline text links. |
|
|
73
|
+
| `buttons` | `ButtonBlock[]` | — | CTA buttons. |
|
|
74
|
+
| `list` | `ContentItem[]` | — | Bullet-style list with optional icons per item (`icon` or `gravityIcon`, plus `title`/`text`). |
|
|
75
|
+
| `controlPosition` | `'default' \| 'bottom'` | — | Vertical placement of buttons/links. |
|
|
76
|
+
| `media` | `MediaProps \| {light, dark}` | — | Media column: `image` (single or array → slider), `video`, `youtube`, `videoIframe`, `iframe`, `dataLens`, plus `previewImg`, `autoplay`, etc. |
|
|
77
|
+
| `caption` | `string` | — | Plain-text caption rendered with the media. |
|
|
78
|
+
| `image` _deprecated_ | `ImageProps \| {light, dark}` | — | Legacy single image; prefer `media`. |
|
|
79
|
+
| `link` _deprecated_ | `LinkProps` | — | Legacy single link; prefer `links`. |
|
|
80
|
+
| `border` | `'shadow' \| 'line' \| 'none'` | — | Border/shadow treatment around the tab panel. |
|
|
81
|
+
|
|
82
|
+
### Common properties
|
|
83
|
+
|
|
84
|
+
Inherits: `anchor`, `visible`, `indent` (`{top?, bottom?}`), `qa`, `className`, `animated`, `when`, `context`. See the root README for details.
|
|
85
|
+
|
|
86
|
+
## Themed values
|
|
87
|
+
|
|
88
|
+
Each tab's `media` (and the legacy `image`) accepts either a plain value or a `{light, dark}` object resolved against the active runtime theme.
|
|
89
|
+
|
|
90
|
+
## Storybook
|
|
91
|
+
|
|
92
|
+
[Tabs](https://preview.gravity-ui.com/page-constructor/?path=/docs/blocks-tabs--docs)
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
# Подготовка данных
|
|
2
|
+
|
|
3
|
+
Документацию по серверным утилитам для преобразования контента, включая конвертацию Yandex Flavored Markdown (YFM) в HTML и обработку текста. Основные возможности:
|
|
4
|
+
|
|
5
|
+
- **`fullTransform`**: Преобразует контент в формате YFM в HTML с настраиваемыми параметрами.
|
|
6
|
+
- **Утилиты**: `typografToText`, `typografToHTML` и `yfmTransformer` для обработки текста в пользовательских компонентах.
|
|
7
|
+
- **`createItemsParser`**: Утилита для преобразования определённых полей в блоках, поддерживающая вложенные поля и массивы.
|
|
8
|
+
|
|
9
|
+
### Серверные утилиты
|
|
10
|
+
|
|
11
|
+
Пакет включает набор серверных утилит для преобразования контента.
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
const {fullTransform} = require('@gravity-ui/page-constructor/server');
|
|
15
|
+
|
|
16
|
+
const {html} = fullTransform(content, {
|
|
17
|
+
lang,
|
|
18
|
+
extractTitle: true,
|
|
19
|
+
allowHTML: true,
|
|
20
|
+
path: __dirname,
|
|
21
|
+
plugins,
|
|
22
|
+
});
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Для преобразования Yandex Flavored Markdown в HTML используется пакет `diplodoc/transfrom`, который входит в peer-зависимости.
|
|
26
|
+
|
|
27
|
+
Эти утилиты можно также использовать в кастомных компонентах или других частях проекта.
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
const {
|
|
31
|
+
typografToText,
|
|
32
|
+
typografToHTML,
|
|
33
|
+
yfmTransformer,
|
|
34
|
+
} = require('@gravity-ui/page-constructor/server');
|
|
35
|
+
|
|
36
|
+
const post = {
|
|
37
|
+
title: typografToText(title, lang),
|
|
38
|
+
content: typografToHTML(content, lang),
|
|
39
|
+
description: yfmTransformer(lang, description, {plugins}),
|
|
40
|
+
};
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Список других доступных утилит можно найти в [этом разделе](https://github.com/gravity-ui/page-constructor/tree/main/src/text-transform).
|
|
44
|
+
|
|
45
|
+
## Документация к `createItemsParser`
|
|
46
|
+
|
|
47
|
+
Метод `createItemsParser` — это утилита, для создания парсеров блоков. Он помогает с преобразованием определённых полей с использованием трансформера. Метод имеет опции, позволяющие указать, какие поля нужно преобразовать и как обрабатывать вложенные поля.
|
|
48
|
+
|
|
49
|
+
### Сигнатура метода
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
export const createItemsParser = (fields: string[]) => (transformer: Transformer, items: Item[]) => Item[];
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Параметры
|
|
56
|
+
|
|
57
|
+
- **fields**: Массив строк, указывающих поля для преобразования. Эти поля могут быть вложенными, используя точечную нотацию (например, `'nested.field'`).
|
|
58
|
+
- **transformer**: Функция, которая принимает строку и возвращает преобразованную строку. Эта функция будет применена к указанным полям.
|
|
59
|
+
- **items**: Массив элементов для парсинга и преобразования. Каждый элемент может быть строкой или сложным объектом.
|
|
60
|
+
|
|
61
|
+
### Возвращаемое значение
|
|
62
|
+
|
|
63
|
+
- Возвращает массив элементов с преобразованными указанными полями с помощью функции `transformer`.
|
|
64
|
+
|
|
65
|
+
## Примеры использования
|
|
66
|
+
|
|
67
|
+
### Пример 1: Базовое использование
|
|
68
|
+
|
|
69
|
+
В этом примере преобразуются поля `text` и `additionalInfo` каждого элемента в массиве `items` с использованием `yfmTransformer`.
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
const config = {
|
|
73
|
+
fields: ['items'],
|
|
74
|
+
transformer: yfmTransformer,
|
|
75
|
+
parser: createItemsParser(['text', 'additionalInfo']),
|
|
76
|
+
};
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Input:**
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
[
|
|
83
|
+
{"text": "Hello, world!", "additionalInfo": "This is a test."},
|
|
84
|
+
{"text": "Another item", "additionalInfo": "More info here."}
|
|
85
|
+
]
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Output:**
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
[
|
|
92
|
+
{"text": "Transformed: Hello, world!", "additionalInfo": "Transformed: This is a test."},
|
|
93
|
+
{"text": "Transformed: Another item", "additionalInfo": "Transformed: More info here."}
|
|
94
|
+
]
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Пример 2: Вложенные поля
|
|
98
|
+
|
|
99
|
+
В этом примере преобразуется вложенное поле `list.text` внутри каждого элемента.
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
const config = {
|
|
103
|
+
fields: ['items'],
|
|
104
|
+
transformer: yfmTransformer,
|
|
105
|
+
parser: createItemsParser(['list.text']),
|
|
106
|
+
renderInline: true,
|
|
107
|
+
};
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Input:**
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
[{"list": {"text": "Вложенный текст 1"}}, {"list": {"text": "Вложенный текст 2"}}]
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**Output:**
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
[
|
|
120
|
+
{"list": {"text": "Transformed: Вложенный текст 1"}},
|
|
121
|
+
{"list": {"text": "Transformed: Вложенный текст 2"}}
|
|
122
|
+
]
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Пример 3: Смешанные типы данных
|
|
126
|
+
|
|
127
|
+
В этом примере массив `items` содержит как строки, так и сложные объекты. Метод `createItemsParser` корректно обрабатывает оба типа данных.
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
const config = {
|
|
131
|
+
fields: ['items'],
|
|
132
|
+
transformer: yfmTransformer,
|
|
133
|
+
parser: createItemsParser(['text', 'list.text']),
|
|
134
|
+
};
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Input:**
|
|
138
|
+
|
|
139
|
+
```json
|
|
140
|
+
["Простая строка", {"text": "Текст объекта", "list": {"text": "Вложенный текст"}}]
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**Output:**
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
[
|
|
147
|
+
"Transformed: Простая строка",
|
|
148
|
+
{"text": "Transformed: Текст объекта", "list": {"text": "Transformed: Вложенный текст"}}
|
|
149
|
+
]
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Примечания
|
|
153
|
+
|
|
154
|
+
- Если поле не найдено в элементе, оно будет пропущено.
|
|
155
|
+
- Если указано вложенное поле, но родительский объект не является объектом или не является массивом, преобразование для этого поля будет пропущено.
|
|
156
|
+
- Метод не изменяет исходные элементы, а возвращает новый массив с преобразованными данными.
|
|
157
|
+
|
|
158
|
+
### Обработка вложенных массивов
|
|
159
|
+
|
|
160
|
+
Если вложенное поле является массивом, метод `createItemsParser` будет итерировать по каждому элементу массива и применять трансформер к указанному полю. Это особенно полезно при работе с массивами объектов, содержащими поля, которые требуют преобразования.
|
|
161
|
+
|
|
162
|
+
### Пример 4: Вложенное поле как массив
|
|
163
|
+
|
|
164
|
+
В этом примере преобразуется поле `text` внутри каждого объекта в массиве `list`, который является вложенным полем элементов `items`.
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
const config = {
|
|
168
|
+
fields: ['items'],
|
|
169
|
+
transformer: yfmTransformer,
|
|
170
|
+
parser: createItemsParser(['list.text']),
|
|
171
|
+
};
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
**Input:**
|
|
175
|
+
|
|
176
|
+
```json
|
|
177
|
+
[
|
|
178
|
+
{
|
|
179
|
+
"list": [{"text": "Вложенный текст 1"}, {"text": "Вложенный текст 2"}]
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"list": [{"text": "Вложенный текст 3"}, {"text": "Вложенный текст 4"}]
|
|
183
|
+
}
|
|
184
|
+
]
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
**Output:**
|
|
188
|
+
|
|
189
|
+
```json
|
|
190
|
+
[
|
|
191
|
+
{
|
|
192
|
+
"list": [{"text": "Transformed: Вложенный текст 1"}, {"text": "Transformed: Вложенный текст 2"}]
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"list": [{"text": "Transformed: Вложенный текст 3"}, {"text": "Transformed: Вложенный текст 4"}]
|
|
196
|
+
}
|
|
197
|
+
]
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Полный пример со всеми случаями
|
|
201
|
+
|
|
202
|
+
Вот комплексный пример, включающий все возможные случаи: обычные поля, вложенные объекты и вложенные массивы.
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
const config = {
|
|
206
|
+
fields: ['items'],
|
|
207
|
+
transformer: yfmTransformer,
|
|
208
|
+
parser: createItemsParser(['text', 'list.text', 'details.info']),
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
const transformedItems = config.parser(config.transformer, items);
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**Input:**
|
|
215
|
+
|
|
216
|
+
```json
|
|
217
|
+
[
|
|
218
|
+
{
|
|
219
|
+
"text": "Обычный текст",
|
|
220
|
+
"list": [{"text": "Вложенный текст 1"}, {"text": "Вложенный текст 2"}],
|
|
221
|
+
"details": {
|
|
222
|
+
"info": "Вложенная информация"
|
|
223
|
+
}
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
"text": "Другой обычный текст",
|
|
227
|
+
"list": {"text": "Вложенный текст 3"},
|
|
228
|
+
"details": {
|
|
229
|
+
"info": "Другая вложенная информация"
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
]
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
**Output:**
|
|
236
|
+
|
|
237
|
+
```json
|
|
238
|
+
[
|
|
239
|
+
{
|
|
240
|
+
"text": "Transformed: Обычный текст",
|
|
241
|
+
"list": [
|
|
242
|
+
{"text": "Transformed: Вложенный текст 1"},
|
|
243
|
+
{"text": "Transformed: Вложенный текст 2"}
|
|
244
|
+
],
|
|
245
|
+
"details": {
|
|
246
|
+
"info": "Transformed: Вложенная информация"
|
|
247
|
+
}
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
"text": "Transformed: Другой обычный текст",
|
|
251
|
+
"list": {"text": "Transformed: Вложенный текст 3"},
|
|
252
|
+
"details": {
|
|
253
|
+
"info": "Transformed: Другая вложенная информация"
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
]
|
|
257
|
+
```
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
# Data preparation
|
|
2
|
+
|
|
3
|
+
This chapter provides documentaion for server utilities for transforming content, including Yandex Flavored Markdown (YFM) to HTML conversion and text processing. Key features include:
|
|
4
|
+
|
|
5
|
+
- fullTransform: Converts YFM content into HTML with customizable options.
|
|
6
|
+
|
|
7
|
+
- Utilities: Includes typografToText, typografToHTML, and yfmTransformer for text processing in custom components.
|
|
8
|
+
|
|
9
|
+
- createItemsParser: A flexible utility for transforming specific fields in complex data structures, supporting nested fields and arrays.
|
|
10
|
+
|
|
11
|
+
## Server utils
|
|
12
|
+
|
|
13
|
+
The package provides a set of server utilities for transforming your content.
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
const {fullTransform} = require('@gravity-ui/page-constructor/server');
|
|
17
|
+
|
|
18
|
+
const {html} = fullTransform(content, {
|
|
19
|
+
lang,
|
|
20
|
+
extractTitle: true,
|
|
21
|
+
allowHTML: true,
|
|
22
|
+
path: __dirname,
|
|
23
|
+
plugins,
|
|
24
|
+
});
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Under the hood, a package is used to transform Yandex Flavored Markdown into HTML - `diplodoc/transfrom`, so it is also in peer dependencies
|
|
28
|
+
|
|
29
|
+
You can also use useful utilities in the places you need, for example in your custom components
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
const {
|
|
33
|
+
typografToText,
|
|
34
|
+
typografToHTML,
|
|
35
|
+
yfmTransformer,
|
|
36
|
+
} = require('@gravity-ui/page-constructor/server');
|
|
37
|
+
|
|
38
|
+
const post = {
|
|
39
|
+
title: typografToText(title, lang),
|
|
40
|
+
content: typografToHTML(content, lang),
|
|
41
|
+
description: yfmTransformer(lang, description, {plugins}),
|
|
42
|
+
};
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
You can find more utilities in this [section](https://github.com/gravity-ui/page-constructor/tree/main/src/text-transform)
|
|
46
|
+
|
|
47
|
+
## `createItemsParser` Method Documentation
|
|
48
|
+
|
|
49
|
+
The `createItemsParser` method is a utility function designed to parse and transform items in a flexible and customizable way. It is particularly useful when dealing with complex data structures that require specific fields to be transformed using a provided transformer function. This method is highly configurable, allowing you to specify which fields to transform and how to handle nested fields.
|
|
50
|
+
|
|
51
|
+
### Method Signature
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
export const createItemsParser = (fields: string[]) => (transformer: Transformer, items: Item[]) => Item[];
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Parameters
|
|
58
|
+
|
|
59
|
+
- **fields**: An array of strings specifying the fields to be transformed. These fields can be nested, using dot notation (e.g., `'nested.field'`).
|
|
60
|
+
- **transformer**: A function that takes a string and returns a transformed string. This function will be applied to the specified fields.
|
|
61
|
+
- **items**: An array of items to be parsed and transformed. Each item can be a string or a complex object.
|
|
62
|
+
|
|
63
|
+
### Return Value
|
|
64
|
+
|
|
65
|
+
- Returns an array of items with the specified fields transformed by the `transformer` function.
|
|
66
|
+
|
|
67
|
+
## Usage Examples
|
|
68
|
+
|
|
69
|
+
### Example 1: Basic Usage
|
|
70
|
+
|
|
71
|
+
In this example, we want to transform the `text` and `additionalInfo` fields of each item in the `items` array using the `yfmTransformer`.
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
const config = {
|
|
75
|
+
fields: ['items'],
|
|
76
|
+
transformer: yfmTransformer,
|
|
77
|
+
parser: createItemsParser(['text', 'additionalInfo']),
|
|
78
|
+
};
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
**Input:**
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
[
|
|
85
|
+
{"text": "Hello, world!", "additionalInfo": "This is a test."},
|
|
86
|
+
{"text": "Another item", "additionalInfo": "More info here."}
|
|
87
|
+
]
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Output:**
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
[
|
|
94
|
+
{"text": "Transformed: Hello, world!", "additionalInfo": "Transformed: This is a test."},
|
|
95
|
+
{"text": "Transformed: Another item", "additionalInfo": "Transformed: More info here."}
|
|
96
|
+
]
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Example 2: Nested Fields
|
|
100
|
+
|
|
101
|
+
In this example, we want to transform a nested field `list.text` within each item.
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
const config = {
|
|
105
|
+
fields: ['items'],
|
|
106
|
+
transformer: yfmTransformer,
|
|
107
|
+
parser: createItemsParser(['list.text']),
|
|
108
|
+
renderInline: true,
|
|
109
|
+
};
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**Input:**
|
|
113
|
+
|
|
114
|
+
```json
|
|
115
|
+
[{"list": {"text": "Nested text 1"}}, {"list": {"text": "Nested text 2"}}]
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Output:**
|
|
119
|
+
|
|
120
|
+
```json
|
|
121
|
+
[{"list": {"text": "Transformed: Nested text 1"}}, {"list": {"text": "Transformed: Nested text 2"}}]
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Example 3: Mixed Data Types
|
|
125
|
+
|
|
126
|
+
In this example, the `items` array contains a mix of strings and complex objects. The `createItemsParser` will handle both types appropriately.
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
const config = {
|
|
130
|
+
fields: ['items'],
|
|
131
|
+
transformer: yfmTransformer,
|
|
132
|
+
parser: createItemsParser(['text', 'list.text']),
|
|
133
|
+
};
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Input:**
|
|
137
|
+
|
|
138
|
+
```json
|
|
139
|
+
["Simple string", {"text": "Object text", "list": {"text": "Nested text"}}]
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Output:**
|
|
143
|
+
|
|
144
|
+
```json
|
|
145
|
+
[
|
|
146
|
+
"Transformed: Simple string",
|
|
147
|
+
{"text": "Transformed: Object text", "list": {"text": "Transformed: Nested text"}}
|
|
148
|
+
]
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
## Key Features
|
|
152
|
+
|
|
153
|
+
- **Flexible Field Specification**: You can specify both top-level and nested fields using dot notation.
|
|
154
|
+
- **Mixed Data Handling**: The method can handle arrays containing both strings and complex objects.
|
|
155
|
+
- **Custom Transformers**: You can pass any transformer function to apply custom transformations to the specified fields.
|
|
156
|
+
|
|
157
|
+
## Notes
|
|
158
|
+
|
|
159
|
+
- If a field is not found in an item, it will be skipped.
|
|
160
|
+
- If a nested field is specified but the parent object is not an object or is an array, the transformation will be skipped for that field.
|
|
161
|
+
- The method does not mutate the original items but returns a new array with the transformed items.
|
|
162
|
+
|
|
163
|
+
### Handling Nested Arrays
|
|
164
|
+
|
|
165
|
+
When a nested field is an array, the `createItemsParser` method will iterate over each element in the array and apply the transformer function to the specified subfield. This is particularly useful when dealing with arrays of objects that contain fields requiring transformation.
|
|
166
|
+
|
|
167
|
+
### Example 4: Nested Field as an Array
|
|
168
|
+
|
|
169
|
+
In this example, we want to transform the `text` field within each object in the `list` array, which is a nested field of the `items`.
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
const config = {
|
|
173
|
+
fields: ['items'],
|
|
174
|
+
transformer: yfmTransformer,
|
|
175
|
+
parser: createItemsParser(['list.text']),
|
|
176
|
+
};
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Input:**
|
|
180
|
+
|
|
181
|
+
```json
|
|
182
|
+
[
|
|
183
|
+
{
|
|
184
|
+
"list": [{"text": "Nested text 1"}, {"text": "Nested text 2"}]
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"list": [{"text": "Nested text 3"}, {"text": "Nested text 4"}]
|
|
188
|
+
}
|
|
189
|
+
]
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**Output:**
|
|
193
|
+
|
|
194
|
+
```json
|
|
195
|
+
[
|
|
196
|
+
{
|
|
197
|
+
"list": [{"text": "Transformed: Nested text 1"}, {"text": "Transformed: Nested text 2"}]
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
"list": [{"text": "Transformed: Nested text 3"}, {"text": "Transformed: Nested text 4"}]
|
|
201
|
+
}
|
|
202
|
+
]
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Full Example with All Cases
|
|
206
|
+
|
|
207
|
+
Here’s a comprehensive example that includes all possible cases: top-level fields, nested objects, and nested arrays.
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
const config = {
|
|
211
|
+
fields: ['items'],
|
|
212
|
+
transformer: yfmTransformer,
|
|
213
|
+
parser: createItemsParser(['text', 'list.text', 'details.info']),
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
const transformedItems = config.parser(config.transformer, items);
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
**Input:**
|
|
220
|
+
|
|
221
|
+
```json
|
|
222
|
+
[
|
|
223
|
+
{
|
|
224
|
+
"text": "Top-level text",
|
|
225
|
+
"list": [{"text": "Nested text 1"}, {"text": "Nested text 2"}],
|
|
226
|
+
"details": {
|
|
227
|
+
"info": "Nested info"
|
|
228
|
+
}
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
"text": "Another top-level text",
|
|
232
|
+
"list": {"text": "Nested text 3"},
|
|
233
|
+
"details": {
|
|
234
|
+
"info": "Another nested info"
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
]
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
**Output:**
|
|
241
|
+
|
|
242
|
+
```json
|
|
243
|
+
[
|
|
244
|
+
{
|
|
245
|
+
"text": "Transformed: Top-level text",
|
|
246
|
+
"list": [{"text": "Transformed: Nested text 1"}, {"text": "Transformed: Nested text 2"}],
|
|
247
|
+
"details": {
|
|
248
|
+
"info": "Transformed: Nested info"
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
"text": "Transformed: Another top-level text",
|
|
253
|
+
"list": {"text": "Transformed: Nested text 3"},
|
|
254
|
+
"details": {
|
|
255
|
+
"info": "Transformed: Another nested info"
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
]
|
|
259
|
+
```
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# BackgroundCard
|
|
2
|
+
|
|
3
|
+
A card that renders text content (title, text, links, buttons, or a content list) over a decorative background image or solid color. Useful for promotional cards inside a card layout.
|
|
4
|
+
|
|
5
|
+
## Sub-block type
|
|
6
|
+
|
|
7
|
+
`type: 'background-card'`
|
|
8
|
+
|
|
9
|
+
## Used in
|
|
10
|
+
|
|
11
|
+
Accepted as a child of: `card-layout-block`, `slider-block`, `slider-old-block`.
|
|
12
|
+
|
|
13
|
+
## Example
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"type": "background-card",
|
|
18
|
+
"title": "Launch your product",
|
|
19
|
+
"text": "**Ut enim ad minim veniam** [quis nostrud](https://example.com) exercitation ullamco.",
|
|
20
|
+
"additionalInfo": "Duis aute irure dolor in reprehenderit.",
|
|
21
|
+
"background": {
|
|
22
|
+
"light": {"src": "/story-assets/img-bg_nopadding_4-12_light.png", "alt": "Background"},
|
|
23
|
+
"dark": {"src": "/story-assets/img-bg_nopadding_4-12_dark.png", "alt": "Background"}
|
|
24
|
+
},
|
|
25
|
+
"buttons": [
|
|
26
|
+
{"text": "Get started", "theme": "action", "url": "https://example.com"},
|
|
27
|
+
{"text": "Learn more", "theme": "outlined", "url": "https://example.com"}
|
|
28
|
+
],
|
|
29
|
+
"theme": "dark"
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Properties
|
|
34
|
+
|
|
35
|
+
| Property | Type | Default | Description |
|
|
36
|
+
| ------------------ | ------------------------------------------------- | ------------------- | ------------------------------------------------------------------------------------------------------ |
|
|
37
|
+
| `type` _required_ | `'background-card'` | — | Sub-block discriminator. |
|
|
38
|
+
| `when` | `string` | — | Conditional rendering expression. |
|
|
39
|
+
| `title` _required_ | `string \| TitleProps` | — | Card title (plain string or Title options). |
|
|
40
|
+
| `text` _required_ | `string` | — | Body text (YFM supported). |
|
|
41
|
+
| `additionalInfo` | `string` | — | Secondary gray text (YFM supported). |
|
|
42
|
+
| `size` | `'s' \| 'm' \| 'l' \| 'xl'` | `'s'` | Content size; controls font sizes. |
|
|
43
|
+
| `theme` | `'default' \| 'dark' \| 'light'` | `'default'` | Card content theme. When not `default`, or when `backgroundColor` is set, the card border is hidden. |
|
|
44
|
+
| `links` | `LinkProps[]` | — | Array of links. |
|
|
45
|
+
| `buttons` | `ButtonProps[]` | — | Array of buttons. |
|
|
46
|
+
| `list` | `ContentItem[]` | — | Array of icon-content items (each requires `icon` or `gravityIcon`). |
|
|
47
|
+
| `border` | `'line' \| 'shadow' \| 'none'` | — | Card border style. Overridden to `'none'` when `backgroundColor` is set or `theme` is not `default`. |
|
|
48
|
+
| `controlPosition` | `'content' \| 'footer'` | `'content'` | Position of buttons/links. `'footer'` only applies when `paddingBottom` is unset. |
|
|
49
|
+
| `colSizes` | `{all?, sm?, md?, lg?, xl?}` (each `number` 1–12) | `{all: 12, md: 12}` | Column width per breakpoint. |
|
|
50
|
+
| `url` | `string` | — | Wraps the whole card in a link. |
|
|
51
|
+
| `urlTitle` | `string` | — | `title` attribute for the card link. |
|
|
52
|
+
| `background` | `ImageObjectProps \| {light, dark}` | — | Decorative background image (themed). |
|
|
53
|
+
| `backgroundColor` | `string` | — | Solid background color (CSS value). Hides the border. |
|
|
54
|
+
| `paddingBottom` | `'s' \| 'm' \| 'l' \| 'xl'` | — | Adds bottom padding. When set, `controlPosition: 'footer'` is ignored. |
|
|
55
|
+
| `analyticsEvents` | `AnalyticsEvent \| AnalyticsEvent[]` | — | Analytics events fired on card interaction. |
|
|
56
|
+
|
|
57
|
+
## Themed values
|
|
58
|
+
|
|
59
|
+
`background` accepts either a plain value or a `{light, dark}` object resolved against the active runtime theme.
|
|
60
|
+
|
|
61
|
+
## Storybook
|
|
62
|
+
|
|
63
|
+
[BackgroundCard](https://preview.gravity-ui.com/page-constructor/?path=/docs/components-cards-backgroundcard--docs)
|