Skip to content

Commit e2a4065

Browse files
authored
Rework core rendering in preparation for new components (#4137)
* slots/types rework in framework-base * replace useSlot implementation and remove use-slot package * updates to framework-base types and render * fix some build breaks * fix build errors around jsx namespace usage * some consistency fixes plus consistent usage of the react type indirection * remove extensions and fix formatting * update dependency-profiles * Add a new pressable hook and fix lint errors * more correctness/test fixes * get tests working and fix issue with prop forwarding with staged components * final bug fixes + change file * update documentation and fix one reference cycle * fix repo links and stop using re-exports from framework for framework-base packages * fix inconsistencies with children handling
1 parent 5b5afea commit e2a4065

192 files changed

Lines changed: 2063 additions & 2279 deletions

File tree

Some content is hidden

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

.changeset/nine-bees-relate.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
"@uifabricshared/foundation-composable": minor
3+
"@fluentui-react-native/themed-stylesheet": minor
4+
"@fluentui-react-native/focus-trap-zone": minor
5+
"@fluentui-react-native/persona-coin": minor
6+
"@fluentui-react-native/menu-button": minor
7+
"@fluentui-react-native/overflow": minor
8+
"@fluentui-react-native/composition": minor
9+
"@fluentui-react-native/use-styling": minor
10+
"@fluentui-react-native/focus-zone": minor
11+
"@fluentui-react-native/experimental-shimmer": minor
12+
"@fluentui-react-native/use-tokens": minor
13+
"@fluentui-react-native/dependency-profiles": minor
14+
"@fluentui-react-native/framework": minor
15+
"@fluentui-react-native/use-slots": minor
16+
"@fluentui-react-native/persona": minor
17+
"@fluentui-react-native/avatar": minor
18+
"@fluentui-react-native/stack": minor
19+
"@fluentui-react-native/menu": minor
20+
"@fluentui-react-native/theme": minor
21+
"@fluentui-react-native/framework-base": minor
22+
"@fluentui-react-native/adapters": minor
23+
---
24+
25+
rework framework rendering to prepare for new component structure

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ The composition framework uses precise types for better type safety:
155155
- `MIGRATION.md` - Migration guide (for V1 components)
156156
- `tsconfig.json`, `babel.config.js`, `jest.config.js`, `eslint.config.js`
157157

158-
**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`.
158+
**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/framework-base`.
159159

160160
**JSX Runtime**: All components use the modern automatic JSX runtime:
161161

CONTRIBUTING.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Tokens help us achieve simpler customization for complex higher order components
4444

4545
This section covers creating and adding a new component package to FluentUI React Native's monorepo. If you are instead working on an existing component and adding a native module, skip to the next two sections.
4646

47-
Most components should use the compose framework as it offers the comprehensive set of patterns like tokens and slots, but if you're creating a simple component that doesn't require those patterns, there's a lighter pattern called [stagedComponent](./packages/framework-base/src/component-patterns/stagedComponent.ts). The stagedComponent pattern splits up the render function into two stages. Stage 1 handles building props and hook calls (best to separate the hook calls from the render tree since they rely on call order). Stage 2 returns the actual element tree, any conditional branching should happen here (Icon is a good example of using stagedCompoenent).
47+
Most components should use the compose framework as it offers the comprehensive set of patterns like tokens and slots, but if you're creating a simple component that doesn't require those patterns, there's a lighter pattern called [stagedComponent](./packages/framework-base/src/component-patterns/phased.ts). The stagedComponent pattern splits up the render function into two stages. Stage 1 handles building props and hook calls (best to separate the hook calls from the render tree since they rely on call order). Stage 2 returns the actual element tree, any conditional branching should happen here (Icon is a good example of using stagedCompoenent).
4848

4949
1. Create a new directory in of these two locations, depending on your component:
5050
- `fluentui-react-native/packages/components/<new-component>`
@@ -63,8 +63,7 @@ Reach out to Samuel Freiberg with any questions related to E2E testing.
6363
1. Create a `src/` subdirectory in your component directory with a minimum of two files (listed below). You may optionally choose to subdivide your code however you wish; there are plenty of examples in the other components of FluentUI React Native.
6464
1. `index.ts`
6565
- This is the file listed as `main` inside your package.json and simply exports other files.
66-
1. `<new-component>.tsx` - This is the file that will actually define your function component, and compose it into a higher order component with slots, theming, and design tokens. - Note that we need the comment `/** @jsxRuntime classic */
67-
/** @jsx withSlots */` at the top of this file. An explanation can be found in the comment at `packages/experimental/use-slots/src/withSlots.tsx`
66+
1. `<new-component>.tsx` - This is the file that will actually define your function component, and compose it into a higher order component with slots, theming, and design tokens. - Note that we need the comment `/** @jsxImportSource @fluentui-react-native/framework-base */` as the first line of this file. This opts the file into the custom JSX runtime that handles slot rendering; an explanation can be found in `packages/framework-base/src/component-patterns/README.md`. Packages using this pragma must include `@fluentui-react-native/framework-base` in their `devDependencies`.
6867
1. `<new-component>.<types | settings | platform | blah>.tsx` (Optional)
6968
- Optional extra files to subdivide your code however you see fit. You can also add platform specific files as you see fit.
7069

apps/component-generator/component-templates/ComponentTemplate/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
},
2727
"dependencies": {},
2828
"devDependencies": {
29+
"@fluentui-react-native/framework-base": "workspace:*",
2930
"@fluentui-react-native/scripts": "workspace:*",
3031
"@fluentui-react-native/test-tools": "workspace:*",
3132
"react": "18.2.0",

apps/component-generator/component-templates/ComponentTemplate/src/ComponentName.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
/** @jsxRuntime classic */
2-
/** @jsx withSlots */
1+
/** @jsxImportSource @fluentui-react-native/framework-base */
32
import * as React from 'react';
43
import { View } from 'react-native';
54
import { componentName, ComponentNameType, ComponentNameProps } from './ComponentName.types';
65
import { TextV1 as Text } from '@fluentui-react-native/text';
76
import { stylingSettings } from './ComponentName.styling';
8-
import { compose, mergeProps, withSlots, UseSlots } from '@fluentui-react-native/framework';
7+
import { compose, mergeProps, UseSlots } from '@fluentui-react-native/framework';
98
import { useComponentName } from './useComponentName';
109
/**
1110
* A function which determines if a set of styles should be applied to the component given the current state and props of the component-name.

apps/fluent-tester/macos/Podfile.lock

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ PODS:
44
- fast_float (8.0.0)
55
- FBLazyVector (0.81.2)
66
- fmt (11.0.2)
7-
- FRNAvatar (0.22.4):
7+
- FRNAvatar (0.22.5):
88
- MicrosoftFluentUI (= 0.13.1)
99
- React
10-
- FRNCallout (0.28.4):
10+
- FRNCallout (0.28.5):
1111
- boost
1212
- DoubleConversion
1313
- fast_float
@@ -36,13 +36,13 @@ PODS:
3636
- ReactCommon/turbomodule/core
3737
- SocketRocket
3838
- Yoga
39-
- FRNCheckbox (0.18.4):
39+
- FRNCheckbox (0.18.5):
4040
- React
41-
- FRNMenuButton (0.14.4):
41+
- FRNMenuButton (0.14.5):
4242
- React
43-
- FRNRadioButton (0.22.4):
43+
- FRNRadioButton (0.22.5):
4444
- React
45-
- FRNVibrancyView (0.4.4):
45+
- FRNVibrancyView (0.4.5):
4646
- React
4747
- glog (0.3.5)
4848
- hermes-engine (0.81.5):
@@ -137,7 +137,7 @@ PODS:
137137
- fmt (= 11.0.2)
138138
- glog
139139
- RCTDeprecation (0.81.2)
140-
- RCTFocusZone (0.22.4):
140+
- RCTFocusZone (0.22.5):
141141
- React
142142
- RCTRequired (0.81.2)
143143
- RCTTypeSafety (0.81.2):
@@ -2667,18 +2667,18 @@ SPEC CHECKSUMS:
26672667
fast_float: 20817c22759af6ac8d4d67e6e059b8b499953656
26682668
FBLazyVector: 0e3076dbb16169b0afc2d701a24a526423b5e76b
26692669
fmt: 24e7591456deb60b4a77518f83d9a916ac84223f
2670-
FRNAvatar: 586585a440e2b23c9ac872fd1fa2ddb7819cd7bd
2671-
FRNCallout: f3234f07e6f49334c0f1de7cb7185494f2915db5
2672-
FRNCheckbox: a5afb9bb4e6405d39a30f997f7e69d6e5672533d
2673-
FRNMenuButton: e9e49a3afa5eb5ecbe4a36c41047bce763f661c7
2674-
FRNRadioButton: 6f7db3424604a413b4cca73c5a22033c79f92d43
2675-
FRNVibrancyView: a9cf18fcaee2a7d9f9ea292924ebf1b3acb0a5b2
2670+
FRNAvatar: c4baf9356785232c547bb76a9ccd290e94e0fda9
2671+
FRNCallout: ee98ce83b788ff3d3716463269560487b787f658
2672+
FRNCheckbox: 2e74a528f6328ea79bf9eaa2a1d466dd8f30be4f
2673+
FRNMenuButton: bb6913908137c530f1a3af2d8d7d5c6a5fae4e19
2674+
FRNRadioButton: adf6b247f1143c9e79f63221405e9b94ef7bef6d
2675+
FRNVibrancyView: ccff736e2c309eba2ed56f1b803a0e55b8a3067f
26762676
glog: ba31c1afa7dcf1915a109861bccdb4421be6175b
26772677
hermes-engine: 9f4dfe93326146a1c99eb535b1cb0b857a3cd172
26782678
MicrosoftFluentUI: dde98d8ed3fc306d9ddd0a6f0bc0c1f24fe5275e
26792679
RCT-Folly: c803cf33238782d5fd21a5e02d44f64068e0e130
26802680
RCTDeprecation: b60b889eafa75f46c3d6be5332681efbb16ad0c7
2681-
RCTFocusZone: a6d62c46c530e790479915bc9faa578137e9e2a6
2681+
RCTFocusZone: f4199120b2260bc5710359852686307a0f8d8b0e
26822682
RCTRequired: 070d7f0ef937e7a93aab20761cef55419f16b5de
26832683
RCTTypeSafety: dd2ad1eb0c0c01ba41222d115be141f9a348c636
26842684
React: 304df3d34c8c0281fd1fd3a506e69f234095425d

apps/tester-core/src/TestComponents/Shadow/ShadowDepthTestSection.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { View, type ViewStyle } from 'react-native';
33

44
import { Text } from '@fluentui/react-native';
55
import { Shadow, getShadowTokenStyleSet } from '@fluentui-react-native/experimental-shadow';
6-
import { mergeStyles, useFluentTheme } from '@fluentui-react-native/framework';
6+
import { useFluentTheme } from '@fluentui-react-native/framework';
7+
import { mergeStyles } from '@fluentui-react-native/framework-base';
78
import type { ShadowToken, Theme } from '@fluentui-react-native/theme-types';
89
import { useTheme } from '@fluentui-react-native/theme-types';
910
import { themedStyleSheet } from '@fluentui-react-native/themed-stylesheet';

docs/pages/Theming/Tokens/UsageWithComponentTokens.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@ This page covers how to access color tokens to fill out a component's tokens.
77
Most components in FURN build a component's styling out of the tokens and theme that are fed into the component. The `compose` framework takes in an object with a `tokens` property, which you can use to define how a component's tokens are filled out. The `tokens` property can be assigned to a function which takes a `Theme` object as an argument and returns an object that is the component's `Token` type. Inside the function, you can access the alias function from the theme as you would if you had the theme inside a component's render function.
88

99
```tsx
10-
/** @jsxRuntime classic */
11-
/** @jsx withSlots */
12-
import { Theme, TokenSettings, buildProps, compose, mergeProps, withSlots, UseSlots } from '@fluentui-react-native/framework';
10+
/** @jsxImportSource @fluentui-react-native/framework-base */
11+
import { Theme, TokenSettings, buildProps, compose, mergeProps, UseSlots } from '@fluentui-react-native/framework';
1312
import { fontStyles } from '@fluentui-react-native/tokens';
1413
import { Text } from '@fluentui-react-native/experimental-text';
1514

packages/agentic-components/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
"test": "fluentui-scripts jest",
3131
"update-snapshots": "fluentui-scripts jest -u"
3232
},
33+
"dependencies": {
34+
"@fluentui-react-native/framework-base": "workspace:*"
35+
},
3336
"devDependencies": {
3437
"@babel/core": "catalog:",
3538
"@fluentui-react-native/scripts": "workspace:*",

packages/agentic-components/src/components/button/button.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import * as React from 'react';
21
import { Pressable, StyleSheet, Text } from 'react-native';
32
import type { GestureResponderEvent, StyleProp, ViewStyle } from 'react-native';
3+
import type { FurnJSX } from '@fluentui-react-native/framework-base';
44

55
/**
66
* Props for the simple {@link Button} component.
@@ -47,7 +47,7 @@ const styles = StyleSheet.create({
4747
/**
4848
* A simple cross-platform button built directly on react-native primitives.
4949
*/
50-
export function Button(props: ButtonProps): React.JSX.Element {
50+
export function Button(props: ButtonProps): FurnJSX.Element {
5151
const { title, onPress, disabled, style } = props;
5252
return (
5353
<Pressable

0 commit comments

Comments
 (0)