Skip to content

Commit 088d6c6

Browse files
authored
Pre RN 0.81 changes: jsx-runtime, build updates, tool updates, package.json linting and normalization (#3987)
* switch repo to typescript 5.x * Change files * remove text behavior change from type fixes * add lint-package command and switch to tsgo * more package.json normalization * switch runtime to automatic, clean up lint errors * switch everything to modern jsx-runtime * integrate depcheck and align deps with package linting and make things consistent * Change files * update catalog usage and integrate it into lint-package * update eslint versions and apply fixes * fix some last bits before submitting the PR * fix scripts on windows machines * add lockfile update after merge * Change files * reorder package.json files based on standard sort-package-json order * revert change to force rewrites
1 parent f9c2930 commit 088d6c6

File tree

364 files changed

+5786
-3932
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

364 files changed

+5786
-3932
lines changed

.ado/azure-pipelines.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,6 @@ jobs:
2828
yarn prettier
2929
displayName: 'check prettier'
3030
31-
- script: |
32-
yarn align-deps
33-
displayName: 'run align-deps'
34-
3531
- script: |
3632
yarn lint-lockfile
3733
displayName: 'run lint-lockfile'

.yarnrc.yml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
catalog:
2+
'@rnx-kit/align-deps': '^3.4.0'
3+
'@rnx-kit/config': '^0.7.4'
4+
'@rnx-kit/eslint-plugin': '^0.9.5'
5+
'@rnx-kit/jest-preset': '^0.3.1'
6+
'@rnx-kit/lint-lockfile': '^0.1.2'
7+
'@rnx-kit/reporter': '^0.1.0'
8+
'@rnx-kit/tools-packages': '^0.1.1'
9+
'@rnx-kit/tools-typescript': '^0.1.1'
10+
'@rnx-kit/tsconfig': '^2.1.1'
211
'@types/jasmine': '5.1.13'
12+
'@types/node': '^22.19.7'
313
'@wdio/appium-service': '^9.23.0'
414
'@wdio/cli': '^9.23.0'
515
'@wdio/globals': '^9.23.0'
@@ -14,7 +24,9 @@ catalog:
1424
'appium-uiautomator2-driver': '^6.7.8'
1525
'appium-windows-driver': '^5.1.5'
1626
'appium-xcuitest-driver': '^10.14.5'
27+
'cross-env': '^10.1.0'
1728
'expect-webdriverio': '^5.6.1'
29+
'knip': '^5.81.0'
1830
'rimraf': '^6.1.2'
1931
'webdriverio': '^9.23.0'
2032

CLAUDE.md

Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
This is the **FluentUI React Native** repository, a monorepo containing React Native components that implement Microsoft's Fluent Design System. The repository supports multiple platforms including iOS, Android, macOS, Windows, and Win32.
8+
9+
## Repository Architecture
10+
11+
### High-Level Structure
12+
```
13+
/apps/ - Demo and test applications
14+
/fluent-tester/ - Main test app for component development
15+
/E2E/ - End-to-end testing setup using Appium/WebDriverIO
16+
/win32/ - Win32-specific test app
17+
/component-generator/ - Tool to generate new components
18+
/packages/ - Core library packages
19+
/components/ - UI component implementations (Button, Checkbox, Avatar, etc.)
20+
/framework/ - Core theming and composition framework
21+
/composition/ - Component composition factory (current approach)
22+
/theme/ - Theme system
23+
/use-tokens/ - Token-based styling hooks
24+
/use-slots/ - Slot-based component composition
25+
/theming/ - Theme definitions for different platforms
26+
/android-theme/
27+
/apple-theme/
28+
/default-theme/
29+
/win32-theme/
30+
/experimental/ - Components under active development
31+
/deprecated/ - Old framework code (foundation-compose, foundation-composable)
32+
/utils/ - Shared utilities and tools
33+
/scripts/ - Build and development scripts (fluentui-scripts CLI)
34+
/docs/ - Component and theming documentation
35+
```
36+
37+
### Key Framework Concepts
38+
39+
**Composition Framework**: The repository uses `@fluentui-react-native/composition` (located at `packages/framework/composition/`) for building components. This is the current approach and is simpler than the older foundation-compose/foundation-composable frameworks in `/deprecated/`.
40+
41+
**Slots**: The slot pattern is used to compose higher-order components. A slot represents an inner component (actual entry in the render tree). For example, a Button might have slots for `root`, `icon`, and `content`. This allows advanced customization scenarios. Components wrapping a single native component typically have one slot.
42+
43+
**Tokens**: Design tokens handle styling and customization. Tokens are design-time values set via theme or component customization (e.g., "brandColor"). Tokens can also be props (specified via "TokensThatAreAlsoProps"). This system enables simpler customization and better memoization.
44+
45+
**Platform-Specific Files**: Components use platform-specific files with extensions like `.ios.ts`, `.android.ts`, `.win32.ts`, `.macos.ts` for platform-specific implementations.
46+
47+
**Legacy vs V1**: Many components have both legacy and V1 implementations (e.g., `Button` and `ButtonV1`). The V1 versions use the newer composition framework and are preferred.
48+
49+
## Build System & Commands
50+
51+
The project uses **Yarn 4** (Berry) in **pnpm mode** with **Lage** as the task runner for orchestrating builds across the monorepo. The pnpm mode provides better disk space efficiency and stricter dependency management.
52+
53+
### Primary Commands
54+
```bash
55+
yarn build # TypeScript build for all packages (outputs to lib/ and lib-commonjs/)
56+
yarn test # Build, lint, and run tests across all packages
57+
yarn lint # ESLint across all packages
58+
yarn bundle # Bundle all packages
59+
yarn buildci # Full CI pipeline: build + test + lint + bundle + depcheck + check-publishing
60+
yarn clean # Clean build artifacts
61+
```
62+
63+
### Development Commands
64+
```bash
65+
yarn prettier-fix # Format code with Prettier
66+
yarn depcheck # Check for unused dependencies across packages
67+
yarn depcheck-fix # Fix depcheck issues automatically
68+
yarn align-deps # Align React Native dependencies using @rnx-kit/align-deps
69+
yarn change # Generate Beachball change files (required before PR merge)
70+
yarn checkchange # Verify change files exist for modified packages
71+
```
72+
73+
### Lage Configuration
74+
The build pipeline is defined in `lage.config.js`:
75+
- Tasks have dependency ordering (e.g., `test` depends on `build`)
76+
- Lage uses caching to avoid redundant steps
77+
- Add `--no-cache` to bypass caching
78+
- Add `--verbose` for detailed output
79+
80+
### Package-Level Commands
81+
Individual packages use `fluentui-scripts` (in `/scripts/`) which provides:
82+
- `yarn build` - TypeScript compilation to `lib/` (ESM) and `lib-commonjs/` (CJS)
83+
- The build script automatically sets `--moduleResolution` to match `--module` for TypeScript 5.8+ compatibility
84+
- ESM builds use `--module esnext --moduleResolution bundler`
85+
- CJS builds use `--module node16 --moduleResolution node16`
86+
- `yarn lint` - ESLint
87+
- `yarn lint-package` - Lint package configuration (includes align-deps and depcheck)
88+
- Use `--fix` flag to automatically fix issues
89+
- Validates dependencies, scripts, entry points, and build configuration
90+
- `yarn test` - Jest tests (where applicable)
91+
- `yarn depcheck` - Check for unused dependencies
92+
- `yarn prettier` - Check code formatting
93+
- `yarn prettier-fix` - Fix code formatting
94+
95+
## TypeScript Configuration
96+
97+
The repository uses **TypeScript 5.8+** with **@typescript/native-preview** for improved performance and React Native compatibility. The native preview is automatically added to packages with a `tsconfig.json` via dynamic package extensions.
98+
99+
### Key TypeScript Settings
100+
- Base configuration in `/scripts/configs/tsconfig.json`
101+
- Module system: `node16` with matching `moduleResolution: node16`
102+
- Target: `es2022`
103+
- Strict mode enabled (with some exceptions for legacy code compatibility)
104+
- **TypeScript Native Preview**: Packages automatically receive `@typescript/native-preview` as a development dependency
105+
106+
### TypeScript 5.8+ Compatibility Notes
107+
- The `suppressImplicitAnyIndexErrors` option has been removed (deprecated in TS 5.8+)
108+
- Module resolution must match module format when using Node16 resolution
109+
- Stricter type checking for platform values (e.g., `Platform.OS` doesn't include 'win32' in React Native types, but react-native-windows does support it at runtime)
110+
- TypeScript native preview provides better performance for large React Native codebases
111+
112+
### Framework Type System
113+
The composition framework uses precise types for better type safety:
114+
- **`SlotFn<TProps>`**: Slot functions return `React.ReactElement | null` (not `ReactNode`)
115+
- This reflects the actual behavior: slots always return elements via staged render or `React.createElement`
116+
- Provides better type inference when accessing slot props (e.g., `Slots.root({}).props`)
117+
- **`FinalRender<TProps>`**: Final render functions in staged components return `JSX.Element | null`
118+
- Used in composition framework's `useRender` functions
119+
- Ensures type compatibility between staged components and the composition system
120+
121+
## Development Workflow
122+
123+
### Setting Up Development Environment
124+
1. Clone repository
125+
2. Run `yarn` to install dependencies
126+
3. Run `yarn build` to build all packages
127+
4. Launch FluentUI Tester app for component testing (see `/apps/fluent-tester/README.md`)
128+
129+
### Component Development
130+
131+
**Component Location**: Components are in `/packages/components/` (stable) or `/packages/experimental/` (under development).
132+
133+
**Component Structure**: Each component typically has:
134+
- `package.json` - Package definition with workspace dependencies
135+
- `src/index.ts` - Main export file
136+
- `src/<Component>.tsx` - Component implementation (requires `/** @jsxImportSource @fluentui-react-native/framework-base */` pragma)
137+
- `src/<Component>.types.ts` - TypeScript type definitions
138+
- `src/<Component>.styling.ts` - Styling and token definitions
139+
- `src/<Component>.<platform>.ts` - Platform-specific implementations
140+
- `SPEC.md` - Component specification and usage documentation
141+
- `MIGRATION.md` - Migration guide (for V1 components)
142+
- `tsconfig.json`, `babel.config.js`, `jest.config.js`, `eslint.config.js`
143+
144+
**Using Composition Framework**: Use `@fluentui-react-native/composition` for new components. For simpler components without slots/tokens, use the `stagedComponent` pattern from `@fluentui-react-native/use-slot`.
145+
146+
**JSX Runtime**: All components use the modern automatic JSX runtime:
147+
- Add `/** @jsxImportSource @fluentui-react-native/framework-base */` at the top of `.tsx` files
148+
- The custom jsx-runtime intercepts JSX calls to optimize slot rendering
149+
- No need to import `withSlots` - it's handled automatically by the runtime
150+
- Components using React Fragments (`<>...</>`) work automatically (Fragment is re-exported from the jsx-runtime)
151+
- Packages using the jsx-runtime need `@fluentui-react-native/framework-base` in `devDependencies`
152+
153+
**TypeScript Patterns**:
154+
- Slot functions automatically return `React.ReactElement`, so you can access `.props` directly without type assertions
155+
- When checking for win32 platform: `Platform.OS === ('win32' as any)` - TypeScript doesn't recognize 'win32' but react-native-windows supports it
156+
- Final render functions should return `FinalRender<TProps>` with children as rest parameters: `(props: TProps, ...children: React.ReactNode[])`
157+
158+
**Native Modules**: Components with native code (iOS/Android/Windows):
159+
- Typically have one root slot wrapping the native component
160+
- Use `codegenNativeComponent` for new architecture compatibility
161+
- May use `constantsToExport` for default values from native side
162+
- iOS/macOS: Include `.podspec` files
163+
- Must be added to FluentTester's Podfile (transitive dependencies aren't autolinked)
164+
165+
### Creating a New Component
166+
167+
1. Create directory: `/packages/components/<ComponentName>` or `/packages/experimental/<ComponentName>`
168+
2. Copy structure from existing component (e.g., Shimmer, Button)
169+
3. Update `package.json` with correct name and dependencies (use `workspace:*` for internal packages)
170+
4. Create source files in `src/`
171+
5. Add test page to FluentTester at `/apps/fluent-tester/src/TestComponents/<ComponentName>/`
172+
6. Register test page in `testPages.tsx` and platform-specific `testPages.<platform>.tsx`
173+
7. Add E2E tests (see E2E Testing section)
174+
8. Run `yarn` and `yarn build` from root
175+
9. For Apple platforms: run `pod install` in test app directories
176+
177+
### Theming
178+
179+
Platform-specific themes are in `/packages/theming/`:
180+
- `android-theme/` - Android theming
181+
- `apple-theme/` - iOS and macOS theming
182+
- `win32-theme/` - Win32 theming
183+
- `default-theme/` - Cross-platform defaults
184+
- `theme-tokens/` - Token definitions
185+
- `theme-types/` - TypeScript types for themes
186+
187+
Components require `ThemeProvider` from `@fluentui-react-native/theme` to work properly.
188+
189+
### Testing
190+
191+
**Manual Testing**: Use FluentUI Tester app (`/apps/fluent-tester/`) for interactive component testing. Test pages are in `/apps/fluent-tester/src/TestComponents/`.
192+
193+
**E2E Testing**: Required for all new components. Uses Appium + WebDriverIO.
194+
- E2E tests live in `/apps/E2E/src/<ComponentName>/`
195+
- Each component needs:
196+
- Page Object (`<Component>PageObject.<platform>.ts`) - Interface to interact with test page
197+
- Spec Document (`<Component>Spec.<platform>.ts`) - Jasmine test cases
198+
- Constants file in test component (`/apps/fluent-tester/src/TestComponents/<Component>/consts.ts`)
199+
- Test pages must include:
200+
- `testID` on first section matching page object's `_pageName`
201+
- Optional `e2eSections` prop for dedicated E2E test elements
202+
- Run E2E tests: `yarn e2etest:<platform>` from `/apps/E2E/`
203+
204+
**Unit Tests**: Component-specific Jest tests where present, typically in `src/` directories.
205+
206+
### Platform-Specific Development
207+
208+
**iOS/macOS**:
209+
- May wrap native controls from FluentUI Apple
210+
- Requires `.podspec` files for native modules
211+
- Run `pod install` after adding dependencies
212+
213+
**Android**:
214+
- Platform-specific styling and tokens
215+
- Uses `accessibilityLabel` for E2E selectors (other platforms use `testID`)
216+
217+
**Win32**:
218+
- Separate test app at `/apps/win32/`
219+
- Uses WinAppDriver for E2E testing
220+
221+
**Windows (UWP)**:
222+
- Separate test app configuration
223+
- Legacy support
224+
225+
## Version Management
226+
227+
**Beachball**: Used for change logs and versioning.
228+
- Run `yarn change` to create change files when modifying packages
229+
- Change files are required before merging PRs (`yarn checkchange` validates)
230+
- Beachball config in `beachball.config.js`
231+
- Major versions are disallowed (`disallowedChangeTypes: ['major']`)
232+
- On publish, `onPublish` field in `package.json` gets merged into package
233+
234+
## Important Notes
235+
236+
- This is an **alpha-stage** library under active development
237+
- **Requires TypeScript 5.8+** with `@typescript/native-preview` for proper type checking and module resolution
238+
- **Uses Yarn 4 in pnpm mode** for dependency management (configured in `.yarnrc.yml`)
239+
- **Uses modern automatic JSX runtime** - all components should use `@jsxImportSource @fluentui-react-native/framework-base`
240+
- **Dynamic package extensions**: Common dev dependencies (TypeScript, Jest, ESLint, Prettier) are automatically added via `scripts/dynamic.extensions.mjs`
241+
- **Integrated linting**: `yarn lint-package` now includes align-deps and depcheck validation
242+
- Follow existing component patterns for consistency
243+
- Test components using FluentUI Tester app before submitting PRs
244+
- Platform differences should be documented in component `SPEC.md` files
245+
- Use the newer composition framework (`@fluentui-react-native/composition`) for new components, not the deprecated foundation frameworks
246+
- When importing V1 components, consider aliasing: `import { ButtonV1 as Button }`
247+
- Slot functions return `React.ReactElement` - you can safely access `.props` without type assertions

0 commit comments

Comments
 (0)