diff --git a/packages/react-devtools-shared/src/devtools/store.js b/packages/react-devtools-shared/src/devtools/store.js index 2631893a543..6ddaedb7981 100644 --- a/packages/react-devtools-shared/src/devtools/store.js +++ b/packages/react-devtools-shared/src/devtools/store.js @@ -189,6 +189,8 @@ export default class Store extends EventEmitter<{ {errorCount: number, warningCount: number}, > = new Map(); + _focusedTransition: 0 | Element['id'] = 0; + // At least one of the injected renderers contains (DEV only) owner metadata. _hasOwnerMetadata: boolean = false; @@ -935,10 +937,9 @@ export default class Store extends EventEmitter<{ } /** - * @param rootID * @param uniqueSuspendersOnly Filters out boundaries without unique suspenders */ - getSuspendableDocumentOrderSuspense( + getSuspendableDocumentOrderSuspenseInitialPaint( uniqueSuspendersOnly: boolean, ): Array { const target: Array = []; @@ -990,6 +991,76 @@ export default class Store extends EventEmitter<{ return target; } + _pushSuspenseChildrenInDocumentOrder( + children: Array, + target: Array, + ): void { + for (let i = 0; i < children.length; i++) { + const childID = children[i]; + const suspense = this.getSuspenseByID(childID); + if (suspense !== null) { + target.push(suspense.id); + } else { + const childElement = this.getElementByID(childID); + if (childElement !== null) { + this._pushSuspenseChildrenInDocumentOrder( + childElement.children, + target, + ); + } + } + } + } + + getSuspenseChildren(id: Element['id']): Array { + const transitionChildren: Array = []; + + const root = this._idToElement.get(id); + if (root === undefined) { + return transitionChildren; + } + + this._pushSuspenseChildrenInDocumentOrder( + root.children, + transitionChildren, + ); + + return transitionChildren; + } + + /** + * @param uniqueSuspendersOnly Filters out boundaries without unique suspenders + */ + getSuspendableDocumentOrderSuspenseTransition( + uniqueSuspendersOnly: boolean, + ): Array { + const target: Array = []; + const focusedTransitionID = this._focusedTransition; + if (focusedTransitionID === null) { + return target; + } + + target.push({ + id: focusedTransitionID, + // TODO: Get environment for Activity + environment: null, + endTime: 0, + }); + + const transitionChildren = this.getSuspenseChildren(focusedTransitionID); + + this.pushTimelineStepsInDocumentOrder( + transitionChildren, + target, + uniqueSuspendersOnly, + // TODO: Get environment for Activity + [], + 0, // Don't pass a minimum end time at the root. The root is always first so doesn't matter. + ); + + return target; + } + pushTimelineStepsInDocumentOrder( children: Array, target: Array, @@ -1045,7 +1116,14 @@ export default class Store extends EventEmitter<{ uniqueSuspendersOnly: boolean, ): $ReadOnlyArray { const timeline = - this.getSuspendableDocumentOrderSuspense(uniqueSuspendersOnly); + this._focusedTransition === 0 + ? this.getSuspendableDocumentOrderSuspenseInitialPaint( + uniqueSuspendersOnly, + ) + : this.getSuspendableDocumentOrderSuspenseTransition( + uniqueSuspendersOnly, + ); + if (timeline.length === 0) { return timeline; } @@ -1058,6 +1136,33 @@ export default class Store extends EventEmitter<{ return timeline; } + getActivities(): Array<{id: Element['id'], depth: number}> { + const target: Array<{id: Element['id'], depth: number}> = []; + // TODO: Keep a live tree in the backend so we don't need to recalculate + // this each time while also including filtered Activities. + this._pushActivitiesInDocumentOrder(this.roots, target, 0); + return target; + } + + _pushActivitiesInDocumentOrder( + children: $ReadOnlyArray, + target: Array<{id: Element['id'], depth: number}>, + depth: number, + ): void { + for (let i = 0; i < children.length; i++) { + const child = this._idToElement.get(children[i]); + if (child === undefined) { + continue; + } + if (child.type === ElementTypeActivity && child.nameProp !== null) { + target.push({id: child.id, depth}); + this._pushActivitiesInDocumentOrder(child.children, target, depth + 1); + } else { + this._pushActivitiesInDocumentOrder(child.children, target, depth); + } + } + } + getRendererIDForElement(id: number): number | null { let current = this._idToElement.get(id); while (current !== undefined) { @@ -1244,7 +1349,7 @@ export default class Store extends EventEmitter<{ const removedElementIDs: Map = new Map(); const removedSuspenseIDs: Map = new Map(); - let nextActivitySliceID = null; + let nextActivitySliceID: Element['id'] | null = null; let i = 2; @@ -2119,6 +2224,10 @@ export default class Store extends EventEmitter<{ } } + if (nextActivitySliceID !== null) { + this._focusedTransition = nextActivitySliceID; + } + this.emit('mutated', [ addedElementIDs, removedElementIDs, diff --git a/packages/react-devtools-shared/src/devtools/views/Components/TreeContext.js b/packages/react-devtools-shared/src/devtools/views/Components/TreeContext.js index 4ad28c38935..2a1477ddb57 100644 --- a/packages/react-devtools-shared/src/devtools/views/Components/TreeContext.js +++ b/packages/react-devtools-shared/src/devtools/views/Components/TreeContext.js @@ -59,6 +59,7 @@ export type StateContext = { // Activity slice activityID: Element['id'] | null, + activities: $ReadOnlyArray<{id: Element['id'], depth: number}>, // Inspection element panel inspectedElementID: number | null, @@ -172,6 +173,7 @@ type State = { // Activity slice activityID: Element['id'] | null, + activities: $ReadOnlyArray<{id: Element['id'], depth: number}>, // Inspection element panel inspectedElementID: number | null, @@ -809,6 +811,7 @@ function reduceActivityState( case 'HANDLE_STORE_MUTATION': let {activityID} = state; const [, , activitySliceIDChange] = action.payload; + const activities = store.getActivities(); if (activitySliceIDChange === 0 && activityID !== null) { activityID = null; } else if ( @@ -817,10 +820,11 @@ function reduceActivityState( ) { activityID = activitySliceIDChange; } - if (activityID !== state.activityID) { + if (activityID !== state.activityID || activities !== state.activities) { return { ...state, activityID, + activities, }; } } @@ -863,6 +867,7 @@ function getInitialState({ // Activity slice activityID: null, + activities: store.getActivities(), // Inspection element panel inspectedElementID: diff --git a/packages/react-devtools-shared/src/devtools/views/SuspenseTab/ActivityList.css b/packages/react-devtools-shared/src/devtools/views/SuspenseTab/ActivityList.css index 0d1180b570c..4781f6899b8 100644 --- a/packages/react-devtools-shared/src/devtools/views/SuspenseTab/ActivityList.css +++ b/packages/react-devtools-shared/src/devtools/views/SuspenseTab/ActivityList.css @@ -1,20 +1,33 @@ -.ActivityList { +.ActivityListContaier { + display: flex; + flex-direction: column; +} + +.ActivityListHeader { + /* even if empty, provides layout alignment with the main view */ + display: flex; + flex: 0 0 42px; + border-bottom: 1px solid var(--color-border); +} + +.ActivityListList { cursor: default; list-style-type: none; margin: 0; padding: 0; } -.ActivityList[data-pending-activity-slice-selection="true"] { +.ActivityListList[data-pending-activity-slice-selection="true"] { cursor: wait; } -.ActivityList:focus { +.ActivityListList:focus { outline: none; } .ActivityListItem { color: var(--color-component-name); + line-height: var(--line-height-data); padding: 0 0.25rem; user-select: none; } @@ -27,7 +40,7 @@ background-color: var(--color-background-inactive); } -.ActivityList:focus .ActivityListItem[aria-selected="true"] { +.ActivityListList:focus .ActivityListItem[aria-selected="true"] { background-color: var(--color-background-selected); color: var(--color-text-selected); diff --git a/packages/react-devtools-shared/src/devtools/views/SuspenseTab/ActivityList.js b/packages/react-devtools-shared/src/devtools/views/SuspenseTab/ActivityList.js index 97218fbbe4c..3a6935b4d00 100644 --- a/packages/react-devtools-shared/src/devtools/views/SuspenseTab/ActivityList.js +++ b/packages/react-devtools-shared/src/devtools/views/SuspenseTab/ActivityList.js @@ -15,10 +15,14 @@ import typeof { SyntheticMouseEvent, SyntheticKeyboardEvent, } from 'react-dom-bindings/src/events/SyntheticEvent'; +import type Store from 'react-devtools-shared/src/devtools/store'; import * as React from 'react'; -import {useContext, useTransition} from 'react'; -import {ComponentFilterActivitySlice} from 'react-devtools-shared/src/frontend/types'; +import {useContext, useMemo, useTransition} from 'react'; +import { + ComponentFilterActivitySlice, + ElementTypeActivity, +} from 'react-devtools-shared/src/frontend/types'; import styles from './ActivityList.css'; import { TreeStateContext, @@ -26,6 +30,8 @@ import { } from '../Components/TreeContext'; import {useHighlightHostInstance} from '../hooks'; import {StoreContext} from '../context'; +import ButtonIcon from '../ButtonIcon'; +import Button from '../Button'; export function useChangeActivitySliceAction(): ( id: Element['id'] | null, @@ -62,15 +68,49 @@ export function useChangeActivitySliceAction(): ( return changeActivitySliceAction; } +function findNearestActivityParentID( + elementID: Element['id'], + store: Store, +): Element['id'] | null { + let currentID: null | Element['id'] = elementID; + while (currentID !== null) { + const element = store.getElementByID(currentID); + if (element === null) { + return null; + } + if (element.type === ElementTypeActivity) { + return element.id; + } + currentID = element.parentID; + } + + return currentID; +} + +function useSelectedActivityID(): Element['id'] | null { + const {inspectedElementID} = useContext(TreeStateContext); + const store = useContext(StoreContext); + return useMemo(() => { + if (inspectedElementID === null) { + return null; + } + const nearestActivityID = findNearestActivityParentID( + inspectedElementID, + store, + ); + return nearestActivityID; + }, [inspectedElementID, store]); +} + export default function ActivityList({ activities, }: { - activities: $ReadOnlyArray, + activities: $ReadOnlyArray<{id: Element['id'], depth: number}>, }): React$Node { - const {inspectedElementID} = useContext(TreeStateContext); + const {activityID, inspectedElementID} = useContext(TreeStateContext); const treeDispatch = useContext(TreeDispatcherContext); - // TODO: Derive from inspected element - const selectedActivityID = inspectedElementID; + const store = useContext(StoreContext); + const selectedActivityID = useSelectedActivityID(); const {highlightHostInstance, clearHighlightHostInstance} = useHighlightHostInstance(); @@ -79,8 +119,13 @@ export default function ActivityList({ const changeActivitySliceAction = useChangeActivitySliceAction(); function handleKeyDown(event: SyntheticKeyboardEvent) { - // TODO: Implement keyboard navigation switch (event.key) { + case 'Escape': + startActivitySliceSelection(() => { + changeActivitySliceAction(null); + }); + event.preventDefault(); + break; case 'Enter': case ' ': if (inspectedElementID !== null) { @@ -149,25 +194,61 @@ export default function ActivityList({ } return ( -
    - {activities.map(activity => ( -
  1. - {activity.nameProp} -
  2. - ))} -
+
+
+ {activityID !== null && ( + // TODO: Obsolete once filtered Activities are included in this list. + + )} +
+
    + {activities.map(({id, depth}) => { + const activity = store.getElementByID(id); + if (activity === null) { + return null; + } + const name = activity.nameProp; + if (name === null) { + // This shouldn't actually happen. We only want to show activities with a name. + // And hide the whole list if no named Activities are present. + return null; + } + + // TODO: Filtered Activities should have dedicated styles once we include + // filtered Activities in this list. + return ( +
  1. + {'\u00A0'.repeat(depth) + name} +
  2. + ); + })} +
+
); } diff --git a/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseBreadcrumbs.js b/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseBreadcrumbs.js index b27e0f59875..2ad235d5777 100644 --- a/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseBreadcrumbs.js +++ b/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseBreadcrumbs.js @@ -12,7 +12,10 @@ import typeof {SyntheticMouseEvent} from 'react-dom-bindings/src/events/Syntheti import * as React from 'react'; import {useContext} from 'react'; -import {TreeDispatcherContext} from '../Components/TreeContext'; +import { + TreeDispatcherContext, + TreeStateContext, +} from '../Components/TreeContext'; import {StoreContext} from '../context'; import {useHighlightHostInstance} from '../hooks'; import styles from './SuspenseBreadcrumbs.css'; @@ -23,6 +26,7 @@ import { export default function SuspenseBreadcrumbs(): React$Node { const store = useContext(StoreContext); + const {activityID} = useContext(TreeStateContext); const treeDispatch = useContext(TreeDispatcherContext); const suspenseTreeDispatch = useContext(SuspenseTreeDispatcherContext); const {selectedSuspenseID, lineage, roots} = useContext( @@ -42,8 +46,8 @@ export default function SuspenseBreadcrumbs(): React$Node {
    {lineage === null ? null : lineage.length === 0 ? ( // We selected the root. This means that we're currently viewing the Transition - // that rendered the whole screen. In laymans terms this is really "Initial Paint". - // TODO: Once we add subtree selection, then the equivalent should be called + // that rendered the whole screen. In laymans terms this is really "Initial Paint" . + // When we're looking at a subtree selection, then the equivalent is a // "Transition" since in that case it's really about a Transition within the page. roots.length > 0 ? (
  1. ) : null diff --git a/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseRects.js b/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseRects.js index f9ea6fd1f32..69d4767a489 100644 --- a/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseRects.js +++ b/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseRects.js @@ -9,6 +9,7 @@ import type Store from 'react-devtools-shared/src/devtools/store'; import type { + Element, SuspenseNode, Rect, } from 'react-devtools-shared/src/frontend/types'; @@ -18,7 +19,7 @@ import typeof { } from 'react-dom-bindings/src/events/SyntheticEvent'; import * as React from 'react'; -import {createContext, useContext, useLayoutEffect} from 'react'; +import {createContext, useContext, useLayoutEffect, useMemo} from 'react'; import { TreeDispatcherContext, TreeStateContext, @@ -426,6 +427,30 @@ function SuspenseRectsRoot({rootID}: {rootID: SuspenseNode['id']}): React$Node { }); } +function SuspenseRectsInitialPaint(): React$Node { + const {roots} = useContext(SuspenseTreeStateContext); + return roots.map(rootID => { + return ; + }); +} + +function SuspenseRectsTransition({id}: {id: Element['id']}): React$Node { + const store = useContext(StoreContext); + const children = useMemo(() => { + return store.getSuspenseChildren(id); + }, [id, store]); + + return children.map(suspenseID => { + return ( + + ); + }); +} + const ViewBox = createContext((null: any)); function SuspenseRectsContainer({ @@ -434,14 +459,25 @@ function SuspenseRectsContainer({ scaleRef: {current: number}, }): React$Node { const store = useContext(StoreContext); - const {inspectedElementID} = useContext(TreeStateContext); + const {activityID, inspectedElementID} = useContext(TreeStateContext); const treeDispatch = useContext(TreeDispatcherContext); const suspenseTreeDispatch = useContext(SuspenseTreeDispatcherContext); // TODO: This relies on a full re-render of all children when the Suspense tree changes. const {roots, timeline, hoveredTimelineIndex, uniqueSuspendersOnly} = useContext(SuspenseTreeStateContext); - // TODO: bbox does not consider uniqueSuspendersOnly filter + const activityChildren: $ReadOnlyArray | null = + useMemo(() => { + if (activityID === null) { + return null; + } + return store.getSuspenseChildren(activityID); + }, [activityID, store]); + const transitionChildren = + activityChildren === null ? roots : activityChildren; + + // We're using the bounding box of the entire document to anchor the Transition + // in the actual document. const boundingBox = getDocumentBoundingRect(store, roots); const boundingBoxWidth = boundingBox.width; @@ -456,14 +492,18 @@ function SuspenseRectsContainer({ // Already clicked on an inner rect return; } - if (roots.length === 0) { + if (transitionChildren.length === 0) { // Nothing to select return; } const arbitraryRootID = roots[0]; + const transitionRoot = activityID === null ? arbitraryRootID : activityID; event.preventDefault(); - treeDispatch({type: 'SELECT_ELEMENT_BY_ID', payload: arbitraryRootID}); + treeDispatch({ + type: 'SELECT_ELEMENT_BY_ID', + payload: transitionRoot, + }); suspenseTreeDispatch({ type: 'SET_SUSPENSE_LINEAGE', payload: arbitraryRootID, @@ -483,7 +523,8 @@ function SuspenseRectsContainer({ } const isRootSelected = roots.includes(inspectedElementID); - const isRootHovered = hoveredTimelineIndex === 0; + // When we're focusing a Transition, the first timeline step will not be a root. + const isRootHovered = activityID === null && hoveredTimelineIndex === 0; let hasRootSuspenders = false; if (!uniqueSuspendersOnly) { @@ -536,7 +577,13 @@ function SuspenseRectsContainer({
    - {roots.map(rootID => { - return ; - })} + {activityID === null ? ( + + ) : ( + + )} {selectedBoundingBox !== null ? ( void, onHoverLeave: () => void, }): React$Node { + const store = useContext(StoreContext); const inputRef = useRef(); function handleChange(event: SyntheticEvent) { const newValue = +event.currentTarget.value; @@ -60,12 +63,16 @@ export default function SuspenseScrubber({ } const steps = []; for (let index = min; index <= max; index++) { - const environment = timeline[index].environment; + const step = timeline[index]; + const environment = step.environment; + const element = store.getElementByID(step.id); const label = index === min ? // The first step in the timeline is always a Transition (Initial Paint). - 'Initial Paint' + - (environment === null ? '' : ' (' + environment + ')') + element === null || element.type === ElementTypeRoot + ? 'Initial Paint' + : 'Transition' + + (environment === null ? '' : ' (' + environment + ')') : // TODO: Consider adding the name of this specific boundary if this step has only one. environment === null ? 'Suspense' diff --git a/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseTab.css b/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseTab.css index 0dec577ea9a..0b1d85b1f48 100644 --- a/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseTab.css +++ b/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseTab.css @@ -92,7 +92,7 @@ } .ActivityList { - flex: 0 0 var(--horizontal-resize-tree-list-percentage); + flex: 0 0 var(--horizontal-resize-activity-list-percentage);; border-right: 1px solid var(--color-border); overflow: auto; } diff --git a/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseTab.js b/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseTab.js index f3929dec94c..36351f82bb8 100644 --- a/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseTab.js +++ b/packages/react-devtools-shared/src/devtools/views/SuspenseTab/SuspenseTab.js @@ -6,14 +6,11 @@ * * @flow */ -import type {Element} from 'react-devtools-shared/src/frontend/types'; - import * as React from 'react'; import { useContext, useEffect, useLayoutEffect, - useMemo, useReducer, useRef, Fragment, @@ -44,12 +41,13 @@ import typeof {SyntheticPointerEvent} from 'react-dom-bindings/src/events/Synthe import SettingsModal from 'react-devtools-shared/src/devtools/views/Settings/SettingsModal'; import SettingsModalContextToggle from 'react-devtools-shared/src/devtools/views/Settings/SettingsModalContextToggle'; import {SettingsModalContextController} from 'react-devtools-shared/src/devtools/views/Settings/SettingsModalContext'; +import {TreeStateContext} from '../Components/TreeContext'; type Orientation = 'horizontal' | 'vertical'; type LayoutActionType = - | 'ACTION_SET_TREE_LIST_TOGGLE' - | 'ACTION_SET_TREE_LIST_HORIZONTAL_FRACTION' + | 'ACTION_SET_ACTIVITY_LIST_TOGGLE' + | 'ACTION_SET_ACTIVITY_LIST_HORIZONTAL_FRACTION' | 'ACTION_SET_INSPECTED_ELEMENT_TOGGLE' | 'ACTION_SET_INSPECTED_ELEMENT_HORIZONTAL_FRACTION' | 'ACTION_SET_INSPECTED_ELEMENT_VERTICAL_FRACTION'; @@ -59,8 +57,8 @@ type LayoutAction = { }; type LayoutState = { - treeListHidden: boolean, - treeListHorizontalFraction: number, + activityListHidden: boolean, + activityListHorizontalFraction: number, inspectedElementHidden: boolean, inspectedElementHorizontalFraction: number, inspectedElementVerticalFraction: number, @@ -97,7 +95,7 @@ function ToggleUniqueSuspenders() { ); } -function ToggleTreeList({ +function ToggleActivityList({ dispatch, state, }: { @@ -108,13 +106,15 @@ function ToggleTreeList({ ); @@ -272,17 +272,6 @@ function SynchronizedScrollContainer({ ); } -// TODO: Get this from the store directly. -// The backend needs to keep a separate tree so that resuspending keeps Activity around. -function useActivities(): $ReadOnlyArray { - const activities = useMemo(() => { - const items: Array = []; - return items; - }, []); - - return activities; -} - function SuspenseTab(_: {}) { const store = useContext(StoreContext); const {hideSettings} = useContext(OptionsContext); @@ -292,14 +281,14 @@ function SuspenseTab(_: {}) { initLayoutState, ); - const activities = useActivities(); + const {activities} = useContext(TreeStateContext); // If there are no named Activity boundaries, we don't have any tree list and we should hide // both the panel and the button to toggle it. - const treeListDisabled = activities.length === 0; + const activityListDisabled = activities.length === 0; const wrapperTreeRef = useRef(null); const resizeTreeRef = useRef(null); - const resizeTreeListRef = useRef(null); + const resizeActivityListRef = useRef(null); // TODO: We'll show the recently inspected element in this tab when it should probably // switch to the nearest Suspense boundary when we switch into this tab. @@ -308,8 +297,8 @@ function SuspenseTab(_: {}) { inspectedElementHidden, inspectedElementHorizontalFraction, inspectedElementVerticalFraction, - treeListHidden, - treeListHorizontalFraction, + activityListHidden, + activityListHorizontalFraction, } = state; useLayoutEffect(() => { @@ -328,12 +317,12 @@ function SuspenseTab(_: {}) { inspectedElementVerticalFraction * 100, ); - const resizeTreeListElement = resizeTreeListRef.current; + const resizeActivityListElement = resizeActivityListRef.current; setResizeCSSVariable( - resizeTreeListElement, - 'tree-list', + resizeActivityListElement, + 'activity-list', 'horizontal', - treeListHorizontalFraction * 100, + activityListHorizontalFraction * 100, ); }, []); useEffect(() => { @@ -344,8 +333,8 @@ function SuspenseTab(_: {}) { inspectedElementHidden, inspectedElementHorizontalFraction, inspectedElementVerticalFraction, - treeListHidden, - treeListHorizontalFraction, + activityListHidden, + activityListHorizontalFraction, }), ); }, 500); @@ -355,8 +344,8 @@ function SuspenseTab(_: {}) { inspectedElementHidden, inspectedElementHorizontalFraction, inspectedElementVerticalFraction, - treeListHidden, - treeListHorizontalFraction, + activityListHidden, + activityListHorizontalFraction, ]); const onResizeStart = (event: SyntheticPointerEvent) => { @@ -420,14 +409,14 @@ function SuspenseTab(_: {}) { } }; - const onResizeTreeList = (event: SyntheticPointerEvent) => { + const onResizeActivityList = (event: SyntheticPointerEvent) => { const element = event.currentTarget; const isResizing = element.hasPointerCapture(event.pointerId); if (!isResizing) { return; } - const resizeElement = resizeTreeListRef.current; + const resizeElement = resizeActivityListRef.current; const wrapperElement = resizeTreeRef.current; if (wrapperElement === null || resizeElement === null) { @@ -443,11 +432,11 @@ function SuspenseTab(_: {}) { const currentMousePosition = orientation === 'horizontal' ? event.clientX - left : event.clientY - top; - const boundaryMin = MINIMUM_TREE_LIST_SIZE; + const boundaryMin = MINIMUM_ACTIVITY_LIST_SIZE; const boundaryMax = orientation === 'horizontal' - ? width - MINIMUM_TREE_LIST_SIZE - : height - MINIMUM_TREE_LIST_SIZE; + ? width - MINIMUM_ACTIVITY_LIST_SIZE + : height - MINIMUM_ACTIVITY_LIST_SIZE; const isMousePositionInBounds = currentMousePosition > boundaryMin && currentMousePosition < boundaryMax; @@ -455,10 +444,15 @@ function SuspenseTab(_: {}) { if (isMousePositionInBounds) { const resizedElementDimension = orientation === 'horizontal' ? width : height; - const actionType = 'ACTION_SET_TREE_LIST_HORIZONTAL_FRACTION'; + const actionType = 'ACTION_SET_ACTIVITY_LIST_HORIZONTAL_FRACTION'; const percentage = (currentMousePosition / resizedElementDimension) * 100; - setResizeCSSVariable(resizeElement, 'tree-list', orientation, percentage); + setResizeCSSVariable( + resizeElement, + 'activity-list', + orientation, + percentage, + ); dispatch({ type: actionType, @@ -473,19 +467,21 @@ function SuspenseTab(_: {}) {
    - {treeListDisabled ? null : ( + {activityListDisabled ? null : ( )} - {treeListDisabled ? null : ( -