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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user