diff --git a/src/components/Report/Report.stories.tsx b/src/components/Report/Report.stories.tsx new file mode 100644 index 00000000..86a5aecc --- /dev/null +++ b/src/components/Report/Report.stories.tsx @@ -0,0 +1,74 @@ +import { Meta, StoryObj } from '@storybook/react'; + +import { withColorSchemeDecorator } from 'src/storybook/decorators'; + +import { Report, ReportLabel, ReportProps } from './index'; +import { InfoCircleOutlined } from '@ant-design/icons'; +import styled from 'styled-components'; + +const args: ReportProps = { + items: [ + { + title: 'Title 1', + value: 'Value 1', + }, + { + title: 'Title 2', + value: 0, + }, + ], +}; + +const meta: Meta = { + title: 'components / Report', + component: Report, + decorators: [withColorSchemeDecorator], + args, +}; + +export default meta; + +type Story = StoryObj; + +export const Default: Story = {}; + +const S = { + Label: styled.div` + display: flex; + gap: 0 4px; + color: ${({ theme }) => theme.neutralPalette.gray_7}; + + svg { + font-size: 14px; + } + `, +}; + +export const FullWidth: Story = { + args: { + fullWidth: true, + items: [ + { + title: 'Title 1', + value: 'Value 1', + }, + { + title: 'Title 2', + value: 0, + }, + { + title: ( + + Title 3 + + + ), + value: 'Value 3', + }, + { + title: 'Title 4', + value: 'Value 4', + }, + ], + }, +}; diff --git a/src/components/Report/index.tsx b/src/components/Report/index.tsx new file mode 100644 index 00000000..98c191cc --- /dev/null +++ b/src/components/Report/index.tsx @@ -0,0 +1,48 @@ +import React from 'react'; +import { S } from './styles'; +import _ from 'lodash'; + +export interface ReportProps { + items: Array<{ + title: React.ReactNode; + value?: React.ReactNode; + }>; + fullWidth?: boolean; + style?: React.CSSProperties; + className?: string; +} + +export function Report(props: ReportProps) { + const { className, style, items, fullWidth = false } = props; + + return ( + + {items.map(({ title, value }, index) => ( + + {_.isString(title) ? {title} : title} + {_.isString(value) || _.isNumber(value) || _.isUndefined(value) || _.isNull(value) ? ( + {value} + ) : ( + value + )} + + ))} + + ); +} + +interface ReportLabelProps { + children: React.ReactNode; +} + +export function ReportLabel(props: ReportLabelProps) { + const { children } = props; + + return {children}; +} + +export function ReportValue(props: ReportLabelProps) { + const { children } = props; + + return {children ?? '-'}; +} diff --git a/src/components/Report/styles.ts b/src/components/Report/styles.ts new file mode 100644 index 00000000..9e822bd0 --- /dev/null +++ b/src/components/Report/styles.ts @@ -0,0 +1,35 @@ +import styled, { css } from 'styled-components'; +import { Text } from '../Typography'; + +export const S = { + Container: styled.div<{ $fullWidth?: boolean }>` + display: flex; + justify-content: flex-start; + gap: 16px 40px; + padding: 16px; + border: 1px solid ${({ theme }) => theme.neutralPalette.gray_4}; + border-radius: 10px; + background-color: ${({ theme }) => theme.neutralPalette.gray_1}; + width: fit-content; + + ${({ $fullWidth }) => + $fullWidth && + css` + width: auto; + justify-content: space-between; + `} + `, + Item: styled.div` + display: flex; + flex-direction: column; + gap: 4px 0; + `, + Label: styled(Text)` + font-size: 12px; + line-height: 20px; + color: ${({ theme }) => theme.neutralPalette.gray_7}; + `, + Value: styled(Text)` + font-weight: 700; + `, +}; diff --git a/src/components/index.ts b/src/components/index.ts index 9b267d11..8f12f3b2 100644 --- a/src/components/index.ts +++ b/src/components/index.ts @@ -30,4 +30,5 @@ export * from './Spinner'; export * from './Table'; export * from './TextWithMacroFill'; export * from './TimePicker'; -export * from './Typography'; \ No newline at end of file +export * from './Typography'; +export * from './Report';