profile
viewpoint
Hristo Kanchev hristo-kanchev @getndazn Amsterdam, Netherlands https://www.linkedin.com/in/hristokkanchev JavaScript geek. Pizza black hole.

hristo-kanchev/bg.reactjs.org 0

(Work in progress) React documentation website in Bulgarian

hristo-kanchev/react 0

A declarative, efficient, and flexible JavaScript library for building user interfaces.

hristo-kanchev/react-devtools 0

An extension that allows inspection of React component hierarchy in the Chrome and Firefox Developer Tools.

hristo-kanchev/react-devtools-experimental 0

Experimental rewrite of the React DevTools extension

pull request commentfacebook/react

[DevTools] Added resize support for Components panel.

Happy to help, Brian! Thanks for the support!

hristo-kanchev

comment created time in a day

pull request commentfacebook/react

[DevTools] Added resize support for Components panel.

Ahh.. I saw the issue..

It was happening because we weren't reading and setting the data from the local storage for both the vertical and horizontal orientations on initial mount.

Sorry to bother you again, but can you please check again, @bvaughn ?

hristo-kanchev

comment created time in 2 days

Pull request review commentfacebook/react

[DevTools] Added resize support for Components panel.

+import type {ElementRef} from 'react';++import * as React from 'react';+import {useEffect, useLayoutEffect, useReducer, useRef} from 'react';+import {+  localStorageGetItem,+  localStorageSetItem,+} from 'react-devtools-shared/src/storage';+import styles from './ComponentsResizer.css';++const LOCAL_STORAGE_KEY = 'React::DevTools::createResizeReducer';+const VERTICAL_MODE_MAX_WIDTH = 600;+const MINIMUM_SIZE = 50;++type Props = {|+  children: ({+    resizeElementRef: ElementRef<HTMLElement>,+    onResizeStart: () => void,+  }) => React$Node,+|};++export default function ComponentsResizer({children}: Props) {+  const wrapperElementRef = useRef(null);+  const resizeElementRef = useRef(null);+  const [state, dispatch] = createResizeReducer(+    wrapperElementRef,+    resizeElementRef,+  );++  const {isResizing} = state;++  const onResizeStart = () =>+    dispatch({type: 'ACTION_SET_IS_RESIZING', payload: true});+  const onResizeEnd = () =>+    dispatch({type: 'ACTION_SET_IS_RESIZING', payload: false});++  const onResize = event => {+    const resizeElement = resizeElementRef.current;+    const wrapperElement = wrapperElementRef.current;++    if (!isResizing || wrapperElement === null || resizeElement === null) {+      return;+    }++    event.preventDefault();++    const orientation = getOrientation(wrapperElementRef);++    const {height, width, left, top} = wrapperElement.getBoundingClientRect();++    const currentMousePosition =+      orientation === 'horizontal' ? event.clientX - left : event.clientY - top;++    const boundaryMin = MINIMUM_SIZE;+    const boundaryMax =+      orientation === 'horizontal'+        ? width - MINIMUM_SIZE+        : height - MINIMUM_SIZE;++    const isMousePositionInBounds =+      currentMousePosition > boundaryMin && currentMousePosition < boundaryMax;++    if (isMousePositionInBounds) {+      const resizedElementDimension =+        orientation === 'horizontal' ? width : height;+      const actionType =+        orientation === 'horizontal'+          ? 'ACTION_SET_HORIZONTAL_PERCENTAGE'+          : 'ACTION_SET_VERTICAL_PERCENTAGE';+      const percentage = (currentMousePosition / resizedElementDimension) * 100;++      resizeElement.style.setProperty(+        `--${orientation}-resize-percentage`,+        `${percentage}%`,+      );++      dispatch({+        type: actionType,+        payload: currentMousePosition / resizedElementDimension,+      });+    }+  };++  return (+    <div+      ref={wrapperElementRef}+      className={styles.ComponentsWrapper}+      {...(isResizing && {+        onMouseMove: onResize,+        onMouseLeave: onResizeEnd,+        onMouseUp: onResizeEnd,+      })}>+      {children({resizeElementRef, onResizeStart})}+    </div>+  );+}++type Orientation = 'horizontal' | 'vertical';++type ResizeActionType =+  | 'ACTION_SET_DID_MOUNT'+  | 'ACTION_SET_IS_RESIZING'+  | 'ACTION_SET_HORIZONTAL_PERCENTAGE'+  | 'ACTION_SET_VERTICAL_PERCENTAGE';++type ResizeAction = {|+  type: ResizeActionType,+  payload: any,+|};++type ResizeState = {|+  horizontalPercentage: number,+  isResizing: boolean,+  verticalPercentage: number,+|};++function initResizeState(): ResizeState {+  let horizontalPercentage = 0.65;+  let verticalPercentage = 0.5;++  try {+    let data = localStorageGetItem(LOCAL_STORAGE_KEY);+    if (data != null) {+      data = JSON.parse(data);+      horizontalPercentage = data.horizontalPercentage;+      verticalPercentage = data.verticalPercentage;+    }+  } catch (error) {}++  return {+    horizontalPercentage,+    isResizing: false,+    verticalPercentage,+  };+}++function resizeReducer(state: ResizeState, action: ResizeAction): ResizeState {+  switch (action.type) {+    case 'ACTION_SET_IS_RESIZING':+      return {+        ...state,+        isResizing: action.payload,+      };+    case 'ACTION_SET_HORIZONTAL_PERCENTAGE':+      return {+        ...state,+        horizontalPercentage: action.payload,+      };+    case 'ACTION_SET_VERTICAL_PERCENTAGE':+      return {+        ...state,+        verticalPercentage: action.payload,+      };+    default:+      return state;+  }+}++function getOrientation(+  wrapperElementRef: ElementRef<HTMLElement>,+): null | Orientation {+  const wrapperElement = wrapperElementRef.current;+  if (wrapperElement != null) {+    const {width} = wrapperElement.getBoundingClientRect();+    return width > VERTICAL_MODE_MAX_WIDTH ? 'horizontal' : 'vertical';+  }+  return null;+}++function createResizeReducer(wrapperElementRef, resizeElementRef) {+  const [state, dispatch] = useReducer(resizeReducer, null, initResizeState);

🤦‍♂

hristo-kanchev

comment created time in 2 days

push eventhristo-kanchev/react

Hristo Kanchev

commit sha c243f4036980f087fc032f9a3865ee85fa4bdccf

feat: DevTools - Added flow types for reducer and refs.

view details

Hristo Kanchev

commit sha 7f4dbd92924e2040c3dfd343081a6068b3887982

feat: DevTools - Fixed orientation change on initial load.

view details

push time in 2 days

issue commentfacebook/react

Bug: Image not loading in the production build

Can you move this issue to the create-react-app rep? -> https://github.com/facebook/create-react-app Thanks!

naveenneog

comment created time in 3 days

pull request commentfacebook/react

[DevTools] Added resize support for Components panel.

Hiya @bvaughn!

I managed to find some time yesterday evening to address the issue that you highlighted.

Can you please check again? (I've incorporated the suggested changes that you highlighted as well 😍 )

hristo-kanchev

comment created time in 3 days

Pull request review commentfacebook/react

[DevTools] Added resize support for Components panel.

+import type {ElementRef} from 'react';++import * as React from 'react';+import {useEffect, useLayoutEffect, useReducer, useRef} from 'react';+import {+  localStorageGetItem,+  localStorageSetItem,+} from 'react-devtools-shared/src/storage';+import styles from './ComponentsResizer.css';++const LOCAL_STORAGE_KEY = 'React::DevTools::createResizeReducer';+const VERTICAL_MODE_MAX_WIDTH = 600;+const MINIMUM_SIZE = 50;++type Props = {|+  children: ({+    resizeElementRef: ElementRef<HTMLElement>,+    onResizeStart: () => void,+  }) => React$Node,+|};++export default function ComponentsResizer({children}: Props) {+  const wrapperElementRef = useRef(null);+  const resizeElementRef = useRef(null);+  const [state, dispatch] = createResizeReducer(+    wrapperElementRef,+    resizeElementRef,+  );++  const {isResizing} = state;++  const onResizeStart = () =>+    dispatch({type: 'ACTION_SET_IS_RESIZING', payload: true});+  const onResizeEnd = () =>+    dispatch({type: 'ACTION_SET_IS_RESIZING', payload: false});++  const onResize = event => {+    const resizeElement = resizeElementRef.current;+    const wrapperElement = wrapperElementRef.current;++    if (!isResizing || wrapperElement === null || resizeElement === null) {+      return;+    }++    event.preventDefault();++    const orientation = getOrientation(wrapperElementRef);++    const {height, width, left, top} = wrapperElement.getBoundingClientRect();++    const currentMousePosition =+      orientation === 'horizontal' ? event.clientX - left : event.clientY - top;++    const boundaryMin = MINIMUM_SIZE;+    const boundaryMax =+      orientation === 'horizontal'+        ? width - MINIMUM_SIZE+        : height - MINIMUM_SIZE;++    const isMousePositionInBounds =+      currentMousePosition > boundaryMin && currentMousePosition < boundaryMax;++    if (isMousePositionInBounds) {+      const resizedElementDimension =+        orientation === 'horizontal' ? width : height;+      const actionType =+        orientation === 'horizontal'+          ? 'ACTION_SET_HORIZONTAL_PERCENTAGE'+          : 'ACTION_SET_VERTICAL_PERCENTAGE';+      const percentage = (currentMousePosition / resizedElementDimension) * 100;++      resizeElement.style.setProperty(+        `--${orientation}-resize-percentage`,+        `${percentage}%`,+      );++      dispatch({+        type: actionType,+        payload: currentMousePosition / resizedElementDimension,+      });+    }+  };++  return (+    <div+      ref={wrapperElementRef}+      className={styles.ComponentsWrapper}+      {...(isResizing && {+        onMouseMove: onResize,+        onMouseLeave: onResizeEnd,+        onMouseUp: onResizeEnd,+      })}>+      {children({resizeElementRef, onResizeStart})}+    </div>+  );+}++type Orientation = 'horizontal' | 'vertical';++type ResizeActionType =+  | 'ACTION_SET_DID_MOUNT'+  | 'ACTION_SET_IS_RESIZING'+  | 'ACTION_SET_HORIZONTAL_PERCENTAGE'+  | 'ACTION_SET_VERTICAL_PERCENTAGE';++type ResizeAction = {|+  type: ResizeActionType,+  payload: any,+|};++type ResizeState = {|+  horizontalPercentage: number,+  isResizing: boolean,+  verticalPercentage: number,+|};++function initResizeState(): ResizeState {+  let horizontalPercentage = 0.65;+  let verticalPercentage = 0.5;++  try {+    let data = localStorageGetItem(LOCAL_STORAGE_KEY);+    if (data != null) {+      data = JSON.parse(data);+      horizontalPercentage = data.horizontalPercentage;+      verticalPercentage = data.verticalPercentage;+    }+  } catch (error) {}++  return {+    horizontalPercentage,+    isResizing: false,+    verticalPercentage,+  };+}++function resizeReducer(state: ResizeState, action: ResizeAction): ResizeState {+  switch (action.type) {+    case 'ACTION_SET_IS_RESIZING':+      return {+        ...state,+        isResizing: action.payload,+      };+    case 'ACTION_SET_HORIZONTAL_PERCENTAGE':+      return {+        ...state,+        horizontalPercentage: action.payload,+      };+    case 'ACTION_SET_VERTICAL_PERCENTAGE':+      return {+        ...state,+        verticalPercentage: action.payload,+      };+    default:+      return state;+  }+}++function getOrientation(+  wrapperElementRef: ElementRef<HTMLElement>,+): null | Orientation {+  const wrapperElement = wrapperElementRef.current;+  if (wrapperElement != null) {+    const {width} = wrapperElement.getBoundingClientRect();+    return width > VERTICAL_MODE_MAX_WIDTH ? 'horizontal' : 'vertical';+  }+  return null;+}++function createResizeReducer(wrapperElementRef, resizeElementRef) {+  const [state, dispatch] = useReducer(resizeReducer, null, initResizeState);+  const {horizontalPercentage, verticalPercentage} = state;+  const orientationRef = useRef(null);++  useLayoutEffect(() => {+    const orientation = getOrientation(wrapperElementRef);++    if (orientation !== orientationRef.current) {+      orientationRef.current = orientation;++      const percentage =+        orientation === 'horizontal'+          ? horizontalPercentage+          : verticalPercentage;+      const resizeElement = resizeElementRef.current;++      resizeElement.style.setProperty(+        `--${orientation}-resize-percentage`,+        `${percentage * 100}%`,+      );

Check - https://github.com/facebook/react/pull/18046/files#r383760089

hristo-kanchev

comment created time in 3 days

Pull request review commentfacebook/react

[DevTools] Added resize support for Components panel.

+import type {ElementRef} from 'react';++import * as React from 'react';+import {useEffect, useLayoutEffect, useReducer, useRef} from 'react';+import {+  localStorageGetItem,+  localStorageSetItem,+} from 'react-devtools-shared/src/storage';+import styles from './ComponentsResizer.css';++const LOCAL_STORAGE_KEY = 'React::DevTools::createResizeReducer';+const VERTICAL_MODE_MAX_WIDTH = 600;+const MINIMUM_SIZE = 50;++type Props = {|+  children: ({+    resizeElementRef: ElementRef<HTMLElement>,+    onResizeStart: () => void,+  }) => React$Node,+|};++export default function ComponentsResizer({children}: Props) {+  const wrapperElementRef = useRef(null);+  const resizeElementRef = useRef(null);+  const [state, dispatch] = createResizeReducer(+    wrapperElementRef,+    resizeElementRef,+  );++  const {isResizing} = state;++  const onResizeStart = () =>+    dispatch({type: 'ACTION_SET_IS_RESIZING', payload: true});+  const onResizeEnd = () =>+    dispatch({type: 'ACTION_SET_IS_RESIZING', payload: false});++  const onResize = event => {+    const resizeElement = resizeElementRef.current;+    const wrapperElement = wrapperElementRef.current;++    if (!isResizing || wrapperElement === null || resizeElement === null) {+      return;+    }++    event.preventDefault();++    const orientation = getOrientation(wrapperElementRef);++    const {height, width, left, top} = wrapperElement.getBoundingClientRect();++    const currentMousePosition =+      orientation === 'horizontal' ? event.clientX - left : event.clientY - top;++    const boundaryMin = MINIMUM_SIZE;+    const boundaryMax =+      orientation === 'horizontal'+        ? width - MINIMUM_SIZE+        : height - MINIMUM_SIZE;++    const isMousePositionInBounds =+      currentMousePosition > boundaryMin && currentMousePosition < boundaryMax;++    if (isMousePositionInBounds) {+      const resizedElementDimension =+        orientation === 'horizontal' ? width : height;+      const actionType =+        orientation === 'horizontal'+          ? 'ACTION_SET_HORIZONTAL_PERCENTAGE'+          : 'ACTION_SET_VERTICAL_PERCENTAGE';+      const percentage = (currentMousePosition / resizedElementDimension) * 100;++      resizeElement.style.setProperty(+        `--${orientation}-resize-percentage`,+        `${percentage}%`,+      );++      dispatch({+        type: actionType,+        payload: currentMousePosition / resizedElementDimension,+      });+    }+  };++  return (+    <div+      ref={wrapperElementRef}+      className={styles.ComponentsWrapper}+      {...(isResizing && {+        onMouseMove: onResize,+        onMouseLeave: onResizeEnd,+        onMouseUp: onResizeEnd,+      })}>+      {children({resizeElementRef, onResizeStart})}+    </div>+  );+}++type Orientation = 'horizontal' | 'vertical';++type ResizeActionType =+  | 'ACTION_SET_DID_MOUNT'+  | 'ACTION_SET_IS_RESIZING'+  | 'ACTION_SET_HORIZONTAL_PERCENTAGE'+  | 'ACTION_SET_VERTICAL_PERCENTAGE';++type ResizeAction = {|+  type: ResizeActionType,+  payload: any,+|};++type ResizeState = {|+  horizontalPercentage: number,+  isResizing: boolean,+  verticalPercentage: number,+|};++function initResizeState(): ResizeState {+  let horizontalPercentage = 0.65;+  let verticalPercentage = 0.5;++  try {+    let data = localStorageGetItem(LOCAL_STORAGE_KEY);+    if (data != null) {+      data = JSON.parse(data);+      horizontalPercentage = data.horizontalPercentage;+      verticalPercentage = data.verticalPercentage;+    }+  } catch (error) {}++  return {+    horizontalPercentage,+    isResizing: false,+    verticalPercentage,+  };+}++function resizeReducer(state: ResizeState, action: ResizeAction): ResizeState {+  switch (action.type) {+    case 'ACTION_SET_IS_RESIZING':+      return {+        ...state,+        isResizing: action.payload,+      };+    case 'ACTION_SET_HORIZONTAL_PERCENTAGE':+      return {+        ...state,+        horizontalPercentage: action.payload,+      };+    case 'ACTION_SET_VERTICAL_PERCENTAGE':+      return {+        ...state,+        verticalPercentage: action.payload,+      };+    default:+      return state;+  }+}++function getOrientation(+  wrapperElementRef: ElementRef<HTMLElement>,+): null | Orientation {+  const wrapperElement = wrapperElementRef.current;+  if (wrapperElement != null) {+    const {width} = wrapperElement.getBoundingClientRect();+    return width > VERTICAL_MODE_MAX_WIDTH ? 'horizontal' : 'vertical';+  }+  return null;+}++function createResizeReducer(wrapperElementRef, resizeElementRef) {+  const [state, dispatch] = useReducer(resizeReducer, null, initResizeState);

Using the flow types over here made my app crash. Any idea as to why @bvaughn ?

hristo-kanchev

comment created time in 3 days

Pull request review commentfacebook/react

[DevTools] Added resize support for Components panel.

+import type {ElementRef} from 'react';++import * as React from 'react';+import {useEffect, useLayoutEffect, useReducer, useRef} from 'react';+import {+  localStorageGetItem,+  localStorageSetItem,+} from 'react-devtools-shared/src/storage';+import styles from './ComponentsResizer.css';++const LOCAL_STORAGE_KEY = 'React::DevTools::createResizeReducer';+const VERTICAL_MODE_MAX_WIDTH = 600;+const MINIMUM_SIZE = 50;++type Props = {|+  children: ({+    resizeElementRef: ElementRef<HTMLElement>,+    onResizeStart: () => void,+  }) => React$Node,+|};++export default function ComponentsResizer({children}: Props) {+  const wrapperElementRef = useRef(null);+  const resizeElementRef = useRef(null);

Using the flow types over here made my app crash. Any idea as to why @bvaughn ?

hristo-kanchev

comment created time in 3 days

Pull request review commentfacebook/react

[DevTools] Added resize support for Components panel.

+import type {ElementRef} from 'react';++import * as React from 'react';+import {useEffect, useLayoutEffect, useReducer, useRef} from 'react';+import {+  localStorageGetItem,+  localStorageSetItem,+} from 'react-devtools-shared/src/storage';+import styles from './ComponentsResizer.css';++const LOCAL_STORAGE_KEY = 'React::DevTools::createResizeReducer';+const VERTICAL_MODE_MAX_WIDTH = 600;+const MINIMUM_SIZE = 50;++type Props = {|+  children: ({+    resizeElementRef: ElementRef<HTMLElement>,+    onResizeStart: () => void,+  }) => React$Node,+|};++export default function ComponentsResizer({children}: Props) {+  const wrapperElementRef = useRef(null);+  const resizeElementRef = useRef(null);+  const [state, dispatch] = createResizeReducer(+    wrapperElementRef,+    resizeElementRef,+  );++  const {isResizing} = state;++  const onResizeStart = () =>+    dispatch({type: 'ACTION_SET_IS_RESIZING', payload: true});+  const onResizeEnd = () =>+    dispatch({type: 'ACTION_SET_IS_RESIZING', payload: false});++  const onResize = event => {+    const resizeElement = resizeElementRef.current;+    const wrapperElement = wrapperElementRef.current;++    if (!isResizing || wrapperElement === null || resizeElement === null) {+      return;+    }++    event.preventDefault();++    const orientation = getOrientation(wrapperElementRef);++    const {height, width, left, top} = wrapperElement.getBoundingClientRect();++    const currentMousePosition =+      orientation === 'horizontal' ? event.clientX - left : event.clientY - top;++    const boundaryMin = MINIMUM_SIZE;+    const boundaryMax =+      orientation === 'horizontal'+        ? width - MINIMUM_SIZE+        : height - MINIMUM_SIZE;++    const isMousePositionInBounds =+      currentMousePosition > boundaryMin && currentMousePosition < boundaryMax;++    if (isMousePositionInBounds) {+      const resizedElementDimension =+        orientation === 'horizontal' ? width : height;+      const actionType =+        orientation === 'horizontal'+          ? 'ACTION_SET_HORIZONTAL_PERCENTAGE'+          : 'ACTION_SET_VERTICAL_PERCENTAGE';+      const percentage = (currentMousePosition / resizedElementDimension) * 100;++      resizeElement.style.setProperty(+        `--${orientation}-resize-percentage`,+        `${percentage}%`,+      );

We are now setting a css variable based on the orientation.

Possible values: --horizontal-resize-percentage --vertical-resize-percentage

We use these two variables in CSS to determine the correct resize percentage based on the orientation using the media query that we have set up there.

I initially thought of using a ResizeObserver but it's far too complex, I think.

Thoughts, @bvaughn ?

hristo-kanchev

comment created time in 3 days

Pull request review commentfacebook/react

[DevTools] Added resize support for Components panel.

+import type {ElementRef} from 'react';++import * as React from 'react';+import {useEffect, useLayoutEffect, useReducer, useRef} from 'react';+import {+  localStorageGetItem,+  localStorageSetItem,+} from 'react-devtools-shared/src/storage';+import styles from './ComponentsResizer.css';++const LOCAL_STORAGE_KEY = 'React::DevTools::createResizeReducer';+const VERTICAL_MODE_MAX_WIDTH = 600;+const MINIMUM_SIZE = 50;++type Props = {|+  children: ({+    resizeElementRef: ElementRef<HTMLElement>,+    onResizeStart: () => void,+  }) => React$Node,+|};++export default function ComponentsResizer({children}: Props) {+  const wrapperElementRef = useRef(null);+  const resizeElementRef = useRef(null);+  const [state, dispatch] = createResizeReducer(+    wrapperElementRef,+    resizeElementRef,+  );

Using the flow types over here made my app crash. Any idea as to why @bvaughn ?

hristo-kanchev

comment created time in 3 days

push eventhristo-kanchev/react

adasq

commit sha 501a78881e356bae2bc66be3d25966e87f5aa757

runAllPassiveEffectDestroysBeforeCreates's feature flag description typo fixed (#18115)

view details

Sebastian Markbåge

commit sha ccab49473897aacae43bb4d55c1061065892403c

Move type DOMContainer to HostConfig (#18112) Exports from ReactDOM represents React's public API. This include types exported by React. At some point we'll start building Flow types from these files. The duplicate name between DOMContainer and Container seems confusing too since it was used in the same files even though they're the same.

view details

Hristo Kanchev

commit sha 6f5d8e5c1bd9133ecf0cfaaaf535dacfb8d870f5

feat: DevTools - Added Resize Support.

view details

Hristo Kanchev

commit sha 65bbec58a3991d63424d3c319fa8ac21641923ab

feat: Prettier.

view details

Hristo Kanchev

commit sha 16dcd67d700af4d03f0b28130db98e54fd0074db

feat: DevTools - Added debug comments.

view details

Hristo Kanchev

commit sha 1c6add24a6f1a3901372ab099c6544402efe01d6

feat: DevTools - Removed Use Memo.

view details

Hristo Kanchev

commit sha 23fba3a77d32ab3abbd4303be2078a70b4c367ad

feat: DevTools - Added types.

view details

Hristo Kanchev

commit sha 02367548294bfbf6dc04efcab7aa1180ed4b833d

feat: DevTools - Extracted values to constants.

view details

Hristo Kanchev

commit sha 1f2e54a2ed721e0e2a0856cd26a51ff614bbf6a6

feat: DevTools - Removed useCallback.

view details

Hristo Kanchev

commit sha 9cee4ef82ce94d410a62cc3b3820a062c394e82b

feat: DevTools - Finished refactoring.

view details

Hristo Kanchev

commit sha fc021847d72086752238e57567514d57b83cf3cc

feat: DevTools - Merging fixup.

view details

Hristo Kanchev

commit sha 0c2ad23eaec8eab311088215626a737384eba8f7

feat: DevTools - Prettier fix.

view details

Hristo Kanchev

commit sha 3ba1909dbe8c78936f6001c7ad0df98ed670261c

feat: DevTools - Extracted code from Components fil.

view details

Hristo Kanchev

commit sha 554f7e858589ab1af076ff446961776265a86723

feat: DevTools - Fixed orientation change issue.

view details

push time in 3 days

pull request commentfacebook/react

[DevTools] Added resize support for Components panel.

...but I've run out of time- so I wanted to share my progress with you for your thoughts! 🙇

The one thing that isn't working right as of yet is that orientation changes (when you resize to go from horizontal to vertical or vice versa) don't trigger any effects, since they don't trigger any state change. Have not thought enough about how to handle this. Thoughts?

Oh wow, thanks for the improvements! I'll try and put some time aside during the work week to figure out the orientation changes issue. I should have something in the PR by the end of the week.

I'll ping you again when it's ready for another round of reviews.

Thanks Brian!

hristo-kanchev

comment created time in 3 days

pull request commentfacebook/react

[DevTools] Added resize support for Components panel.

I've added the changes, @bvaughn. If you want you can do a quick test run in this PR and tell me how it feels and if there are further changes needed? Cheers!

hristo-kanchev

comment created time in 5 days

Pull request review commentfacebook/react

[DevTools] Added resize support for Components panel.

 import portaledContent from '../portaledContent'; import {ModalDialog} from '../ModalDialog'; import SettingsModal from 'react-devtools-shared/src/devtools/views/Settings/SettingsModal'; import {SettingsModalContextController} from 'react-devtools-shared/src/devtools/views/Settings/SettingsModalContext';+import {useLocalStorage} from '../hooks';  import styles from './Components.css';  function Components(_: {||}) {-  // TODO Flex wrappers below should be user resizable.   return (     <SettingsModalContextController>       <OwnersListContextController>         <InspectedElementContextController>-          <div className={styles.Components}>-            <div className={styles.TreeWrapper}>-              <Tree />-            </div>-            <div className={styles.SelectedElementWrapper}>-              <NativeStyleContextController>-                <Suspense fallback={<Loading />}>-                  <SelectedElement />-                </Suspense>-              </NativeStyleContextController>-            </div>-            <ModalDialog />-            <SettingsModal />-          </div>+          <ComponentResizer>+            {({resizeElementRef, onResizeStart, resizeElementStyles}) => (+              <Fragment>+                <div+                  ref={resizeElementRef}+                  className={styles.TreeWrapper}+                  style={{+                    ...resizeElementStyles,+                  }}>+                  <Tree />+                </div>+                <div className={styles.ResizeBarWrapper}>+                  <div+                    onMouseDown={onResizeStart}+                    className={styles.ResizeBar}+                  />+                </div>+                <div className={styles.SelectedElementWrapper}>+                  <NativeStyleContextController>+                    <Suspense fallback={<Loading />}>+                      <SelectedElement />+                    </Suspense>+                  </NativeStyleContextController>+                </div>+                <ModalDialog />+                <SettingsModal />+              </Fragment>+            )}+          </ComponentResizer>         </InspectedElementContextController>       </OwnersListContextController>     </SettingsModalContextController>   ); } +type HorizontalResizeDirection = 'HORIZONTAL';+type VerticalResizeDirection = 'VERTICAL';++const RESIZE_DIRECTIONS: {|+  HORIZONTAL: HorizontalResizeDirection,+  VERTICAL: VerticalResizeDirection,+|} = {+  HORIZONTAL: 'HORIZONTAL',+  VERTICAL: 'VERTICAL',+};++const LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_HORIZONTAL_KEY = `React::DevTools::resizedElementPercentage::${RESIZE_DIRECTIONS.HORIZONTAL}`;+const LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_VERTICAL_KEY = `React::DevTools::resizedElementPercentage::${RESIZE_DIRECTIONS.VERTICAL}`;++function ComponentResizer({children}): {|children: Function|} {+  const [isResizing, setIsResizing] = useState<boolean>(false);+  const [+    horizontalPercentage,+    setHorizontalPercentage,+  ] = useLocalStorage<number>(+    LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_HORIZONTAL_KEY,+    65,+  );+  const [verticalPercentage, setVerticalPercentage] = useLocalStorage<number>(+    LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_VERTICAL_KEY,+    50,+  );+  const updateLocalStorageTimeoutId = useRef<number>(null);+  const componentsWrapperRef = useRef<HTMLDivElement>(null);+  const resizeElementRef = useRef<HTMLElement>(null);+  const [resizeElementStyles, setResizeElementStyles] = useState<Object>({});+  const getResizeDirection: Function = useCallback(() => {+    if (componentsWrapperRef.current === null) {+      return RESIZE_DIRECTIONS.HORIZONTAL;+    }+    const VERTICAL_MODE_MAX_WIDTH: number = 600;+    const {width} = componentsWrapperRef.current.getBoundingClientRect();++    return width > VERTICAL_MODE_MAX_WIDTH+      ? RESIZE_DIRECTIONS.HORIZONTAL+      : RESIZE_DIRECTIONS.VERTICAL;+  }, [componentsWrapperRef]);++  const onResizeStart = useCallback(() => {+    setIsResizing(true);+  }, [setIsResizing]);++  const onResizeEnd = useCallback(() => {+    setIsResizing(false);+  }, [setIsResizing]);++  const onResize = useCallback(+    e => {+      if (+        !isResizing ||+        componentsWrapperRef.current === null ||+        resizeElementRef.current === null+      ) {+        return;+      }++      e.preventDefault();++      const {+        height,+        width,+        left,+        top,+      } = componentsWrapperRef.current.getBoundingClientRect();+      const resizeDirection = getResizeDirection();+      const currentMousePosition: number =+        resizeDirection === RESIZE_DIRECTIONS.HORIZONTAL+          ? e.clientX - left+          : e.clientY - top;+      const BOUNDARY_PADDING: number = 40;+      const boundary: {|+        min: number,+        max: number,+      |} = {+        min: BOUNDARY_PADDING,+        max:+          resizeDirection === RESIZE_DIRECTIONS.HORIZONTAL+            ? width - BOUNDARY_PADDING+            : height - BOUNDARY_PADDING,+      };+      const isMousePositionInBounds: boolean =+        currentMousePosition > boundary.min &&+        currentMousePosition < boundary.max;++      if (isMousePositionInBounds) {+        const resizedElementDimension: number =+          resizeDirection === RESIZE_DIRECTIONS.HORIZONTAL ? width : height;+        const updatedFlexBasisValue: number =+          (currentMousePosition / resizedElementDimension) * 100;++        resizeElementRef.current.style.flexBasis = `${updatedFlexBasisValue}%`;++        clearTimeout(updateLocalStorageTimeoutId.current);++        updateLocalStorageTimeoutId.current = setTimeout(() => {+          if (resizeDirection === RESIZE_DIRECTIONS.HORIZONTAL) {+            setHorizontalPercentage(updatedFlexBasisValue);+          } else {+            setVerticalPercentage(updatedFlexBasisValue);+          }+        }, 500);+      }+    },+    [componentsWrapperRef, resizeElementRef, isResizing],+  );++  useLayoutEffect(() => {+    if (componentsWrapperRef.current !== null) {+      if (getResizeDirection() === RESIZE_DIRECTIONS.HORIZONTAL) {+        setResizeElementStyles({

Hiya @bvaughn ! I've added the changes. Much much more readable and clean 🥂 Thanks for the suggestion.

hristo-kanchev

comment created time in 5 days

push eventhristo-kanchev/react

Hristo Kanchev

commit sha f948865cd2404f9ae60a8bfda2ca1936284a8c57

feat: DevTools - Prettier fix.

view details

push time in 5 days

push eventhristo-kanchev/react

Brian Vaughn

commit sha 031a5aaffbc06f0ac115f1d814e43e4d63ae15d2

Show component location for selected element in bottom/right of props panel (#17567) * Show component location info for selected element in bottom/right of props panel * Moved RegExp declaration into function basedon PR feedback

view details

Andrew Clark

commit sha 7bf40e1cfdb780788700a41bf30163fdb8d105a3

Initialize update queue object on mount (#17560) * Refactor Update Queues to Fix Rebasing Bug Fixes a bug related to rebasing updates. Once an update has committed, it should never un-commit, even if interrupted by a higher priority update. The fix includes a refactor of how update queues work. This commit is a combination of two PRs: - #17483 by @sebmarkbage refactors the hook update queue - #17510 by @acdlite refactors the class and root update queue Landing one without the other would cause state updates to sometimes be inconsistent across components, so I've combined them into a single commit in case they need to be reverted. Co-authored-by: Sebastian Markbåge <sema@fb.com> Co-authored-by: Andrew Clark <git@andrewclark.io> * Initialize update queue object on mount Instead of lazily initializing update queue objects on the first update, class and host root queues are created on mount. This simplifies the logic for appending new updates and matches what we do for hooks.

view details

Laura buns

commit sha 9ac42dd074c42b66ecc0334b75200b1d2989f892

Remove the condition argument from warning() (#17568) * prep for codemod * prep warnings * rename lint rules * codemod for ifs * shim www functions * Handle more cases in the transform * Thanks De Morgan * Run the codemod * Delete the transform * Fix up confusing conditions manually * Fix up www shims to match expected API * Also check for low-pri warning in the lint rule

view details

Dominic Gannaway

commit sha 2afeebdcc4ed8a78ab5b36792f768078d70e1ffd

[react-interactions] Remove responder root event types + revert commit phase change (#17577)

view details

Brian Vaughn

commit sha 12c000412d05c4a6079b4f57f721a40b8cea374d

Improved inspected element props with inline previews (#17579) * Improved inspected element props with inline previews This mimics the inline preview shown by the brower console and dramatically improves the UX when inspecting deep values. I also updated tests to add more coverage for this new functionality. * Cleaned up the DataView vs typed array check * Added early bailouts to DevTools when generating preview strings for iterables/objects/arrays, to avoid doing unnecessary work

view details

Nicolas Gallagher

commit sha 612a76812fce2354aa37e8cbcc1b39bba3e9a97b

[react-interactions] Mock touchend events should use empty array for 'touches' (#17589) The 'touches' value should be an empty array rather than 'null'

view details

Dan Abramov

commit sha b15bf36750ca4c4a5a09f2de76c5315ded1258d0

Add component stacks to (almost) all warnings (#17586)

view details

Dominic Gannaway

commit sha be603f5a51be33027193d9e5ae35a0e572d8ad5d

[react-events] Remove lastNativeEvent in favor of SystemFlags (#17585)

view details

Sebastian Markbåge

commit sha 8a347ed024159a5307172ea633a4561160f4a6b9

Remove renderPhaseUpdates Map (#17484) * Render phase updates can now be extracted from the pending queue * Use a custom dispatcher for the second render pass * Discard render phase updates if component throws When aborting a render, we also need to throw out render phase updates. Remove the updates from the queues so they do not persist to the next render. We already did a single pass through the whole list of hooks, so we know that any pending updates must have been dispatched during the render phase. The ones that were dispatched before we started rendering were already transferred to the current hook's queue.

view details

Dan Abramov

commit sha b6c423daadaa35da3f34048628df9635505eecb1

Use matching test command for equivalence tests (#17604)

view details

Dan Abramov

commit sha 0cf22a56a18790ef34c71bef14f64695c0498619

Use console directly instead of warning() modules (#17599) * Replace all warning/lowPriWarning with console calls * Replace console.warn/error with a custom wrapper at build time * Fail the build for console.error/warn() where we can't read the stack

view details

Dan Abramov

commit sha 0b5a26a4895261894f04e50d5a700e83b9c0dcf6

Rename toWarnDev -> toErrorDev, toLowPriorityWarnDev -> toWarnDev (#17605) * Rename toWarnDev -> toErrorDev in tests * Rename toWarnDev matcher implementation to toErrorDev * Rename toLowPriorityWarnDev -> toWarnDev in tests and implementation

view details

Dan Abramov

commit sha f42431abe1a31a3798989a6477422c492cf8dac1

Revert "Remove renderPhaseUpdates Map (#17484)" (#17623) This reverts commit 8a347ed024159a5307172ea633a4561160f4a6b9.

view details

Dan Abramov

commit sha 7c21bf72ace77094fd1910cc350a548287ef8350

Fix release script to ignore empty package folders

view details

Dan Abramov

commit sha 36a6e29bb3eead85e3500ba7269cbcd55516a8fb

Fix test_build_devtools CI job to run test-build-devtools (#17631) * Skip abandoned project folders in Jest config This fixes a problem that occurs after renaming a package. * Fix test_build_devtools to run test-build-devtools * Exclude console.error plugin for DevTools packages * Use correct release channel for DevTools tests This should fix the createRoot error. * Fix TZ dependent test * Change DT job dependencies

view details

Dan Abramov

commit sha 0253ee9a2e94d43e220a997eeedfcc6847c4542b

Additional test infra changes for toErrorDev rename (#17632)

view details

Dan Abramov

commit sha c2d1561c60507189b43ae96c6b89580874367e36

[Fast Refresh] Support injecting runtime after renderer executes (#17633)

view details

Dan Abramov

commit sha b66e86d9578b031a23385dfc21b0eca4e0cf4456

react-refresh@0.7.1

view details

Dan Abramov

commit sha 3c54df0914f02fed146faa519a5a899d0e3af32e

Fix missing stacks in WWW warnings (#17638)

view details

Dan Abramov

commit sha 9bb3fbe893619a26f48e8a08fcc04763ef1d4b12

Move DevTools CI job to experimental workflow (#17640)

view details

push time in 5 days

push eventhristo-kanchev/react

Dominic Gannaway

commit sha f48a5e64e8fd903293f5b854beb795dcc6bae86d

Further cleanup of plugin event system (#18056)

view details

Haseeb Furkhan Mohammed

commit sha d5ddc16a3398c33d70489cee87f5176c85f3c9f5

React developer tools extension for Microsoft Edge (#18041) * Port Chrome extension to Microsoft Edge

view details

Brian Vaughn

commit sha 90be006da8e231279151e7b1518bb64c62e26851

Updated Yarn lockfile

view details

Ryota Murakami

commit sha 48c4867d745bbf91ae73892545960c0979c2dbf7

Update issue templates to directly link to relevant sources (#18039) GitHub supports linking to off-site sources for certain types of issue.

view details

Dominic Gannaway

commit sha 1a6d8179b6dd427fdf7ee50d5ac45ae5a40979eb

[react-interactions] Ensure onBeforeBlur fires for hideInstance (#18064)

view details

Andrew Clark

commit sha 56d8a73affad624ee4d48f1685e0a92adce0bd9c

[www] Disable Scheduler `timeout` w/ dynamic flag (#18069) Before attempting to land an expiration times refactor, I want to see if this particular change will impact performance (either positively or negatively). I will test this with a GK.

view details

Brian Vaughn

commit sha 691096c95d1019f57e0da2c9a060c5e094b7c586

Split recent passive effects changes into 2 flags (#18030) * Split recent passive effects changes into 2 flags Separate flags can now be used to opt passive effects into: 1) Deferring destroy functions on unmount to subsequent passive effects flush 2) Running all destroy functions (for all fibers) before create functions This allows us to test the less risky feature (2) separately from the more risky one. * deferPassiveEffectCleanupDuringUnmount is ignored unless runAllPassiveEffectDestroysBeforeCreates is true

view details

Brian Vaughn

commit sha 14afeb1033e25942e63787750388972916f20a39

Added missing feature flag

view details

Andrew Clark

commit sha 4d9f8500651c5d1e19d8ec9a2359d5476a53814b

Re-throw errors thrown by the renderer at the root in the complete phase (#18029) * Re-throw errors thrown by the renderer at the root React treats errors thrown at the root as a fatal because there's no parent component that can capture it. (This is distinct from an "uncaught error" that isn't wrapped in an error boundary, because in that case we can fall back to deleting the whole tree -- not great, but at least the error is contained to a single root, and React is left in a consistent state.) It turns out we didn't have a test case for this path. The only way it can happen is if the renderer's host config throws. We had similar test cases for host components, but none for the host root. This adds a new test case and fixes a bug where React would keep retrying the root because the `workInProgress` pointer was not advanced to the next fiber. (Which in this case is `null`, since it's the root.) We could consider in the future trying to gracefully exit from certain types of root errors without leaving React in an inconsistent state. For example, we should be able to gracefully exit from errors thrown in the begin phase. For now, I'm treating it like an internal invariant and immediately exiting. * Add comment

view details

Dominic Gannaway

commit sha 4912ba31e3dcc8d08f5b16ae38b38d74da85ea21

Add modern event system flag + rename legacy plugin module (#18073)

view details

Sunil Pai

commit sha a8643e905e39f041cda80b498dc06018b27f6554

add no-restricted-globals to eslint config (#18076) Our current lint config assumes a browser environment, which means it won't warn you if you use a variable like `name` without declaring it earlier. This imports the same list as the one used by create-react-app, and enables it against our codebase.

view details

Dominic Gannaway

commit sha 2512c309e34f0207d29c19392d144edab719f347

Remove Flare bundles from build (#18077)

view details

Moji Izadmehr

commit sha 44e5f5e6451cf192af5dee3aa1f3a87119fc231e

Add fiber summary tooltip to devtools profiling (#18048) * Add tooltip component * Separate logic of ProfilerWhatChanged to a component * Add hovered Fiber info tooltip component * Add flame graph chart tooltip * Add commit ranked list tooltip * Fix flow issues * Minor improvement in filter * Fix flickering issue * Resolved issues on useCallbacks and mouse event listeners * Fix lints * Remove unnecessary useCallback

view details

Dan Abramov

commit sha a12dd52a4a5f19d990694810db86cc30e98308ae

Don't build some packages for WWW (#18078)

view details

Dominic Gannaway

commit sha 1000f6135efba4f8d8ebffedeb7b472f532a8475

Add container to event listener signature (#18075)

view details

Dominic Gannaway

commit sha b6c94d636cb33a265671b864b97870da38d97207

Add guard around FocusWithin responder root events (#18080)

view details

Brian Vaughn

commit sha 7e770dae93e1a934b905d8678c7ce368ed86ef0b

Profiler tooltip tweaks (#18082) * Moved Profiler views into Profiler folder * Tweaked Profiler tooltip CSS styles * Tweaked Tooltip positioning code

view details

Eli White

commit sha 085d02133e9e3b24ae548d89e4003899bf85022c

[Native] Migrate focus/blur to call TextInputState with the host component (#18068)

view details

Andrew Clark

commit sha ea6ed3dbbd32515e2d4d9783c358beceeadd4b1d

Warn for update on different component in render (#17099) This warning already exists for class components, but not for functions. It does not apply to render phase updates to the same component, which have special semantics that we do support.

view details

Dominic Gannaway

commit sha 3f85d53ca6f2af8a711daae6322e6bdda862f660

Further pre-requisite changes to plugin event system (#18083)

view details

push time in 5 days

Pull request review commentfacebook/react

[DevTools] Added resize support for Components panel.

 import portaledContent from '../portaledContent'; import {ModalDialog} from '../ModalDialog'; import SettingsModal from 'react-devtools-shared/src/devtools/views/Settings/SettingsModal'; import {SettingsModalContextController} from 'react-devtools-shared/src/devtools/views/Settings/SettingsModalContext';+import {useLocalStorage} from '../hooks';  import styles from './Components.css';  function Components(_: {||}) {-  // TODO Flex wrappers below should be user resizable.   return (     <SettingsModalContextController>       <OwnersListContextController>         <InspectedElementContextController>-          <div className={styles.Components}>-            <div className={styles.TreeWrapper}>-              <Tree />-            </div>-            <div className={styles.SelectedElementWrapper}>-              <NativeStyleContextController>-                <Suspense fallback={<Loading />}>-                  <SelectedElement />-                </Suspense>-              </NativeStyleContextController>-            </div>-            <ModalDialog />-            <SettingsModal />-          </div>+          <ComponentResizer>+            {({resizeElementRef, onResizeStart, resizeElementStyles}) => (+              <Fragment>+                <div+                  ref={resizeElementRef}+                  className={styles.TreeWrapper}+                  style={{+                    ...resizeElementStyles,+                  }}>+                  <Tree />+                </div>+                <div className={styles.ResizeBarWrapper}>+                  <div+                    onMouseDown={onResizeStart}+                    className={styles.ResizeBar}+                  />+                </div>+                <div className={styles.SelectedElementWrapper}>+                  <NativeStyleContextController>+                    <Suspense fallback={<Loading />}>+                      <SelectedElement />+                    </Suspense>+                  </NativeStyleContextController>+                </div>+                <ModalDialog />+                <SettingsModal />+              </Fragment>+            )}+          </ComponentResizer>         </InspectedElementContextController>       </OwnersListContextController>     </SettingsModalContextController>   ); } +type HorizontalResizeDirection = 'HORIZONTAL';+type VerticalResizeDirection = 'VERTICAL';++const RESIZE_DIRECTIONS: {|+  HORIZONTAL: HorizontalResizeDirection,+  VERTICAL: VerticalResizeDirection,+|} = {+  HORIZONTAL: 'HORIZONTAL',+  VERTICAL: 'VERTICAL',+};++const LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_HORIZONTAL_KEY = `React::DevTools::resizedElementPercentage::${RESIZE_DIRECTIONS.HORIZONTAL}`;+const LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_VERTICAL_KEY = `React::DevTools::resizedElementPercentage::${RESIZE_DIRECTIONS.VERTICAL}`;++function ComponentResizer({children}): {|children: Function|} {+  const [isResizing, setIsResizing] = useState<boolean>(false);+  const [+    horizontalPercentage,+    setHorizontalPercentage,+  ] = useLocalStorage<number>(+    LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_HORIZONTAL_KEY,+    65,+  );+  const [verticalPercentage, setVerticalPercentage] = useLocalStorage<number>(+    LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_VERTICAL_KEY,+    50,+  );+  const updateLocalStorageTimeoutId = useRef<number>(null);+  const componentsWrapperRef = useRef<HTMLDivElement>(null);+  const resizeElementRef = useRef<HTMLElement>(null);+  const [resizeElementStyles, setResizeElementStyles] = useState<Object>({});+  const getResizeDirection: Function = useCallback(() => {+    if (componentsWrapperRef.current === null) {+      return RESIZE_DIRECTIONS.HORIZONTAL;+    }+    const VERTICAL_MODE_MAX_WIDTH: number = 600;+    const {width} = componentsWrapperRef.current.getBoundingClientRect();++    return width > VERTICAL_MODE_MAX_WIDTH+      ? RESIZE_DIRECTIONS.HORIZONTAL+      : RESIZE_DIRECTIONS.VERTICAL;+  }, [componentsWrapperRef]);++  const onResizeStart = useCallback(() => {+    setIsResizing(true);+  }, [setIsResizing]);++  const onResizeEnd = useCallback(() => {+    setIsResizing(false);+  }, [setIsResizing]);++  const onResize = useCallback(+    e => {+      if (+        !isResizing ||+        componentsWrapperRef.current === null ||+        resizeElementRef.current === null+      ) {+        return;+      }++      e.preventDefault();++      const {+        height,+        width,+        left,+        top,+      } = componentsWrapperRef.current.getBoundingClientRect();+      const resizeDirection = getResizeDirection();+      const currentMousePosition: number =+        resizeDirection === RESIZE_DIRECTIONS.HORIZONTAL+          ? e.clientX - left+          : e.clientY - top;+      const BOUNDARY_PADDING: number = 40;+      const boundary: {|+        min: number,+        max: number,+      |} = {+        min: BOUNDARY_PADDING,+        max:+          resizeDirection === RESIZE_DIRECTIONS.HORIZONTAL+            ? width - BOUNDARY_PADDING+            : height - BOUNDARY_PADDING,+      };+      const isMousePositionInBounds: boolean =+        currentMousePosition > boundary.min &&+        currentMousePosition < boundary.max;++      if (isMousePositionInBounds) {+        const resizedElementDimension: number =+          resizeDirection === RESIZE_DIRECTIONS.HORIZONTAL ? width : height;+        const updatedFlexBasisValue: number =+          (currentMousePosition / resizedElementDimension) * 100;++        resizeElementRef.current.style.flexBasis = `${updatedFlexBasisValue}%`;++        clearTimeout(updateLocalStorageTimeoutId.current);++        updateLocalStorageTimeoutId.current = setTimeout(() => {+          if (resizeDirection === RESIZE_DIRECTIONS.HORIZONTAL) {+            setHorizontalPercentage(updatedFlexBasisValue);+          } else {+            setVerticalPercentage(updatedFlexBasisValue);+          }+        }, 500);+      }+    },+    [componentsWrapperRef, resizeElementRef, isResizing],+  );++  useLayoutEffect(() => {+    if (componentsWrapperRef.current !== null) {+      if (getResizeDirection() === RESIZE_DIRECTIONS.HORIZONTAL) {+        setResizeElementStyles({

Hey Brian! Thanks for the review!

I'll do my best to make the necessary changes this weekend.

Having everything in a centralized state would be ideal, I agree.

hristo-kanchev

comment created time in 9 days

push eventhristo-kanchev/react

Hristo Kanchev

commit sha d18cf7fafd1e12edccd679c695a26a642fcd9cdc

feat: DevTools - Removed useCallback.

view details

push time in 9 days

push eventhristo-kanchev/react

Will Douglas

commit sha 93a229bab59f94e214256582c55d3b6c1fc2b958

Update eslint rule exhaustive deps to use new suggestions feature (#17385) This closes #16313

view details

Dan Abramov

commit sha 56a8c353219ac93ab358eb28009de881ae48251e

eslint-plugin-react-hooks@2.4.0

view details

Dan Abramov

commit sha d533229fba8f7e7e576436bf52bbcae56c862906

Fix Prettier

view details

Hristo Kanchev

commit sha a11dc8bd75b3f26dab0b0a6cfd637ca5c948a38b

feat: DevTools - Added Resize Support.

view details

Hristo Kanchev

commit sha 6f158a981abad2d3546efb3f257b1f2bb3d52200

feat: Prettier.

view details

Hristo Kanchev

commit sha c1ae446f361e5f9600795a9b1f6eeeda946555c1

feat: DevTools - Added debug comments.

view details

Hristo Kanchev

commit sha 15bb5b0b8e94aef086e6582eb68337a14713eb47

feat: DevTools - Removed Use Memo.

view details

Hristo Kanchev

commit sha e0af09daca80d6244121a057254f7e4d56d21043

feat: DevTools - Added types.

view details

Hristo Kanchev

commit sha dc30845fd32d60f44e90b2b28033db924933c385

feat: DevTools - Extracted values to constants.

view details

push time in 10 days

pull request commentfacebook/react

[DevTools] Added resize support for Components panel.

Not sure why ci/codesandbox step is failing 😕

hristo-kanchev

comment created time in 10 days

Pull request review commentfacebook/react

[DevTools] Added resize support for Components panel.

 import portaledContent from '../portaledContent'; import {ModalDialog} from '../ModalDialog'; import SettingsModal from 'react-devtools-shared/src/devtools/views/Settings/SettingsModal'; import {SettingsModalContextController} from 'react-devtools-shared/src/devtools/views/Settings/SettingsModalContext';+import {useLocalStorage} from '../hooks';  import styles from './Components.css';  function Components(_: {||}) {-  // TODO Flex wrappers below should be user resizable.   return (     <SettingsModalContextController>       <OwnersListContextController>         <InspectedElementContextController>-          <div className={styles.Components}>-            <div className={styles.TreeWrapper}>-              <Tree />-            </div>-            <div className={styles.SelectedElementWrapper}>-              <NativeStyleContextController>-                <Suspense fallback={<Loading />}>-                  <SelectedElement />-                </Suspense>-              </NativeStyleContextController>-            </div>-            <ModalDialog />-            <SettingsModal />-          </div>+          <ComponentResizer>+            {({resizeElementRef, onResizeStart, resizeElementStyles}) => (+              <Fragment>+                <div+                  ref={resizeElementRef}+                  className={styles.TreeWrapper}+                  style={{+                    ...resizeElementStyles,+                  }}>+                  <Tree />+                </div>+                <div className={styles.ResizeBarWrapper}>+                  <div+                    onMouseDown={onResizeStart}+                    className={styles.ResizeBar}+                  />+                </div>+                <div className={styles.SelectedElementWrapper}>+                  <NativeStyleContextController>+                    <Suspense fallback={<Loading />}>+                      <SelectedElement />+                    </Suspense>+                  </NativeStyleContextController>+                </div>+                <ModalDialog />+                <SettingsModal />+              </Fragment>+            )}+          </ComponentResizer>         </InspectedElementContextController>       </OwnersListContextController>     </SettingsModalContextController>   ); } +type HorizontalResizeDirection = 'HORIZONTAL';+type VerticalResizeDirection = 'VERTICAL';++const RESIZE_DIRECTIONS: {|+  HORIZONTAL: HorizontalResizeDirection,+  VERTICAL: VerticalResizeDirection,+|} = {+  HORIZONTAL: 'HORIZONTAL',+  VERTICAL: 'VERTICAL',+};++const LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_HORIZONTAL_KEY = `React::DevTools::resizedElementPercentage::${RESIZE_DIRECTIONS.HORIZONTAL}`;+const LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_VERTICAL_KEY = `React::DevTools::resizedElementPercentage::${RESIZE_DIRECTIONS.VERTICAL}`;++function ComponentResizer({children}): {|children: Function|} {+  const [isResizing, setIsResizing] = useState<boolean>(false);+  const [+    horizontalPercentage,+    setHorizontalPercentage,+  ] = useLocalStorage<number>(+    LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_HORIZONTAL_KEY,+    65,+  );+  const [verticalPercentage, setVerticalPercentage] = useLocalStorage<number>(+    LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_VERTICAL_KEY,+    50,+  );+  const updateLocalStorageTimeoutId = useRef<number>(null);+  const componentsWrapperRef = useRef<HTMLDivElement>(null);+  const resizeElementRef = useRef<HTMLElement>(null);+  const [resizeElementStyles, setResizeElementStyles] = useState<Object>({});+  const getResizeDirection: Function = useCallback(() => {+    if (componentsWrapperRef.current === null) {+      return RESIZE_DIRECTIONS.HORIZONTAL;+    }+    const {width} = componentsWrapperRef.current.getBoundingClientRect();++    return width > 600+      ? RESIZE_DIRECTIONS.HORIZONTAL+      : RESIZE_DIRECTIONS.VERTICAL;+  }, [componentsWrapperRef]);++  const onResizeStart = useCallback(() => {+    setIsResizing(true);+  }, [setIsResizing]);++  const onResizeEnd = useCallback(() => {+    setIsResizing(false);+  }, [setIsResizing]);++  const onResize = useCallback(+    e => {+      if (+        !isResizing ||+        componentsWrapperRef.current === null ||+        resizeElementRef.current === null+      ) {+        return;+      }++      e.preventDefault();++      const {+        height,+        width,+        left,+        top,+      } = componentsWrapperRef.current.getBoundingClientRect();+      const resizeDirection = getResizeDirection();+      const currentMousePosition: number =+        resizeDirection === RESIZE_DIRECTIONS.HORIZONTAL+          ? e.clientX - left+          : e.clientY - top;+      const boundary: {|+        min: number,+        max: number,+      |} = {+        min: 40,+        max:+          resizeDirection === RESIZE_DIRECTIONS.HORIZONTAL+            ? width - 40+            : height - 40,+      };+      const mousePositionInBounds: boolean =+        currentMousePosition > boundary.min &&+        currentMousePosition < boundary.max;++      if (mousePositionInBounds) {+        const updatedFlexBasisValue: number =+          (currentMousePosition /+            (resizeDirection === RESIZE_DIRECTIONS.HORIZONTAL+              ? width+              : height)) *+          100;

hristo-kanchev

comment created time in 10 days

Pull request review commentfacebook/react

[DevTools] Added resize support for Components panel.

 import portaledContent from '../portaledContent'; import {ModalDialog} from '../ModalDialog'; import SettingsModal from 'react-devtools-shared/src/devtools/views/Settings/SettingsModal'; import {SettingsModalContextController} from 'react-devtools-shared/src/devtools/views/Settings/SettingsModalContext';+import {useLocalStorage} from '../hooks';  import styles from './Components.css';  function Components(_: {||}) {-  // TODO Flex wrappers below should be user resizable.   return (     <SettingsModalContextController>       <OwnersListContextController>         <InspectedElementContextController>-          <div className={styles.Components}>-            <div className={styles.TreeWrapper}>-              <Tree />-            </div>-            <div className={styles.SelectedElementWrapper}>-              <NativeStyleContextController>-                <Suspense fallback={<Loading />}>-                  <SelectedElement />-                </Suspense>-              </NativeStyleContextController>-            </div>-            <ModalDialog />-            <SettingsModal />-          </div>+          <ComponentResizer>+            {({resizeElementRef, onResizeStart, resizeElementStyles}) => (+              <Fragment>+                <div+                  ref={resizeElementRef}+                  className={styles.TreeWrapper}+                  style={{+                    ...resizeElementStyles,+                  }}>+                  <Tree />+                </div>+                <div className={styles.ResizeBarWrapper}>+                  <div+                    onMouseDown={onResizeStart}+                    className={styles.ResizeBar}+                  />+                </div>+                <div className={styles.SelectedElementWrapper}>+                  <NativeStyleContextController>+                    <Suspense fallback={<Loading />}>+                      <SelectedElement />+                    </Suspense>+                  </NativeStyleContextController>+                </div>+                <ModalDialog />+                <SettingsModal />+              </Fragment>+            )}+          </ComponentResizer>         </InspectedElementContextController>       </OwnersListContextController>     </SettingsModalContextController>   ); } +type HorizontalResizeDirection = 'HORIZONTAL';+type VerticalResizeDirection = 'VERTICAL';++const RESIZE_DIRECTIONS: {|+  HORIZONTAL: HorizontalResizeDirection,+  VERTICAL: VerticalResizeDirection,+|} = {+  HORIZONTAL: 'HORIZONTAL',+  VERTICAL: 'VERTICAL',+};++const LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_HORIZONTAL_KEY = `React::DevTools::resizedElementPercentage::${RESIZE_DIRECTIONS.HORIZONTAL}`;+const LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_VERTICAL_KEY = `React::DevTools::resizedElementPercentage::${RESIZE_DIRECTIONS.VERTICAL}`;++function ComponentResizer({children}): {|children: Function|} {+  const [isResizing, setIsResizing] = useState<boolean>(false);+  const [+    horizontalPercentage,+    setHorizontalPercentage,+  ] = useLocalStorage<number>(+    LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_HORIZONTAL_KEY,+    65,+  );+  const [verticalPercentage, setVerticalPercentage] = useLocalStorage<number>(+    LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_VERTICAL_KEY,+    50,+  );+  const updateLocalStorageTimeoutId = useRef<number>(null);+  const componentsWrapperRef = useRef<HTMLDivElement>(null);+  const resizeElementRef = useRef<HTMLElement>(null);+  const [resizeElementStyles, setResizeElementStyles] = useState<Object>({});+  const getResizeDirection: Function = useCallback(() => {+    if (componentsWrapperRef.current === null) {+      return RESIZE_DIRECTIONS.HORIZONTAL;+    }+    const {width} = componentsWrapperRef.current.getBoundingClientRect();++    return width > 600+      ? RESIZE_DIRECTIONS.HORIZONTAL+      : RESIZE_DIRECTIONS.VERTICAL;+  }, [componentsWrapperRef]);++  const onResizeStart = useCallback(() => {+    setIsResizing(true);+  }, [setIsResizing]);++  const onResizeEnd = useCallback(() => {+    setIsResizing(false);+  }, [setIsResizing]);++  const onResize = useCallback(+    e => {+      if (+        !isResizing ||+        componentsWrapperRef.current === null ||+        resizeElementRef.current === null+      ) {+        return;+      }++      e.preventDefault();++      const {+        height,+        width,+        left,+        top,+      } = componentsWrapperRef.current.getBoundingClientRect();+      const resizeDirection = getResizeDirection();+      const currentMousePosition: number =+        resizeDirection === RESIZE_DIRECTIONS.HORIZONTAL+          ? e.clientX - left+          : e.clientY - top;+      const boundary: {|+        min: number,+        max: number,+      |} = {+        min: 40,

Added 🥂

hristo-kanchev

comment created time in 10 days

Pull request review commentfacebook/react

[DevTools] Added resize support for Components panel.

 import portaledContent from '../portaledContent'; import {ModalDialog} from '../ModalDialog'; import SettingsModal from 'react-devtools-shared/src/devtools/views/Settings/SettingsModal'; import {SettingsModalContextController} from 'react-devtools-shared/src/devtools/views/Settings/SettingsModalContext';+import {useLocalStorage} from '../hooks';  import styles from './Components.css';  function Components(_: {||}) {-  // TODO Flex wrappers below should be user resizable.   return (     <SettingsModalContextController>       <OwnersListContextController>         <InspectedElementContextController>-          <div className={styles.Components}>-            <div className={styles.TreeWrapper}>-              <Tree />-            </div>-            <div className={styles.SelectedElementWrapper}>-              <NativeStyleContextController>-                <Suspense fallback={<Loading />}>-                  <SelectedElement />-                </Suspense>-              </NativeStyleContextController>-            </div>-            <ModalDialog />-            <SettingsModal />-          </div>+          <ComponentResizer>+            {({resizeElementRef, onResizeStart, resizeElementStyles}) => (+              <Fragment>+                <div+                  ref={resizeElementRef}+                  className={styles.TreeWrapper}+                  style={{+                    ...resizeElementStyles,+                  }}>+                  <Tree />+                </div>+                <div className={styles.ResizeBarWrapper}>+                  <div+                    onMouseDown={onResizeStart}+                    className={styles.ResizeBar}+                  />+                </div>+                <div className={styles.SelectedElementWrapper}>+                  <NativeStyleContextController>+                    <Suspense fallback={<Loading />}>+                      <SelectedElement />+                    </Suspense>+                  </NativeStyleContextController>+                </div>+                <ModalDialog />+                <SettingsModal />+              </Fragment>+            )}+          </ComponentResizer>         </InspectedElementContextController>       </OwnersListContextController>     </SettingsModalContextController>   ); } +type HorizontalResizeDirection = 'HORIZONTAL';+type VerticalResizeDirection = 'VERTICAL';++const RESIZE_DIRECTIONS: {|+  HORIZONTAL: HorizontalResizeDirection,+  VERTICAL: VerticalResizeDirection,+|} = {+  HORIZONTAL: 'HORIZONTAL',+  VERTICAL: 'VERTICAL',+};++const LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_HORIZONTAL_KEY = `React::DevTools::resizedElementPercentage::${RESIZE_DIRECTIONS.HORIZONTAL}`;+const LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_VERTICAL_KEY = `React::DevTools::resizedElementPercentage::${RESIZE_DIRECTIONS.VERTICAL}`;++function ComponentResizer({children}): {|children: Function|} {+  const [isResizing, setIsResizing] = useState<boolean>(false);+  const [+    horizontalPercentage,+    setHorizontalPercentage,+  ] = useLocalStorage<number>(+    LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_HORIZONTAL_KEY,+    65,+  );+  const [verticalPercentage, setVerticalPercentage] = useLocalStorage<number>(+    LOCAL_STORAGE_RESIZE_ELEMENT_PERCENTAGE_VERTICAL_KEY,+    50,+  );+  const updateLocalStorageTimeoutId = useRef<number>(null);+  const componentsWrapperRef = useRef<HTMLDivElement>(null);+  const resizeElementRef = useRef<HTMLElement>(null);+  const [resizeElementStyles, setResizeElementStyles] = useState<Object>({});+  const getResizeDirection: Function = useCallback(() => {+    if (componentsWrapperRef.current === null) {+      return RESIZE_DIRECTIONS.HORIZONTAL;+    }+    const {width} = componentsWrapperRef.current.getBoundingClientRect();++    return width > 600+      ? RESIZE_DIRECTIONS.HORIZONTAL+      : RESIZE_DIRECTIONS.VERTICAL;

Nice one! Thanks

hristo-kanchev

comment created time in 10 days

push eventhristo-kanchev/react

Hristo Kanchev

commit sha a0daca487a9ce6df8c6ab10b4d790dca0dec8588

feat: DevTools - Extracted values to constants.

view details

push time in 10 days

PR opened facebook/react

Devtools add resize support

Summary

Solves: #17389

Adding support for resizing the components panel.

Changes are remembered when the user refreshes.

Demo:

Horizontal Resize: 74515268-89e76080-4f0e-11ea-8b1b-4c2e2cf90322

Vertical Resize: 74515373-bac79580-4f0e-11ea-96d5-fcfa2c7ffff4

PS: I saw something weird happening. I'm seeing vertical scroll bars in the components / inspected component areas. This is happening as well in master so I am pretty sure that these changes aren't causing the issue.

Screenshot 2020-02-16 at 11 16 29

Can you check if it's happening for you as well @bvaughn ?

+201 -19

0 comment

2 changed files

pr created time in 12 days

push eventhristo-kanchev/react

Hristo Kanchev

commit sha a1971fb1053d27c30c722a984c2c4c069c2e4b37

feat: DevTools - Added types.

view details

push time in 12 days

create barnchhristo-kanchev/react

branch : devtools-add-resize-support

created branch time in 12 days

issue commentfacebook/react

Devtools resize Component State/Props pane

Almost done! (I expect to open the PR this Saturday).

Here how it looks so far:

Horizontal Resize:

horizontal-resize

Vertical Resize:

vertical-resize

codercodingthecode

comment created time in 14 days

issue commentfacebook/react

Devtools resize Component State/Props pane

Progress so far:

horizontal-resize

I have a question though, @bvaughn.

Should we also support vertical resizing when we are in this mode?

Screenshot 2020-02-13 at 13 09 27

Thoughts?

Note: The red horizontal line is for debugging purposes 😆

codercodingthecode

comment created time in 14 days

issue commentfacebook/react

Devtools resize Component State/Props pane

Cool @bvaughn. I'll try and open a PR by the end of this week. I'll ping you again when it's done.

codercodingthecode

comment created time in 18 days

issue commentfacebook/react

Bug: React Dev Tools Firefox extension fails to detect React

It's happening because the page is explicitly blocking our script that gets injected in the page. We are using that to detect if React is there or not.

Content Security Policy: The page’s settings blocked the loading of a resource at inline (“script-src”). in injectGlobalHook.js

Kein

comment created time in 20 days

issue commentfacebook/react

Devtools resize Component State/Props pane

Hey @bvaughn !

Are we still looking at adding this feature?

Maybe we can have a checkbox in Settings -> General that will allows the user to dock the Component State/Props/.. to the bottom instead of supporting resizing for that pane?

What do you think?

codercodingthecode

comment created time in a month

issue commentfacebook/react

[HMR] Waiting for update signal from WDS...

@leantide Please file this issue in the create-react-app repo. Thanks!

leantide

comment created time in 2 months

pull request commentfacebook/react

Improved inspected element props with inline previews

Nice one, @bvaughn 🤘 !!

bvaughn

comment created time in 3 months

issue commentfacebook/react

Can't import image dynamically in reactjs

@JeremyMeissner You can use dynamic imports for that.

e.g.:

import('./img/item.png').then(image => console.log(image));
JeremyMeissner

comment created time in 3 months

issue commentfacebook/react

Error: "Could not find node with id "836" in commit tree"

Hello @disko998! Could you please create clear reproduction steps and a CodeSandbox link in order for us to investigate. It's impossible to actually figure out what kind of issue you are having. Thanks!

disko998

comment created time in 3 months

issue commentfacebook/react

Can't import image dynamically in reactjs

If you are using create-react-app you can do the following:

import itemImage from './img/item.png';

If you have a custom Webpack configuration take a look at https://webpack.js.org/loaders/file-loader/

JeremyMeissner

comment created time in 3 months

issue commentfacebook/react

React Dev Tools Standalone only draggable, not clickable

I can't seem to reproduce it on a Mac 🤔

mbman

comment created time in 3 months

push eventhristo-kanchev/react

Andrew Clark

commit sha 6dc2734b41aef944e457eaa23ae218952fce0a54

Codemod tests to `it.experimental` (#17243) `it.experimental` marks that a test only works in Experimental builds. It also asserts that a test does *not* work in the stable builds. The main benefit is that we're less likely to accidentally expose an experimental API before we intend. It also forces us to un- mark an experimental test once it become stable.

view details

Andrew Clark

commit sha a2e05b6c148b25590884e8911d4d4acfcb76a487

[Scheduler] Delete old rAF implementation (#17252) We've been using the message loop version for a while. Time to delete.

view details

Brian Vaughn

commit sha 36fd29f09fae82766207899ac31e462d8ee284e5

Don't show empty (no work) commits in Profiler (#17253)

view details

Sebastian Markbåge

commit sha fadc97167f8d2387dfc2c7b2493ba9ffbbb35fcf

[Flight] Add Client Infrastructure (#17234) * Change demo to server * Expose client in package.json * Reorganize tests We don't want unit tests but instead test how both server and clients work together. So this merges server/client test files. * Fill in the client implementation a bit * Use new client in fixture * Add Promise/Uint8Array to lint rule I'll probably end up deleting these deps later but they're here for now.

view details

Sebastian Markbåge

commit sha f4148b2561d468c292f184fb35b186efbc5dd758

[Flight] Move around the Server side a bit (#17251) * Rename ReactFlightStreamer -> ReactFlightServer * Unify Browser/Node stream tests into one file and use the client reader * Defer to the actual ReactDOM for HTML rendering for now This will need to use a variant of Fizz to do inline SSR in Flight. However, I don't want to build the whole impl right now but also don't want to exclude the use case yet. So I outsource it to the existing renderer. Ofc, this doesn't work with Suspense atm.

view details

Mateusz Burzyński

commit sha 62ef25077ed440947c19386f33c28db44e10de92

Avoid bundling in ponyfill for Object.assign in use-subscription package (#17259)

view details

Eli White

commit sha 6095993d461a58da14dae9866486359497af339e

Types: findHostInstance_DEPRECATED returns React.ElementRef<HostComponent<mixed>> (#17265) * Types: findHostInstance_DEPRECATED returns React.ElementRef<HostComponent<mixed>> * Prettier

view details

Dominic Gannaway

commit sha cb09dbe0ab0f42185c4892c045b0c32e04f6b9cb

[react-interactions] Add handleSimulateChildBlur upon DOM node removal (#17225) * [react-interactions] Add handleSimulateChildBlur upon DOM node removal

view details

Andrew Clark

commit sha 0f3838a01b0fda0ac5fd054c6be13166697a113c

Remove `debugRenderPhaseSideEffects` flag (#17270) There are two similar flags, `debugRenderPhaseSideEffects` and `debugRenderPhaseSideEffectsForStrictMode`. The strict mode one is the only one that is actually used. I think originally the theory is that we would one day turn it on for all components, even outside strict mode. But what we'll do instead is migrate everyone to strict mode. The only place `debugRenderPhaseSideEffects` was being used was in an internal test file. I rewrote those tests to use public APIs.

view details

Brian Vaughn

commit sha 053cf0fedc91a1507080afe43d3be354ec346e9e

Fix react-is memo and lazy type checks (#17278)

view details

Waseem Dahman

commit sha 4f02c93c7cb213355b3c7d2011e531431d1c6dd8

Fix devtools displaying Anonymous for memo of ref-forwarding components (#17274) * [react-is] return correct typeOf value of forwardRef * [react-devtools-shared] use correct displayName of memo(forwardRef(Component)) * [react-devtools-shared] add resolveFiberType and resolve fiber type of memo recursively Resolving the fiber type of memo recursively before passing it to getDisplayName will prevent it from displaying "Anonymous" as displayName for components wrapped with both memo and forwardRef: memo(forwardRef(Component)) * rework resolveFiberType

view details

Dominic Gannaway

commit sha cd1bdcd0672d87f275a6394b055dea1016a7f29d

[react-interactions] Prevent duplicate onPress firing for keyboard Enter (#17266) * [react-interactions] Prevent duplicate onPress firing for keyboard Enter * address feedback

view details

Brian Vaughn

commit sha 34527063083195558f98108cde10b5d6ad0d6865

DevTools cleanup (#17283) 1. Add a Store test for memo, lazy, and forwardRef components 2. Remove dead code for React.lazy 3. Update DT tests to include HOC badge names in the serialized store

view details

Dan Abramov

commit sha f50f39b55fb09fc78c8fc2bd63d286c147fd30f2

[Flight] Better compat with http.createServer (#17289)

view details

Sebastian Markbåge

commit sha dee03049f5690e23787f3ba1afd3150fb3540624

[Flight] Basic Streaming Suspense Support (#17285) * Return whether to keep flowing in Host config * Emit basic chunk based streaming in the Flight server When something suspends a new chunk is created. * Add reentrancy check The WHATWG API is designed to be pulled recursively. We should refactor to favor that approach. * Basic streaming Suspense support on the client * Add basic suspense in example * Add comment describing the protocol that the server generates

view details

Dominic Gannaway

commit sha ce4b3e998191445b2934f6846ee7661578ef6444

[react-interactions] Add optional searchNodes to Scope.queryAllNodes (#17293)

view details

Dominic Gannaway

commit sha e701632ad4112038c4dd8e7302b90c0bb3fc4f2b

[react-interactions] Change unmount blur logic to a dedicated event (#17291)

view details

Moti Zilberman

commit sha 61d3dd0e08a53eebeaf06537b84b78dedbc92168

Update deepDiffer usage in React Native renderer (#17282) * Add RN prop diffing test with function values * Update RN deepDiffer mock * Explicitly ignore functions in RN prop differ

view details

Moti Zilberman

commit sha 38dd17ab98ce288fd0d0b68682a6df0f0a49e158

[RN] Hoist static deepDiffer options object (#17303)

view details

Dan Abramov

commit sha 6cb6b1d6682077852b48b7eae597df58e871ed23

Add yarn build --unsafe-partial (#17316) * Add yarn build --partial * unsafe-partial

view details

push time in 3 months

issue commentfacebook/react

React Devtools standalone subpanels frozen on version 4.2.1

Hey @BartlomiejLewandowski and @olo2552! What OS are you using by the way?

BartlomiejLewandowski

comment created time in 3 months

issue commentfacebook/react

React Dev Tools Standalone only draggable, not clickable

I went through the PRs that were merged after the 4.2.0 release and from what I can see this might be causing the issue -> https://github.com/facebook/react/pull/17213/files#diff-0f549815d0bbdc6626381ce99a584450R100

I'm super busy at the moment, so I'll probably not be able to fix this bug myself.

Any takers? 😸

mbman

comment created time in 3 months

issue commentfacebook/react

React Devtools standalone subpanels frozen on version 4.2.1

Duplicate of #17522

BartlomiejLewandowski

comment created time in 3 months

issue commentfacebook/react

DevTools: Updating state or props in devtools does not trigger component update.

@thisisDom We have a PR open for this https://github.com/facebook/react/pull/17062 👍

thisisDom

comment created time in 4 months

issue commentfacebook/react

DevTools: Updating state or props in devtools does not trigger component update.

@thisisDom I can't reproduce the issue. Did you by any chance forgot to press Enter after you entered the text?

thisisDom

comment created time in 4 months

issue commentfacebook/react

DevTools: Component bookmarks

The unfortunate part is that we'll need to clutter the UI somewhere. I'll see what I can do. 👍

bvaughn

comment created time in 4 months

issue commentfacebook/react

DevTools: Component bookmarks

Hey @bvaughn are we still interested in implementing this? I have some ideas, so if you'd like I can create a PoC branch?

bvaughn

comment created time in 4 months

push eventhristo-kanchev/react

Dan Abramov

commit sha 4ddcb8e1344630a63c10790d8e24e1194a1abdce

[DevTools] Remove Welcome dialog (#16834)

view details

Nicolas Gallagher

commit sha fd870e6b6a9c35cf4bb77d83dbfe61e07327368f

[react-ui/events] Tap responder API changes (#16827) This patch limits the `onTap*` callbacks to the primary pointer button. Auxiliary button and modified primary button interactions call `onAuxiliaryTap`, cancel any active tap, and preserve the native behavior.

view details

Sebastian Markbåge

commit sha 35bf9d27a3f9fdf60cea060d20b5c178e437520d

Exclude react-dom when flow checking other builds (#16737) This is because the HostConfig can't be guaranteed to be consistent with other code such as code that touches the DOM directly. Ideally we'd have a more systemic solution to this since it will pop up for other packages later too.

view details

Brian Vaughn

commit sha b5cebedfbe0c05c530ead002b123448b6b71e052

React DevTools version bump 4.0.6 -> 4.1.0

view details

Brian Vaughn

commit sha 08b51aa384125c2169fa5e0371bfdf4e292737a9

Added React DevTools v4.1.0 release date to CHANGELOG

view details

Dominic Gannaway

commit sha 57a5805a9f07cbda3fea99b7cca59bd3b2bb8476

[react-ui] Add preventDefault+stopPropagation to Keyboard + update Focus components (#16833)

view details

Dan Abramov

commit sha cef47cbc01b3c41ef4bfe3cdf7abd09c34e4a9c2

Rename experimental react-ui => react-interactions (#16842)

view details

Dominic Gannaway

commit sha d7f6dd5a80827aea76fc42f07c77d05abb7180b2

[react-interactions] Fix typo in FocusTable (#16860)

view details

Dominic Gannaway

commit sha 70754f10d4119a999ac9a46b6ea8c11a12a1a72d

[react-interaction] Tweak Focus Table component (#16862)

view details

Nicolas Gallagher

commit sha 312b462d5444c231d5acf656efea6780ad9ba89d

[react-interactions] Improve consistency of Tap responder (#16837) Makes sure that touch events with modifier keys behave the same way as other pointer types (i.e., does not call `onTapStart` if the gesture begins with a modifier key held down)

view details

Andrew Clark

commit sha a87d245fc2d0b5eedd5463e6f21bf12443489b15

[work loop] Prevent work loop from being inlined (#16865) Uses Closure Compiler's `@noinline` directive. See https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler#noinline

view details

Sebastian Markbåge

commit sha 0a527707cd8befd21a741ca9646a8551842190b0

Event Replaying (#16725) * Add Event Replaying Infra * Wire up Roots and Suspense boundaries, to retry events, after they commit * Replay discrete events in order in a separate scheduler callback * Add continuous events These events only replay their last target if the target is not yet hydrated. That way we don't have to wait for a previously hovered boundary before invoking the current target. * Enable tests from before These tests were written with replaying in mind and now we can properly enable them. * Unify replaying and dispatching * Mark system flags as a replay and pass to legacy events That way we can check if this is a replay and therefore needs a special case. One such special case is "mouseover" where we check the relatedTarget. * Eagerly listen to all replayable events To minimize breakages in a minor, I only do this for the new root APIs since replaying only matters there anyway. Only if hydrating. For Flare, I have to attach all active listeners since the current system has one DOM listener for each. In a follow up I plan on optimizing that by only attaching one if there's at least one active listener which would allow us to start with only passive and then upgrade. * Desperate attempt to save bytese * Add test for mouseover replaying We need to check if the "relatedTarget" is mounted due to how the old event system dispatches from the "out" event. * Fix for nested boundaries and suspense in root container This is a follow up to #16673 which didn't have a test because it wasn't observable yet. This shows that it had a bug. * Rename RESPONDER_EVENT_SYSTEM to PLUGIN_EVENT_SYSTEM

view details

Andrew Clark

commit sha 013b7ad117834cbb99b4fc0a3d08fdb8622597c9

[suspense][error handling] Inline renderRoot and fix error handling bug (#16801) * Outline push/pop logic in `renderRoot` I want to get rid of the the `isSync` argument to `renderRoot`, and instead use separate functions for concurrent and synchronous render. As a first step, this extracts the push/pop logic that happens before and after the render phase into helper functions. * Extract `catch` block into helper function Similar to previous commit. Extract error handling logic into a separate function so it can be reused. * Fork `renderRoot` for sync and concurrent Removes `isSync` argument in favor of separate functions. * Extra "root completion" logic to separate function Moving this out to avoid an accidental early return, which would bypass the call to `ensureRootIsScheduled` and freeze the UI. * Inline `renderRoot` Inlines `renderRoot` into `performConcurrentWorkOnRoot` and `performSyncWorkOnRoot`. This lets me remove the `isSync` argument and also get rid of a redundant try-catch wrapper. * [suspense][error handling] Add failing unit test Covers an edge case where an error is thrown inside the complete phase of a component that is in the return path of a component that suspends. The second error should also be handled (i.e. able to be captured by an error boundary. The test is currently failing because there's a call to `completeUnitOfWork` inside the main render phase `catch` block. That call is not itself wrapped in try-catch, so anything that throws is treated as a fatal/unhandled error. I believe this bug is only observable if something in the host config throws; and, only in legacy mode, because in concurrent/batched mode, `completeUnitOfWork` on fiber that throws follows the "unwind" path only, not the "complete" path, and the "unwind" path does not call any host config methods. * [scheduler][profiler] Start time of delayed tasks Fixes a bug in the Scheduler profiler where the start time of a delayed tasks is always 0. * Remove ad hoc `throw` Fatal errors (errors that are not captured by an error boundary) are currently rethrown from directly inside the render phase's `catch` block. This is a refactor hazard because the code in this branch has to mirror the code that happens at the end of the function, when exiting the render phase in the normal case. This commit moves the throw to the end, using a new root exit status. * Handle errors that occur on unwind

view details

Dominic Gannaway

commit sha 1758b3f7bafdb9197cf9464182f02da355f4c540

[react-interactions] Add no-op stopPropagation + preventDefault to Press (#16868) Fix

view details

Dominic Gannaway

commit sha 1a6294d3e2254f03267da3412becbe51188e830f

[react-interaction] Refactor a11y components more (#16866)

view details

Brian Vaughn

commit sha 9b3cde9b627e91f9d4a81093384d579928474c37

Fix DevTools v4.1 editable hook regression (#16867) * Fixed a regression in hooks editor from a recent EditableValue change * Fixed a reset/state bug in useEditableValue() hook and removed unnecessary useMemo()

view details

Brian Vaughn

commit sha bce2ac63a93fd77e352286a0074ffe471301ab8a

Revert change to backend injection method from PR #16752 (#16864) PR #16752 changed how we were injecting the backend script to be done by the content script in order to work around Trusted Type limitations with our previous approach. This may have caused a regression (see #16840) so I'm backing it out to verify.

view details

Brian Vaughn

commit sha 911104a129d48fb58c5ef4f80339f2e58539186a

DevTools CHANGELOG update

view details

Nicolas Gallagher

commit sha c5e7190ed4af266bbc636bda08e766fce9ee68a7

[react-interactions] Press with useRef instead of useState (#16870) We only need to read and modify the value for the lifetime of the hook

view details

Andrew Clark

commit sha 8b580a89d6dbbde8a3ed69475899addef1751116

Idle updates should not be blocked by hidden work (#16871) * Idle updates should not be blocked by hidden work Use the special `Idle` expiration time for updates that are triggered at Scheduler's `IdlePriority`, instead of `Never`. The key difference between Idle and Never¹ is that Never work can be committed in an inconsistent state without tearing the UI. The main example is offscreen content, like a hidden subtree. ¹ "Never" isn't the best name. I originally called it that because it "never" expires, but neither does Idle. Since it's mostly used for offscreen subtrees, we could call it "Offscreen." However, it's also used for dehydrated Suspense boundaries, which are inconsistent in the sense that they haven't finished yet, but aren't visibly inconsistent because the server rendered HTML matches what the hydrated tree would look like. * Reset as early as possible using local variable * Updates in a hidden effect should be Idle I had made them Never to avoid an extra render when a hidden effect updates the hidden component -- if they are Idle, we have to render once at Idle, which bails out on the hidden subtree, then again at Never to actually process the update -- but the problem of needing an extra render pass to bail out hidden updates already exists and we should fix that properly instead of adding yet another special case.

view details

push time in 4 months

issue commentfacebook/react

React DevTools force re-render button

Hey @nik72619c there is already a PR open for this.

We are currently in a discussion if we actually need this feature.

I agree with @kentcdodds that it might "increase people's general unfounded fear of re-renders".

We are also adding an additional button, and the UI is looking cluttered (especially if you have a long component name).

Should we close this issue/PR for now, @bvaughn ? I'm not sure what should we do 🤷‍♂

kentcdodds

comment created time in 4 months

pull request commentfacebook/react

[DevTools] Implemented re-render mechanism for React 16.9+

Heya @bvaughn ! I'll address your comments and after that we can park it for the time being, untill we get more feature requests like this one? What do you think?

hristo-kanchev

comment created time in 4 months

push eventhristo-kanchev/react

Hristo Kanchev

commit sha 271518f067013fa973b77cd89d960050e9566c5f

Merged if statements.

view details

push time in 4 months

Pull request review commentfacebook/react

[DevTools] Implemented re-render mechanism for React 16.9+

 export function attach(     }   } +  function forceRerender(id: number) {+    const fiber = findCurrentFiberUsingSlowPathById(id);++    if (fiber !== null) {+      if (typeof scheduleUpdate === 'function') {

Yup! I've pushed the changes.

hristo-kanchev

comment created time in 4 months

PR opened facebook/react

feat: Implemented re-render mechanism for React 16.9+

Solves: #16968

Description: Added force re-render mechanism for components.

Support: As @bvaughn suggested, we will only support React 16.9+ Versions that aren't supported won't show the re-render button in the UI.

re-render

+72 -0

0 comment

8 changed files

pr created time in 5 months

push eventhristo-kanchev/react

Hristo Kanchev

commit sha 62fdda433fe48fdc7cb0a2a0d26ee744fc46c1c4

feat: Rolled back codechange.

view details

push time in 5 months

create barnchhristo-kanchev/react

branch : feat/force-rerender

created branch time in 5 months

issue commentfacebook/react

Annoying popup from chrome devtools wrongly telling me I'm using an old version of React

@LukenAgile42 @hsiehc Can you provide a CodeSandbox repro link, please?

LukenAgile42

comment created time in 5 months

issue commentfacebook/react

Annoying popup from chrome devtools wrongly telling me I'm using an old version of React

What version of DevTools are you using?

LukenAgile42

comment created time in 5 months

issue commentfacebook/react

React DevTools force re-render button

Hey @bvaughn! Hope you are doing well.

I'm struggling to find a good way to re-render the component that will capture all use cases.

I used instance.forceUpdate but this doesn't capture all use cases - for example functional components.

I can push my code if you want to check it out and advise if possible?

kentcdodds

comment created time in 5 months

issue commentfacebook/react

React DevTools force re-render button

Yeah, "Re-render component" is better. I'll change the tooltip text 👍

kentcdodds

comment created time in 5 months

issue commentfacebook/react

React DevTools force re-render button

Something like this maybe?

forceupdate

Do you think the UI is getting cluttered over there, @bvaughn ?

If you are cool with this I can submit the PR.

kentcdodds

comment created time in 5 months

issue commentfacebook/react

Devtools v4 does not work with Firefox's private window

Hey everyone. Just reproduced the issue and tried to fix it.

It seems more complex than I initially thought.

For some reason when we create the panels via devtools.panels.create and we attach the onShown event we receive a completely different window object (called panel in this case).

When using the DevTools normally we get the full window object and it's properties, but when in private mode it seems like a stripped down version of it.

I tried digging through both the chromium/MDN docs but I can't find anything related.

Also, I tweaked my Firefox configuration without success.

Does anyone have any ideas to why this might happen?

Thanks @saneyuki for the detailed description and repro steps!

saneyuki

comment created time in 5 months

issue commentfacebook/react

DevTools: showing wrong state

I closed the PR that I submitted yesterday. Unfortunately it didn't fully fix the issue.

I won't be able to work on this this weekend sadly 😭

Anyone want to help out?

You can see the comments that @bvaughn made that fully describes the problem we are having.

Kogoruhn

comment created time in 5 months

PR closed facebook/react

[DevTools] Hotfix: Fixed element tree sorting when we have an array of entries. CLA Signed

Fixes: #16843

Description: The bug was caused due to the use of Object.entries in the InspectedElementTree component.

We aren't taking into account that the data prop could change and that the data entries could be an array.

If we removed the second entry out of three entries in total the index will shift and thus remove the last one which is the incorrect one.

@bvaughn Could you check this out? Thanks!

+13 -6

10 comments

1 changed file

hristo-kanchev

pr closed time in 5 months

pull request commentfacebook/react

[DevTools] Hotfix: Fixed element tree sorting when we have an array of entries.

Closing PR for now, as this won't actually fix the issue.

hristo-kanchev

comment created time in 5 months

pull request commentfacebook/react

[DevTools] Hotfix: Fixed element tree sorting when we have an array of entries.

Ahh, yeah, now I see the problem. This PR won't fix the issue.

You are correct, the useEditableValue is the culprit.

hristo-kanchev

comment created time in 5 months

pull request commentfacebook/react

[DevTools] Hotfix: Fixed element tree sorting when we have an array of entries.

That's weird. I tried building the extension with yarn test:firefox in the extensions package and and it was fine.

I agree, we definitely need to expand our tests in order to not regress 👍

hristo-kanchev

comment created time in 5 months

pull request commentfacebook/react

[DevTools] Hotfix: Fixed element tree sorting when we have an array of entries.

I tried it out and it actually fixed it.

I can check it out in further detail early tomorrow morning, if you'd like?

I think initially when I submitted the PR for the prop/state editing interface I didn't see this issue because of https://github.com/facebook/react/pull/16700/files/389010a27e9a0bb0f332dff844ff744b23e1a5e0#diff-3230479a214c02a97506fb71c4315109R41

As you said this uses https://reactjs.org/blog/2018/06/07/you-probably-dont-need-derived-state.html#anti-pattern-erasing-state-when-props-change which is 😒

And, no worries, it's been an absolute pleasure to work on DevTools!

hristo-kanchev

comment created time in 5 months

PR opened facebook/react

[DevTools] Hotfix: Fixed element tree sorting when we have an array of entries.

Fixes: #16843

Description: The bug was caused due to the use of Object.entries in the InspectedElementTree component.

We aren't taking into account that the data prop could change and that the data entries could be an array.

If we removed the second entry out of three entries in total the index will shift and thus remove the last one which is the incorrect one.

@bvaughn Could you check this out? Thanks!

+13 -6

0 comment

1 changed file

pr created time in 5 months

create barnchhristo-kanchev/react

branch : hotfix/array-index-fix

created branch time in 5 months

issue commentfacebook/react

DevTools: showing wrong state

Found the issue. Currently about to open a PR with thee hotfix. @bvaughn expect something in 10-15 minutes.

Kogoruhn

comment created time in 5 months

push eventhristo-kanchev/react

Heaven

commit sha 9444c876d5731e55d9b9931cb239a5b7170162d3

Remove wrong copy-paste code in test (#16695)

view details

Nicolas Gallagher

commit sha f26fe8c0a7950ebee023e30745203a33ef27deb8

[react-events] Keyboard: fix callback return types (#16693)

view details

Nicolas Gallagher

commit sha 031eba789f0548838cf876b7c497f88aecec86f7

[react-events] Tap: change order of events (#16694) Before: start -> change -> update -> end (cancel) -> change Now: start -> change -> update -> change -> end (cancel)

view details

Sebastian Markbåge

commit sha cc2492ccf14ebc20b2a05ff6806a42b6107e2154

Schedule passive callbacks before layout effects are invoked (#16713)

view details

Sebastian Markbåge

commit sha 440cbf2ee57420bd36ef90aaae19e6542614677a

Let's schedule the passive effects even earlier (#16714) It turns out I needed to schedule mine in the mutation phase and there are also clean up life-cycles there.

view details

Daniel Lo Nigro

commit sha 35f447ddbf652091ce98f102bedc71a054a638f6

Remove console.log from copyWithSet (#16716)

view details

Hristo Kanchev

commit sha 4905590e1e9f9798804d71da14a45084880edbb4

Fixed font family issue in FF. (#16701)

view details

Heaven

commit sha 38c03ce00643c02f61bee69fec16459cea01af04

Fix typo in commet (#16727)

view details

Dominic Gannaway

commit sha fd3e8cb0aea97d7945350b434af3e79f4493c98e

[react-events] Remove stopPropagation (Press) + use document for delegation (#16730)

view details

Dan Abramov

commit sha ba6bb0fccf21d6b2c6eeb7a6e1036b0071711c2c

[Fresh] Hash signatures (#16738)

view details

Dan Abramov

commit sha 240040078885767544ddb650ab06d24756e5ee1e

react-refresh@0.4.2

view details

Nicolas Gallagher

commit sha 41a78cd85c461d2f029c1863614c73a28faabade

[react-events] Tap: add maximumDistance prop (#16689) A prop for configuring the maximum distance that the active pointer can move before the tap is cancelled.

view details

Liad Yosef

commit sha c317fc273b6fbe03e30971f7dd5690e540f6a029

Correct link for troubleshooting react-dev-tools (#16690) (#16708) * Correct link for troubleshooting react-dev-tools (#16690) As pointed out in #16690 - the link for 'React Tab Doesn't Show Up' points to the empty README.MD. This points it to that section in the v3 version README.MD - until an updated section will be added to the new dev-tools. * Add a "The React Tab Doesn't Show Up" section Add the troubleshooting section to the react dev tools readme * point to the correct section in react-dev-tools readme After adding the troubleshooting section to the readme - this will point to the correct place * Moved README file to GitHub * Update new issue link to include DevTools label

view details

Hristo Kanchev

commit sha 4ef6387d6e79e87c3ebc11a53847fd26ad5e71d9

[DevTools] [Context] Legacy Context (#16617) * Added hasLegacyContext check. * Passed hasLegacyContext as prop to SelectedElement * Changing context labels based on hasLegacyContext * Fixed flow types. * Fixed typos. * Added tests for hasLegacyContext. * Renamed test. * Removed test imports.

view details

Hristo Kanchev

commit sha 709baf1fecdbc8982aa70957a7bd620a929cea68

[DevTools] Support for adding props | Improved state/props value editing (#16700) * Extracted sanitizeForParse * Added canAddEntries flag to InspectedElementTree * Added EditableKey component. * Added support to add an additional entry. * Added support to add more complex data structures in the EditableValue component. Added support to change the dataType of the value that is being changed. * Fixed flow error. * Removed unneeded fragment. * Renamed EditableKey -> EditableName * Removed unneeded dependency * Removed problematic props to state hook. * Prettified changes. * Removed unused import. * Fixed shouldStringify check. * Removed testing props from EditableProps. * Made some inline tweaks

view details

Brian Vaughn

commit sha 2ce5801c25235b198d99393c193a721547eaefac

Added upcoming changes to DevTools CHANGELOG

view details

Brian Vaughn

commit sha 2c98af77c3633e10ce38f4592718eb08096ceecf

DevTools: Props editing interface tweaks (#16740) * Fix DevTools new prop input size * Don't allow adding new values unless an overridePropsFn function has been provided. * Do not show empty 'none' label ablve a new prop input

view details

Stephanie Ding

commit sha c93038fabe08f7dc26b1a301ed4518a3bc64102f

Moved backend injection logic to content script

view details

Stephanie Ding

commit sha 788036c7ed51fa2a7fc021bbe3807762072dee33

Moved backend injection logic to content script

view details

Stephanie Ding

commit sha 85c7211014a1364fef8d0c3da512ddf63fb408e8

Moved injection logic to content script

view details

push time in 5 months

issue commentfacebook/react

Devtools v4 does not work with Firefox's private window

I'll take a look at this one. 👍

I'll try and provide you with an update by the end of the week.

saneyuki

comment created time in 5 months

pull request commentfacebook/react

[DevTools] Support for adding props | Improved state/props value editing

Hey @bvaughn ! I addressed all of your comments. I'll be going on holidays from tomorrow, so I won't be able to add the additional feature requests that you and @Jessidhia request. Feel free to hijack this PR and add them if it's urgent to get them in. If not, I can add them myself next week.

Thanks for the feedback!

hristo-kanchev

comment created time in 6 months

push eventhristo-kanchev/react

Hristo Kanchev

commit sha 389010a27e9a0bb0f332dff844ff744b23e1a5e0

Removed testing props from EditableProps.

view details

push time in 6 months

push eventhristo-kanchev/react

Hristo Kanchev

commit sha d4c415adb4e73f026dfc84e07fb3078d6598cd82

Fixed shouldStringify check.

view details

push time in 6 months

push eventhristo-kanchev/react

push time in 6 months

Pull request review commentfacebook/react

[DevTools] Support for adding props | Improved state/props value editing

 export default function InspectedElementTree({               value={value}             />           ))}+        {entryToAdd && (+          <div className={styles.AddEntry}>+            <EditableKey overrideKeyFn={handleEntryAddName} />:

@bvaughn Regarding the ability to edit a name of an already set prop, as I mentioned in the other comment, I think we should add this support in another PR.

hristo-kanchev

comment created time in 6 months

Pull request review commentfacebook/react

[DevTools] Support for adding props | Improved state/props value editing

 export default function InspectedElementTree({               value={value}             />           ))}+        {entryToAdd && (+          <div className={styles.AddEntry}>+            <EditableKey overrideKeyFn={handleEntryAddName} />:

I really like the idea from @Jessidhia ! 🚀

I've added support for canResetEntries

Demo:

reset-props

hristo-kanchev

comment created time in 6 months

push eventhristo-kanchev/react

Hristo Kanchev

commit sha 6864696d5c17d5b4298421c7ed2cb6cfe27de371

Added prop for resetEntries.

view details

push time in 6 months

push eventhristo-kanchev/react

Hristo Kanchev

commit sha c4ad6794e2fd2401c7cb351e9cc36a933e623f85

Added Reset to original functionality.

view details

push time in 6 months

push eventhristo-kanchev/react

Hristo Kanchev

commit sha a5cc62b2c5b849b51732508876ed38554ef15b90

Removed unused import.

view details

push time in 6 months

Pull request review commentfacebook/react

[DevTools] Support for adding props | Improved state/props value editing

 export default function EditableValue({   path,   value, }: EditableValueProps) {+  const [isValid, setIsValid] = useState(true);   const [hasPendingChanges, setHasPendingChanges] = useState(false);-  const [editableValue, setEditableValue] = useState(value);+  const [stringifiedValue, setStringifiedValue] = useState(+    JSON.stringify(value),+  );+  const [editableValue, setEditableValue] = useState(stringifiedValue);   const inputRef = useRef<HTMLInputElement | null>(null); -  if (hasPendingChanges && editableValue === value) {+  useEffect(

I completely removed this bit. Thanks for the input!

hristo-kanchev

comment created time in 6 months

push eventhristo-kanchev/react

Hristo Kanchev

commit sha a30cfa4bd1f66f9319a26ac74c63054406b7aa44

Renamed EditableKey -> EditableName

view details

Hristo Kanchev

commit sha 578947267fde93118e709f7d4cbd843e80b7957a

Removed unneeded dependency

view details

Hristo Kanchev

commit sha 20280fbe3ff64c36ca6c91c1eda08fb299350868

Removed problematic props to state hook.

view details

Hristo Kanchev

commit sha c53c79a0158fe2ed77daf8e589e37f5046673971

Prettified changes.

view details

push time in 6 months

Pull request review commentfacebook/react

[DevTools] Support for adding props | Improved state/props value editing

 export default function EditableValue({        const {key} = event; -      if (key === 'Enter') {-        if (dataType === 'number') {-          const parsedValue = parseFloat(editableValue);-          if (!Number.isNaN(parsedValue)) {-            overrideValueFn(path, parsedValue);-          }-        } else {-          overrideValueFn(path, editableValue);+      if (key === 'Enter' && isValid) {+        const parsedEditableValue = JSON.parse(sanitizeForParse(editableValue));++        if (value !== parsedEditableValue) {+          overrideValueFn(path, parsedEditableValue);         }          // Don't reset the pending change flag here.         // The inspected fiber won't be updated until after the next "inspectElement" message.         // We'll reset that flag during a subsequent render.       } else if (key === 'Escape') {-        setEditableValue(value);+        setEditableValue(stringifiedValue);         setHasPendingChanges(false);+        setIsValid(true);       }     },-    [editableValue, dataType, overrideValueFn, path, value],+    [editableValue, isValid, dataType, overrideValueFn, path, value],   ); -  // Render different input types based on the dataType-  let type = 'text';-  if (dataType === 'boolean') {-    type = 'checkbox';-  } else if (dataType === 'number') {

I thought it would be cool to keep this as it is. Users can still override it via Add new prop -> type name and set the value to "hello world" for example. Do you think it would be better if we just displayed true / false instead of the checkbox? That way we can change it more easily.

hristo-kanchev

comment created time in 6 months

Pull request review commentfacebook/react

[DevTools] Support for adding props | Improved state/props value editing

+/**+ * Copyright (c) Facebook, Inc. and its affiliates.+ *+ * This source code is licensed under the MIT license found in the+ * LICENSE file in the root directory of this source tree.+ *+ * @flow+ */++import React, {useRef, useCallback, useEffect, useState} from 'react';+import styles from './EditableKey.css';++type OverrideKeyFn = (path: Array<string | number>, value: any) => void;++type EditableKeyProps = {|+  key?: string,+  overrideKeyFn: OverrideKeyFn,+|};++export default function EditableKey({+  key = '',

@bvaughn I initially had this idea and played around with it in the KeyValue component, but I saw that the PR is getting chunky and decided to not implement it, as it will add more complexity. Maybe we can create a new issue for this one and after this get's merged we can start enhancing this feature? What do you think?

hristo-kanchev

comment created time in 6 months

Pull request review commentfacebook/react

[DevTools] [Context] Legacy Context

 import typeof ReactTestRenderer from 'react-test-renderer'; import type {GetInspectedElementPath} from 'react-devtools-shared/src/devtools/views/Components/InspectedElementContext'; import type {FrontendBridge} from 'react-devtools-shared/src/bridge'; import type Store from 'react-devtools-shared/src/devtools/store';+import React, {Component, createContext} from 'react';+import {Fragment} from '../../../../../../../../../../Applications/WebStorm.app/Contents/plugins/JavaScriptLanguage/jsLanguageServicesImpl/flow/react';

Freakin' WebStorm 😆 #NeverTrustYourEditor

hristo-kanchev

comment created time in 6 months

pull request commentfacebook/react

[DevTools] Support for adding props | Improved state/props value editing

  • New line characters (\n) are hidden from string renders (perhaps hidden characters should be shown but in a different color?) From what I can see \n characters are rendered. Or am I missing something? Screenshot 2019-09-08 at 15 15 37
  • Infinity is rendered as nothing
  • -Infinity is rendered as nothing
  • NaN is rendered as nothing With this new addition they will be rendered as null do we want to fix this in this PR, Brian? This is due to JSON.stringify.
  • empty string renders as (string) when "" is probably better With this PR they will be rendered as ""

Screenshot 2019-09-08 at 15 19 19

  • If strings are now in quotation marks perhaps it makes sense for these changes: (null) -> null and (undefined) -> undefined With this PR null will be rendered as null but undefined is indeed (undefined) Screenshot 2019-09-08 at 15 20 51

I think it's up to Brian to decide. I don't mind adding the support for this in this PR, but my own personal opinion is that the above unsolved issues should be in different issue.

What do you think @bvaughn ?

hristo-kanchev

comment created time in 6 months

push eventhristo-kanchev/react

Hristo Kanchev

commit sha 36c4905f031844de468faae06f307e0658dbf163

Removed unneeded fragment.

view details

push time in 6 months

PR opened facebook/react

Fixed font family issue in FF.

Fixes: #16464

It appears that we need to explicitly set the font-family for FF.

Screenshot: Screenshot 2019-09-07 at 19 30 13

+1 -0

0 comment

1 changed file

pr created time in 6 months

create barnchhristo-kanchev/react

branch : bugfix/firefox-tooltip-font-family

created branch time in 6 months

push eventhristo-kanchev/react

Dominic Gannaway

commit sha 46f912fd57604bd3c3949b5e8d6cc30a843ab1b9

[react-core] Add more support for experimental React Scope API (#16621)

view details

Heaven

commit sha 92f094d86d22afa77407a693681d7725e2540225

fix typo: oncurrent - concurrent (#16633)

view details

Hristo Kanchev

commit sha 77bb1023986225a12aaa1b45b85703df5deaf95a

[DevTools] [Profiler]: Save profile now working in Firefox (#16612) * Added anchor dom element in order to successfully download profiling data. * Reworked downloadFile to accept a DOMElement in order for FF to successfully download profiling data. * Prettify downloadFile changes.

view details

Brian Vaughn

commit sha f705e2bac7582b2114f381f14546ff6ca02436b9

Updated pending CHANGELOG for DevTools

view details

Dominic Gannaway

commit sha af032764a9f244633eb7ff1a3205d2ec6073b501

[react-events] Adds preventKeys support to Keyboard responder (#16642)

view details

Dominic Gannaway

commit sha 539640d89f327743f2872098ec8aad08ab3a4dfd

[react-events] Various core tweaks for event responder system (#16654)

view details

Dominic Gannaway

commit sha 7126a37bf4284a30377e08b2ef84f61b64fdb8cd

[react-events] Keyboard responder propagation handling (#16657)

view details

Dominic Gannaway

commit sha 9ff60ff16b289a9efce46e21fe223aec1638b5d6

[react-events] Fix Scope listener issue (#16658)

view details

Dominic Gannaway

commit sha c66edb9f8b6baba71df4c21908829f805e57c0b1

[react-events] Refactor getCurrentTarget to getResponderNode (#16660)

view details

Dominic Gannaway

commit sha e86146e714bb98e973404350069915bf2760a1bd

[react-events] Refine executeUserEventHandler (#16662)

view details

Nicolas Gallagher

commit sha 9ce8711d5a7c84e71587c75d2935966023ee6dbb

[react-events] Tap responder (#16628) This is a partial replacement for the 'Press' responder: 1. `useTap` is scoped to pointers (no keyboard support). Our current thinking is that "responders" should be limited to working with pointers, and that they can be combined with 'useKeyboard' in user-space. For example, we might create a 'usePress' hook in user-space that combines 'useTap' with 'useKeyboard' to react to both pointers and keyboard interactions. 2. `useTap` cancels the gesture once the pointer moves over an element that is not within the responder target's subtree. This differs from `usePress` (and React Native), where the gesture remains active after the pointer exits the target's subtree and is restarted once the pointer reenters. One of the drawbacks with the `usePress` behavior is that it requires repeatedly measuring DOM elements (which can cause jank) to perform hit region tests. `useTap` avoids doing this and relies on `document.elementFromPoint` only to support the TouchEvent fallbacks. 3. `useTap` calls `onTapUpdate` when the active gesture's state changes, `onTapEnd` when the gesture successfully completes. and `onTapCancel` when it fails. There is no `onTap` callback. `usePress` did not explicitly report back when the gesture failed, and product developers were confused about the difference between `onPress` and `onPressEnd`. 4. `useTap` explicitly separates the PointerEvent implementation from the MouseEvent/TouchEvent fallback. 5. `useTap` has better unit test coverage . All pointer types and the fallback environment are tested. The shape of the gesture state object is also defined and tested.

view details

Sebastian Markbåge

commit sha 8d7c733f1fdad55d0f10947931b378edc5e039ad

[Partial Hydration] Don't invoke listeners on parent of dehydrated event target (#16591) * Don't invoke listeners on parent of dehydrated event target * Move Suspense boundary check to getClosestInstanceFromNode Now getClosestInstanceFromNode can return either a host component, host text component or suspense component when the suspense component is dehydrated. We then use that to ignore events on a suspense component. * Attach the HostRoot fiber to the DOM container This lets us detect if an event happens on this root's subtree before it has rendered something. * Add todo The approach of checking isFiberMounted answers if we might be in an in-progress hydration but it doesn't answer which root or boundary might be in-progress so we don't know what to wait for. This needs some refactoring. * Refactor isFiberMountedImpl to getNearestMountedFiber We'll need the nearest boundary for event replaying so this prepares for that. This surfaced an issue that we attach Hydrating tag on the root but normally this (and Placement) is attached on the child. This surfaced an issue that this can lead to both Placement and Hydrating effects which is not supported so we need to ensure that we only ever use one or the other. * Add todo for bug I spotted * Cache tags * Check the ContainerInstanceKey before the InstanceKey The container is inside the instance, so we must find it before the instance, since otherwise we'll miss it.

view details

Luna Ruan

commit sha 79e46b67784623f42186f69baa233e5854a8408f

updated flags from false to dicated on www (#16647)

view details

Brian Vaughn

commit sha d96f478f8a79da3125f6842c16efbc2ae8bcd3bf

use-subscription tearing fix (#16623) * Add (failing) subscription tearing test and bugfix * Added more inline comments to test * Simplified tearing test case slightly

view details

Dan Abramov

commit sha 040ca0fad7296fcc1fb9a01ebdb169fb32e1bc32

Enable MessageLoop implementation by default (#16408)

view details

Nicolas Gallagher

commit sha ff006451ad792ed26793691402bf7b5f813205f7

[react-events] Fix isTargetWithinNode type (#16671) isTargetWithinNode passes the childTarget to getClosestInstanceFromNode which does not account for a null value of 'node'.

view details

Dan Abramov

commit sha 962dfc2c33710b880d90ba8db4f531040077d48e

Remove experimental scheduler flags (#16672)

view details

Sebastian Markbåge

commit sha e11bf42ceac5bb5ef0d7c98d0d075048c94352dd

Check for Suspense boundary in a root Container (#16673) If we find a Container that might mean that we're on a node that is inside a Suspense boundary that is directly inside the Container root. Imagine the div is a Container and the span is a dehydrated instance: ``` <div> <!--$--> <span /> <!--/$--> </div> ``` There's no way to tests this yet since I'm not actually utilizing the return value yet. The solution is to just use the same path to check for a Suspense boundary as if we find a parent instance.

view details

Heaven

commit sha 61836fba2a5446c25aa223d2a8b3939cc90c6d03

Fix typo: wnless -> unless (#16680)

view details

Alex Rohleder

commit sha 206d61f72214e8ae5b935f0bf8628491cb7f0797

fix typos on react-devtools comments (#16681)

view details

push time in 6 months

push eventhristo-kanchev/react

Hristo Kanchev

commit sha c61c8f7880c3acdff5528cf88f11a3ff179d88b6

Fixed flow error.

view details

push time in 6 months

Pull request review commentfacebook/react

[DevTools] Support for adding props | Improved state/props value editing

 export default function EditableValue({        const {key} = event; -      if (key === 'Enter') {-        if (dataType === 'number') {-          const parsedValue = parseFloat(editableValue);-          if (!Number.isNaN(parsedValue)) {-            overrideValueFn(path, parsedValue);-          }-        } else {-          overrideValueFn(path, editableValue);+      if (key === 'Enter' && isValid) {+        const parsedEditableValue = JSON.parse(sanitizeForParse(editableValue));++        if (value !== parsedEditableValue) {+          overrideValueFn(path, parsedEditableValue);         }          // Don't reset the pending change flag here.         // The inspected fiber won't be updated until after the next "inspectElement" message.         // We'll reset that flag during a subsequent render.       } else if (key === 'Escape') {-        setEditableValue(value);+        setEditableValue(stringifiedValue);         setHasPendingChanges(false);+        setIsValid(true);       }     },-    [editableValue, dataType, overrideValueFn, path, value],+    [editableValue, isValid, dataType, overrideValueFn, path, value],   ); -  // Render different input types based on the dataType-  let type = 'text';-  if (dataType === 'boolean') {-    type = 'checkbox';-  } else if (dataType === 'number') {-    type = 'number';-  }--  let inputValue = value == null ? '' : value;+  let inputValue = value === undefined ? '' : stringifiedValue;   if (hasPendingChanges) {-    inputValue = editableValue == null ? '' : editableValue;+    inputValue = editableValue;   }    let placeholder = '';-  if (value === null) {-    placeholder = '(null)';-  } else if (value === undefined) {+  if (value === undefined) {     placeholder = '(undefined)';-  } else if (dataType === 'string') {-    placeholder = '(string)';+  } else {+    placeholder = 'Enter valid JSON';   }    return (     <Fragment>       {dataType === 'boolean' && (         <label className={styles.CheckboxLabel}>           <input-            checked={inputValue}+            checked={inputValue === 'true'}

inputValue is now the stringifiedVersion of value. That's why we need to make this check.

hristo-kanchev

comment created time in 6 months

Pull request review commentfacebook/react

[DevTools] Support for adding props | Improved state/props value editing

 export default function EditableValue({        const {key} = event; -      if (key === 'Enter') {-        if (dataType === 'number') {-          const parsedValue = parseFloat(editableValue);-          if (!Number.isNaN(parsedValue)) {-            overrideValueFn(path, parsedValue);-          }-        } else {-          overrideValueFn(path, editableValue);+      if (key === 'Enter' && isValid) {+        const parsedEditableValue = JSON.parse(sanitizeForParse(editableValue));++        if (value !== parsedEditableValue) {+          overrideValueFn(path, parsedEditableValue);         }          // Don't reset the pending change flag here.         // The inspected fiber won't be updated until after the next "inspectElement" message.         // We'll reset that flag during a subsequent render.       } else if (key === 'Escape') {-        setEditableValue(value);+        setEditableValue(stringifiedValue);         setHasPendingChanges(false);+        setIsValid(true);       }     },-    [editableValue, dataType, overrideValueFn, path, value],+    [editableValue, isValid, dataType, overrideValueFn, path, value],   ); -  // Render different input types based on the dataType-  let type = 'text';-  if (dataType === 'boolean') {-    type = 'checkbox';-  } else if (dataType === 'number') {-    type = 'number';-  }--  let inputValue = value == null ? '' : value;+  let inputValue = value === undefined ? '' : stringifiedValue;   if (hasPendingChanges) {-    inputValue = editableValue == null ? '' : editableValue;+    inputValue = editableValue;   }    let placeholder = '';-  if (value === null) {-    placeholder = '(null)';-  } else if (value === undefined) {+  if (value === undefined) {     placeholder = '(undefined)';-  } else if (dataType === 'string') {-    placeholder = '(string)';+  } else {+    placeholder = 'Enter valid JSON';

I think it would be good to have this placeholder for non undefined values. What do you think @bvaughn ?

hristo-kanchev

comment created time in 6 months

Pull request review commentfacebook/react

[DevTools] Support for adding props | Improved state/props value editing

 export default function EditableValue({        const {key} = event; -      if (key === 'Enter') {-        if (dataType === 'number') {-          const parsedValue = parseFloat(editableValue);-          if (!Number.isNaN(parsedValue)) {-            overrideValueFn(path, parsedValue);-          }-        } else {-          overrideValueFn(path, editableValue);+      if (key === 'Enter' && isValid) {+        const parsedEditableValue = JSON.parse(sanitizeForParse(editableValue));++        if (value !== parsedEditableValue) {+          overrideValueFn(path, parsedEditableValue);         }          // Don't reset the pending change flag here.         // The inspected fiber won't be updated until after the next "inspectElement" message.         // We'll reset that flag during a subsequent render.       } else if (key === 'Escape') {-        setEditableValue(value);+        setEditableValue(stringifiedValue);         setHasPendingChanges(false);+        setIsValid(true);       }     },-    [editableValue, dataType, overrideValueFn, path, value],+    [editableValue, isValid, dataType, overrideValueFn, path, value],   ); -  // Render different input types based on the dataType-  let type = 'text';-  if (dataType === 'boolean') {-    type = 'checkbox';-  } else if (dataType === 'number') {

We don't need this anymore. Now we have the ability to change the value from a number to an array for example.

hristo-kanchev

comment created time in 6 months

Pull request review commentfacebook/react

[DevTools] Support for adding props | Improved state/props value editing

 export default function EditableValue({   path,   value, }: EditableValueProps) {+  const [isValid, setIsValid] = useState(true);   const [hasPendingChanges, setHasPendingChanges] = useState(false);-  const [editableValue, setEditableValue] = useState(value);+  const [stringifiedValue, setStringifiedValue] = useState(+    JSON.stringify(value),+  );+  const [editableValue, setEditableValue] = useState(stringifiedValue);   const inputRef = useRef<HTMLInputElement | null>(null); -  if (hasPendingChanges && editableValue === value) {+  useEffect(

If the value changes we need to update the stringified version of it.

hristo-kanchev

comment created time in 6 months

PR opened facebook/react

[DevTools] Support for adding props | Improved state/props value editing

Solves:

  • #16484
  • #16476

As both issues are highly overlapping, @bvaughn and I decided to submit the fix for both in one PR.

Changes:

  • Extracted sanitizeForParse to the utils file as it's used in multiple places
  • Added new component - EditableKey
  • Added support for adding additional entries (currently only enabled for prop)
  • Fixed the issue with locking values by type.
  • String values are now surrounded by quotes.

Screenshots:

Adding new props props-1 props-2 props-3


Overwriting an existing prop value props-4


Changing data type - null -> array props-5

+237 -54

0 comment

9 changed files

pr created time in 6 months

create barnchhristo-kanchev/react

branch : feature/add-edit-entries

created branch time in 6 months

more