Skip to content

Commit ac638f1

Browse files
author
Brian Vaughn
committed
Add stylex metadata to new plugins field
And display it separately in DevTools, as read-only (for now)
1 parent 578853e commit ac638f1

File tree

10 files changed

+247
-45
lines changed

10 files changed

+247
-45
lines changed

packages/react-devtools-shared/src/backend/StyleX/__tests__/utils-test.js

+78-29
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*/
99

1010
describe('Stylex plugin utils', () => {
11-
let getStyleXValues;
11+
let getStyleXData;
1212
let styleElements;
1313

1414
function defineStyles(style) {
@@ -22,7 +22,7 @@ describe('Stylex plugin utils', () => {
2222
}
2323

2424
beforeEach(() => {
25-
getStyleXValues = require('../utils').getStyleXValues;
25+
getStyleXData = require('../utils').getStyleXData;
2626

2727
styleElements = [];
2828
});
@@ -47,16 +47,25 @@ describe('Stylex plugin utils', () => {
4747
`);
4848

4949
expect(
50-
getStyleXValues({
50+
getStyleXData({
51+
// The source/module styles are defined in
52+
Example__style: 'Example__style',
53+
54+
// Map of CSS style to StyleX class name, booleans, or nested structures
5155
display: 'foo',
5256
flexDirection: 'baz',
5357
alignItems: 'bar',
5458
}),
5559
).toMatchInlineSnapshot(`
5660
Object {
57-
"alignItems": "center",
58-
"display": "flex",
59-
"flexDirection": "center",
61+
"resolvedStyles": Object {
62+
"alignItems": "center",
63+
"display": "flex",
64+
"flexDirection": "center",
65+
},
66+
"sources": Array [
67+
"Example__style",
68+
],
6069
}
6170
`);
6271
});
@@ -75,15 +84,25 @@ describe('Stylex plugin utils', () => {
7584
`);
7685

7786
expect(
78-
getStyleXValues([
79-
{display: 'foo'},
80-
{flexDirection: 'baz', alignItems: 'bar'},
87+
getStyleXData([
88+
{Example1__style: 'Example1__style', display: 'foo'},
89+
{
90+
Example2__style: 'Example2__style',
91+
flexDirection: 'baz',
92+
alignItems: 'bar',
93+
},
8194
]),
8295
).toMatchInlineSnapshot(`
8396
Object {
84-
"alignItems": "center",
85-
"display": "flex",
86-
"flexDirection": "center",
97+
"resolvedStyles": Object {
98+
"alignItems": "center",
99+
"display": "flex",
100+
"flexDirection": "center",
101+
},
102+
"sources": Array [
103+
"Example1__style",
104+
"Example2__style",
105+
],
87106
}
88107
`);
89108
});
@@ -102,19 +121,29 @@ describe('Stylex plugin utils', () => {
102121
`);
103122

104123
expect(
105-
getStyleXValues([
124+
getStyleXData([
106125
false,
107-
{display: 'foo'},
126+
{Example1__style: 'Example1__style', display: 'foo'},
108127
false,
109128
false,
110-
{flexDirection: 'baz', alignItems: 'bar'},
129+
{
130+
Example2__style: 'Example2__style',
131+
flexDirection: 'baz',
132+
alignItems: 'bar',
133+
},
111134
false,
112135
]),
113136
).toMatchInlineSnapshot(`
114137
Object {
115-
"alignItems": "center",
116-
"display": "flex",
117-
"flexDirection": "center",
138+
"resolvedStyles": Object {
139+
"alignItems": "center",
140+
"display": "flex",
141+
"flexDirection": "center",
142+
},
143+
"sources": Array [
144+
"Example1__style",
145+
"Example2__style",
146+
],
118147
}
119148
`);
120149
});
@@ -133,7 +162,11 @@ describe('Stylex plugin utils', () => {
133162
`);
134163

135164
expect(
136-
getStyleXValues({
165+
getStyleXData({
166+
// The source/module styles are defined in
167+
Example__style: 'Example__style',
168+
169+
// Map of CSS style to StyleX class name, booleans, or nested structures
137170
color: 'foo',
138171
':hover': {
139172
color: 'bar',
@@ -142,11 +175,16 @@ describe('Stylex plugin utils', () => {
142175
}),
143176
).toMatchInlineSnapshot(`
144177
Object {
145-
":hover": Object {
146-
"color": "blue",
147-
"textDecoration": "none",
178+
"resolvedStyles": Object {
179+
":hover": Object {
180+
"color": "blue",
181+
"textDecoration": "none",
182+
},
183+
"color": "black",
148184
},
149-
"color": "black",
185+
"sources": Array [
186+
"Example__style",
187+
],
150188
}
151189
`);
152190
});
@@ -165,17 +203,28 @@ describe('Stylex plugin utils', () => {
165203
`);
166204

167205
expect(
168-
getStyleXValues([
169-
{display: 'foo'},
206+
getStyleXData([
207+
{Example1__style: 'Example1__style', display: 'foo'},
170208
false,
171-
[false, {flexDirection: 'baz'}, {alignItems: 'bar'}],
209+
[
210+
false,
211+
{Example2__style: 'Example2__style', flexDirection: 'baz'},
212+
{Example3__style: 'Example3__style', alignItems: 'bar'},
213+
],
172214
false,
173215
]),
174216
).toMatchInlineSnapshot(`
175217
Object {
176-
"alignItems": "center",
177-
"display": "flex",
178-
"flexDirection": "center",
218+
"resolvedStyles": Object {
219+
"alignItems": "center",
220+
"display": "flex",
221+
"flexDirection": "center",
222+
},
223+
"sources": Array [
224+
"Example1__style",
225+
"Example2__style",
226+
"Example3__style",
227+
],
179228
}
180229
`);
181230
});

packages/react-devtools-shared/src/backend/StyleX/utils.js

+41-9
Original file line numberDiff line numberDiff line change
@@ -7,34 +7,66 @@
77
* @flow
88
*/
99

10+
export type StyleXData = {|
11+
sources: Array<string>,
12+
resolvedStyles: Object,
13+
|};
14+
1015
const cachedStyleNameToValueMap: Map<string, string> = new Map();
1116

12-
export function getStyleXValues(data: any, mappedStyles: Object = {}) {
17+
export function getStyleXData(data: any): StyleXData {
18+
const sources = new Set();
19+
const resolvedStyles = {};
20+
21+
crawlData(data, sources, resolvedStyles);
22+
23+
return {
24+
sources: Array.from(sources).sort(),
25+
resolvedStyles,
26+
};
27+
}
28+
29+
export function crawlData(
30+
data: any,
31+
sources: Set<string>,
32+
resolvedStyles: Object,
33+
): void {
1334
if (Array.isArray(data)) {
1435
data.forEach(entry => {
1536
if (Array.isArray(entry)) {
16-
getStyleXValues(entry, mappedStyles);
37+
crawlData(entry, sources, resolvedStyles);
1738
} else {
18-
crawlObjectProperties(entry, mappedStyles);
39+
crawlObjectProperties(entry, sources, resolvedStyles);
1940
}
2041
});
2142
} else {
22-
crawlObjectProperties(data, mappedStyles);
43+
crawlObjectProperties(data, sources, resolvedStyles);
2344
}
2445

25-
return Object.fromEntries<string, any>(Object.entries(mappedStyles).sort());
46+
resolvedStyles = Object.fromEntries<string, any>(
47+
Object.entries(resolvedStyles).sort(),
48+
);
2649
}
2750

28-
function crawlObjectProperties(entry: Object, mappedStyles: Object) {
51+
function crawlObjectProperties(
52+
entry: Object,
53+
sources: Set<string>,
54+
resolvedStyles: Object,
55+
): void {
2956
const keys = Object.keys(entry);
3057
keys.forEach(key => {
3158
const value = entry[key];
3259
if (typeof value === 'string') {
33-
mappedStyles[key] = getPropertyValueForStyleName(value);
60+
if (key === value) {
61+
// Special case; this key is the name of the style's source/file/module.
62+
sources.add(key);
63+
} else {
64+
resolvedStyles[key] = getPropertyValueForStyleName(value);
65+
}
3466
} else {
3567
const nestedStyle = {};
36-
mappedStyles[key] = nestedStyle;
37-
getStyleXValues([value], nestedStyle);
68+
resolvedStyles[key] = nestedStyle;
69+
crawlData([value], sources, nestedStyle);
3870
}
3971
});
4072
}

packages/react-devtools-shared/src/backend/legacy/renderer.js

+2
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,8 @@ export function attach(
838838
rootType: null,
839839
rendererPackageName: null,
840840
rendererVersion: null,
841+
842+
plugins: [],
841843
};
842844
}
843845

packages/react-devtools-shared/src/backend/renderer.js

+12-7
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ import {
8989
import is from 'shared/objectIs';
9090
import isArray from 'shared/isArray';
9191
import hasOwnProperty from 'shared/hasOwnProperty';
92-
import {getStyleXValues} from './StyleX/utils';
92+
import {getStyleXData} from './StyleX/utils';
9393

9494
import type {Fiber} from 'react-reconciler/src/ReactInternalTypes';
9595
import type {
@@ -102,6 +102,7 @@ import type {
102102
NativeType,
103103
PathFrame,
104104
PathMatch,
105+
Plugin,
105106
ProfilingDataBackend,
106107
ProfilingDataForRootBackend,
107108
ReactRenderer,
@@ -3238,12 +3239,14 @@ export function attach(
32383239
targetErrorBoundaryID = getNearestErrorBoundaryID(fiber);
32393240
}
32403241

3241-
const modifiedProps = {
3242-
...memoizedProps,
3243-
};
3242+
const plugins: Array<Plugin> = [];
3243+
32443244
if (enableStyleXFeatures) {
3245-
if (modifiedProps.hasOwnProperty('xstyle')) {
3246-
modifiedProps.xstyle = getStyleXValues(modifiedProps.xstyle);
3245+
if (memoizedProps.hasOwnProperty('xstyle')) {
3246+
plugins.push({
3247+
type: 'stylex',
3248+
data: getStyleXData(memoizedProps.xstyle),
3249+
});
32473250
}
32483251
}
32493252

@@ -3292,7 +3295,7 @@ export function attach(
32923295
// TODO Review sanitization approach for the below inspectable values.
32933296
context,
32943297
hooks,
3295-
props: modifiedProps,
3298+
props: memoizedProps,
32963299
state: showState ? memoizedState : null,
32973300
errors: Array.from(errors.entries()),
32983301
warnings: Array.from(warnings.entries()),
@@ -3306,6 +3309,8 @@ export function attach(
33063309
rootType,
33073310
rendererPackageName: renderer.rendererPackageName,
33083311
rendererVersion: renderer.version,
3312+
3313+
plugins,
33093314
};
33103315
}
33113316

packages/react-devtools-shared/src/backend/types.js

+11
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,14 @@ export type OwnersList = {|
213213
owners: Array<SerializedElement> | null,
214214
|};
215215

216+
// For now, let's only support a hard-coded set of plugins.
217+
type PluginType = 'stylex';
218+
219+
export type Plugin = {
220+
type: PluginType,
221+
data: any,
222+
};
223+
216224
export type InspectedElement = {|
217225
id: number,
218226

@@ -265,6 +273,9 @@ export type InspectedElement = {|
265273
// Meta information about the renderer that created this element.
266274
rendererPackageName: string | null,
267275
rendererVersion: string | null,
276+
277+
// Array of UI plugins/visualizations for the inspected element.
278+
plugins: Array<Plugin>,
268279
|};
269280

270281
export const InspectElementErrorType = 'error';

packages/react-devtools-shared/src/backendAPI.js

+2
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ export function convertInspectedElementBackendToFrontend(
208208
owners,
209209
context,
210210
hooks,
211+
plugins,
211212
props,
212213
rendererPackageName,
213214
rendererVersion,
@@ -233,6 +234,7 @@ export function convertInspectedElementBackendToFrontend(
233234
hasLegacyContext,
234235
id,
235236
key,
237+
plugins,
236238
rendererPackageName,
237239
rendererVersion,
238240
rootType,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.Source {
2+
color: var(--color-dim);
3+
margin-left: 1rem;
4+
overflow: auto;
5+
text-overflow: ellipsis;
6+
}

0 commit comments

Comments
 (0)