avatar modal
This commit is contained in:
@@ -2,7 +2,14 @@ import {
|
|||||||
Avatar as MantineAvatar,
|
Avatar as MantineAvatar,
|
||||||
AvatarProps as MantineAvatarProps,
|
AvatarProps as MantineAvatarProps,
|
||||||
Paper,
|
Paper,
|
||||||
|
Modal,
|
||||||
|
Image,
|
||||||
|
Group,
|
||||||
|
Text,
|
||||||
|
ActionIcon,
|
||||||
} from "@mantine/core";
|
} from "@mantine/core";
|
||||||
|
import { useState } from "react";
|
||||||
|
import { XIcon } from "@phosphor-icons/react";
|
||||||
|
|
||||||
interface AvatarProps
|
interface AvatarProps
|
||||||
extends Omit<MantineAvatarProps, "radius" | "color" | "size"> {
|
extends Omit<MantineAvatarProps, "radius" | "color" | "size"> {
|
||||||
@@ -10,6 +17,7 @@ interface AvatarProps
|
|||||||
size?: number;
|
size?: number;
|
||||||
radius?: string | number;
|
radius?: string | number;
|
||||||
withBorder?: boolean;
|
withBorder?: boolean;
|
||||||
|
disableFullscreen?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Avatar = ({
|
const Avatar = ({
|
||||||
@@ -17,26 +25,121 @@ const Avatar = ({
|
|||||||
size = 35,
|
size = 35,
|
||||||
radius = "100%",
|
radius = "100%",
|
||||||
withBorder = true,
|
withBorder = true,
|
||||||
|
disableFullscreen = false,
|
||||||
...props
|
...props
|
||||||
}: AvatarProps) => {
|
}: AvatarProps) => {
|
||||||
|
const [isFullscreenOpen, setIsFullscreenOpen] = useState(false);
|
||||||
|
const hasImage = Boolean(props.src);
|
||||||
|
|
||||||
|
const handleAvatarClick = () => {
|
||||||
|
if (hasImage && !disableFullscreen) {
|
||||||
|
setIsFullscreenOpen(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Paper p={size / 20} radius={radius} withBorder={withBorder}>
|
<>
|
||||||
<MantineAvatar
|
<Paper
|
||||||
alt={name}
|
p={size / 20}
|
||||||
key={name}
|
|
||||||
name={name}
|
|
||||||
color="initials"
|
|
||||||
size={size}
|
|
||||||
radius={radius}
|
radius={radius}
|
||||||
w={size}
|
withBorder={withBorder}
|
||||||
|
style={{
|
||||||
|
cursor: hasImage && !disableFullscreen ? 'pointer' : 'default',
|
||||||
|
transition: 'transform 0.15s ease',
|
||||||
|
}}
|
||||||
|
onMouseEnter={(e) => {
|
||||||
|
if (hasImage && !disableFullscreen) {
|
||||||
|
e.currentTarget.style.transform = 'scale(1.02)';
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onMouseLeave={(e) => {
|
||||||
|
e.currentTarget.style.transform = 'scale(1)';
|
||||||
|
}}
|
||||||
|
onClick={handleAvatarClick}
|
||||||
|
>
|
||||||
|
<MantineAvatar
|
||||||
|
alt={name}
|
||||||
|
key={name}
|
||||||
|
name={name}
|
||||||
|
color="initials"
|
||||||
|
size={size}
|
||||||
|
radius={radius}
|
||||||
|
w={size}
|
||||||
|
styles={{
|
||||||
|
image: {
|
||||||
|
objectFit: "contain",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
</Paper>
|
||||||
|
|
||||||
|
<Modal
|
||||||
|
opened={isFullscreenOpen}
|
||||||
|
onClose={() => setIsFullscreenOpen(false)}
|
||||||
|
size="auto"
|
||||||
|
centered
|
||||||
|
withCloseButton={false}
|
||||||
|
overlayProps={{
|
||||||
|
backgroundOpacity: 0.9,
|
||||||
|
blur: 2,
|
||||||
|
}}
|
||||||
styles={{
|
styles={{
|
||||||
image: {
|
content: {
|
||||||
objectFit: "contain",
|
background: 'transparent',
|
||||||
|
border: 'none',
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
padding: 0,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
{...props}
|
>
|
||||||
/>
|
<div style={{ position: 'relative', maxWidth: '90vw', maxHeight: '90vh' }}>
|
||||||
</Paper>
|
<ActionIcon
|
||||||
|
variant="filled"
|
||||||
|
color="dark"
|
||||||
|
size="lg"
|
||||||
|
radius="xl"
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: -10,
|
||||||
|
right: -10,
|
||||||
|
zIndex: 1000,
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.7)',
|
||||||
|
}}
|
||||||
|
onClick={() => setIsFullscreenOpen(false)}
|
||||||
|
>
|
||||||
|
<XIcon size={18} color="white" />
|
||||||
|
</ActionIcon>
|
||||||
|
|
||||||
|
<Image
|
||||||
|
src={props.src}
|
||||||
|
alt={name}
|
||||||
|
fit="contain"
|
||||||
|
style={{
|
||||||
|
borderRadius: 8,
|
||||||
|
maxWidth: '90vw',
|
||||||
|
maxHeight: '90vh',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Group
|
||||||
|
justify="center"
|
||||||
|
mt="md"
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
bottom: -50,
|
||||||
|
left: '50%',
|
||||||
|
transform: 'translateX(-50%)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Text c="white" size="sm" fw={500}>
|
||||||
|
{name}
|
||||||
|
</Text>
|
||||||
|
</Group>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user