@fluentui-react-native/use-slots 0.10.12 → 0.11.0
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/CHANGELOG.json +1 -1
- package/CHANGELOG.md +39 -2
- package/lib/buildUseSlots.d.ts +11 -10
- package/lib/buildUseSlots.d.ts.map +1 -1
- package/lib/buildUseSlots.js +16 -14
- package/lib/buildUseSlots.js.map +1 -1
- package/lib/buildUseSlots.test.d.ts +1 -1
- package/lib/buildUseSlots.test.js +27 -17
- package/lib/buildUseSlots.test.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/useSlots.samples.test.d.ts +1 -1
- package/lib/useSlots.samples.test.js +228 -187
- package/lib/useSlots.samples.test.js.map +1 -1
- package/lib-commonjs/buildUseSlots.d.ts +11 -10
- package/lib-commonjs/buildUseSlots.d.ts.map +1 -1
- package/lib-commonjs/buildUseSlots.js +20 -19
- package/lib-commonjs/buildUseSlots.js.map +1 -1
- package/lib-commonjs/buildUseSlots.test.d.ts +1 -1
- package/lib-commonjs/buildUseSlots.test.js +82 -45
- package/lib-commonjs/buildUseSlots.test.js.map +1 -1
- package/lib-commonjs/index.d.ts +1 -1
- package/lib-commonjs/index.js +10 -5
- package/lib-commonjs/index.js.map +1 -1
- package/lib-commonjs/useSlots.samples.test.d.ts +1 -1
- package/lib-commonjs/useSlots.samples.test.js +297 -215
- package/lib-commonjs/useSlots.samples.test.js.map +1 -1
- package/package.json +44 -44
- package/src/__snapshots__/useSlots.samples.test.tsx.snap +42 -42
- package/src/buildUseSlots.test.tsx +8 -5
- package/src/buildUseSlots.ts +8 -5
- package/src/useSlots.samples.test.tsx +42 -42
package/package.json
CHANGED
|
@@ -1,83 +1,83 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluentui-react-native/use-slots",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0",
|
|
4
4
|
"description": "Hook function to return styled slots",
|
|
5
|
+
"keywords": [],
|
|
5
6
|
"repository": {
|
|
6
7
|
"type": "git",
|
|
7
8
|
"url": "https://github.com/microsoft/fluentui-react-native",
|
|
8
9
|
"directory": "packages/framework/use-slots"
|
|
9
10
|
},
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"react-native": "src/index.ts",
|
|
11
|
+
"license": "MIT",
|
|
12
|
+
"author": "",
|
|
13
13
|
"exports": {
|
|
14
14
|
".": {
|
|
15
|
+
"types": "./lib/index.d.ts",
|
|
15
16
|
"import": "./lib/index.js",
|
|
16
|
-
"require": "./lib-commonjs/index.js"
|
|
17
|
-
"types": "./lib/index.d.ts"
|
|
17
|
+
"require": "./lib-commonjs/index.js"
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
|
-
"
|
|
20
|
+
"main": "lib-commonjs/index.js",
|
|
21
|
+
"module": "lib/index.js",
|
|
22
|
+
"types": "lib/index.d.ts",
|
|
21
23
|
"scripts": {
|
|
22
24
|
"build": "fluentui-scripts build",
|
|
25
|
+
"build-cjs": "tsgo --outDir lib-commonjs",
|
|
26
|
+
"build-esm": "tsgo --outDir lib --module esnext --moduleResolution bundler",
|
|
23
27
|
"clean": "fluentui-scripts clean",
|
|
24
28
|
"depcheck": "fluentui-scripts depcheck",
|
|
25
|
-
"just": "fluentui-scripts",
|
|
26
29
|
"lint": "fluentui-scripts eslint",
|
|
30
|
+
"lint-package": "fluentui-scripts lint-package",
|
|
31
|
+
"prettier": "fluentui-scripts prettier",
|
|
27
32
|
"start": "fluentui-scripts dev",
|
|
28
33
|
"start-test": "fluentui-scripts jest-watch",
|
|
29
34
|
"test": "fluentui-scripts jest",
|
|
30
|
-
"update-snapshots": "fluentui-scripts jest -u"
|
|
31
|
-
"prettier": "fluentui-scripts prettier",
|
|
32
|
-
"prettier-fix": "fluentui-scripts prettier --fix true"
|
|
35
|
+
"update-snapshots": "fluentui-scripts jest -u"
|
|
33
36
|
},
|
|
34
|
-
"keywords": [],
|
|
35
|
-
"author": "",
|
|
36
|
-
"license": "MIT",
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@fluentui-react-native/framework-base": "0.
|
|
39
|
-
"@fluentui-react-native/use-slot": "0.
|
|
38
|
+
"@fluentui-react-native/framework-base": "0.3.0",
|
|
39
|
+
"@fluentui-react-native/use-slot": "0.7.0"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@babel/core": "^7.20.0",
|
|
43
43
|
"@fluentui-react-native/babel-config": "0.1.1",
|
|
44
44
|
"@fluentui-react-native/eslint-config-rules": "0.1.1",
|
|
45
45
|
"@fluentui-react-native/jest-config": "0.1.1",
|
|
46
|
-
"@fluentui-react-native/
|
|
47
|
-
"@react-native/
|
|
48
|
-
"@react-native/
|
|
49
|
-
"@
|
|
50
|
-
"@
|
|
51
|
-
"react": "
|
|
52
|
-
"react-native": "^0.
|
|
53
|
-
"react
|
|
46
|
+
"@fluentui-react-native/kit-config": "0.1.2",
|
|
47
|
+
"@fluentui-react-native/scripts": "0.1.2",
|
|
48
|
+
"@react-native-community/cli": "^20.0.0",
|
|
49
|
+
"@react-native-community/cli-platform-android": "^20.0.0",
|
|
50
|
+
"@react-native-community/cli-platform-ios": "^20.0.0",
|
|
51
|
+
"@react-native/babel-preset": "^0.81.0",
|
|
52
|
+
"@react-native/metro-config": "^0.81.0",
|
|
53
|
+
"@types/react": "~19.1.0",
|
|
54
|
+
"@types/react-test-renderer": "^19.1.0",
|
|
55
|
+
"react": "19.1.0",
|
|
56
|
+
"react-native": "^0.81.0",
|
|
57
|
+
"react-test-renderer": "19.1.0"
|
|
54
58
|
},
|
|
55
59
|
"peerDependencies": {
|
|
56
|
-
"react": "18.2.0",
|
|
57
|
-
"react
|
|
60
|
+
"@types/react": "~18.2.0 || ~19.0.0 || ~19.1.0",
|
|
61
|
+
"react": "18.2.0 || 19.0.0 || 19.1.0"
|
|
62
|
+
},
|
|
63
|
+
"peerDependenciesMeta": {
|
|
64
|
+
"@types/react": {
|
|
65
|
+
"optional": true
|
|
66
|
+
}
|
|
58
67
|
},
|
|
59
68
|
"rnx-kit": {
|
|
60
69
|
"kitType": "library",
|
|
61
70
|
"alignDeps": {
|
|
62
|
-
"presets": [
|
|
63
|
-
"microsoft/react-native"
|
|
64
|
-
],
|
|
65
|
-
"requirements": {
|
|
66
|
-
"development": [
|
|
67
|
-
"react-native@0.74"
|
|
68
|
-
],
|
|
69
|
-
"production": [
|
|
70
|
-
"react-native@0.73 || 0.74"
|
|
71
|
-
]
|
|
72
|
-
},
|
|
73
71
|
"capabilities": [
|
|
74
|
-
"
|
|
75
|
-
"core",
|
|
76
|
-
"core-
|
|
77
|
-
"core-ios",
|
|
72
|
+
"core-android-dev-only",
|
|
73
|
+
"core-dev-only",
|
|
74
|
+
"core-ios-dev-only",
|
|
78
75
|
"react",
|
|
79
|
-
"react-test-renderer"
|
|
76
|
+
"react-test-renderer",
|
|
77
|
+
"tools-core",
|
|
78
|
+
"tools-jest"
|
|
80
79
|
]
|
|
81
|
-
}
|
|
80
|
+
},
|
|
81
|
+
"extends": "@fluentui-react-native/kit-config"
|
|
82
82
|
}
|
|
83
|
-
}
|
|
83
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
3
|
exports[`useSlots sample code test suite renders sample 1 - the two types of basic bold text components 1`] = `
|
|
4
|
-
<
|
|
5
|
-
<
|
|
4
|
+
<View>
|
|
5
|
+
<Text
|
|
6
6
|
style={
|
|
7
7
|
{
|
|
8
8
|
"color": "black",
|
|
@@ -11,8 +11,8 @@ exports[`useSlots sample code test suite renders sample 1 - the two types of bas
|
|
|
11
11
|
}
|
|
12
12
|
>
|
|
13
13
|
Staged component at one level
|
|
14
|
-
</
|
|
15
|
-
<
|
|
14
|
+
</Text>
|
|
15
|
+
<Text
|
|
16
16
|
style={
|
|
17
17
|
{
|
|
18
18
|
"color": "black",
|
|
@@ -21,13 +21,13 @@ exports[`useSlots sample code test suite renders sample 1 - the two types of bas
|
|
|
21
21
|
}
|
|
22
22
|
>
|
|
23
23
|
Standard component of a single level
|
|
24
|
-
</
|
|
25
|
-
</
|
|
24
|
+
</Text>
|
|
25
|
+
</View>
|
|
26
26
|
`;
|
|
27
27
|
|
|
28
28
|
exports[`useSlots sample code test suite renders sample 2 = the two types of two level header components 1`] = `
|
|
29
29
|
<div>
|
|
30
|
-
<
|
|
30
|
+
<Text
|
|
31
31
|
style={
|
|
32
32
|
{
|
|
33
33
|
"color": "black",
|
|
@@ -37,8 +37,8 @@ exports[`useSlots sample code test suite renders sample 2 = the two types of two
|
|
|
37
37
|
}
|
|
38
38
|
>
|
|
39
39
|
Staged component with two levels
|
|
40
|
-
</
|
|
41
|
-
<
|
|
40
|
+
</Text>
|
|
41
|
+
<Text
|
|
42
42
|
style={
|
|
43
43
|
{
|
|
44
44
|
"color": "black",
|
|
@@ -48,7 +48,7 @@ exports[`useSlots sample code test suite renders sample 2 = the two types of two
|
|
|
48
48
|
}
|
|
49
49
|
>
|
|
50
50
|
Standard component with two levels
|
|
51
|
-
</
|
|
51
|
+
</Text>
|
|
52
52
|
</div>
|
|
53
53
|
`;
|
|
54
54
|
|
|
@@ -57,7 +57,7 @@ exports[`useSlots sample code test suite renders sample 3 - the two types of hig
|
|
|
57
57
|
<span>
|
|
58
58
|
--- SIMPLE USAGE COMPARISON ---
|
|
59
59
|
</span>
|
|
60
|
-
<
|
|
60
|
+
<View
|
|
61
61
|
style={
|
|
62
62
|
{
|
|
63
63
|
"backgroundColor": "gray",
|
|
@@ -68,7 +68,7 @@ exports[`useSlots sample code test suite renders sample 3 - the two types of hig
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
>
|
|
71
|
-
<
|
|
71
|
+
<Text
|
|
72
72
|
style={
|
|
73
73
|
{
|
|
74
74
|
"fontSize": 20,
|
|
@@ -77,9 +77,9 @@ exports[`useSlots sample code test suite renders sample 3 - the two types of hig
|
|
|
77
77
|
}
|
|
78
78
|
>
|
|
79
79
|
Standard HOC
|
|
80
|
-
</
|
|
81
|
-
</
|
|
82
|
-
<
|
|
80
|
+
</Text>
|
|
81
|
+
</View>
|
|
82
|
+
<View
|
|
83
83
|
style={
|
|
84
84
|
{
|
|
85
85
|
"backgroundColor": "gray",
|
|
@@ -90,7 +90,7 @@ exports[`useSlots sample code test suite renders sample 3 - the two types of hig
|
|
|
90
90
|
}
|
|
91
91
|
}
|
|
92
92
|
>
|
|
93
|
-
<
|
|
93
|
+
<Text
|
|
94
94
|
style={
|
|
95
95
|
{
|
|
96
96
|
"fontSize": 20,
|
|
@@ -99,12 +99,12 @@ exports[`useSlots sample code test suite renders sample 3 - the two types of hig
|
|
|
99
99
|
}
|
|
100
100
|
>
|
|
101
101
|
Staged HOC
|
|
102
|
-
</
|
|
103
|
-
</
|
|
102
|
+
</Text>
|
|
103
|
+
</View>
|
|
104
104
|
<span>
|
|
105
105
|
--- COMPARISON WITH CAPTIONS ---
|
|
106
106
|
</span>
|
|
107
|
-
<
|
|
107
|
+
<View
|
|
108
108
|
style={
|
|
109
109
|
{
|
|
110
110
|
"backgroundColor": "gray",
|
|
@@ -115,7 +115,7 @@ exports[`useSlots sample code test suite renders sample 3 - the two types of hig
|
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
>
|
|
118
|
-
<
|
|
118
|
+
<Text
|
|
119
119
|
style={
|
|
120
120
|
{
|
|
121
121
|
"fontSize": 20,
|
|
@@ -124,8 +124,8 @@ exports[`useSlots sample code test suite renders sample 3 - the two types of hig
|
|
|
124
124
|
}
|
|
125
125
|
>
|
|
126
126
|
Standard HOC with Caption
|
|
127
|
-
</
|
|
128
|
-
<
|
|
127
|
+
</Text>
|
|
128
|
+
<Text
|
|
129
129
|
style={
|
|
130
130
|
{
|
|
131
131
|
"fontWeight": 900,
|
|
@@ -133,9 +133,9 @@ exports[`useSlots sample code test suite renders sample 3 - the two types of hig
|
|
|
133
133
|
}
|
|
134
134
|
>
|
|
135
135
|
Caption text
|
|
136
|
-
</
|
|
137
|
-
</
|
|
138
|
-
<
|
|
136
|
+
</Text>
|
|
137
|
+
</View>
|
|
138
|
+
<View
|
|
139
139
|
style={
|
|
140
140
|
{
|
|
141
141
|
"backgroundColor": "gray",
|
|
@@ -146,7 +146,7 @@ exports[`useSlots sample code test suite renders sample 3 - the two types of hig
|
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
>
|
|
149
|
-
<
|
|
149
|
+
<Text
|
|
150
150
|
style={
|
|
151
151
|
{
|
|
152
152
|
"fontSize": 20,
|
|
@@ -155,8 +155,8 @@ exports[`useSlots sample code test suite renders sample 3 - the two types of hig
|
|
|
155
155
|
}
|
|
156
156
|
>
|
|
157
157
|
Staged HOC with Caption
|
|
158
|
-
</
|
|
159
|
-
<
|
|
158
|
+
</Text>
|
|
159
|
+
<Text
|
|
160
160
|
style={
|
|
161
161
|
{
|
|
162
162
|
"fontWeight": 900,
|
|
@@ -164,12 +164,12 @@ exports[`useSlots sample code test suite renders sample 3 - the two types of hig
|
|
|
164
164
|
}
|
|
165
165
|
>
|
|
166
166
|
Caption text
|
|
167
|
-
</
|
|
168
|
-
</
|
|
167
|
+
</Text>
|
|
168
|
+
</View>
|
|
169
169
|
<span>
|
|
170
170
|
--- COMPARISON WITH CAPTIONS AND CUSTOMIZATIONS ---
|
|
171
171
|
</span>
|
|
172
|
-
<
|
|
172
|
+
<View
|
|
173
173
|
style={
|
|
174
174
|
{
|
|
175
175
|
"backgroundColor": "gray",
|
|
@@ -180,7 +180,7 @@ exports[`useSlots sample code test suite renders sample 3 - the two types of hig
|
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
>
|
|
183
|
-
<
|
|
183
|
+
<Text
|
|
184
184
|
style={
|
|
185
185
|
{
|
|
186
186
|
"color": "red",
|
|
@@ -190,8 +190,8 @@ exports[`useSlots sample code test suite renders sample 3 - the two types of hig
|
|
|
190
190
|
}
|
|
191
191
|
>
|
|
192
192
|
Standard HOC with caption and customizations
|
|
193
|
-
</
|
|
194
|
-
<
|
|
193
|
+
</Text>
|
|
194
|
+
<Text
|
|
195
195
|
style={
|
|
196
196
|
{
|
|
197
197
|
"color": "yellow",
|
|
@@ -200,9 +200,9 @@ exports[`useSlots sample code test suite renders sample 3 - the two types of hig
|
|
|
200
200
|
}
|
|
201
201
|
>
|
|
202
202
|
Caption text
|
|
203
|
-
</
|
|
204
|
-
</
|
|
205
|
-
<
|
|
203
|
+
</Text>
|
|
204
|
+
</View>
|
|
205
|
+
<View
|
|
206
206
|
style={
|
|
207
207
|
{
|
|
208
208
|
"backgroundColor": "gray",
|
|
@@ -213,7 +213,7 @@ exports[`useSlots sample code test suite renders sample 3 - the two types of hig
|
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
215
|
>
|
|
216
|
-
<
|
|
216
|
+
<Text
|
|
217
217
|
style={
|
|
218
218
|
{
|
|
219
219
|
"color": "red",
|
|
@@ -223,8 +223,8 @@ exports[`useSlots sample code test suite renders sample 3 - the two types of hig
|
|
|
223
223
|
}
|
|
224
224
|
>
|
|
225
225
|
Staged HOC with caption and customizations
|
|
226
|
-
</
|
|
227
|
-
<
|
|
226
|
+
</Text>
|
|
227
|
+
<Text
|
|
228
228
|
style={
|
|
229
229
|
{
|
|
230
230
|
"color": "yellow",
|
|
@@ -233,7 +233,7 @@ exports[`useSlots sample code test suite renders sample 3 - the two types of hig
|
|
|
233
233
|
}
|
|
234
234
|
>
|
|
235
235
|
Caption text
|
|
236
|
-
</
|
|
237
|
-
</
|
|
236
|
+
</Text>
|
|
237
|
+
</View>
|
|
238
238
|
</div>
|
|
239
239
|
`;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
/** @
|
|
2
|
-
|
|
1
|
+
/** @jsxImportSource @fluentui-react-native/framework-base */
|
|
2
|
+
import { act } from 'react';
|
|
3
3
|
import type { ViewProps, TextProps } from 'react-native';
|
|
4
4
|
import { View, Text } from 'react-native';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { stagedComponent } from '@fluentui-react-native/framework-base';
|
|
7
7
|
import * as renderer from 'react-test-renderer';
|
|
8
8
|
|
|
9
9
|
import { buildUseSlots } from './buildUseSlots';
|
|
@@ -38,7 +38,10 @@ const CompBase = stagedComponent((props: ViewProps) => {
|
|
|
38
38
|
|
|
39
39
|
describe('buildUseSlots test suite', () => {
|
|
40
40
|
it('Simple component render', () => {
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
let component: renderer.ReactTestRenderer;
|
|
42
|
+
act(() => {
|
|
43
|
+
component = renderer.create(<CompBase style={{ width: 30, height: 20, borderColor: 'green', borderWidth: 1 }} />);
|
|
44
|
+
});
|
|
45
|
+
expect(component!.toJSON()).toMatchSnapshot();
|
|
43
46
|
});
|
|
44
47
|
});
|
package/src/buildUseSlots.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import { useSlot, type ComponentType } from '@fluentui-react-native/use-slot';
|
|
2
|
+
import type { FunctionComponent, PropsFilter } from '@fluentui-react-native/framework-base';
|
|
3
3
|
|
|
4
4
|
// type AsObject<T> = T extends object ? T : never
|
|
5
5
|
|
|
@@ -8,11 +8,11 @@ import { useSlot } from '@fluentui-react-native/use-slot';
|
|
|
8
8
|
*/
|
|
9
9
|
type UseStyling<TSlotProps> = (...props: unknown[]) => TSlotProps;
|
|
10
10
|
|
|
11
|
-
export type Slots<TSlotProps> = { [K in keyof TSlotProps]:
|
|
11
|
+
export type Slots<TSlotProps> = { [K in keyof TSlotProps]: FunctionComponent<TSlotProps[K]> };
|
|
12
12
|
|
|
13
13
|
export type UseSlotOptions<TSlotProps> = {
|
|
14
|
-
slots: { [K in keyof TSlotProps]:
|
|
15
|
-
filters?: { [K in keyof TSlotProps]?:
|
|
14
|
+
slots: { [K in keyof TSlotProps]: ComponentType<TSlotProps[K]> };
|
|
15
|
+
filters?: { [K in keyof TSlotProps]?: PropsFilter };
|
|
16
16
|
useStyling?: TSlotProps | GetSlotProps<TSlotProps>;
|
|
17
17
|
};
|
|
18
18
|
|
|
@@ -31,6 +31,9 @@ export function buildUseSlots<TSlotProps>(options: UseSlotOptions<TSlotProps>):
|
|
|
31
31
|
const builtSlots: Slots<TSlotProps> = {} as Slots<TSlotProps>;
|
|
32
32
|
|
|
33
33
|
// for each slot go through and either cache the slot props or call part one render if it is staged
|
|
34
|
+
|
|
35
|
+
// note: changing this to a for..in loop causes rule of hooks violations
|
|
36
|
+
// eslint-disable-next-line @rnx-kit/no-foreach-with-captured-variables
|
|
34
37
|
Object.keys(slots).forEach((slotName) => {
|
|
35
38
|
builtSlots[slotName] = useSlot(slots[slotName], slotProps[slotName], filters[slotName]);
|
|
36
39
|
});
|
|
@@ -1,19 +1,13 @@
|
|
|
1
|
-
/** @
|
|
2
|
-
|
|
3
|
-
import type { CSSProperties } from 'react';
|
|
4
|
-
|
|
1
|
+
/** @jsxImportSource @fluentui-react-native/framework-base */
|
|
2
|
+
import { act } from 'react';
|
|
5
3
|
import { mergeProps } from '@fluentui-react-native/framework-base';
|
|
6
|
-
import {
|
|
4
|
+
import { phasedComponent } from '@fluentui-react-native/framework-base';
|
|
7
5
|
import * as renderer from 'react-test-renderer';
|
|
6
|
+
import { View, Text } from 'react-native';
|
|
7
|
+
import type { ViewProps, TextProps, ViewStyle, TextStyle } from 'react-native';
|
|
8
8
|
|
|
9
9
|
import { buildUseSlots } from './buildUseSlots';
|
|
10
10
|
|
|
11
|
-
// types for web
|
|
12
|
-
type TextProps = { style?: CSSProperties };
|
|
13
|
-
type ViewProps = { style?: CSSProperties };
|
|
14
|
-
type ViewStyle = CSSProperties;
|
|
15
|
-
type TextStyle = CSSProperties;
|
|
16
|
-
|
|
17
11
|
/**
|
|
18
12
|
* This file contains samples and description to help explain what the useSlots hook does and why it is useful
|
|
19
13
|
* for building components.
|
|
@@ -47,7 +41,7 @@ describe('useSlots sample code test suite', () => {
|
|
|
47
41
|
* Now render the text, merging the baseProps with the style updates with the rest param. Note that this leverages the fact
|
|
48
42
|
* that mergeProps will reliably produce style objects with the same reference, given the same inputs.
|
|
49
43
|
*/
|
|
50
|
-
return <
|
|
44
|
+
return <Text {...mergeProps(boldBaseProps, rest)}>{children}</Text>;
|
|
51
45
|
};
|
|
52
46
|
BoldTextStandard.displayName = 'BoldTextStandard';
|
|
53
47
|
|
|
@@ -55,19 +49,21 @@ describe('useSlots sample code test suite', () => {
|
|
|
55
49
|
* To write the same component using the staged pattern is only slightly more complex. The pattern involves splitting the component rendering into
|
|
56
50
|
* two parts and executing any hooks in the first part.
|
|
57
51
|
*
|
|
58
|
-
* The
|
|
52
|
+
* The phasedComponent function takes an input function of this form and wraps it in a function component that react knows how to render
|
|
59
53
|
*/
|
|
60
|
-
const BoldTextStaged =
|
|
54
|
+
const BoldTextStaged = phasedComponent((props: React.PropsWithChildren<TextProps>) => {
|
|
61
55
|
/**
|
|
62
56
|
* This section would be where hook/styling code would go, props here would include everything coming in from the base react tree with the
|
|
63
57
|
* exception of children, which will be passed in stage 2.
|
|
64
58
|
*/
|
|
65
|
-
return (extra:
|
|
59
|
+
return (extra: React.PropsWithChildren<TextProps>) => {
|
|
66
60
|
/**
|
|
67
61
|
* extra are additional props that may be filled in by a higher order component. They should not include styling and are only props the
|
|
68
62
|
* enclosing component are passing to the JSX elements
|
|
69
63
|
*/
|
|
70
|
-
|
|
64
|
+
|
|
65
|
+
const { children, ...rest } = extra;
|
|
66
|
+
return <Text {...mergeProps(boldBaseProps, props, rest)}>{children}</Text>;
|
|
71
67
|
};
|
|
72
68
|
});
|
|
73
69
|
BoldTextStaged.displayName = 'BoldTextStaged';
|
|
@@ -78,15 +74,16 @@ describe('useSlots sample code test suite', () => {
|
|
|
78
74
|
/**
|
|
79
75
|
* First render the staged component. This invokes the wrapper that was built by the stagedComponent function
|
|
80
76
|
*/
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
77
|
+
let component: renderer.ReactTestRenderer;
|
|
78
|
+
act(() => {
|
|
79
|
+
component = renderer.create(
|
|
80
|
+
<View>
|
|
84
81
|
<BoldTextStaged style={styleToMerge}>Staged component at one level</BoldTextStaged>
|
|
85
82
|
<BoldTextStandard style={styleToMerge}>Standard component of a single level</BoldTextStandard>
|
|
86
|
-
</
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
expect(
|
|
83
|
+
</View>,
|
|
84
|
+
);
|
|
85
|
+
});
|
|
86
|
+
expect(component!.toJSON()).toMatchSnapshot();
|
|
90
87
|
});
|
|
91
88
|
|
|
92
89
|
/**
|
|
@@ -121,7 +118,7 @@ describe('useSlots sample code test suite', () => {
|
|
|
121
118
|
/**
|
|
122
119
|
* Now author the staged component using the slot hook
|
|
123
120
|
*/
|
|
124
|
-
const HeaderStaged =
|
|
121
|
+
const HeaderStaged = phasedComponent((props: React.PropsWithChildren<TextProps>) => {
|
|
125
122
|
/**
|
|
126
123
|
* Call the slots hook (or any hook) outside of the inner closure. The useSlots hook will return an object with each slot as a renderable
|
|
127
124
|
* function. The hooks for sub-components will be called as part of this call. Props passed in at this point will be the props that appear
|
|
@@ -132,7 +129,8 @@ describe('useSlots sample code test suite', () => {
|
|
|
132
129
|
const BoldText = useHeaderSlots(props).text;
|
|
133
130
|
|
|
134
131
|
/** Now the inner closure, pretty much the same as before */
|
|
135
|
-
return (extra: TextProps
|
|
132
|
+
return (extra: TextProps) => {
|
|
133
|
+
const { children, ...rest } = extra;
|
|
136
134
|
/**
|
|
137
135
|
* Instead of rendering the <BoldTextStageed> component directly we render using the slot. If this is a staged component it will call the
|
|
138
136
|
* inner closure directly, without going through createElement. Entries passed into the JSX, including children, are what appear in the
|
|
@@ -141,7 +139,7 @@ describe('useSlots sample code test suite', () => {
|
|
|
141
139
|
* NOTE: this requires using the withSlots helper via the jsx directive. This knows how to pick apart the entries and just call the second
|
|
142
140
|
* part of the function
|
|
143
141
|
*/
|
|
144
|
-
return <BoldText {...mergeProps(headerBaseProps, props,
|
|
142
|
+
return <BoldText {...mergeProps(headerBaseProps, props, rest)}>{children}</BoldText>;
|
|
145
143
|
};
|
|
146
144
|
});
|
|
147
145
|
HeaderStaged.displayName = 'HeaderStaged';
|
|
@@ -156,15 +154,16 @@ describe('useSlots sample code test suite', () => {
|
|
|
156
154
|
/**
|
|
157
155
|
* First render the staged component. This invokes the wrapper that was built by the stagedComponent function
|
|
158
156
|
*/
|
|
159
|
-
|
|
160
|
-
|
|
157
|
+
let component: renderer.ReactTestRenderer;
|
|
158
|
+
act(() => {
|
|
159
|
+
component = renderer.create(
|
|
161
160
|
<div>
|
|
162
161
|
<HeaderStaged style={styleToMerge}>Staged component with two levels</HeaderStaged>
|
|
163
162
|
<HeaderStandard style={styleToMerge}>Standard component with two levels</HeaderStandard>
|
|
164
163
|
</div>,
|
|
165
|
-
)
|
|
166
|
-
|
|
167
|
-
expect(
|
|
164
|
+
);
|
|
165
|
+
});
|
|
166
|
+
expect(component!.toJSON()).toMatchSnapshot();
|
|
168
167
|
});
|
|
169
168
|
|
|
170
169
|
/**
|
|
@@ -199,10 +198,10 @@ describe('useSlots sample code test suite', () => {
|
|
|
199
198
|
const headerColorProps = getColorProps(headerColor);
|
|
200
199
|
const captionColorProps = getColorProps(captionColor);
|
|
201
200
|
return (
|
|
202
|
-
<
|
|
201
|
+
<View {...mergeProps(containerProps, rest)}>
|
|
203
202
|
<HeaderStandard {...headerColorProps}>{children}</HeaderStandard>
|
|
204
203
|
{captionText && <BoldTextStandard {...captionColorProps}>{captionText}</BoldTextStandard>}
|
|
205
|
-
</
|
|
204
|
+
</View>
|
|
206
205
|
);
|
|
207
206
|
};
|
|
208
207
|
CaptionedHeaderStandard.displayName = `CaptionedHeaderStandard';`;
|
|
@@ -213,7 +212,7 @@ describe('useSlots sample code test suite', () => {
|
|
|
213
212
|
const useCaptionedHeaderSlots = buildUseSlots({
|
|
214
213
|
/** Slots are just like above, this component will have three sub-components */
|
|
215
214
|
slots: {
|
|
216
|
-
container:
|
|
215
|
+
container: View,
|
|
217
216
|
header: HeaderStaged,
|
|
218
217
|
caption: BoldTextStaged,
|
|
219
218
|
},
|
|
@@ -231,12 +230,12 @@ describe('useSlots sample code test suite', () => {
|
|
|
231
230
|
/**
|
|
232
231
|
* now use the hook to implement it as a staged component
|
|
233
232
|
*/
|
|
234
|
-
const CaptionedHeaderStaged =
|
|
233
|
+
const CaptionedHeaderStaged = phasedComponent<React.PropsWithChildren<HeaderWithCaptionProps>>((props) => {
|
|
235
234
|
// At the point where this is called the slots are initialized with the initial prop values from useStyling above
|
|
236
235
|
const Slots = useCaptionedHeaderSlots(props);
|
|
237
|
-
return (extra: HeaderWithCaptionProps
|
|
236
|
+
return (extra: HeaderWithCaptionProps) => {
|
|
238
237
|
// merge the props together, picking out the caption text and clearing any custom values we don't want forwarded to the view
|
|
239
|
-
const { captionText, ...rest } = mergeProps(props, extra, clearCustomProps);
|
|
238
|
+
const { children, captionText, ...rest } = mergeProps(props, extra, clearCustomProps);
|
|
240
239
|
|
|
241
240
|
// now render using the slots. Any values passed in via JSX will be merged with values from the slot hook above
|
|
242
241
|
return (
|
|
@@ -256,8 +255,9 @@ describe('useSlots sample code test suite', () => {
|
|
|
256
255
|
* Render the two sets of components. Note in the snapshots how the render tree layers for the standard approach are starting
|
|
257
256
|
* to add up.
|
|
258
257
|
*/
|
|
259
|
-
|
|
260
|
-
|
|
258
|
+
let component: renderer.ReactTestRenderer;
|
|
259
|
+
act(() => {
|
|
260
|
+
component = renderer.create(
|
|
261
261
|
<div>
|
|
262
262
|
<span>--- SIMPLE USAGE COMPARISON ---</span>
|
|
263
263
|
<CaptionedHeaderStandard style={styleToMerge}>Standard HOC</CaptionedHeaderStandard>
|
|
@@ -277,8 +277,8 @@ describe('useSlots sample code test suite', () => {
|
|
|
277
277
|
Staged HOC with caption and customizations
|
|
278
278
|
</CaptionedHeaderStaged>
|
|
279
279
|
</div>,
|
|
280
|
-
)
|
|
281
|
-
|
|
282
|
-
expect(
|
|
280
|
+
);
|
|
281
|
+
});
|
|
282
|
+
expect(component!.toJSON()).toMatchSnapshot();
|
|
283
283
|
});
|
|
284
284
|
});
|