@mediacubeco/expo-template-fsd 2.3.1 → 2.4.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.
- package/.claude/commands/git-commit.md +164 -0
- package/.claude/rules/architecture.md +38 -0
- package/.claude/rules/{prettier-eslint-typescript.mdc → prettier-eslint-typescript.md} +5 -10
- package/.claude/settings.json +2 -2
- package/.claude/skills/api/SKILL.md +362 -0
- package/.claude/skills/api/references/client/overview.md +106 -0
- package/.claude/skills/api/references/hooks/index.ts +3 -0
- package/.claude/skills/api/references/hooks/use-api-health.ts +25 -0
- package/.claude/skills/api/references/hooks/use-api-post.ts +46 -0
- package/.claude/skills/api/references/hooks/use-api-posts.ts +24 -0
- package/.claude/skills/api/references/mock/post.mock.ts +29 -0
- package/.claude/skills/{generate-api-model/references → api/references/model}/entities/common.ts +5 -2
- package/.claude/skills/api/references/model/resources/common.ts +9 -0
- package/.claude/skills/api/references/queries/health.ts +14 -0
- package/.claude/skills/api/references/queries/index.ts +2 -0
- package/.claude/skills/api/references/queries/post.ts +23 -0
- package/.claude/skills/api/references/repository/health/health.ts +11 -0
- package/.claude/skills/api/references/repository/health/health.types.ts +25 -0
- package/.claude/skills/api/references/repository/health/index.ts +2 -0
- package/.claude/skills/api/references/repository/post/index.ts +9 -0
- package/.claude/skills/api/references/repository/post/post.ts +34 -0
- package/.claude/skills/api/references/repository/post/post.types.ts +61 -0
- package/.claude/skills/code-style/SKILL.md +1025 -1
- package/.claude/skills/code-style/references/components/payout-speed-option/index.ts +2 -0
- package/.claude/skills/code-style/references/components/payout-speed-option/payout-speed-option.styles.ts +76 -0
- package/.claude/skills/code-style/references/components/payout-speed-option/payout-speed-option.tsx +58 -0
- package/.claude/skills/code-style/references/components/payout-speed-option/payout-speed-option.types.ts +22 -0
- package/.claude/skills/code-style/references/components/post/index.ts +2 -0
- package/.claude/skills/code-style/references/components/post/post.styles.ts +19 -0
- package/.claude/skills/code-style/references/components/post/post.tsx +21 -0
- package/.claude/skills/code-style/references/components/post/post.types.ts +9 -0
- package/.claude/skills/code-style/references/components/wrap/index.ts +2 -0
- package/.claude/skills/code-style/references/components/wrap/wrap.styles.ts +15 -0
- package/.claude/skills/code-style/references/components/wrap/wrap.tsx +31 -0
- package/.claude/skills/code-style/references/components/wrap/wrap.types.ts +10 -0
- package/.claude/skills/code-style/references/hooks/use-posts.ts +37 -0
- package/.claude/skills/code-style/references/pages/post/index.ts +4 -0
- package/.claude/skills/code-style/references/pages/post/post-details/index.ts +1 -0
- package/.claude/skills/code-style/references/pages/post/post-details/post-details.tsx +13 -0
- package/.claude/skills/code-style/references/pages/post/post-guide/index.ts +1 -0
- package/.claude/skills/code-style/references/pages/post/post-guide/post-guide.tsx +17 -0
- package/.claude/skills/code-style/references/pages/post/post-list/index.ts +1 -0
- package/.claude/skills/code-style/references/pages/post/post-list/post-list.styles.ts +17 -0
- package/.claude/skills/code-style/references/pages/post/post-list/post-list.tsx +25 -0
- package/.claude/skills/code-style/references/pages/post/post-share/index.ts +1 -0
- package/.claude/skills/code-style/references/pages/post/post-share/post-share.tsx +13 -0
- package/.claude/skills/code-style/references/routes/(stack)/_layout.tsx +18 -0
- package/.claude/skills/code-style/references/routes/(stack)/details.tsx +8 -0
- package/.claude/skills/code-style/references/routes/(stack)/guide.tsx +8 -0
- package/.claude/skills/code-style/references/routes/(stack)/index.tsx +8 -0
- package/.claude/skills/code-style/references/routes/(stack)/share.tsx +8 -0
- package/.claude/skills/code-style/references/routes/(tabs)/(post-details)/index.tsx +8 -0
- package/.claude/skills/code-style/references/routes/(tabs)/(post-list)/index.tsx +8 -0
- package/.claude/skills/code-style/references/routes/(tabs)/_layout.tsx +50 -0
- package/.claude/skills/code-style/references/routes/_app.tsx +20 -0
- package/.claude/skills/code-style/references/routes/guide.tsx +8 -0
- package/.claude/skills/code-style/references/routes/share.tsx +8 -0
- package/.claude/skills/code-style/references/store/use-post-draft-store.ts +62 -0
- package/.claude/skills/design-style/SKILL.md +320 -0
- package/.env +3 -1
- package/.env.example +3 -1
- package/CLAUDE.md +5 -11
- package/app.json +6 -3
- package/axios.d.ts +5 -0
- package/env.d.ts +3 -1
- package/package.json +33 -40
- package/patches/react-native-screens+4.25.2.patch +118 -0
- package/react-query.d.ts +13 -0
- package/src/app/(root)/(home)/_layout.tsx +2 -2
- package/src/app/(root)/(home)/index.tsx +2 -2
- package/src/app/(root)/(settings)/_layout.tsx +2 -2
- package/src/app/(root)/(settings)/index.tsx +2 -2
- package/src/app/(root)/_layout.tsx +35 -32
- package/src/pages/home/home-main.tsx +3 -7
- package/src/pages/settings/settings-main.tsx +3 -7
- package/src/shared/assets/fonts/index.ts +3 -3
- package/src/shared/assets/fonts/sf-pro-text-bold.ttf +0 -0
- package/src/shared/assets/fonts/sf-pro-text-regular.ttf +0 -0
- package/src/shared/assets/fonts/sf-pro-text-semibold.ttf +0 -0
- package/src/shared/assets/icons/back.tsx +21 -0
- package/src/shared/assets/icons/close.tsx +21 -0
- package/src/shared/assets/icons/common.ts +8 -0
- package/src/shared/assets/icons/default.tsx +44 -0
- package/src/shared/assets/icons/index.ts +14 -1
- package/src/shared/assets/icons/refresh.tsx +23 -0
- package/src/shared/assets/icons/share.tsx +38 -0
- package/src/shared/assets/icons/type.ts +7 -0
- package/src/shared/assets/translations/index.ts +4 -4
- package/src/shared/constants/config.ts +13 -0
- package/src/shared/constants/environment.ts +16 -4
- package/src/shared/constants/index.ts +1 -0
- package/src/shared/hooks/index.ts +1 -4
- package/src/shared/hooks/use-compose.ts +23 -0
- package/src/shared/lib/api/api.client.ts +157 -0
- package/src/shared/lib/api/api.provider.tsx +14 -36
- package/src/shared/lib/api/api.ts +1 -5
- package/src/shared/lib/api/api.types.ts +6 -3
- package/src/shared/lib/api/hooks/index.ts +1 -0
- package/src/shared/lib/api/index.ts +2 -3
- package/src/shared/lib/api/models/api-instance/api-instance.client.ts +50 -0
- package/src/shared/lib/api/models/api-instance/api-instance.ts +30 -82
- package/src/shared/lib/api/models/api-instance/api-instance.types.ts +16 -18
- package/src/shared/lib/api/models/api-instance/api-instance.utils.ts +13 -20
- package/src/shared/lib/api/models/api-instance/index.ts +3 -0
- package/src/shared/lib/api/queries/index.ts +1 -0
- package/src/shared/lib/api/repositories/index.ts +1 -1
- package/src/shared/lib/localization/constants/index.ts +16 -5
- package/src/shared/lib/localization/index.ts +5 -1
- package/src/shared/lib/navigation/hooks/index.ts +8 -3
- package/src/shared/{hooks/use-breakpoints.ts → lib/navigation/hooks/use-navigation-breakpoints.ts} +2 -5
- package/src/shared/lib/navigation/hooks/use-navigation-dimensions.ts +12 -0
- package/src/shared/lib/navigation/hooks/use-navigation-options.tsx +175 -0
- package/src/shared/lib/navigation/hooks/{use-navigation.ts → use-navigation-route.ts} +2 -2
- package/src/shared/lib/navigation/hooks/use-navigation-safe-area.ts +61 -0
- package/src/shared/lib/navigation/hooks/use-navigation-tabs-native.ts +10 -0
- package/src/shared/lib/navigation/hooks/use-navigation-tabs.tsx +10 -0
- package/src/shared/lib/navigation/hooks/use-navigation-transition.ts +27 -0
- package/src/shared/lib/navigation/index.ts +11 -4
- package/src/shared/lib/navigation/navigation-tabs-native.context.tsx +5 -0
- package/src/shared/lib/navigation/navigation-tabs-native.provider.tsx +17 -0
- package/src/shared/lib/navigation/navigation-tabs.context.tsx +10 -0
- package/src/shared/lib/navigation/navigation-tabs.provider.tsx +22 -0
- package/src/shared/lib/navigation/navigation.provider.tsx +6 -1
- package/src/shared/lib/storage/index.ts +1 -1
- package/src/shared/lib/storage/storage.provider.tsx +4 -0
- package/src/shared/lib/storage/storage.ts +29 -25
- package/src/shared/lib/theme/constants/animations.ts +26 -0
- package/src/shared/lib/theme/constants/colors.ts +336 -43
- package/src/shared/lib/theme/constants/delays.ts +1 -1
- package/src/shared/lib/theme/constants/durations.ts +1 -1
- package/src/shared/lib/theme/constants/fonts.ts +2 -1
- package/src/shared/lib/theme/constants/index.ts +42 -20
- package/src/shared/lib/theme/constants/shadows.ts +7 -25
- package/src/shared/lib/theme/constants/sizes.ts +11 -2
- package/src/shared/lib/theme/constants/transparencies.ts +1 -1
- package/src/shared/lib/theme/hooks/use-theme-setup.ts +3 -1
- package/src/shared/lib/theme/index.ts +10 -1
- package/src/shared/lib/theme/theme.provider.tsx +45 -19
- package/src/shared/lib/theme/theme.scope.tsx +43 -0
- package/src/shared/lib/theme/theme.types.ts +15 -3
- package/src/shared/lib/theme/utils/color.ts +81 -0
- package/src/shared/lib/theme/utils/index.ts +2 -0
- package/src/shared/lib/theme/utils/snapshot.ts +17 -0
- package/src/shared/lib/theme/utils/storage.ts +5 -2
- package/src/shared/services/browser/browser.ts +66 -0
- package/src/shared/services/browser/index.ts +1 -0
- package/src/shared/services/cookies/cookies.ts +73 -0
- package/src/shared/services/cookies/index.ts +1 -0
- package/src/shared/services/index.ts +5 -0
- package/src/shared/services/linking/index.ts +1 -0
- package/src/shared/services/linking/linking.ts +22 -0
- package/src/shared/services/share/index.ts +1 -0
- package/src/shared/services/share/share.ts +28 -0
- package/src/shared/services/universal-links/index.ts +104 -0
- package/src/shared/services/universal-links/universal-links.ts +25 -0
- package/src/shared/services/universal-links/universal-links.types.ts +5 -0
- package/src/shared/ui/atoms/blur/blur.tsx +9 -4
- package/src/shared/ui/atoms/blur/blur.types.ts +1 -1
- package/src/shared/ui/atoms/blur-progress/blur-progress.styles.ts +16 -0
- package/src/shared/ui/atoms/blur-progress/blur-progress.tsx +30 -0
- package/src/shared/ui/atoms/blur-progress/blur-progress.types.tsx +5 -0
- package/src/shared/ui/atoms/blur-progress/index.ts +1 -0
- package/src/shared/ui/atoms/glass/glass.tsx +13 -5
- package/src/shared/ui/atoms/glass/glass.types.ts +1 -1
- package/src/shared/ui/atoms/icon/icon.styles.ts +82 -0
- package/src/shared/ui/atoms/icon/icon.tsx +21 -0
- package/src/shared/ui/atoms/icon/icon.types.ts +23 -0
- package/src/shared/ui/atoms/icon/index.ts +2 -0
- package/src/shared/ui/atoms/index.ts +7 -0
- package/src/shared/ui/atoms/skeleton/index.ts +2 -0
- package/src/shared/ui/atoms/skeleton/skeleton.styles.ts +69 -0
- package/src/shared/ui/atoms/skeleton/skeleton.tsx +26 -0
- package/src/shared/ui/atoms/skeleton/skeleton.types.ts +9 -0
- package/src/shared/ui/atoms/spinner/index.ts +2 -0
- package/src/shared/ui/atoms/spinner/spinner.styles.ts +102 -0
- package/src/shared/ui/atoms/spinner/spinner.tsx +48 -0
- package/src/shared/ui/atoms/spinner/spinner.types.ts +25 -0
- package/src/shared/ui/atoms/text/index.ts +2 -0
- package/src/shared/ui/atoms/text/text.styles.ts +186 -0
- package/src/shared/ui/atoms/text/text.tsx +37 -0
- package/src/shared/ui/atoms/text/text.types.ts +35 -0
- package/src/shared/ui/atoms/touch/components/haptics/haptics.styles.ts +21 -0
- package/src/shared/ui/atoms/touch/components/haptics/haptics.tsx +28 -0
- package/src/shared/ui/atoms/touch/components/haptics/haptics.types.ts +17 -0
- package/src/shared/ui/atoms/touch/components/haptics/index.ts +2 -0
- package/src/shared/ui/atoms/touch/components/index.ts +3 -0
- package/src/shared/ui/atoms/touch/components/ripple/index.ts +2 -0
- package/src/shared/ui/atoms/touch/components/ripple/ripple.styles.ts +78 -0
- package/src/shared/ui/atoms/touch/components/ripple/ripple.tsx +29 -0
- package/src/shared/ui/atoms/touch/components/ripple/ripple.types.ts +17 -0
- package/src/shared/ui/atoms/touch/components/spring/index.ts +2 -0
- package/src/shared/ui/atoms/touch/components/spring/spring.styles.ts +31 -0
- package/src/shared/ui/atoms/touch/components/spring/spring.tsx +28 -0
- package/src/shared/ui/atoms/touch/components/spring/spring.types.ts +17 -0
- package/src/shared/ui/atoms/touch/index.ts +2 -0
- package/src/shared/ui/atoms/touch/touch.styles.ts +14 -0
- package/src/shared/ui/atoms/touch/touch.tsx +137 -0
- package/src/shared/ui/atoms/touch/touch.types.ts +27 -0
- package/src/shared/ui/atoms/visibility/index.ts +2 -0
- package/src/shared/ui/atoms/visibility/visibility.styles.ts +85 -0
- package/src/shared/ui/atoms/visibility/visibility.tsx +61 -0
- package/src/shared/ui/atoms/visibility/visibility.types.ts +34 -0
- package/src/shared/ui/molecules/keyboard-area/keyboard-area.styles.ts +11 -9
- package/src/shared/ui/molecules/keyboard-area/keyboard-area.tsx +3 -6
- package/src/shared/ui/molecules/refresh-control/refresh-control.tsx +3 -5
- package/src/shared/ui/molecules/refresh-control/refresh-control.types.ts +1 -1
- package/src/shared/ui/molecules/slider/components/indicator/components/dot/dot.styles.ts +41 -0
- package/src/shared/ui/molecules/slider/components/indicator/components/dot/dot.tsx +12 -0
- package/src/shared/ui/molecules/slider/components/indicator/components/dot/dot.types.ts +13 -0
- package/src/shared/ui/molecules/slider/components/indicator/components/dot/index.ts +2 -0
- package/src/shared/ui/molecules/slider/components/indicator/index.ts +2 -0
- package/src/shared/ui/molecules/slider/components/indicator/indicator.styles.ts +20 -0
- package/src/shared/ui/molecules/slider/components/indicator/indicator.tsx +22 -0
- package/src/shared/ui/molecules/slider/components/indicator/indicator.types.ts +10 -0
- package/src/shared/ui/molecules/slider/index.ts +3 -0
- package/src/shared/ui/molecules/slider/slider.styles.ts +68 -0
- package/src/shared/ui/molecules/slider/slider.tsx +64 -0
- package/src/shared/ui/molecules/slider/slider.types.ts +28 -0
- package/src/shared/ui/organisms/bar/bar.styles.ts +100 -0
- package/src/shared/ui/organisms/bar/bar.tsx +89 -0
- package/src/shared/ui/organisms/bar/bar.types.ts +49 -0
- package/src/shared/ui/organisms/bar/index.ts +2 -0
- package/src/shared/ui/organisms/bar-tab/bar-tab.tsx +9 -0
- package/src/shared/ui/organisms/bar-tab/bar-tab.types.ts +5 -0
- package/src/shared/ui/organisms/bar-tab/components/index.ts +1 -0
- package/src/shared/ui/organisms/bar-tab/components/tab/index.ts +2 -0
- package/src/shared/ui/organisms/bar-tab/components/tab/tab.styles.ts +21 -0
- package/src/shared/ui/organisms/bar-tab/components/tab/tab.tsx +18 -0
- package/src/shared/ui/organisms/bar-tab/components/tab/tab.types.ts +5 -0
- package/src/shared/ui/organisms/bar-tab/index.ts +2 -0
- package/src/shared/ui/organisms/bar-tab-navigation/bar-tab-navigation.styles.ts +22 -0
- package/src/shared/ui/organisms/bar-tab-navigation/bar-tab-navigation.tsx +66 -0
- package/src/shared/ui/organisms/bar-tab-navigation/bar-tab-navigation.types.ts +5 -0
- package/src/shared/ui/organisms/bar-tab-navigation/components/index.ts +1 -0
- package/src/shared/ui/organisms/bar-tab-navigation/components/tab-navigation/index.ts +2 -0
- package/src/shared/ui/organisms/bar-tab-navigation/components/tab-navigation/tab-navigation.styles.ts +56 -0
- package/src/shared/ui/organisms/bar-tab-navigation/components/tab-navigation/tab-navigation.tsx +30 -0
- package/src/shared/ui/organisms/bar-tab-navigation/components/tab-navigation/tab-navigation.types.ts +7 -0
- package/src/shared/ui/organisms/bar-tab-navigation/index.ts +2 -0
- package/src/shared/ui/organisms/index.ts +4 -1
- package/src/shared/ui/organisms/slider/components/indicator/components/dot/dot.styles.ts +41 -0
- package/src/shared/ui/organisms/slider/components/indicator/components/dot/dot.tsx +12 -0
- package/src/shared/ui/organisms/slider/components/indicator/components/dot/dot.types.ts +13 -0
- package/src/shared/ui/organisms/slider/components/indicator/components/dot/index.ts +2 -0
- package/src/shared/ui/organisms/slider/components/indicator/index.ts +2 -0
- package/src/shared/ui/organisms/slider/components/indicator/indicator.styles.ts +20 -0
- package/src/shared/ui/organisms/slider/components/indicator/indicator.tsx +22 -0
- package/src/shared/ui/organisms/slider/components/indicator/indicator.types.ts +10 -0
- package/src/shared/ui/organisms/slider/index.ts +3 -0
- package/src/shared/ui/organisms/slider/slider.styles.ts +68 -0
- package/src/shared/ui/organisms/slider/slider.tsx +64 -0
- package/src/shared/ui/organisms/slider/slider.types.ts +28 -0
- package/src/shared/ui/templates/index.ts +3 -0
- package/src/shared/ui/templates/modal-container/index.ts +13 -0
- package/src/shared/ui/templates/modal-container/modal-container-list.tsx +45 -0
- package/src/shared/ui/templates/modal-container/modal-container-scroll.tsx +66 -0
- package/src/shared/ui/templates/modal-container/modal-container-section-list.tsx +46 -0
- package/src/shared/ui/templates/modal-container/modal-container.hooks.tsx +172 -0
- package/src/shared/ui/templates/modal-container/modal-container.styles.ts +121 -0
- package/src/shared/ui/templates/modal-container/modal-container.types.ts +69 -0
- package/src/shared/ui/templates/screen-container/index.ts +1 -1
- package/src/shared/ui/templates/screen-container/screen-container-list.tsx +28 -10
- package/src/shared/ui/templates/screen-container/screen-container-scroll.tsx +28 -10
- package/src/shared/ui/templates/screen-container/screen-container-section-list.tsx +29 -11
- package/src/shared/ui/templates/screen-container/screen-container.hooks.tsx +79 -8
- package/src/shared/ui/templates/screen-container/screen-container.styles.ts +105 -15
- package/src/shared/ui/templates/screen-container/screen-container.types.tsx +34 -7
- package/src/shared/ui/templates/screen-header/components/index.ts +6 -0
- package/src/shared/ui/templates/screen-header/components/screen-header-description/index.ts +2 -0
- package/src/shared/ui/templates/screen-header/components/screen-header-description/screen-header-description.tsx +15 -0
- package/src/shared/ui/templates/screen-header/components/screen-header-description/screen-header-description.types.ts +11 -0
- package/src/shared/ui/templates/screen-header/components/screen-header-icon/index.ts +2 -0
- package/src/shared/ui/templates/screen-header/components/screen-header-icon/screen-header-icon.styles.ts +44 -0
- package/src/shared/ui/templates/screen-header/components/screen-header-icon/screen-header-icon.tsx +65 -0
- package/src/shared/ui/templates/screen-header/components/screen-header-icon/screen-header-icon.types.ts +14 -0
- package/src/shared/ui/templates/screen-header/components/screen-header-icon-back/index.ts +2 -0
- package/src/shared/ui/templates/screen-header/components/screen-header-icon-back/screen-header-icon-back.tsx +17 -0
- package/src/shared/ui/templates/screen-header/components/screen-header-icon-back/screen-header-icon-back.types.ts +6 -0
- package/src/shared/ui/templates/screen-header/components/screen-header-icon-close/index.ts +2 -0
- package/src/shared/ui/templates/screen-header/components/screen-header-icon-close/screen-header-icon-close.tsx +27 -0
- package/src/shared/ui/templates/screen-header/components/screen-header-icon-close/screen-header-icon-close.types.ts +10 -0
- package/src/shared/ui/templates/screen-header/components/screen-header-info/index.ts +2 -0
- package/src/shared/ui/templates/screen-header/components/screen-header-info/screen-header-info.tsx +15 -0
- package/src/shared/ui/templates/screen-header/components/screen-header-info/screen-header-info.types.ts +10 -0
- package/src/shared/ui/templates/screen-header/components/screen-header-title/index.ts +2 -0
- package/src/shared/ui/templates/screen-header/components/screen-header-title/screen-header-title.tsx +19 -0
- package/src/shared/ui/templates/screen-header/components/screen-header-title/screen-header-title.types.ts +13 -0
- package/src/shared/ui/templates/screen-header/index.ts +3 -0
- package/src/shared/ui/templates/screen-header/screen-header.styles.ts +49 -0
- package/src/shared/ui/templates/screen-header/screen-header.tsx +26 -0
- package/src/shared/ui/templates/screen-header/screen-header.types.ts +15 -0
- package/src/shared/ui/templates/web-container/index.ts +2 -0
- package/src/shared/ui/templates/web-container/web-container.styles.ts +34 -0
- package/src/shared/ui/templates/web-container/web-container.tsx +172 -0
- package/src/shared/ui/templates/web-container/web-container.types.ts +21 -0
- package/.claude/rules/app-routing.mdc +0 -47
- package/.claude/rules/exports-at-end.mdc +0 -55
- package/.claude/rules/kebab-case-naming.mdc +0 -29
- package/.claude/rules/mediacubeco-packages.mdc +0 -56
- package/.claude/skills/generate-api-model/SKILL.md +0 -230
- package/.claude/skills/generate-api-model/references/resources/common.ts +0 -8
- package/.claude/skills/generate-api-model-mock/SKILL.md +0 -56
- package/.claude/skills/git-commit/SKILL.md +0 -139
- package/.gitignore +0 -34
- package/src/shared/assets/icons/like.tsx +0 -17
- package/src/shared/hooks/use-animated.ts +0 -200
- package/src/shared/hooks/use-mixins.ts +0 -36
- package/src/shared/hooks/use-safe-area.ts +0 -75
- package/src/shared/lib/api/repositories/auth/auth.ts +0 -23
- package/src/shared/lib/api/repositories/auth/auth.types.ts +0 -22
- package/src/shared/lib/api/repositories/auth/index.ts +0 -1
- package/src/shared/lib/navigation/hooks/use-navigation-native-tabs.ts +0 -10
- package/src/shared/lib/navigation/hooks/use-navigation-options.ts +0 -123
- package/src/shared/lib/navigation/navigation-native-tabs.context.tsx +0 -5
- package/src/shared/lib/navigation/navigation-native-tabs.provider.tsx +0 -12
- package/src/shared/lib/theme/constants/borders.ts +0 -8
- package/src/shared/lib/theme/constants/weights.ts +0 -13
- /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/index.ts +0 -0
- /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/post/index.ts +0 -0
- /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/post/post-comment.ts +0 -0
- /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/post/post.ts +0 -0
- /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/user/index.ts +0 -0
- /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/user/user-settings.ts +0 -0
- /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/user/user-verification.ts +0 -0
- /package/.claude/skills/{generate-api-model/references → api/references/model}/entities/user/user.ts +0 -0
- /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/index.ts +0 -0
- /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/post/index.ts +0 -0
- /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/post/post-comment.ts +0 -0
- /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/post/post.ts +0 -0
- /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/user/index.ts +0 -0
- /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/user/user-settings.ts +0 -0
- /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/user/user-verification.ts +0 -0
- /package/.claude/skills/{generate-api-model/references → api/references/model}/resources/user/user.ts +0 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { create } from 'zustand'
|
|
2
|
+
import { createJSONStorage, persist } from 'zustand/middleware'
|
|
3
|
+
import { storageAsync } from '~shared/lib/storage'
|
|
4
|
+
|
|
5
|
+
/** Данные, сохраняемые в черновик при вводе текста поста. */
|
|
6
|
+
type PostDraftPayload = {
|
|
7
|
+
title: string
|
|
8
|
+
body: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** Состояние черновика нового поста. */
|
|
12
|
+
type PostDraftState = {
|
|
13
|
+
/** Заголовок черновика: персистится, переживает перезапуск приложения. */
|
|
14
|
+
title: string
|
|
15
|
+
/** Текст черновика: персистится, переживает перезапуск приложения. */
|
|
16
|
+
body: string
|
|
17
|
+
/** Признак открытого превью: живёт только в памяти, не персистится. */
|
|
18
|
+
isPreviewVisible: boolean
|
|
19
|
+
/** Сохранить черновик при вводе текста. */
|
|
20
|
+
setDraft: (payload: PostDraftPayload) => void
|
|
21
|
+
/** Переключить превью черновика. */
|
|
22
|
+
togglePreview: () => void
|
|
23
|
+
/** Сбросить черновик после публикации или отмены. */
|
|
24
|
+
clearDraft: () => void
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Стор черновика поста: текст в MMKV, состояние превью — в памяти. */
|
|
28
|
+
const usePostDraftStore = create<PostDraftState>()(
|
|
29
|
+
persist(
|
|
30
|
+
(set) => ({
|
|
31
|
+
title: '',
|
|
32
|
+
body: '',
|
|
33
|
+
isPreviewVisible: false,
|
|
34
|
+
setDraft: ({ title, body }) =>
|
|
35
|
+
set({
|
|
36
|
+
title,
|
|
37
|
+
body,
|
|
38
|
+
}),
|
|
39
|
+
togglePreview: () =>
|
|
40
|
+
set((state) => ({
|
|
41
|
+
isPreviewVisible: !state.isPreviewVisible,
|
|
42
|
+
})),
|
|
43
|
+
clearDraft: () =>
|
|
44
|
+
set({
|
|
45
|
+
title: '',
|
|
46
|
+
body: '',
|
|
47
|
+
isPreviewVisible: false,
|
|
48
|
+
}),
|
|
49
|
+
}),
|
|
50
|
+
{
|
|
51
|
+
name: 'post-draft',
|
|
52
|
+
storage: createJSONStorage(() => storageAsync),
|
|
53
|
+
partialize: (state) => ({
|
|
54
|
+
title: state.title,
|
|
55
|
+
body: state.body,
|
|
56
|
+
}),
|
|
57
|
+
}
|
|
58
|
+
)
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
export { usePostDraftStore }
|
|
62
|
+
export type { PostDraftState, PostDraftPayload }
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: design-style
|
|
3
|
+
description: >-
|
|
4
|
+
The project's design language for thinking through UI and UX: the target
|
|
5
|
+
character (fresh, laconic, explicit, fluid — yet strict), color chosen by
|
|
6
|
+
semantic role with one accent per composition and paired contrast, capsule
|
|
7
|
+
silhouettes and concentric corner rounding, the airy-but-strict spacing
|
|
8
|
+
hierarchy, steep-and-shallow typography where content is the ornament,
|
|
9
|
+
glass reserved for floating navigation, short purposeful motion with press
|
|
10
|
+
feedback picked by role, the single selection language (frame + check +
|
|
11
|
+
haptic), reuse-before-invention (grow the design system), show-don't-tell
|
|
12
|
+
settings, hero scenes, designing every state (loading, empty, error,
|
|
13
|
+
disabled, pending), UX guardrails, and edge-case resilience.
|
|
14
|
+
Use this skill EVERY time UI is designed, built, edited, or reviewed in this
|
|
15
|
+
project — new screens, widgets, components, cards, lists, pickers, forms,
|
|
16
|
+
settings options, empty states — and whenever colors, spacing, sizes, corner
|
|
17
|
+
radii, shadows, typography, animations, haptics, or press feedback appear in
|
|
18
|
+
the work, even for a small tweak. Also use when the user asks to make
|
|
19
|
+
something beautiful, fresh, modern, laconic, or "in our style", or asks why
|
|
20
|
+
a screen looks off.
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
# Design Style
|
|
24
|
+
|
|
25
|
+
How interfaces look, move, and respond in this project. The target character:
|
|
26
|
+
**fresh, laconic, explicit, fluid — yet strict.** Every rule below serves that
|
|
27
|
+
character; when improvising beyond the rules, optimize for it.
|
|
28
|
+
|
|
29
|
+
What those words mean operationally:
|
|
30
|
+
|
|
31
|
+
- **Fresh** — generous rounding, airy spacing, tight modern typography, real
|
|
32
|
+
data presented beautifully instead of decoration bolted on.
|
|
33
|
+
- **Laconic** — few elements, each earning its place; one accent per
|
|
34
|
+
composition; no visual noise, no gratuitous ornament.
|
|
35
|
+
- **Explicit** — state is always visible: selection has a frame and a check,
|
|
36
|
+
pressed things visibly press, disabled things look disabled. The user never
|
|
37
|
+
guesses.
|
|
38
|
+
- **Fluid yet strict** — everything that changes state animates, but motion is
|
|
39
|
+
short, purposeful, and never orchestrated into choreography. Movement
|
|
40
|
+
communicates; it does not entertain (hero scenes are the one exception, see
|
|
41
|
+
Motion).
|
|
42
|
+
|
|
43
|
+
This skill is about **decisions** — what the result looks and feels like and
|
|
44
|
+
why. How those decisions are written down (the theme tokens, the shared
|
|
45
|
+
components, the feedback props, the styles-hook layout) lives in the
|
|
46
|
+
`code-style` skill; both apply whenever UI code is written.
|
|
47
|
+
|
|
48
|
+
## Reuse before invention
|
|
49
|
+
|
|
50
|
+
The design system is the product of every screen shipped so far. Before
|
|
51
|
+
designing anything new, look for the existing component, pattern, or
|
|
52
|
+
composition that already solves the problem — and prefer extending it over
|
|
53
|
+
inventing a parallel one. A new visual pattern must *earn* its existence by
|
|
54
|
+
doing something no existing pattern can. Two screens that solve the same
|
|
55
|
+
problem differently feel like two apps; every reuse makes the next screen
|
|
56
|
+
cheaper and the whole app more coherent.
|
|
57
|
+
|
|
58
|
+
The same discipline applies to values: a new color, size, radius, or timing
|
|
59
|
+
is added **into** the system (so the whole app can use it and theming keeps
|
|
60
|
+
working) — never dropped beside it as a local one-off.
|
|
61
|
+
|
|
62
|
+
## Color
|
|
63
|
+
|
|
64
|
+
**Color is chosen by role, not by look.** Decide what the element *is* — a
|
|
65
|
+
screen plane, a surface, a border, a piece of text — and its color follows
|
|
66
|
+
from that role in the current theme. Never pick a color because it "looks
|
|
67
|
+
right today": that choice silently breaks the second theme and the accent
|
|
68
|
+
system.
|
|
69
|
+
|
|
70
|
+
- **Shades are steps, not new colors.** A lighter version of a semantic color
|
|
71
|
+
is a weaker intensity step of the same role — never a freshly invented
|
|
72
|
+
neighbor color.
|
|
73
|
+
- **The accent belongs to the user.** Anything accent-colored must follow the
|
|
74
|
+
user-chosen accent and recolor itself when the accent changes.
|
|
75
|
+
- **Every background has a paired content color.** Content on the accent, on
|
|
76
|
+
dark surfaces, on light surfaces — each pairing is defined by the system.
|
|
77
|
+
Never assume "white looks fine here"; it stops being fine one accent later.
|
|
78
|
+
- **One accent per composition.** The accent marks the single most important
|
|
79
|
+
thing on the screen; spending it twice spends it on nothing.
|
|
80
|
+
- A new color concept (a new accent, a new semantic status) is **built into**
|
|
81
|
+
the theme system so both themes and every accent handle it with zero extra
|
|
82
|
+
work at call sites. The single sanctioned exception: **artistic scene
|
|
83
|
+
colors** — ambient hero backdrops that deliberately ignore the theme,
|
|
84
|
+
declared once as explicit, documented art.
|
|
85
|
+
|
|
86
|
+
### Honest previews
|
|
87
|
+
|
|
88
|
+
When UI previews another theme, accent, or appearance (a theme picker, a mini
|
|
89
|
+
phone mock), draw it with the **real palette of the target** — never with
|
|
90
|
+
hand-picked "looks close" approximations. Real values make previews truthful
|
|
91
|
+
and self-updating when the design system evolves.
|
|
92
|
+
|
|
93
|
+
## Shape and rounding
|
|
94
|
+
|
|
95
|
+
The silhouette of this design is **soft and continuous**. Corners are
|
|
96
|
+
generous, and every radius is *reasoned* — derived from the element's own
|
|
97
|
+
anatomy, never picked by eye.
|
|
98
|
+
|
|
99
|
+
- **Capsule is the default shape for self-contained interactive elements** —
|
|
100
|
+
buttons, badges, chips, single-row cards. The radius is half the element's
|
|
101
|
+
height, derived from the same dimensions that build the element, so the
|
|
102
|
+
shape survives any size change.
|
|
103
|
+
- **Row containers are capsules of one row.** A card that stacks uniform rows
|
|
104
|
+
(a menu, a list) takes the capsule radius of a single row as its own corner
|
|
105
|
+
radius. This is the project's ideal card and the reference for "how round
|
|
106
|
+
is round".
|
|
107
|
+
- **Nested rounding is concentric.** An element inside a rounded container
|
|
108
|
+
gets the container's radius minus the gap to the container's edge; corners
|
|
109
|
+
then share a visual center and the margin reads even all the way around.
|
|
110
|
+
The inverse also holds: a frame *around* rounded content gets the content
|
|
111
|
+
radius plus the frame padding. Never give a nested element an arbitrary
|
|
112
|
+
smaller radius — mismatched corners are the fastest way to look cheap.
|
|
113
|
+
- **Cards are never square-ish.** A multi-row card derives its radius from
|
|
114
|
+
its own anatomy — inner content radius plus card padding, or the capsule
|
|
115
|
+
radius of its densest row. If a radius "looks fine" but reads flat next to
|
|
116
|
+
the menu card, it is too small — the menu card is the calibration
|
|
117
|
+
reference. Screen-level sheets and hero surfaces go larger still. When in
|
|
118
|
+
doubt, round more, not less.
|
|
119
|
+
|
|
120
|
+
## Spacing
|
|
121
|
+
|
|
122
|
+
Spacing carries the "airy but strict" feel. It follows one descending rhythm,
|
|
123
|
+
outermost to innermost — each level visibly airier than the one inside it:
|
|
124
|
+
|
|
125
|
+
1. **Between independent blocks on a screen** — the widest step; sections
|
|
126
|
+
must read as separate thoughts.
|
|
127
|
+
2. **Inside a card** — generous padding; content never touches the shell.
|
|
128
|
+
3. **Between the parts of a row** — icon, text, trailing control breathe but
|
|
129
|
+
clearly belong together.
|
|
130
|
+
4. **Between sibling tiles, label to card** — a small, consistent step.
|
|
131
|
+
5. **Between a value and its caption** — nearly touching; line height already
|
|
132
|
+
provides the air.
|
|
133
|
+
|
|
134
|
+
Section labels sit **outside** their card (uppercase, small, secondary,
|
|
135
|
+
aligned with the card's content inset) — the card stays pure content.
|
|
136
|
+
Symmetry is part of strictness: content inset on the left is matched on the
|
|
137
|
+
right; a divider that should align with text starts at the text's inset, not
|
|
138
|
+
at zero. Every derived layout value (tile sizes, divider insets, computed
|
|
139
|
+
radii) must have an auditable derivation — arithmetic, not eyeballing.
|
|
140
|
+
|
|
141
|
+
## Typography
|
|
142
|
+
|
|
143
|
+
The app speaks one typographic scale with tight, modern letter-spacing —
|
|
144
|
+
never recreate text styles by hand; always speak the scale.
|
|
145
|
+
|
|
146
|
+
- **Hierarchy is steep and shallow**: one heading level per screen (usually
|
|
147
|
+
on the hero), semibold for values, small secondary text for captions.
|
|
148
|
+
Weight signals importance: bold = headings, semibold = data/emphasis,
|
|
149
|
+
regular = prose.
|
|
150
|
+
- **The value–caption pair** is the workhorse of informational UI: the datum
|
|
151
|
+
first, prominent; its label beneath, small and secondary. Data first, label
|
|
152
|
+
second — the user scans values, not labels.
|
|
153
|
+
- **Long content is planned, not hoped away**: cap multi-line text at a
|
|
154
|
+
designed line count; shrink critical one-liners (IDs, serials) to fit
|
|
155
|
+
instead of ellipsizing them into uselessness.
|
|
156
|
+
- **Content is the ornament.** Before adding a decorative element, check
|
|
157
|
+
whether the data itself can be beautiful: native names, real numbers, a
|
|
158
|
+
live preview. A screen decorated with its own content ages better than one
|
|
159
|
+
decorated with clip-art.
|
|
160
|
+
|
|
161
|
+
## Materials
|
|
162
|
+
|
|
163
|
+
Three planes, strictly assigned:
|
|
164
|
+
|
|
165
|
+
1. **Glass — the floating navigation layer only**: the screen header and the
|
|
166
|
+
bottom bar. Glass signals "this floats above your content"; spending it on
|
|
167
|
+
content cards dilutes the signal and costs legibility.
|
|
168
|
+
2. **Blur** — scrims and overlays that must hint at what is underneath
|
|
169
|
+
(behind modals, under progress veils).
|
|
170
|
+
3. **Everything else is opaque.** Content is for reading; translucent content
|
|
171
|
+
is neither fresh nor strict, just hazy.
|
|
172
|
+
|
|
173
|
+
Layering in this design is done with fill contrast and rounding, not drop
|
|
174
|
+
shadows — shadows are rare and reserved for genuinely floating surfaces.
|
|
175
|
+
|
|
176
|
+
## Motion and interactivity
|
|
177
|
+
|
|
178
|
+
Motion exists to communicate state. The whole app moves on **one shared
|
|
179
|
+
tempo**: a standard beat for state changes, a shorter one for micro-feedback,
|
|
180
|
+
a longer one reserved for screen-scale transitions. An ad-hoc duration
|
|
181
|
+
invented for one animation breaks the tempo — timing is a system decision,
|
|
182
|
+
not a local one.
|
|
183
|
+
|
|
184
|
+
### Everything pressable responds
|
|
185
|
+
|
|
186
|
+
A pressable element with no visible reaction is broken feedback. Pick the
|
|
187
|
+
response by the element's role:
|
|
188
|
+
|
|
189
|
+
- **Rows and small utility targets** (menu items, list rows, header icons) —
|
|
190
|
+
the surface acknowledges the touch in place; the layout does not move.
|
|
191
|
+
- **Self-contained cards and standalone elements** (promo cards, tiles,
|
|
192
|
+
floating actions) — the element itself compresses slightly, like a physical
|
|
193
|
+
object under a finger.
|
|
194
|
+
- **Haptics — sparingly**, only where the action is *significant*: committing
|
|
195
|
+
a selection, toggling a control, destructive confirmation. Haptics on every
|
|
196
|
+
tap makes the phone buzz like a toy; scarcity is what makes it read as
|
|
197
|
+
importance.
|
|
198
|
+
|
|
199
|
+
### The selection language
|
|
200
|
+
|
|
201
|
+
Every "pick one of N" UI speaks the same dialect, whatever the content:
|
|
202
|
+
|
|
203
|
+
- an **animated frame** around the option — the border color fades in while
|
|
204
|
+
the border width stays constant, so color changes but layout never jumps;
|
|
205
|
+
- a **check or radio indicator** appearing by growing and fading in together;
|
|
206
|
+
- **haptics on the commit**.
|
|
207
|
+
|
|
208
|
+
Reuse this pattern; do not invent a second selection visual. Two screens that
|
|
209
|
+
select things differently feel like two apps.
|
|
210
|
+
|
|
211
|
+
### Choreography restraint
|
|
212
|
+
|
|
213
|
+
One property per state change, elements animating independently. No staggered
|
|
214
|
+
cascades, no multi-step sequences, no bounce for its own sake. If removing an
|
|
215
|
+
animation would lose no information, remove it — except:
|
|
216
|
+
|
|
217
|
+
### Hero scenes — the sanctioned exception
|
|
218
|
+
|
|
219
|
+
Showcase screens (sign-in, onboarding, big empty states) may carry **one**
|
|
220
|
+
ambient animated scene: slow, continuous, behind the content, never competing
|
|
221
|
+
with controls. Product screens get none. A hero scene is scenery, not UI — it
|
|
222
|
+
must be beautiful when ignored.
|
|
223
|
+
|
|
224
|
+
## Show, don't tell
|
|
225
|
+
|
|
226
|
+
A setting should **demonstrate its result, not describe it**. A theme option
|
|
227
|
+
shows a mini interface in that theme; a language option greets the user in
|
|
228
|
+
that language; an accent option is painted in that accent. If the user must
|
|
229
|
+
read a label to know what the option does, look for a way to make the option
|
|
230
|
+
*be* the answer. This is also why previews use real values (see Color): a
|
|
231
|
+
demonstration must be true.
|
|
232
|
+
|
|
233
|
+
## Every state is designed
|
|
234
|
+
|
|
235
|
+
A screen is not one picture — it is a small state machine, and **every state
|
|
236
|
+
the data can reach gets a designed face**. Shipping only the happy path is
|
|
237
|
+
the fastest way to make a polished app feel broken. Before calling any
|
|
238
|
+
surface done, walk its states:
|
|
239
|
+
|
|
240
|
+
- **Loading** — show structure, not a void: content-shaped placeholders where
|
|
241
|
+
the layout is known, a spinner only where it is not. A placeholder must match
|
|
242
|
+
the **exact size of the content it stands in for** — a text skeleton is as
|
|
243
|
+
tall as that text's rendered line box, a tile skeleton fills the tile — so the
|
|
244
|
+
real data drops into the same footprint without a single pixel of reflow. A
|
|
245
|
+
skeleton a different height than its content produces a visible jump the
|
|
246
|
+
moment data arrives, which reads as broken however smooth the shimmer looks.
|
|
247
|
+
Screens with server data render cached content immediately and refresh in the
|
|
248
|
+
background — never hide data the user already saw behind a loader.
|
|
249
|
+
- **Empty** — friendly and actionable: what this place is, why it is empty,
|
|
250
|
+
and one clear thing to do about it (a CTA when an action exists). An empty
|
|
251
|
+
screen is a first impression, not an error.
|
|
252
|
+
- **Error** — say what happened in human words and always offer a way out
|
|
253
|
+
(retry, go back). Danger color used sparingly, so it keeps its alarm value.
|
|
254
|
+
- **Disabled** — visibly inert and completely unresponsive: no ripple, no
|
|
255
|
+
compression, no haptics. A dead control that still reacts feels glitchy,
|
|
256
|
+
not strict.
|
|
257
|
+
- **Pending / in-flight** — every action acknowledges instantly: buttons show
|
|
258
|
+
progress, mutations prefer optimistic updates with rollback on failure. A
|
|
259
|
+
tap that goes unanswered while the network thinks is perceived as a bug.
|
|
260
|
+
|
|
261
|
+
Transitions between states animate (a crossfade on the standard tempo) inside
|
|
262
|
+
a stable layout — the state changes, the ground does not. This is the wider
|
|
263
|
+
rule: **the layout never shifts on its own.** A calm interface holds still —
|
|
264
|
+
content stays exactly where the user last saw it, and the only movement is
|
|
265
|
+
deliberate, smooth, and tied to something the user did or a real feature (a
|
|
266
|
+
sheet opening, an item the user just removed collapsing away). Space that will
|
|
267
|
+
be filled is reserved ahead of time; nothing reflows merely because data
|
|
268
|
+
arrived, an image decoded, or a boolean flipped. A jump that no feature asked
|
|
269
|
+
for is a bug, not a transition — the default character is static, fluid, and
|
|
270
|
+
tidy.
|
|
271
|
+
|
|
272
|
+
## UX guardrails
|
|
273
|
+
|
|
274
|
+
- **Touch targets stay comfortable.** A small glyph gets a padded pressable
|
|
275
|
+
area; never make the user aim.
|
|
276
|
+
- **Destructive actions are unmistakable**: danger color, an explicit
|
|
277
|
+
confirmation step, haptics on the commit.
|
|
278
|
+
- **Nothing moves under the finger.** Content the user is about to tap never
|
|
279
|
+
shifts because something loaded above it — reserve space or push new
|
|
280
|
+
content below the fold.
|
|
281
|
+
- **Local pending beats global blocking.** Show progress on the element that
|
|
282
|
+
is working; never freeze the whole screen for a partial operation.
|
|
283
|
+
- **Pull-to-refresh** exists on every screen with server data.
|
|
284
|
+
- **Forms follow the keyboard rules** from the `forms` skill: autofocus after
|
|
285
|
+
the transition, Enter walks the fields, Enter on the last field submits.
|
|
286
|
+
|
|
287
|
+
## Edge cases are part of the design
|
|
288
|
+
|
|
289
|
+
A design is judged at its worst moment, not its best screenshot:
|
|
290
|
+
|
|
291
|
+
- **Reserve space for things that change.** Crossfading or swapping content
|
|
292
|
+
gets a fixed-height stage so the layout never jumps.
|
|
293
|
+
- **Hide what degenerates.** A caption that would duplicate its title, a
|
|
294
|
+
translation that is missing — render nothing rather than noise.
|
|
295
|
+
- **Respect writing systems.** RTL scripts, non-Latin punctuation, and long
|
|
296
|
+
German words are inputs to layout, not surprises.
|
|
297
|
+
- **Both themes, all accents, always.** Verify light and dark and at least
|
|
298
|
+
one light accent (where the accent's paired content color is dark) before
|
|
299
|
+
calling UI done.
|
|
300
|
+
|
|
301
|
+
## Self-check before finishing a design
|
|
302
|
+
|
|
303
|
+
- Existing components and patterns reused; anything new earns its place and
|
|
304
|
+
is added into the system, not beside it.
|
|
305
|
+
- One accent per composition; every color chosen by role; every background
|
|
306
|
+
paired with its content color.
|
|
307
|
+
- Radii reasoned from element anatomy: capsules for interactive elements,
|
|
308
|
+
concentric nesting, the menu card as calibration — when in doubt, rounder.
|
|
309
|
+
- Spacing follows the descending rhythm; insets symmetric; labels outside
|
|
310
|
+
cards.
|
|
311
|
+
- Typography speaks the scale: one heading per screen, value–caption pairs,
|
|
312
|
+
long content planned.
|
|
313
|
+
- Every pressable responds according to its role; haptics only on significant
|
|
314
|
+
actions; selections use the frame + check language.
|
|
315
|
+
- Glass only on the floating navigation; content opaque.
|
|
316
|
+
- Every reachable state designed: loading, empty, error, disabled, pending;
|
|
317
|
+
overflow and RTL considered; both themes and a contrasting accent checked.
|
|
318
|
+
- Layout holds still: placeholders match the final content's size (a text
|
|
319
|
+
skeleton as tall as its line box), space reserved for what changes, no reflow
|
|
320
|
+
on load — motion happens only where a feature calls for it.
|
package/.env
CHANGED
package/.env.example
CHANGED
package/CLAUDE.md
CHANGED
|
@@ -10,7 +10,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
|
|
10
10
|
Create `.env.local` with:
|
|
11
11
|
|
|
12
12
|
```
|
|
13
|
-
|
|
13
|
+
EXPO_PUBLIC_APP_URL_API=https://...
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
Required at startup — `src/shared/constants/environment.ts` throws if is missing or `API_URL` doesn't start with `https://`.
|
|
@@ -38,7 +38,7 @@ ApiProvider → ThemeProvider → LocalizationProvider → NavigationProvider
|
|
|
38
38
|
|
|
39
39
|
- **ApiProvider** — TanStack Query with AsyncStorage persistence. Queries with `meta.persist = true` survive app restarts.
|
|
40
40
|
- **ThemeProvider** — light/dark/system mode stored in SecureStore. Theme tokens accessed via `useTheme()` / `useThemeMode()`.
|
|
41
|
-
- **LocalizationProvider** — i18next
|
|
41
|
+
- **LocalizationProvider** — i18next; the translations workflow lives in the `code-style` skill, section "Translations".
|
|
42
42
|
- **NavigationProvider** — wraps GestureHandler, SafeArea, KeyboardController, and `@react-navigation/native`'s ThemeProvider.
|
|
43
43
|
|
|
44
44
|
### API layer (`src/shared/lib/api/`)
|
|
@@ -63,19 +63,13 @@ Token constants live in `constants/` (colors, fonts, sizes, shadows, borders, du
|
|
|
63
63
|
|
|
64
64
|
Expo Router with file-based routing. Helper hooks:
|
|
65
65
|
|
|
66
|
-
- `
|
|
66
|
+
- `useNavigationRoute()` — thin wrapper around `useRouter()`
|
|
67
67
|
- `useNavigationParams()` — typed local params
|
|
68
|
-
- `useNavigationStackOptions()` —
|
|
69
|
-
- `useNavigationTabBarOptions()`
|
|
68
|
+
- `useNavigationStackOptions()` — ready option objects (`stackOptions`, `screenOptions`, `sheetOptions`, `webOptions`) plus `createXxxOptions(overrides)` factories
|
|
69
|
+
- `useNavigationTabBarOptions()` / `useNavigationTabBarNativeOptions()` — tab bar options (custom / native tabs)
|
|
70
70
|
|
|
71
71
|
### Shared UI (`src/shared/ui/`)
|
|
72
72
|
|
|
73
73
|
Atomic design: `atoms/` → `molecules/` → `organisms/` → `templates/`.
|
|
74
74
|
|
|
75
75
|
`ScreenContainer` (in `templates/`) is the standard scrollable/list screen wrapper — handles safe area, pull-to-refresh (`RefreshControl`), keyboard avoidance (`KeyboardArea`), and header/footer overflow.
|
|
76
|
-
|
|
77
|
-
Utility hooks in `src/shared/hooks/`: `useTheme`, `useBreakpoints` (responsive breakpoints), `useMixins` (window-relative sizing), `useSafeArea`, `useAnimated`.
|
|
78
|
-
|
|
79
|
-
### Secrets
|
|
80
|
-
|
|
81
|
-
`.secret/` is git-ignored. Keystore and provisioning files go there — see `.secret/README.md` for the expected file list.
|
package/app.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"expo": {
|
|
3
3
|
"name": "expo-template-fsd",
|
|
4
4
|
"slug": "expo-template-fsd",
|
|
5
|
-
"scheme": "
|
|
5
|
+
"scheme": "expo-template-fsd",
|
|
6
6
|
"version": "1.0.0",
|
|
7
7
|
"orientation": "portrait",
|
|
8
8
|
"userInterfaceStyle": "automatic",
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
},
|
|
13
13
|
"ios": {
|
|
14
14
|
"supportsTablet": true,
|
|
15
|
+
"usesAppleSignIn": true,
|
|
15
16
|
"bundleIdentifier": "com.mediacube.application",
|
|
16
17
|
"icon": "./src/shared/assets/images/logo-ios.png"
|
|
17
18
|
},
|
|
@@ -19,7 +20,7 @@
|
|
|
19
20
|
"predictiveBackGestureEnabled": false,
|
|
20
21
|
"package": "com.mediacube.application",
|
|
21
22
|
"adaptiveIcon": {
|
|
22
|
-
"backgroundColor": "#
|
|
23
|
+
"backgroundColor": "#ffffff",
|
|
23
24
|
"foregroundImage": "./src/shared/assets/images/logo-android-foreground.png",
|
|
24
25
|
"backgroundImage": "./src/shared/assets/images/logo-android-background.png",
|
|
25
26
|
"monochromeImage": "./src/shared/assets/images/logo-android-monochrome.png"
|
|
@@ -29,14 +30,16 @@
|
|
|
29
30
|
["expo-font", {}],
|
|
30
31
|
["expo-image", {}],
|
|
31
32
|
["expo-router", {}],
|
|
33
|
+
["expo-sharing", {}],
|
|
32
34
|
["expo-system-ui", {}],
|
|
33
35
|
["expo-web-browser", {}],
|
|
34
36
|
["expo-localization", {}],
|
|
35
37
|
["expo-secure-store", {}],
|
|
38
|
+
["expo-build-properties", {}],
|
|
36
39
|
[
|
|
37
40
|
"expo-splash-screen",
|
|
38
41
|
{
|
|
39
|
-
"backgroundColor": "#
|
|
42
|
+
"backgroundColor": "#ffffff",
|
|
40
43
|
"android": {
|
|
41
44
|
"image": "./src/shared/assets/images/splash-light.png",
|
|
42
45
|
"dark": {
|
package/axios.d.ts
ADDED
package/env.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,58 +1,46 @@
|
|
|
1
1
|
{
|
|
2
2
|
"private": false,
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.1",
|
|
4
4
|
"name": "@mediacubeco/expo-template-fsd",
|
|
5
5
|
"description": "Application by Mediacube developers",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "expo-router/entry",
|
|
9
|
-
"files": [
|
|
10
|
-
".agents",
|
|
11
|
-
".claude",
|
|
12
|
-
".husky",
|
|
13
|
-
".secret",
|
|
14
|
-
"src",
|
|
15
|
-
".env",
|
|
16
|
-
".env.example",
|
|
17
|
-
".gitignore",
|
|
18
|
-
"AGENTS.md",
|
|
19
|
-
"app.json",
|
|
20
|
-
"CLAUDE.md",
|
|
21
|
-
"eas.json",
|
|
22
|
-
"env.d.ts",
|
|
23
|
-
"eslint.config.js",
|
|
24
|
-
"expo-env.d.ts",
|
|
25
|
-
"i18next.d.ts",
|
|
26
|
-
"package-lock.json",
|
|
27
|
-
"package.json",
|
|
28
|
-
"prettier.config.js",
|
|
29
|
-
"README.md",
|
|
30
|
-
"skills-lock.json",
|
|
31
|
-
"svg.d.ts",
|
|
32
|
-
"tsconfig.json"
|
|
33
|
-
],
|
|
34
9
|
"keywords": [
|
|
35
10
|
"mediacube",
|
|
36
11
|
"mediacubeco",
|
|
37
12
|
"application"
|
|
38
13
|
],
|
|
39
14
|
"dependencies": {
|
|
15
|
+
"@dev-plugins/react-native-mmkv": "^0.4.0",
|
|
16
|
+
"@dev-plugins/react-navigation": "^0.4.0",
|
|
17
|
+
"@dev-plugins/react-query": "^0.4.0",
|
|
40
18
|
"@tanstack/query-async-storage-persister": "^5.99.0",
|
|
41
19
|
"@tanstack/react-query": "^5.99.0",
|
|
42
20
|
"@tanstack/react-query-persist-client": "^5.99.0",
|
|
21
|
+
"@sbaiahmed1/react-native-blur": "^4.6.4-beta.1",
|
|
22
|
+
"@shopify/flash-list": "2.0.2",
|
|
23
|
+
"@shopify/react-native-skia": "2.6.2",
|
|
24
|
+
"axios": "^1.18.1",
|
|
43
25
|
"expo": "~56.0.8",
|
|
44
26
|
"expo-blur": "~56.0.3",
|
|
27
|
+
"expo-build-properties": "~56.0.19",
|
|
45
28
|
"expo-constants": "~56.0.16",
|
|
29
|
+
"expo-dev-client": "~56.0.20",
|
|
46
30
|
"expo-device": "~56.0.4",
|
|
31
|
+
"expo-file-system": "~56.0.8",
|
|
47
32
|
"expo-font": "~56.0.5",
|
|
48
33
|
"expo-glass-effect": "~56.0.4",
|
|
49
34
|
"expo-haptics": "~56.0.3",
|
|
50
35
|
"expo-image": "~56.0.9",
|
|
36
|
+
"expo-linear-gradient": "~56.0.4",
|
|
51
37
|
"expo-linking": "~56.0.13",
|
|
52
38
|
"expo-localization": "~56.0.6",
|
|
53
39
|
"expo-navigation-bar": "~56.0.3",
|
|
40
|
+
"expo-network": "~56.0.5",
|
|
54
41
|
"expo-router": "~56.2.8",
|
|
55
42
|
"expo-secure-store": "~56.0.4",
|
|
43
|
+
"expo-sharing": "~56.0.20",
|
|
56
44
|
"expo-splash-screen": "~56.0.10",
|
|
57
45
|
"expo-status-bar": "~56.0.4",
|
|
58
46
|
"expo-symbols": "~56.0.5",
|
|
@@ -66,36 +54,41 @@
|
|
|
66
54
|
"react-native": "0.85.3",
|
|
67
55
|
"react-native-gesture-handler": "~2.31.2",
|
|
68
56
|
"react-native-keyboard-controller": "1.21.6",
|
|
57
|
+
"react-native-mmkv": "^4.3.1",
|
|
58
|
+
"react-native-nitro-cookies": "^1.2.0",
|
|
59
|
+
"react-native-nitro-modules": "^0.35.9",
|
|
69
60
|
"react-native-reanimated": "4.3.1",
|
|
70
61
|
"react-native-safe-area-context": "~5.7.0",
|
|
71
62
|
"react-native-screens": "~4.25.2",
|
|
72
63
|
"react-native-svg": "15.15.4",
|
|
73
64
|
"react-native-web": "^0.21.0",
|
|
65
|
+
"react-native-webview": "13.16.1",
|
|
74
66
|
"react-native-worklets": "0.8.3",
|
|
75
|
-
"@mediacubeco/base": "2.
|
|
76
|
-
"@mediacubeco/base-react
|
|
77
|
-
"@mediacubeco/base-react": "2.
|
|
67
|
+
"@mediacubeco/base": "2.4.0",
|
|
68
|
+
"@mediacubeco/base-react": "2.4.0",
|
|
69
|
+
"@mediacubeco/base-react-native": "2.4.0"
|
|
78
70
|
},
|
|
79
71
|
"devDependencies": {
|
|
80
72
|
"@types/react": "^19.2.0",
|
|
81
73
|
"@types/react-dom": "^19.2.3",
|
|
82
74
|
"eslint": "^9.39.1",
|
|
75
|
+
"patch-package": "^8.0.1",
|
|
83
76
|
"husky": "^9.1.7",
|
|
84
77
|
"prettier": "^3.8.1",
|
|
85
78
|
"typescript": "^6.0.3",
|
|
86
|
-
"@mediacubeco/eslint-config": "2.
|
|
87
|
-
"@mediacubeco/
|
|
88
|
-
"@mediacubeco/
|
|
89
|
-
"@mediacubeco/
|
|
90
|
-
"@mediacubeco/
|
|
91
|
-
"@mediacubeco/
|
|
92
|
-
"@mediacubeco/
|
|
93
|
-
"@mediacubeco/
|
|
94
|
-
"@mediacubeco/typescript-config-react": "2.
|
|
95
|
-
"@mediacubeco/
|
|
79
|
+
"@mediacubeco/eslint-config": "2.4.0",
|
|
80
|
+
"@mediacubeco/eslint-config-fsd": "2.4.0",
|
|
81
|
+
"@mediacubeco/eslint-config-react": "2.4.0",
|
|
82
|
+
"@mediacubeco/eslint-config-react-native": "2.4.0",
|
|
83
|
+
"@mediacubeco/prettier-config": "2.4.0",
|
|
84
|
+
"@mediacubeco/prettier-config-fsd": "2.4.0",
|
|
85
|
+
"@mediacubeco/typescript-config-fsd": "2.4.0",
|
|
86
|
+
"@mediacubeco/typescript-config": "2.4.0",
|
|
87
|
+
"@mediacubeco/typescript-config-react": "2.4.0",
|
|
88
|
+
"@mediacubeco/typescript-config-react-native": "2.4.0"
|
|
96
89
|
},
|
|
97
90
|
"scripts": {
|
|
98
|
-
"postinstall": "
|
|
91
|
+
"postinstall": "patch-package && npm run prebuild && npx skills update",
|
|
99
92
|
"prebuild": "expo prebuild",
|
|
100
93
|
"start": "expo start",
|
|
101
94
|
"android": "expo run:android",
|