mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-09 06:49:02 +08:00
feat: add route animation
feat: add route animation
This commit is contained in:
parent
26d823e0a5
commit
0d9f1882b9
@ -86,6 +86,7 @@
|
|||||||
"electron-window-state": "^5.0.3",
|
"electron-window-state": "^5.0.3",
|
||||||
"epub": "patch:epub@npm%3A1.3.0#~/.yarn/patches/epub-npm-1.3.0-8325494ffe.patch",
|
"epub": "patch:epub@npm%3A1.3.0#~/.yarn/patches/epub-npm-1.3.0-8325494ffe.patch",
|
||||||
"fast-xml-parser": "^5.2.0",
|
"fast-xml-parser": "^5.2.0",
|
||||||
|
"framer-motion": "^12.17.0",
|
||||||
"franc-min": "^6.2.0",
|
"franc-min": "^6.2.0",
|
||||||
"fs-extra": "^11.2.0",
|
"fs-extra": "^11.2.0",
|
||||||
"jsdom": "^26.0.0",
|
"jsdom": "^26.0.0",
|
||||||
|
|||||||
@ -12,7 +12,6 @@ import { NotificationProvider } from './context/NotificationProvider'
|
|||||||
import StyleSheetManager from './context/StyleSheetManager'
|
import StyleSheetManager from './context/StyleSheetManager'
|
||||||
import { ThemeProvider } from './context/ThemeProvider'
|
import { ThemeProvider } from './context/ThemeProvider'
|
||||||
import NavigationHandler from './handler/NavigationHandler'
|
import NavigationHandler from './handler/NavigationHandler'
|
||||||
import MainSidebar from './pages/home/MainSidebar/MainSidebar'
|
|
||||||
import Routes from './Routes'
|
import Routes from './Routes'
|
||||||
|
|
||||||
function App(): React.ReactElement {
|
function App(): React.ReactElement {
|
||||||
@ -27,7 +26,6 @@ function App(): React.ReactElement {
|
|||||||
<TopViewContainer>
|
<TopViewContainer>
|
||||||
<HashRouter>
|
<HashRouter>
|
||||||
<NavigationHandler />
|
<NavigationHandler />
|
||||||
<MainSidebar />
|
|
||||||
<Routes />
|
<Routes />
|
||||||
</HashRouter>
|
</HashRouter>
|
||||||
</TopViewContainer>
|
</TopViewContainer>
|
||||||
|
|||||||
@ -1,4 +1,7 @@
|
|||||||
|
import { AnimatePresence, motion } from 'framer-motion'
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
import { Route, Routes, useLocation } from 'react-router-dom'
|
import { Route, Routes, useLocation } from 'react-router-dom'
|
||||||
|
import styled from 'styled-components'
|
||||||
|
|
||||||
import AgentsPage from './pages/agents/AgentsPage'
|
import AgentsPage from './pages/agents/AgentsPage'
|
||||||
import AppsPage from './pages/apps/AppsPage'
|
import AppsPage from './pages/apps/AppsPage'
|
||||||
@ -10,27 +13,93 @@ import PaintingsRoutePage from './pages/paintings/PaintingsRoutePage'
|
|||||||
import SettingsPage from './pages/settings/SettingsPage'
|
import SettingsPage from './pages/settings/SettingsPage'
|
||||||
import TranslatePage from './pages/translate/TranslatePage'
|
import TranslatePage from './pages/translate/TranslatePage'
|
||||||
|
|
||||||
|
const WILDCARD_ROUTES = ['/settings', '/paintings', '/mcp-servers']
|
||||||
|
|
||||||
const RouteContainer = () => {
|
const RouteContainer = () => {
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
const isHomePage = location.pathname === '/'
|
const isHomePage = location.pathname === '/'
|
||||||
|
const [isReady, setIsReady] = useState(false)
|
||||||
|
|
||||||
|
// 获取当前路径的主路由部分
|
||||||
|
const mainPath = WILDCARD_ROUTES.find((route) => location.pathname.startsWith(route))
|
||||||
|
|
||||||
|
// 使用主路由作为 key,这样同一主路由下的切换不会触发动画
|
||||||
|
const animationKey = mainPath || location.pathname
|
||||||
|
|
||||||
|
// 路由变化时重置状态
|
||||||
|
useEffect(() => {
|
||||||
|
setIsReady(false)
|
||||||
|
// 给一个很短的延迟,确保组件已经渲染
|
||||||
|
const timer = setTimeout(() => setIsReady(true), 300)
|
||||||
|
return () => clearTimeout(timer)
|
||||||
|
}, [location.pathname])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ display: 'flex', width: '100%', height: '100%', minWidth: '0' }}>
|
<Container>
|
||||||
<HomePage style={{ display: isHomePage ? 'flex' : 'none' }} />
|
<HomePageWrapper />
|
||||||
<div style={{ display: isHomePage ? 'none' : 'flex', flex: 1 }}>
|
<AnimatePresence mode="wait">
|
||||||
<Routes location={location}>
|
{!isHomePage && (
|
||||||
<Route path="/agents" element={<AgentsPage />} />
|
<PageContainer
|
||||||
<Route path="/paintings/*" element={<PaintingsRoutePage />} />
|
key={animationKey}
|
||||||
<Route path="/translate" element={<TranslatePage />} />
|
initial={isReady ? 'initial' : false}
|
||||||
<Route path="/files" element={<FilesPage />} />
|
animate={isReady ? 'animate' : false}
|
||||||
<Route path="/knowledge" element={<KnowledgePage />} />
|
exit="exit"
|
||||||
<Route path="/apps" element={<AppsPage />} />
|
variants={pageVariants}
|
||||||
<Route path="/mcp-servers/*" element={<McpServersPage />} />
|
transition={pageTransition}>
|
||||||
<Route path="/settings/*" element={<SettingsPage />} />
|
<Routes location={location}>
|
||||||
</Routes>
|
<Route path="/agents" element={<AgentsPage />} />
|
||||||
</div>
|
<Route path="/paintings/*" element={<PaintingsRoutePage />} />
|
||||||
</div>
|
<Route path="/translate" element={<TranslatePage />} />
|
||||||
|
<Route path="/files" element={<FilesPage />} />
|
||||||
|
<Route path="/knowledge" element={<KnowledgePage />} />
|
||||||
|
<Route path="/apps" element={<AppsPage />} />
|
||||||
|
<Route path="/mcp-servers/*" element={<McpServersPage />} />
|
||||||
|
<Route path="/settings/*" element={<SettingsPage />} />
|
||||||
|
</Routes>
|
||||||
|
</PageContainer>
|
||||||
|
)}
|
||||||
|
</AnimatePresence>
|
||||||
|
</Container>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Container = styled.div`
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
min-width: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
`
|
||||||
|
|
||||||
|
const HomePageWrapper = styled(HomePage)`
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
`
|
||||||
|
|
||||||
|
const PageContainer = styled(motion.div)`
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: var(--color-base);
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 10;
|
||||||
|
`
|
||||||
|
|
||||||
|
const pageTransition = {
|
||||||
|
type: 'tween',
|
||||||
|
duration: 0.25,
|
||||||
|
ease: 'easeInOut'
|
||||||
|
}
|
||||||
|
|
||||||
|
const pageVariants = {
|
||||||
|
initial: { y: '100%' },
|
||||||
|
animate: { y: 0 },
|
||||||
|
exit: { y: '100%' }
|
||||||
|
}
|
||||||
|
|
||||||
export default RouteContainer
|
export default RouteContainer
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { CircleArrowLeft, X } from 'lucide-react'
|
|||||||
import type { FC, PropsWithChildren } from 'react'
|
import type { FC, PropsWithChildren } from 'react'
|
||||||
import type { HTMLAttributes } from 'react'
|
import type { HTMLAttributes } from 'react'
|
||||||
import { useNavigate } from 'react-router-dom'
|
import { useNavigate } from 'react-router-dom'
|
||||||
import styled from 'styled-components'
|
import styled, { keyframes } from 'styled-components'
|
||||||
|
|
||||||
type Props = PropsWithChildren & HTMLAttributes<HTMLDivElement>
|
type Props = PropsWithChildren & HTMLAttributes<HTMLDivElement>
|
||||||
|
|
||||||
@ -38,6 +38,19 @@ export const NavbarMain: FC<Props> = ({ children, ...props }) => {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const rotateAnimation = keyframes`
|
||||||
|
from {
|
||||||
|
transform: rotate(-180deg);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
transform: rotate(0);
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const AnimatedButton = styled(Button)`
|
||||||
|
animation: ${rotateAnimation} 0.4s ease-out;
|
||||||
|
`
|
||||||
|
|
||||||
const MacCloseIcon = () => {
|
const MacCloseIcon = () => {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
|
|
||||||
@ -45,7 +58,7 @@ const MacCloseIcon = () => {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return <Button type="text" icon={<X size={18} />} onClick={() => navigate('/')} className="nodrag" />
|
return <AnimatedButton type="text" icon={<X size={18} />} onClick={() => navigate('/')} className="nodrag" />
|
||||||
}
|
}
|
||||||
|
|
||||||
const CloseIcon = () => {
|
const CloseIcon = () => {
|
||||||
@ -90,6 +103,7 @@ const NavbarMainContainer = styled.div<{ $isFullscreen: boolean }>`
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
background-color: var(--color-background);
|
||||||
height: var(--navbar-height);
|
height: var(--navbar-height);
|
||||||
max-height: var(--navbar-height);
|
max-height: var(--navbar-height);
|
||||||
min-height: var(--navbar-height);
|
min-height: var(--navbar-height);
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import type { MenuProps } from 'antd'
|
|||||||
import { Dropdown, message } from 'antd'
|
import { Dropdown, message } from 'antd'
|
||||||
import { FC } from 'react'
|
import { FC } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { useLocation, useNavigate } from 'react-router'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@ -22,8 +23,15 @@ const App: FC<Props> = ({ app, onClick, size = 60, isLast }) => {
|
|||||||
const { minapps, pinned, disabled, updateMinapps, updateDisabledMinapps, updatePinnedMinapps } = useMinapps()
|
const { minapps, pinned, disabled, updateMinapps, updateDisabledMinapps, updatePinnedMinapps } = useMinapps()
|
||||||
const isPinned = pinned.some((p) => p.id === app.id)
|
const isPinned = pinned.some((p) => p.id === app.id)
|
||||||
const isVisible = minapps.some((m) => m.id === app.id)
|
const isVisible = minapps.some((m) => m.id === app.id)
|
||||||
|
const location = useLocation()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
const isHome = location.pathname === '/'
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
|
if (!isHome) {
|
||||||
|
navigate('/')
|
||||||
|
}
|
||||||
|
|
||||||
openMinappKeepAlive(app)
|
openMinappKeepAlive(app)
|
||||||
onClick?.()
|
onClick?.()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
import { Navbar } from '@renderer/components/app/Navbar'
|
import { Navbar } from '@renderer/components/app/Navbar'
|
||||||
import NarrowModeIcon from '@renderer/components/Icons/NarrowModeIcon'
|
import NarrowModeIcon from '@renderer/components/Icons/NarrowModeIcon'
|
||||||
import { HStack } from '@renderer/components/Layout'
|
import { HStack } from '@renderer/components/Layout'
|
||||||
import MinAppsPopover from '@renderer/components/Popups/MinAppsPopover'
|
|
||||||
import SearchPopup from '@renderer/components/Popups/SearchPopup'
|
import SearchPopup from '@renderer/components/Popups/SearchPopup'
|
||||||
import { isLinux, isMac, isWindows } from '@renderer/config/constant'
|
import { isLinux, isMac, isWindows } from '@renderer/config/constant'
|
||||||
import { useAssistant } from '@renderer/hooks/useAssistant'
|
import { useAssistant } from '@renderer/hooks/useAssistant'
|
||||||
@ -17,6 +16,7 @@ import { Tooltip } from 'antd'
|
|||||||
import { t } from 'i18next'
|
import { t } from 'i18next'
|
||||||
import { LayoutGrid, PanelLeft, PanelRight, Search } from 'lucide-react'
|
import { LayoutGrid, PanelLeft, PanelRight, Search } from 'lucide-react'
|
||||||
import { FC } from 'react'
|
import { FC } from 'react'
|
||||||
|
import { useNavigate } from 'react-router'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
import SelectModelButton from './components/SelectModelButton'
|
import SelectModelButton from './components/SelectModelButton'
|
||||||
@ -29,6 +29,7 @@ const ChatNavbar: FC = () => {
|
|||||||
const isFullscreen = useFullscreen()
|
const isFullscreen = useFullscreen()
|
||||||
const { sidebarIcons, narrowMode } = useSettings()
|
const { sidebarIcons, narrowMode } = useSettings()
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
|
const navigate = useNavigate()
|
||||||
|
|
||||||
useShortcut('search_message', SearchPopup.show)
|
useShortcut('search_message', SearchPopup.show)
|
||||||
|
|
||||||
@ -63,13 +64,11 @@ const ChatNavbar: FC = () => {
|
|||||||
</NarrowIcon>
|
</NarrowIcon>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
{sidebarIcons.visible.includes('minapp') && (
|
{sidebarIcons.visible.includes('minapp') && (
|
||||||
<MinAppsPopover>
|
<Tooltip title={t('minapp.title')} mouseEnterDelay={0.8}>
|
||||||
<Tooltip title={t('minapp.title')} mouseEnterDelay={0.8}>
|
<NarrowIcon onClick={() => navigate('/apps')}>
|
||||||
<NarrowIcon>
|
<LayoutGrid size={18} />
|
||||||
<LayoutGrid size={18} />
|
</NarrowIcon>
|
||||||
</NarrowIcon>
|
</Tooltip>
|
||||||
</Tooltip>
|
|
||||||
</MinAppsPopover>
|
|
||||||
)}
|
)}
|
||||||
</HStack>
|
</HStack>
|
||||||
</NavbarContainer>
|
</NavbarContainer>
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
|
import { HStack } from '@renderer/components/Layout'
|
||||||
import { useSettings } from '@renderer/hooks/useSettings'
|
import { useSettings } from '@renderer/hooks/useSettings'
|
||||||
import { FC, useEffect } from 'react'
|
import { FC, useEffect } from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
import Chat from './Chat'
|
import Chat from './Chat'
|
||||||
import ChatNavbar from './ChatNavbar'
|
import ChatNavbar from './ChatNavbar'
|
||||||
|
import MainSidebar from './MainSidebar/MainSidebar'
|
||||||
|
|
||||||
const HomePage: FC<{ style?: React.CSSProperties }> = ({ style }) => {
|
const HomePage: FC<{ style?: React.CSSProperties }> = ({ style }) => {
|
||||||
const { showAssistants, showTopics, topicPosition } = useSettings()
|
const { showAssistants, showTopics, topicPosition } = useSettings()
|
||||||
@ -17,12 +19,15 @@ const HomePage: FC<{ style?: React.CSSProperties }> = ({ style }) => {
|
|||||||
}, [showAssistants, showTopics, topicPosition])
|
}, [showAssistants, showTopics, topicPosition])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container id="home-page" style={style}>
|
<HStack style={{ display: 'flex', flex: 1 }}>
|
||||||
<ChatNavbar />
|
<MainSidebar />
|
||||||
<ContentContainer id="content-container">
|
<Container id="home-page" style={style}>
|
||||||
<Chat />
|
<ChatNavbar />
|
||||||
</ContentContainer>
|
<ContentContainer id="content-container">
|
||||||
</Container>
|
<Chat />
|
||||||
|
</ContentContainer>
|
||||||
|
</Container>
|
||||||
|
</HStack>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -133,10 +133,6 @@ const MainSidebar: FC = () => {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (location.pathname !== '/') {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container id="main-sidebar">
|
<Container id="main-sidebar">
|
||||||
<MainNavbar />
|
<MainNavbar />
|
||||||
@ -165,13 +161,7 @@ const MainSidebar: FC = () => {
|
|||||||
transition={{ duration: 0.2 }}>
|
transition={{ duration: 0.2 }}>
|
||||||
<SubMenu>
|
<SubMenu>
|
||||||
{appMenuItems.map((item) => (
|
{appMenuItems.map((item) => (
|
||||||
<MainMenuItem
|
<MainMenuItem key={item.path} active={isRoutes(item.path)} onClick={() => navigate(item.path)}>
|
||||||
key={item.path}
|
|
||||||
active={isRoutes(item.path)}
|
|
||||||
onClick={() => {
|
|
||||||
navigate(item.path)
|
|
||||||
setIsAppMenuExpanded(false)
|
|
||||||
}}>
|
|
||||||
<MainMenuItemLeft>
|
<MainMenuItemLeft>
|
||||||
<MainMenuItemIcon>{item.icon}</MainMenuItemIcon>
|
<MainMenuItemIcon>{item.icon}</MainMenuItemIcon>
|
||||||
<MainMenuItemText>{item.text}</MainMenuItemText>
|
<MainMenuItemText>{item.text}</MainMenuItemText>
|
||||||
|
|||||||
@ -51,6 +51,7 @@ export const Container = styled.div`
|
|||||||
width: var(--assistant-width);
|
width: var(--assistant-width);
|
||||||
max-width: var(--assistant-width);
|
max-width: var(--assistant-width);
|
||||||
border-right: 0.5px solid var(--color-border);
|
border-right: 0.5px solid var(--color-border);
|
||||||
|
height: 100vh;
|
||||||
`
|
`
|
||||||
|
|
||||||
export const MainMenu = styled.div`
|
export const MainMenu = styled.div`
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import ImageStorage from '@renderer/services/ImageStorage'
|
|||||||
import { INITIAL_PROVIDERS } from '@renderer/store/llm'
|
import { INITIAL_PROVIDERS } from '@renderer/store/llm'
|
||||||
import { Provider } from '@renderer/types'
|
import { Provider } from '@renderer/types'
|
||||||
import { droppableReorder, generateColorFromChar, getFirstCharacter, uuid } from '@renderer/utils'
|
import { droppableReorder, generateColorFromChar, getFirstCharacter, uuid } from '@renderer/utils'
|
||||||
import { Avatar, Button, Dropdown, Input, MenuProps, Tag } from 'antd'
|
import { Avatar, Button, Dropdown, Input, MenuProps, Spin, Tag } from 'antd'
|
||||||
import { Search, UserPen } from 'lucide-react'
|
import { Search, UserPen } from 'lucide-react'
|
||||||
import { FC, useEffect, useState } from 'react'
|
import { FC, useEffect, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
@ -27,6 +27,7 @@ const ProvidersList: FC = () => {
|
|||||||
const [searchText, setSearchText] = useState<string>('')
|
const [searchText, setSearchText] = useState<string>('')
|
||||||
const [dragging, setDragging] = useState(false)
|
const [dragging, setDragging] = useState(false)
|
||||||
const [providerLogos, setProviderLogos] = useState<Record<string, string>>({})
|
const [providerLogos, setProviderLogos] = useState<Record<string, string>>({})
|
||||||
|
const [ready, setReady] = useState(false)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const loadAllLogos = async () => {
|
const loadAllLogos = async () => {
|
||||||
@ -241,6 +242,18 @@ const ProvidersList: FC = () => {
|
|||||||
return isProviderMatch || isModelMatch
|
return isProviderMatch || isModelMatch
|
||||||
})
|
})
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setTimeout(() => setReady(true), 250)
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
if (!ready) {
|
||||||
|
return (
|
||||||
|
<div style={{ width: '100%', height: '100%', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
|
||||||
|
<Spin />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container className="selectable">
|
<Container className="selectable">
|
||||||
<ProviderListContainer>
|
<ProviderListContainer>
|
||||||
|
|||||||
39
yarn.lock
39
yarn.lock
@ -5656,6 +5656,7 @@ __metadata:
|
|||||||
eslint-plugin-unused-imports: "npm:^4.1.4"
|
eslint-plugin-unused-imports: "npm:^4.1.4"
|
||||||
fast-diff: "npm:^1.3.0"
|
fast-diff: "npm:^1.3.0"
|
||||||
fast-xml-parser: "npm:^5.2.0"
|
fast-xml-parser: "npm:^5.2.0"
|
||||||
|
framer-motion: "npm:^12.17.0"
|
||||||
franc-min: "npm:^6.2.0"
|
franc-min: "npm:^6.2.0"
|
||||||
fs-extra: "npm:^11.2.0"
|
fs-extra: "npm:^11.2.0"
|
||||||
html-to-image: "npm:^1.11.13"
|
html-to-image: "npm:^1.11.13"
|
||||||
@ -9863,6 +9864,28 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"framer-motion@npm:^12.17.0":
|
||||||
|
version: 12.17.0
|
||||||
|
resolution: "framer-motion@npm:12.17.0"
|
||||||
|
dependencies:
|
||||||
|
motion-dom: "npm:^12.17.0"
|
||||||
|
motion-utils: "npm:^12.12.1"
|
||||||
|
tslib: "npm:^2.4.0"
|
||||||
|
peerDependencies:
|
||||||
|
"@emotion/is-prop-valid": "*"
|
||||||
|
react: ^18.0.0 || ^19.0.0
|
||||||
|
react-dom: ^18.0.0 || ^19.0.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
"@emotion/is-prop-valid":
|
||||||
|
optional: true
|
||||||
|
react:
|
||||||
|
optional: true
|
||||||
|
react-dom:
|
||||||
|
optional: true
|
||||||
|
checksum: 10c0/3262ab125650d71cd13eb9f4838da70550ea383d68a2fbd2664b05bac88b7420fe7db25911fbd30cbc237327d98a4567df34e675c8261dde559a9375e580103c
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"franc-min@npm:^6.2.0":
|
"franc-min@npm:^6.2.0":
|
||||||
version: 6.2.0
|
version: 6.2.0
|
||||||
resolution: "franc-min@npm:6.2.0"
|
resolution: "franc-min@npm:6.2.0"
|
||||||
@ -13552,6 +13575,22 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"motion-dom@npm:^12.17.0":
|
||||||
|
version: 12.17.0
|
||||||
|
resolution: "motion-dom@npm:12.17.0"
|
||||||
|
dependencies:
|
||||||
|
motion-utils: "npm:^12.12.1"
|
||||||
|
checksum: 10c0/1ec428e113f334193dcd52293c94bca21fcca97f3825521d1dafe41f6b999e8dda5013b48de2c09e2f32204f80d1d7281079ba3a142c71b8d6923a0ddb056513
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
|
"motion-utils@npm:^12.12.1":
|
||||||
|
version: 12.12.1
|
||||||
|
resolution: "motion-utils@npm:12.12.1"
|
||||||
|
checksum: 10c0/880a174769d1be42b46cfb34af81b4a629c068d30d5cf7e07d249fbf2f5121d577482d3ea5bdc1db549c0288733e1e987efecb195fae350995270651559c6697
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"motion-utils@npm:^12.9.4":
|
"motion-utils@npm:^12.9.4":
|
||||||
version: 12.9.4
|
version: 12.9.4
|
||||||
resolution: "motion-utils@npm:12.9.4"
|
resolution: "motion-utils@npm:12.9.4"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user