react-native-divkit 0.1.0-alpha.1 → 0.1.0-alpha.3

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 (150) hide show
  1. package/README.md +200 -201
  2. package/dist/DivKit.d.ts.map +1 -1
  3. package/dist/DivKit.js +24 -7
  4. package/dist/DivKit.js.map +1 -1
  5. package/dist/actions/array.d.ts.map +1 -1
  6. package/dist/actions/array.js +1 -1
  7. package/dist/actions/array.js.map +1 -1
  8. package/dist/actions/copyToClipboard.d.ts.map +1 -1
  9. package/dist/actions/copyToClipboard.js +2 -1
  10. package/dist/actions/copyToClipboard.js.map +1 -1
  11. package/dist/actions/dict.d.ts.map +1 -1
  12. package/dist/actions/dict.js.map +1 -1
  13. package/dist/actions/updateStructure.d.ts.map +1 -1
  14. package/dist/actions/updateStructure.js.map +1 -1
  15. package/dist/components/container/DivContainer.d.ts.map +1 -1
  16. package/dist/components/container/DivContainer.js +3 -5
  17. package/dist/components/container/DivContainer.js.map +1 -1
  18. package/dist/components/image/DivImage.d.ts.map +1 -1
  19. package/dist/components/image/DivImage.js +1 -6
  20. package/dist/components/image/DivImage.js.map +1 -1
  21. package/dist/components/state/DivState.d.ts.map +1 -1
  22. package/dist/components/state/DivState.js +3 -5
  23. package/dist/components/state/DivState.js.map +1 -1
  24. package/dist/components/text/DivText.d.ts.map +1 -1
  25. package/dist/components/text/DivText.js +4 -4
  26. package/dist/components/text/DivText.js.map +1 -1
  27. package/dist/components/utilities/Background.d.ts +11 -0
  28. package/dist/components/utilities/Background.d.ts.map +1 -0
  29. package/dist/components/utilities/Background.js +73 -0
  30. package/dist/components/utilities/Background.js.map +1 -0
  31. package/dist/components/utilities/Outer.d.ts.map +1 -1
  32. package/dist/components/utilities/Outer.js +24 -10
  33. package/dist/components/utilities/Outer.js.map +1 -1
  34. package/dist/context/index.d.ts.map +1 -1
  35. package/dist/context/index.js.map +1 -1
  36. package/dist/expressions/eval.d.ts.map +1 -1
  37. package/dist/expressions/eval.js +19 -11
  38. package/dist/expressions/eval.js.map +1 -1
  39. package/dist/expressions/funcs/array.d.ts.map +1 -1
  40. package/dist/expressions/funcs/array.js +72 -168
  41. package/dist/expressions/funcs/array.js.map +1 -1
  42. package/dist/expressions/funcs/colors.d.ts.map +1 -1
  43. package/dist/expressions/funcs/colors.js.map +1 -1
  44. package/dist/expressions/funcs/customFuncs.d.ts.map +1 -1
  45. package/dist/expressions/funcs/customFuncs.js +6 -4
  46. package/dist/expressions/funcs/customFuncs.js.map +1 -1
  47. package/dist/expressions/funcs/datetime.d.ts.map +1 -1
  48. package/dist/expressions/funcs/datetime.js +1 -1
  49. package/dist/expressions/funcs/datetime.js.map +1 -1
  50. package/dist/expressions/funcs/dict.d.ts.map +1 -1
  51. package/dist/expressions/funcs/dict.js.map +1 -1
  52. package/dist/expressions/funcs/funcs.d.ts.map +1 -1
  53. package/dist/expressions/funcs/funcs.js +21 -13
  54. package/dist/expressions/funcs/funcs.js.map +1 -1
  55. package/dist/expressions/funcs/math.d.ts.map +1 -1
  56. package/dist/expressions/funcs/math.js +40 -20
  57. package/dist/expressions/funcs/math.js.map +1 -1
  58. package/dist/expressions/funcs/std.d.ts.map +1 -1
  59. package/dist/expressions/funcs/std.js +4 -4
  60. package/dist/expressions/funcs/std.js.map +1 -1
  61. package/dist/expressions/funcs/strings.d.ts.map +1 -1
  62. package/dist/expressions/funcs/strings.js +1 -2
  63. package/dist/expressions/funcs/strings.js.map +1 -1
  64. package/dist/expressions/funcs/trigonometry.js +2 -2
  65. package/dist/expressions/funcs/trigonometry.js.map +1 -1
  66. package/dist/expressions/json.d.ts +2 -2
  67. package/dist/expressions/json.d.ts.map +1 -1
  68. package/dist/expressions/json.js +6 -4
  69. package/dist/expressions/json.js.map +1 -1
  70. package/dist/expressions/utils.d.ts.map +1 -1
  71. package/dist/expressions/utils.js +9 -10
  72. package/dist/expressions/utils.js.map +1 -1
  73. package/dist/expressions/variable.d.ts.map +1 -1
  74. package/dist/expressions/variable.js +3 -7
  75. package/dist/expressions/variable.js.map +1 -1
  76. package/dist/expressions/walk.d.ts.map +1 -1
  77. package/dist/expressions/walk.js.map +1 -1
  78. package/dist/hooks/index.d.ts.map +1 -1
  79. package/dist/hooks/index.js.map +1 -1
  80. package/dist/hooks/useAction.d.ts.map +1 -1
  81. package/dist/hooks/useAction.js.map +1 -1
  82. package/dist/hooks/useDerivedFromVars.d.ts.map +1 -1
  83. package/dist/hooks/useDerivedFromVars.js.map +1 -1
  84. package/dist/hooks/useVariable.d.ts.map +1 -1
  85. package/dist/hooks/useVariable.js +4 -4
  86. package/dist/hooks/useVariable.js.map +1 -1
  87. package/dist/index.d.ts.map +1 -1
  88. package/dist/index.js.map +1 -1
  89. package/dist/stores/createObservable.d.ts.map +1 -1
  90. package/dist/stores/createObservable.js.map +1 -1
  91. package/dist/utils/applyTemplate.d.ts +2 -2
  92. package/dist/utils/applyTemplate.d.ts.map +1 -1
  93. package/dist/utils/applyTemplate.js +13 -13
  94. package/dist/utils/applyTemplate.js.map +1 -1
  95. package/dist/utils/correctColor.d.ts.map +1 -1
  96. package/dist/utils/correctColor.js +8 -6
  97. package/dist/utils/correctColor.js.map +1 -1
  98. package/dist/utils/formatDate.d.ts.map +1 -1
  99. package/dist/utils/formatDate.js +7 -10
  100. package/dist/utils/formatDate.js.map +1 -1
  101. package/dist/utils/wrapError.d.ts.map +1 -1
  102. package/dist/utils/wrapError.js.map +1 -1
  103. package/package.json +8 -7
  104. package/src/DivKit.tsx +258 -220
  105. package/src/actions/array.ts +91 -64
  106. package/src/actions/copyToClipboard.ts +28 -19
  107. package/src/actions/dict.ts +36 -26
  108. package/src/actions/updateStructure.ts +86 -61
  109. package/src/components/README.md +38 -18
  110. package/src/components/container/DivContainer.tsx +4 -14
  111. package/src/components/image/DivImage.tsx +1 -11
  112. package/src/components/state/DivState.tsx +3 -9
  113. package/src/components/text/DivText.tsx +8 -20
  114. package/src/components/utilities/Background.tsx +120 -0
  115. package/src/components/utilities/Outer.tsx +24 -23
  116. package/src/components/utilities/README.md +37 -32
  117. package/src/context/index.ts +2 -11
  118. package/src/expressions/ast.d.ts +16 -9
  119. package/src/expressions/eval.ts +82 -37
  120. package/src/expressions/funcs/array.ts +129 -209
  121. package/src/expressions/funcs/colors.ts +1 -3
  122. package/src/expressions/funcs/customFuncs.ts +6 -4
  123. package/src/expressions/funcs/datetime.ts +10 -3
  124. package/src/expressions/funcs/dict.ts +16 -2
  125. package/src/expressions/funcs/funcs.ts +75 -89
  126. package/src/expressions/funcs/math.ts +103 -43
  127. package/src/expressions/funcs/std.ts +4 -7
  128. package/src/expressions/funcs/strings.ts +9 -25
  129. package/src/expressions/funcs/trigonometry.ts +2 -2
  130. package/src/expressions/json.ts +60 -53
  131. package/src/expressions/utils.ts +24 -22
  132. package/src/expressions/variable.ts +5 -21
  133. package/src/expressions/walk.ts +6 -3
  134. package/src/hooks/README.md +61 -53
  135. package/src/hooks/index.ts +3 -18
  136. package/src/hooks/useAction.ts +1 -3
  137. package/src/hooks/useDerivedFromVars.ts +3 -13
  138. package/src/hooks/useVariable.ts +7 -17
  139. package/src/index.ts +10 -48
  140. package/src/stores/createObservable.ts +35 -35
  141. package/src/types/alignment.d.ts +15 -6
  142. package/src/types/background.d.ts +6 -2
  143. package/src/types/base.d.ts +41 -9
  144. package/src/types/componentContext.d.ts +27 -22
  145. package/src/types/container.d.ts +1 -4
  146. package/src/types/text.d.ts +1 -1
  147. package/src/utils/applyTemplate.ts +103 -109
  148. package/src/utils/correctColor.ts +9 -8
  149. package/src/utils/formatDate.ts +175 -86
  150. package/src/utils/wrapError.ts +7 -4
package/README.md CHANGED
@@ -1,340 +1,339 @@
1
1
  # react-native-divkit
2
2
 
3
- DivKit renderer for React Native - Server-driven UI framework.
3
+ Рендерер DivKit для React Native фреймворк для Server-Driven UI.
4
4
 
5
5
  [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
6
6
  [![npm version](https://img.shields.io/npm/v/react-native-divkit.svg)](https://www.npmjs.com/package/react-native-divkit)
7
7
 
8
- ## Overview
8
+ ## Обзор
9
9
 
10
- DivKit is a server-driven UI framework that allows you to define UI layouts in JSON and render them natively. This React Native implementation is based on the [DivKit Web](../web/divkit/) implementation, reusing the expression engine and adapting components for React Native.
10
+ DivKit это фреймворк для построения UI на основе данных с сервера (Server-Driven UI), который позволяет описывать макеты в формате JSON и рендерить их нативно. Данная реализация для React Native основана на веб-версии DivKit, переиспользуя движок выражений и адаптируя компоненты под React Native.
11
11
 
12
- ## Status
12
+ ## Статус
13
13
 
14
- **MVP Version 0.1.0-alpha**
14
+ **MVP Версия 0.1.0-alpha**
15
15
 
16
- | Feature | Status |
17
- |---------|--------|
18
- | Text component | ✅ Complete |
19
- | Container component | Complete |
20
- | Image component | Complete |
21
- | State component | ✅ Complete |
22
- | Variable system | ✅ Complete |
23
- | Expression engine | ✅ Complete |
24
- | Action handlers | Complete |
25
- | Template resolution | Complete |
16
+ | Функция | Статус |
17
+ | ------------------- | ----------- |
18
+ | Текстовый компонент | ✅ Готово |
19
+ | Компонент контейнера|Готово |
20
+ | Компонент изображения|Готово |
21
+ | Компонент состояния | ✅ Готово |
22
+ | Система переменных | ✅ Готово |
23
+ | Движок выражений | ✅ Готово |
24
+ | Обработчики действий|Готово |
25
+ | Подстановка шаблонов|Готово |
26
26
 
27
- ## Installation
27
+ ## Скриншоты
28
+
29
+ <p>
30
+ <img src="screenshots/image1.png" width="200" alt="" />
31
+ <img src="screenshots/image3.png" width="200" alt="" />
32
+ <img src="screenshots/image4.png" width="200" alt="" />
33
+ <img src="screenshots/image8.png" width="200" alt="" />
34
+ </p>
35
+
36
+ ## Установка
28
37
 
29
38
  ```bash
30
39
  npm install react-native-divkit
31
40
  ```
32
41
 
33
- ### Optional Dependencies
42
+ ### Опциональные зависимости
34
43
 
35
- For enhanced functionality, install these optional packages:
44
+ Для расширенной функциональности установите следующие пакеты:
36
45
 
37
46
  ```bash
38
- # Optimized image loading with caching
47
+ # Оптимизированная загрузка изображений с кешированием
39
48
  npm install react-native-fast-image
40
49
 
41
- # Gradient support (backgrounds)
50
+ # Поддержка градиентов (фоны)
42
51
  npm install react-native-linear-gradient
43
52
 
44
- # Clipboard support
53
+ # Поддержка буфера обмена
45
54
  npm install @react-native-clipboard/clipboard
46
55
  ```
47
56
 
48
- ## Quick Start
57
+ ## Быстрый старт
49
58
 
50
59
  ```tsx
51
60
  import { DivKit } from 'react-native-divkit';
52
61
 
53
62
  const divKitJson = {
54
- card: {
55
- log_id: 'hello_world',
56
- states: [{
57
- state_id: 0,
58
- div: {
59
- type: 'text',
60
- text: 'Hello, @{name}!',
61
- font_size: 24,
62
- text_color: '#000000',
63
- text_alignment_horizontal: 'center'
64
- }
65
- }],
66
- variables: [{
67
- type: 'string',
68
- name: 'name',
69
- value: 'World'
70
- }]
71
- }
63
+ card: {
64
+ log_id: 'hello_world',
65
+ states: [
66
+ {
67
+ state_id: 0,
68
+ div: {
69
+ type: 'text',
70
+ text: 'Привет, @{name}!',
71
+ font_size: 24,
72
+ text_color: '#000000',
73
+ text_alignment_horizontal: 'center'
74
+ }
75
+ }
76
+ ],
77
+ variables: [
78
+ {
79
+ type: 'string',
80
+ name: 'name',
81
+ value: 'Мир'
82
+ }
83
+ ]
84
+ }
72
85
  };
73
86
 
74
87
  export default function App() {
75
- return (
76
- <DivKit
77
- data={divKitJson}
78
- onStat={(stat) => console.log('Stat:', stat.type, stat.action.log_id)}
79
- onCustomAction={(action) => console.log('Custom action:', action.url)}
80
- onError={(error) => console.error('Error:', error.message)}
81
- />
82
- );
88
+ return (
89
+ <DivKit
90
+ data={divKitJson}
91
+ onStat={stat => console.log('Статистика:', stat.type, stat.action.log_id)}
92
+ onCustomAction={action => console.log('Кастомное действие:', action.url)}
93
+ onError={error => console.error('Ошибка:', error.message)}
94
+ />
95
+ );
83
96
  }
84
97
  ```
85
98
 
86
- ## Components
99
+ ## Компоненты
87
100
 
88
- ### Text
101
+ ### Text (Текст)
89
102
 
90
103
  ```json
91
104
  {
92
- "type": "text",
93
- "text": "Hello World",
94
- "font_size": 16,
95
- "font_weight": "bold",
96
- "text_color": "#000000",
97
- "text_alignment_horizontal": "center",
98
- "max_lines": 2
105
+ "type": "text",
106
+ "text": "Привет, мир",
107
+ "font_size": 16,
108
+ "font_weight": "bold",
109
+ "text_color": "#000000",
110
+ "text_alignment_horizontal": "center",
111
+ "max_lines": 2
99
112
  }
100
113
  ```
101
114
 
102
- ### Container
115
+ ### Container (Контейнер)
103
116
 
104
117
  ```json
105
118
  {
106
- "type": "container",
107
- "orientation": "vertical",
108
- "items": [
109
- { "type": "text", "text": "Item 1" },
110
- { "type": "text", "text": "Item 2" }
111
- ],
112
- "content_alignment_horizontal": "center"
119
+ "type": "container",
120
+ "orientation": "vertical",
121
+ "items": [
122
+ { "type": "text", "text": "Элемент 1" },
123
+ { "type": "text", "text": "Элемент 2" }
124
+ ],
125
+ "content_alignment_horizontal": "center"
113
126
  }
114
127
  ```
115
128
 
116
- ### Image
129
+ ### Image (Изображение)
117
130
 
118
131
  ```json
119
132
  {
120
- "type": "image",
121
- "image_url": "https://example.com/image.png",
122
- "scale": "fill",
123
- "width": { "type": "fixed", "value": 200 },
124
- "height": { "type": "fixed", "value": 150 }
133
+ "type": "image",
134
+ "image_url": "https://example.com/image.png",
135
+ "scale": "fill",
136
+ "width": { "type": "fixed", "value": 200 },
137
+ "height": { "type": "fixed", "value": 150 }
125
138
  }
126
139
  ```
127
140
 
128
- ### State
141
+ ### State (Состояние)
129
142
 
130
143
  ```json
131
144
  {
132
- "type": "state",
133
- "id": "my_state",
134
- "default_state_id": "state1",
135
- "states": [
136
- {
137
- "state_id": "state1",
138
- "div": { "type": "text", "text": "State 1" }
139
- },
140
- {
141
- "state_id": "state2",
142
- "div": { "type": "text", "text": "State 2" }
143
- }
144
- ]
145
+ "type": "state",
146
+ "id": "my_state",
147
+ "default_state_id": "state1",
148
+ "states": [
149
+ {
150
+ "state_id": "state1",
151
+ "div": { "type": "text", "text": "Состояние 1" }
152
+ },
153
+ {
154
+ "state_id": "state2",
155
+ "div": { "type": "text", "text": "Состояние 2" }
156
+ }
157
+ ]
145
158
  }
146
159
  ```
147
160
 
148
- ## Variables
161
+ ## Переменные
149
162
 
150
- Define variables in your JSON:
163
+ Объявление переменных в JSON:
151
164
 
152
165
  ```json
153
166
  {
154
- "card": {
155
- "variables": [
156
- { "type": "string", "name": "userName", "value": "World" },
157
- { "type": "integer", "name": "counter", "value": 0 },
158
- { "type": "color", "name": "textColor", "value": "#FF0000" },
159
- { "type": "boolean", "name": "isActive", "value": true }
160
- ]
161
- }
167
+ "card": {
168
+ "variables": [
169
+ { "type": "string", "name": "userName", "value": "Мир" },
170
+ { "type": "integer", "name": "counter", "value": 0 },
171
+ { "type": "color", "name": "textColor", "value": "#FF0000" },
172
+ { "type": "boolean", "name": "isActive", "value": true }
173
+ ]
174
+ }
162
175
  }
163
176
  ```
164
177
 
165
- Use variables in expressions:
178
+ Использование переменных в выражениях:
166
179
 
167
180
  ```json
168
181
  {
169
- "type": "text",
170
- "text": "Hello, @{userName}!",
171
- "text_color": "@{textColor}"
182
+ "type": "text",
183
+ "text": "Привет, @{userName}!",
184
+ "text_color": "@{textColor}"
172
185
  }
173
186
  ```
174
187
 
175
- ### Variable Types
188
+ ### Типы переменных
176
189
 
177
- | Type | Description | Example |
178
- |------|-------------|---------|
179
- | `string` | Text value | `"Hello"` |
180
- | `integer` | Whole number | `42` |
181
- | `number` | Decimal number | `3.14` |
182
- | `boolean` | True/false | `true` |
183
- | `color` | Color value | `"#FF5500"` |
184
- | `url` | URL string | `"https://..."` |
185
- | `dict` | Key-value object | `{"key": "value"}` |
186
- | `array` | List of values | `[1, 2, 3]` |
190
+ | Тип | Описание | Пример |
191
+ | --------- | ---------------- | ------------------ |
192
+ | `string` | Текстовая строка | `"Hello"` |
193
+ | `integer` | Целое число | `42` |
194
+ | `number` | Дробное число | `3.14` |
195
+ | `boolean` | Логическое | `true` |
196
+ | `color` | Цвет | `"#FF5500"` |
197
+ | `url` | URL | `"https://..."` |
198
+ | `dict` | Словарь (объект) | `{"key": "value"}` |
199
+ | `array` | Список (массив) | `[1, 2, 3]` |
187
200
 
188
- ## Actions
201
+ ## Действия (Actions)
189
202
 
190
- Actions are triggered by user interaction:
203
+ Действия вызываются при взаимодействии с пользователем:
191
204
 
192
205
  ```json
193
206
  {
194
- "type": "text",
195
- "text": "Tap me",
196
- "actions": [{
197
- "log_id": "button_tap",
198
- "url": "divkit://custom_action"
199
- }]
207
+ "type": "text",
208
+ "text": "Нажми меня",
209
+ "actions": [
210
+ {
211
+ "log_id": "button_tap",
212
+ "url": "divkit://custom_action"
213
+ }
214
+ ]
200
215
  }
201
216
  ```
202
217
 
203
- ### Typed Actions
218
+ ### Типизированные действия
204
219
 
205
- #### set_variable
220
+ #### set_variable (установка переменной)
206
221
 
207
222
  ```json
208
223
  {
209
- "typed": {
210
- "type": "set_variable",
211
- "variable_name": "counter",
212
- "value": { "type": "integer", "value": 10 }
213
- }
224
+ "typed": {
225
+ "type": "set_variable",
226
+ "variable_name": "counter",
227
+ "value": { "type": "integer", "value": 10 }
228
+ }
214
229
  }
215
230
  ```
216
231
 
217
- #### set_state
232
+ #### set_state (смена состояния)
218
233
 
219
234
  ```json
220
235
  {
221
- "typed": {
222
- "type": "set_state",
223
- "state_id": "my_state",
224
- "temporary_state_id": "state2"
225
- }
236
+ "typed": {
237
+ "type": "set_state",
238
+ "state_id": "my_state",
239
+ "temporary_state_id": "state2"
240
+ }
226
241
  }
227
242
  ```
228
243
 
229
- ## Props
244
+ ## Свойства (Props)
230
245
 
231
- | Prop | Type | Required | Description |
232
- |------|------|----------|-------------|
233
- | `data` | `DivJson` | Yes | DivKit JSON data |
234
- | `onStat` | `(stat) => void` | No | Statistics callback |
235
- | `onCustomAction` | `(action) => void` | No | Custom action handler |
236
- | `onError` | `(error) => void` | No | Error handler |
237
- | `direction` | `'ltr' \| 'rtl'` | No | Text direction (default: `'ltr'`) |
238
- | `platform` | `'desktop' \| 'touch'` | No | Platform type (default: `'touch'`) |
239
- | `style` | `ViewStyle` | No | Container style |
246
+ | Свойство | Тип | Обязательно | Описание |
247
+ | ---------------- | ---------------------- | ----------- | ---------------------------------- |
248
+ | `data` | `DivJson` | Да | JSON-данные DivKit |
249
+ | `onStat` | `(stat) => void` | Нет | Колбэк статистики |
250
+ | `onCustomAction` | `(action) => void` | Нет | Обработчик кастомных действий |
251
+ | `onError` | `(error) => void` | Нет | Обработчик ошибок |
252
+ | `direction` | `'ltr' \| 'rtl'` | Нет | Направление текста (по умолч.: `'ltr'`) |
253
+ | `platform` | `'desktop' \| 'touch'` | Нет | Тип платформы (по умолч.: `'touch'`) |
254
+ | `style` | `ViewStyle` | Нет | Стили контейнера |
240
255
 
241
- ## Hooks
256
+ ## Хуки
242
257
 
243
- For advanced usage, you can use hooks directly:
258
+ Для продвинутого использования вы можете использовать хуки напрямую:
244
259
 
245
260
  ```tsx
246
- import {
247
- useDivKitContext,
248
- useVariable,
249
- useVariableState,
250
- useAction
251
- } from 'react-native-divkit';
261
+ import { useDivKitContext, useVariable, useVariableState, useAction } from 'react-native-divkit';
252
262
 
253
263
  function MyComponent() {
254
- const { setVariable } = useDivKitContext();
255
- const counter = useVariable('counter');
256
-
257
- return (
258
- <View>
259
- <Text>Count: {counter}</Text>
260
- <Button
261
- onPress={() => setVariable('counter', counter + 1)}
262
- title="Increment"
263
- />
264
- </View>
265
- );
264
+ const { setVariable } = useDivKitContext();
265
+ const counter = useVariable('counter');
266
+
267
+ return (
268
+ <View>
269
+ <Text>Счетчик: {counter}</Text>
270
+ <Button onPress={() => setVariable('counter', counter + 1)} title="Увеличить" />
271
+ </View>
272
+ );
266
273
  }
267
274
  ```
268
275
 
269
- ## Examples
276
+ ## Примеры
270
277
 
271
- See the [examples/BasicExample](examples/BasicExample/) directory for a complete React Native app demonstrating all features.
278
+ Смотрите директорию [examples/BasicExample](examples/BasicExample/) для готового React Native приложения, демонстрирующего все возможности.
272
279
 
273
280
  ```bash
274
281
  cd examples/BasicExample
275
282
  npm install
276
- npm run ios # or npm run android
283
+ npm run ios # или npm run android
277
284
  ```
278
285
 
279
- ## Documentation
286
+ ## Документация
280
287
 
281
- - [API Reference](docs/API.md) - Complete API documentation
282
- - [Migration Guide](docs/MIGRATION.md) - Migrating from Web version
283
- - [Architecture](docs/ARCHITECTURE.md) - Internal architecture
288
+ - [Справочник API](docs/API.md) - Полная документация API
289
+ - [Руководство по миграции](docs/MIGRATION.md) - Миграция с веб-версии
290
+ - [Архитектура](docs/ARCHITECTURE.md) - Внутренняя архитектура
284
291
 
285
- ## Not Included in MVP
292
+ ## Не включено в MVP
286
293
 
287
- The following features are planned for future versions:
294
+ Следующие функции запланированы для будущих версий:
288
295
 
289
- - Gallery, Pager, Slider, Tabs
290
- - Input, Select, Switch
291
- - Video, Lottie animations
292
- - Text ranges, complex gradients
293
- - Advanced transitions and animations
294
- - Custom components API
296
+ - Gallery (Галерея), Pager (Пейджер), Slider (Слайдер), Tabs (Вкладки)
297
+ - Input (Ввод), Select (Выбор), Switch (Переключатель)
298
+ - Видео, Lottie-анимации
299
+ - Диапазоны текста, сложные градиенты
300
+ - Продвинутые переходы и анимации
301
+ - API пользовательских компонентов
295
302
 
296
- ## Architecture
303
+ ## Архитектура
297
304
 
298
- This library is based on DivKit Web (TypeScript + Svelte):
305
+ Библиотека основана на DivKit Web (TypeScript + Svelte):
299
306
 
300
- | Component | Reuse |
301
- |-----------|-------|
302
- | Expression engine | 100% copied |
303
- | Type definitions | 100% copied |
304
- | Utilities | ~90% adapted |
305
- | Components | ~20% (rewritten for RN) |
306
- | Context system | New (React-specific) |
307
+ | Компонент | Переиспользование |
308
+ | ----------------- | ----------------------- |
309
+ | Движок выражений | 100% скопировано |
310
+ | Определения типов | 100% скопировано |
311
+ | Утилиты | ~90% адаптировано |
312
+ | Компоненты | ~20% (переписано под RN)|
313
+ | Система контекстов| Новая (специфично для React)|
307
314
 
308
- ## Development
315
+ ## Разработка
309
316
 
310
317
  ```bash
311
- # Install dependencies
318
+ # Установка зависимостей
312
319
  npm install
313
320
 
314
- # Build PEG parser
321
+ # Сборка парсера PEG
315
322
  npm run build:peggy
316
323
 
317
- # Type check
324
+ # Проверка типов
318
325
  npm run typecheck
319
326
 
320
- # Lint
327
+ # Линтинг
321
328
  npm run lint
322
329
 
323
- # Build
330
+ # Сборка
324
331
  npm run build
325
332
 
326
- # Test
333
+ # Тесты
327
334
  npm test
328
335
  ```
329
336
 
330
- ## Contributing
331
-
332
- 1. Fork the repository
333
- 2. Create a feature branch
334
- 3. Make your changes
335
- 4. Add tests
336
- 5. Submit a pull request
337
-
338
- ## License
337
+ ## Лицензия
339
338
 
340
339
  Apache 2.0
@@ -1 +1 @@
1
- {"version":3,"file":"DivKit.d.ts","sourceRoot":"","sources":["../src/DivKit.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAuC,MAAM,OAAO,CAAC;AAC5D,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAe,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAUjF,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAOjE;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAClB,KAAK,IAAI,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,CAAC;AAE9E;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,uBAAuB;IACvB,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAEvB,sCAAsC;IACtC,MAAM,CAAC,EAAE,YAAY,CAAC;IAEtB,kCAAkC;IAClC,cAAc,CAAC,EAAE,oBAAoB,CAAC;IAEtC,0BAA0B;IAC1B,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB,sCAAsC;IACtC,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;IAE/B,0CAA0C;IAC1C,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB,mCAAmC;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,EACnB,IAAI,EACJ,MAAM,EACN,cAAc,EACd,OAAO,EACP,SAAiB,EACjB,QAAkB,EAClB,KAAK,EACL,EAAW,EACd,EAAE,WAAW,qBAmbb"}
1
+ {"version":3,"file":"DivKit.d.ts","sourceRoot":"","sources":["../src/DivKit.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAuC,MAAM,OAAO,CAAC;AAC5D,OAAO,EAAoB,KAAK,SAAS,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,KAAK,EAAE,MAAM,EAAE,OAAO,EAAe,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAUjF,OAAO,EAAa,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAQjE;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,CAAC;AAE5E;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,CAAC;AAE9E;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,uBAAuB;IACvB,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAEvB,sCAAsC;IACtC,MAAM,CAAC,EAAE,YAAY,CAAC;IAEtB,kCAAkC;IAClC,cAAc,CAAC,EAAE,oBAAoB,CAAC;IAEtC,0BAA0B;IAC1B,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB,sCAAsC;IACtC,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;IAE/B,0CAA0C;IAC1C,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB,mCAAmC;IACnC,EAAE,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,EACnB,IAAI,EACJ,MAAM,EACN,cAAc,EACd,OAAO,EACP,SAAiB,EACjB,QAAkB,EAClB,KAAK,EACL,EAAW,EACd,EAAE,WAAW,qBA2db"}
package/dist/DivKit.js CHANGED
@@ -31,6 +31,7 @@ import { dictSetValue } from './actions/dict';
31
31
  import { copyToClipboard } from './actions/copyToClipboard';
32
32
  import { updateStructure } from './actions/updateStructure';
33
33
  import { evalExpression } from './expressions/eval';
34
+ import { parse } from './expressions/expressions';
34
35
  /**
35
36
  * DivKit - Main component
36
37
  *
@@ -158,12 +159,32 @@ export function DivKit({ data, onStat, onCustomAction, onError, direction = 'ltr
158
159
  const typedValue = typed.value;
159
160
  let value;
160
161
  // Convert typed value to raw value
161
- if (typeof typedValue === 'object' && typedValue !== null && 'value' in typedValue) {
162
+ if (typeof typedValue === 'object' &&
163
+ typedValue !== null &&
164
+ 'value' in typedValue) {
162
165
  value = typedValue.value;
163
166
  }
164
167
  else {
165
168
  value = typedValue;
166
169
  }
170
+ // Evaluate expression if value is a string with @{...}
171
+ if (typeof value === 'string' && value.includes('@{')) {
172
+ try {
173
+ const ast = parse(value, { startRule: 'JsonStringContents' });
174
+ const res = evalExpression(variables, undefined, undefined, ast);
175
+ if (res.result.type !== 'error') {
176
+ value = res.result.value;
177
+ }
178
+ }
179
+ catch (err) {
180
+ logError(wrapError(err, {
181
+ additional: {
182
+ phase: 'set_variable_expression',
183
+ expression: value
184
+ }
185
+ }));
186
+ }
187
+ }
167
188
  setVariable(typed.variable_name, value);
168
189
  }
169
190
  break;
@@ -321,9 +342,7 @@ export function DivKit({ data, onStat, onCustomAction, onError, direction = 'ltr
321
342
  return evalExpression(allVars, undefined, store, expr, opts);
322
343
  },
323
344
  produceChildContext: (div, opts) => {
324
- const childPath = opts?.path !== undefined
325
- ? [...context.path, String(opts.path)]
326
- : context.path;
345
+ const childPath = opts?.path !== undefined ? [...context.path, String(opts.path)] : context.path;
327
346
  const childContext = {
328
347
  ...context,
329
348
  path: childPath,
@@ -378,9 +397,7 @@ export function DivKit({ data, onStat, onCustomAction, onError, direction = 'ltr
378
397
  }, [rootDiv, variables, logError, execAnyActions, genId, id, stateContextValue]);
379
398
  // Render
380
399
  if (!rootDiv || !rootComponentContext) {
381
- return (<View style={[styles.container, style]}>
382
- {/* Empty state - could render error UI here */}
383
- </View>);
400
+ return <View style={[styles.container, style]}>{/* Empty state - could render error UI here */}</View>;
384
401
  }
385
402
  return (<DivKitContext.Provider value={divKitContextValue}>
386
403
  <ActionContext.Provider value={actionContextValue}>