react-native-divkit 0.1.0-alpha.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 (322) hide show
  1. package/LICENSE +176 -0
  2. package/README.md +340 -0
  3. package/dist/DivKit.d.ts +68 -0
  4. package/dist/DivKit.d.ts.map +1 -0
  5. package/dist/DivKit.js +400 -0
  6. package/dist/DivKit.js.map +1 -0
  7. package/dist/actions/array.d.ts +8 -0
  8. package/dist/actions/array.d.ts.map +1 -0
  9. package/dist/actions/array.js +139 -0
  10. package/dist/actions/array.js.map +1 -0
  11. package/dist/actions/copyToClipboard.d.ts +22 -0
  12. package/dist/actions/copyToClipboard.d.ts.map +1 -0
  13. package/dist/actions/copyToClipboard.js +63 -0
  14. package/dist/actions/copyToClipboard.js.map +1 -0
  15. package/dist/actions/dict.d.ts +6 -0
  16. package/dist/actions/dict.d.ts.map +1 -0
  17. package/dist/actions/dict.js +58 -0
  18. package/dist/actions/dict.js.map +1 -0
  19. package/dist/actions/index.d.ts +11 -0
  20. package/dist/actions/index.d.ts.map +1 -0
  21. package/dist/actions/index.js +11 -0
  22. package/dist/actions/index.js.map +1 -0
  23. package/dist/actions/updateStructure.d.ts +6 -0
  24. package/dist/actions/updateStructure.d.ts.map +1 -0
  25. package/dist/actions/updateStructure.js +116 -0
  26. package/dist/actions/updateStructure.js.map +1 -0
  27. package/dist/components/DivComponent.d.ts +29 -0
  28. package/dist/components/DivComponent.d.ts.map +1 -0
  29. package/dist/components/DivComponent.js +62 -0
  30. package/dist/components/DivComponent.js.map +1 -0
  31. package/dist/components/container/DivContainer.d.ts +26 -0
  32. package/dist/components/container/DivContainer.d.ts.map +1 -0
  33. package/dist/components/container/DivContainer.js +172 -0
  34. package/dist/components/container/DivContainer.js.map +1 -0
  35. package/dist/components/container/index.d.ts +3 -0
  36. package/dist/components/container/index.d.ts.map +1 -0
  37. package/dist/components/container/index.js +2 -0
  38. package/dist/components/container/index.js.map +1 -0
  39. package/dist/components/image/DivImage.d.ts +29 -0
  40. package/dist/components/image/DivImage.d.ts.map +1 -0
  41. package/dist/components/image/DivImage.js +122 -0
  42. package/dist/components/image/DivImage.js.map +1 -0
  43. package/dist/components/image/index.d.ts +3 -0
  44. package/dist/components/image/index.d.ts.map +1 -0
  45. package/dist/components/image/index.js +2 -0
  46. package/dist/components/image/index.js.map +1 -0
  47. package/dist/components/index.d.ts +14 -0
  48. package/dist/components/index.d.ts.map +1 -0
  49. package/dist/components/index.js +11 -0
  50. package/dist/components/index.js.map +1 -0
  51. package/dist/components/state/DivState.d.ts +26 -0
  52. package/dist/components/state/DivState.d.ts.map +1 -0
  53. package/dist/components/state/DivState.js +121 -0
  54. package/dist/components/state/DivState.js.map +1 -0
  55. package/dist/components/state/index.d.ts +3 -0
  56. package/dist/components/state/index.d.ts.map +1 -0
  57. package/dist/components/state/index.js +2 -0
  58. package/dist/components/state/index.js.map +1 -0
  59. package/dist/components/text/DivText.d.ts +28 -0
  60. package/dist/components/text/DivText.d.ts.map +1 -0
  61. package/dist/components/text/DivText.js +143 -0
  62. package/dist/components/text/DivText.js.map +1 -0
  63. package/dist/components/text/index.d.ts +3 -0
  64. package/dist/components/text/index.d.ts.map +1 -0
  65. package/dist/components/text/index.js +2 -0
  66. package/dist/components/text/index.js.map +1 -0
  67. package/dist/components/utilities/Outer.d.ts +17 -0
  68. package/dist/components/utilities/Outer.d.ts.map +1 -0
  69. package/dist/components/utilities/Outer.js +210 -0
  70. package/dist/components/utilities/Outer.js.map +1 -0
  71. package/dist/components/utilities/Unknown.d.ts +11 -0
  72. package/dist/components/utilities/Unknown.d.ts.map +1 -0
  73. package/dist/components/utilities/Unknown.js +50 -0
  74. package/dist/components/utilities/Unknown.js.map +1 -0
  75. package/dist/components/utilities/index.d.ts +5 -0
  76. package/dist/components/utilities/index.d.ts.map +1 -0
  77. package/dist/components/utilities/index.js +3 -0
  78. package/dist/components/utilities/index.js.map +1 -0
  79. package/dist/context/ActionContext.d.ts +25 -0
  80. package/dist/context/ActionContext.d.ts.map +1 -0
  81. package/dist/context/ActionContext.js +20 -0
  82. package/dist/context/ActionContext.js.map +1 -0
  83. package/dist/context/DivKitContext.d.ts +33 -0
  84. package/dist/context/DivKitContext.d.ts.map +1 -0
  85. package/dist/context/DivKitContext.js +14 -0
  86. package/dist/context/DivKitContext.js.map +1 -0
  87. package/dist/context/EnabledContext.d.ts +31 -0
  88. package/dist/context/EnabledContext.d.ts.map +1 -0
  89. package/dist/context/EnabledContext.js +31 -0
  90. package/dist/context/EnabledContext.js.map +1 -0
  91. package/dist/context/StateContext.d.ts +57 -0
  92. package/dist/context/StateContext.d.ts.map +1 -0
  93. package/dist/context/StateContext.js +20 -0
  94. package/dist/context/StateContext.js.map +1 -0
  95. package/dist/context/index.d.ts +9 -0
  96. package/dist/context/index.d.ts.map +1 -0
  97. package/dist/context/index.js +9 -0
  98. package/dist/context/index.js.map +1 -0
  99. package/dist/expressions/bigint.d.ts +8 -0
  100. package/dist/expressions/bigint.d.ts.map +1 -0
  101. package/dist/expressions/bigint.js +31 -0
  102. package/dist/expressions/bigint.js.map +1 -0
  103. package/dist/expressions/const.d.ts +15 -0
  104. package/dist/expressions/const.d.ts.map +1 -0
  105. package/dist/expressions/const.js +15 -0
  106. package/dist/expressions/const.js.map +1 -0
  107. package/dist/expressions/eval.d.ts +77 -0
  108. package/dist/expressions/eval.d.ts.map +1 -0
  109. package/dist/expressions/eval.js +459 -0
  110. package/dist/expressions/eval.js.map +1 -0
  111. package/dist/expressions/expressions.d.ts +7 -0
  112. package/dist/expressions/expressions.d.ts.map +1 -0
  113. package/dist/expressions/expressions.js +3191 -0
  114. package/dist/expressions/expressions.js.map +1 -0
  115. package/dist/expressions/funcs/array.d.ts +2 -0
  116. package/dist/expressions/funcs/array.d.ts.map +1 -0
  117. package/dist/expressions/funcs/array.js +381 -0
  118. package/dist/expressions/funcs/array.js.map +1 -0
  119. package/dist/expressions/funcs/colors.d.ts +2 -0
  120. package/dist/expressions/funcs/colors.d.ts.map +1 -0
  121. package/dist/expressions/funcs/colors.js +75 -0
  122. package/dist/expressions/funcs/colors.js.map +1 -0
  123. package/dist/expressions/funcs/customFuncs.d.ts +8 -0
  124. package/dist/expressions/funcs/customFuncs.d.ts.map +1 -0
  125. package/dist/expressions/funcs/customFuncs.js +114 -0
  126. package/dist/expressions/funcs/customFuncs.js.map +1 -0
  127. package/dist/expressions/funcs/datetime.d.ts +2 -0
  128. package/dist/expressions/funcs/datetime.d.ts.map +1 -0
  129. package/dist/expressions/funcs/datetime.js +182 -0
  130. package/dist/expressions/funcs/datetime.js.map +1 -0
  131. package/dist/expressions/funcs/dict.d.ts +2 -0
  132. package/dist/expressions/funcs/dict.d.ts.map +1 -0
  133. package/dist/expressions/funcs/dict.js +170 -0
  134. package/dist/expressions/funcs/dict.js.map +1 -0
  135. package/dist/expressions/funcs/funcs.d.ts +80 -0
  136. package/dist/expressions/funcs/funcs.d.ts.map +1 -0
  137. package/dist/expressions/funcs/funcs.js +146 -0
  138. package/dist/expressions/funcs/funcs.js.map +1 -0
  139. package/dist/expressions/funcs/index.d.ts +2 -0
  140. package/dist/expressions/funcs/index.d.ts.map +1 -0
  141. package/dist/expressions/funcs/index.js +23 -0
  142. package/dist/expressions/funcs/index.js.map +1 -0
  143. package/dist/expressions/funcs/interval.d.ts +2 -0
  144. package/dist/expressions/funcs/interval.d.ts.map +1 -0
  145. package/dist/expressions/funcs/interval.js +61 -0
  146. package/dist/expressions/funcs/interval.js.map +1 -0
  147. package/dist/expressions/funcs/math.d.ts +2 -0
  148. package/dist/expressions/funcs/math.d.ts.map +1 -0
  149. package/dist/expressions/funcs/math.js +324 -0
  150. package/dist/expressions/funcs/math.js.map +1 -0
  151. package/dist/expressions/funcs/std.d.ts +2 -0
  152. package/dist/expressions/funcs/std.d.ts.map +1 -0
  153. package/dist/expressions/funcs/std.js +293 -0
  154. package/dist/expressions/funcs/std.js.map +1 -0
  155. package/dist/expressions/funcs/stored.d.ts +4 -0
  156. package/dist/expressions/funcs/stored.d.ts.map +1 -0
  157. package/dist/expressions/funcs/stored.js +62 -0
  158. package/dist/expressions/funcs/stored.js.map +1 -0
  159. package/dist/expressions/funcs/strings.d.ts +2 -0
  160. package/dist/expressions/funcs/strings.d.ts.map +1 -0
  161. package/dist/expressions/funcs/strings.js +158 -0
  162. package/dist/expressions/funcs/strings.js.map +1 -0
  163. package/dist/expressions/funcs/trigonometry.d.ts +2 -0
  164. package/dist/expressions/funcs/trigonometry.d.ts.map +1 -0
  165. package/dist/expressions/funcs/trigonometry.js +92 -0
  166. package/dist/expressions/funcs/trigonometry.js.map +1 -0
  167. package/dist/expressions/json.d.ts +18 -0
  168. package/dist/expressions/json.d.ts.map +1 -0
  169. package/dist/expressions/json.js +271 -0
  170. package/dist/expressions/json.js.map +1 -0
  171. package/dist/expressions/parserCache.d.ts +4 -0
  172. package/dist/expressions/parserCache.d.ts.map +1 -0
  173. package/dist/expressions/parserCache.js +23 -0
  174. package/dist/expressions/parserCache.js.map +1 -0
  175. package/dist/expressions/simpleUnescapeString.d.ts +2 -0
  176. package/dist/expressions/simpleUnescapeString.d.ts.map +1 -0
  177. package/dist/expressions/simpleUnescapeString.js +61 -0
  178. package/dist/expressions/simpleUnescapeString.js.map +1 -0
  179. package/dist/expressions/utils.d.ts +29 -0
  180. package/dist/expressions/utils.d.ts.map +1 -0
  181. package/dist/expressions/utils.js +236 -0
  182. package/dist/expressions/utils.js.map +1 -0
  183. package/dist/expressions/variable.d.ts +82 -0
  184. package/dist/expressions/variable.d.ts.map +1 -0
  185. package/dist/expressions/variable.js +337 -0
  186. package/dist/expressions/variable.js.map +1 -0
  187. package/dist/expressions/walk.d.ts +7 -0
  188. package/dist/expressions/walk.d.ts.map +1 -0
  189. package/dist/expressions/walk.js +39 -0
  190. package/dist/expressions/walk.js.map +1 -0
  191. package/dist/hooks/index.d.ts +8 -0
  192. package/dist/hooks/index.d.ts.map +1 -0
  193. package/dist/hooks/index.js +11 -0
  194. package/dist/hooks/index.js.map +1 -0
  195. package/dist/hooks/useAction.d.ts +102 -0
  196. package/dist/hooks/useAction.d.ts.map +1 -0
  197. package/dist/hooks/useAction.js +116 -0
  198. package/dist/hooks/useAction.js.map +1 -0
  199. package/dist/hooks/useDerivedFromVars.d.ts +72 -0
  200. package/dist/hooks/useDerivedFromVars.d.ts.map +1 -0
  201. package/dist/hooks/useDerivedFromVars.js +100 -0
  202. package/dist/hooks/useDerivedFromVars.js.map +1 -0
  203. package/dist/hooks/useVariable.d.ts +86 -0
  204. package/dist/hooks/useVariable.d.ts.map +1 -0
  205. package/dist/hooks/useVariable.js +130 -0
  206. package/dist/hooks/useVariable.js.map +1 -0
  207. package/dist/index.d.ts +30 -0
  208. package/dist/index.d.ts.map +1 -0
  209. package/dist/index.js +28 -0
  210. package/dist/index.js.map +1 -0
  211. package/dist/stores/createObservable.d.ts +38 -0
  212. package/dist/stores/createObservable.d.ts.map +1 -0
  213. package/dist/stores/createObservable.js +49 -0
  214. package/dist/stores/createObservable.js.map +1 -0
  215. package/dist/utils/applyTemplate.d.ts +8 -0
  216. package/dist/utils/applyTemplate.d.ts.map +1 -0
  217. package/dist/utils/applyTemplate.js +94 -0
  218. package/dist/utils/applyTemplate.js.map +1 -0
  219. package/dist/utils/correctColor.d.ts +18 -0
  220. package/dist/utils/correctColor.d.ts.map +1 -0
  221. package/dist/utils/correctColor.js +79 -0
  222. package/dist/utils/correctColor.js.map +1 -0
  223. package/dist/utils/escapeRegExp.d.ts +2 -0
  224. package/dist/utils/escapeRegExp.d.ts.map +1 -0
  225. package/dist/utils/escapeRegExp.js +4 -0
  226. package/dist/utils/escapeRegExp.js.map +1 -0
  227. package/dist/utils/formatDate.d.ts +6 -0
  228. package/dist/utils/formatDate.d.ts.map +1 -0
  229. package/dist/utils/formatDate.js +325 -0
  230. package/dist/utils/formatDate.js.map +1 -0
  231. package/dist/utils/padLeft.d.ts +2 -0
  232. package/dist/utils/padLeft.d.ts.map +1 -0
  233. package/dist/utils/padLeft.js +7 -0
  234. package/dist/utils/padLeft.js.map +1 -0
  235. package/dist/utils/uniq.d.ts +2 -0
  236. package/dist/utils/uniq.d.ts.map +1 -0
  237. package/dist/utils/uniq.js +4 -0
  238. package/dist/utils/uniq.js.map +1 -0
  239. package/dist/utils/wrapError.d.ts +10 -0
  240. package/dist/utils/wrapError.d.ts.map +1 -0
  241. package/dist/utils/wrapError.js +9 -0
  242. package/dist/utils/wrapError.js.map +1 -0
  243. package/package.json +58 -0
  244. package/src/DivKit.tsx +542 -0
  245. package/src/actions/array.ts +170 -0
  246. package/src/actions/copyToClipboard.ts +82 -0
  247. package/src/actions/dict.ts +71 -0
  248. package/src/actions/index.ts +11 -0
  249. package/src/actions/updateStructure.ts +134 -0
  250. package/src/components/DivComponent.tsx +75 -0
  251. package/src/components/README.md +230 -0
  252. package/src/components/container/DivContainer.tsx +222 -0
  253. package/src/components/container/index.ts +2 -0
  254. package/src/components/image/DivImage.tsx +172 -0
  255. package/src/components/image/index.ts +2 -0
  256. package/src/components/index.ts +20 -0
  257. package/src/components/state/DivState.tsx +146 -0
  258. package/src/components/state/index.ts +2 -0
  259. package/src/components/text/DivText.tsx +186 -0
  260. package/src/components/text/index.ts +2 -0
  261. package/src/components/utilities/Outer.tsx +239 -0
  262. package/src/components/utilities/README.md +175 -0
  263. package/src/components/utilities/Unknown.tsx +60 -0
  264. package/src/components/utilities/index.ts +4 -0
  265. package/src/context/ActionContext.tsx +37 -0
  266. package/src/context/DivKitContext.tsx +54 -0
  267. package/src/context/EnabledContext.tsx +50 -0
  268. package/src/context/StateContext.tsx +75 -0
  269. package/src/context/index.ts +33 -0
  270. package/src/expressions/ast.d.ts +101 -0
  271. package/src/expressions/bigint.ts +38 -0
  272. package/src/expressions/const.ts +16 -0
  273. package/src/expressions/eval.ts +669 -0
  274. package/src/expressions/expressions.peggy +235 -0
  275. package/src/expressions/expressions.ts +2854 -0
  276. package/src/expressions/funcs/array.ts +412 -0
  277. package/src/expressions/funcs/colors.ts +100 -0
  278. package/src/expressions/funcs/customFuncs.ts +139 -0
  279. package/src/expressions/funcs/datetime.ts +232 -0
  280. package/src/expressions/funcs/dict.ts +207 -0
  281. package/src/expressions/funcs/funcs.ts +323 -0
  282. package/src/expressions/funcs/index.ts +23 -0
  283. package/src/expressions/funcs/interval.ts +76 -0
  284. package/src/expressions/funcs/math.ts +395 -0
  285. package/src/expressions/funcs/std.ts +392 -0
  286. package/src/expressions/funcs/stored.ts +62 -0
  287. package/src/expressions/funcs/strings.ts +200 -0
  288. package/src/expressions/funcs/trigonometry.ts +108 -0
  289. package/src/expressions/json.ts +367 -0
  290. package/src/expressions/parserCache.ts +32 -0
  291. package/src/expressions/simpleUnescapeString.ts +57 -0
  292. package/src/expressions/utils.ts +271 -0
  293. package/src/expressions/variable.ts +429 -0
  294. package/src/expressions/walk.ts +43 -0
  295. package/src/hooks/README.md +265 -0
  296. package/src/hooks/index.ts +28 -0
  297. package/src/hooks/useAction.ts +152 -0
  298. package/src/hooks/useDerivedFromVars.ts +187 -0
  299. package/src/hooks/useVariable.ts +157 -0
  300. package/src/index.ts +97 -0
  301. package/src/stores/createObservable.ts +64 -0
  302. package/src/types/alignment.d.ts +13 -0
  303. package/src/types/background.d.ts +71 -0
  304. package/src/types/base.d.ts +224 -0
  305. package/src/types/border.d.ts +46 -0
  306. package/src/types/componentContext.d.ts +98 -0
  307. package/src/types/container.d.ts +40 -0
  308. package/src/types/edgeInserts.d.ts +9 -0
  309. package/src/types/general.d.ts +3 -0
  310. package/src/types/image.d.ts +33 -0
  311. package/src/types/imageScale.d.ts +1 -0
  312. package/src/types/layoutParams.d.ts +27 -0
  313. package/src/types/sizes.d.ts +37 -0
  314. package/src/types/state.d.ts +19 -0
  315. package/src/types/text.d.ts +126 -0
  316. package/src/utils/applyTemplate.ts +145 -0
  317. package/src/utils/correctColor.ts +102 -0
  318. package/src/utils/escapeRegExp.ts +3 -0
  319. package/src/utils/formatDate.ts +385 -0
  320. package/src/utils/padLeft.ts +6 -0
  321. package/src/utils/uniq.ts +3 -0
  322. package/src/utils/wrapError.ts +21 -0
@@ -0,0 +1,175 @@
1
+ # Utility Components
2
+
3
+ Base utility components for DivKit React Native library.
4
+
5
+ ## Components
6
+
7
+ ### Outer
8
+
9
+ Base wrapper component for all DivKit components. Handles common properties like visibility, sizing, padding, margins, background, borders, and actions.
10
+
11
+ **Features:**
12
+ - ✅ Visibility handling (`gone`, `invisible`, `visible`)
13
+ - ✅ Width/Height sizing (`fixed`, `match_parent`, `wrap_content`)
14
+ - ✅ Padding and margins (with RTL support)
15
+ - ✅ Opacity/alpha
16
+ - ✅ Background (solid colors for MVP)
17
+ - ✅ Borders (width, color, style, radius)
18
+ - ✅ Shadows
19
+ - ✅ Actions (tap handlers)
20
+ - ✅ Reactive variable binding
21
+
22
+ **Usage:**
23
+
24
+ ```tsx
25
+ import { Outer } from './components/utilities';
26
+
27
+ function MyComponent({ componentContext }) {
28
+ return (
29
+ <Outer componentContext={componentContext}>
30
+ <Text>Content goes here</Text>
31
+ </Outer>
32
+ );
33
+ }
34
+ ```
35
+
36
+ **Props:**
37
+
38
+ - `componentContext: ComponentContext` - Component context with JSON and variables
39
+ - `children: ReactNode` - Child components to render
40
+ - `style?: ViewStyle` - Additional custom styles
41
+
42
+ **Visibility Behavior:**
43
+
44
+ - `gone` - Component returns `null` (removed from layout)
45
+ - `invisible` - Component rendered with `opacity: 0` (takes space but not visible)
46
+ - `visible` - Component rendered normally
47
+
48
+ **Sizing:**
49
+
50
+ - `fixed` - Explicit size in dp
51
+ - `match_parent` - Fills parent container (100% width/height)
52
+ - `wrap_content` - Wraps content size (default React Native behavior)
53
+
54
+ **Actions:**
55
+
56
+ If the component has `actions` defined in JSON, Outer automatically wraps children in `Pressable` for tap handling.
57
+
58
+ **RTL Support:**
59
+
60
+ Padding and margins respect `direction` from DivKitContext:
61
+ - `start`/`end` → automatically mapped to `left`/`right` based on direction
62
+ - Supports both LTR and RTL layouts
63
+
64
+ ---
65
+
66
+ ### Unknown
67
+
68
+ Fallback component for unsupported component types. Renders a placeholder in DEV mode and nothing in production.
69
+
70
+ **Usage:**
71
+
72
+ ```tsx
73
+ import { Unknown } from './components/utilities';
74
+
75
+ function ComponentResolver({ type }) {
76
+ switch (type) {
77
+ case 'text':
78
+ return <DivText />;
79
+ case 'container':
80
+ return <DivContainer />;
81
+ default:
82
+ return <Unknown type={type} message="Not implemented yet" />;
83
+ }
84
+ }
85
+ ```
86
+
87
+ **Props:**
88
+
89
+ - `type: string` - Component type that is unknown
90
+ - `message?: string` - Optional error message
91
+
92
+ **Behavior:**
93
+
94
+ - **DEV mode**: Renders yellow warning box with component type
95
+ - **Production**: Returns `null` (renders nothing)
96
+ - Logs warning to console in DEV mode
97
+
98
+ ---
99
+
100
+ ## Implementation Notes
101
+
102
+ ### MVP Scope
103
+
104
+ The current implementation is MVP-focused and includes only essential features:
105
+
106
+ **Included:**
107
+ - Basic sizing and layout
108
+ - Solid color backgrounds
109
+ - Simple borders and shadows
110
+ - Basic action handling
111
+
112
+ **Deferred (Post-MVP):**
113
+ - Complex backgrounds (images, gradients)
114
+ - Advanced animations and transitions
115
+ - Extensions
116
+ - Custom focus handling
117
+ - Transform/transformations
118
+ - Visibility actions
119
+ - Layout provider
120
+
121
+ ### Performance
122
+
123
+ - Uses `useMemo` for style computation to minimize re-renders
124
+ - Reactive variables are tracked via `useDerivedFromVarsSimple`
125
+ - Conditional rendering based on visibility for optimal performance
126
+
127
+ ### Future Enhancements
128
+
129
+ 1. **Advanced Backgrounds** - Add support for images, gradients, nine-patch
130
+ 2. **Animations** - Implement action animations and transitions
131
+ 3. **Focus** - Add keyboard focus and custom focus styles
132
+ 4. **Accessibility** - Enhanced accessibility support
133
+ 5. **Extensions** - Plugin system for custom behaviors
134
+ 6. **Layout Provider** - Width/height variable tracking
135
+
136
+ ---
137
+
138
+ ## Related Files
139
+
140
+ - [Outer.tsx](./Outer.tsx) - Main wrapper component
141
+ - [Unknown.tsx](./Unknown.tsx) - Fallback component
142
+ - [Web Outer.svelte](../../../web/divkit/src/components/utilities/Outer.svelte) - Reference implementation
143
+
144
+ ---
145
+
146
+ ## Testing
147
+
148
+ Test Outer component behavior:
149
+
150
+ ```tsx
151
+ import { render } from '@testing-library/react-native';
152
+ import { Outer } from './Outer';
153
+
154
+ it('renders children when visible', () => {
155
+ const { getByText } = render(
156
+ <Outer componentContext={mockContext}>
157
+ <Text>Test</Text>
158
+ </Outer>
159
+ );
160
+ expect(getByText('Test')).toBeTruthy();
161
+ });
162
+
163
+ it('returns null when visibility is gone', () => {
164
+ const context = {
165
+ ...mockContext,
166
+ json: { ...mockContext.json, visibility: 'gone' }
167
+ };
168
+ const { queryByText } = render(
169
+ <Outer componentContext={context}>
170
+ <Text>Test</Text>
171
+ </Outer>
172
+ );
173
+ expect(queryByText('Test')).toBeNull();
174
+ });
175
+ ```
@@ -0,0 +1,60 @@
1
+ import React from 'react';
2
+ import { View, Text, StyleSheet } from 'react-native';
3
+
4
+ export interface UnknownProps {
5
+ type: string;
6
+ message?: string;
7
+ }
8
+
9
+ /**
10
+ * Unknown component - fallback for unsupported component types
11
+ * Renders a placeholder with error message
12
+ */
13
+ export function Unknown({ type, message }: UnknownProps) {
14
+ if (__DEV__) {
15
+ console.warn(`[DivKit] Unknown component type: "${type}"${message ? ` - ${message}` : ''}`);
16
+ }
17
+
18
+ // Only show visual error in DEV mode
19
+ if (__DEV__) {
20
+ return (
21
+ <View style={styles.container}>
22
+ <Text style={styles.title}>Unknown Component</Text>
23
+ <Text style={styles.type}>Type: {type}</Text>
24
+ {message && <Text style={styles.message}>{message}</Text>}
25
+ </View>
26
+ );
27
+ }
28
+
29
+ // In production, render nothing
30
+ return null;
31
+ }
32
+
33
+ const styles = StyleSheet.create({
34
+ container: {
35
+ padding: 16,
36
+ margin: 8,
37
+ backgroundColor: '#fff3cd',
38
+ borderWidth: 1,
39
+ borderColor: '#ffc107',
40
+ borderRadius: 4,
41
+ borderStyle: 'dashed'
42
+ },
43
+ title: {
44
+ fontSize: 14,
45
+ fontWeight: 'bold',
46
+ color: '#856404',
47
+ marginBottom: 4
48
+ },
49
+ type: {
50
+ fontSize: 12,
51
+ color: '#856404',
52
+ fontFamily: 'monospace'
53
+ },
54
+ message: {
55
+ fontSize: 11,
56
+ color: '#856404',
57
+ marginTop: 4,
58
+ fontStyle: 'italic'
59
+ }
60
+ });
@@ -0,0 +1,4 @@
1
+ export { Outer } from './Outer';
2
+ export type { OuterProps } from './Outer';
3
+ export { Unknown } from './Unknown';
4
+ export type { UnknownProps } from './Unknown';
@@ -0,0 +1,37 @@
1
+ import { createContext, useContext } from 'react';
2
+
3
+ /**
4
+ * Action context interface
5
+ * Based on ActionCtxValue from Web implementation
6
+ *
7
+ * This context is used to track whether a component or its parent has actions.
8
+ * It's useful for optimizing rendering and event handling.
9
+ */
10
+ export interface ActionContextValue {
11
+ /**
12
+ * Check if the current component or any parent has actions
13
+ * @returns true if actions are present
14
+ */
15
+ hasAction(): boolean;
16
+ }
17
+
18
+ export const ActionContext = createContext<ActionContextValue | null>(null);
19
+
20
+ /**
21
+ * Hook to access ActionContext
22
+ * Throws an error if used outside of ActionContext.Provider
23
+ */
24
+ export function useActionContext(): ActionContextValue {
25
+ const context = useContext(ActionContext);
26
+ if (!context) {
27
+ throw new Error('useActionContext must be used within ActionContext.Provider');
28
+ }
29
+ return context;
30
+ }
31
+
32
+ /**
33
+ * Hook to safely access ActionContext (returns null if not available)
34
+ */
35
+ export function useActionContextOptional(): ActionContextValue | null {
36
+ return useContext(ActionContext);
37
+ }
@@ -0,0 +1,54 @@
1
+ import { createContext, useContext } from 'react';
2
+ import type { Action, Direction } from '../../typings/common';
3
+ import type { MaybeMissing } from '../expressions/json';
4
+ import type { Variable } from '../expressions/variable';
5
+ import type { ComponentContext } from '../types/componentContext';
6
+
7
+ /**
8
+ * Main DivKit context interface
9
+ * Based on RootCtxValue from Web implementation with simplifications for MVP
10
+ */
11
+ export interface DivKitContextValue {
12
+ // Logging & callbacks
13
+ logStat(type: string, action: MaybeMissing<Action>): void;
14
+ execCustomAction(action: Action & { url: string }): void;
15
+
16
+ // Configuration
17
+ direction: Direction;
18
+ platform: 'desktop' | 'touch';
19
+
20
+ // Variable system
21
+ variables: Map<string, Variable>;
22
+ getVariable(name: string): Variable | undefined;
23
+ setVariable(name: string, value: unknown): void;
24
+
25
+ // Component registration (simplified for MVP)
26
+ registerComponent(id: string, context: ComponentContext): void;
27
+ unregisterComponent(id: string): void;
28
+
29
+ // Action execution
30
+ execAnyActions(
31
+ actions: MaybeMissing<Action[]> | undefined,
32
+ opts?: {
33
+ componentContext?: ComponentContext;
34
+ processUrls?: boolean;
35
+ }
36
+ ): Promise<void>;
37
+
38
+ // ID generation (for unique component IDs)
39
+ genId(key: string): string;
40
+ }
41
+
42
+ export const DivKitContext = createContext<DivKitContextValue | null>(null);
43
+
44
+ /**
45
+ * Hook to access DivKitContext
46
+ * Throws an error if used outside of DivKitContext.Provider
47
+ */
48
+ export function useDivKitContext(): DivKitContextValue {
49
+ const context = useContext(DivKitContext);
50
+ if (!context) {
51
+ throw new Error('useDivKitContext must be used within DivKitContext.Provider');
52
+ }
53
+ return context;
54
+ }
@@ -0,0 +1,50 @@
1
+ import { createContext, useContext } from 'react';
2
+ import type { Observable } from '../stores/createObservable';
3
+
4
+ /**
5
+ * Enabled context interface
6
+ * Based on EnabledCtxValue from Web implementation
7
+ *
8
+ * This context tracks whether the current component is enabled.
9
+ * Used for cascading enabled/disabled state down the component tree.
10
+ */
11
+ export interface EnabledContextValue {
12
+ /**
13
+ * Observable that tracks whether the component is enabled
14
+ * Subscribers will be notified when the enabled state changes
15
+ */
16
+ isEnabled: Observable<boolean>;
17
+ }
18
+
19
+ export const EnabledContext = createContext<EnabledContextValue | null>(null);
20
+
21
+ /**
22
+ * Hook to access EnabledContext
23
+ * Throws an error if used outside of EnabledContext.Provider
24
+ */
25
+ export function useEnabledContext(): EnabledContextValue {
26
+ const context = useContext(EnabledContext);
27
+ if (!context) {
28
+ throw new Error('useEnabledContext must be used within EnabledContext.Provider');
29
+ }
30
+ return context;
31
+ }
32
+
33
+ /**
34
+ * Hook to safely access EnabledContext (returns null if not available)
35
+ */
36
+ export function useEnabledContextOptional(): EnabledContextValue | null {
37
+ return useContext(EnabledContext);
38
+ }
39
+
40
+ /**
41
+ * Hook to get the current enabled state value
42
+ * Returns true if no EnabledContext is available (enabled by default)
43
+ */
44
+ export function useIsEnabled(): boolean {
45
+ const context = useEnabledContextOptional();
46
+ if (!context) {
47
+ return true; // Enabled by default if no context
48
+ }
49
+ return context.isEnabled.get();
50
+ }
@@ -0,0 +1,75 @@
1
+ import { createContext, useContext } from 'react';
2
+
3
+ /**
4
+ * State setter function type
5
+ * Takes a state ID and returns a promise that resolves when the state is changed
6
+ */
7
+ export type StateSetter = (stateId: string) => Promise<void>;
8
+
9
+ /**
10
+ * State context interface
11
+ * Based on StateCtxValue from Web implementation, simplified for MVP
12
+ *
13
+ * This context manages state transitions for div-state components.
14
+ * In the MVP version, complex transitions are deferred.
15
+ */
16
+ export interface StateContextValue {
17
+ /**
18
+ * Register a state component
19
+ * @param id - Component ID
20
+ * @param setState - Function to change the state
21
+ * @returns Unregister function
22
+ */
23
+ registerState(id: string, setState: StateSetter): () => void;
24
+
25
+ /**
26
+ * Switch to a specific state by ID
27
+ * @param stateId - The state ID to switch to
28
+ */
29
+ switchState(stateId: string): Promise<void>;
30
+
31
+ /**
32
+ * Get state setter by component ID
33
+ * @param id - Component ID
34
+ * @returns State setter function or undefined
35
+ */
36
+ getStateSetter(id: string): StateSetter | undefined;
37
+
38
+ /**
39
+ * Register a child component (for tracking purposes)
40
+ * Simplified for MVP - full transition support deferred
41
+ */
42
+ registerChild(id: string): void;
43
+
44
+ /**
45
+ * Unregister a child component
46
+ */
47
+ unregisterChild(id: string): void;
48
+
49
+ /**
50
+ * Check if there's a transition change for a component
51
+ * MVP: Always returns false (transitions deferred)
52
+ */
53
+ hasTransitionChange(id?: string): boolean;
54
+ }
55
+
56
+ export const StateContext = createContext<StateContextValue | null>(null);
57
+
58
+ /**
59
+ * Hook to access StateContext
60
+ * Throws an error if used outside of StateContext.Provider
61
+ */
62
+ export function useStateContext(): StateContextValue {
63
+ const context = useContext(StateContext);
64
+ if (!context) {
65
+ throw new Error('useStateContext must be used within StateContext.Provider');
66
+ }
67
+ return context;
68
+ }
69
+
70
+ /**
71
+ * Hook to safely access StateContext (returns null if not available)
72
+ */
73
+ export function useStateContextOptional(): StateContextValue | null {
74
+ return useContext(StateContext);
75
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Context exports for React Native DivKit
3
+ * Phase 2: Context System
4
+ */
5
+
6
+ export {
7
+ DivKitContext,
8
+ useDivKitContext,
9
+ type DivKitContextValue
10
+ } from './DivKitContext';
11
+
12
+ export {
13
+ ActionContext,
14
+ useActionContext,
15
+ useActionContextOptional,
16
+ type ActionContextValue
17
+ } from './ActionContext';
18
+
19
+ export {
20
+ StateContext,
21
+ useStateContext,
22
+ useStateContextOptional,
23
+ type StateContextValue,
24
+ type StateSetter
25
+ } from './StateContext';
26
+
27
+ export {
28
+ EnabledContext,
29
+ useEnabledContext,
30
+ useEnabledContextOptional,
31
+ useIsEnabled,
32
+ type EnabledContextValue
33
+ } from './EnabledContext';
@@ -0,0 +1,101 @@
1
+ export type Node = BinaryExpression | LogicalExpression |
2
+ UnaryExpression |
3
+ StringLiteral | NumberLiteral | IntegerLiteral | BooleanLiteral |
4
+ TemplateLiteral |
5
+ ConditionalExpression | TryExpression |
6
+ CallExpression | MethodExpression |
7
+ Variable;
8
+
9
+ export type UnaryOperator = '!' | '+' | '-';
10
+
11
+ export type EqualityOperator = '==' | '!=';
12
+
13
+ export type CompareOperator = '>' | '>=' | '<' | '<=';
14
+
15
+ export type SumOperator = '+' | '-';
16
+
17
+ export type FactorOperator = '/' | '*' | '%';
18
+
19
+ export type LogicalOperator = '&&' | '||';
20
+
21
+ export interface BinaryExpression {
22
+ type: 'BinaryExpression',
23
+ operator: EqualityOperator | CompareOperator | SumOperator | FactorOperator;
24
+ left: Node;
25
+ right: Node;
26
+ }
27
+
28
+ export interface LogicalExpression {
29
+ type: 'LogicalExpression',
30
+ operator: LogicalOperator;
31
+ left: Node;
32
+ right: Node;
33
+ }
34
+
35
+ export interface StringLiteral {
36
+ type: 'StringLiteral';
37
+ value: string;
38
+ }
39
+
40
+ export interface TemplateLiteral {
41
+ type: 'TemplateLiteral';
42
+ quasis: StringLiteral[];
43
+ expressions: Node[];
44
+ }
45
+
46
+ export interface NumberLiteral {
47
+ type: 'NumberLiteral';
48
+ value: number;
49
+ }
50
+
51
+ export interface IntegerLiteral {
52
+ type: 'IntegerLiteral';
53
+ value: bigint;
54
+ }
55
+
56
+ export interface BooleanLiteral {
57
+ type: 'BooleanLiteral';
58
+ value: boolean;
59
+ }
60
+
61
+ export interface ConditionalExpression {
62
+ type: 'ConditionalExpression';
63
+ test: Node;
64
+ consequent: Node;
65
+ alternate: Node;
66
+ }
67
+
68
+ export interface TryExpression {
69
+ type: 'TryExpression';
70
+ test: Node;
71
+ alternate: Node;
72
+ }
73
+
74
+ export interface Identifier {
75
+ type: 'Identifier';
76
+ name: string;
77
+ }
78
+
79
+ export interface Variable {
80
+ type: 'Variable';
81
+ id: Identifier;
82
+ }
83
+
84
+ export interface UnaryExpression {
85
+ type: 'UnaryExpression';
86
+ operator: UnaryOperator;
87
+ argument: Node;
88
+ }
89
+
90
+ export interface CallExpression {
91
+ type: 'CallExpression';
92
+ callee: Identifier;
93
+ arguments: Node[];
94
+ }
95
+
96
+ export interface MethodExpression {
97
+ type: 'MethodExpression';
98
+ object: Node;
99
+ method: Identifier;
100
+ arguments: Node[];
101
+ }
@@ -0,0 +1,38 @@
1
+ export function toBigIntNoCheck(val: number | bigint | string): bigint {
2
+ return BigInt(val);
3
+ }
4
+
5
+ export const MAX_INT = toBigIntNoCheck('9223372036854775807');
6
+ export const MIN_INT = toBigIntNoCheck('-9223372036854775808');
7
+
8
+ export function toBigInt(val: number | bigint | string): bigint {
9
+ const res = toBigIntNoCheck(val);
10
+ if (res > MAX_INT || res < MIN_INT) {
11
+ throw new Error('Integer overflow.');
12
+ }
13
+ return res;
14
+ }
15
+
16
+ export const bigIntZero = toBigInt(0);
17
+
18
+ export function absBigInt(val: bigint): bigint {
19
+ let res = val;
20
+
21
+ if (res < 0) {
22
+ res = -res;
23
+ }
24
+
25
+ return res;
26
+ }
27
+
28
+ export function signBigInt(val: bigint): bigint {
29
+ let res = 0;
30
+
31
+ if (val > 0) {
32
+ res = 1;
33
+ } else if (val < 0) {
34
+ res = -1;
35
+ }
36
+
37
+ return toBigInt(res);
38
+ }
@@ -0,0 +1,16 @@
1
+ export const MAX_INT32 = 2147483647;
2
+ export const MIN_INT32 = -2147483648;
3
+
4
+ export const MAX_NUMBER = Number.MAX_VALUE;
5
+ export const MIN_NUMBER = Number.MIN_VALUE;
6
+
7
+ export const STRING = 'string';
8
+ export const INTEGER = 'integer';
9
+ export const NUMBER = 'number';
10
+ export const BOOLEAN = 'boolean';
11
+ export const COLOR = 'color';
12
+ export const URL = 'url';
13
+ export const DATETIME = 'datetime';
14
+ export const DICT = 'dict';
15
+ export const ARRAY = 'array';
16
+ export const FUNCTION = 'function';