Skip to content

Commit 61df1f3

Browse files
authored
Merge pull request #11574 from TylerAPfledderer/feat/stats
feat: create Stat component and stories
2 parents f719d3d + 9f93377 commit 61df1f3

File tree

4 files changed

+106
-3
lines changed

4 files changed

+106
-3
lines changed

src/components/Stat/Stat.stories.tsx

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { Meta, StoryObj } from "@storybook/react"
2+
3+
import StatComponent from "."
4+
5+
const meta = {
6+
title: "Molecules / Display Content / Stat",
7+
component: StatComponent,
8+
} satisfies Meta<typeof StatComponent>
9+
10+
export default meta
11+
12+
export const Stat: StoryObj<typeof meta> = {
13+
args: {
14+
tooltipProps: {
15+
content: "Tooltip content",
16+
},
17+
isError: false,
18+
label: "Label",
19+
value: "000",
20+
},
21+
argTypes: {
22+
isError: {
23+
table: {
24+
disable: true,
25+
},
26+
},
27+
},
28+
}
29+
30+
export const StatError: StoryObj<typeof meta> = {
31+
args: {
32+
...Stat.args,
33+
isError: true,
34+
value: undefined,
35+
},
36+
argTypes: {
37+
value: {
38+
table: {
39+
disable: true,
40+
},
41+
},
42+
},
43+
}

src/components/Stat/index.tsx

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { useEffect, useState } from "react"
2+
import type { IconType } from "react-icons/lib"
3+
import { MdInfoOutline, MdWarning } from "react-icons/md"
4+
import { Flex, HStack, Icon, Text } from "@chakra-ui/react"
5+
6+
import { NULL_VALUE } from "@/lib/constants"
7+
8+
import Tooltip, { type TooltipProps } from "../Tooltip"
9+
10+
const initialContent = {
11+
contentValue: NULL_VALUE,
12+
tooltipIcon: MdInfoOutline,
13+
}
14+
15+
export type StatProps = {
16+
tooltipProps?: TooltipProps
17+
value: string | undefined
18+
label: string
19+
isError: boolean
20+
}
21+
22+
const Stat = ({ tooltipProps, value, label, isError }: StatProps) => {
23+
const [content, setContent] = useState<{
24+
contentValue: string | JSX.Element
25+
tooltipIcon: IconType
26+
}>(initialContent)
27+
28+
useEffect(() => {
29+
if (isError) {
30+
return setContent({
31+
contentValue: NULL_VALUE,
32+
tooltipIcon: MdWarning,
33+
})
34+
}
35+
36+
if (!value) return
37+
38+
return setContent({ ...initialContent, contentValue: value })
39+
}, [isError, value])
40+
41+
return (
42+
<Flex flexDirection="column-reverse">
43+
<HStack lineHeight="initial" spacing="0.5" color="body.medium">
44+
<Text as="span">{label}</Text>
45+
{!!tooltipProps && (
46+
<Tooltip {...tooltipProps}>
47+
<Icon as={content.tooltipIcon} />
48+
</Tooltip>
49+
)}
50+
</HStack>
51+
<Text as="span" size="5xl" fontWeight="bold">
52+
{content.contentValue}
53+
</Text>
54+
</Flex>
55+
)
56+
}
57+
58+
export default Stat

src/components/Tooltip/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,18 @@ import {
1212

1313
import { isMobile } from "@/lib/utils/isMobile"
1414

15-
export interface IProps extends PopoverProps {
15+
export interface TooltipProps extends PopoverProps {
1616
content: ReactNode
1717
children?: ReactNode
1818
onBeforeOpen?: () => void
1919
}
2020

21-
const Tooltip: React.FC<IProps> = ({
21+
const Tooltip = ({
2222
content,
2323
children,
2424
onBeforeOpen,
2525
...rest
26-
}) => {
26+
}: TooltipProps) => {
2727
const { isOpen, onOpen, onClose } = useDisclosure()
2828

2929
// Close the popover when the user scrolls.

src/lib/constants.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ export const TRANSLATED_IMAGES_DIR = "/content/translations"
1111
export const PLACEHOLDER_IMAGE_DIR = "src/data/placeholders"
1212
export const INTL_JSON_DIR = "src/intl"
1313

14+
export const NULL_VALUE = "—"
15+
1416
// i18n
1517
export const DEFAULT_LOCALE = "en"
1618
export const FAKE_LOCALE = "default"

0 commit comments

Comments
 (0)