Skip to content

Commit d2158d6

Browse files
author
Brian Vaughn
authored
Fix flow types (#18204)
* Added missing @flow pragma to React.js * Fixed useContext() return type definition * Fixed previously masked Flow errors in DevTools and react-interactions packages * Added displayName to internal Context Flow type * Removed Flow generic annotations for createResponder This seems to cause a parsing error. (Not sure why.) The API is deprecated anyway so I'm being lazy for now and just adding a .
1 parent 8e6a08e commit d2158d6

29 files changed

+150
-95
lines changed

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

+47-35
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import {RegistryContext} from './Contexts';
1414

1515
import styles from './ContextMenu.css';
1616

17+
import type {RegistryContextType} from './Contexts';
18+
1719
function respositionToFit(element: HTMLElement, pageX: number, pageY: number) {
1820
const ownerWindow = element.ownerDocument.defaultView;
1921
if (element !== null) {
@@ -52,7 +54,7 @@ type Props = {|
5254
|};
5355

5456
export default function ContextMenu({children, id}: Props) {
55-
const {registerMenu} = useContext(RegistryContext);
57+
const {registerMenu} = useContext<RegistryContextType>(RegistryContext);
5658

5759
const [state, setState] = useState(HIDDEN_STATE);
5860

@@ -61,12 +63,15 @@ export default function ContextMenu({children, id}: Props) {
6163
const menuRef = useRef(null);
6264

6365
useEffect(() => {
64-
const ownerDocument = bodyAccessorRef.current.ownerDocument;
65-
containerRef.current = ownerDocument.createElement('div');
66-
ownerDocument.body.appendChild(containerRef.current);
67-
return () => {
68-
ownerDocument.body.removeChild(containerRef.current);
69-
};
66+
const element = bodyAccessorRef.current;
67+
if (element !== null) {
68+
const ownerDocument = element.ownerDocument;
69+
containerRef.current = ownerDocument.createElement('div');
70+
ownerDocument.body.appendChild(containerRef.current);
71+
return () => {
72+
ownerDocument.body.removeChild(containerRef.current);
73+
};
74+
}
7075
}, []);
7176

7277
useEffect(() => {
@@ -82,45 +87,52 @@ export default function ContextMenu({children, id}: Props) {
8287
return;
8388
}
8489

85-
const menu = menuRef.current;
90+
const menu = ((menuRef.current: any): HTMLElement);
91+
const container = containerRef.current;
92+
if (container !== null) {
93+
const hideUnlessContains = event => {
94+
if (!menu.contains(event.target)) {
95+
setState(HIDDEN_STATE);
96+
}
97+
};
8698

87-
const hideUnlessContains = event => {
88-
if (!menu.contains(event.target)) {
99+
const hide = event => {
89100
setState(HIDDEN_STATE);
90-
}
91-
};
101+
};
92102

93-
const hide = event => {
94-
setState(HIDDEN_STATE);
95-
};
103+
const ownerDocument = container.ownerDocument;
104+
ownerDocument.addEventListener('mousedown', hideUnlessContains);
105+
ownerDocument.addEventListener('touchstart', hideUnlessContains);
106+
ownerDocument.addEventListener('keydown', hideUnlessContains);
96107

97-
const ownerDocument = containerRef.current.ownerDocument;
98-
ownerDocument.addEventListener('mousedown', hideUnlessContains);
99-
ownerDocument.addEventListener('touchstart', hideUnlessContains);
100-
ownerDocument.addEventListener('keydown', hideUnlessContains);
108+
const ownerWindow = ownerDocument.defaultView;
109+
ownerWindow.addEventListener('resize', hide);
101110

102-
const ownerWindow = ownerDocument.defaultView;
103-
ownerWindow.addEventListener('resize', hide);
111+
respositionToFit(menu, state.pageX, state.pageY);
104112

105-
respositionToFit(menu, state.pageX, state.pageY);
113+
return () => {
114+
ownerDocument.removeEventListener('mousedown', hideUnlessContains);
115+
ownerDocument.removeEventListener('touchstart', hideUnlessContains);
116+
ownerDocument.removeEventListener('keydown', hideUnlessContains);
106117

107-
return () => {
108-
ownerDocument.removeEventListener('mousedown', hideUnlessContains);
109-
ownerDocument.removeEventListener('touchstart', hideUnlessContains);
110-
ownerDocument.removeEventListener('keydown', hideUnlessContains);
111-
112-
ownerWindow.removeEventListener('resize', hide);
113-
};
118+
ownerWindow.removeEventListener('resize', hide);
119+
};
120+
}
114121
}, [state]);
115122

116123
if (!state.isVisible) {
117124
return <div ref={bodyAccessorRef} />;
118125
} else {
119-
return createPortal(
120-
<div ref={menuRef} className={styles.ContextMenu}>
121-
{children(state.data)}
122-
</div>,
123-
containerRef.current,
124-
);
126+
const container = containerRef.current;
127+
if (container !== null) {
128+
return createPortal(
129+
<div ref={menuRef} className={styles.ContextMenu}>
130+
{children(state.data)}
131+
</div>,
132+
container,
133+
);
134+
} else {
135+
return null;
136+
}
125137
}
126138
}

packages/react-devtools-shared/src/devtools/ContextMenu/ContextMenuItem.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,16 @@ import {RegistryContext} from './Contexts';
1313

1414
import styles from './ContextMenuItem.css';
1515

16+
import type {RegistryContextType} from './Contexts';
17+
1618
type Props = {|
1719
children: React$Node,
1820
onClick: () => void,
1921
title: string,
2022
|};
2123

2224
export default function ContextMenuItem({children, onClick, title}: Props) {
23-
const {hideMenu} = useContext(RegistryContext);
25+
const {hideMenu} = useContext<RegistryContextType>(RegistryContext);
2426

2527
const handleClick = event => {
2628
onClick();

packages/react-devtools-shared/src/devtools/ContextMenu/Contexts.js

+12-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,18 @@ function registerMenu(id: string, showFn: ShowFn, hideFn: HideFn) {
5555
};
5656
}
5757

58-
export const RegistryContext = createContext({
58+
export type RegistryContextType = {|
59+
hideMenu: () => void,
60+
showMenu: ({|
61+
data: Object,
62+
id: string,
63+
pageX: number,
64+
pageY: number,
65+
|}) => void,
66+
registerMenu: (string, ShowFn, HideFn) => Function,
67+
|};
68+
69+
export const RegistryContext = createContext<RegistryContextType>({
5970
hideMenu,
6071
showMenu,
6172
registerMenu,

packages/react-devtools-shared/src/devtools/ContextMenu/useContextMenu.js

+6-5
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import {useContext, useEffect} from 'react';
1111
import {RegistryContext} from './Contexts';
1212

13+
import type {RegistryContextType} from './Contexts';
1314
import type {ElementRef} from 'react';
1415

1516
export default function useContextMenu({
@@ -21,7 +22,7 @@ export default function useContextMenu({
2122
id: string,
2223
ref: {current: ElementRef<'div'> | null},
2324
|}) {
24-
const {showMenu} = useContext(RegistryContext);
25+
const {showMenu} = useContext<RegistryContextType>(RegistryContext);
2526

2627
useEffect(() => {
2728
if (ref.current !== null) {
@@ -30,11 +31,11 @@ export default function useContextMenu({
3031
event.stopPropagation();
3132

3233
const pageX =
33-
event.pageX ||
34-
(event.touches && ((event: any): TouchEvent).touches[0].pageX);
34+
(event: any).pageX ||
35+
(event.touches && (event: any).touches[0].pageX);
3536
const pageY =
36-
event.pageY ||
37-
(event.touches && ((event: any): TouchEvent).touches[0].pageY);
37+
(event: any).pageY ||
38+
(event.touches && (event: any).touches[0].pageY);
3839

3940
showMenu({data, id, pageX, pageY});
4041
};

packages/react-devtools-shared/src/devtools/views/Components/Components.js

+22-22
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,30 @@ import {NativeStyleContextController} from './NativeStyleEditor/context';
3232

3333
import styles from './Components.css';
3434

35+
type Orientation = 'horizontal' | 'vertical';
36+
37+
type ResizeActionType =
38+
| 'ACTION_SET_DID_MOUNT'
39+
| 'ACTION_SET_IS_RESIZING'
40+
| 'ACTION_SET_HORIZONTAL_PERCENTAGE'
41+
| 'ACTION_SET_VERTICAL_PERCENTAGE';
42+
43+
type ResizeAction = {|
44+
type: ResizeActionType,
45+
payload: any,
46+
|};
47+
48+
type ResizeState = {|
49+
horizontalPercentage: number,
50+
isResizing: boolean,
51+
verticalPercentage: number,
52+
|};
53+
3554
function Components(_: {||}) {
36-
const wrapperElementRef = useRef<HTMLElement>(null);
37-
const resizeElementRef = useRef<HTMLElement>(null);
55+
const wrapperElementRef = useRef<null | HTMLElement>(null);
56+
const resizeElementRef = useRef<null | HTMLElement>(null);
3857

39-
const [state, dispatch] = useReducer<ResizeState, ResizeAction>(
58+
const [state, dispatch] = useReducer<ResizeState, any, ResizeAction>(
4059
resizeReducer,
4160
null,
4261
initResizeState,
@@ -171,25 +190,6 @@ const LOCAL_STORAGE_KEY = 'React::DevTools::createResizeReducer';
171190
const VERTICAL_MODE_MAX_WIDTH = 600;
172191
const MINIMUM_SIZE = 50;
173192

174-
type Orientation = 'horizontal' | 'vertical';
175-
176-
type ResizeActionType =
177-
| 'ACTION_SET_DID_MOUNT'
178-
| 'ACTION_SET_IS_RESIZING'
179-
| 'ACTION_SET_HORIZONTAL_PERCENTAGE'
180-
| 'ACTION_SET_VERTICAL_PERCENTAGE';
181-
182-
type ResizeAction = {|
183-
type: ResizeActionType,
184-
payload: any,
185-
|};
186-
187-
type ResizeState = {|
188-
horizontalPercentage: number,
189-
isResizing: boolean,
190-
verticalPercentage: number,
191-
|};
192-
193193
function initResizeState(): ResizeState {
194194
let horizontalPercentage = 0.65;
195195
let verticalPercentage = 0.5;

packages/react-devtools-shared/src/devtools/views/Components/EditableName.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import {useCallback, useState} from 'react';
1212
import AutoSizeInput from './NativeStyleEditor/AutoSizeInput';
1313
import styles from './EditableName.css';
1414

15-
type OverrideNameFn = (path: Array<string | number>, value: any) => void;
15+
type OverrideNameFn = (name: string, value: any) => void;
1616

1717
type EditableNameProps = {|
1818
autoFocus?: boolean,

packages/react-devtools-shared/src/devtools/views/Components/HooksTree.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ function HookView({canEditHooks, hook, id, inspectPath, path}: HookViewProps) {
241241
} else {
242242
let overrideValueFn = null;
243243
// TODO Maybe read editable value from debug hook?
244-
if (canEditHooks && isStateEditable) {
244+
if (canEditHooks && isStateEditable && hookID !== null) {
245245
overrideValueFn = (
246246
absolutePath: Array<string | number>,
247247
newValue: any,

packages/react-devtools-shared/src/devtools/views/Components/InspectedElementContext.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,16 @@ export type GetInspectedElement = (
5151
id: number,
5252
) => InspectedElementFrontend | null;
5353

54-
type Context = {|
54+
export type InspectedElementContextType = {|
5555
copyInspectedElementPath: CopyInspectedElementPath,
5656
getInspectedElementPath: GetInspectedElementPath,
5757
getInspectedElement: GetInspectedElement,
5858
storeAsGlobal: StoreAsGlobal,
5959
|};
6060

61-
const InspectedElementContext = createContext<Context>(((null: any): Context));
61+
const InspectedElementContext = createContext<InspectedElementContextType>(
62+
((null: any): InspectedElementContextType),
63+
);
6264
InspectedElementContext.displayName = 'InspectedElementContext';
6365

6466
type ResolveFn = (inspectedElement: InspectedElementFrontend) => void;

packages/react-devtools-shared/src/devtools/views/Components/NativeStyleEditor/context.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ import {
2424
} from 'react-devtools-shared/src/devtools/views/context';
2525
import {TreeStateContext} from '../TreeContext';
2626

27+
import type {StateContext} from '../TreeContext';
28+
import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
29+
import type Store from 'react-devtools-shared/src/devtools/store';
2730
import type {StyleAndLayout as StyleAndLayoutBackend} from 'react-devtools-shared/src/backend/NativeStyleEditor/types';
2831
import type {StyleAndLayout as StyleAndLayoutFrontend} from './types';
2932
import type {Element} from 'react-devtools-shared/src/devtools/views/Components/types';
@@ -77,8 +80,8 @@ type Props = {|
7780
|};
7881

7982
function NativeStyleContextController({children}: Props) {
80-
const bridge = useContext(BridgeContext);
81-
const store = useContext(StoreContext);
83+
const bridge = useContext<FrontendBridge>(BridgeContext);
84+
const store = useContext<Store>(StoreContext);
8285

8386
const getStyleAndLayout = useCallback<GetStyleAndLayout>(
8487
(id: number) => {
@@ -95,7 +98,7 @@ function NativeStyleContextController({children}: Props) {
9598
// It's very important that this context consumes selectedElementID and not NativeStyleID.
9699
// Otherwise the effect that sends the "inspect" message across the bridge-
97100
// would itself be blocked by the same render that suspends (waiting for the data).
98-
const {selectedElementID} = useContext(TreeStateContext);
101+
const {selectedElementID} = useContext<StateContext>(TreeStateContext);
99102

100103
const [
101104
currentStyleAndLayout,

packages/react-devtools-shared/src/devtools/views/Components/OwnersStack.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export default function OwnerStack() {
7777
const {ownerID} = useContext(TreeStateContext);
7878
const treeDispatch = useContext(TreeDispatcherContext);
7979

80-
const [state, dispatch] = useReducer<State, Action>(dialogReducer, {
80+
const [state, dispatch] = useReducer<State, State, Action>(dialogReducer, {
8181
ownerID: null,
8282
owners: [],
8383
selectedIndex: 0,

packages/react-devtools-shared/src/devtools/views/Components/SelectedElement.js

+4-5
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,11 @@ import {
3737

3838
import styles from './SelectedElement.css';
3939

40+
import type {ContextMenuContextType} from '../context';
4041
import type {
4142
CopyInspectedElementPath,
4243
GetInspectedElementPath,
44+
InspectedElementContextType,
4345
StoreAsGlobal,
4446
} from './InspectedElementContext';
4547
import type {Element, InspectedElement} from './types';
@@ -62,8 +64,7 @@ export default function SelectedElement(_: Props) {
6264
getInspectedElementPath,
6365
getInspectedElement,
6466
storeAsGlobal,
65-
viewInspectedElementPath,
66-
} = useContext(InspectedElementContext);
67+
} = useContext<InspectedElementContextType>(InspectedElementContext);
6768

6869
const element =
6970
inspectedElementID !== null
@@ -244,7 +245,6 @@ export default function SelectedElement(_: Props) {
244245
getInspectedElementPath={getInspectedElementPath}
245246
inspectedElement={inspectedElement}
246247
storeAsGlobal={storeAsGlobal}
247-
viewInspectedElementPath={viewInspectedElementPath}
248248
/>
249249
)}
250250
</div>
@@ -270,7 +270,6 @@ function InspectedElementView({
270270
getInspectedElementPath,
271271
inspectedElement,
272272
storeAsGlobal,
273-
viewInspectedElementPath,
274273
}: InspectedElementViewProps) {
275274
const {id, type} = element;
276275
const {
@@ -293,7 +292,7 @@ function InspectedElementView({
293292
const {
294293
isEnabledForInspectedElement,
295294
viewAttributeSourceFunction,
296-
} = useContext(ContextMenuContext);
295+
} = useContext<ContextMenuContextType>(ContextMenuContext);
297296

298297
const inspectContextPath = useCallback(
299298
(path: Array<string | number>) => {

packages/react-devtools-shared/src/devtools/views/ModalDialog.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ type Props = {|
7878
|};
7979

8080
function ModalDialogContextController({children}: Props) {
81-
const [state, dispatch] = useReducer<State, Action>(dialogReducer, {
81+
const [state, dispatch] = useReducer<State, State, Action>(dialogReducer, {
8282
canBeDismissed: true,
8383
content: null,
8484
isVisible: false,

packages/react-devtools-shared/src/devtools/views/Profiler/CommitFlamegraph.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,9 @@ type Props = {|
9696
|};
9797

9898
function CommitFlamegraph({chartData, commitTree, height, width}: Props) {
99-
const [hoveredFiberData, hoverFiber] = useState<number | null>(null);
99+
const [hoveredFiberData, hoverFiber] = useState<TooltipFiberData | null>(
100+
null,
101+
);
100102
const {lineHeight} = useContext(SettingsContext);
101103
const {selectFiber, selectedFiberID} = useContext(ProfilerContext);
102104

0 commit comments

Comments
 (0)