From eeeb9340db702638d9bddd76f0beb989e0279a8a Mon Sep 17 00:00:00 2001 From: KSzarek Date: Wed, 17 Jul 2024 12:29:22 +0200 Subject: [PATCH 01/11] feat: TET-906 add Dimmer component --- src/components/Dimmer/Dimmer.props.ts | 5 ++ src/components/Dimmer/Dimmer.stories.tsx | 98 ++++++++++++++++++++++++ src/components/Dimmer/Dimmer.styles.ts | 17 ++++ src/components/Dimmer/Dimmer.test.tsx | 19 +++++ src/components/Dimmer/Dimmer.tsx | 16 ++++ src/components/Dimmer/index.ts | 3 + src/components/Dimmer/stylesBuilder.ts | 27 +++++++ src/components/Dimmer/types/index.ts | 1 + src/docs-components/DimmerDocs.tsx | 14 ++++ src/index.ts | 1 + 10 files changed, 201 insertions(+) create mode 100644 src/components/Dimmer/Dimmer.props.ts create mode 100644 src/components/Dimmer/Dimmer.stories.tsx create mode 100644 src/components/Dimmer/Dimmer.styles.ts create mode 100644 src/components/Dimmer/Dimmer.test.tsx create mode 100644 src/components/Dimmer/Dimmer.tsx create mode 100644 src/components/Dimmer/index.ts create mode 100644 src/components/Dimmer/stylesBuilder.ts create mode 100644 src/components/Dimmer/types/index.ts create mode 100644 src/docs-components/DimmerDocs.tsx diff --git a/src/components/Dimmer/Dimmer.props.ts b/src/components/Dimmer/Dimmer.props.ts new file mode 100644 index 00000000..c95fc69e --- /dev/null +++ b/src/components/Dimmer/Dimmer.props.ts @@ -0,0 +1,5 @@ +import { DimmerConfig } from './Dimmer.styles'; + +export type DimmerProps = { + custom?: DimmerConfig; +}; diff --git a/src/components/Dimmer/Dimmer.stories.tsx b/src/components/Dimmer/Dimmer.stories.tsx new file mode 100644 index 00000000..78179c19 --- /dev/null +++ b/src/components/Dimmer/Dimmer.stories.tsx @@ -0,0 +1,98 @@ +import type { Meta, StoryObj } from '@storybook/react'; + +import { Dimmer } from './Dimmer'; +import { Badge } from '../Badge'; +import { Card } from '../Card'; + +import { DimmerDocs } from '@/docs-components/DimmerDocs'; +import { TetDocs } from '@/docs-components/TetDocs'; +import { tet } from '@/tetrisly'; + +const meta = { + title: 'Dimmer', + component: Dimmer, + tags: ['autodocs'], + args: {}, + parameters: { + backgrounds: {}, + docs: { + description: { + component: + 'An overlay that darkens the background content to focus the users attention on another specific element or interaction, such as a Modal or Side Panel.', + }, + page: () => ( + + + + ), + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: {}, +}; + +export const WithCardComponent: Story = { + render: () => ( + <> + + + + + + + + Task: + + + Creating React components + + + + + + Created + + + Mon, 14 Feb 2023 + + + + + Last modified + + + Today, 5:23 am + + + + + + + + ), +}; diff --git a/src/components/Dimmer/Dimmer.styles.ts b/src/components/Dimmer/Dimmer.styles.ts new file mode 100644 index 00000000..ff470cef --- /dev/null +++ b/src/components/Dimmer/Dimmer.styles.ts @@ -0,0 +1,17 @@ +import type { BaseProps } from '@/types/BaseProps'; + +export type DimmerConfig = BaseProps; + +export const defaultConfig = { + w: '100%', + h: '100%', + backgroundColor: '$color-interaction-background-dimmer', + top: 0, + left: 0, + position: 'absolute', + zIndex: 3, +} satisfies DimmerConfig; + +export const dimmerStyles = { + defaultConfig, +}; diff --git a/src/components/Dimmer/Dimmer.test.tsx b/src/components/Dimmer/Dimmer.test.tsx new file mode 100644 index 00000000..1fd9ed78 --- /dev/null +++ b/src/components/Dimmer/Dimmer.test.tsx @@ -0,0 +1,19 @@ +import { Dimmer } from './Dimmer'; +import { render } from '../../tests/render'; + +const getDimmer = (jsx: JSX.Element) => { + const { getByTestId } = render(jsx); + return getByTestId('dimmer'); +}; + +describe('Dimmer', () => { + it('should render the dimmer', () => { + const dimmer = getDimmer(); + expect(dimmer).toBeInTheDocument(); + }); + + it('should render correct color', () => { + const dimmer = getDimmer(); + expect(dimmer).toHaveStyle('background-color: rgba(25, 39, 58, 0.741)'); + }); +}); diff --git a/src/components/Dimmer/Dimmer.tsx b/src/components/Dimmer/Dimmer.tsx new file mode 100644 index 00000000..71a389f3 --- /dev/null +++ b/src/components/Dimmer/Dimmer.tsx @@ -0,0 +1,16 @@ +import { type FC, useMemo } from 'react'; + +import type { DimmerProps } from './Dimmer.props'; +import { stylesBuilder } from './stylesBuilder'; + +import { tet } from '@/tetrisly'; +import type { MarginProps } from '@/types'; + +export const Dimmer: FC = ({ + custom, + ...restProps +}) => { + const styles = useMemo(() => stylesBuilder({ custom }), [custom]); + + return ; +}; diff --git a/src/components/Dimmer/index.ts b/src/components/Dimmer/index.ts new file mode 100644 index 00000000..1e412629 --- /dev/null +++ b/src/components/Dimmer/index.ts @@ -0,0 +1,3 @@ +export { Dimmer } from './Dimmer'; +export type { DimmerProps } from './Dimmer.props'; +export { dimmerStyles } from './Dimmer.styles'; diff --git a/src/components/Dimmer/stylesBuilder.ts b/src/components/Dimmer/stylesBuilder.ts new file mode 100644 index 00000000..6dc2bb9d --- /dev/null +++ b/src/components/Dimmer/stylesBuilder.ts @@ -0,0 +1,27 @@ +import { DimmerProps } from './Dimmer.props'; +import { defaultConfig } from './Dimmer.styles'; + +import { mergeConfigWithCustom } from '@/services'; +import { BaseProps } from '@/types/BaseProps'; + +type StylesBuilderParams = { + custom: DimmerProps['custom']; +}; + +type DimmerStylesBuilder = { + container: BaseProps; +}; + +export const stylesBuilder = ({ + custom, +}: StylesBuilderParams): DimmerStylesBuilder => { + const config = mergeConfigWithCustom({ defaultConfig, custom }); + + const { ...restStyles } = config; + + return { + container: { + ...restStyles, + }, + }; +}; diff --git a/src/components/Dimmer/types/index.ts b/src/components/Dimmer/types/index.ts new file mode 100644 index 00000000..fd74e7a6 --- /dev/null +++ b/src/components/Dimmer/types/index.ts @@ -0,0 +1 @@ +export type { StatusDotAppearance } from './StatusDotAppearance.type'; diff --git a/src/docs-components/DimmerDocs.tsx b/src/docs-components/DimmerDocs.tsx new file mode 100644 index 00000000..1801dee2 --- /dev/null +++ b/src/docs-components/DimmerDocs.tsx @@ -0,0 +1,14 @@ +import { Dimmer } from '@/components/Dimmer/Dimmer'; +import { tet } from '@/tetrisly'; + +export const DimmerDocs = () => ( + + + + + + + + + +); diff --git a/src/index.ts b/src/index.ts index fcc44c65..77bb95d1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -7,6 +7,7 @@ export * from './components/Checkbox'; export * from './components/CheckboxGroup'; export * from './components/CornerDialog'; export * from './components/Counter'; +export * from './components/Dimmer'; export * from './components/Divider'; export * from './components/FileItem'; export * from './components/HelperText'; From 69d1ede56acded867363f773e88cdd4fd4b59a40 Mon Sep 17 00:00:00 2001 From: KSzarek Date: Wed, 17 Jul 2024 12:57:51 +0200 Subject: [PATCH 02/11] feat: TET-906 add custom prop tester to tests --- src/components/Dimmer/Dimmer.test.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/components/Dimmer/Dimmer.test.tsx b/src/components/Dimmer/Dimmer.test.tsx index 1fd9ed78..63b2e446 100644 --- a/src/components/Dimmer/Dimmer.test.tsx +++ b/src/components/Dimmer/Dimmer.test.tsx @@ -1,6 +1,8 @@ import { Dimmer } from './Dimmer'; import { render } from '../../tests/render'; +import { customPropTester } from '@/tests/customPropTester'; + const getDimmer = (jsx: JSX.Element) => { const { getByTestId } = render(jsx); return getByTestId('dimmer'); @@ -16,4 +18,8 @@ describe('Dimmer', () => { const dimmer = getDimmer(); expect(dimmer).toHaveStyle('background-color: rgba(25, 39, 58, 0.741)'); }); + + customPropTester(, { + containerId: 'dimmer', + }); }); From f018bc94868e6a7a29343692b92aa58ee1448979 Mon Sep 17 00:00:00 2001 From: KSzarek Date: Wed, 17 Jul 2024 13:00:44 +0200 Subject: [PATCH 03/11] feat: TET-906 delete unused file --- src/components/Dimmer/types/index.ts | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/components/Dimmer/types/index.ts diff --git a/src/components/Dimmer/types/index.ts b/src/components/Dimmer/types/index.ts deleted file mode 100644 index fd74e7a6..00000000 --- a/src/components/Dimmer/types/index.ts +++ /dev/null @@ -1 +0,0 @@ -export type { StatusDotAppearance } from './StatusDotAppearance.type'; From e0844eba379b39882b17b61757a1ddb8a2b0e524 Mon Sep 17 00:00:00 2001 From: KSzarek Date: Wed, 17 Jul 2024 13:05:57 +0200 Subject: [PATCH 04/11] feat: TET-851 add Dialog component --- src/components/Dialog/Dialog.props.ts | 66 +++++++++++ src/components/Dialog/Dialog.stories.tsx | 93 +++++++++++++++ src/components/Dialog/Dialog.styles.ts | 112 ++++++++++++++++++ src/components/Dialog/Dialog.test.tsx | 26 ++++ src/components/Dialog/Dialog.tsx | 77 ++++++++++++ src/components/Dialog/index.ts | 3 + src/components/Dialog/stylesBuilder.ts | 57 +++++++++ .../Dialog/types/DialogFooter.type.ts | 1 + .../Dialog/types/DialogIntent.type.ts | 1 + .../Dialog/types/DialogSize.type.ts | 1 + src/components/Dialog/types/index.ts | 3 + src/docs-components/DialogDocs.tsx | 55 +++++++++ src/index.ts | 1 + 13 files changed, 496 insertions(+) create mode 100644 src/components/Dialog/Dialog.props.ts create mode 100644 src/components/Dialog/Dialog.stories.tsx create mode 100644 src/components/Dialog/Dialog.styles.ts create mode 100644 src/components/Dialog/Dialog.test.tsx create mode 100644 src/components/Dialog/Dialog.tsx create mode 100644 src/components/Dialog/index.ts create mode 100644 src/components/Dialog/stylesBuilder.ts create mode 100644 src/components/Dialog/types/DialogFooter.type.ts create mode 100644 src/components/Dialog/types/DialogIntent.type.ts create mode 100644 src/components/Dialog/types/DialogSize.type.ts create mode 100644 src/components/Dialog/types/index.ts create mode 100644 src/docs-components/DialogDocs.tsx diff --git a/src/components/Dialog/Dialog.props.ts b/src/components/Dialog/Dialog.props.ts new file mode 100644 index 00000000..7b6e6874 --- /dev/null +++ b/src/components/Dialog/Dialog.props.ts @@ -0,0 +1,66 @@ +// import { ReactNode } from 'react'; +// import { DialogConfig } from './Dialog.styles'; +// import { DialogFooter, DialogIntent, DialogSize } from './types'; + +// import type { Action, HelperTextProp } from '@/types'; + +// export type CommonDialogProps = { +// actions?: Action[]; +// content?: string; +// custom?: DialogConfig; +// docsPresentation?: boolean; +// footer?: DialogFooter; +// hasCloseButton?: boolean; +// intent?: DialogIntent; +// size?: DialogSize; +// title?: string; +// }; +// type DialogWithoutAdditionalChildProps = { hasAdditionalChild?: false }; +// type DialogWithAdditionalChildProps = { +// hasAdditionalChild?: true; +// } & (AdditionalActionChildProps | AdditionalCustomContentChildProps | AdditionalNestedChildProps); +// // type AdditionalChildProps = { +// // type: 'action' | 'custom content' | 'nested component'; +// // }; + +// type AdditionalActionChildProps = { +// type: 'action', +// action: Action +// } + +// type AdditionalCustomContentChildProps = { +// type: 'custom content', +// content: ReactNode +// } + +// // type NestedComponentType = Avatar | Button | Checkbox | Counter | Dialog | HelperText | StatusDot | Icon | Loader | SelectablePill | SearchInput | InlineSearchInput | Status +// // TODO add DimmerProps, LogoProps, HeaderProps when Dimmer, Logo, Header components are added +// type AdditionalNestedChildProps = { +// type: 'nested component', +// component: ReactNode +// } + +// export type DialogProps = CommonDialogProps & +// (DialogWithAdditionalChildProps | DialogWithoutAdditionalChildProps); + +// ------------------------------------------------------------------------------------------------------------------------------- + +import { ReactNode } from 'react'; + +import { DialogConfig } from './Dialog.styles'; +import { DialogFooter, DialogIntent, DialogSize } from './types'; + +import type { Action, HelperTextProp } from '@/types'; + +export type DialogProps = { + actions?: Action[]; + children?: ReactNode; + content?: string; + custom?: DialogConfig; + docsPresentation?: boolean; + footer?: DialogFooter; + hasCloseButton?: boolean; + intent?: DialogIntent; + size?: DialogSize; + title?: string; +}; diff --git a/src/components/Dialog/Dialog.stories.tsx b/src/components/Dialog/Dialog.stories.tsx new file mode 100644 index 00000000..10fda43a --- /dev/null +++ b/src/components/Dialog/Dialog.stories.tsx @@ -0,0 +1,93 @@ +import { Meta, StoryObj } from '@storybook/react'; + +import { Dialog } from './Dialog'; +import { customStyleForDocs } from './Dialog.styles'; +import { DialogFooter, DialogSize } from './types'; +import { Button } from '../Button'; + +import { DialogDocs } from '@/docs-components/DialogDocs'; +import { TetDocs } from '@/docs-components/TetDocs'; + +const meta = { + title: 'Dialog', + component: Dialog, + tags: ['autodocs'], + argTypes: { + actions: { + control: { + type: 'object', + }, + }, + children: { + control: { + type: 'string', + }, + }, + content: { + type: 'string', + }, + custom: { + control: { + type: 'object', + }, + }, + footer: { + control: 'select', + options: ['confirmation', 'decision', 'steps'] satisfies DialogFooter[], + }, + size: { + control: 'radio', + options: ['small', 'medium', 'large'] satisfies DialogSize[], + }, + hasCloseButton: { + control: 'radio', + options: [true, false], + }, + intent: { + value: 'none', + control: 'radio', + options: ['destructive', 'warning', 'none'], + }, + }, + parameters: { + docs: { + description: { + component: + 'A temporary, focused window that overlays the main content. Often used to prompt user input or present important information that requires interaction, such as confirmation or error messages.', + }, + page: () => ( + + + + ), + }, + }, +} satisfies Meta; + +export default meta; +type Story = StoryObj; + +export const Default: Story = { + args: { + title: 'title', + content: 'content', + hasCloseButton: true, + footer: 'steps', + actions: [{ label: 'first action' }, { label: 'second action' }], + size: 'small', + custom: customStyleForDocs, // is it ok? Different prezentation in docs and different in usage + }, +}; + +export const WithAdditionalChildren: Story = { + args: { + title: 'title', + content: 'content', + hasCloseButton: true, + footer: 'decision', + actions: [{ label: 'first action' }, { label: 'second action' }], + size: 'small', + custom: customStyleForDocs, + children: