From 8ff85a9a688bbdd680b5dcae1c6f2efd326d2ec0 Mon Sep 17 00:00:00 2001 From: Curry Yang <1019yanglu@gmail.com> Date: Wed, 27 Nov 2024 11:39:09 +0800 Subject: [PATCH] feat: scroll into view if needed --- packages/insomnia/src/ui/components/tabs/tab.tsx | 12 ++++++++++-- packages/insomnia/src/ui/components/tabs/tabList.tsx | 8 ++++++-- packages/insomnia/src/ui/routes/debug.tsx | 10 +++++++++- packages/insomnia/src/utils/index.ts | 6 ++++++ 4 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 packages/insomnia/src/utils/index.ts diff --git a/packages/insomnia/src/ui/components/tabs/tab.tsx b/packages/insomnia/src/ui/components/tabs/tab.tsx index 8d9a2c9fca..33bdc2edd8 100644 --- a/packages/insomnia/src/ui/components/tabs/tab.tsx +++ b/packages/insomnia/src/ui/components/tabs/tab.tsx @@ -1,6 +1,7 @@ -import React from 'react'; +import React, { useCallback } from 'react'; import { Button, GridListItem } from 'react-aria-components'; +import { scrollElementIntoView } from '../../../utils'; import { useInsomniaTabContext } from '../../context/app/insomnia-tab-context'; import { Icon } from '../icon'; import { Tooltip } from '../tooltip'; @@ -73,7 +74,7 @@ const WORKSPACE_TAB_UI_MAP: Record = { export const InsomniaTab = ({ tab }: { tab: BaseTab }) => { - const { closeTabById } = useInsomniaTabContext(); + const { closeTabById, currentOrgTabs } = useInsomniaTabContext(); const renderTabIcon = (type: TabEnum) => { if (WORKSPACE_TAB_UI_MAP[type]) { @@ -126,11 +127,18 @@ export const InsomniaTab = ({ tab }: { tab: BaseTab }) => { }); }; + const scrollIntoView = useCallback((node: HTMLDivElement) => { + if (node && currentOrgTabs.activeTabId === tab.id) { + scrollElementIntoView(node, { behavior: 'instant' }); + } + }, [currentOrgTabs.activeTabId, tab.id]); + return ( {({ isSelected, isHovered }) => ( diff --git a/packages/insomnia/src/ui/components/tabs/tabList.tsx b/packages/insomnia/src/ui/components/tabs/tabList.tsx index 4c1c69ddae..4bf87d7aae 100644 --- a/packages/insomnia/src/ui/components/tabs/tabList.tsx +++ b/packages/insomnia/src/ui/components/tabs/tabList.tsx @@ -1,4 +1,4 @@ -import _ from 'lodash'; +import _, { set } from 'lodash'; import React, { useCallback, useEffect, useState } from 'react'; import { Button, GridList, Menu, MenuItem, MenuTrigger, Popover, type Selection } from 'react-aria-components'; import { useFetcher, useNavigate } from 'react-router-dom'; @@ -188,14 +188,18 @@ export const OrganizationTabList = ({ showActiveStatus = true, currentPage = '' if (!tabListWrapperRef.current) { return; } + tabListWrapperRef.current.style.scrollBehavior = 'smooth'; tabListWrapperRef.current.scrollLeft -= 150; + tabListWrapperRef.current.style.scrollBehavior = 'auto'; }; const scrollRight = () => { if (!tabListWrapperRef.current) { return; } + tabListWrapperRef.current.style.scrollBehavior = 'smooth'; tabListWrapperRef.current.scrollLeft += 150; + tabListWrapperRef.current.style.scrollBehavior = 'auto'; }; useEffect(() => { @@ -254,7 +258,7 @@ export const OrganizationTabList = ({ showActiveStatus = true, currentPage = '' -
+
{ + if (isSelected && node) { + scrollElementIntoView(node, { behavior: 'instant' }); + } + }, [isSelected]); + return (
{ e.preventDefault(); setIsContextMenuOpen(true); diff --git a/packages/insomnia/src/utils/index.ts b/packages/insomnia/src/utils/index.ts new file mode 100644 index 0000000000..94b3ba88ed --- /dev/null +++ b/packages/insomnia/src/utils/index.ts @@ -0,0 +1,6 @@ +export const scrollElementIntoView = (element: HTMLElement, options?: ScrollIntoViewOptions) => { + if (element) { + // @ts-expect-error -- scrollIntoViewIfNeeded is not a standard method + element.scrollIntoViewIfNeeded ? element.scrollIntoViewIfNeeded() : element.scrollIntoView(options); + } +};