From ceeeca814cdd6017cb6cdc855a8200261fa85f9a Mon Sep 17 00:00:00 2001 From: FTCHD Date: Sat, 14 Sep 2024 21:21:31 +0300 Subject: [PATCH] [editor] Inspector Root and Section styling --- sdk/inspector/index.tsx | 85 +++++++++++++++++++++++++++++------------ 1 file changed, 60 insertions(+), 25 deletions(-) diff --git a/sdk/inspector/index.tsx b/sdk/inspector/index.tsx index 2408869e..965c107f 100644 --- a/sdk/inspector/index.tsx +++ b/sdk/inspector/index.tsx @@ -3,7 +3,7 @@ import { useScrollSection, useScrollSectionContext } from '@/components/editor/useScrollSection' import { cn } from '@/lib/shadcn' import {} from 'jotai' -import React, { type ReactElement, type ReactNode } from 'react' +import React, { useEffect, useMemo, useRef, type ReactElement, type ReactNode } from 'react' interface SectionProps { title: string @@ -16,48 +16,81 @@ function Section({ title, children, description }: SectionProps): ReactElement { return (
-

{title}

-
+
+

{title}

{description && (

{description}

)} - {children}
+ {children}
) } -interface RootProps { +function Root(props: { children: ReactNode -} - -function Root(props: RootProps): ReactElement { - const { currentSection } = useScrollSectionContext() +}): ReactElement { + const { currentSection } = useScrollSectionContext() + const sectionsContainerRef = useRef(null) const children = props.children as ReactElement | ReactElement[] - const validChildren = React.Children.map(children, (child) => { - if (child && React.isValidElement(child) && child.type === Section) { - return ( -
- {child} -
+ const validChildren = useMemo(() => { + return React.Children.map(children, (child) => { + if (child && React.isValidElement(child) && child.type === Section) { + return ( +
+ {child} +
+ ) + } + if (!child) { + return + } + throw new Error( + 'Configuration.Root only accepts Configuration.Section components as direct children' ) + }) + }, [children]) + + useEffect(() => { + if (sectionsContainerRef.current && currentSection) { + const container = sectionsContainerRef.current + const activeElement = container.querySelector(`a[href="#${currentSection}"]`) + + if (activeElement) { + const containerRect = container.getBoundingClientRect() + const activeElementRect = activeElement.getBoundingClientRect() + + const isFullyVisible = + activeElementRect.left >= containerRect.left && + activeElementRect.right <= containerRect.right + + if (!isFullyVisible) { + const scrollLeft = + activeElementRect.left - + containerRect.left + + container.scrollLeft - + (containerRect.width - activeElementRect.width) / 2 + container.scrollTo({ + left: scrollLeft, + behavior: 'smooth', + }) + } + } } - if (!child) { - return - } - throw new Error( - 'Configuration.Root only accepts Configuration.Section components as direct children' - ) - }) + }, [currentSection]) return (
{validChildren.length > 1 && ( -
+
{validChildren.map((child) => { const sectionId = child.props.id return ( @@ -65,7 +98,9 @@ function Root(props: RootProps): ReactElement { key={sectionId} href={`#${sectionId}`} className={cn( - 'whitespace-nowrap h-full border border-[#ffffff30] rounded-xl p-2 px-4 hover:border-[#ffffff90] text-[#ffffff90]', + 'border border-[#ffffff30] rounded-xl p-2 px-4 text-slate-300', + 'max-md:text-xs max-md:p-1 max-md:px-2', + 'hover:border-[#ffffff90]', currentSection === sectionId && 'text-white bg-border' )} > @@ -75,7 +110,7 @@ function Root(props: RootProps): ReactElement { })}
)} -
+
{validChildren}