docs: update to next 15 + eslint 9 (#9839)

* update next

* updated react

* update eslint

* finish updating eslint

* fix content lint errors

* fix docs test

* fix vale action

* fix installation errors
This commit is contained in:
Shahed Nasser
2024-11-13 17:03:17 +02:00
committed by GitHub
parent 6f7467f071
commit 938f3bd934
143 changed files with 4193 additions and 3226 deletions
@@ -297,7 +297,7 @@ export const AiAssistant = () => {
}
}, [loading, answer, thread, lastAnswerIndex, inputRef.current])
useResizeObserver(contentRef, () => {
useResizeObserver(contentRef as React.RefObject<HTMLDivElement>, () => {
if (!loading) {
return
}
@@ -85,8 +85,8 @@ export const ApiRunnerParamArrayInput = ({
Array.isArray(prev[0])
? [...prev[0]]
: typeof prev[0] === "object"
? Object.assign({}, prev[0])
: prev[0],
? Object.assign({}, prev[0])
: prev[0],
])
}}
className="mt-0.5"
@@ -94,8 +94,8 @@ export const ApiRunnerParamInput = ({
typeof paramValue === "string"
? (paramValue as string)
: typeof paramValue === "number"
? (paramValue as number)
: `${paramValue}`
? (paramValue as number)
: `${paramValue}`
}
className="w-full"
/>
@@ -163,8 +163,8 @@ export const ApiRunner = React.forwardRef<HTMLDivElement, ApiRunnerProps>(
!responseCode
? "red"
: responseCode.startsWith("2")
? "green"
: "red"
? "green"
: "red"
}
/>
)}
@@ -33,18 +33,18 @@ export const Breadcrumbs = () => {
item.parentItem?.type === "link"
? getLinkPath(item.parentItem)
: (item.parentItem?.type === "category" &&
breadcrumbOptions?.showCategories) ||
item.parentItem?.type === "sub-category"
? "#"
: undefined
breadcrumbOptions?.showCategories) ||
item.parentItem?.type === "sub-category"
? "#"
: undefined
const firstItemPath =
item.default[0].type === "link"
? getLinkPath(item.default[0])
: (item.default[0].type === "category" &&
breadcrumbOptions?.showCategories) ||
item.default[0].type === "sub-category"
? "#"
: undefined
breadcrumbOptions?.showCategories) ||
item.default[0].type === "sub-category"
? "#"
: undefined
const breadcrumbPath = parentPath || firstItemPath || "/"
@@ -1,7 +1,7 @@
"use client"
import React, { useMemo } from "react"
import { Card, CardList, MDXComponents, useSidebar } from "../.."
import { Card, CardList, H2, useSidebar } from "../.."
import { InteractiveSidebarItem, SidebarItem, SidebarItemLink } from "types"
import slugify from "slugify"
@@ -27,8 +27,8 @@ export const ChildDocs = ({
return showItems !== undefined
? "show"
: hideItems.length > 0
? "hide"
: "all"
? "hide"
: "all"
}, [showItems, hideItems])
const filterCondition = (item: SidebarItem): boolean => {
@@ -132,12 +132,12 @@ export const ChildDocs = ({
childItem.type === "link"
? childItem.path
: childItem.children?.length
? (
childItem.children.find(
(item) => item.type === "link"
) as SidebarItemLink
)?.path
: "#"
? (
childItem.children.find(
(item) => item.type === "link"
) as SidebarItemLink
)?.path
: "#"
return {
title: childItem.title,
href,
@@ -151,9 +151,7 @@ export const ChildDocs = ({
const getAllLevelsElms = (items?: SidebarItem[]) =>
filterNonInteractiveItems(items).map((item, key) => {
const itemChildren = getChildrenForLevel(item)
const HeadingComponent = itemChildren?.length
? MDXComponents["h2"]
: undefined
const HeadingComponent = itemChildren?.length ? H2 : undefined
return (
<React.Fragment key={key}>
@@ -1,6 +1,4 @@
"use client"
import React, { useMemo } from "react"
import React from "react"
import { CollapsibleReturn } from "../../../../hooks"
export type CodeBlockCollapsibleLinesProps = {
@@ -12,18 +10,13 @@ export const CodeBlockCollapsibleLines = ({
children,
type,
collapsed,
getCollapsibleElms,
}: CodeBlockCollapsibleLinesProps) => {
const shownChildren: React.ReactNode = useMemo(() => {
const isStart = type === "start"
return (
<>
{collapsed && Array.isArray(children)
? children.slice(isStart ? -2 : 0, isStart ? undefined : 2)
: children}
</>
)
}, [children, collapsed])
return getCollapsibleElms(shownChildren)
const isStart = type === "start"
return (
<>
{collapsed && Array.isArray(children)
? children.slice(isStart ? -2 : 0, isStart ? undefined : 2)
: children}
</>
)
}
@@ -8,6 +8,7 @@ import { useColorMode } from "@/providers"
import { CodeBlockHeader, CodeBlockHeaderMeta } from "./Header"
import { CodeBlockLine } from "./Line"
import { ApiAuthType, ApiDataOptions, ApiMethod } from "types"
// @ts-expect-error can't install the types package because it doesn't support React v19
import { CSSTransition } from "react-transition-group"
import { useCollapsibleCodeLines } from "../.."
import { HighlightProps as CollapsibleHighlightProps } from "@/hooks"
@@ -16,6 +16,7 @@ import { CodeBlockHeaderWrapper } from "../CodeBlock/Header/Wrapper"
type CodeTab = BaseTabType & {
codeProps: CodeBlockProps
codeBlock: React.ReactNode
children?: React.ReactNode
}
type CodeTabProps = {
@@ -33,36 +34,72 @@ export const CodeTabs = ({
blockStyle = "loud",
}: CodeTabProps) => {
const { colorMode } = useColorMode()
const isCodeBlock = (
node: React.ReactNode
): node is
| React.ReactElement<unknown, string | React.JSXElementConstructor<any>>
| React.ReactPortal => {
if (!React.isValidElement(node)) {
return false
}
if (node.type === "pre") {
return true
}
const typedProps = node.props as Record<string, unknown>
return "source" in typedProps
}
const tabs: CodeTab[] = useMemo(() => {
const tempTabs: CodeTab[] = []
Children.forEach(children, (child) => {
if (!React.isValidElement(child)) {
return
}
const typedChildProps = child.props as CodeTab
if (
!React.isValidElement(child) ||
!child.props.label ||
!child.props.value ||
!React.isValidElement(child.props.children)
!typedChildProps.label ||
!typedChildProps.value ||
!React.isValidElement(typedChildProps.children)
) {
return
}
// extract child code block
const codeBlock =
child.props.children.type === "pre" &&
React.isValidElement(child.props.children.props.children)
? child.props.children.props.children
: child.props.children
const codeBlock: React.ReactNode = isCodeBlock(typedChildProps.children)
? typedChildProps.children
: undefined
if (!codeBlock) {
return
}
const codeBlockProps = codeBlock.props as CodeBlockProps
tempTabs.push({
label: child.props.label,
value: child.props.value,
codeProps: codeBlock.props,
label: typedChildProps.label,
value: typedChildProps.value,
codeProps: codeBlockProps,
codeBlock: {
...codeBlock,
props: {
...codeBlock.props,
badgeLabel: undefined,
hasTabs: true,
className: clsx("!my-0", codeBlock.props.className),
...codeBlockProps,
children: {
...(typeof codeBlockProps.children === "object"
? codeBlockProps.children
: {}),
props: {
...(React.isValidElement(codeBlockProps.children)
? (codeBlockProps.children.props as Record<string, unknown>)
: {}),
badgeLabel: undefined,
hasTabs: true,
className: clsx("!my-0", codeBlockProps.className),
},
},
},
},
})
@@ -188,7 +225,7 @@ export const CodeTabs = ({
return (
<child.type
{...child.props}
{...(typeof child.props === "object" ? child.props : {})}
changeSelectedTab={changeSelectedTab}
pushRef={(tabButton: HTMLButtonElement | null) =>
tabRefs.push(tabButton)
@@ -197,7 +234,7 @@ export const CodeTabs = ({
isSelected={
!selectedTab
? index === 0
: selectedTab.value === child.props.value
: selectedTab.value === (child.props as CodeTab).value
}
/>
)
@@ -34,7 +34,7 @@ export const DetailsSummary = ({
expandable && "cursor-pointer",
!expandable &&
"border-medusa-border-base border-y border-solid border-x-0",
(expandable || badge) && "gap-0.5",
(expandable || badge !== undefined) && "gap-0.5",
"no-marker",
className
)}
@@ -3,7 +3,7 @@
import React, { Suspense, cloneElement, useRef, useState } from "react"
import { Loading } from "@/components"
import clsx from "clsx"
import { DetailsSummary } from "./Summary"
import { DetailsSummary, DetailsSummaryProps } from "./Summary"
import { useCollapsible } from "../../hooks"
export type DetailsProps = {
@@ -22,12 +22,14 @@ export const Details = ({
...props
}: DetailsProps) => {
const [open, setOpen] = useState(openInitial)
const ref = useRef<HTMLDetailsElement>(null)
const childrenWrapperRef = useRef<HTMLDivElement>(null)
const { getCollapsibleElms, setCollapsed } = useCollapsible({
initialValue: !openInitial,
heightAnimation,
onClose: () => setOpen(false),
childrenRef: childrenWrapperRef,
})
const ref = useRef<HTMLDetailsElement>(null)
const handleToggle = (e: React.MouseEvent<HTMLElement>) => {
const targetElm = e.target as HTMLElement
@@ -77,13 +79,19 @@ export const Details = ({
/>
)}
{summaryElm &&
cloneElement(summaryElm as React.ReactElement, {
open,
onClick: handleToggle,
})}
cloneElement<DetailsSummaryProps>(
summaryElm as React.ReactElement<
DetailsSummaryProps,
React.FunctionComponent<DetailsSummaryProps>
>,
{
open,
onClick: handleToggle,
}
)}
{getCollapsibleElms(
<Suspense fallback={<Loading className="!mb-docs_2 !mt-0" />}>
{children}
<div ref={childrenWrapperRef}>{children}</div>
</Suspense>
)}
</details>
@@ -1,6 +1,7 @@
"use client"
import React, { useRef, useState } from "react"
// @ts-expect-error can't install the types package because it doesn't support React v19
import { CSSTransition, SwitchTransition } from "react-transition-group"
import { Solutions } from "./Solutions"
import { ExtraData, useAnalytics } from "@/providers/Analytics"
@@ -65,11 +66,11 @@ export const Feedback = ({
const [medusaVersion, setMedusaVersion] = useState("")
const [errorFix, setErrorFix] = useState("")
const [contactInfo, setContactInfo] = useState("")
const nodeRef: React.RefObject<HTMLDivElement> = submittedFeedback
const nodeRef = submittedFeedback
? inlineMessageRef
: showForm
? inlineQuestionRef
: inlineFeedbackRef
? inlineQuestionRef
: inlineFeedbackRef
const { loaded, track } = useAnalytics()
function handleFeedback(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) {
@@ -132,12 +133,12 @@ export const Feedback = ({
showForm
? "show_form"
: !submittedFeedback
? "feedback"
: "submitted_feedback"
? "feedback"
: "submitted_feedback"
}
nodeRef={nodeRef}
timeout={300}
addEndListener={(done) => {
addEndListener={(done: () => void) => {
nodeRef.current?.addEventListener("transitionend", done, false)
}}
classNames={{
@@ -7,7 +7,7 @@ import { useIsBrowser } from "../../../providers"
type H2Props = React.HTMLAttributes<HTMLHeadingElement> & {
id?: string
passRef?: React.RefObject<HTMLHeadingElement>
passRef?: React.RefObject<HTMLHeadingElement | null>
}
export const H2 = ({ className, children, passRef, ...props }: H2Props) => {
@@ -32,7 +32,7 @@ export const LearningPathFinish = ({
)}
{type === "custom" && (
<span className="text-compact-small text-medusa-fg-subtle">
{step.descriptionJSX}
{step.descriptionJSX as React.ReactNode}
</span>
)}
</>
@@ -5,6 +5,7 @@ import clsx from "clsx"
import { IconCircleDottedLine } from "@/components/Icons"
import { CheckCircleSolid, CircleMiniSolid, ListBullet } from "@medusajs/icons"
import { Badge, Button, Link } from "@/components"
// @ts-expect-error can't install the types package because it doesn't support React v19
import { CSSTransition, SwitchTransition } from "react-transition-group"
type LearningPathStepsProps = {
@@ -17,7 +18,7 @@ export const LearningPathSteps = ({ ...rest }: LearningPathStepsProps) => {
const [collapsed, setCollapsed] = useState(false)
const stepsRef = useRef<HTMLDivElement>(null)
const buttonRef = useRef<HTMLButtonElement>(null)
const nodeRef: React.RefObject<HTMLElement> = collapsed ? buttonRef : stepsRef
const nodeRef = collapsed ? buttonRef : stepsRef
const handleScroll = useCallback(() => {
if (window.scrollY > 100 && !collapsed) {
@@ -51,7 +52,7 @@ export const LearningPathSteps = ({ ...rest }: LearningPathStepsProps) => {
key={collapsed ? "show_path" : "show_button"}
nodeRef={nodeRef}
timeout={300}
addEndListener={(done) => {
addEndListener={(done: () => void) => {
nodeRef.current?.addEventListener("transitionend", done, false)
}}
classNames={{
@@ -120,7 +121,8 @@ export const LearningPathSteps = ({ ...rest }: LearningPathStepsProps) => {
"text-medium text-ui-fg-subtle mt-docs_1"
)}
>
{step.descriptionJSX ?? step.description}
{(step.descriptionJSX as React.ReactNode) ??
step.description}
</div>
</div>
)}
@@ -23,7 +23,7 @@ import { MenuItem } from "types"
export const MainNavDesktopMenu = () => {
const [isOpen, setIsOpen] = useState(false)
const { setDesktopSidebarOpen, isSidebarShown } = useSidebar()
const ref = useRef(null)
const ref = useRef<HTMLDivElement>(null)
useClickOutside({
elmRef: ref,
@@ -5,6 +5,7 @@ import { Button } from "../../Button"
import { ArrowUturnLeft, BarsThree, XMark } from "@medusajs/icons"
import clsx from "clsx"
import { MenuItem } from "types"
// @ts-expect-error can't install the types package because it doesn't support React v19
import { CSSTransition, SwitchTransition } from "react-transition-group"
import { MainNavMobileMainMenu } from "./Main"
import { MainNavMobileSubMenu } from "./SubMenu"
@@ -1,15 +1,13 @@
import React from "react"
import ReactMarkdown from "react-markdown"
import { ReactMarkdownOptions } from "react-markdown/lib/react-markdown"
import ReactMarkdown, {
Options as ReactMarkdownOptions,
Components,
} from "react-markdown"
import { MDXComponents, Link } from "@/components"
import clsx from "clsx"
import { NormalComponents } from "react-markdown/lib/complex-types"
import { SpecialComponents } from "react-markdown/lib/ast-to-react"
export type MarkdownContentProps = ReactMarkdownOptions & {
components?: Partial<
Omit<NormalComponents, keyof SpecialComponents> & SpecialComponents
>
components?: Partial<Components> | null | undefined
}
export const MarkdownContent = ({
@@ -18,6 +16,7 @@ export const MarkdownContent = ({
...props
}: MarkdownContentProps) => {
return (
// @ts-expect-error React v19 doesn't see this type as a React element
<ReactMarkdown
components={
components || {
@@ -65,8 +65,8 @@ export const MermaidDiagram = ({ diagramContent }: MermaidDiagramProps) => {
isZoomed
? `100vh`
: matchedRegex && matchedRegex.length >= 1
? `${matchedRegex[1]}px`
: "100%"
? `${matchedRegex[1]}px`
: "100%"
}
/>
</ControlledZoom>
@@ -22,9 +22,7 @@ export const ModalFooter = ({
className
)}
>
{actions?.map((action, index) => (
<Button {...action} key={index} />
))}
{actions?.map((action, index) => <Button {...action} key={index} />)}
{children}
</div>
)
@@ -18,16 +18,26 @@ export type NotificationItemProps = {
closeButtonText?: string
} & React.HTMLAttributes<HTMLDivElement>
export const NotificationItem = ({
className = "",
placement = "bottom",
show = true,
layout = "default",
setShow,
onClose,
children,
...rest
}: NotificationItemProps) => {
type EmptyLayoutProps = {
onClose?: () => void
}
export const NotificationItem = React.forwardRef<
HTMLDivElement,
NotificationItemProps
>(function NotificationItem(
{
className = "",
placement = "bottom",
show = true,
layout = "default",
setShow,
onClose,
children,
...rest
},
ref
) {
const handleClose = () => {
setShow?.(false)
onClose?.()
@@ -44,6 +54,7 @@ export const NotificationItem = ({
!show && "!opacity-0",
className
)}
ref={ref}
>
{layout === "default" && (
<NotificationItemLayoutDefault {...rest} handleClose={handleClose}>
@@ -53,11 +64,17 @@ export const NotificationItem = ({
{layout === "empty" &&
Children.map(children, (child) => {
if (child) {
return React.cloneElement(child, {
onClose: handleClose,
})
return React.cloneElement<EmptyLayoutProps>(
child as React.ReactElement<
EmptyLayoutProps,
React.FunctionComponent<EmptyLayoutProps>
>,
{
onClose: handleClose,
}
)
}
})}
</div>
)
}
})
@@ -1,10 +1,13 @@
"use client"
import {
NotificationContextType,
NotificationItemType,
useNotifications,
} from "@/providers"
import React from "react"
import React, { useEffect, useRef } from "react"
import { NotificationItem } from "./Item"
// @ts-expect-error can't install the types package because it doesn't support React v19
import { CSSTransition, TransitionGroup } from "react-transition-group"
import clsx from "clsx"
@@ -12,6 +15,15 @@ export const NotificationContainer = () => {
const { notifications, removeNotification } =
useNotifications() as NotificationContextType
const notificationRefs = useRef([])
useEffect(() => {
notificationRefs.current = notificationRefs.current.slice(
0,
notifications.length
)
}, [notifications])
const handleClose = (notification: NotificationItemType) => {
notification.onClose?.()
if (notification.id) {
@@ -33,7 +45,7 @@ export const NotificationContainer = () => {
className
)}
>
{notifications.filter(condition).map((notification) => (
{notifications.filter(condition).map((notification, index) => (
<CSSTransition
key={notification.id}
timeout={200}
@@ -41,10 +53,12 @@ export const NotificationContainer = () => {
enter: "animate-slideInRight animate-fast",
exit: "animate-slideOutRight animate-fast",
}}
nodeRef={notificationRefs.current[index]}
>
<NotificationItem
{...notification}
onClose={() => handleClose(notification)}
ref={notificationRefs.current[index]}
className={clsx(
notification.className,
"!relative !top-0 !bottom-0 !right-0"
@@ -73,6 +73,7 @@ export const SearchHitsWrapper = ({
<div className="h-full overflow-auto px-docs_0.5">
{status !== "loading" && showNoResults && <SearchNoResult />}
{indices.map((indexName, index) => (
// @ts-expect-error React v19 doesn't see this type as a React element
<Index indexName={indexName} key={index}>
<SearchHits
indexName={indexName}
@@ -177,6 +178,7 @@ export const SearchHits = ({
"max-w-full"
)}
>
{/* @ts-expect-error React v19 doesn't see this type as a React element */}
<Snippet
attribute={[
"hierarchy",
@@ -192,6 +194,7 @@ export const SearchHits = ({
</span>
{item.type !== "lvl1" && (
<span className="text-compact-small text-medusa-fg-subtle">
{/* @ts-expect-error React v19 doesn't see this type as a React element */}
<Snippet
attribute={
item.content
@@ -94,6 +94,7 @@ export const Search = ({
className="px-docs_1 pt-docs_1 bg-medusa-bg-base z-10"
/>
)}
{/* @ts-expect-error React v19 doesn't see this type as a React element */}
<InstantSearch
indexName={algolia.mainIndexName}
searchClient={searchClient}
@@ -102,6 +103,7 @@ export const Search = ({
}}
>
<div className={clsx("bg-medusa-bg-base flex z-[1]")}>
{/* @ts-expect-error React v19 doesn't see this type as a React element */}
<SearchBox
classNames={{
root: clsx(
@@ -128,7 +130,7 @@ export const Search = ({
)}
placeholder="Find something..."
autoFocus
formRef={searchBoxRef}
formRef={searchBoxRef as React.RefObject<HTMLFormElement>}
loadingIconComponent={() => <SpinnerLoading />}
/>
</div>
@@ -108,7 +108,7 @@ export const SelectBadge = ({
isValueSelected={isValueSelected}
handleSelectAll={handleSelectAll}
handleChange={handleChange}
parentRef={ref}
parentRef={ref as React.RefObject<HTMLDivElement>}
passedRef={dropdownRef}
setSelectedValues={setSelectedValues}
/>
@@ -115,7 +115,7 @@ export const SelectInput = ({
isValueSelected={isValueSelected}
handleSelectAll={handleSelectAll}
handleChange={handleChange}
parentRef={ref}
parentRef={ref as React.RefObject<HTMLDivElement>}
passedRef={dropdownRef}
/>
</div>
@@ -5,6 +5,7 @@ import { useSidebar } from "@/providers"
import clsx from "clsx"
import { Loading } from "@/components"
import { SidebarItem } from "./Item"
// @ts-expect-error can't install the types package because it doesn't support React v19
import { CSSTransition, SwitchTransition } from "react-transition-group"
import { SidebarTop, SidebarTopProps } from "./Top"
import { useClickOutside, useKeyboardShortcut } from "@/hooks"
@@ -55,7 +56,7 @@ export const Sidebar = ({
[items, currentItems]
)
useResizeObserver(sidebarTopRef, () => {
useResizeObserver(sidebarTopRef as React.RefObject<HTMLElement>, () => {
setSidebarTopHeight(sidebarTopRef.current?.clientHeight || 0)
})
@@ -139,8 +140,8 @@ export const Sidebar = ({
item.type === "separator"
? index
: item.type === "link"
? `${item.path}-${index}`
: `${item.title}-${index}`
? `${item.path}-${index}`
: `${item.title}-${index}`
return (
<Suspense
fallback={
@@ -104,7 +104,9 @@ export const WorkflowDiagramCanvas = ({
>
<div className="relative size-full overflow-hidden object-contain rounded-docs_DEFAULT shadow-elevation-card-rest">
<div>
{/* @ts-expect-error React v19 doesn't see this type as a React element */}
<motion.div
// @ts-expect-error React v19 isn't recognizing accepted props
onMouseDown={() => setIsDragging(true)}
onMouseUp={() => setIsDragging(false)}
drag
@@ -108,8 +108,8 @@ export const useActiveOnScroll = ({
const halfway = isElmWindow(scrollableElement)
? scrollableElement.innerHeight / 2
: scrollableElement
? scrollableElement.scrollHeight / 2
: 0
? scrollableElement.scrollHeight / 2
: 0
headings?.forEach((heading) => {
if (heading.id === hash) {
@@ -145,12 +145,12 @@ export const useActiveOnScroll = ({
chosenClosest
? (chosenClosest as HTMLHeadingElement).id
: selectedHeadingByHash
? (selectedHeadingByHash as HTMLHeadingElement).id
: items.length
? useDefaultIfNoActive
? items[0].heading.id
: ""
: ""
? (selectedHeadingByHash as HTMLHeadingElement).id
: items.length
? useDefaultIfNoActive
? items[0].heading.id
: ""
: ""
)
}, [getHeadingsInElm, items, enable])
@@ -4,7 +4,7 @@ import React, { useCallback, useEffect } from "react"
import { useIsBrowser } from "../.."
export type UseClickOutsideProps = {
elmRef: React.RefObject<HTMLElement>
elmRef: React.RefObject<HTMLElement | null>
onClickOutside: (e: MouseEvent) => void
}
@@ -7,7 +7,7 @@ import {
TokenInputProps,
TokenOutputProps,
} from "prism-react-renderer"
import React, { useCallback, useMemo } from "react"
import React, { useCallback, useMemo, useRef } from "react"
import { CodeBlockCollapsibleLines } from "../../components/CodeBlock/Collapsible/Lines"
import { useCollapsible } from "../use-collapsible"
@@ -22,7 +22,7 @@ export type CollapsibleCodeLines = {
token: Token[][],
highlightProps: HighlightProps,
lineNumberOffset?: number
) => React.ReactNode
) => React.JSX.Element[]
}
export type CollapsedCodeLinesPosition = "start" | "end"
@@ -65,10 +65,12 @@ export const useCollapsibleCodeLines = ({
return collapsedRange.start === 1 ? "start" : "end"
}, [collapsedRange])
const ref = useRef(null)
const collapsibleHookResult = useCollapsible({
unmountOnExit: false,
translateEnabled: false,
heightAnimation: true,
childrenRef: ref,
})
const getCollapsedLinesElm = useCallback(
@@ -1,6 +1,7 @@
"use client"
import React, { useState } from "react"
// @ts-expect-error can't install the types package because it doesn't support React v19
import { CSSTransition } from "react-transition-group"
export type CollapsibleProps = {
@@ -9,6 +10,7 @@ export type CollapsibleProps = {
translateEnabled?: boolean
onClose?: () => void
unmountOnExit?: boolean
childrenRef?: React.RefObject<HTMLElement | null>
}
export type CollapsibleReturn = {
@@ -23,59 +25,95 @@ export const useCollapsible = ({
translateEnabled = true,
onClose,
unmountOnExit = true,
childrenRef,
}: CollapsibleProps): CollapsibleReturn => {
const [collapsed, setCollapsed] = useState(initialValue)
const getCollapsibleElms = (children: React.ReactNode) => (
<CSSTransition
unmountOnExit={unmountOnExit}
in={!collapsed}
timeout={150}
onEnter={(node: HTMLElement) => {
if (heightAnimation) {
node.classList.add("transition-[height]")
node.style.height = `0px`
} else {
node.classList.add("!mb-docs_2", "!mt-0")
if (translateEnabled) {
node.classList.add("translate-y-docs_1", "transition-transform")
const getNodeFromChildrenRef = () => {
return (
(childrenRef?.current?.firstElementChild as HTMLElement) ||
childrenRef?.current
)
}
const getCollapsibleElms = (children: React.ReactNode) => {
return (
<CSSTransition
unmountOnExit={unmountOnExit}
in={!collapsed}
timeout={150}
nodeRef={childrenRef}
onEnter={() => {
const node = getNodeFromChildrenRef()
if (!node) {
return
}
}
}}
onEntering={(node: HTMLElement) => {
if (heightAnimation) {
node.style.height = `${node.scrollHeight}px`
}
}}
onEntered={(node: HTMLElement) => {
if (heightAnimation) {
node.style.height = `auto`
}
}}
onExit={(node: HTMLElement) => {
if (heightAnimation) {
node.style.height = `${node.scrollHeight}px`
} else {
if (translateEnabled) {
node.classList.add("transition-transform", "!-translate-y-docs_1")
if (heightAnimation) {
node.classList.add("transition-[height]")
node.style.height = `0px`
} else {
node.classList.add("!mb-docs_2", "!mt-0")
if (translateEnabled) {
node.classList.add("translate-y-docs_1", "transition-transform")
}
}
setTimeout(() => {
onClose?.()
}, 100)
}
}}
onExiting={(node: HTMLElement) => {
if (heightAnimation) {
node.style.height = `0px`
setTimeout(() => {
onClose?.()
}, 100)
}
}}
>
{children}
</CSSTransition>
)
}}
onEntering={() => {
const node = getNodeFromChildrenRef()
if (!node) {
return
}
if (heightAnimation) {
node.style.height = `${node.scrollHeight}px`
}
}}
onEntered={() => {
const node = getNodeFromChildrenRef()
if (!node) {
return
}
if (heightAnimation) {
node.style.height = `auto`
}
}}
onExit={() => {
const node = getNodeFromChildrenRef()
if (!node) {
return
}
if (heightAnimation) {
node.style.height = `${node.scrollHeight}px`
} else {
if (translateEnabled) {
node.classList.add("transition-transform", "!-translate-y-docs_1")
}
setTimeout(() => {
onClose?.()
}, 100)
}
}}
onExiting={() => {
const node = getNodeFromChildrenRef()
if (!node) {
return
}
if (heightAnimation) {
node.style.height = `0px`
setTimeout(() => {
onClose?.()
}, 100)
}
}}
>
{children}
</CSSTransition>
)
}
return {
getCollapsibleElms,
@@ -18,11 +18,7 @@ export const usePageScrollManager = () => {
.map((nav) => (nav as PerformanceNavigationTiming).type)
.includes("reload")
useEffect(() => {
if (!scrollableElement || !checkedPageReload) {
return
}
const tryToScroll = () => {
if (getScrolledTop(scrollableElement) !== 0 && !location.hash) {
scrollableElement?.scrollTo({
top: 0,
@@ -36,7 +32,13 @@ export const usePageScrollManager = () => {
targetElm?.scrollIntoView()
}
}, [pathname, scrollableElement, checkedPageReload])
}
useEffect(() => {
if (checkedPageReload) {
setCheckedPageReload(false)
}
}, [pathname])
useEffect(() => {
if (!scrollableElement || checkedPageReload) {
@@ -49,8 +51,12 @@ export const usePageScrollManager = () => {
scrollableElement?.scrollTo({
top: parseInt(loadedScrollPosition),
})
localStorage.removeItem("scrollPos")
} else {
tryToScroll()
}
localStorage.removeItem("scrollPos")
} else {
tryToScroll()
}
setCheckedPageReload(true)
@@ -45,7 +45,11 @@ export const useRequestRunner = ({
})
.then((data) => {
const stringifiedData = JSON.stringify(data, undefined, 2)
replaceLog ? replaceLog(stringifiedData) : pushLog(stringifiedData)
if (replaceLog) {
replaceLog(stringifiedData)
} else {
pushLog(stringifiedData)
}
})
.catch((error) => {
pushLog(`\nAn error ocurred: ${JSON.stringify(error, undefined, 2)}`)
@@ -39,7 +39,7 @@ export function useEvent<T extends EventFunc>(callback: T): T {
* Gets `value` from the last render.
*/
export function usePrevious<T>(value: T): T | undefined {
const ref = useRef<T>()
const ref = useRef<T>(undefined)
useLayoutEffect(() => {
ref.current = value
@@ -96,10 +96,10 @@ function useScrollControllerContextValue({
parentTop !== undefined
? parentTop
: isElmWindow(scrollableElement)
? 0
: scrollableElement instanceof HTMLElement
? scrollableElement.offsetTop
: 0
? 0
: scrollableElement instanceof HTMLElement
? scrollableElement.offsetTop
: 0
scrollableElement?.scrollTo({
// 56 is the height of the navbar
@@ -137,7 +137,7 @@ export function ScrollControllerProvider({
children: ReactNode
scrollableSelector?: string
restoreScrollOnReload?: boolean
}): JSX.Element {
}) {
const value = useScrollControllerContextValue({
scrollableSelector,
})
@@ -63,9 +63,11 @@ export const useSelect = ({
const handleChange = (selectedValue: string, wasSelected: boolean) => {
if (multiple) {
wasSelected
? removeSelected?.(selectedValue)
: addSelected?.(selectedValue)
if (wasSelected) {
removeSelected?.(selectedValue)
} else {
addSelected?.(selectedValue)
}
} else {
setSelected?.(selectedValue)
}
@@ -3,6 +3,7 @@
import React, { createContext, useContext } from "react"
import { useAnalytics } from "@/providers"
import { AiAssistant } from "@/components"
// @ts-expect-error can't install the types package because it doesn't support React v19
import ReCAPTCHA from "react-google-recaptcha"
export type AiAssistantFeedbackType = "upvote" | "downvote"
@@ -18,6 +18,7 @@ import {
SearchResponse,
} from "algoliasearch/lite"
import clsx from "clsx"
// @ts-expect-error can't install the types package because it doesn't support React v19
import { CSSTransition, SwitchTransition } from "react-transition-group"
export type SearchCommand = {
@@ -208,6 +209,8 @@ export const SearchProvider = ({
}
}, [initialDefaultFilters])
const componentWrapperRef = useRef(null)
return (
<SearchContext.Provider
value={{
@@ -248,13 +251,14 @@ export const SearchProvider = ({
}}
timeout={250}
key={command?.name || "search"}
nodeRef={componentWrapperRef}
>
<>
<div ref={componentWrapperRef} className="h-full">
{command === null && (
<Search {...searchProps} algolia={algolia} />
)}
{command?.component}
</>
</div>
</CSSTransition>
</SwitchTransition>
</Modal>
@@ -53,7 +53,7 @@ export type SidebarContextType = {
setDesktopSidebarOpen: React.Dispatch<React.SetStateAction<boolean>>
staticSidebarItems?: boolean
shouldHandleHashChange: boolean
sidebarRef: React.RefObject<HTMLDivElement>
sidebarRef: React.RefObject<HTMLDivElement | null>
goBack: () => void
sidebarTopHeight: number
setSidebarTopHeight: React.Dispatch<React.SetStateAction<number>>
@@ -247,8 +247,8 @@ export const reducer = (
loaded: parent.changeLoaded
? true
: i.type === "link"
? i.loaded
: true,
? i.loaded
: true,
}
}
return i