Files
01c352636c feat(mobile): upgrade Expo SDK to v55 (#7433)
* feat(mobile): upgrade Expo SDK to v55

Upgrade Expo SDK from v54 to v55, along with React Native 0.83.4,
React 19.2, and all related dependencies.

Key changes:
- Refactored @safe-global/theme to use sub-path exports to fix RN
  import resolution issues
- Added react-native patch for Appearance.setColorScheme bug
  (facebook/react-native#08d176453) not yet in 0.83.4 release
- Replaced Tamagui Skeleton with custom SafeSkeleton component
- Updated expo config plugins for SDK 55 compatibility

* fix: downgrade eslint-config-next to v15 to match next.js version

eslint-config-next v16 requires next v16 but the project uses next
v15.5.8. The v16 package tries to import next/dist/compiled/babel/
eslint-parser which doesn't exist in next v15.

* fix: migrate packages away from eslint-config-next

eslint-config-next requires next at runtime for its babel parser,
but next is only installed in apps/web. After the Expo SDK v55
upgrade changed dependency hoisting, the parser became unreachable.

- Create shared config/eslint/base.mjs using direct plugin imports
- Migrate store, theme, utils, and tx-builder to the shared config
- Add packageExtensions in .yarnrc.yml so eslint-config-next in
  apps/web can still resolve next as a peer dependency

* chore: align react 19.2 across workspaces and fix MUI peer dep

- Bump react/react-dom to 19.2.0 in web and tx-builder to match
  mobile
- Add @mui/material as optional peer dependency in theme package to
  avoid duplicate installations causing type conflicts

* chore(mobile): update storybook on mobile to v10

* fix(web): resolve @emotion/react hoisting issue after Expo SDK 55 upgrade

Yarn 4's node-modules hoisting shifted after dependency graph changes,
leaving @emotion/react only in apps/web/node_modules while @mui/styled-engine
remained at root. Add webpack resolve aliases to ensure Next.js finds emotion
packages from the web workspace.

* fix(web): resolve @emotion hoisting issue in Jest config

Same hoisting fix as next.config.mjs but for Jest's module resolution.
Add moduleNameMapper entries for @emotion/react and @emotion/styled.

* fix(tx-builder): prettier

* fix: resolve type-check errors after Expo SDK 55 upgrade

- Fix BlurView tint prop: map ColorSchemeName to valid BlurTint values
- Replace @storybook/test imports with storybook/test (merged in v10)
- Align @types/react (~19.2.10) and @types/react-dom (~19.2.0) across
  all workspaces to prevent duplicate @mui/material type mismatches
- Spread visuallyHidden into sx prop for @types/react 19.2.x compat
- Add @types/react, @types/react-dom, storybook to yarn version checker

* chore: align more dependencies

* chore(web): update storybook snapshot

* fix(mobile): normalize color scheme and deduplicate MUI/emotion packages

- Normalize useTheme colorScheme to 'light' | 'dark', never 'unspecified'
  so TamaguiProvider always receives a valid theme name
- Update ColorScheme type to exclude 'unspecified'
- Remove redundant ?? 'light' fallbacks in SafeThemeProvider
- Align @emotion/* and @mui/icons-material versions across workspaces
  to prevent Yarn from creating duplicate lockfile resolutions
- Remove emotion webpack/Jest aliases (no longer needed after dedup)
- Add @emotion/react, @emotion/styled, @mui/material, @mui/icons-material
  to yarn version consistency checker

---------

Co-authored-by: Hanzo Dev <[email protected]>
2026-03-18 09:29:16 +01:00

87 lines
2.9 KiB
TypeScript

import type { StorybookConfig as WebStorybookConfig } from '@storybook/react-webpack5'
import type { StorybookConfig as RNStorybookConfig } from '@storybook/react-native'
import path from 'path'
import { fileURLToPath } from 'url'
import TsconfigPathsPlugin from 'tsconfig-paths-webpack-plugin'
import { globSync } from 'glob'
const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)
let config: WebStorybookConfig | RNStorybookConfig
const isWeb = process.env.STORYBOOK_WEB
const appDirectory = path.resolve(__dirname, '../')
if (isWeb) {
/**
* We have some stories that require native modules, and they don't have
* any equivalents in web. If we have such a story, we need to ignore it
* otherwise webpack will fail to compile.
*
* https://github.com/storybookjs/storybook/issues/11181
*/
const getStories = () => {
return [
...globSync(`${appDirectory}/src/**/*.mdx)`),
...globSync(`${appDirectory}/src/**/*.stories.@(js|jsx|ts|tsx|mdx)`, {
ignore: `${appDirectory}/src/**/*.native.stories.@(js|jsx|ts|tsx|mdx)`,
}),
]
}
config = {
stories: [...getStories()],
addons: [
{
name: '@storybook/addon-react-native-web',
options: {
projectRoot: '../',
modulesToTranspile: [],
},
},
],
/**
* Use standard framework configuration instead of path resolution.
* The path resolution workaround causes issues in CI environments.
*/
framework: {
name: '@storybook/react-webpack5',
options: {},
},
core: {
disableTelemetry: true,
},
webpackFinal: async (config) => {
if (config.resolve) {
config.resolve.plugins = [
...(config.resolve.plugins || []),
new TsconfigPathsPlugin({
extensions: config.resolve.extensions,
}),
]
config.resolve.alias = {
...config.resolve.alias,
'@': path.resolve(__dirname, '../'),
// Mock React Native modules for web environment
'react-native-worklets': path.resolve(__dirname, './mocks/react-native-worklets'),
'react-native-reanimated': path.resolve(__dirname, './mocks/react-native-reanimated.js'),
'react-native-quick-crypto': path.resolve(__dirname, './mocks/react-native-quick-crypto.js'),
// Mock react-refresh to prevent production bundle errors
'react-refresh/runtime': path.resolve(__dirname, './mocks/react-refresh.js'),
'react-refresh': path.resolve(__dirname, './mocks/react-refresh.js'),
}
}
return config
},
} as WebStorybookConfig
} else {
config = {
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
addons: ['@storybook/addon-ondevice-controls', '@storybook/addon-ondevice-actions'],
} as RNStorybookConfig
}
export default config