|
1 | 1 | import React, { useState } from "react";
|
2 | 2 | import Image from "next/image";
|
3 | 3 | import {
|
| 4 | + AbsoluteCenter, |
4 | 5 | Box,
|
| 6 | + Button, |
| 7 | + ButtonGroup, |
| 8 | + Card, |
| 9 | + CardBody, |
| 10 | + Center, |
5 | 11 | Image as ChakraImage,
|
6 |
| - Code, |
7 | 12 | HStack,
|
| 13 | + Link, |
8 | 14 | Modal,
|
9 | 15 | ModalBody,
|
10 | 16 | ModalCloseButton,
|
11 | 17 | ModalContent,
|
| 18 | + ModalHeader, |
12 | 19 | ModalOverlay,
|
13 | 20 | Spinner,
|
14 | 21 | Text,
|
| 22 | + VStack, |
15 | 23 | useDisclosure,
|
16 | 24 | } from "@chakra-ui/react";
|
17 | 25 |
|
| 26 | +import { ExternalLinkIcon } from "@chakra-ui/icons"; |
| 27 | + |
18 | 28 | type Value =
|
19 | 29 | | string
|
20 | 30 | | {
|
@@ -44,44 +54,92 @@ export default function ImageField({ value }: { value: unknown }) {
|
44 | 54 |
|
45 | 55 | return (
|
46 | 56 | <>
|
47 |
| - <Box> |
48 |
| - {loading && ( |
| 57 | + <Card variant="outline"> |
| 58 | + <CardBody> |
49 | 59 | <HStack>
|
50 |
| - <Spinner emptyColor="gray.200" color="blue.500" /> |
51 |
| - <Text>Loading image...</Text> |
| 60 | + <HStack> |
| 61 | + <Box height="5rem" width="5rem" pos="relative"> |
| 62 | + {loading && ( |
| 63 | + <AbsoluteCenter> |
| 64 | + <Spinner emptyColor="gray.200" color="brand.500" /> |
| 65 | + </AbsoluteCenter> |
| 66 | + )} |
| 67 | + {error && ( |
| 68 | + <AbsoluteCenter> |
| 69 | + <Text |
| 70 | + fontSize="xs" |
| 71 | + backgroundColor="red.100" |
| 72 | + textColor="red.900" |
| 73 | + p={2} |
| 74 | + > |
| 75 | + Unable to load image. |
| 76 | + </Text> |
| 77 | + </AbsoluteCenter> |
| 78 | + )} |
| 79 | + {!error && ( |
| 80 | + <Image |
| 81 | + fill |
| 82 | + src={config.src} |
| 83 | + alt={config.alt ?? ""} |
| 84 | + onLoad={() => setLoading(false)} |
| 85 | + onError={() => { |
| 86 | + setLoading(false); |
| 87 | + setError(true); |
| 88 | + }} |
| 89 | + style={{ objectFit: "contain" }} |
| 90 | + /> |
| 91 | + )} |
| 92 | + </Box> |
| 93 | + <Box m={2}> |
| 94 | + <Text |
| 95 | + fontSize="sm" |
| 96 | + userSelect="all" |
| 97 | + sx={{ |
| 98 | + overflowWrap: "break-word", |
| 99 | + wordWrap: "break-word", |
| 100 | + wordBreak: "break-word", |
| 101 | + }} |
| 102 | + > |
| 103 | + {config.src} |
| 104 | + </Text> |
| 105 | + <ButtonGroup> |
| 106 | + {!error && ( |
| 107 | + <Button onClick={onOpen} size="xs"> |
| 108 | + View Image |
| 109 | + </Button> |
| 110 | + )} |
| 111 | + <Button |
| 112 | + as={Link} |
| 113 | + variant="link" |
| 114 | + size="xs" |
| 115 | + href={config.src} |
| 116 | + isExternal |
| 117 | + > |
| 118 | + Open in New Tab <ExternalLinkIcon mx="2px" /> |
| 119 | + </Button> |
| 120 | + </ButtonGroup> |
| 121 | + </Box> |
| 122 | + </HStack> |
52 | 123 | </HStack>
|
53 |
| - )} |
54 |
| - {error && ( |
55 |
| - <Code fontSize="xs" variant="outline" colorScheme="orange"> |
56 |
| - Unable to load image. |
57 |
| - </Code> |
58 |
| - )} |
59 |
| - {!error && ( |
60 |
| - <Image |
61 |
| - height={200} |
62 |
| - width={200} |
63 |
| - src={config.src} |
64 |
| - alt={config.alt ?? ""} |
65 |
| - onLoad={() => setLoading(false)} |
66 |
| - onError={() => { |
67 |
| - setLoading(false); |
68 |
| - setError(true); |
69 |
| - }} |
70 |
| - onClick={onOpen} |
71 |
| - style={{ cursor: "pointer" }} |
72 |
| - /> |
73 |
| - )} |
74 |
| - </Box> |
75 |
| - <Modal onClose={onClose} isOpen={isOpen} size="full"> |
| 124 | + </CardBody> |
| 125 | + </Card> |
| 126 | + <Modal onClose={onClose} isOpen={isOpen}> |
76 | 127 | <ModalOverlay />
|
77 |
| - <ModalContent> |
| 128 | + <ModalContent maxW="90vw"> |
78 | 129 | <ModalCloseButton />
|
| 130 | + <ModalHeader /> |
79 | 131 | <ModalBody>
|
80 |
| - <ChakraImage |
81 |
| - src={config.src} |
82 |
| - alt={config.alt ?? ""} |
83 |
| - objectFit="contain" |
84 |
| - /> |
| 132 | + <VStack> |
| 133 | + <Box rounded={8} backgroundColor="gray.50" w="100%" p={4}> |
| 134 | + <Center> |
| 135 | + <ChakraImage |
| 136 | + src={config.src} |
| 137 | + alt={config.alt ?? ""} |
| 138 | + objectFit="contain" |
| 139 | + /> |
| 140 | + </Center> |
| 141 | + </Box> |
| 142 | + </VStack> |
85 | 143 | </ModalBody>
|
86 | 144 | </ModalContent>
|
87 | 145 | </Modal>
|
|
0 commit comments