diff --git a/.prettierignore b/.prettierignore index 72079094..b109670a 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,8 @@ ios/Pods +ios +.github/workflows .yarn android/app/.cxx -CHANGELOG.md \ No newline at end of file +android/app/build +android/build +CHANGELOG.md diff --git a/MIGRATION.md b/MIGRATION.md new file mode 100644 index 00000000..bf312246 --- /dev/null +++ b/MIGRATION.md @@ -0,0 +1,79 @@ +# Миграция на Unistyles V3 + +Стили переведены на `react-native-unistyles`. Удален собственный `React Context` +и провайдер. + +## Изменения + +### `ThemeContextProvider` — удалён + +Темы регистрируются автоматически. Обёртка больше не нужна. + +### `useFonts` — deprecated + +Используйте `useUnistyles`: + +```tsx +import { useUnistyles } from '@cdek-it/react-native-ui-kit' + +const { theme } = useUnistyles() +theme.fonts +``` + +Или прямо в стилях через `StyleSheet.create(...)`. + +### `makeStyles` — deprecated + +Используйте `StyleSheet.create(...)`: + +```tsx +import { StyleSheet } from '@cdek-it/react-native-ui-kit' + +const styles = StyleSheet.create((theme) => ({ + container: { backgroundColor: theme.Button.Brand.buttonBg }, +})) +``` + +`makeStyles` использует `useUnistyles()`, что вызывает React-ререндеры при смене +темы. `StyleSheet.create(...)` — нативный путь, обновляет стили **без** +ререндеров. + +SDK реэкспортирует `StyleSheet`, `useUnistyles`, `UnistylesRuntime` и +`withUnistyles`, поэтому потребителям не нужно импортировать +`react-native-unistyles` напрямую. + +### `useTheme()` — deprecated + +```tsx +import { UnistylesRuntime, useUnistyles } from '@cdek-it/react-native-ui-kit' + +const themeName = UnistylesRuntime.themeName // 'light' | 'dark' +``` + +Для реактивного поведения используйте `useUnistyles()`: + +```tsx +const { rt } = useUnistyles() +rt.themeName +``` + +### `useChangeTheme()` — deprecated + +```tsx +import { UnistylesRuntime } from '@cdek-it/react-native-ui-kit' + +UnistylesRuntime.setTheme('dark') +``` + +## Babel конфигурация + +Для получения нативного обновления стилей без React-ререндеров: + +1. Используйте `StyleSheet.create(...)`. +2. Добавьте `autoProcessPaths` в Babel-конфиг вашего приложения. + +Документация: + +- [useUnistyles](https://www.unistyl.es/v3/references/use-unistyles/) +- [StyleSheet](https://www.unistyl.es/v3/references/stylesheet/) +- [Babel plugin](https://www.unistyl.es/v3/other/babel-plugin/) diff --git a/eslint.config.ts b/eslint.config.ts index 509fd717..063ecab3 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -5,9 +5,28 @@ import { MobileConfig } from './configs/eslint' export default defineConfig([ ...MobileConfig, { files: ['configs/eslint/**/*'], rules: { 'max-lines': 'off' } }, + // Временное решение до миграции компонентов + { + files: ['src/components/**/*.{ts,tsx}'], + rules: { '@typescript-eslint/no-deprecated': 'off' }, + }, { ignores: [ + 'node_modules/**/*', + '.expo/**/*', + '.git/**/*', + '.idea/**/*', 'dist/**/*', + 'build/**/*', + 'coverage/**/*', + '**/*.min.js', + '.gradle/**/*', + 'android/**/*', + 'ios/**/*', + '.yarn/**/*', + '.vscode/**/*', + '.jest/**/*', + '.gemini/**/*', '.storybook/**/*', 'configs/cz-conventional-mobile/**/*', ], diff --git a/jest.config.ts b/jest.config.ts index b5a706d8..f0700547 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -14,7 +14,7 @@ const config: Config.InitialOptions = { coverageReporters: ['text', 'text-summary'], moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], testRunner: 'jest-circus', - maxWorkers: 4, + maxWorkers: '100%', rootDir: '.', moduleNameMapper: { '\\.svg': '/__mocks__/svgMock.js' }, setupFiles: ['/jest.setup.ts'], diff --git a/jest.d.ts b/jest.d.ts index a86a4041..d41f79d0 100644 --- a/jest.d.ts +++ b/jest.d.ts @@ -3,3 +3,9 @@ type PropertyCombinations = { [K in keyof T]: Array } declare let generatePropsCombinations: ( properties: PropertyCombinations ) => T[] + +declare module '@react-native/normalize-colors' { + const normalizeColors: (color: string | number) => number | null + + export default normalizeColors +} diff --git a/jest.setup.ts b/jest.setup.ts index 5fbb78c5..28a57c3f 100644 --- a/jest.setup.ts +++ b/jest.setup.ts @@ -1,9 +1,56 @@ import 'jest-extended' import 'react-native-gesture-handler/jestSetup' import { setUpTests } from 'react-native-reanimated' +import 'react-native-unistyles/mocks' setUpTests() +type ThemeName = 'light' | 'dark' + +interface MockedUnistylesModule { + StyleSheet: { create: (...args: unknown[]) => unknown } + UnistylesRuntime: { + miniRuntime: unknown + setTheme: jest.Mock + themeName: ThemeName | undefined + } + useUnistyles: jest.Mock + withUnistyles: jest.Mock +} + +const { darkTheme, lightTheme } = require('./src/theme') + +const unistyles = jest.requireMock( + 'react-native-unistyles' +) as MockedUnistylesModule + +const getTheme = (themeName: ThemeName | undefined) => + themeName === 'dark' ? darkTheme : lightTheme + +const originalStyleSheetCreate = unistyles.StyleSheet.create +const runtime = unistyles.UnistylesRuntime + +runtime.themeName = 'light' +runtime.setTheme = jest.fn((themeName: ThemeName) => { + runtime.themeName = themeName +}) + +unistyles.useUnistyles = jest.fn(() => ({ + theme: getTheme(runtime.themeName), + rt: runtime, +})) + +unistyles.StyleSheet.create = jest.fn( + (stylesheet: Parameters[0]) => + typeof stylesheet === 'function' + ? originalStyleSheetCreate(() => + stylesheet(getTheme(runtime.themeName), runtime.miniRuntime) + ) + : originalStyleSheetCreate(stylesheet) +) + +unistyles.withUnistyles = jest.fn((Component: T) => Component) + generatePropsCombinations = (properties: PropertyCombinations): T[] => { const keys = Object.keys(properties) as Array diff --git a/package.json b/package.json index 9f0494ed..af6da0b2 100644 --- a/package.json +++ b/package.json @@ -33,8 +33,8 @@ "storybook-generate": "sb-rn-get-stories --config-path .storybook && sed -i -e 's/export const view = global.view/export const view: ReturnType = global.view/' .storybook/storybook.requires.ts && prettier .storybook --write", "doctor": "expo-doctor", "check": "expo install --check", - "lint:check": "eslint .", - "lint:fix": "eslint --fix .", + "lint:check": "eslint --cache .", + "lint:fix": "eslint --fix --cache .", "prettier:check": "prettier . --check", "prettier:fix": "prettier . --write", "prettier:watch": "onchange . -- prettier --write --ignore-unknown \"{{changed}}\"", @@ -42,7 +42,8 @@ "pod-install": "bundle exec pod install --project-directory=ios" }, "dependencies": { - "@tabler/icons-react-native": "^3.36.0" + "@tabler/icons-react-native": "3.36.1", + "react-native-unistyles": "3.2.3" }, "devDependencies": { "@babel/core": "7.28.5", @@ -106,6 +107,7 @@ "react-native": "0.81.5", "react-native-advanced-input-mask": "1.4.6", "react-native-gesture-handler": "2.29.1", + "react-native-nitro-modules": "0.35.2", "react-native-reanimated": "4.1.1", "react-native-safe-area-context": "5.6.2", "react-native-svg": "15.15.1", diff --git a/src/components/Accordion/__tests__/__snapshots__/Accordion.test.tsx.snap b/src/components/Accordion/__tests__/__snapshots__/Accordion.test.tsx.snap index 163abe4c..f17b7d8b 100644 --- a/src/components/Accordion/__tests__/__snapshots__/Accordion.test.tsx.snap +++ b/src/components/Accordion/__tests__/__snapshots__/Accordion.test.tsx.snap @@ -344,7 +344,7 @@ exports[`Accordion Header elements maximal 1`] = ` strokeWidth={2} > { + beforeEach(() => { + jest.clearAllMocks() + }) + + test('вызывает UnistylesRuntime.setTheme с "light" для ThemeVariant.Light', () => { + const { result } = renderHook(() => useChangeTheme()) + + act(() => { + result.current(ThemeVariant.Light) + }) + + expect(UnistylesRuntime.setTheme).toHaveBeenCalledWith('light') + }) + + test('вызывает UnistylesRuntime.setTheme с "dark" для ThemeVariant.Dark', () => { + const { result } = renderHook(() => useChangeTheme()) + + act(() => { + result.current(ThemeVariant.Dark) + }) + + expect(UnistylesRuntime.setTheme).toHaveBeenCalledWith('dark') + }) + + test('возвращает стабильную ссылку на callback', () => { + const { result, rerender } = renderHook(() => useChangeTheme()) + const first = result.current + + rerender({}) + + expect(result.current).toBe(first) + }) +}) diff --git a/src/hooks/__tests__/useChangeTheme.test.tsx b/src/hooks/__tests__/useChangeTheme.test.tsx deleted file mode 100644 index f1e5c2b4..00000000 --- a/src/hooks/__tests__/useChangeTheme.test.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import { renderHook } from '@testing-library/react-native' - -import { ThemeContext, ThemeVariant } from '../../theme' -import { useChangeTheme } from '../useChangeTheme' - -describe('useChangeTheme', () => { - test('returns correct function', () => { - const mockedChangeTheme = jest.fn() - const { result } = renderHook(() => useChangeTheme(), { - wrapper: ({ children }) => ( - - {children} - - ), - }) - - expect(result.current).toStrictEqual(expect.any(Function)) - - result.current?.(ThemeVariant.Dark) - - expect(mockedChangeTheme).toHaveBeenCalledWith(ThemeVariant.Dark) - }) -}) diff --git a/src/hooks/__tests__/useTheme.test.ts b/src/hooks/__tests__/useTheme.test.ts new file mode 100644 index 00000000..c4cd5982 --- /dev/null +++ b/src/hooks/__tests__/useTheme.test.ts @@ -0,0 +1,32 @@ +/* eslint-disable @typescript-eslint/no-deprecated -- Проверяем deprecated API на обратную совместимость. */ +import { renderHook } from '@testing-library/react-native' +import { UnistylesRuntime } from 'react-native-unistyles' + +import { ThemeVariant } from '../../theme' +import { useTheme } from '../useTheme' + +const setThemeName = (themeName: 'light' | 'dark') => { + Object.assign(UnistylesRuntime, { themeName }) +} + +describe('useTheme', () => { + afterEach(() => { + setThemeName('light') + }) + + test('возвращает ThemeVariant.Light, когда активна светлая тема', () => { + setThemeName('light') + + const { result } = renderHook(() => useTheme()) + + expect(result.current).toBe(ThemeVariant.Light) + }) + + test('возвращает ThemeVariant.Dark, когда активна тёмная тема', () => { + setThemeName('dark') + + const { result } = renderHook(() => useTheme()) + + expect(result.current).toBe(ThemeVariant.Dark) + }) +}) diff --git a/src/hooks/__tests__/useTheme.test.tsx b/src/hooks/__tests__/useTheme.test.tsx deleted file mode 100644 index bcb3fcf5..00000000 --- a/src/hooks/__tests__/useTheme.test.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { renderHook } from '@testing-library/react-native' - -import { ThemeContextProvider, ThemeVariant } from '../../theme' -import { useTheme } from '../useTheme' - -describe('useTheme', () => { - test('returns correct function', () => { - const { result } = renderHook(() => useTheme(), { - wrapper: ({ children }) => ( - {children} - ), - }) - - expect(Object.values(ThemeVariant)).toContain(result.current) - }) -}) diff --git a/src/hooks/useChangeTheme.ts b/src/hooks/useChangeTheme.ts index 896e21ff..f0f889d0 100644 --- a/src/hooks/useChangeTheme.ts +++ b/src/hooks/useChangeTheme.ts @@ -1,7 +1,21 @@ -import { useContext } from 'react' +import { useCallback } from 'react' +import { UnistylesRuntime } from 'react-native-unistyles' -import { ThemeContext } from '../theme' +import { ThemeVariant } from '../theme' +const THEME_MAP: Record = { + [ThemeVariant.Light]: 'light', + [ThemeVariant.Dark]: 'dark', +} + +/** + * Возвращает callback для переключения темы. + * + * @deprecated Используйте `UnistylesRuntime.setTheme` из SDK напрямую. + * Будет удалён в следующей minor версии. + */ export const useChangeTheme = () => { - return useContext(ThemeContext).changeTheme + return useCallback((theme: ThemeVariant) => { + UnistylesRuntime.setTheme(THEME_MAP[theme]) + }, []) } diff --git a/src/hooks/useFonts.ts b/src/hooks/useFonts.ts index 9bd519d7..5c70ec8b 100644 --- a/src/hooks/useFonts.ts +++ b/src/hooks/useFonts.ts @@ -1,7 +1,16 @@ -import { useContext } from 'react' +import { useUnistyles } from 'react-native-unistyles' -import { ThemeContext } from '../theme' +import type { FontsConfig } from '../theme' -export const useFonts = () => { - return useContext(ThemeContext).fonts +/** + * Возвращает конфигурацию шрифтов. + * + * @deprecated Используйте `useUnistyles().theme.fonts` или `StyleSheet.create(...)` + * из SDK. + * Будет удалён в следующей minor версии. + */ +export const useFonts = (): FontsConfig => { + const { theme } = useUnistyles() + + return theme.fonts } diff --git a/src/hooks/useTheme.ts b/src/hooks/useTheme.ts index 5f9057af..3e8b5ab9 100644 --- a/src/hooks/useTheme.ts +++ b/src/hooks/useTheme.ts @@ -1,7 +1,14 @@ -import { useContext } from 'react' +import { UnistylesRuntime } from 'react-native-unistyles' -import { ThemeContext } from '../theme' +import { ThemeVariant } from '../theme' -export const useTheme = () => { - return useContext(ThemeContext).theme -} +/** + * Возвращает текущую тему. + * + * @deprecated Используйте `UnistylesRuntime.themeName` из SDK. + * + * Для реактивного поведения: `useUnistyles().rt.themeName`. + * Будет удалён в следующей minor версии. + */ +export const useTheme = (): ThemeVariant => + UnistylesRuntime.themeName === 'dark' ? ThemeVariant.Dark : ThemeVariant.Light diff --git a/src/index.ts b/src/index.ts index 4b9cc530..0f3f9a6f 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,12 +1,22 @@ export * from './components' +/* eslint-disable @typescript-eslint/no-deprecated -- Deprecated API сохраняем в публичном интерфейсе для обратной совместимости. */ export { useChangeTheme } from './hooks/useChangeTheme' export { - ThemeContext, - ThemeContextProvider, ThemeVariant, darkTheme, lightTheme, + type ThemeType, + type FontsConfig, + type FontsConfigType, } from './theme' +export { + StyleSheet, + UnistylesRuntime, + useUnistyles, + withUnistyles, +} from 'react-native-unistyles' +export { useFonts } from './hooks/useFonts' export { makeStyles } from './utils/makeStyles' export { useTheme } from './hooks/useTheme' +/* eslint-enable @typescript-eslint/no-deprecated */ export { SvgUniversal, type SvgSource } from './utils/SvgUniversal' diff --git a/src/theme/ThemeContext.tsx b/src/theme/ThemeContext.tsx deleted file mode 100644 index e62e96ce..00000000 --- a/src/theme/ThemeContext.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { - type ReactNode, - createContext, - useCallback, - useMemo, - useState, -} from 'react' - -import { SkeletonContextProvider } from '../utils/SkeletonContext' - -import { ThemeVariant, type FontsConfig } from './types' - -interface ThemeContextType { - theme: ThemeVariant - fonts: FontsConfig - changeTheme: (theme: ThemeVariant) => void -} - -export interface ThemeContextProviderProps { - readonly initialTheme?: ThemeVariant - readonly fonts?: FontsConfig - readonly children: ReactNode -} - -const defaultThemeContext: ThemeContextType = { - theme: ThemeVariant.Light, - fonts: { primary: 'TT Fellows', secondary: 'PT Sans' }, - changeTheme: () => { - /* do nothing */ - }, -} -export const ThemeContext = createContext(defaultThemeContext) - -export const ThemeContextProvider = ({ - children, - initialTheme = defaultThemeContext.theme, - fonts = defaultThemeContext.fonts, -}: ThemeContextProviderProps) => { - const [theme, setTheme] = useState(initialTheme) - - const changeTheme = useCallback((nextTheme: ThemeVariant) => { - setTheme(nextTheme) - }, []) - - const contextValue = useMemo( - () => ({ theme, fonts, changeTheme }), - [theme, fonts, changeTheme] - ) - - return ( - - {children} - - ) -} diff --git a/src/theme/darkTheme.ts b/src/theme/darkTheme.ts index bf0edf21..46a628d9 100644 --- a/src/theme/darkTheme.ts +++ b/src/theme/darkTheme.ts @@ -8,4 +8,5 @@ import type { ThemeType } from './types' export const darkTheme: ThemeType = { theme: { ...darkThemeAssets, InputSize, ModalSize, custom: customDark }, ...commonTheme, + fonts: { primary: 'TT Fellows', secondary: 'PT Sans' }, } diff --git a/src/theme/index.ts b/src/theme/index.ts index b5184e05..2420961e 100644 --- a/src/theme/index.ts +++ b/src/theme/index.ts @@ -1,9 +1,24 @@ -export { darkTheme } from './darkTheme' -export { lightTheme } from './lightTheme' -export { ThemeContextProvider, ThemeContext } from './ThemeContext' +import { StyleSheet } from 'react-native-unistyles' + +import { darkTheme } from './darkTheme' +import { lightTheme } from './lightTheme' + +StyleSheet.configure({ + settings: { initialTheme: 'light' }, + themes: { light: lightTheme, dark: darkTheme }, +}) + +export { darkTheme, lightTheme } export { type ThemeType, ThemeVariant, type FontsConfigType, type FontsConfig, } from './types' + +declare module 'react-native-unistyles' { + export interface UnistylesThemes { + light: typeof lightTheme + dark: typeof darkTheme + } +} diff --git a/src/theme/lightTheme.ts b/src/theme/lightTheme.ts index 68d86d2c..eecf593d 100644 --- a/src/theme/lightTheme.ts +++ b/src/theme/lightTheme.ts @@ -8,4 +8,5 @@ import type { ThemeType } from './types' export const lightTheme: ThemeType = { theme: { ...lightThemeAssets, InputSize, ModalSize, custom: customLight }, ...commonTheme, + fonts: { primary: 'TT Fellows', secondary: 'PT Sans' }, } diff --git a/src/theme/types.ts b/src/theme/types.ts index 1545a96e..250836a5 100644 --- a/src/theme/types.ts +++ b/src/theme/types.ts @@ -29,6 +29,7 @@ export interface ThemeType { typography: typeof typography custom: typeof customCommon shadow: typeof shadow + fonts: FontsConfig } export enum ThemeVariant { diff --git a/src/utils/makeStyles.ts b/src/utils/makeStyles.ts index 64fc8141..cf9ac78d 100644 --- a/src/utils/makeStyles.ts +++ b/src/utils/makeStyles.ts @@ -1,38 +1,23 @@ import { useMemo } from 'react' import type { ImageStyle, TextStyle, ViewStyle } from 'react-native' - -import { useFonts } from '../hooks/useFonts' -import { useTheme } from '../hooks/useTheme' -import { - type FontsConfigType, - type ThemeType, - darkTheme, - lightTheme, - ThemeVariant, -} from '../theme' - +import { useUnistyles } from 'react-native-unistyles' + +import type { ThemeType } from '../theme' + +/** + * @deprecated Используйте `StyleSheet.create(...)` из SDK. + * + * `makeStyles` использует `useUnistyles()`, что вызывает React-ререндеры при смене + * темы. `StyleSheet.create(...)` — нативный путь, обновляет стили **без** ререндеров. + * + * Будет удалён в следующей minor версии. + */ export const makeStyles = (createStyles: CreateStyles): (() => T) => - () => { - const fonts = useFonts() - const theme = useTheme() - const themeValues = useMemo(() => { - switch (theme) { - case ThemeVariant.Light: - return lightTheme - - case ThemeVariant.Dark: - return darkTheme - - default: - return lightTheme - } - }, [theme]) - - return useMemo( - () => createStyles({ ...themeValues, fonts }) as T, - [fonts, themeValues] - ) + (): T => { + const { theme } = useUnistyles() + + return useMemo(() => createStyles(theme as ThemeType) as T, [theme]) } type StylesItem = ViewStyle | ImageStyle | TextStyle @@ -40,7 +25,7 @@ type StylesItem = ViewStyle | ImageStyle | TextStyle type StylesObject = Record type CreateStyles = ( - theme: ThemeType & FontsConfigType + theme: ThemeType ) => CheckInvalidProps extends never ? T : 'TypeError. Invalid key of style property was used.' diff --git a/yarn.lock b/yarn.lock index 5b49e045..4bb2e48b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2682,6 +2682,16 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:7.29.0": + version: 7.29.0 + resolution: "@babel/types@npm:7.29.0" + dependencies: + "@babel/helper-string-parser": "npm:^7.27.1" + "@babel/helper-validator-identifier": "npm:^7.28.5" + checksum: 10/bfc2b211210f3894dcd7e6a33b2d1c32c93495dc1e36b547376aa33441abe551ab4bc1640d4154ee2acd8e46d3bbc925c7224caae02fcaf0e6a771e97fccc661 + languageName: node + linkType: hard + "@babel/types@npm:^7.0.0, @babel/types@npm:^7.20.7, @babel/types@npm:^7.25.7, @babel/types@npm:^7.25.8, @babel/types@npm:^7.3.3": version: 7.25.8 resolution: "@babel/types@npm:7.25.8" @@ -2778,7 +2788,7 @@ __metadata: "@storybook/preview-api": "npm:8.6.14" "@storybook/react-native": "npm:10.1.1" "@stylistic/eslint-plugin": "npm:5.6.1" - "@tabler/icons-react-native": "npm:^3.36.0" + "@tabler/icons-react-native": "npm:3.36.1" "@testing-library/react-native": "npm:13.3.3" "@types/jest": "npm:29.5.14" "@types/lodash.map": "npm:4.6.13" @@ -2820,9 +2830,11 @@ __metadata: react-native: "npm:0.81.5" react-native-advanced-input-mask: "npm:1.4.6" react-native-gesture-handler: "npm:2.29.1" + react-native-nitro-modules: "npm:0.35.2" react-native-reanimated: "npm:4.1.1" react-native-safe-area-context: "npm:5.6.2" react-native-svg: "npm:15.15.1" + react-native-unistyles: "npm:3.2.3" react-native-worklets: "npm:0.5.1" release-it: "npm:19.1.0" standard-version: "npm:9.5.0" @@ -5578,21 +5590,21 @@ __metadata: languageName: node linkType: hard -"@tabler/icons-react-native@npm:^3.36.0": - version: 3.36.0 - resolution: "@tabler/icons-react-native@npm:3.36.0" +"@tabler/icons-react-native@npm:3.36.1": + version: 3.36.1 + resolution: "@tabler/icons-react-native@npm:3.36.1" dependencies: - "@tabler/icons": "npm:3.36.0" + "@tabler/icons": "npm:" peerDependencies: react: ">= 16.5.1" - checksum: 10/aa3f9075074b6eedadfa5ebb97f2cfb96fd4eaacab79e8f0615f3247b34537a31c2df7ed53f461af8f69c35b478748f82ffdb60e7afbc79fec4f17a4616f0635 + checksum: 10/34e944ebd0376bdbe5c7e1a845ec19e34423ecbf8390eea1c1ef6b47ace09bbd9831c51b7bbec00e0e96c1468be302f4fe67a001137ad31ee151d3939f2e1dcd languageName: node linkType: hard -"@tabler/icons@npm:3.36.0": - version: 3.36.0 - resolution: "@tabler/icons@npm:3.36.0" - checksum: 10/007ec7ddad617f784a81f792d2bddfc11e76541c011bc50e9ebed9ce5210278076c8688cd73d081ac1c54e42a8bc7437bbcda41638204d43edd069a0c8387516 +"@tabler/icons@npm:": + version: 3.41.1 + resolution: "@tabler/icons@npm:3.41.1" + checksum: 10/9a1af1a659c9e997a37e83acfd408fc32486687107b1a71e8fe03472274490c92c4512a1e62fd68d23e8d2d5f2c57feea2d22245605a07c8eeed67fcc683c544 languageName: node linkType: hard @@ -16113,6 +16125,16 @@ __metadata: languageName: node linkType: hard +"react-native-nitro-modules@npm:0.35.2": + version: 0.35.2 + resolution: "react-native-nitro-modules@npm:0.35.2" + peerDependencies: + react: "*" + react-native: "*" + checksum: 10/22977e5e22c63fb91526c90fa59fcfe5c7f97978c583400f433a1d3ef8ee32fbceb0ad1b009b5bf0d1794e94a11716ad752fd7702c2d67fc808a0256c6e35488 + languageName: node + linkType: hard + "react-native-reanimated@npm:4.1.1": version: 4.1.1 resolution: "react-native-reanimated@npm:4.1.1" @@ -16152,6 +16174,27 @@ __metadata: languageName: node linkType: hard +"react-native-unistyles@npm:3.2.3": + version: 3.2.3 + resolution: "react-native-unistyles@npm:3.2.3" + dependencies: + "@babel/types": "npm:7.29.0" + peerDependencies: + "@react-native/normalize-colors": "*" + react: "*" + react-native: ">=0.76.0" + react-native-edge-to-edge: "*" + react-native-nitro-modules: "*" + react-native-reanimated: "*" + peerDependenciesMeta: + react-native-edge-to-edge: + optional: true + react-native-reanimated: + optional: true + checksum: 10/217875c9993f88bd5b183e2341feff115777872c3ea6dc0aac493f01bcb7cb2f34a3f4dabd1f0ba613553cad8a42395eda62f448f71e7f8b64fcd9fb262cb99b + languageName: node + linkType: hard + "react-native-url-polyfill@npm:^3.0.0": version: 3.0.0 resolution: "react-native-url-polyfill@npm:3.0.0"