diff --git a/README.md b/README.md
index fa2f0763..cbe9ff7a 100644
--- a/README.md
+++ b/README.md
@@ -70,11 +70,12 @@ npm install @devup-ui/vite-plugin
Next.js Build Time and Build Size (AMD Ryzen 9 9950X, 128GB RAM, Windows 11)
-| Library | Build Time | Build Size |
-|-----------|------------|--------------|
-| kuma-ui | 20.933s | 57,295,073b |
-| chakra-ui | 36.961s | 129,527,610b |
-| devup-ui | 15.162s | 48,047,678b |
+| Library | Version | Build Time | Build Size |
+|--------------|----------|------------|-----------------|
+| kuma-ui | 1.5.9 | 13.948s | 61,910,524b |
+| chakra-ui | 3.22.0 | 20.557s | 189,541,604b |
+| mui | 7.2.0 | 20.002s | 218,204,592b |
+| devup-ui | 1.0.10 | 10.583s | 53,111,181b |
## How it works
diff --git a/benchmark.js b/benchmark.js
index 7b1006c5..01f8a8ce 100644
--- a/benchmark.js
+++ b/benchmark.js
@@ -20,6 +20,11 @@ function clearBuildFile() {
recursive: true,
force: true,
})
+ if (existsSync('./benchmark/next-mui/.next'))
+ rmSync('./benchmark/next-mui/.next', {
+ recursive: true,
+ force: true,
+ })
if (existsSync('./benchmark/next-devup-ui/df'))
rmSync('./benchmark/next-devup-ui/df', {
recursive: true,
@@ -63,6 +68,13 @@ execSync('pnpm -F next-chakra-ui-benchmark build', {
console.timeEnd('chakra-ui')
console.info('chakra-ui', checkDirSize('./benchmark/next-chakra-ui/.next'))
+console.time('mui')
+execSync('pnpm -F next-mui-benchmark build', {
+ stdio: 'inherit',
+})
+console.timeEnd('mui')
+console.info('mui', checkDirSize('./benchmark/next-mui/.next'))
+
console.time('devup-ui')
execSync('pnpm -F next-devup-ui-benchmark build', {
stdio: 'inherit',
diff --git a/benchmark/next-mui/.gitignore b/benchmark/next-mui/.gitignore
new file mode 100644
index 00000000..5ef6a520
--- /dev/null
+++ b/benchmark/next-mui/.gitignore
@@ -0,0 +1,41 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.*
+.yarn/*
+!.yarn/patches
+!.yarn/plugins
+!.yarn/releases
+!.yarn/versions
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+.pnpm-debug.log*
+
+# env files (can opt-in for committing if needed)
+.env*
+
+# vercel
+.vercel
+
+# typescript
+*.tsbuildinfo
+next-env.d.ts
diff --git a/benchmark/next-mui/README.md b/benchmark/next-mui/README.md
new file mode 100644
index 00000000..665152ea
--- /dev/null
+++ b/benchmark/next-mui/README.md
@@ -0,0 +1 @@
+## Nextjs App
diff --git a/benchmark/next-mui/next.config.mjs b/benchmark/next-mui/next.config.mjs
new file mode 100644
index 00000000..7339eefb
--- /dev/null
+++ b/benchmark/next-mui/next.config.mjs
@@ -0,0 +1,5 @@
+export default {
+ experimental: {
+ optimizePackageImports: ['@chakra-ui/react'],
+ },
+}
diff --git a/benchmark/next-mui/package.json b/benchmark/next-mui/package.json
new file mode 100644
index 00000000..b35a3547
--- /dev/null
+++ b/benchmark/next-mui/package.json
@@ -0,0 +1,28 @@
+{
+ "name": "next-mui-benchmark",
+ "version": "0.1.0",
+ "type": "module",
+ "private": true,
+ "scripts": {
+ "dev": "next dev",
+ "build": "next build --experimental-debug-memory-usage",
+ "start": "next start",
+ "lint": "next lint"
+ },
+ "dependencies": {
+ "@emotion/react": "^11.14.0",
+ "@emotion/styled": "^11.14.1",
+ "@mui/material": "7.2.0",
+ "next": "^15.4.1",
+ "next-themes": "^0.4.6",
+ "react": "^19.1.0",
+ "react-dom": "^19.1.0",
+ "react-icons": "^5.5.0"
+ },
+ "devDependencies": {
+ "@types/node": "^24",
+ "@types/react": "^19",
+ "@types/react-dom": "^19",
+ "typescript": "^5"
+ }
+}
\ No newline at end of file
diff --git a/benchmark/next-mui/public/file.svg b/benchmark/next-mui/public/file.svg
new file mode 100644
index 00000000..004145cd
--- /dev/null
+++ b/benchmark/next-mui/public/file.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/benchmark/next-mui/public/globe.svg b/benchmark/next-mui/public/globe.svg
new file mode 100644
index 00000000..567f17b0
--- /dev/null
+++ b/benchmark/next-mui/public/globe.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/benchmark/next-mui/public/next.svg b/benchmark/next-mui/public/next.svg
new file mode 100644
index 00000000..5174b28c
--- /dev/null
+++ b/benchmark/next-mui/public/next.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/benchmark/next-mui/public/vercel.svg b/benchmark/next-mui/public/vercel.svg
new file mode 100644
index 00000000..77053960
--- /dev/null
+++ b/benchmark/next-mui/public/vercel.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/benchmark/next-mui/public/window.svg b/benchmark/next-mui/public/window.svg
new file mode 100644
index 00000000..b2b2a44f
--- /dev/null
+++ b/benchmark/next-mui/public/window.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/benchmark/next-mui/src/app/favicon.ico b/benchmark/next-mui/src/app/favicon.ico
new file mode 100644
index 00000000..718d6fea
Binary files /dev/null and b/benchmark/next-mui/src/app/favicon.ico differ
diff --git a/benchmark/next-mui/src/app/layout.tsx b/benchmark/next-mui/src/app/layout.tsx
new file mode 100644
index 00000000..5b39c286
--- /dev/null
+++ b/benchmark/next-mui/src/app/layout.tsx
@@ -0,0 +1,22 @@
+import type { Metadata } from 'next'
+
+import { Provider } from '../components/ui/provider'
+
+export const metadata: Metadata = {
+ title: 'Create Next App',
+ description: 'Generated by create next app',
+}
+
+export default function RootLayout({
+ children,
+}: Readonly<{
+ children: React.ReactNode
+}>) {
+ return (
+
+
+ {children}
+
+
+ )
+}
diff --git a/benchmark/next-mui/src/app/page.tsx b/benchmark/next-mui/src/app/page.tsx
new file mode 100644
index 00000000..f38bbc19
--- /dev/null
+++ b/benchmark/next-mui/src/app/page.tsx
@@ -0,0 +1,52 @@
+'use client'
+
+import { Box, Typography } from '@mui/material'
+import { useState } from 'react'
+
+export default function HomePage() {
+ const [color, setColor] = useState('yellow')
+ const [enabled, setEnabled] = useState(false)
+
+ return (
+
+
+ Track & field champions:
+
+
+ hello
+ hello
+
+
text
+
+ hello
+
+
hello
+
+
+ )
+}
diff --git a/benchmark/next-mui/src/components/ui/avatar.tsx b/benchmark/next-mui/src/components/ui/avatar.tsx
new file mode 100644
index 00000000..dae6074f
--- /dev/null
+++ b/benchmark/next-mui/src/components/ui/avatar.tsx
@@ -0,0 +1,74 @@
+'use client'
+
+import type { GroupProps, SlotRecipeProps } from '@chakra-ui/react'
+import { Avatar as ChakraAvatar, Group } from '@chakra-ui/react'
+import * as React from 'react'
+
+type ImageProps = React.ImgHTMLAttributes
+
+export interface AvatarProps extends ChakraAvatar.RootProps {
+ name?: string
+ src?: string
+ srcSet?: string
+ loading?: ImageProps['loading']
+ icon?: React.ReactElement
+ fallback?: React.ReactNode
+}
+
+export const Avatar = React.forwardRef(
+ function Avatar(props, ref) {
+ const { name, src, srcSet, loading, icon, fallback, children, ...rest } =
+ props
+ return (
+
+
+ {fallback}
+
+
+ {children}
+
+ )
+ },
+)
+
+interface AvatarFallbackProps extends ChakraAvatar.FallbackProps {
+ name?: string
+ icon?: React.ReactElement
+}
+
+const AvatarFallback = React.forwardRef(
+ function AvatarFallback(props, ref) {
+ const { name, icon, children, ...rest } = props
+ return (
+
+ {children}
+ {name != null && children == null && <>{getInitials(name)}>}
+ {name == null && children == null && (
+ {icon}
+ )}
+
+ )
+ },
+)
+
+function getInitials(name: string) {
+ const names = name.trim().split(' ')
+ const firstName = names[0] != null ? names[0] : ''
+ const lastName = names.length > 1 ? names[names.length - 1] : ''
+ return firstName && lastName
+ ? `${firstName.charAt(0)}${lastName.charAt(0)}`
+ : firstName.charAt(0)
+}
+
+interface AvatarGroupProps extends GroupProps, SlotRecipeProps<'avatar'> {}
+
+export const AvatarGroup = React.forwardRef(
+ function AvatarGroup(props, ref) {
+ const { size, variant, borderless, ...rest } = props
+ return (
+
+
+
+ )
+ },
+)
diff --git a/benchmark/next-mui/src/components/ui/button.tsx b/benchmark/next-mui/src/components/ui/button.tsx
new file mode 100644
index 00000000..1f64de87
--- /dev/null
+++ b/benchmark/next-mui/src/components/ui/button.tsx
@@ -0,0 +1,40 @@
+import type { ButtonProps as ChakraButtonProps } from '@chakra-ui/react'
+import {
+ AbsoluteCenter,
+ Button as ChakraButton,
+ Span,
+ Spinner,
+} from '@chakra-ui/react'
+import * as React from 'react'
+
+interface ButtonLoadingProps {
+ loading?: boolean
+ loadingText?: React.ReactNode
+}
+
+export interface ButtonProps extends ChakraButtonProps, ButtonLoadingProps {}
+
+export const Button = React.forwardRef(
+ function Button(props, ref) {
+ const { loading, disabled, loadingText, children, ...rest } = props
+ return (
+
+ {loading && !loadingText ? (
+ <>
+
+
+
+ {children}
+ >
+ ) : loading && loadingText ? (
+ <>
+
+ {loadingText}
+ >
+ ) : (
+ children
+ )}
+
+ )
+ },
+)
diff --git a/benchmark/next-mui/src/components/ui/checkbox.tsx b/benchmark/next-mui/src/components/ui/checkbox.tsx
new file mode 100644
index 00000000..966fa5e2
--- /dev/null
+++ b/benchmark/next-mui/src/components/ui/checkbox.tsx
@@ -0,0 +1,25 @@
+import { Checkbox as ChakraCheckbox } from '@chakra-ui/react'
+import * as React from 'react'
+
+export interface CheckboxProps extends ChakraCheckbox.RootProps {
+ icon?: React.ReactNode
+ inputProps?: React.InputHTMLAttributes
+ rootRef?: React.Ref
+}
+
+export const Checkbox = React.forwardRef(
+ function Checkbox(props, ref) {
+ const { icon, children, inputProps, rootRef, ...rest } = props
+ return (
+
+
+
+ {icon || }
+
+ {children != null && (
+ {children}
+ )}
+
+ )
+ },
+)
diff --git a/benchmark/next-mui/src/components/ui/close-button.tsx b/benchmark/next-mui/src/components/ui/close-button.tsx
new file mode 100644
index 00000000..d1740dde
--- /dev/null
+++ b/benchmark/next-mui/src/components/ui/close-button.tsx
@@ -0,0 +1,17 @@
+import type { ButtonProps } from '@chakra-ui/react'
+import { IconButton as ChakraIconButton } from '@chakra-ui/react'
+import * as React from 'react'
+import { LuX } from 'react-icons/lu'
+
+export type CloseButtonProps = ButtonProps
+
+export const CloseButton = React.forwardRef<
+ HTMLButtonElement,
+ CloseButtonProps
+>(function CloseButton(props, ref) {
+ return (
+
+ {props.children ?? }
+
+ )
+})
diff --git a/benchmark/next-mui/src/components/ui/color-mode.tsx b/benchmark/next-mui/src/components/ui/color-mode.tsx
new file mode 100644
index 00000000..09868064
--- /dev/null
+++ b/benchmark/next-mui/src/components/ui/color-mode.tsx
@@ -0,0 +1,62 @@
+'use client'
+
+import type { IconButtonProps } from '@chakra-ui/react'
+import { ClientOnly, IconButton, Skeleton } from '@chakra-ui/react'
+import type { ThemeProviderProps } from 'next-themes'
+import { ThemeProvider, useTheme } from 'next-themes'
+import * as React from 'react'
+import { LuMoon, LuSun } from 'react-icons/lu'
+
+export type ColorModeProviderProps = ThemeProviderProps
+
+export function ColorMode(props: ColorModeProviderProps) {
+ return (
+
+ )
+}
+
+export function useColorMode() {
+ const { resolvedTheme, setTheme } = useTheme()
+ const toggleColorMode = () => {
+ setTheme(resolvedTheme === 'light' ? 'dark' : 'light')
+ }
+ return {
+ colorMode: resolvedTheme,
+ setColorMode: setTheme,
+ toggleColorMode,
+ }
+}
+
+export function ColorModeIcon() {
+ const { colorMode } = useColorMode()
+ return colorMode === 'light' ? :
+}
+
+type ColorModeButtonProps = Omit
+
+export const ColorModeButton = React.forwardRef<
+ HTMLButtonElement,
+ ColorModeButtonProps
+>(function ColorModeButton(props, ref) {
+ const { toggleColorMode } = useColorMode()
+ return (
+ }>
+
+
+
+
+ )
+})
diff --git a/benchmark/next-mui/src/components/ui/dialog.tsx b/benchmark/next-mui/src/components/ui/dialog.tsx
new file mode 100644
index 00000000..4acb4988
--- /dev/null
+++ b/benchmark/next-mui/src/components/ui/dialog.tsx
@@ -0,0 +1,67 @@
+import { Dialog as ChakraDialog, Portal } from '@chakra-ui/react'
+import * as React from 'react'
+
+import { CloseButton } from './close-button'
+
+interface DialogContentProps extends ChakraDialog.ContentProps {
+ portalled?: boolean
+ portalRef?: React.RefObject
+ backdrop?: boolean
+}
+
+export const DialogContent = React.forwardRef<
+ HTMLDivElement,
+ DialogContentProps
+>(function DialogContent(props, ref) {
+ const {
+ children,
+ portalled = true,
+ portalRef,
+ backdrop = true,
+ ...rest
+ } = props
+
+ return (
+
+ {backdrop && }
+
+
+ {children}
+
+
+
+ )
+})
+
+export const DialogCloseTrigger = React.forwardRef<
+ HTMLButtonElement,
+ ChakraDialog.CloseTriggerProps
+>(function DialogCloseTrigger(props, ref) {
+ return (
+
+
+ {props.children}
+
+
+ )
+})
+
+export const DialogRoot = ChakraDialog.Root
+export const DialogFooter = ChakraDialog.Footer
+export const DialogHeader = ChakraDialog.Header
+export const DialogBody = ChakraDialog.Body
+export const DialogBackdrop = ChakraDialog.Backdrop
+export const DialogTitle = ChakraDialog.Title
+export const DialogDescription = ChakraDialog.Description
+export const DialogTrigger = ChakraDialog.Trigger
+export const DialogActionTrigger = ChakraDialog.ActionTrigger
+
+export function Dialog() {
+ return <>>
+}
diff --git a/benchmark/next-mui/src/components/ui/drawer.tsx b/benchmark/next-mui/src/components/ui/drawer.tsx
new file mode 100644
index 00000000..fac17981
--- /dev/null
+++ b/benchmark/next-mui/src/components/ui/drawer.tsx
@@ -0,0 +1,57 @@
+import { Drawer as ChakraDrawer, Portal } from '@chakra-ui/react'
+import * as React from 'react'
+
+import { CloseButton } from './close-button'
+
+interface DrawerContentProps extends ChakraDrawer.ContentProps {
+ portalled?: boolean
+ portalRef?: React.RefObject
+ offset?: ChakraDrawer.ContentProps['padding']
+}
+
+export const DrawerContent = React.forwardRef<
+ HTMLDivElement,
+ DrawerContentProps
+>(function DrawerContent(props, ref) {
+ const { children, portalled = true, portalRef, offset, ...rest } = props
+ return (
+
+
+
+ {children}
+
+
+
+ )
+})
+
+export const DrawerCloseTrigger = React.forwardRef<
+ HTMLButtonElement,
+ ChakraDrawer.CloseTriggerProps
+>(function DrawerCloseTrigger(props, ref) {
+ return (
+
+
+
+ )
+})
+
+export const DrawerTrigger = ChakraDrawer.Trigger
+export const DrawerRoot = ChakraDrawer.Root
+export const DrawerFooter = ChakraDrawer.Footer
+export const DrawerHeader = ChakraDrawer.Header
+export const DrawerBody = ChakraDrawer.Body
+export const DrawerBackdrop = ChakraDrawer.Backdrop
+export const DrawerDescription = ChakraDrawer.Description
+export const DrawerTitle = ChakraDrawer.Title
+export const DrawerActionTrigger = ChakraDrawer.ActionTrigger
+
+export function Drawer() {
+ return <>>
+}
diff --git a/benchmark/next-mui/src/components/ui/field.tsx b/benchmark/next-mui/src/components/ui/field.tsx
new file mode 100644
index 00000000..f99747be
--- /dev/null
+++ b/benchmark/next-mui/src/components/ui/field.tsx
@@ -0,0 +1,33 @@
+import { Field as ChakraField } from '@chakra-ui/react'
+import * as React from 'react'
+
+export interface FieldProps extends Omit {
+ label?: React.ReactNode
+ helperText?: React.ReactNode
+ errorText?: React.ReactNode
+ optionalText?: React.ReactNode
+}
+
+export const Field = React.forwardRef(
+ function Field(props, ref) {
+ const { label, children, helperText, errorText, optionalText, ...rest } =
+ props
+ return (
+
+ {label && (
+
+ {label}
+
+
+ )}
+ {children}
+ {helperText && (
+ {helperText}
+ )}
+ {errorText && (
+ {errorText}
+ )}
+
+ )
+ },
+)
diff --git a/benchmark/next-mui/src/components/ui/input-group.tsx b/benchmark/next-mui/src/components/ui/input-group.tsx
new file mode 100644
index 00000000..55bf0d18
--- /dev/null
+++ b/benchmark/next-mui/src/components/ui/input-group.tsx
@@ -0,0 +1,53 @@
+import type { BoxProps, InputElementProps } from '@chakra-ui/react'
+import { Group, InputElement } from '@chakra-ui/react'
+import * as React from 'react'
+
+export interface InputGroupProps extends BoxProps {
+ startElementProps?: InputElementProps
+ endElementProps?: InputElementProps
+ startElement?: React.ReactNode
+ endElement?: React.ReactNode
+ children: React.ReactElement
+ startOffset?: InputElementProps['paddingStart']
+ endOffset?: InputElementProps['paddingEnd']
+}
+
+export const InputGroup = React.forwardRef(
+ function InputGroup(props, ref) {
+ const {
+ startElement,
+ startElementProps,
+ endElement,
+ endElementProps,
+ children,
+ startOffset = '6px',
+ endOffset = '6px',
+ ...rest
+ } = props
+
+ const child =
+ React.Children.only>(children)
+
+ return (
+
+ {startElement && (
+
+ {startElement}
+
+ )}
+ {React.cloneElement(child, {
+ ...(startElement && {
+ ps: `calc(var(--input-height) - ${startOffset})`,
+ }),
+ ...(endElement && { pe: `calc(var(--input-height) - ${endOffset})` }),
+ ...children.props,
+ })}
+ {endElement && (
+
+ {endElement}
+
+ )}
+
+ )
+ },
+)
diff --git a/benchmark/next-mui/src/components/ui/popover.tsx b/benchmark/next-mui/src/components/ui/popover.tsx
new file mode 100644
index 00000000..8613b609
--- /dev/null
+++ b/benchmark/next-mui/src/components/ui/popover.tsx
@@ -0,0 +1,64 @@
+import { Popover as ChakraPopover, Portal } from '@chakra-ui/react'
+import * as React from 'react'
+
+import { CloseButton } from './close-button'
+
+interface PopoverContentProps extends ChakraPopover.ContentProps {
+ portalled?: boolean
+ portalRef?: React.RefObject
+}
+
+export const PopoverContent = React.forwardRef<
+ HTMLDivElement,
+ PopoverContentProps
+>(function PopoverContent(props, ref) {
+ const { portalled = true, portalRef, ...rest } = props
+ return (
+
+
+
+
+
+ )
+})
+
+export const PopoverArrow = React.forwardRef<
+ HTMLDivElement,
+ ChakraPopover.ArrowProps
+>(function PopoverArrow(props, ref) {
+ return (
+
+
+
+ )
+})
+
+export const PopoverCloseTrigger = React.forwardRef<
+ HTMLButtonElement,
+ ChakraPopover.CloseTriggerProps
+>(function PopoverCloseTrigger(props, ref) {
+ return (
+
+
+
+ )
+})
+
+export const PopoverTitle = ChakraPopover.Title
+export const PopoverDescription = ChakraPopover.Description
+export const PopoverFooter = ChakraPopover.Footer
+export const PopoverHeader = ChakraPopover.Header
+export const PopoverRoot = ChakraPopover.Root
+export const PopoverBody = ChakraPopover.Body
+export const PopoverTrigger = ChakraPopover.Trigger
+
+export function Popover() {
+ return <>>
+}
diff --git a/benchmark/next-mui/src/components/ui/provider.tsx b/benchmark/next-mui/src/components/ui/provider.tsx
new file mode 100644
index 00000000..6a918af4
--- /dev/null
+++ b/benchmark/next-mui/src/components/ui/provider.tsx
@@ -0,0 +1,13 @@
+'use client'
+
+import { ChakraProvider, defaultSystem } from '@chakra-ui/react'
+
+import { ColorMode, type ColorModeProviderProps } from './color-mode'
+
+export function Provider(props: ColorModeProviderProps) {
+ return (
+
+
+
+ )
+}
diff --git a/benchmark/next-mui/src/components/ui/radio.tsx b/benchmark/next-mui/src/components/ui/radio.tsx
new file mode 100644
index 00000000..c5d5c85b
--- /dev/null
+++ b/benchmark/next-mui/src/components/ui/radio.tsx
@@ -0,0 +1,24 @@
+import { RadioGroup as ChakraRadioGroup } from '@chakra-ui/react'
+import * as React from 'react'
+
+export interface RadioProps extends ChakraRadioGroup.ItemProps {
+ rootRef?: React.Ref
+ inputProps?: React.InputHTMLAttributes
+}
+
+export const Radio = React.forwardRef(
+ function Radio(props, ref) {
+ const { children, inputProps, rootRef, ...rest } = props
+ return (
+
+
+
+ {children && (
+ {children}
+ )}
+
+ )
+ },
+)
+
+export const RadioGroup = ChakraRadioGroup.Root
diff --git a/benchmark/next-mui/src/components/ui/slider.tsx b/benchmark/next-mui/src/components/ui/slider.tsx
new file mode 100644
index 00000000..113d1363
--- /dev/null
+++ b/benchmark/next-mui/src/components/ui/slider.tsx
@@ -0,0 +1,82 @@
+import { For, HStack, Slider as ChakraSlider } from '@chakra-ui/react'
+import * as React from 'react'
+
+export interface SliderProps extends ChakraSlider.RootProps {
+ marks?: Array
+ label?: React.ReactNode
+ showValue?: boolean
+}
+
+export const Slider = React.forwardRef(
+ function Slider(props, ref) {
+ const { marks: marksProp, label, showValue, ...rest } = props
+ const value = props.defaultValue ?? props.value
+
+ const marks = marksProp?.map((mark) => {
+ if (typeof mark === 'number') return { value: mark, label: undefined }
+ return mark
+ })
+
+ const hasMarkLabel = !!marks?.some((mark) => mark.label)
+
+ return (
+
+ {label && !showValue && (
+ {label}
+ )}
+ {label && showValue && (
+
+ {label}
+
+
+ )}
+
+
+
+
+
+
+
+
+ )
+ },
+)
+
+function SliderThumbs(props: { value?: number[] }) {
+ const { value } = props
+ return (
+
+ {(_, index) => (
+
+
+
+ )}
+
+ )
+}
+
+interface SliderMarksProps {
+ marks?: Array
+}
+
+const SliderMarks = React.forwardRef(
+ function SliderMarks(props, ref) {
+ const { marks } = props
+ if (!marks?.length) return null
+
+ return (
+
+ {marks.map((mark, index) => {
+ const value = typeof mark === 'number' ? mark : mark.value
+ const label = typeof mark === 'number' ? undefined : mark.label
+ return (
+
+
+ {label}
+
+ )
+ })}
+
+ )
+ },
+)
diff --git a/benchmark/next-mui/src/components/ui/tooltip.tsx b/benchmark/next-mui/src/components/ui/tooltip.tsx
new file mode 100644
index 00000000..1d91a73b
--- /dev/null
+++ b/benchmark/next-mui/src/components/ui/tooltip.tsx
@@ -0,0 +1,46 @@
+import { Portal, Tooltip as ChakraTooltip } from '@chakra-ui/react'
+import * as React from 'react'
+
+export interface TooltipProps extends ChakraTooltip.RootProps {
+ showArrow?: boolean
+ portalled?: boolean
+ portalRef?: React.RefObject
+ content: React.ReactNode
+ contentProps?: ChakraTooltip.ContentProps
+ disabled?: boolean
+}
+
+export const Tooltip = React.forwardRef(
+ function Tooltip(props, ref) {
+ const {
+ showArrow,
+ children,
+ disabled,
+ portalled,
+ content,
+ contentProps,
+ portalRef,
+ ...rest
+ } = props
+
+ if (disabled) return children
+
+ return (
+
+ {children}
+
+
+
+ {showArrow && (
+
+
+
+ )}
+ {content}
+
+
+
+
+ )
+ },
+)
diff --git a/benchmark/next-mui/tsconfig.json b/benchmark/next-mui/tsconfig.json
new file mode 100644
index 00000000..426d9c2d
--- /dev/null
+++ b/benchmark/next-mui/tsconfig.json
@@ -0,0 +1,41 @@
+{
+ "compilerOptions": {
+ "target": "ES2017",
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext"
+ ],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": true,
+ "noEmit": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "bundler",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve",
+ "incremental": true,
+ "plugins": [
+ {
+ "name": "next"
+ }
+ ],
+ "paths": {
+ "@/*": [
+ "./src/*"
+ ]
+ }
+ },
+ "include": [
+ "next-env.d.ts",
+ "**/*.ts",
+ "**/*.tsx",
+ ".next/types/**/*.ts",
+ "df/*.d.ts"
+ ],
+ "exclude": [
+ "node_modules"
+ ]
+}
\ No newline at end of file
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index b8d36340..7e6cf462 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -338,6 +338,46 @@ importers:
specifier: ^5
version: 5.8.3
+ benchmark/next-mui:
+ dependencies:
+ '@emotion/react':
+ specifier: ^11.14.0
+ version: 11.14.0(@types/react@19.1.8)(react@19.1.0)
+ '@emotion/styled':
+ specifier: ^11.14.1
+ version: 11.14.1(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0)
+ '@mui/material':
+ specifier: 7.2.0
+ version: 7.2.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
+ next:
+ specifier: ^15.4.1
+ version: 15.4.1(@babel/core@7.27.4)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
+ next-themes:
+ specifier: ^0.4.6
+ version: 0.4.6(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
+ react:
+ specifier: ^19.1.0
+ version: 19.1.0
+ react-dom:
+ specifier: ^19.1.0
+ version: 19.1.0(react@19.1.0)
+ react-icons:
+ specifier: ^5.5.0
+ version: 5.5.0(react@19.1.0)
+ devDependencies:
+ '@types/node':
+ specifier: ^24
+ version: 24.0.14
+ '@types/react':
+ specifier: ^19
+ version: 19.1.8
+ '@types/react-dom':
+ specifier: ^19
+ version: 19.1.6(@types/react@19.1.8)
+ typescript:
+ specifier: ^5
+ version: 5.8.3
+
bindings/devup-ui-wasm: {}
packages/components:
@@ -1198,6 +1238,16 @@ packages:
'@emotion/sheet@1.4.0':
resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==}
+ '@emotion/styled@11.14.1':
+ resolution: {integrity: sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==}
+ peerDependencies:
+ '@emotion/react': ^11.0.0-rc.0
+ '@types/react': '*'
+ react: '>=16.8.0'
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
'@emotion/unitless@0.10.0':
resolution: {integrity: sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==}
@@ -1836,6 +1886,86 @@ packages:
'@module-federation/webpack-bundler-runtime@0.16.0':
resolution: {integrity: sha512-yqIDQTelJZP0Rxml0OXv4Er8Kbdxy7NFh6PCzPwDFWI1SkiokJ3uXQJBvtlxZ3lOnCDYOzdHstqa8sJG4JP02Q==}
+ '@mui/core-downloads-tracker@7.2.0':
+ resolution: {integrity: sha512-d49s7kEgI5iX40xb2YPazANvo7Bx0BLg/MNRwv+7BVpZUzXj1DaVCKlQTDex3gy/0jsCb4w7AY2uH4t4AJvSog==}
+
+ '@mui/material@7.2.0':
+ resolution: {integrity: sha512-NTuyFNen5Z2QY+I242MDZzXnFIVIR6ERxo7vntFi9K1wCgSwvIl0HcAO2OOydKqqKApE6omRiYhpny1ZhGuH7Q==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ '@emotion/react': ^11.5.0
+ '@emotion/styled': ^11.3.0
+ '@mui/material-pigment-css': ^7.2.0
+ '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
+ react: ^17.0.0 || ^18.0.0 || ^19.0.0
+ react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ '@emotion/react':
+ optional: true
+ '@emotion/styled':
+ optional: true
+ '@mui/material-pigment-css':
+ optional: true
+ '@types/react':
+ optional: true
+
+ '@mui/private-theming@7.2.0':
+ resolution: {integrity: sha512-y6N1Yt3T5RMxVFnCh6+zeSWBuQdNDm5/UlM0EAYZzZR/1u+XKJWYQmbpx4e+F+1EpkYi3Nk8KhPiQDi83M3zIw==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
+ react: ^17.0.0 || ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@mui/styled-engine@7.2.0':
+ resolution: {integrity: sha512-yq08xynbrNYcB1nBcW9Fn8/h/iniM3ewRguGJXPIAbHvxEF7Pz95kbEEOAAhwzxMX4okhzvHmk0DFuC5ayvgIQ==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ '@emotion/react': ^11.4.1
+ '@emotion/styled': ^11.3.0
+ react: ^17.0.0 || ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ '@emotion/react':
+ optional: true
+ '@emotion/styled':
+ optional: true
+
+ '@mui/system@7.2.0':
+ resolution: {integrity: sha512-PG7cm/WluU6RAs+gNND2R9vDwNh+ERWxPkqTaiXQJGIFAyJ+VxhyKfzpdZNk0z0XdmBxxi9KhFOpgxjehf/O0A==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ '@emotion/react': ^11.5.0
+ '@emotion/styled': ^11.3.0
+ '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
+ react: ^17.0.0 || ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ '@emotion/react':
+ optional: true
+ '@emotion/styled':
+ optional: true
+ '@types/react':
+ optional: true
+
+ '@mui/types@7.4.4':
+ resolution: {integrity: sha512-p63yhbX52MO/ajXC7hDHJA5yjzJekvWD3q4YDLl1rSg+OXLczMYPvTuSuviPRCgRX8+E42RXz1D/dz9SxPSlWg==}
+ peerDependencies:
+ '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
+ '@mui/utils@7.2.0':
+ resolution: {integrity: sha512-O0i1GQL6MDzhKdy9iAu5Yr0Sz1wZjROH1o3aoztuivdCXqEeQYnEjTDiRLGuFxI9zrUbTHBwobMyQH5sNtyacw==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
+ react: ^17.0.0 || ^18.0.0 || ^19.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+
'@napi-rs/wasm-runtime@0.2.12':
resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==}
@@ -1924,6 +2054,9 @@ packages:
resolution: {integrity: sha512-YLT9Zo3oNPJoBjBc4q8G2mjU4tqIbf5CEOORbUUr48dCD9q3umJ3IPlVqOqDakPfd2HuwccBaqlGhN4Gmr5OWg==}
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
+ '@popperjs/core@2.11.8':
+ resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
+
'@rolldown/pluginutils@1.0.0-beta.19':
resolution: {integrity: sha512-3FL3mnMbPu0muGOCaKAhhFEYmqv9eTfPSJRJmANrCwtgK8VuxpsZDGK+m0LYAGoyO8+0j5uRe4PeyPDK1yA/hA==}
@@ -2325,6 +2458,9 @@ packages:
'@types/parse-json@4.0.2':
resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==}
+ '@types/prop-types@15.7.15':
+ resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==}
+
'@types/react-dom@19.1.6':
resolution: {integrity: sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==}
peerDependencies:
@@ -2333,6 +2469,11 @@ packages:
'@types/react-syntax-highlighter@15.5.13':
resolution: {integrity: sha512-uLGJ87j6Sz8UaBAooU0T6lWJ0dBmjZgN1PZTrj05TNql2/XpC6+4HhMT5syIdFUUt+FASfCeLLv4kBygNU+8qA==}
+ '@types/react-transition-group@4.4.12':
+ resolution: {integrity: sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==}
+ peerDependencies:
+ '@types/react': '*'
+
'@types/react@19.1.8':
resolution: {integrity: sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g==}
@@ -3191,6 +3332,9 @@ packages:
dom-accessibility-api@0.6.3:
resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==}
+ dom-helpers@5.2.1:
+ resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==}
+
dunder-proto@1.0.1:
resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==}
engines: {node: '>= 0.4'}
@@ -4613,6 +4757,9 @@ packages:
react-is@17.0.2:
resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==}
+ react-is@19.1.0:
+ resolution: {integrity: sha512-Oe56aUPnkHyyDxxkvqtd7KkdQP5uIUfHxd5XTb3wE9d/kRnZLmKbDB0GWk919tdQ+mxxPtG6EAs6RMT6i1qtHg==}
+
react-markdown@10.1.0:
resolution: {integrity: sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==}
peerDependencies:
@@ -4628,6 +4775,12 @@ packages:
peerDependencies:
react: '>= 0.14.0'
+ react-transition-group@4.4.5:
+ resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==}
+ peerDependencies:
+ react: '>=16.6.0'
+ react-dom: '>=16.6.0'
+
react@19.1.0:
resolution: {integrity: sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==}
engines: {node: '>=0.10.0'}
@@ -6425,6 +6578,21 @@ snapshots:
'@emotion/sheet@1.4.0': {}
+ '@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0)':
+ dependencies:
+ '@babel/runtime': 7.27.6
+ '@emotion/babel-plugin': 11.13.5
+ '@emotion/is-prop-valid': 1.3.1
+ '@emotion/react': 11.14.0(@types/react@19.1.8)(react@19.1.0)
+ '@emotion/serialize': 1.3.3
+ '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.1.0)
+ '@emotion/utils': 1.4.2
+ react: 19.1.0
+ optionalDependencies:
+ '@types/react': 19.1.8
+ transitivePeerDependencies:
+ - supports-color
+
'@emotion/unitless@0.10.0': {}
'@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.1.0)':
@@ -7017,6 +7185,85 @@ snapshots:
'@module-federation/runtime': 0.16.0
'@module-federation/sdk': 0.16.0
+ '@mui/core-downloads-tracker@7.2.0': {}
+
+ '@mui/material@7.2.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react-dom@19.1.0(react@19.1.0))(react@19.1.0)':
+ dependencies:
+ '@babel/runtime': 7.27.6
+ '@mui/core-downloads-tracker': 7.2.0
+ '@mui/system': 7.2.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0)
+ '@mui/types': 7.4.4(@types/react@19.1.8)
+ '@mui/utils': 7.2.0(@types/react@19.1.8)(react@19.1.0)
+ '@popperjs/core': 2.11.8
+ '@types/react-transition-group': 4.4.12(@types/react@19.1.8)
+ clsx: 2.1.1
+ csstype: 3.1.3
+ prop-types: 15.8.1
+ react: 19.1.0
+ react-dom: 19.1.0(react@19.1.0)
+ react-is: 19.1.0
+ react-transition-group: 4.4.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
+ optionalDependencies:
+ '@emotion/react': 11.14.0(@types/react@19.1.8)(react@19.1.0)
+ '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0)
+ '@types/react': 19.1.8
+
+ '@mui/private-theming@7.2.0(@types/react@19.1.8)(react@19.1.0)':
+ dependencies:
+ '@babel/runtime': 7.27.6
+ '@mui/utils': 7.2.0(@types/react@19.1.8)(react@19.1.0)
+ prop-types: 15.8.1
+ react: 19.1.0
+ optionalDependencies:
+ '@types/react': 19.1.8
+
+ '@mui/styled-engine@7.2.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0))(react@19.1.0)':
+ dependencies:
+ '@babel/runtime': 7.27.6
+ '@emotion/cache': 11.14.0
+ '@emotion/serialize': 1.3.3
+ '@emotion/sheet': 1.4.0
+ csstype: 3.1.3
+ prop-types: 15.8.1
+ react: 19.1.0
+ optionalDependencies:
+ '@emotion/react': 11.14.0(@types/react@19.1.8)(react@19.1.0)
+ '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0)
+
+ '@mui/system@7.2.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0)':
+ dependencies:
+ '@babel/runtime': 7.27.6
+ '@mui/private-theming': 7.2.0(@types/react@19.1.8)(react@19.1.0)
+ '@mui/styled-engine': 7.2.0(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0))(react@19.1.0)
+ '@mui/types': 7.4.4(@types/react@19.1.8)
+ '@mui/utils': 7.2.0(@types/react@19.1.8)(react@19.1.0)
+ clsx: 2.1.1
+ csstype: 3.1.3
+ prop-types: 15.8.1
+ react: 19.1.0
+ optionalDependencies:
+ '@emotion/react': 11.14.0(@types/react@19.1.8)(react@19.1.0)
+ '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.1.8)(react@19.1.0))(@types/react@19.1.8)(react@19.1.0)
+ '@types/react': 19.1.8
+
+ '@mui/types@7.4.4(@types/react@19.1.8)':
+ dependencies:
+ '@babel/runtime': 7.27.6
+ optionalDependencies:
+ '@types/react': 19.1.8
+
+ '@mui/utils@7.2.0(@types/react@19.1.8)(react@19.1.0)':
+ dependencies:
+ '@babel/runtime': 7.27.6
+ '@mui/types': 7.4.4(@types/react@19.1.8)
+ '@types/prop-types': 15.7.15
+ clsx: 2.1.1
+ prop-types: 15.8.1
+ react: 19.1.0
+ react-is: 19.1.0
+ optionalDependencies:
+ '@types/react': 19.1.8
+
'@napi-rs/wasm-runtime@0.2.12':
dependencies:
'@emnapi/core': 1.4.3
@@ -7076,6 +7323,8 @@ snapshots:
'@pkgr/core@0.2.7': {}
+ '@popperjs/core@2.11.8': {}
+
'@rolldown/pluginutils@1.0.0-beta.19': {}
'@rollup/pluginutils@5.2.0(rollup@4.44.0)':
@@ -7510,6 +7759,8 @@ snapshots:
'@types/parse-json@4.0.2': {}
+ '@types/prop-types@15.7.15': {}
+
'@types/react-dom@19.1.6(@types/react@19.1.8)':
dependencies:
'@types/react': 19.1.8
@@ -7518,6 +7769,10 @@ snapshots:
dependencies:
'@types/react': 19.1.8
+ '@types/react-transition-group@4.4.12(@types/react@19.1.8)':
+ dependencies:
+ '@types/react': 19.1.8
+
'@types/react@19.1.8':
dependencies:
csstype: 3.1.3
@@ -8780,6 +9035,11 @@ snapshots:
dom-accessibility-api@0.6.3: {}
+ dom-helpers@5.2.1:
+ dependencies:
+ '@babel/runtime': 7.27.6
+ csstype: 3.1.3
+
dunder-proto@1.0.1:
dependencies:
call-bind-apply-helpers: 1.0.2
@@ -10669,6 +10929,8 @@ snapshots:
react-is@17.0.2: {}
+ react-is@19.1.0: {}
+
react-markdown@10.1.0(@types/react@19.1.8)(react@19.1.0):
dependencies:
'@types/hast': 3.0.4
@@ -10699,6 +10961,15 @@ snapshots:
react: 19.1.0
refractor: 3.6.0
+ react-transition-group@4.4.5(react-dom@19.1.0(react@19.1.0))(react@19.1.0):
+ dependencies:
+ '@babel/runtime': 7.27.6
+ dom-helpers: 5.2.1
+ loose-envify: 1.4.0
+ prop-types: 15.8.1
+ react: 19.1.0
+ react-dom: 19.1.0(react@19.1.0)
+
react@19.1.0: {}
read-yaml-file@1.1.0: