init commit,
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
import type { BoxProps } from '@mui/material/Box';
|
||||
|
||||
import { m } from 'framer-motion';
|
||||
import { varAlpha } from 'minimal-shared/utils';
|
||||
|
||||
import Box from '@mui/material/Box';
|
||||
import useMediaQuery from '@mui/material/useMediaQuery';
|
||||
|
||||
import { CONFIG } from 'src/global-config';
|
||||
|
||||
import { MotionContainer } from 'src/components/animate';
|
||||
|
||||
import { Dots, Lines, Texts, Circles, PlusIcon } from './hero-svg';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function HeroBackground({ sx, ...other }: BoxProps) {
|
||||
const mdUp = useMediaQuery((theme) => theme.breakpoints.up('md'));
|
||||
|
||||
const strokeCount = 12;
|
||||
|
||||
return (
|
||||
<MotionContainer>
|
||||
<Box
|
||||
sx={[
|
||||
(theme) => ({
|
||||
'--stroke-dasharray': 3,
|
||||
'--stroke-spacing': '80px',
|
||||
/* line */
|
||||
'--hero-line-stroke-width': 1,
|
||||
'--hero-line-stroke-color': varAlpha(theme.vars.palette.grey['500Channel'], 0.32),
|
||||
...theme.applyStyles('dark', {
|
||||
'--hero-line-stroke-color': varAlpha(theme.vars.palette.grey['600Channel'], 0.16),
|
||||
}),
|
||||
/* text */
|
||||
'--hero-text-stroke-width': 1,
|
||||
'--hero-text-stroke-color': varAlpha(theme.vars.palette.grey['500Channel'], 0.24),
|
||||
...theme.applyStyles('dark', {
|
||||
'--hero-text-stroke-color': varAlpha(theme.vars.palette.grey['600Channel'], 0.12),
|
||||
}),
|
||||
/* circle */
|
||||
'--hero-circle-stroke-width': 1,
|
||||
'--hero-circle-stroke-color': varAlpha(theme.vars.palette.grey['500Channel'], 0.48),
|
||||
...theme.applyStyles('dark', {
|
||||
'--hero-circle-stroke-color': varAlpha(theme.vars.palette.grey['600Channel'], 0.24),
|
||||
}),
|
||||
/* plus */
|
||||
'--hero-plus-stroke-color': theme.vars.palette.text.disabled,
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: 1,
|
||||
height: 1,
|
||||
position: 'absolute',
|
||||
}),
|
||||
...(Array.isArray(sx) ? sx : [sx]),
|
||||
]}
|
||||
{...other}
|
||||
>
|
||||
<Dots />
|
||||
|
||||
{mdUp && <Texts />}
|
||||
|
||||
<Box
|
||||
component={m.svg}
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="1440"
|
||||
height="1080"
|
||||
fill="none"
|
||||
viewBox="0 0 1440 1080"
|
||||
initial="hidden"
|
||||
animate="visible"
|
||||
sx={[{ width: 1, height: 1 }]}
|
||||
>
|
||||
<defs>
|
||||
<radialGradient
|
||||
id="mask_gradient_id"
|
||||
cx="0"
|
||||
cy="0"
|
||||
r="1"
|
||||
gradientTransform="matrix(720 0 0 420 720 560)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0%" stopColor="#FFFFFF" stopOpacity={1} />
|
||||
<stop offset="100%" stopColor="#FFFFFF" stopOpacity={0.08} />
|
||||
</radialGradient>
|
||||
|
||||
<mask id="mask_id">
|
||||
<ellipse cx="50%" cy="50%" rx="50%" ry="36%" fill="url(#mask_gradient_id)" />
|
||||
</mask>
|
||||
</defs>
|
||||
|
||||
<g mask="url(#mask_id)">
|
||||
<Circles />
|
||||
<PlusIcon />
|
||||
<Lines strokeCount={strokeCount} />
|
||||
</g>
|
||||
</Box>
|
||||
|
||||
<Box
|
||||
component={m.div}
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
sx={[
|
||||
(theme) => ({
|
||||
...theme.mixins.bgGradient({
|
||||
images: [
|
||||
`linear-gradient(180deg, ${theme.vars.palette.background.default} 12%, ${varAlpha(theme.vars.palette.background.defaultChannel, 0.92)} 50%, ${theme.vars.palette.background.default} 88%)`,
|
||||
`url(${CONFIG.assetsDir}/assets/background/background-3.webp)`,
|
||||
],
|
||||
}),
|
||||
top: 0,
|
||||
left: 0,
|
||||
width: 1,
|
||||
height: 1,
|
||||
zIndex: -1,
|
||||
position: 'absolute',
|
||||
...theme.applyStyles('dark', {
|
||||
...theme.mixins.bgGradient({
|
||||
images: [
|
||||
`url(${CONFIG.assetsDir}/assets/images/home/hero-blur.webp)`,
|
||||
`linear-gradient(180deg, ${theme.vars.palette.background.default} 12%, ${varAlpha(theme.vars.palette.background.defaultChannel, 0.96)} 50%, ${theme.vars.palette.background.default} 88%)`,
|
||||
`url(${CONFIG.assetsDir}/assets/background/background-3.webp)`,
|
||||
],
|
||||
}),
|
||||
}),
|
||||
}),
|
||||
]}
|
||||
/>
|
||||
</Box>
|
||||
</MotionContainer>
|
||||
);
|
||||
}
|
332
03_source/frontend/src/sections/home/components/hero-svg.tsx
Normal file
332
03_source/frontend/src/sections/home/components/hero-svg.tsx
Normal file
@@ -0,0 +1,332 @@
|
||||
import type { MotionProps } from 'framer-motion';
|
||||
import type { BoxProps } from '@mui/material/Box';
|
||||
import type { PaletteColorKey } from 'src/theme/core';
|
||||
import type { Theme, SxProps } from '@mui/material/styles';
|
||||
|
||||
import { m } from 'framer-motion';
|
||||
|
||||
import Box from '@mui/material/Box';
|
||||
|
||||
import { varFade } from 'src/components/animate';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function Lines({ strokeCount }: { strokeCount: number }) {
|
||||
const drawVariants = {
|
||||
x: {
|
||||
hidden: { x2: 0, strokeOpacity: 0 },
|
||||
visible: (i: number) => {
|
||||
const delay = 1 + i * 0.5;
|
||||
return {
|
||||
x2: '100%',
|
||||
strokeOpacity: 1,
|
||||
transition: {
|
||||
strokeOpacity: { delay, duration: 0.01 },
|
||||
x2: { delay, bounce: 0, duration: 1.5, type: 'spring' },
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
y: {
|
||||
hidden: { y2: 0, strokeOpacity: 0 },
|
||||
visible: (i: number) => {
|
||||
const delay = 1 + i * 0.5;
|
||||
return {
|
||||
y2: '100%',
|
||||
strokeOpacity: 1,
|
||||
transition: {
|
||||
strokeOpacity: { delay, duration: 0.01 },
|
||||
y2: { delay, bounce: 0, duration: 1.5, type: 'spring' },
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const translateY = (index: number) =>
|
||||
strokeCount / 2 > index
|
||||
? `translateY(calc(((${index} * var(--stroke-spacing)) + var(--stroke-spacing) / 2) * -1))`
|
||||
: `translateY(calc(((${strokeCount - (index + 1)} * var(--stroke-spacing)) + var(--stroke-spacing) / 2)))`;
|
||||
|
||||
const linesX = (
|
||||
<>
|
||||
{Array.from({ length: strokeCount }, (_, index) => (
|
||||
<m.line
|
||||
key={index}
|
||||
x1="0"
|
||||
x2="100%"
|
||||
y1="50%"
|
||||
y2="50%"
|
||||
variants={drawVariants.x}
|
||||
style={{
|
||||
transform: translateY(index),
|
||||
stroke: 'var(--hero-line-stroke-color)',
|
||||
strokeDasharray: 'var(--stroke-dasharray)',
|
||||
strokeWidth: 'var(--hero-line-stroke-width)',
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
|
||||
const translateX = (index: number) =>
|
||||
strokeCount / 2 > index
|
||||
? `translateX(calc(((${index} * var(--stroke-spacing)) + var(--stroke-spacing) / 2) * -1))`
|
||||
: `translateX(calc(((${strokeCount - (index + 1)} * var(--stroke-spacing)) + var(--stroke-spacing) / 2)))`;
|
||||
|
||||
const linesY = (
|
||||
<>
|
||||
{Array.from({ length: strokeCount }, (_, index) => (
|
||||
<m.line
|
||||
key={index}
|
||||
x1="50%"
|
||||
x2="50%"
|
||||
y1="0%"
|
||||
y2="100%"
|
||||
variants={drawVariants.y}
|
||||
style={{
|
||||
transform: translateX(index),
|
||||
stroke: 'var(--hero-line-stroke-color)',
|
||||
strokeDasharray: 'var(--stroke-dasharray)',
|
||||
strokeWidth: 'var(--hero-line-stroke-width)',
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{linesX}
|
||||
{linesY}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function Circles() {
|
||||
const drawCircle = {
|
||||
hidden: { opacity: 0 },
|
||||
visible: (i: number) => {
|
||||
const delay = 1 + i * 0.5;
|
||||
return { opacity: 1, transition: { opacity: { delay, duration: 0.01 } } };
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<m.path
|
||||
variants={drawCircle}
|
||||
d="M1 41C1 63.0914 18.9086 81 41 81C63.0914 81 81 63.0914 81 41C81 18.9086 63.0914 1 41 1"
|
||||
style={{
|
||||
strokeDasharray: 'var(--stroke-dasharray)',
|
||||
stroke: 'var(--hero-circle-stroke-color)',
|
||||
strokeWidth: 'var(--hero-circle-stroke-width)',
|
||||
transform: 'translate(calc(50% - 480px), calc(50% - 80px))',
|
||||
}}
|
||||
/>
|
||||
|
||||
<m.path
|
||||
variants={drawCircle}
|
||||
d="M1 41C1 63.0914 18.9086 81 41 81C63.0914 81 81 63.0914 81 41C81 18.9086 63.0914 1 41 1"
|
||||
style={{
|
||||
strokeDasharray: 'var(--stroke-dasharray)',
|
||||
stroke: 'var(--hero-circle-stroke-color)',
|
||||
strokeWidth: 'var(--hero-circle-stroke-width)',
|
||||
transform: 'translate(calc(50% + 400px), calc(50% + 80px))',
|
||||
}}
|
||||
/>
|
||||
|
||||
<m.circle
|
||||
cx="50%"
|
||||
cy="50%"
|
||||
fill="var(--hero-circle-stroke-color)"
|
||||
style={{ transform: 'translate(calc(0% - 200px), calc(0% + 200px))' }}
|
||||
initial={{ r: 0 }}
|
||||
animate={{ r: 5 }}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function PlusIcon() {
|
||||
const drawPlus = {
|
||||
hidden: { opacity: 0, pathLength: 0 },
|
||||
visible: (i: number) => {
|
||||
const delay = 1 + i * 0.5;
|
||||
return {
|
||||
opacity: 1,
|
||||
pathLength: 1,
|
||||
transition: {
|
||||
opacity: { delay, duration: 0.01 },
|
||||
pathLength: { delay, bounce: 0, duration: 1.5, type: 'spring' },
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<m.path
|
||||
variants={drawPlus}
|
||||
d="M8 0V16M16 8.08889H0"
|
||||
stroke="var(--hero-plus-stroke-color)"
|
||||
style={{ transform: 'translate(calc(50% - 448px), calc(50% - 128px))' }}
|
||||
/>
|
||||
|
||||
<m.path
|
||||
variants={drawPlus}
|
||||
d="M8 0V16M16 8.08889H0"
|
||||
stroke="var(--hero-plus-stroke-color)"
|
||||
style={{ transform: 'translate(calc(50% + 432px), calc(50% + 192px))' }}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function Texts({ sx, ...other }: BoxProps & MotionProps) {
|
||||
return (
|
||||
<Box
|
||||
component={m.div}
|
||||
variants={varFade('in')}
|
||||
sx={[
|
||||
() => ({
|
||||
left: 0,
|
||||
width: 1,
|
||||
bottom: 0,
|
||||
height: 200,
|
||||
position: 'absolute',
|
||||
}),
|
||||
...(Array.isArray(sx) ? sx : [sx]),
|
||||
]}
|
||||
{...other}
|
||||
>
|
||||
<Box
|
||||
component="svg"
|
||||
sx={[
|
||||
(theme) => ({
|
||||
width: 1,
|
||||
height: 1,
|
||||
'& text': {
|
||||
fill: 'none',
|
||||
fontSize: 200,
|
||||
fontWeight: 800,
|
||||
strokeDasharray: 4,
|
||||
textTransform: 'uppercase',
|
||||
stroke: 'var(--hero-text-stroke-color)',
|
||||
strokeWidth: 'var(--hero-text-stroke-width)',
|
||||
fontFamily: theme.typography.fontSecondaryFamily,
|
||||
},
|
||||
}),
|
||||
]}
|
||||
>
|
||||
<m.text
|
||||
x="0"
|
||||
y="12px"
|
||||
dominantBaseline="hanging"
|
||||
animate={{ x: ['0%', '-50%'] }}
|
||||
transition={{ duration: 64, ease: 'linear', repeat: Infinity }}
|
||||
>
|
||||
Minimal Design System Minimal Design System
|
||||
</m.text>
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
type DotProps = Pick<MotionProps, 'animate' | 'transition'> & {
|
||||
sx?: SxProps<Theme>;
|
||||
color?: PaletteColorKey;
|
||||
};
|
||||
|
||||
function Dot({ color = 'primary', animate, transition, sx, ...other }: DotProps) {
|
||||
return (
|
||||
<Box
|
||||
component={m.div}
|
||||
variants={{
|
||||
initial: { opacity: 0 },
|
||||
animate: { opacity: 1, transition: { duration: 0.64, ease: [0.43, 0.13, 0.23, 0.96] } },
|
||||
}}
|
||||
sx={[
|
||||
() => ({
|
||||
width: 12,
|
||||
height: 12,
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
position: 'absolute',
|
||||
}),
|
||||
...(Array.isArray(sx) ? sx : [sx]),
|
||||
]}
|
||||
{...other}
|
||||
>
|
||||
<Box
|
||||
component={m.div}
|
||||
animate={animate}
|
||||
transition={
|
||||
transition ?? {
|
||||
duration: 6,
|
||||
ease: 'linear',
|
||||
repeat: Infinity,
|
||||
repeatType: 'reverse',
|
||||
}
|
||||
}
|
||||
sx={[
|
||||
(theme) => ({
|
||||
width: 1,
|
||||
height: 1,
|
||||
borderRadius: '50%',
|
||||
boxShadow: `0px -2px 4px 0px ${theme.vars.palette[color].main} inset`,
|
||||
background: `linear-gradient(135deg, ${theme.vars.palette[color].lighter}, ${theme.vars.palette[color].light})`,
|
||||
...theme.applyStyles('dark', {
|
||||
boxShadow: `0px -2px 4px 0px ${theme.vars.palette[color].dark} inset`,
|
||||
}),
|
||||
}),
|
||||
...(Array.isArray(sx) ? sx : [sx]),
|
||||
]}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export function Dots() {
|
||||
return (
|
||||
<>
|
||||
<Dot
|
||||
color="error"
|
||||
animate={{ x: [0, 24] }}
|
||||
sx={{ width: 14, height: 14, transform: 'translate(calc(50% - 457px), calc(50% - 259px))' }}
|
||||
/>
|
||||
|
||||
<Dot
|
||||
color="warning"
|
||||
animate={{ y: [0, 24] }}
|
||||
sx={{ transform: 'translate(calc(50% - 356px), calc(50% + 37px))' }}
|
||||
/>
|
||||
|
||||
<Dot
|
||||
color="info"
|
||||
animate={{ x: [0, 24] }}
|
||||
sx={{ transform: 'translate(calc(50% + 332px), calc(50% + 135px))' }}
|
||||
/>
|
||||
|
||||
<Dot
|
||||
color="secondary"
|
||||
animate={{ x: [0, 24] }}
|
||||
sx={{ transform: 'translate(calc(50% + 430px), calc(50% - 160px))' }}
|
||||
/>
|
||||
|
||||
<Dot
|
||||
color="success"
|
||||
animate={{ y: [0, 24] }}
|
||||
sx={{ transform: 'translate(calc(50% + 136px), calc(50% + 332px))' }}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
@@ -0,0 +1,117 @@
|
||||
import type { MotionProps } from 'framer-motion';
|
||||
import type { BoxProps } from '@mui/material/Box';
|
||||
import type { Theme, SxProps } from '@mui/material/styles';
|
||||
|
||||
import { m } from 'framer-motion';
|
||||
import { varAlpha } from 'minimal-shared/utils';
|
||||
|
||||
import Box from '@mui/material/Box';
|
||||
import Typography from '@mui/material/Typography';
|
||||
|
||||
import { varFade } from 'src/components/animate';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
type TextProps = {
|
||||
sx?: SxProps<Theme>;
|
||||
title: React.ReactNode;
|
||||
variants?: MotionProps['variants'];
|
||||
};
|
||||
|
||||
type SectionTitleProps = BoxProps & {
|
||||
txtGradient?: string;
|
||||
title: React.ReactNode;
|
||||
caption?: React.ReactNode;
|
||||
description?: React.ReactNode;
|
||||
slotProps?: {
|
||||
title?: Omit<TextProps, 'title'>;
|
||||
caption?: Omit<TextProps, 'title'>;
|
||||
description?: Omit<TextProps, 'title'>;
|
||||
};
|
||||
};
|
||||
|
||||
export function SectionTitle({
|
||||
sx,
|
||||
title,
|
||||
caption,
|
||||
slotProps,
|
||||
txtGradient,
|
||||
description,
|
||||
...other
|
||||
}: SectionTitleProps) {
|
||||
return (
|
||||
<Box
|
||||
sx={[
|
||||
{
|
||||
gap: 3,
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
},
|
||||
...(Array.isArray(sx) ? sx : [sx]),
|
||||
]}
|
||||
{...other}
|
||||
>
|
||||
{caption && (
|
||||
<SectionCaption
|
||||
title={caption}
|
||||
variants={slotProps?.caption?.variants}
|
||||
sx={slotProps?.caption?.sx}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Typography
|
||||
component={m.h2}
|
||||
variant="h2"
|
||||
variants={slotProps?.title?.variants ?? varFade('inUp', { distance: 24 })}
|
||||
sx={slotProps?.title?.sx}
|
||||
>
|
||||
{`${title} `}
|
||||
<Box
|
||||
component="span"
|
||||
sx={(theme) => ({
|
||||
opacity: 0.4,
|
||||
display: 'inline-block',
|
||||
...theme.mixins.textGradient(
|
||||
`to right, ${theme.vars.palette.text.primary}, ${varAlpha(theme.vars.palette.text.primaryChannel, 0.2)}`
|
||||
),
|
||||
})}
|
||||
>
|
||||
{txtGradient}
|
||||
</Box>
|
||||
</Typography>
|
||||
|
||||
{description && (
|
||||
<Typography
|
||||
component={m.p}
|
||||
variants={slotProps?.description?.variants ?? varFade('inUp', { distance: 24 })}
|
||||
sx={[
|
||||
{ color: 'text.secondary' },
|
||||
...(Array.isArray(slotProps?.description?.sx)
|
||||
? (slotProps?.description?.sx ?? [])
|
||||
: [slotProps?.description?.sx]),
|
||||
]}
|
||||
>
|
||||
{description}
|
||||
</Typography>
|
||||
)}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function SectionCaption({ title, variants, sx, ...other }: TextProps) {
|
||||
return (
|
||||
<Box
|
||||
component={m.span}
|
||||
variants={variants ?? varFade('inUp', { distance: 24 })}
|
||||
sx={[
|
||||
() => ({ typography: 'overline', color: 'text.disabled' }),
|
||||
...(Array.isArray(sx) ? sx : [sx]),
|
||||
]}
|
||||
{...other}
|
||||
>
|
||||
{title}
|
||||
</Box>
|
||||
);
|
||||
}
|
287
03_source/frontend/src/sections/home/components/svg-elements.tsx
Normal file
287
03_source/frontend/src/sections/home/components/svg-elements.tsx
Normal file
@@ -0,0 +1,287 @@
|
||||
import type { BoxProps } from '@mui/material/Box';
|
||||
import type { Theme, SxProps } from '@mui/material/styles';
|
||||
import type { Transition, MotionProps } from 'framer-motion';
|
||||
|
||||
import { useId } from 'react';
|
||||
import { m } from 'framer-motion';
|
||||
|
||||
import Box from '@mui/material/Box';
|
||||
import { styled } from '@mui/material/styles';
|
||||
|
||||
import { varFade } from 'src/components/animate';
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const baseStyles = (theme: Theme): SxProps<Theme> => ({
|
||||
zIndex: 2,
|
||||
display: 'none',
|
||||
color: 'grey.500',
|
||||
position: 'absolute',
|
||||
'& line': { strokeDasharray: 3, stroke: 'currentColor' },
|
||||
'& path': { fill: 'currentColor', stroke: 'currentColor' },
|
||||
[theme.breakpoints.up(1440)]: { display: 'block' },
|
||||
});
|
||||
|
||||
const transition: Transition = {
|
||||
duration: 0.64,
|
||||
ease: [0.43, 0.13, 0.23, 0.96],
|
||||
};
|
||||
|
||||
type SvgRootProps = React.ComponentProps<typeof SvgRoot>;
|
||||
|
||||
const SvgRoot = styled(m.svg)``;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function FloatLine({ sx, vertical, ...other }: SvgRootProps & { vertical?: boolean }) {
|
||||
return (
|
||||
<SvgRoot
|
||||
sx={[
|
||||
(theme) => ({
|
||||
...baseStyles(theme),
|
||||
width: 1,
|
||||
zIndex: 1,
|
||||
height: '1px',
|
||||
opacity: 0.24,
|
||||
...(vertical && { width: '1px', height: 1 }),
|
||||
}),
|
||||
...(Array.isArray(sx) ? sx : [sx]),
|
||||
]}
|
||||
{...other}
|
||||
>
|
||||
{vertical ? (
|
||||
<m.line
|
||||
x1="0.5"
|
||||
x2="0.5"
|
||||
y1="0"
|
||||
y2="100%"
|
||||
variants={{
|
||||
initial: { y2: '0%' },
|
||||
animate: { y2: '100%', transition },
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<m.line
|
||||
x1="0"
|
||||
x2="100%"
|
||||
y1="0.5"
|
||||
y2="0.5"
|
||||
variants={{
|
||||
initial: { x2: '0%' },
|
||||
animate: { x2: '100%', transition },
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</SvgRoot>
|
||||
);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function FloatPlusIcon({ sx, ...other }: SvgRootProps) {
|
||||
return (
|
||||
<SvgRoot
|
||||
variants={{
|
||||
initial: { scale: 0 },
|
||||
animate: { scale: 1, transition },
|
||||
}}
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
sx={[
|
||||
(theme) => ({
|
||||
...baseStyles(theme),
|
||||
width: 16,
|
||||
height: 16,
|
||||
}),
|
||||
...(Array.isArray(sx) ? sx : [sx]),
|
||||
]}
|
||||
{...other}
|
||||
>
|
||||
<path d="M8 0V16M16 8.08889H0" />
|
||||
</SvgRoot>
|
||||
);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function FloatXIcon({ sx, ...other }: SvgRootProps) {
|
||||
return (
|
||||
<SvgRoot
|
||||
variants={{
|
||||
initial: { scaleX: 0 },
|
||||
animate: { scaleX: 1, transition },
|
||||
}}
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
sx={[
|
||||
(theme) => ({
|
||||
...baseStyles(theme),
|
||||
width: 16,
|
||||
height: 16,
|
||||
}),
|
||||
...(Array.isArray(sx) ? sx : [sx]),
|
||||
]}
|
||||
{...other}
|
||||
>
|
||||
<path d="M14 2L7.96685 8.03315M7.96685 8.03315L2.0663 13.9337M7.96685 8.03315L13.9337 14M7.96685 8.03315L2 2.0663" />
|
||||
</SvgRoot>
|
||||
);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function FloatTriangleLeftIcon({ sx, ...other }: SvgRootProps) {
|
||||
return (
|
||||
<SvgRoot
|
||||
variants={{
|
||||
initial: { scaleY: 0 },
|
||||
animate: { scaleY: 1, transition },
|
||||
}}
|
||||
width="10"
|
||||
height="20"
|
||||
viewBox="0 0 10 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
sx={[
|
||||
(theme) => ({
|
||||
...baseStyles(theme),
|
||||
width: 10,
|
||||
height: 20,
|
||||
}),
|
||||
...(Array.isArray(sx) ? sx : [sx]),
|
||||
]}
|
||||
{...other}
|
||||
>
|
||||
<path d="M10 10L8.74228e-07 20L0 0L10 10Z" />
|
||||
</SvgRoot>
|
||||
);
|
||||
}
|
||||
|
||||
export function FloatTriangleDownIcon({ sx, ...other }: SvgRootProps) {
|
||||
return (
|
||||
<SvgRoot
|
||||
variants={{
|
||||
initial: { scaleX: 0 },
|
||||
animate: { scaleX: 1, transition },
|
||||
}}
|
||||
width="20"
|
||||
height="10"
|
||||
viewBox="0 0 20 10"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
sx={[
|
||||
(theme) => ({
|
||||
...baseStyles(theme),
|
||||
width: 20,
|
||||
height: 10,
|
||||
}),
|
||||
...(Array.isArray(sx) ? sx : [sx]),
|
||||
]}
|
||||
{...other}
|
||||
>
|
||||
<path d="M10 10L0 0H20L10 10Z" />
|
||||
</SvgRoot>
|
||||
);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function CircleSvg({ sx, variants }: SvgRootProps) {
|
||||
const maskId = useId();
|
||||
const clipPathId = useId();
|
||||
const gradientId = useId();
|
||||
|
||||
return (
|
||||
<SvgRoot
|
||||
width="100%"
|
||||
height="100%"
|
||||
viewBox="0 0 560 560"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="none"
|
||||
variants={variants ?? varFade('in')}
|
||||
sx={[
|
||||
() => ({
|
||||
top: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
m: 'auto',
|
||||
width: 560,
|
||||
height: 560,
|
||||
color: 'grey.500',
|
||||
position: 'absolute',
|
||||
}),
|
||||
...(Array.isArray(sx) ? sx : [sx]),
|
||||
]}
|
||||
>
|
||||
<defs>
|
||||
<radialGradient
|
||||
id={gradientId}
|
||||
cx="0"
|
||||
cy="0"
|
||||
r="1"
|
||||
gradientTransform="matrix(280 0 0 280 280 280)"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop />
|
||||
<stop offset="1" stopOpacity={0} />
|
||||
</radialGradient>
|
||||
|
||||
<clipPath id={clipPathId}>
|
||||
<path fill="#fff" d="M0 0H560V560H0z" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
|
||||
<g clipPath={`url(#${clipPathId})`}>
|
||||
<mask
|
||||
id={maskId}
|
||||
style={{ maskType: 'alpha' }}
|
||||
width="560"
|
||||
height="560"
|
||||
x="0"
|
||||
y="0"
|
||||
maskUnits="userSpaceOnUse"
|
||||
>
|
||||
<path fill={`url(#${gradientId})`} d="M0 0H560V560H0z" />
|
||||
</mask>
|
||||
|
||||
<g stroke="currentColor" strokeDasharray={3} mask={`url(#${maskId})`} opacity={0.4}>
|
||||
<circle cx="280" cy="280" r="90" />
|
||||
<circle cx="280" cy="280" r="180" />
|
||||
<path d="M0 0l560 560M560 0L0 560" />
|
||||
</g>
|
||||
</g>
|
||||
</SvgRoot>
|
||||
);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
export function FloatDotIcon({ sx, ...other }: BoxProps<'span'> & MotionProps) {
|
||||
return (
|
||||
<Box
|
||||
component={m.span}
|
||||
variants={{
|
||||
initial: { scale: 0 },
|
||||
animate: { scale: 1, transition },
|
||||
}}
|
||||
sx={[
|
||||
(theme) => ({
|
||||
...baseStyles(theme),
|
||||
width: 12,
|
||||
height: 12,
|
||||
borderRadius: '50%',
|
||||
bgcolor: 'currentColor',
|
||||
}),
|
||||
...(Array.isArray(sx) ? sx : [sx]),
|
||||
]}
|
||||
{...other}
|
||||
/>
|
||||
);
|
||||
}
|
Reference in New Issue
Block a user