@mediacubeco/expo-template-fsd 2.3.1 → 2.4.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.
Files changed (333) hide show
  1. package/.claude/commands/git-commit.md +164 -0
  2. package/.claude/rules/architecture.md +38 -0
  3. package/.claude/rules/{prettier-eslint-typescript.mdc → prettier-eslint-typescript.md} +5 -10
  4. package/.claude/settings.json +2 -2
  5. package/.claude/skills/api/SKILL.md +362 -0
  6. package/.claude/skills/api/references/client/overview.md +106 -0
  7. package/.claude/skills/api/references/hooks/index.ts +3 -0
  8. package/.claude/skills/api/references/hooks/use-api-health.ts +25 -0
  9. package/.claude/skills/api/references/hooks/use-api-post.ts +46 -0
  10. package/.claude/skills/api/references/hooks/use-api-posts.ts +24 -0
  11. package/.claude/skills/api/references/mock/post.mock.ts +29 -0
  12. package/.claude/skills/{generate-api-model/references → api/references/model}/entities/common.ts +5 -2
  13. package/.claude/skills/api/references/model/resources/common.ts +9 -0
  14. package/.claude/skills/api/references/queries/health.ts +14 -0
  15. package/.claude/skills/api/references/queries/index.ts +2 -0
  16. package/.claude/skills/api/references/queries/post.ts +23 -0
  17. package/.claude/skills/api/references/repository/health/health.ts +11 -0
  18. package/.claude/skills/api/references/repository/health/health.types.ts +25 -0
  19. package/.claude/skills/api/references/repository/health/index.ts +2 -0
  20. package/.claude/skills/api/references/repository/post/index.ts +9 -0
  21. package/.claude/skills/api/references/repository/post/post.ts +34 -0
  22. package/.claude/skills/api/references/repository/post/post.types.ts +61 -0
  23. package/.claude/skills/code-style/SKILL.md +1025 -1
  24. package/.claude/skills/code-style/references/components/payout-speed-option/index.ts +2 -0
  25. package/.claude/skills/code-style/references/components/payout-speed-option/payout-speed-option.styles.ts +76 -0
  26. package/.claude/skills/code-style/references/components/payout-speed-option/payout-speed-option.tsx +58 -0
  27. package/.claude/skills/code-style/references/components/payout-speed-option/payout-speed-option.types.ts +22 -0
  28. package/.claude/skills/code-style/references/components/post/index.ts +2 -0
  29. package/.claude/skills/code-style/references/components/post/post.styles.ts +19 -0
  30. package/.claude/skills/code-style/references/components/post/post.tsx +21 -0
  31. package/.claude/skills/code-style/references/components/post/post.types.ts +9 -0
  32. package/.claude/skills/code-style/references/components/wrap/index.ts +2 -0
  33. package/.claude/skills/code-style/references/components/wrap/wrap.styles.ts +15 -0
  34. package/.claude/skills/code-style/references/components/wrap/wrap.tsx +31 -0
  35. package/.claude/skills/code-style/references/components/wrap/wrap.types.ts +10 -0
  36. package/.claude/skills/code-style/references/hooks/use-posts.ts +37 -0
  37. package/.claude/skills/code-style/references/pages/post/index.ts +4 -0
  38. package/.claude/skills/code-style/references/pages/post/post-details/index.ts +1 -0
  39. package/.claude/skills/code-style/references/pages/post/post-details/post-details.tsx +13 -0
  40. package/.claude/skills/code-style/references/pages/post/post-guide/index.ts +1 -0
  41. package/.claude/skills/code-style/references/pages/post/post-guide/post-guide.tsx +17 -0
  42. package/.claude/skills/code-style/references/pages/post/post-list/index.ts +1 -0
  43. package/.claude/skills/code-style/references/pages/post/post-list/post-list.styles.ts +17 -0
  44. package/.claude/skills/code-style/references/pages/post/post-list/post-list.tsx +25 -0
  45. package/.claude/skills/code-style/references/pages/post/post-share/index.ts +1 -0
  46. package/.claude/skills/code-style/references/pages/post/post-share/post-share.tsx +13 -0
  47. package/.claude/skills/code-style/references/routes/(stack)/_layout.tsx +18 -0
  48. package/.claude/skills/code-style/references/routes/(stack)/details.tsx +8 -0
  49. package/.claude/skills/code-style/references/routes/(stack)/guide.tsx +8 -0
  50. package/.claude/skills/code-style/references/routes/(stack)/index.tsx +8 -0
  51. package/.claude/skills/code-style/references/routes/(stack)/share.tsx +8 -0
  52. package/.claude/skills/code-style/references/routes/(tabs)/(post-details)/index.tsx +8 -0
  53. package/.claude/skills/code-style/references/routes/(tabs)/(post-list)/index.tsx +8 -0
  54. package/.claude/skills/code-style/references/routes/(tabs)/_layout.tsx +50 -0
  55. package/.claude/skills/code-style/references/routes/_app.tsx +20 -0
  56. package/.claude/skills/code-style/references/routes/guide.tsx +8 -0
  57. package/.claude/skills/code-style/references/routes/share.tsx +8 -0
  58. package/.claude/skills/code-style/references/store/use-post-draft-store.ts +62 -0
  59. package/.claude/skills/design-style/SKILL.md +320 -0
  60. package/.env +3 -1
  61. package/.env.example +3 -1
  62. package/CLAUDE.md +5 -11
  63. package/app.json +6 -3
  64. package/axios.d.ts +5 -0
  65. package/env.d.ts +3 -1
  66. package/package.json +33 -40
  67. package/patches/react-native-screens+4.25.2.patch +118 -0
  68. package/react-query.d.ts +13 -0
  69. package/src/app/(root)/(home)/_layout.tsx +2 -2
  70. package/src/app/(root)/(home)/index.tsx +2 -2
  71. package/src/app/(root)/(settings)/_layout.tsx +2 -2
  72. package/src/app/(root)/(settings)/index.tsx +2 -2
  73. package/src/app/(root)/_layout.tsx +35 -32
  74. package/src/pages/home/home-main.tsx +3 -7
  75. package/src/pages/settings/settings-main.tsx +3 -7
  76. package/src/shared/assets/fonts/index.ts +3 -3
  77. package/src/shared/assets/fonts/sf-pro-text-bold.ttf +0 -0
  78. package/src/shared/assets/fonts/sf-pro-text-regular.ttf +0 -0
  79. package/src/shared/assets/fonts/sf-pro-text-semibold.ttf +0 -0
  80. package/src/shared/assets/icons/back.tsx +21 -0
  81. package/src/shared/assets/icons/close.tsx +21 -0
  82. package/src/shared/assets/icons/common.ts +8 -0
  83. package/src/shared/assets/icons/default.tsx +44 -0
  84. package/src/shared/assets/icons/index.ts +13 -1
  85. package/src/shared/assets/icons/refresh.tsx +23 -0
  86. package/src/shared/assets/icons/share.tsx +38 -0
  87. package/src/shared/assets/icons/type.ts +7 -0
  88. package/src/shared/assets/translations/index.ts +4 -4
  89. package/src/shared/constants/config.ts +13 -0
  90. package/src/shared/constants/environment.ts +16 -4
  91. package/src/shared/constants/index.ts +1 -0
  92. package/src/shared/hooks/index.ts +1 -4
  93. package/src/shared/hooks/use-compose.ts +23 -0
  94. package/src/shared/lib/api/api.client.ts +157 -0
  95. package/src/shared/lib/api/api.provider.tsx +14 -36
  96. package/src/shared/lib/api/api.ts +1 -5
  97. package/src/shared/lib/api/api.types.ts +6 -3
  98. package/src/shared/lib/api/hooks/index.ts +1 -0
  99. package/src/shared/lib/api/index.ts +2 -3
  100. package/src/shared/lib/api/models/api-instance/api-instance.client.ts +50 -0
  101. package/src/shared/lib/api/models/api-instance/api-instance.ts +30 -82
  102. package/src/shared/lib/api/models/api-instance/api-instance.types.ts +16 -18
  103. package/src/shared/lib/api/models/api-instance/api-instance.utils.ts +13 -20
  104. package/src/shared/lib/api/models/api-instance/index.ts +3 -0
  105. package/src/shared/lib/api/queries/index.ts +1 -0
  106. package/src/shared/lib/api/repositories/index.ts +1 -1
  107. package/src/shared/lib/localization/constants/index.ts +16 -5
  108. package/src/shared/lib/localization/index.ts +5 -1
  109. package/src/shared/lib/navigation/hooks/index.ts +8 -3
  110. package/src/shared/{hooks/use-breakpoints.ts → lib/navigation/hooks/use-navigation-breakpoints.ts} +2 -5
  111. package/src/shared/lib/navigation/hooks/use-navigation-dimensions.ts +12 -0
  112. package/src/shared/lib/navigation/hooks/use-navigation-options.tsx +175 -0
  113. package/src/shared/lib/navigation/hooks/{use-navigation.ts → use-navigation-route.ts} +2 -2
  114. package/src/shared/lib/navigation/hooks/use-navigation-safe-area.ts +61 -0
  115. package/src/shared/lib/navigation/hooks/use-navigation-tabs-native.ts +10 -0
  116. package/src/shared/lib/navigation/hooks/use-navigation-tabs.tsx +10 -0
  117. package/src/shared/lib/navigation/hooks/use-navigation-transition.ts +27 -0
  118. package/src/shared/lib/navigation/index.ts +11 -4
  119. package/src/shared/lib/navigation/navigation-tabs-native.context.tsx +5 -0
  120. package/src/shared/lib/navigation/navigation-tabs-native.provider.tsx +17 -0
  121. package/src/shared/lib/navigation/navigation-tabs.context.tsx +10 -0
  122. package/src/shared/lib/navigation/navigation-tabs.provider.tsx +22 -0
  123. package/src/shared/lib/navigation/navigation.provider.tsx +6 -1
  124. package/src/shared/lib/storage/index.ts +1 -1
  125. package/src/shared/lib/storage/storage.provider.tsx +4 -0
  126. package/src/shared/lib/storage/storage.ts +29 -25
  127. package/src/shared/lib/theme/constants/animations.ts +26 -0
  128. package/src/shared/lib/theme/constants/colors.ts +336 -43
  129. package/src/shared/lib/theme/constants/delays.ts +1 -1
  130. package/src/shared/lib/theme/constants/durations.ts +1 -1
  131. package/src/shared/lib/theme/constants/fonts.ts +2 -1
  132. package/src/shared/lib/theme/constants/index.ts +42 -20
  133. package/src/shared/lib/theme/constants/shadows.ts +7 -25
  134. package/src/shared/lib/theme/constants/sizes.ts +11 -2
  135. package/src/shared/lib/theme/constants/transparencies.ts +1 -1
  136. package/src/shared/lib/theme/hooks/use-theme-setup.ts +3 -1
  137. package/src/shared/lib/theme/index.ts +10 -1
  138. package/src/shared/lib/theme/theme.provider.tsx +45 -19
  139. package/src/shared/lib/theme/theme.scope.tsx +43 -0
  140. package/src/shared/lib/theme/theme.types.ts +15 -3
  141. package/src/shared/lib/theme/utils/color.ts +81 -0
  142. package/src/shared/lib/theme/utils/index.ts +2 -0
  143. package/src/shared/lib/theme/utils/snapshot.ts +17 -0
  144. package/src/shared/lib/theme/utils/storage.ts +5 -2
  145. package/src/shared/services/browser/browser.ts +66 -0
  146. package/src/shared/services/browser/index.ts +1 -0
  147. package/src/shared/services/cookies/cookies.ts +73 -0
  148. package/src/shared/services/cookies/index.ts +1 -0
  149. package/src/shared/services/index.ts +5 -0
  150. package/src/shared/services/linking/index.ts +1 -0
  151. package/src/shared/services/linking/linking.ts +22 -0
  152. package/src/shared/services/share/index.ts +1 -0
  153. package/src/shared/services/share/share.ts +28 -0
  154. package/src/shared/services/universal-links/index.ts +104 -0
  155. package/src/shared/services/universal-links/universal-links.ts +25 -0
  156. package/src/shared/services/universal-links/universal-links.types.ts +5 -0
  157. package/src/shared/ui/atoms/blur/blur.tsx +9 -4
  158. package/src/shared/ui/atoms/blur/blur.types.ts +1 -1
  159. package/src/shared/ui/atoms/blur-progress/blur-progress.styles.ts +16 -0
  160. package/src/shared/ui/atoms/blur-progress/blur-progress.tsx +30 -0
  161. package/src/shared/ui/atoms/blur-progress/blur-progress.types.tsx +5 -0
  162. package/src/shared/ui/atoms/blur-progress/index.ts +1 -0
  163. package/src/shared/ui/atoms/glass/glass.tsx +13 -5
  164. package/src/shared/ui/atoms/glass/glass.types.ts +1 -1
  165. package/src/shared/ui/atoms/icon/icon.styles.ts +82 -0
  166. package/src/shared/ui/atoms/icon/icon.tsx +21 -0
  167. package/src/shared/ui/atoms/icon/icon.types.ts +23 -0
  168. package/src/shared/ui/atoms/icon/index.ts +2 -0
  169. package/src/shared/ui/atoms/index.ts +7 -0
  170. package/src/shared/ui/atoms/skeleton/index.ts +2 -0
  171. package/src/shared/ui/atoms/skeleton/skeleton.styles.ts +69 -0
  172. package/src/shared/ui/atoms/skeleton/skeleton.tsx +26 -0
  173. package/src/shared/ui/atoms/skeleton/skeleton.types.ts +9 -0
  174. package/src/shared/ui/atoms/spinner/index.ts +2 -0
  175. package/src/shared/ui/atoms/spinner/spinner.styles.ts +102 -0
  176. package/src/shared/ui/atoms/spinner/spinner.tsx +48 -0
  177. package/src/shared/ui/atoms/spinner/spinner.types.ts +25 -0
  178. package/src/shared/ui/atoms/text/index.ts +2 -0
  179. package/src/shared/ui/atoms/text/text.styles.ts +186 -0
  180. package/src/shared/ui/atoms/text/text.tsx +37 -0
  181. package/src/shared/ui/atoms/text/text.types.ts +35 -0
  182. package/src/shared/ui/atoms/touch/components/haptics/haptics.styles.ts +21 -0
  183. package/src/shared/ui/atoms/touch/components/haptics/haptics.tsx +28 -0
  184. package/src/shared/ui/atoms/touch/components/haptics/haptics.types.ts +17 -0
  185. package/src/shared/ui/atoms/touch/components/haptics/index.ts +2 -0
  186. package/src/shared/ui/atoms/touch/components/index.ts +3 -0
  187. package/src/shared/ui/atoms/touch/components/ripple/index.ts +2 -0
  188. package/src/shared/ui/atoms/touch/components/ripple/ripple.styles.ts +78 -0
  189. package/src/shared/ui/atoms/touch/components/ripple/ripple.tsx +29 -0
  190. package/src/shared/ui/atoms/touch/components/ripple/ripple.types.ts +17 -0
  191. package/src/shared/ui/atoms/touch/components/spring/index.ts +2 -0
  192. package/src/shared/ui/atoms/touch/components/spring/spring.styles.ts +31 -0
  193. package/src/shared/ui/atoms/touch/components/spring/spring.tsx +28 -0
  194. package/src/shared/ui/atoms/touch/components/spring/spring.types.ts +17 -0
  195. package/src/shared/ui/atoms/touch/index.ts +2 -0
  196. package/src/shared/ui/atoms/touch/touch.styles.ts +14 -0
  197. package/src/shared/ui/atoms/touch/touch.tsx +137 -0
  198. package/src/shared/ui/atoms/touch/touch.types.ts +27 -0
  199. package/src/shared/ui/atoms/visibility/index.ts +2 -0
  200. package/src/shared/ui/atoms/visibility/visibility.styles.ts +85 -0
  201. package/src/shared/ui/atoms/visibility/visibility.tsx +61 -0
  202. package/src/shared/ui/atoms/visibility/visibility.types.ts +34 -0
  203. package/src/shared/ui/molecules/keyboard-area/keyboard-area.styles.ts +11 -9
  204. package/src/shared/ui/molecules/keyboard-area/keyboard-area.tsx +3 -6
  205. package/src/shared/ui/molecules/refresh-control/refresh-control.tsx +3 -5
  206. package/src/shared/ui/molecules/refresh-control/refresh-control.types.ts +1 -1
  207. package/src/shared/ui/molecules/slider/components/indicator/components/dot/dot.styles.ts +41 -0
  208. package/src/shared/ui/molecules/slider/components/indicator/components/dot/dot.tsx +12 -0
  209. package/src/shared/ui/molecules/slider/components/indicator/components/dot/dot.types.ts +13 -0
  210. package/src/shared/ui/molecules/slider/components/indicator/components/dot/index.ts +2 -0
  211. package/src/shared/ui/molecules/slider/components/indicator/index.ts +2 -0
  212. package/src/shared/ui/molecules/slider/components/indicator/indicator.styles.ts +20 -0
  213. package/src/shared/ui/molecules/slider/components/indicator/indicator.tsx +22 -0
  214. package/src/shared/ui/molecules/slider/components/indicator/indicator.types.ts +10 -0
  215. package/src/shared/ui/molecules/slider/index.ts +3 -0
  216. package/src/shared/ui/molecules/slider/slider.styles.ts +68 -0
  217. package/src/shared/ui/molecules/slider/slider.tsx +64 -0
  218. package/src/shared/ui/molecules/slider/slider.types.ts +28 -0
  219. package/src/shared/ui/organisms/bar/bar.styles.ts +100 -0
  220. package/src/shared/ui/organisms/bar/bar.tsx +89 -0
  221. package/src/shared/ui/organisms/bar/bar.types.ts +49 -0
  222. package/src/shared/ui/organisms/bar/index.ts +2 -0
  223. package/src/shared/ui/organisms/bar-tab/bar-tab.tsx +9 -0
  224. package/src/shared/ui/organisms/bar-tab/bar-tab.types.ts +5 -0
  225. package/src/shared/ui/organisms/bar-tab/components/index.ts +1 -0
  226. package/src/shared/ui/organisms/bar-tab/components/tab/index.ts +2 -0
  227. package/src/shared/ui/organisms/bar-tab/components/tab/tab.styles.ts +21 -0
  228. package/src/shared/ui/organisms/bar-tab/components/tab/tab.tsx +18 -0
  229. package/src/shared/ui/organisms/bar-tab/components/tab/tab.types.ts +5 -0
  230. package/src/shared/ui/organisms/bar-tab/index.ts +2 -0
  231. package/src/shared/ui/organisms/bar-tab-navigation/bar-tab-navigation.styles.ts +22 -0
  232. package/src/shared/ui/organisms/bar-tab-navigation/bar-tab-navigation.tsx +66 -0
  233. package/src/shared/ui/organisms/bar-tab-navigation/bar-tab-navigation.types.ts +5 -0
  234. package/src/shared/ui/organisms/bar-tab-navigation/components/index.ts +1 -0
  235. package/src/shared/ui/organisms/bar-tab-navigation/components/tab-navigation/index.ts +2 -0
  236. package/src/shared/ui/organisms/bar-tab-navigation/components/tab-navigation/tab-navigation.styles.ts +56 -0
  237. package/src/shared/ui/organisms/bar-tab-navigation/components/tab-navigation/tab-navigation.tsx +30 -0
  238. package/src/shared/ui/organisms/bar-tab-navigation/components/tab-navigation/tab-navigation.types.ts +7 -0
  239. package/src/shared/ui/organisms/bar-tab-navigation/index.ts +2 -0
  240. package/src/shared/ui/organisms/index.ts +4 -1
  241. package/src/shared/ui/organisms/slider/components/indicator/components/dot/dot.styles.ts +41 -0
  242. package/src/shared/ui/organisms/slider/components/indicator/components/dot/dot.tsx +12 -0
  243. package/src/shared/ui/organisms/slider/components/indicator/components/dot/dot.types.ts +13 -0
  244. package/src/shared/ui/organisms/slider/components/indicator/components/dot/index.ts +2 -0
  245. package/src/shared/ui/organisms/slider/components/indicator/index.ts +2 -0
  246. package/src/shared/ui/organisms/slider/components/indicator/indicator.styles.ts +20 -0
  247. package/src/shared/ui/organisms/slider/components/indicator/indicator.tsx +22 -0
  248. package/src/shared/ui/organisms/slider/components/indicator/indicator.types.ts +10 -0
  249. package/src/shared/ui/organisms/slider/index.ts +3 -0
  250. package/src/shared/ui/organisms/slider/slider.styles.ts +68 -0
  251. package/src/shared/ui/organisms/slider/slider.tsx +64 -0
  252. package/src/shared/ui/organisms/slider/slider.types.ts +28 -0
  253. package/src/shared/ui/templates/index.ts +3 -0
  254. package/src/shared/ui/templates/modal-container/index.ts +13 -0
  255. package/src/shared/ui/templates/modal-container/modal-container-list.tsx +45 -0
  256. package/src/shared/ui/templates/modal-container/modal-container-scroll.tsx +66 -0
  257. package/src/shared/ui/templates/modal-container/modal-container-section-list.tsx +46 -0
  258. package/src/shared/ui/templates/modal-container/modal-container.hooks.tsx +172 -0
  259. package/src/shared/ui/templates/modal-container/modal-container.styles.ts +121 -0
  260. package/src/shared/ui/templates/modal-container/modal-container.types.ts +69 -0
  261. package/src/shared/ui/templates/screen-container/index.ts +1 -1
  262. package/src/shared/ui/templates/screen-container/screen-container-list.tsx +28 -10
  263. package/src/shared/ui/templates/screen-container/screen-container-scroll.tsx +28 -10
  264. package/src/shared/ui/templates/screen-container/screen-container-section-list.tsx +29 -11
  265. package/src/shared/ui/templates/screen-container/screen-container.hooks.tsx +79 -8
  266. package/src/shared/ui/templates/screen-container/screen-container.styles.ts +105 -15
  267. package/src/shared/ui/templates/screen-container/screen-container.types.tsx +34 -7
  268. package/src/shared/ui/templates/screen-header/components/index.ts +6 -0
  269. package/src/shared/ui/templates/screen-header/components/screen-header-description/index.ts +2 -0
  270. package/src/shared/ui/templates/screen-header/components/screen-header-description/screen-header-description.tsx +15 -0
  271. package/src/shared/ui/templates/screen-header/components/screen-header-description/screen-header-description.types.ts +11 -0
  272. package/src/shared/ui/templates/screen-header/components/screen-header-icon/index.ts +2 -0
  273. package/src/shared/ui/templates/screen-header/components/screen-header-icon/screen-header-icon.styles.ts +44 -0
  274. package/src/shared/ui/templates/screen-header/components/screen-header-icon/screen-header-icon.tsx +65 -0
  275. package/src/shared/ui/templates/screen-header/components/screen-header-icon/screen-header-icon.types.ts +14 -0
  276. package/src/shared/ui/templates/screen-header/components/screen-header-icon-back/index.ts +2 -0
  277. package/src/shared/ui/templates/screen-header/components/screen-header-icon-back/screen-header-icon-back.tsx +17 -0
  278. package/src/shared/ui/templates/screen-header/components/screen-header-icon-back/screen-header-icon-back.types.ts +6 -0
  279. package/src/shared/ui/templates/screen-header/components/screen-header-icon-close/index.ts +2 -0
  280. package/src/shared/ui/templates/screen-header/components/screen-header-icon-close/screen-header-icon-close.tsx +27 -0
  281. package/src/shared/ui/templates/screen-header/components/screen-header-icon-close/screen-header-icon-close.types.ts +10 -0
  282. package/src/shared/ui/templates/screen-header/components/screen-header-info/index.ts +2 -0
  283. package/src/shared/ui/templates/screen-header/components/screen-header-info/screen-header-info.tsx +15 -0
  284. package/src/shared/ui/templates/screen-header/components/screen-header-info/screen-header-info.types.ts +10 -0
  285. package/src/shared/ui/templates/screen-header/components/screen-header-title/index.ts +2 -0
  286. package/src/shared/ui/templates/screen-header/components/screen-header-title/screen-header-title.tsx +19 -0
  287. package/src/shared/ui/templates/screen-header/components/screen-header-title/screen-header-title.types.ts +13 -0
  288. package/src/shared/ui/templates/screen-header/index.ts +3 -0
  289. package/src/shared/ui/templates/screen-header/screen-header.styles.ts +49 -0
  290. package/src/shared/ui/templates/screen-header/screen-header.tsx +26 -0
  291. package/src/shared/ui/templates/screen-header/screen-header.types.ts +15 -0
  292. package/src/shared/ui/templates/web-container/index.ts +2 -0
  293. package/src/shared/ui/templates/web-container/web-container.styles.ts +34 -0
  294. package/src/shared/ui/templates/web-container/web-container.tsx +172 -0
  295. package/src/shared/ui/templates/web-container/web-container.types.ts +21 -0
  296. package/.claude/rules/app-routing.mdc +0 -47
  297. package/.claude/rules/exports-at-end.mdc +0 -55
  298. package/.claude/rules/kebab-case-naming.mdc +0 -29
  299. package/.claude/rules/mediacubeco-packages.mdc +0 -56
  300. package/.claude/skills/generate-api-model/SKILL.md +0 -230
  301. package/.claude/skills/generate-api-model/references/resources/common.ts +0 -8
  302. package/.claude/skills/generate-api-model-mock/SKILL.md +0 -56
  303. package/.claude/skills/git-commit/SKILL.md +0 -139
  304. package/.gitignore +0 -34
  305. package/src/shared/assets/icons/like.tsx +0 -17
  306. package/src/shared/hooks/use-animated.ts +0 -200
  307. package/src/shared/hooks/use-mixins.ts +0 -36
  308. package/src/shared/hooks/use-safe-area.ts +0 -75
  309. package/src/shared/lib/api/repositories/auth/auth.ts +0 -23
  310. package/src/shared/lib/api/repositories/auth/auth.types.ts +0 -22
  311. package/src/shared/lib/api/repositories/auth/index.ts +0 -1
  312. package/src/shared/lib/navigation/hooks/use-navigation-native-tabs.ts +0 -10
  313. package/src/shared/lib/navigation/hooks/use-navigation-options.ts +0 -123
  314. package/src/shared/lib/navigation/navigation-native-tabs.context.tsx +0 -5
  315. package/src/shared/lib/navigation/navigation-native-tabs.provider.tsx +0 -12
  316. package/src/shared/lib/theme/constants/borders.ts +0 -8
  317. package/src/shared/lib/theme/constants/weights.ts +0 -13
  318. /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/index.ts +0 -0
  319. /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/post/index.ts +0 -0
  320. /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/post/post-comment.ts +0 -0
  321. /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/post/post.ts +0 -0
  322. /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/user/index.ts +0 -0
  323. /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/user/user-settings.ts +0 -0
  324. /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/user/user-verification.ts +0 -0
  325. /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/user/user.ts +0 -0
  326. /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/index.ts +0 -0
  327. /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/post/index.ts +0 -0
  328. /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/post/post-comment.ts +0 -0
  329. /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/post/post.ts +0 -0
  330. /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/user/index.ts +0 -0
  331. /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/user/user-settings.ts +0 -0
  332. /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/user/user-verification.ts +0 -0
  333. /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/user/user.ts +0 -0
@@ -21,15 +21,29 @@ type ScreenContainerExcludeExtraNativeProps<
21
21
  'style' | 'contentContainerStyle' | 'refreshControl' | 'refreshing' | 'onRefresh' | Prop
22
22
  >
23
23
 
24
- type ScreenContainerProps<Component extends ScrollView | FlatList | SectionList> = {
25
- reference?: Ref<Component>
24
+ type ScreenContainerProps<
25
+ Component extends ScrollView | FlatList | SectionList = ScrollView | FlatList | SectionList,
26
+ > = {
27
+ ref?: Ref<Component>
26
28
  wrapperStyle?: StyleProp<ViewStyle>
29
+ bodyStyle?: StyleProp<ViewStyle>
27
30
  outerStyle?: StyleProp<ViewStyle>
28
31
  innerStyle?: StyleProp<ViewStyle>
29
- header?: ReactNode
30
- footer?: ReactNode
32
+ variant?: 'base' | 'secondary'
33
+ withScroll?: boolean
34
+ withBlurTop?: boolean
35
+ withBlurBottom?: boolean
36
+ withAreaTop?: boolean
37
+ withAreaBottom?: boolean
38
+ withIndentTop?: boolean
39
+ withIndentBottom?: boolean
31
40
  withOverflowTop?: boolean
32
41
  withOverflowBottom?: boolean
42
+ overlay?: ReactNode
43
+ screenHeader?: ReactNode
44
+ // screenFooter?: ReactNode
45
+ header?: ReactNode
46
+ footer?: ReactNode
33
47
  onRefresh?: () => unknown | Promise<unknown>
34
48
  }
35
49
 
@@ -58,12 +72,25 @@ type ScreenContainerSectionListRenderFooterInfo<Item = unknown> = {
58
72
  section: SectionListData<Item>
59
73
  }
60
74
 
61
- type ScreenContainerStylesConfig = {
62
- withOverflowTop: boolean
63
- withOverflowBottom: boolean
75
+ type ScreenContainerStylesConfig = Required<
76
+ Pick<
77
+ ScreenContainerProps,
78
+ | 'withAreaTop'
79
+ | 'withAreaBottom'
80
+ | 'withIndentTop'
81
+ | 'withIndentBottom'
82
+ | 'withOverflowTop'
83
+ | 'withOverflowBottom'
84
+ >
85
+ > & {
86
+ withScreenHeader: boolean
87
+ withScreenFooter: boolean
88
+ withHeader: boolean
89
+ withFooter: boolean
64
90
  }
65
91
 
66
92
  export type {
93
+ ScreenContainerProps,
67
94
  ScreenContainerScrollProps,
68
95
  ScreenContainerListProps,
69
96
  ScreenContainerSectionListProps,
@@ -0,0 +1,6 @@
1
+ export * from './screen-header-description'
2
+ export * from './screen-header-icon'
3
+ export * from './screen-header-icon-back'
4
+ export * from './screen-header-icon-close'
5
+ export * from './screen-header-info'
6
+ export * from './screen-header-title'
@@ -0,0 +1,2 @@
1
+ export { default as ScreenHeaderDescription } from './screen-header-description'
2
+ export type { ScreenHeaderDescriptionProps } from './screen-header-description.types'
@@ -0,0 +1,15 @@
1
+ import { Text, Touch } from '../../../../atoms'
2
+ import { type ScreenHeaderDescriptionProps } from './screen-header-description.types'
3
+
4
+ /** Описание в шапке экрана: вторичный текст нейтрального цвета под заголовком. */
5
+ const ScreenHeaderDescription = ({ value, onPress, onLongPress }: ScreenHeaderDescriptionProps) => {
6
+ return (
7
+ <Touch onPress={onPress} onLongPress={onLongPress}>
8
+ <Text type={'description'} variant={'neutral'} align={'center'} lineCount={2} shouldFit>
9
+ {value}
10
+ </Text>
11
+ </Touch>
12
+ )
13
+ }
14
+
15
+ export default ScreenHeaderDescription
@@ -0,0 +1,11 @@
1
+ import { type Noop } from '@mediacubeco/base/types'
2
+
3
+ /** Пропсы описания шапки экрана. */
4
+ type ScreenHeaderDescriptionProps = {
5
+ /** Текст описания. */
6
+ value: string
7
+ onPress?: Noop
8
+ onLongPress?: Noop
9
+ }
10
+
11
+ export type { ScreenHeaderDescriptionProps }
@@ -0,0 +1,2 @@
1
+ export { default as ScreenHeaderIcon } from './screen-header-icon'
2
+ export type { ScreenHeaderIconProps } from './screen-header-icon.types'
@@ -0,0 +1,44 @@
1
+ import { StyleSheet } from 'react-native'
2
+ import { useThemeMode } from '../../../../../lib'
3
+
4
+ /** Стили иконки-кнопки шапки: круглая стеклянная подложка и растянутая нажимаемая область с отступом под иконку. */
5
+ const useScreenHeaderIconStyles = () => {
6
+ const { COLORS, SIZES, SHADOWS } = useThemeMode()
7
+
8
+ const styles = StyleSheet.create({
9
+ wrapper: {
10
+ borderRadius: SIZES['INFINITY'],
11
+ ...SHADOWS.BASE,
12
+ },
13
+ body: {
14
+ flexDirection: 'row',
15
+ borderRadius: SIZES['INFINITY'],
16
+ },
17
+ glass: {},
18
+ blur: {
19
+ overflow: 'hidden',
20
+ },
21
+ touch: {
22
+ padding: SIZES['L'],
23
+ },
24
+ icon: {},
25
+ })
26
+
27
+ const stylesByVariant = {
28
+ body: StyleSheet.create({
29
+ base: {
30
+ backgroundColor: COLORS.BAR.BASE,
31
+ },
32
+ secondary: {
33
+ backgroundColor: COLORS.BAR.DISABLED,
34
+ },
35
+ contrast: {
36
+ backgroundColor: COLORS.BAR.DISABLED,
37
+ },
38
+ }),
39
+ }
40
+
41
+ return { styles, stylesByVariant }
42
+ }
43
+
44
+ export { useScreenHeaderIconStyles }
@@ -0,0 +1,65 @@
1
+ import { type IterableOf } from '@mediacubeco/base/types'
2
+ import { forceList, getValueByKey, runCallback } from '@mediacubeco/base/utils'
3
+ import { useCallback } from 'react'
4
+ import { View } from 'react-native'
5
+ import { isGlassEffectAPIAvailable } from 'expo-glass-effect'
6
+ import { Glass, Icon, type IconProps, Touch } from '../../../../atoms'
7
+ import { useScreenHeaderIconStyles } from './screen-header-icon.styles'
8
+ import { type ScreenHeaderIconProps } from './screen-header-icon.types'
9
+
10
+ const ScreenHeaderIcon = <Item extends IconProps['name']>({
11
+ value,
12
+ variant = 'base',
13
+ onPress,
14
+ onLongPress,
15
+ }: ScreenHeaderIconProps<Item>) => {
16
+ const { styles, stylesByVariant } = useScreenHeaderIconStyles()
17
+
18
+ const valueList = forceList(value)
19
+ const hasGlass = isGlassEffectAPIAvailable()
20
+
21
+ const iconVariant = getValueByKey(
22
+ variant,
23
+ {
24
+ secondary: 'base',
25
+ } as const,
26
+ variant
27
+ )
28
+
29
+ const handlePress = useCallback(
30
+ (value: IterableOf<typeof valueList>) => () => {
31
+ runCallback(onPress, value)
32
+ },
33
+ [onPress]
34
+ )
35
+
36
+ const handleLongPress = useCallback(
37
+ (value: IterableOf<typeof valueList>) => () => {
38
+ runCallback(onLongPress, value)
39
+ },
40
+ [onLongPress]
41
+ )
42
+
43
+ return (
44
+ <Glass
45
+ style={[styles.wrapper, hasGlass ? styles.glass : styles.blur]}
46
+ glassEffectStyle={'clear'}
47
+ >
48
+ <View style={[styles.body, stylesByVariant.body[variant]]}>
49
+ {valueList.map((value) => (
50
+ <Touch
51
+ key={value}
52
+ style={styles.touch}
53
+ withRipple={!hasGlass}
54
+ onPress={handlePress(value)}
55
+ onLongPress={handleLongPress(value)}
56
+ >
57
+ <Icon name={value} variant={iconVariant} style={styles.icon} />
58
+ </Touch>
59
+ ))}
60
+ </View>
61
+ </Glass>
62
+ )
63
+ }
64
+
65
+ export default ScreenHeaderIcon
@@ -0,0 +1,14 @@
1
+ import { type Callback } from '@mediacubeco/base/types'
2
+ import { type IconProps } from '../../../../atoms'
3
+
4
+ /** Пропсы иконки-кнопки шапки экрана. */
5
+ type ScreenHeaderIconProps<Value extends IconProps['name'] = IconProps['name']> = {
6
+ /** Вариант окраски иконки. */
7
+ variant?: 'base' | 'secondary' | 'contrast'
8
+ /** Имя отображаемой иконки. */
9
+ value: Value | Value[]
10
+ onPress?: Callback<[Value]>
11
+ onLongPress?: Callback<[Value]>
12
+ }
13
+
14
+ export type { ScreenHeaderIconProps }
@@ -0,0 +1,2 @@
1
+ export { default as ScreenHeaderIconBack } from './screen-header-icon-back'
2
+ export type { ScreenHeaderIconBackProps } from './screen-header-icon-back.types'
@@ -0,0 +1,17 @@
1
+ import { useCallback } from 'react'
2
+ import { useNavigationRoute } from '../../../../../lib'
3
+ import { ScreenHeaderIcon } from '../screen-header-icon'
4
+ import { type ScreenHeaderIconBackProps } from './screen-header-icon-back.types'
5
+
6
+ /** Иконка-кнопка шапки экрана для возврата на предыдущий экран. */
7
+ const ScreenHeaderIconBack = ({ variant }: ScreenHeaderIconBackProps) => {
8
+ const navigation = useNavigationRoute()
9
+
10
+ const handlePress = useCallback(() => {
11
+ navigation.back()
12
+ }, [navigation])
13
+
14
+ return <ScreenHeaderIcon value={'back'} variant={variant} onPress={handlePress} />
15
+ }
16
+
17
+ export default ScreenHeaderIconBack
@@ -0,0 +1,6 @@
1
+ import { type ScreenHeaderIconProps } from '../screen-header-icon'
2
+
3
+ /** Пропсы иконки-кнопки возврата на предыдущий экран. */
4
+ type ScreenHeaderIconBackProps = Pick<ScreenHeaderIconProps, 'variant'>
5
+
6
+ export type { ScreenHeaderIconBackProps }
@@ -0,0 +1,2 @@
1
+ export { default as ScreenHeaderIconClose } from './screen-header-icon-close'
2
+ export type { ScreenHeaderIconCloseProps } from './screen-header-icon-close.types'
@@ -0,0 +1,27 @@
1
+ import { useCallback } from 'react'
2
+ import { useNavigationRoute } from '../../../../../lib'
3
+ import { ScreenHeaderIcon } from '../screen-header-icon'
4
+ import { type ScreenHeaderIconCloseProps } from './screen-header-icon-close.types'
5
+
6
+ /**
7
+ * Иконка-кнопка шапки для закрытия флоу с последнего экрана: сворачивает стек к
8
+ * первому экрану флоу (`to`), а без него — к корню стека. Не путать с
9
+ * `ScreenHeaderIconBack`, который делает шаг назад.
10
+ */
11
+ const ScreenHeaderIconClose = ({ to, variant }: ScreenHeaderIconCloseProps) => {
12
+ const navigation = useNavigationRoute()
13
+
14
+ const handlePress = useCallback(() => {
15
+ if (to) {
16
+ navigation.dismissTo(to)
17
+
18
+ return
19
+ }
20
+
21
+ navigation.dismissAll()
22
+ }, [to, navigation])
23
+
24
+ return <ScreenHeaderIcon value={'close'} variant={variant} onPress={handlePress} />
25
+ }
26
+
27
+ export default ScreenHeaderIconClose
@@ -0,0 +1,10 @@
1
+ import { type Href } from 'expo-router'
2
+ import { type ScreenHeaderIconProps } from '../screen-header-icon'
3
+
4
+ /** Пропсы иконки-кнопки закрытия флоу. */
5
+ type ScreenHeaderIconCloseProps = Pick<ScreenHeaderIconProps, 'variant'> & {
6
+ /** Первый экран флоу, на который свернуть стек; без него — выход к корню стека. */
7
+ to?: Href
8
+ }
9
+
10
+ export type { ScreenHeaderIconCloseProps }
@@ -0,0 +1,2 @@
1
+ export { default as ScreenHeaderInfo } from './screen-header-info'
2
+ export type { ScreenHeaderInfoProps } from './screen-header-info.types'
@@ -0,0 +1,15 @@
1
+ import { ScreenHeaderDescription } from '../screen-header-description'
2
+ import { ScreenHeaderTitle } from '../screen-header-title'
3
+ import { type ScreenHeaderInfoProps } from './screen-header-info.types'
4
+
5
+ /** Информационный блок шапки экрана: заголовок и описание под ним. */
6
+ const ScreenHeaderInfo = ({ title, description, variant }: ScreenHeaderInfoProps) => {
7
+ return (
8
+ <>
9
+ {title && <ScreenHeaderTitle value={title} variant={variant} />}
10
+ {description && <ScreenHeaderDescription value={description} />}
11
+ </>
12
+ )
13
+ }
14
+
15
+ export default ScreenHeaderInfo
@@ -0,0 +1,10 @@
1
+ /** Пропсы информационного блока шапки экрана. */
2
+ type ScreenHeaderInfoProps = {
3
+ variant?: 'base' | 'contrast'
4
+ /** Текст заголовка. */
5
+ title?: string
6
+ /** Текст описания. */
7
+ description?: string
8
+ }
9
+
10
+ export type { ScreenHeaderInfoProps }
@@ -0,0 +1,2 @@
1
+ export { default as ScreenHeaderTitle } from './screen-header-title'
2
+ export type { ScreenHeaderTitleProps } from './screen-header-title.types'
@@ -0,0 +1,19 @@
1
+ import { Text, Touch } from '../../../../atoms'
2
+ import { type ScreenHeaderTitleProps } from './screen-header-title.types'
3
+
4
+ const ScreenHeaderTitle = ({
5
+ value,
6
+ variant = 'base',
7
+ onPress,
8
+ onLongPress,
9
+ }: ScreenHeaderTitleProps) => {
10
+ return (
11
+ <Touch onPress={onPress} onLongPress={onLongPress}>
12
+ <Text variant={variant} type={'subtitle'} align={'center'} lineCount={2} shouldFit={true}>
13
+ {value}
14
+ </Text>
15
+ </Touch>
16
+ )
17
+ }
18
+
19
+ export default ScreenHeaderTitle
@@ -0,0 +1,13 @@
1
+ import { type Noop } from '@mediacubeco/base/types'
2
+
3
+ /** Пропсы заголовка шапки экрана. */
4
+ type ScreenHeaderTitleProps = {
5
+ /** Текст заголовка. */
6
+ value: string
7
+ /** Вариант окраски текста. */
8
+ variant?: 'base' | 'contrast'
9
+ onPress?: Noop
10
+ onLongPress?: Noop
11
+ }
12
+
13
+ export type { ScreenHeaderTitleProps }
@@ -0,0 +1,3 @@
1
+ export * from './components'
2
+ export { default as ScreenHeader } from './screen-header'
3
+ export type { ScreenHeaderProps } from './screen-header.types'
@@ -0,0 +1,49 @@
1
+ import { StyleSheet } from 'react-native'
2
+ import { useNavigationSafeArea, useThemeMode } from '../../../lib'
3
+ import { type ScreenHeaderStylesContext } from './screen-header.types'
4
+
5
+ const useScreenHeaderStyles = ({ withArea }: ScreenHeaderStylesContext) => {
6
+ const { COLORS, SIZES } = useThemeMode()
7
+ const { TOP, HEADER } = useNavigationSafeArea()
8
+
9
+ const HEADER_AREA = withArea ? TOP : 0
10
+
11
+ const styles = StyleSheet.create({
12
+ wrapper: {
13
+ justifyContent: 'flex-end',
14
+ height: HEADER + HEADER_AREA,
15
+ paddingTop: HEADER_AREA,
16
+ },
17
+ wrapperWithBlur: {
18
+ backgroundColor: COLORS.FILL.TRANSPARENT,
19
+ },
20
+ wrapperWithoutBlur: {
21
+ backgroundColor: COLORS.BACKGROUND.SECONDARY,
22
+ },
23
+ body: {
24
+ flexDirection: 'row',
25
+ alignItems: 'center',
26
+ gap: SIZES['L'],
27
+ paddingVertical: SIZES['M'],
28
+ },
29
+ left: {
30
+ flex: 1,
31
+ alignItems: 'flex-start',
32
+ flexBasis: SIZES['MIN'],
33
+ },
34
+ center: {
35
+ flexGrow: 3,
36
+ flexBasis: SIZES['MIN'],
37
+ alignItems: 'center',
38
+ },
39
+ right: {
40
+ flex: 1,
41
+ alignItems: 'flex-end',
42
+ flexBasis: SIZES['MIN'],
43
+ },
44
+ })
45
+
46
+ return { styles }
47
+ }
48
+
49
+ export { useScreenHeaderStyles }
@@ -0,0 +1,26 @@
1
+ import { View } from 'react-native'
2
+ import { useScreenHeaderStyles } from './screen-header.styles'
3
+ import { type ScreenHeaderProps } from './screen-header.types'
4
+
5
+ const ScreenHeader = ({
6
+ ref,
7
+ style,
8
+ center = '',
9
+ left,
10
+ right,
11
+ withArea = true,
12
+ }: ScreenHeaderProps) => {
13
+ const { styles } = useScreenHeaderStyles({ withArea })
14
+
15
+ return (
16
+ <View ref={ref} style={[styles.wrapper, style]}>
17
+ <View style={styles.body}>
18
+ <View style={styles.left}>{left}</View>
19
+ <View style={styles.center}>{center}</View>
20
+ <View style={styles.right}>{right}</View>
21
+ </View>
22
+ </View>
23
+ )
24
+ }
25
+
26
+ export default ScreenHeader
@@ -0,0 +1,15 @@
1
+ import { type ReactNode, type Ref } from 'react'
2
+ import { type View, type ViewProps } from 'react-native'
3
+
4
+ type ScreenHeaderProps = {
5
+ ref?: Ref<View>
6
+ style?: ViewProps['style']
7
+ center?: ReactNode
8
+ left?: ReactNode
9
+ right?: ReactNode
10
+ withArea?: boolean
11
+ }
12
+
13
+ type ScreenHeaderStylesContext = Required<Pick<ScreenHeaderProps, 'withArea'>> & {}
14
+
15
+ export type { ScreenHeaderProps, ScreenHeaderStylesContext }
@@ -0,0 +1,2 @@
1
+ export { default as WebContainer } from './web-container'
2
+ export type { WebContainerProps } from './web-container.types'
@@ -0,0 +1,34 @@
1
+ import { StyleSheet } from 'react-native'
2
+ import { useThemeMode } from '../../../lib'
3
+
4
+ /**
5
+ * Визуальная логика контейнера WebView. Контейнер живёт внутри formSheet: шапка в потоке
6
+ * (с запасом сверху под grabber листа), WebView занимает остаток высоты. Загрузка и ошибка —
7
+ * непрозрачные оверлеи поверх WebView, чтобы скрыть белую вспышку страницы и «голый» экран
8
+ * при провале навигации. Пропорции шапки повторяют `ScreenHeader`: боковые зоны равной
9
+ * ширины, поэтому заголовок стоит по центру независимо от кнопки закрытия.
10
+ */
11
+ const useWebContainerStyles = () => {
12
+ const { COLORS } = useThemeMode()
13
+
14
+ const styles = StyleSheet.create({
15
+ wrapper: {},
16
+ outer: {},
17
+ inner: {
18
+ paddingHorizontal: 0,
19
+ },
20
+ web: {
21
+ flex: 1,
22
+ backgroundColor: COLORS.FILL.TRANSPARENT,
23
+ },
24
+ spinner: {
25
+ ...StyleSheet.absoluteFill,
26
+ alignItems: 'center',
27
+ justifyContent: 'center',
28
+ },
29
+ })
30
+
31
+ return { styles }
32
+ }
33
+
34
+ export { useWebContainerStyles }