@udixio/ui-react 2.5.2 → 2.7.0
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/CHANGELOG.md +41 -0
- package/dist/index.cjs +2 -2
- package/dist/index.js +2566 -2264
- package/dist/lib/components/Button.d.ts.map +1 -1
- package/dist/lib/components/Card.d.ts.map +1 -1
- package/dist/lib/components/Carousel.d.ts +0 -2
- package/dist/lib/components/Carousel.d.ts.map +1 -1
- package/dist/lib/components/Fab.d.ts +1 -1
- package/dist/lib/components/Fab.d.ts.map +1 -1
- package/dist/lib/components/FabMenu.d.ts +9 -0
- package/dist/lib/components/FabMenu.d.ts.map +1 -0
- package/dist/lib/components/IconButton.d.ts.map +1 -1
- package/dist/lib/components/NavigationRail.d.ts.map +1 -1
- package/dist/lib/components/NavigationRailItem.d.ts.map +1 -1
- package/dist/lib/components/Tab.d.ts.map +1 -1
- package/dist/lib/components/ToolTip.d.ts.map +1 -1
- package/dist/lib/components/index.d.ts +1 -0
- package/dist/lib/components/index.d.ts.map +1 -1
- package/dist/lib/effects/AnimateOnScroll.d.ts.map +1 -1
- package/dist/lib/effects/State.d.ts +26 -0
- package/dist/lib/effects/State.d.ts.map +1 -0
- package/dist/lib/effects/index.d.ts +1 -0
- package/dist/lib/effects/index.d.ts.map +1 -1
- package/dist/lib/effects/ripple/RippleEffect.d.ts.map +1 -1
- package/dist/lib/interfaces/button.interface.d.ts +4 -1
- package/dist/lib/interfaces/button.interface.d.ts.map +1 -1
- package/dist/lib/interfaces/fab-menu.interface.d.ts +12 -0
- package/dist/lib/interfaces/fab-menu.interface.d.ts.map +1 -0
- package/dist/lib/interfaces/fab.interface.d.ts +2 -2
- package/dist/lib/interfaces/fab.interface.d.ts.map +1 -1
- package/dist/lib/interfaces/index.d.ts +1 -0
- package/dist/lib/interfaces/index.d.ts.map +1 -1
- package/dist/lib/interfaces/side-sheet.interface.d.ts +1 -1
- package/dist/lib/interfaces/side-sheet.interface.d.ts.map +1 -1
- package/dist/lib/styles/button.style.d.ts +43 -3
- package/dist/lib/styles/button.style.d.ts.map +1 -1
- package/dist/lib/styles/card.style.d.ts +9 -1
- package/dist/lib/styles/card.style.d.ts.map +1 -1
- package/dist/lib/styles/carousel-item.style.d.ts +11 -1
- package/dist/lib/styles/carousel-item.style.d.ts.map +1 -1
- package/dist/lib/styles/carousel.style.d.ts +16 -1
- package/dist/lib/styles/carousel.style.d.ts.map +1 -1
- package/dist/lib/styles/divider.style.d.ts +8 -2
- package/dist/lib/styles/divider.style.d.ts.map +1 -1
- package/dist/lib/styles/fab-menu.style.d.ts +83 -0
- package/dist/lib/styles/fab-menu.style.d.ts.map +1 -0
- package/dist/lib/styles/fab.style.d.ts +29 -5
- package/dist/lib/styles/fab.style.d.ts.map +1 -1
- package/dist/lib/styles/icon-button.style.d.ts +37 -1
- package/dist/lib/styles/icon-button.style.d.ts.map +1 -1
- package/dist/lib/styles/index.d.ts +2 -0
- package/dist/lib/styles/index.d.ts.map +1 -1
- package/dist/lib/styles/navigation-rail-item.style.d.ts +11 -1
- package/dist/lib/styles/navigation-rail-item.style.d.ts.map +1 -1
- package/dist/lib/styles/navigation-rail.style.d.ts +31 -1
- package/dist/lib/styles/navigation-rail.style.d.ts.map +1 -1
- package/dist/lib/styles/progress-indicator.style.d.ts +12 -1
- package/dist/lib/styles/progress-indicator.style.d.ts.map +1 -1
- package/dist/lib/styles/side-sheet.style.d.ts +20 -3
- package/dist/lib/styles/side-sheet.style.d.ts.map +1 -1
- package/dist/lib/styles/slider.style.d.ts +21 -2
- package/dist/lib/styles/slider.style.d.ts.map +1 -1
- package/dist/lib/styles/snackbar.style.d.ts +14 -3
- package/dist/lib/styles/snackbar.style.d.ts.map +1 -1
- package/dist/lib/styles/switch.style.d.ts +14 -2
- package/dist/lib/styles/switch.style.d.ts.map +1 -1
- package/dist/lib/styles/tab.style.d.ts +12 -2
- package/dist/lib/styles/tab.style.d.ts.map +1 -1
- package/dist/lib/styles/tabs.style.d.ts +17 -2
- package/dist/lib/styles/tabs.style.d.ts.map +1 -1
- package/dist/lib/styles/text-field.style.d.ts +23 -2
- package/dist/lib/styles/text-field.style.d.ts.map +1 -1
- package/dist/lib/styles/tooltip.style.d.ts +20 -3
- package/dist/lib/styles/tooltip.style.d.ts.map +1 -1
- package/dist/lib/utils/styles/get-classname.d.ts +3 -0
- package/dist/lib/utils/styles/get-classname.d.ts.map +1 -1
- package/dist/lib/utils/styles/index.d.ts +1 -0
- package/dist/lib/utils/styles/index.d.ts.map +1 -1
- package/dist/lib/utils/styles/use-classnames.d.ts +6 -0
- package/dist/lib/utils/styles/use-classnames.d.ts.map +1 -0
- package/package.json +3 -3
- package/src/lib/components/Button.tsx +54 -20
- package/src/lib/components/Card.tsx +11 -9
- package/src/lib/components/Carousel.tsx +70 -205
- package/src/lib/components/CarouselItem.tsx +2 -2
- package/src/lib/components/Divider.tsx +2 -2
- package/src/lib/components/Fab.tsx +22 -21
- package/src/lib/components/FabMenu.tsx +229 -0
- package/src/lib/components/IconButton.tsx +24 -30
- package/src/lib/components/NavigationRail.tsx +7 -4
- package/src/lib/components/NavigationRailItem.tsx +13 -4
- package/src/lib/components/ProgressIndicator.tsx +2 -2
- package/src/lib/components/SideSheet.tsx +2 -2
- package/src/lib/components/Slider.tsx +2 -2
- package/src/lib/components/Snackbar.tsx +2 -2
- package/src/lib/components/Switch.tsx +2 -2
- package/src/lib/components/Tab.tsx +11 -11
- package/src/lib/components/Tabs.tsx +2 -2
- package/src/lib/components/TextField.tsx +2 -2
- package/src/lib/components/ToolTip.tsx +9 -3
- package/src/lib/components/index.ts +1 -0
- package/src/lib/effects/AnimateOnScroll.ts +51 -18
- package/src/lib/effects/State.tsx +83 -0
- package/src/lib/effects/index.ts +1 -0
- package/src/lib/effects/ripple/RippleEffect.tsx +40 -27
- package/src/lib/interfaces/button.interface.ts +5 -1
- package/src/lib/interfaces/fab-menu.interface.ts +12 -0
- package/src/lib/interfaces/fab.interface.ts +8 -2
- package/src/lib/interfaces/index.ts +1 -0
- package/src/lib/interfaces/side-sheet.interface.tsx +1 -1
- package/src/lib/styles/button.style.ts +127 -136
- package/src/lib/styles/card.style.ts +22 -17
- package/src/lib/styles/carousel-item.style.ts +23 -9
- package/src/lib/styles/carousel.style.ts +17 -5
- package/src/lib/styles/divider.style.ts +27 -13
- package/src/lib/styles/fab-menu.style.ts +28 -0
- package/src/lib/styles/fab.style.ts +41 -43
- package/src/lib/styles/icon-button.style.ts +160 -149
- package/src/lib/styles/index.ts +2 -0
- package/src/lib/styles/navigation-rail-item.style.ts +49 -40
- package/src/lib/styles/navigation-rail.style.ts +31 -15
- package/src/lib/styles/progress-indicator.style.ts +49 -36
- package/src/lib/styles/side-sheet.style.ts +41 -27
- package/src/lib/styles/slider.style.ts +37 -23
- package/src/lib/styles/snackbar.style.ts +22 -10
- package/src/lib/styles/switch.style.ts +61 -45
- package/src/lib/styles/tab.style.ts +76 -66
- package/src/lib/styles/tabs.style.ts +19 -10
- package/src/lib/styles/text-field.style.ts +108 -97
- package/src/lib/styles/tooltip.style.ts +42 -33
- package/src/lib/utils/styles/get-classname.ts +23 -0
- package/src/lib/utils/styles/index.ts +1 -0
- package/src/lib/utils/styles/use-classnames.ts +25 -0
- package/src/tests/useClassNames.spec.tsx +82 -0
|
@@ -152,10 +152,11 @@ function queryJsObserverCandidates(
|
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
// Utility: identify presence of in/out classes
|
|
155
|
-
function
|
|
156
|
-
return
|
|
155
|
+
function hasOutClass(cls: DOMTokenList, prefix: string): boolean {
|
|
156
|
+
return Array.from(cls).some(
|
|
157
|
+
(className) => className.startsWith(prefix) && className.includes('-out'),
|
|
158
|
+
);
|
|
157
159
|
}
|
|
158
|
-
|
|
159
160
|
// Utility: set run flags for a given direction ("in" or "out"), always ensuring generic run flag exists
|
|
160
161
|
function setRunFlag(el: HTMLElement, prefix: string, dir: 'in' | 'out'): void {
|
|
161
162
|
el.setAttribute(`data-${prefix}-run`, ``);
|
|
@@ -163,12 +164,20 @@ function setRunFlag(el: HTMLElement, prefix: string, dir: 'in' | 'out'): void {
|
|
|
163
164
|
}
|
|
164
165
|
|
|
165
166
|
// Utility: reset run flags and restart animation timeline without changing computed styles
|
|
166
|
-
function resetRunFlags(
|
|
167
|
+
function resetRunFlags(
|
|
168
|
+
el: HTMLElement,
|
|
169
|
+
prefix: string,
|
|
170
|
+
direction?: 'in' | 'out',
|
|
171
|
+
): void {
|
|
167
172
|
const currentAnimationName = el.style.animationName;
|
|
168
173
|
el.style.animationName = 'none';
|
|
169
174
|
el.removeAttribute(`data-${prefix}-run`);
|
|
170
|
-
|
|
171
|
-
|
|
175
|
+
if (!direction) {
|
|
176
|
+
el.removeAttribute(`data-${prefix}-in-run`);
|
|
177
|
+
el.removeAttribute(`data-${prefix}-out-run`);
|
|
178
|
+
} else {
|
|
179
|
+
el.removeAttribute(`data-${prefix}-${direction}-run`);
|
|
180
|
+
}
|
|
172
181
|
void (el as HTMLElement).offsetWidth; // reflow to restart animations
|
|
173
182
|
el.style.animationName = currentAnimationName;
|
|
174
183
|
}
|
|
@@ -198,11 +207,9 @@ function addAnimationLifecycle(el: HTMLElement, prefix: string): void {
|
|
|
198
207
|
|
|
199
208
|
const onEndOrCancel = (e: AnimationEvent) => {
|
|
200
209
|
if (e.target !== el) return;
|
|
210
|
+
// If an IN animation just finished, persist a completion flag so it won't replay on upward scroll
|
|
211
|
+
|
|
201
212
|
el.removeAttribute(`data-${prefix}-animating`);
|
|
202
|
-
// Clear directional run flags so a new trigger can happen after completion
|
|
203
|
-
el.removeAttribute(`data-${prefix}-in-run`);
|
|
204
|
-
el.removeAttribute(`data-${prefix}-out-run`);
|
|
205
|
-
// Note: keep generic data-{prefix}-run for style stability
|
|
206
213
|
};
|
|
207
214
|
|
|
208
215
|
el.addEventListener('animationstart', onStart as EventListener);
|
|
@@ -229,6 +236,21 @@ export function initAnimateOnScroll(
|
|
|
229
236
|
// Setup JS observers for non-scroll-driven animations
|
|
230
237
|
const observed = new WeakSet<Element>();
|
|
231
238
|
|
|
239
|
+
// Track scroll direction to prevent triggering IN when scrolling up
|
|
240
|
+
let lastScrollY =
|
|
241
|
+
typeof window !== 'undefined'
|
|
242
|
+
? window.pageYOffset || window.scrollY || 0
|
|
243
|
+
: 0;
|
|
244
|
+
let scrollingDown = true; // default allow initial IN
|
|
245
|
+
const onScrollDir = () => {
|
|
246
|
+
const y = window.pageYOffset || window.scrollY || 0;
|
|
247
|
+
scrollingDown = y >= lastScrollY;
|
|
248
|
+
lastScrollY = y;
|
|
249
|
+
};
|
|
250
|
+
if (typeof window !== 'undefined') {
|
|
251
|
+
window.addEventListener('scroll', onScrollDir, { passive: true });
|
|
252
|
+
}
|
|
253
|
+
|
|
232
254
|
const io = new IntersectionObserver(
|
|
233
255
|
(entries) => {
|
|
234
256
|
for (const entry of entries) {
|
|
@@ -239,17 +261,25 @@ export function initAnimateOnScroll(
|
|
|
239
261
|
// If an animation is in progress, avoid re-triggering or flipping direction
|
|
240
262
|
if (el.hasAttribute(`data-${prefix}-animating`)) continue;
|
|
241
263
|
|
|
242
|
-
const isOut = el.classList
|
|
264
|
+
const isOut = hasOutClass(el.classList, prefix);
|
|
243
265
|
|
|
244
|
-
if (
|
|
266
|
+
if (entry.isIntersecting) {
|
|
267
|
+
if (isOut) {
|
|
268
|
+
resetRunFlags(el, prefix, 'out');
|
|
269
|
+
}
|
|
245
270
|
setRunFlag(el, prefix, 'in');
|
|
271
|
+
|
|
246
272
|
if (once) io.unobserve(el);
|
|
247
|
-
} else
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
273
|
+
} else {
|
|
274
|
+
if (!once) {
|
|
275
|
+
if (!scrollingDown) {
|
|
276
|
+
resetRunFlags(el, prefix, 'in');
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (isOut) {
|
|
280
|
+
setRunFlag(el, prefix, 'out');
|
|
281
|
+
}
|
|
282
|
+
}
|
|
253
283
|
}
|
|
254
284
|
}
|
|
255
285
|
},
|
|
@@ -349,6 +379,9 @@ export function initAnimateOnScroll(
|
|
|
349
379
|
// Public cleanup
|
|
350
380
|
return () => {
|
|
351
381
|
if (cleanupScrollDriven) cleanupScrollDriven();
|
|
382
|
+
if (typeof window !== 'undefined') {
|
|
383
|
+
window.removeEventListener('scroll', onScrollDir as EventListener);
|
|
384
|
+
}
|
|
352
385
|
io.disconnect();
|
|
353
386
|
};
|
|
354
387
|
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { RippleEffect } from './ripple';
|
|
2
|
+
import {
|
|
3
|
+
ClassNameComponent,
|
|
4
|
+
classNames,
|
|
5
|
+
createUseClassNames,
|
|
6
|
+
ReactProps,
|
|
7
|
+
} from '../utils';
|
|
8
|
+
import { useEffect, useRef, useState } from 'react';
|
|
9
|
+
|
|
10
|
+
export interface StateInterface {
|
|
11
|
+
type: 'div';
|
|
12
|
+
props: {
|
|
13
|
+
colorName: string;
|
|
14
|
+
stateClassName?:
|
|
15
|
+
| string
|
|
16
|
+
| 'state-ripple-group'
|
|
17
|
+
| 'state-group'
|
|
18
|
+
| 'state-layer';
|
|
19
|
+
className?: string;
|
|
20
|
+
style?: React.CSSProperties;
|
|
21
|
+
};
|
|
22
|
+
states: { isClient: boolean };
|
|
23
|
+
elements: ['stateLayer'];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const State = ({
|
|
27
|
+
style,
|
|
28
|
+
colorName,
|
|
29
|
+
stateClassName = 'state-ripple-group',
|
|
30
|
+
className,
|
|
31
|
+
}: ReactProps<StateInterface>) => {
|
|
32
|
+
const ref = useRef<HTMLDivElement>(null);
|
|
33
|
+
const groupStateRef = useRef<HTMLElement | null>(null);
|
|
34
|
+
|
|
35
|
+
const [isClient, setIsClient] = useState(false);
|
|
36
|
+
const styles = useStateStyle({
|
|
37
|
+
isClient,
|
|
38
|
+
stateClassName,
|
|
39
|
+
className,
|
|
40
|
+
colorName,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
if (ref.current && stateClassName !== 'state-layer') {
|
|
45
|
+
const groupName = !stateClassName.includes('[')
|
|
46
|
+
? 'group'
|
|
47
|
+
: stateClassName.split('[')[1].split(']')[0];
|
|
48
|
+
const furthestGroupState = ref.current.closest(
|
|
49
|
+
`.${groupName}:not(.${groupName} .${groupName})`,
|
|
50
|
+
);
|
|
51
|
+
groupStateRef.current = furthestGroupState as HTMLElement | null;
|
|
52
|
+
}
|
|
53
|
+
setIsClient(true);
|
|
54
|
+
}, []);
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<div
|
|
58
|
+
ref={ref}
|
|
59
|
+
className={styles.stateLayer}
|
|
60
|
+
style={{
|
|
61
|
+
['--state-color' as any]: `var(--default-color, var(--color-${colorName}))`,
|
|
62
|
+
...style,
|
|
63
|
+
}}
|
|
64
|
+
>
|
|
65
|
+
{isClient && <RippleEffect triggerRef={groupStateRef} />}
|
|
66
|
+
</div>
|
|
67
|
+
);
|
|
68
|
+
};
|
|
69
|
+
// ... existing code ...
|
|
70
|
+
const cardConfig: ClassNameComponent<StateInterface> = ({
|
|
71
|
+
isClient,
|
|
72
|
+
stateClassName,
|
|
73
|
+
}) => ({
|
|
74
|
+
stateLayer: classNames([
|
|
75
|
+
stateClassName,
|
|
76
|
+
'w-full top-0 left-0 h-full absolute pointer-events-none overflow-hidden',
|
|
77
|
+
]),
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
export const useStateStyle = createUseClassNames<StateInterface>(
|
|
81
|
+
'stateLayer',
|
|
82
|
+
cardConfig,
|
|
83
|
+
);
|
package/src/lib/effects/index.ts
CHANGED
|
@@ -12,37 +12,38 @@ const RippleEffect: React.FC<RippleEffectProps> = ({
|
|
|
12
12
|
}) => {
|
|
13
13
|
const ripple = {
|
|
14
14
|
initial: {
|
|
15
|
-
opacity:
|
|
16
|
-
|
|
17
|
-
width: '25%',
|
|
18
|
-
height: '25%',
|
|
15
|
+
opacity: 1,
|
|
16
|
+
['--r' as any]: '25%',
|
|
19
17
|
},
|
|
20
18
|
animate: {
|
|
21
19
|
opacity: 1,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
20
|
+
['--r' as any]: '100%',
|
|
21
|
+
transition: {
|
|
22
|
+
duration: 0.5,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
exit: {
|
|
26
|
+
opacity: 0,
|
|
27
|
+
['--r' as any]: '100%',
|
|
25
28
|
transition: {
|
|
26
29
|
duration: 0.3,
|
|
27
|
-
borderRadius: { duration: 0.3, delay: 0.3 },
|
|
28
30
|
},
|
|
29
31
|
},
|
|
30
|
-
};
|
|
32
|
+
} as const;
|
|
31
33
|
|
|
32
34
|
const [isCompleted, setIsCompleted] = useState(true);
|
|
33
35
|
const [isActive, setIsActive] = useState(false);
|
|
34
|
-
const [coordinates, setCoordinates] = useState({ x:
|
|
36
|
+
const [coordinates, setCoordinates] = useState({ x: 50, y: 50 });
|
|
35
37
|
|
|
36
38
|
useEffect(() => {
|
|
37
39
|
if (isActive) {
|
|
40
|
+
// restart presence cycle to allow exit animation after mouse up
|
|
38
41
|
setIsCompleted(true);
|
|
39
42
|
setIsCompleted(false);
|
|
40
43
|
}
|
|
41
44
|
}, [isActive]);
|
|
42
45
|
|
|
43
46
|
useEffect(() => {
|
|
44
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
45
|
-
// @ts-expect-error
|
|
46
47
|
const element = triggerRef?.current;
|
|
47
48
|
if (element) {
|
|
48
49
|
element.addEventListener('mousedown', handleMouseDown);
|
|
@@ -59,7 +60,10 @@ const RippleEffect: React.FC<RippleEffectProps> = ({
|
|
|
59
60
|
const handleMouseDown = (e: MouseEvent) => {
|
|
60
61
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
61
62
|
// @ts-expect-error
|
|
62
|
-
const el = triggerRef?.current as Element
|
|
63
|
+
const el = triggerRef?.current as Element & {
|
|
64
|
+
clientWidth: number;
|
|
65
|
+
clientHeight: number;
|
|
66
|
+
};
|
|
63
67
|
const rect = el.getBoundingClientRect();
|
|
64
68
|
setIsActive(true);
|
|
65
69
|
setCoordinates({
|
|
@@ -67,33 +71,42 @@ const RippleEffect: React.FC<RippleEffectProps> = ({
|
|
|
67
71
|
y: ((e.clientY - rect.top) / el.clientHeight) * 100,
|
|
68
72
|
});
|
|
69
73
|
};
|
|
70
|
-
const handleMouseLeave = (
|
|
74
|
+
const handleMouseLeave = (_e: MouseEvent) => {
|
|
71
75
|
setIsActive(false);
|
|
72
76
|
};
|
|
73
77
|
|
|
74
|
-
const handleMouseUp = (
|
|
78
|
+
const handleMouseUp = (_e: MouseEvent) => {
|
|
75
79
|
setIsActive(false);
|
|
76
80
|
};
|
|
77
81
|
|
|
82
|
+
// Build the background as a function of state.
|
|
83
|
+
// color token mixed to a subtle alpha
|
|
84
|
+
const colorMix = `color-mix(in srgb, var(--state-color,_var(--color-${colorName})) 10%, transparent)`;
|
|
85
|
+
// const colorMix = `red`;
|
|
86
|
+
|
|
87
|
+
const style: React.CSSProperties & Record<string, any> = {
|
|
88
|
+
position: 'absolute',
|
|
89
|
+
inset: 0,
|
|
90
|
+
width: '100%',
|
|
91
|
+
height: '100%',
|
|
92
|
+
// supply CSS variables for gradient center and radius
|
|
93
|
+
['--x' as any]: coordinates.x + '%',
|
|
94
|
+
['--y' as any]: coordinates.y + '%',
|
|
95
|
+
['--r' as any]: '0%', // will be animated by motion
|
|
96
|
+
background: `radial-gradient(ellipse at var(--x) var(--y), ${colorMix} var(--r), transparent calc(var(--r) * 2))`,
|
|
97
|
+
pointerEvents: 'none',
|
|
98
|
+
};
|
|
99
|
+
|
|
78
100
|
return (
|
|
79
101
|
<AnimatePresence mode="wait">
|
|
80
102
|
{(isActive || (!isActive && !isCompleted)) && (
|
|
81
103
|
<motion.div
|
|
82
|
-
style={
|
|
83
|
-
position: 'absolute',
|
|
84
|
-
width: '100%',
|
|
85
|
-
height: '100%',
|
|
86
|
-
top: coordinates.y + '%',
|
|
87
|
-
left: coordinates.x + '%',
|
|
88
|
-
background: `color-mix(in srgb, var(--color-${colorName}) 12%, transparent)`,
|
|
89
|
-
pointerEvents: 'none',
|
|
90
|
-
}}
|
|
104
|
+
style={style}
|
|
91
105
|
variants={ripple}
|
|
92
106
|
initial="initial"
|
|
93
|
-
animate=
|
|
94
|
-
exit=
|
|
107
|
+
animate="animate"
|
|
108
|
+
exit="exit"
|
|
95
109
|
onAnimationComplete={() => setIsCompleted(true)}
|
|
96
|
-
className={'transform -translate-x-1/2 -translate-y-1/2'}
|
|
97
110
|
/>
|
|
98
111
|
)}
|
|
99
112
|
</AnimatePresence>
|
|
@@ -2,6 +2,9 @@ import { ActionOrLink } from '../utils';
|
|
|
2
2
|
import { Transition } from 'motion';
|
|
3
3
|
import { Icon } from '../icon';
|
|
4
4
|
|
|
5
|
+
type ButtonVariant = 'filled' | 'elevated' | 'tonal' | 'outlined' | 'text';
|
|
6
|
+
type ButtonVariantAlias = 'primary' | 'secondary';
|
|
7
|
+
|
|
5
8
|
type Props = {
|
|
6
9
|
/**
|
|
7
10
|
* The label is the text that is displayed on the button.
|
|
@@ -14,8 +17,9 @@ type Props = {
|
|
|
14
17
|
|
|
15
18
|
/**
|
|
16
19
|
* The button variant determines the style of the button.
|
|
20
|
+
* Aliases: 'primary' maps to 'filled', 'secondary' maps to 'tonal'
|
|
17
21
|
*/
|
|
18
|
-
variant?:
|
|
22
|
+
variant?: ButtonVariant | ButtonVariantAlias;
|
|
19
23
|
|
|
20
24
|
/**
|
|
21
25
|
* Disables the button if set to true.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { FabInterface } from './fab.interface';
|
|
2
|
+
|
|
3
|
+
export interface FabMenuInterface {
|
|
4
|
+
type: 'div';
|
|
5
|
+
props: FabInterface['props'] & {
|
|
6
|
+
variant?: 'primary' | 'secondary' | 'tertiary';
|
|
7
|
+
open?: boolean;
|
|
8
|
+
defaultOpen?: boolean;
|
|
9
|
+
onOpenChange?: (open: boolean) => void;
|
|
10
|
+
};
|
|
11
|
+
elements: ['fabMenu', 'fab', 'actions', 'action'];
|
|
12
|
+
}
|
|
@@ -2,14 +2,20 @@ import { ActionOrLink } from '../utils/component';
|
|
|
2
2
|
import { Transition } from 'motion';
|
|
3
3
|
import { Icon } from '../icon';
|
|
4
4
|
|
|
5
|
-
export type FabVariant =
|
|
5
|
+
export type FabVariant =
|
|
6
|
+
| 'primary'
|
|
7
|
+
| 'secondary'
|
|
8
|
+
| 'tertiary'
|
|
9
|
+
| 'primaryContainer'
|
|
10
|
+
| 'secondaryContainer'
|
|
11
|
+
| 'tertiaryContainer';
|
|
6
12
|
type Props = {
|
|
7
13
|
variant?: FabVariant;
|
|
8
14
|
label?: string;
|
|
9
15
|
children?: string;
|
|
10
16
|
icon: Icon;
|
|
11
17
|
size?: 'small' | 'medium' | 'large';
|
|
12
|
-
|
|
18
|
+
extended?: boolean;
|
|
13
19
|
transition?: Transition;
|
|
14
20
|
};
|
|
15
21
|
|
|
@@ -4,6 +4,7 @@ export * from './carousel-item.interface';
|
|
|
4
4
|
export * from './carousel.interface';
|
|
5
5
|
export * from './divider.interface';
|
|
6
6
|
export * from './fab.interface';
|
|
7
|
+
export * from './fab-menu.interface';
|
|
7
8
|
export * from './icon-button.interface';
|
|
8
9
|
export * from './progress-indicator.interface';
|
|
9
10
|
export * from './side-sheet.interface';
|