@12-apps/ui 1.3.1 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -4
- package/src/components/data-display/Carousel/Carousel.chrome.tsx +83 -0
- package/src/components/data-display/Carousel/Carousel.hooks.ts +88 -0
- package/src/components/data-display/Carousel/Carousel.parts.tsx +346 -0
- package/src/components/data-display/Carousel/Carousel.slide.tsx +190 -0
- package/src/components/data-display/Carousel/Carousel.styles.ts +86 -0
- package/src/components/data-display/Carousel/Carousel.tsx +84 -732
- package/src/components/data-display/HoverCard/HoverCard.animations.ts +73 -0
- package/src/components/data-display/HoverCard/HoverCard.content.tsx +143 -0
- package/src/components/data-display/HoverCard/HoverCard.hooks.ts +180 -0
- package/src/components/data-display/HoverCard/HoverCard.styles.ts +178 -0
- package/src/components/data-display/HoverCard/HoverCard.tsx +117 -631
- package/src/components/data-display/Sheet/Sheet.animations.ts +44 -0
- package/src/components/data-display/Sheet/Sheet.body.tsx +124 -0
- package/src/components/data-display/Sheet/Sheet.drag.ts +203 -0
- package/src/components/data-display/Sheet/Sheet.hooks.ts +318 -0
- package/src/components/data-display/Sheet/Sheet.parts.tsx +224 -0
- package/src/components/data-display/Sheet/Sheet.styles.ts +257 -0
- package/src/components/data-display/Sheet/Sheet.tsx +125 -948
- package/src/components/feedback/Modal/Modal.styles.ts +126 -0
- package/src/components/feedback/Modal/Modal.transitions.tsx +40 -0
- package/src/components/feedback/Modal/Modal.tsx +37 -242
- package/src/components/form/InputOTP/InputOTP.hooks.ts +104 -0
- package/src/components/form/InputOTP/InputOTP.styles.ts +97 -0
- package/src/components/form/InputOTP/InputOTP.tsx +74 -221
- package/src/components/form/Label/Label.parts.tsx +75 -0
- package/src/components/form/Label/Label.styles.ts +206 -0
- package/src/components/form/Label/Label.tsx +73 -325
- package/src/components/form/Menubar/Menubar.hooks.ts +41 -0
- package/src/components/form/Menubar/Menubar.item.tsx +121 -0
- package/src/components/form/Menubar/Menubar.separator.tsx +25 -0
- package/src/components/form/Menubar/Menubar.styles.ts +110 -0
- package/src/components/form/Menubar/Menubar.toolbar.tsx +103 -0
- package/src/components/form/Menubar/Menubar.tsx +64 -347
- package/src/components/form/RadioGroup/RadioGroup.animations.ts +48 -0
- package/src/components/form/RadioGroup/RadioGroup.styles.ts +305 -0
- package/src/components/form/RadioGroup/RadioGroup.tsx +81 -651
- package/src/components/form/RadioGroup/RadioGroup.variants.tsx +291 -0
- package/src/components/form/Slider/Slider.animations.ts +40 -0
- package/src/components/form/Slider/Slider.styles.ts +292 -0
- package/src/components/form/Slider/Slider.tsx +106 -357
- package/src/components/form/Switch/Switch.animations.ts +62 -0
- package/src/components/form/Switch/Switch.parts.tsx +213 -0
- package/src/components/form/Switch/Switch.styles.ts +355 -0
- package/src/components/form/Switch/Switch.tsx +87 -566
- package/src/components/typography/Blockquote/Blockquote.test.stories.tsx +7 -7
- package/src/components/typography/Heading/Heading.styles.ts +101 -0
- package/src/components/typography/Heading/Heading.tsx +48 -164
- package/src/components/utility/AnimatedIcon/AnimatedIcon.animations.ts +274 -0
- package/src/components/utility/AnimatedIcon/AnimatedIcon.styles.ts +231 -0
- package/src/components/utility/AnimatedIcon/AnimatedIcon.tsx +39 -559
- package/src/utils/index.ts +1 -0
- package/src/utils/withDefaults.ts +20 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import type { CSSObject, Theme } from '@mui/material';
|
|
2
|
+
|
|
3
|
+
import type { HeadingProps } from './Heading.types';
|
|
4
|
+
|
|
5
|
+
type Level = NonNullable<HeadingProps['level']>;
|
|
6
|
+
type Weight = NonNullable<HeadingProps['weight']>;
|
|
7
|
+
|
|
8
|
+
const getColorFromTheme = (theme: Theme, color: string): string => {
|
|
9
|
+
if (color === 'neutral') {
|
|
10
|
+
return theme.palette.text.primary;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const colorMap: Record<string, string> = {
|
|
14
|
+
primary: theme.palette.primary.main,
|
|
15
|
+
secondary: theme.palette.secondary.main,
|
|
16
|
+
success: theme.palette.success.main,
|
|
17
|
+
warning: theme.palette.warning.main,
|
|
18
|
+
danger: theme.palette.error.main,
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
return colorMap[color] || theme.palette.text.primary;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const WEIGHTS: Record<Weight, number> = {
|
|
25
|
+
light: 300,
|
|
26
|
+
normal: 400,
|
|
27
|
+
medium: 500,
|
|
28
|
+
semibold: 600,
|
|
29
|
+
bold: 700,
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Each level's metrics, plus the weight it uses when the caller asks for
|
|
34
|
+
* `normal`. A heading's "normal" is not body text's 400 — it is the weight that
|
|
35
|
+
* level is meant to carry, which gets heavier as the level gets larger.
|
|
36
|
+
*/
|
|
37
|
+
const LEVELS: Record<Level, CSSObject & { normalWeight: number }> = {
|
|
38
|
+
display: { fontSize: '4rem', lineHeight: 0.95, letterSpacing: '-0.03em', normalWeight: 800 },
|
|
39
|
+
h1: { fontSize: '3rem', lineHeight: 1.1, letterSpacing: '-0.02em', normalWeight: 700 },
|
|
40
|
+
h2: { fontSize: '2.5rem', lineHeight: 1.2, letterSpacing: '-0.015em', normalWeight: 700 },
|
|
41
|
+
h3: { fontSize: '2rem', lineHeight: 1.25, letterSpacing: '-0.01em', normalWeight: 600 },
|
|
42
|
+
h4: { fontSize: '1.5rem', lineHeight: 1.3, letterSpacing: '-0.005em', normalWeight: 600 },
|
|
43
|
+
h5: { fontSize: '1.25rem', lineHeight: 1.4, normalWeight: 600 },
|
|
44
|
+
h6: { fontSize: '1.125rem', lineHeight: 1.4, normalWeight: 600 },
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/** The two-stop gradient each colour paints its glyphs with. */
|
|
48
|
+
const PRIMARY_STOPS = (theme: Theme): [string, string] => [
|
|
49
|
+
theme.palette.primary.main,
|
|
50
|
+
theme.palette.secondary.main,
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
const GRADIENT_STOPS: Record<string, (theme: Theme) => [string, string]> = {
|
|
54
|
+
primary: PRIMARY_STOPS,
|
|
55
|
+
secondary: (theme) => [theme.palette.secondary.main, theme.palette.primary.main],
|
|
56
|
+
success: (theme) => [theme.palette.success.light, theme.palette.success.dark],
|
|
57
|
+
warning: (theme) => [theme.palette.warning.light, theme.palette.warning.dark],
|
|
58
|
+
danger: (theme) => [theme.palette.error.light, theme.palette.error.dark],
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const gradientFor = (theme: Theme, color: string) => {
|
|
62
|
+
const [from, to] = (GRADIENT_STOPS[color] ?? PRIMARY_STOPS)(theme);
|
|
63
|
+
return `linear-gradient(135deg, ${from} 0%, ${to} 100%)`;
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export interface HeadingFlags {
|
|
67
|
+
customLevel?: string;
|
|
68
|
+
customColor?: string;
|
|
69
|
+
customWeight?: string;
|
|
70
|
+
gradient?: boolean;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export const headingSx = (theme: Theme, flags: HeadingFlags): CSSObject => {
|
|
74
|
+
const { customLevel = 'h2', customColor = 'neutral', customWeight = 'bold', gradient } = flags;
|
|
75
|
+
const { normalWeight, ...metrics } = LEVELS[customLevel as Level] ?? LEVELS.h2;
|
|
76
|
+
|
|
77
|
+
const base: CSSObject = {
|
|
78
|
+
fontFamily: theme.typography.h1.fontFamily,
|
|
79
|
+
margin: 0,
|
|
80
|
+
transition: 'all 0.2s ease',
|
|
81
|
+
...metrics,
|
|
82
|
+
fontWeight:
|
|
83
|
+
customWeight === 'normal' ? normalWeight : (WEIGHTS[customWeight as Weight] ?? WEIGHTS.bold),
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
if (!gradient) {
|
|
87
|
+
return { ...base, color: getColorFromTheme(theme, customColor) };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// The gradient paints the glyphs themselves, so the text must draw no fill of
|
|
91
|
+
// its own for it to show through.
|
|
92
|
+
return {
|
|
93
|
+
...base,
|
|
94
|
+
background: gradientFor(theme, customColor),
|
|
95
|
+
backgroundClip: 'text',
|
|
96
|
+
WebkitBackgroundClip: 'text',
|
|
97
|
+
WebkitTextFillColor: 'transparent',
|
|
98
|
+
MozBackgroundClip: 'text',
|
|
99
|
+
MozTextFillColor: 'transparent',
|
|
100
|
+
};
|
|
101
|
+
};
|
|
@@ -1,177 +1,61 @@
|
|
|
1
|
-
import type { Theme } from '@mui/material';
|
|
2
1
|
import { styled } from '@mui/material/styles';
|
|
3
2
|
import React from 'react';
|
|
4
3
|
|
|
4
|
+
import { headingSx } from './Heading.styles';
|
|
5
|
+
import type { HeadingFlags } from './Heading.styles';
|
|
5
6
|
import type { HeadingProps } from './Heading.types';
|
|
6
7
|
|
|
7
|
-
const
|
|
8
|
-
if (color === 'neutral') {
|
|
9
|
-
return theme.palette.text.primary;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const colorMap: Record<string, string> = {
|
|
13
|
-
primary: theme.palette.primary.main,
|
|
14
|
-
secondary: theme.palette.secondary.main,
|
|
15
|
-
success: theme.palette.success.main,
|
|
16
|
-
warning: theme.palette.warning.main,
|
|
17
|
-
danger: theme.palette.error.main,
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
return colorMap[color] || theme.palette.text.primary;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
// Create styled versions of each heading element
|
|
24
|
-
const createStyledHeading = () =>
|
|
8
|
+
const styledHeading = () =>
|
|
25
9
|
styled('h1', {
|
|
26
10
|
shouldForwardProp: (prop) =>
|
|
27
11
|
!['customLevel', 'customColor', 'customWeight', 'gradient'].includes(prop as string),
|
|
28
|
-
})<{
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
fontWeight:
|
|
59
|
-
customWeight === 'normal' ? 700 : weightMap[customWeight as keyof typeof weightMap],
|
|
60
|
-
},
|
|
61
|
-
h3: {
|
|
62
|
-
fontSize: '2rem',
|
|
63
|
-
lineHeight: 1.25,
|
|
64
|
-
letterSpacing: '-0.01em',
|
|
65
|
-
fontWeight:
|
|
66
|
-
customWeight === 'normal' ? 600 : weightMap[customWeight as keyof typeof weightMap],
|
|
67
|
-
},
|
|
68
|
-
h4: {
|
|
69
|
-
fontSize: '1.5rem',
|
|
70
|
-
lineHeight: 1.3,
|
|
71
|
-
letterSpacing: '-0.005em',
|
|
72
|
-
fontWeight:
|
|
73
|
-
customWeight === 'normal' ? 600 : weightMap[customWeight as keyof typeof weightMap],
|
|
74
|
-
},
|
|
75
|
-
h5: {
|
|
76
|
-
fontSize: '1.25rem',
|
|
77
|
-
lineHeight: 1.4,
|
|
78
|
-
fontWeight:
|
|
79
|
-
customWeight === 'normal' ? 600 : weightMap[customWeight as keyof typeof weightMap],
|
|
80
|
-
},
|
|
81
|
-
h6: {
|
|
82
|
-
fontSize: '1.125rem',
|
|
83
|
-
lineHeight: 1.4,
|
|
84
|
-
fontWeight:
|
|
85
|
-
customWeight === 'normal' ? 600 : weightMap[customWeight as keyof typeof weightMap],
|
|
86
|
-
},
|
|
87
|
-
display: {
|
|
88
|
-
fontSize: '4rem',
|
|
89
|
-
lineHeight: 0.95,
|
|
90
|
-
letterSpacing: '-0.03em',
|
|
91
|
-
fontWeight:
|
|
92
|
-
customWeight === 'normal' ? 800 : weightMap[customWeight as keyof typeof weightMap],
|
|
93
|
-
},
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
const baseStyles = {
|
|
97
|
-
fontFamily: theme.typography.h1.fontFamily,
|
|
98
|
-
margin: 0,
|
|
99
|
-
transition: 'all 0.2s ease',
|
|
100
|
-
...levelStyles[customLevel as keyof typeof levelStyles],
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
// Gradient text effect
|
|
104
|
-
if (gradient) {
|
|
105
|
-
const gradientColor =
|
|
106
|
-
customColor === 'primary'
|
|
107
|
-
? `linear-gradient(135deg, ${theme.palette.primary.main} 0%, ${theme.palette.secondary.main} 100%)`
|
|
108
|
-
: customColor === 'secondary'
|
|
109
|
-
? `linear-gradient(135deg, ${theme.palette.secondary.main} 0%, ${theme.palette.primary.main} 100%)`
|
|
110
|
-
: customColor === 'success'
|
|
111
|
-
? `linear-gradient(135deg, ${theme.palette.success.light} 0%, ${theme.palette.success.dark} 100%)`
|
|
112
|
-
: customColor === 'warning'
|
|
113
|
-
? `linear-gradient(135deg, ${theme.palette.warning.light} 0%, ${theme.palette.warning.dark} 100%)`
|
|
114
|
-
: customColor === 'danger'
|
|
115
|
-
? `linear-gradient(135deg, ${theme.palette.error.light} 0%, ${theme.palette.error.dark} 100%)`
|
|
116
|
-
: `linear-gradient(135deg, ${theme.palette.primary.main} 0%, ${theme.palette.secondary.main} 100%)`;
|
|
117
|
-
|
|
118
|
-
return {
|
|
119
|
-
...baseStyles,
|
|
120
|
-
background: gradientColor,
|
|
121
|
-
backgroundClip: 'text',
|
|
122
|
-
WebkitBackgroundClip: 'text',
|
|
123
|
-
WebkitTextFillColor: 'transparent',
|
|
124
|
-
MozBackgroundClip: 'text',
|
|
125
|
-
MozTextFillColor: 'transparent',
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return {
|
|
130
|
-
...baseStyles,
|
|
131
|
-
color: textColor,
|
|
132
|
-
};
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
// Create styled components for each heading level
|
|
136
|
-
const StyledH1 = createStyledHeading().withComponent('h1');
|
|
137
|
-
const StyledH2 = createStyledHeading().withComponent('h2');
|
|
138
|
-
const StyledH3 = createStyledHeading().withComponent('h3');
|
|
139
|
-
const StyledH4 = createStyledHeading().withComponent('h4');
|
|
140
|
-
const StyledH5 = createStyledHeading().withComponent('h5');
|
|
141
|
-
const StyledH6 = createStyledHeading().withComponent('h6');
|
|
12
|
+
})<HeadingFlags>(({ theme, ...flags }) => ({ ...headingSx(theme, flags) }));
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* One styled component per tag. They share a style function but must be
|
|
16
|
+
* separate components, since `withComponent` fixes the element at definition
|
|
17
|
+
* time — a single component switching tags per render would remount the text.
|
|
18
|
+
*/
|
|
19
|
+
const STYLED_BY_TAG = {
|
|
20
|
+
h1: styledHeading().withComponent('h1'),
|
|
21
|
+
h2: styledHeading().withComponent('h2'),
|
|
22
|
+
h3: styledHeading().withComponent('h3'),
|
|
23
|
+
h4: styledHeading().withComponent('h4'),
|
|
24
|
+
h5: styledHeading().withComponent('h5'),
|
|
25
|
+
h6: styledHeading().withComponent('h6'),
|
|
26
|
+
} as const;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Which tag each level renders. `display` is a size, not a rank, so it uses the
|
|
30
|
+
* h1 element — the document still gets one level-one heading rather than an
|
|
31
|
+
* unnamed tag outside the outline.
|
|
32
|
+
*/
|
|
33
|
+
const TAG_FOR_LEVEL: Record<string, keyof typeof STYLED_BY_TAG> = {
|
|
34
|
+
display: 'h1',
|
|
35
|
+
h1: 'h1',
|
|
36
|
+
h2: 'h2',
|
|
37
|
+
h3: 'h3',
|
|
38
|
+
h4: 'h4',
|
|
39
|
+
h5: 'h5',
|
|
40
|
+
h6: 'h6',
|
|
41
|
+
};
|
|
142
42
|
|
|
143
43
|
export const Heading = React.forwardRef<globalThis.HTMLHeadingElement, HeadingProps>(
|
|
144
|
-
(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
case 'h1':
|
|
160
|
-
case 'display':
|
|
161
|
-
return <StyledH1 {...commonProps}>{children}</StyledH1>;
|
|
162
|
-
case 'h2':
|
|
163
|
-
return <StyledH2 {...commonProps}>{children}</StyledH2>;
|
|
164
|
-
case 'h3':
|
|
165
|
-
return <StyledH3 {...commonProps}>{children}</StyledH3>;
|
|
166
|
-
case 'h4':
|
|
167
|
-
return <StyledH4 {...commonProps}>{children}</StyledH4>;
|
|
168
|
-
case 'h5':
|
|
169
|
-
return <StyledH5 {...commonProps}>{children}</StyledH5>;
|
|
170
|
-
case 'h6':
|
|
171
|
-
return <StyledH6 {...commonProps}>{children}</StyledH6>;
|
|
172
|
-
default:
|
|
173
|
-
return <StyledH2 {...commonProps}>{children}</StyledH2>;
|
|
174
|
-
}
|
|
44
|
+
({ level = 'h2', color = 'neutral', weight = 'bold', gradient = false, children, ...props }, ref) => {
|
|
45
|
+
const Styled = STYLED_BY_TAG[TAG_FOR_LEVEL[level] ?? 'h2'];
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<Styled
|
|
49
|
+
ref={ref}
|
|
50
|
+
customLevel={level}
|
|
51
|
+
customColor={color}
|
|
52
|
+
customWeight={weight}
|
|
53
|
+
gradient={gradient}
|
|
54
|
+
{...props}
|
|
55
|
+
>
|
|
56
|
+
{children}
|
|
57
|
+
</Styled>
|
|
58
|
+
);
|
|
175
59
|
},
|
|
176
60
|
);
|
|
177
61
|
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import { keyframes } from '@mui/material';
|
|
2
|
+
|
|
3
|
+
export const rotateAnimation = keyframes`
|
|
4
|
+
from {
|
|
5
|
+
transform: rotate(0deg);
|
|
6
|
+
}
|
|
7
|
+
to {
|
|
8
|
+
transform: rotate(360deg);
|
|
9
|
+
}
|
|
10
|
+
`;
|
|
11
|
+
|
|
12
|
+
export const pulseAnimation = keyframes`
|
|
13
|
+
0% {
|
|
14
|
+
transform: scale(1);
|
|
15
|
+
opacity: 1;
|
|
16
|
+
}
|
|
17
|
+
50% {
|
|
18
|
+
transform: scale(1.1);
|
|
19
|
+
opacity: 0.8;
|
|
20
|
+
}
|
|
21
|
+
100% {
|
|
22
|
+
transform: scale(1);
|
|
23
|
+
opacity: 1;
|
|
24
|
+
}
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
export const translateAnimation = keyframes`
|
|
28
|
+
0% {
|
|
29
|
+
transform: translateY(0px);
|
|
30
|
+
}
|
|
31
|
+
50% {
|
|
32
|
+
transform: translateY(-8px);
|
|
33
|
+
}
|
|
34
|
+
100% {
|
|
35
|
+
transform: translateY(0px);
|
|
36
|
+
}
|
|
37
|
+
`;
|
|
38
|
+
|
|
39
|
+
export const glowPulseAnimation = keyframes`
|
|
40
|
+
0% {
|
|
41
|
+
box-shadow: 0 0 5px currentColor, 0 0 10px currentColor, 0 0 15px currentColor;
|
|
42
|
+
}
|
|
43
|
+
50% {
|
|
44
|
+
box-shadow: 0 0 10px currentColor, 0 0 20px currentColor, 0 0 30px currentColor;
|
|
45
|
+
}
|
|
46
|
+
100% {
|
|
47
|
+
box-shadow: 0 0 5px currentColor, 0 0 10px currentColor, 0 0 15px currentColor;
|
|
48
|
+
}
|
|
49
|
+
`;
|
|
50
|
+
|
|
51
|
+
// New animation keyframes
|
|
52
|
+
export const bounceAnimation = keyframes`
|
|
53
|
+
0%, 20%, 50%, 80%, 100% {
|
|
54
|
+
transform: translateY(0);
|
|
55
|
+
}
|
|
56
|
+
40% {
|
|
57
|
+
transform: translateY(-20px);
|
|
58
|
+
}
|
|
59
|
+
60% {
|
|
60
|
+
transform: translateY(-10px);
|
|
61
|
+
}
|
|
62
|
+
`;
|
|
63
|
+
|
|
64
|
+
export const shakeAnimation = keyframes`
|
|
65
|
+
0%, 100% {
|
|
66
|
+
transform: translateX(0);
|
|
67
|
+
}
|
|
68
|
+
10%, 30%, 50%, 70%, 90% {
|
|
69
|
+
transform: translateX(-4px);
|
|
70
|
+
}
|
|
71
|
+
20%, 40%, 60%, 80% {
|
|
72
|
+
transform: translateX(4px);
|
|
73
|
+
}
|
|
74
|
+
`;
|
|
75
|
+
|
|
76
|
+
export const flipAnimation = keyframes`
|
|
77
|
+
0% {
|
|
78
|
+
transform: perspective(400px) rotateY(0);
|
|
79
|
+
}
|
|
80
|
+
100% {
|
|
81
|
+
transform: perspective(400px) rotateY(360deg);
|
|
82
|
+
}
|
|
83
|
+
`;
|
|
84
|
+
|
|
85
|
+
export const spinAnimation = keyframes`
|
|
86
|
+
0% {
|
|
87
|
+
transform: rotate(0deg) scale(1);
|
|
88
|
+
}
|
|
89
|
+
50% {
|
|
90
|
+
transform: rotate(180deg) scale(1.2);
|
|
91
|
+
}
|
|
92
|
+
100% {
|
|
93
|
+
transform: rotate(360deg) scale(1);
|
|
94
|
+
}
|
|
95
|
+
`;
|
|
96
|
+
|
|
97
|
+
export const fadeInOutAnimation = keyframes`
|
|
98
|
+
0%, 100% {
|
|
99
|
+
opacity: 0.3;
|
|
100
|
+
}
|
|
101
|
+
50% {
|
|
102
|
+
opacity: 1;
|
|
103
|
+
}
|
|
104
|
+
`;
|
|
105
|
+
|
|
106
|
+
export const heartbeatAnimation = keyframes`
|
|
107
|
+
0%, 100% {
|
|
108
|
+
transform: scale(1);
|
|
109
|
+
}
|
|
110
|
+
5% {
|
|
111
|
+
transform: scale(1.25);
|
|
112
|
+
}
|
|
113
|
+
10% {
|
|
114
|
+
transform: scale(1);
|
|
115
|
+
}
|
|
116
|
+
15% {
|
|
117
|
+
transform: scale(1.25);
|
|
118
|
+
}
|
|
119
|
+
20% {
|
|
120
|
+
transform: scale(1);
|
|
121
|
+
}
|
|
122
|
+
`;
|
|
123
|
+
|
|
124
|
+
export const wobbleAnimation = keyframes`
|
|
125
|
+
0%, 100% {
|
|
126
|
+
transform: translateX(0) rotate(0deg);
|
|
127
|
+
}
|
|
128
|
+
15% {
|
|
129
|
+
transform: translateX(-10px) rotate(-5deg);
|
|
130
|
+
}
|
|
131
|
+
30% {
|
|
132
|
+
transform: translateX(8px) rotate(3deg);
|
|
133
|
+
}
|
|
134
|
+
45% {
|
|
135
|
+
transform: translateX(-6px) rotate(-3deg);
|
|
136
|
+
}
|
|
137
|
+
60% {
|
|
138
|
+
transform: translateX(4px) rotate(2deg);
|
|
139
|
+
}
|
|
140
|
+
75% {
|
|
141
|
+
transform: translateX(-2px) rotate(-1deg);
|
|
142
|
+
}
|
|
143
|
+
`;
|
|
144
|
+
|
|
145
|
+
export const morphAnimation = keyframes`
|
|
146
|
+
0%, 100% {
|
|
147
|
+
border-radius: 50%;
|
|
148
|
+
transform: scale(1);
|
|
149
|
+
}
|
|
150
|
+
25% {
|
|
151
|
+
border-radius: 30%;
|
|
152
|
+
transform: scale(1.1);
|
|
153
|
+
}
|
|
154
|
+
50% {
|
|
155
|
+
border-radius: 20%;
|
|
156
|
+
transform: scale(0.95);
|
|
157
|
+
}
|
|
158
|
+
75% {
|
|
159
|
+
border-radius: 40%;
|
|
160
|
+
transform: scale(1.05);
|
|
161
|
+
}
|
|
162
|
+
`;
|
|
163
|
+
|
|
164
|
+
export const swingAnimation = keyframes`
|
|
165
|
+
20% {
|
|
166
|
+
transform: rotate(15deg);
|
|
167
|
+
}
|
|
168
|
+
40% {
|
|
169
|
+
transform: rotate(-10deg);
|
|
170
|
+
}
|
|
171
|
+
60% {
|
|
172
|
+
transform: rotate(5deg);
|
|
173
|
+
}
|
|
174
|
+
80% {
|
|
175
|
+
transform: rotate(-5deg);
|
|
176
|
+
}
|
|
177
|
+
100% {
|
|
178
|
+
transform: rotate(0deg);
|
|
179
|
+
}
|
|
180
|
+
`;
|
|
181
|
+
|
|
182
|
+
export const floatAnimation = keyframes`
|
|
183
|
+
0%, 100% {
|
|
184
|
+
transform: translateY(0) translateX(0);
|
|
185
|
+
}
|
|
186
|
+
33% {
|
|
187
|
+
transform: translateY(-10px) translateX(-5px);
|
|
188
|
+
}
|
|
189
|
+
66% {
|
|
190
|
+
transform: translateY(5px) translateX(5px);
|
|
191
|
+
}
|
|
192
|
+
`;
|
|
193
|
+
|
|
194
|
+
export const jelloAnimation = keyframes`
|
|
195
|
+
0%, 100% {
|
|
196
|
+
transform: scale(1, 1);
|
|
197
|
+
}
|
|
198
|
+
25% {
|
|
199
|
+
transform: scale(0.9, 1.1);
|
|
200
|
+
}
|
|
201
|
+
50% {
|
|
202
|
+
transform: scale(1.1, 0.9);
|
|
203
|
+
}
|
|
204
|
+
75% {
|
|
205
|
+
transform: scale(0.95, 1.05);
|
|
206
|
+
}
|
|
207
|
+
`;
|
|
208
|
+
|
|
209
|
+
export const rippleAnimation = keyframes`
|
|
210
|
+
0% {
|
|
211
|
+
transform: scale(0.8);
|
|
212
|
+
opacity: 1;
|
|
213
|
+
}
|
|
214
|
+
100% {
|
|
215
|
+
transform: scale(2);
|
|
216
|
+
opacity: 0;
|
|
217
|
+
}
|
|
218
|
+
`;
|
|
219
|
+
|
|
220
|
+
export const neonFlickerAnimation = keyframes`
|
|
221
|
+
0%, 100% {
|
|
222
|
+
opacity: 1;
|
|
223
|
+
filter: brightness(1) drop-shadow(0 0 10px currentColor);
|
|
224
|
+
}
|
|
225
|
+
10% {
|
|
226
|
+
opacity: 0.8;
|
|
227
|
+
filter: brightness(0.8) drop-shadow(0 0 5px currentColor);
|
|
228
|
+
}
|
|
229
|
+
20% {
|
|
230
|
+
opacity: 1;
|
|
231
|
+
filter: brightness(1.2) drop-shadow(0 0 15px currentColor);
|
|
232
|
+
}
|
|
233
|
+
30% {
|
|
234
|
+
opacity: 0.9;
|
|
235
|
+
filter: brightness(0.9) drop-shadow(0 0 8px currentColor);
|
|
236
|
+
}
|
|
237
|
+
40% {
|
|
238
|
+
opacity: 1;
|
|
239
|
+
filter: brightness(1.1) drop-shadow(0 0 12px currentColor);
|
|
240
|
+
}
|
|
241
|
+
50% {
|
|
242
|
+
opacity: 0.95;
|
|
243
|
+
filter: brightness(1) drop-shadow(0 0 10px currentColor);
|
|
244
|
+
}
|
|
245
|
+
60% {
|
|
246
|
+
opacity: 0.85;
|
|
247
|
+
filter: brightness(0.85) drop-shadow(0 0 6px currentColor);
|
|
248
|
+
}
|
|
249
|
+
70% {
|
|
250
|
+
opacity: 1;
|
|
251
|
+
filter: brightness(1.15) drop-shadow(0 0 14px currentColor);
|
|
252
|
+
}
|
|
253
|
+
80% {
|
|
254
|
+
opacity: 0.9;
|
|
255
|
+
filter: brightness(0.95) drop-shadow(0 0 9px currentColor);
|
|
256
|
+
}
|
|
257
|
+
90% {
|
|
258
|
+
opacity: 1;
|
|
259
|
+
filter: brightness(1.05) drop-shadow(0 0 11px currentColor);
|
|
260
|
+
}
|
|
261
|
+
`;
|
|
262
|
+
|
|
263
|
+
export const breatheAnimation = keyframes`
|
|
264
|
+
0%, 100% {
|
|
265
|
+
transform: scale(1);
|
|
266
|
+
filter: brightness(1);
|
|
267
|
+
}
|
|
268
|
+
50% {
|
|
269
|
+
transform: scale(1.05);
|
|
270
|
+
filter: brightness(1.2);
|
|
271
|
+
}
|
|
272
|
+
`;
|
|
273
|
+
|
|
274
|
+
// Size configurations
|