Skip to content
This repository has been archived by the owner on Mar 23, 2024. It is now read-only.

Commit

Permalink
feat: ✨ shared flex icon wrapper (#107)
Browse files Browse the repository at this point in the history
* feat: ✨ add flex component

* feat: ✨ add flex component and docs

* docs: 📝 add docs for Flex component

* fix: in flex width auto -> 100%

* fix: in flex width auto -> 100% in storybook
  • Loading branch information
velenyx committed Sep 24, 2023
1 parent 4487510 commit a946bd3
Show file tree
Hide file tree
Showing 10 changed files with 528 additions and 1 deletion.
5 changes: 4 additions & 1 deletion client/src/shared/assets/storybook.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import * as ICONS from './index';

type IconOptions = Record<keyof typeof ICONS, React.ReactNode>;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type IconOptions = Record<keyof typeof ICONS, any>;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
export const ICON_OPTIONS = Object.entries(ICONS).reduce<IconOptions>(
(acc, [iconName, IconComponent]) => {
acc[iconName.replace(/icon$/i, '') as keyof typeof ICONS] = IconComponent({});
Expand Down
14 changes: 14 additions & 0 deletions client/src/shared/ui/flex/flex.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
.flexWrapper {
display: flex;
align-items: var(--align, normal);
justify-content: var(--justify, normal);
gap: var(--gap, 0);
margin: var(--margin, 0);
padding: var(--padding, 0);
flex-direction: var(--direction, row);
max-height: var(--maxHeight, none);
position: var(--position, static);
width: var(--width, 100%);
max-width: var(--maxWidth, none);
height: var(--height, auto);
}
152 changes: 152 additions & 0 deletions client/src/shared/ui/flex/flex.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import React from 'react';
import { ArgTypes, Meta, StoryObj } from '@storybook/react';
import { Flex, FlexProps } from './flex';

const flexProps: FlexProps = {
align: 'center',
justify: 'space-between',
gap: 10,
margin: 20,
padding: 20,
direction: 'row',
maxHeight: '500px',
position: 'relative',
width: '100%',
maxWidth: '500px',
height: 'auto',
children: <div>Item 1</div>,
};

// Defining meta information for Storybook
type Story = StoryObj<typeof Flex>;
const FlexTemplate: Story = {
render: args => (
<Flex {...args}>
<div>Item 1</div>
<div>Item 2</div>
<div>Item 3</div>
</Flex>
),
};

export const Playground = { ...FlexTemplate };
Playground.args = flexProps;

// Flex with column direction
export const ColumnDirection = { ...FlexTemplate };
ColumnDirection.args = {
...flexProps,
direction: 'column',
};

// Flex with different alignment
export const DifferentAlignment = { ...FlexTemplate };
DifferentAlignment.args = {
...flexProps,
align: 'flex-start',
justify: 'flex-end',
};

// Flex with different spacing
export const DifferentSpacing = { ...FlexTemplate };
DifferentSpacing.args = {
...flexProps,
gap: 20,
margin: 10,
padding: 10,
};

// Flex with different dimensions
export const DifferentDimensions = { ...FlexTemplate };
DifferentDimensions.args = {
...flexProps,
width: '50%',
maxWidth: '300px',
height: '200px',
};

const flexArgTypes: ArgTypes = {
align: {
control: {
type: 'select',
},
options: ['flex-start', 'flex-end', 'center', 'baseline', 'stretch', 'normal'],
defaultValue: { summary: 'normal' },
description: 'Defines the default behavior for how items are laid out along the cross axis.',
},
justify: {
control: {
type: 'select',
},
options: [
'flex-start',
'flex-end',
'center',
'space-between',
'space-around',
'space-evenly',
'normal',
],
defaultValue: { summary: 'normal' },
description:
'Defines how the browser distributes space between and around content items along the main axis.',
},
direction: {
control: {
type: 'select',
},
options: ['row', 'column'],
defaultValue: { summary: 'row' },
description: 'Defines in which direction the container wants to stack the flex items.',
},
position: {
control: {
type: 'select',
},
options: ['static', 'relative', 'absolute', 'fixed', 'sticky'],
defaultValue: { summary: 'static' },
description: 'Specifies the type of positioning method used for an element.',
},
gap: {
control: 'text',
defaultValue: { summary: '0' },
description: 'Defines the space between flex items.',
},
margin: {
control: 'text',
defaultValue: { summary: '0' },
description: 'Defines the space around the component.',
},
padding: {
control: 'text',
defaultValue: { summary: '0' },
description: 'Defines the space inside the component.',
},
maxHeight: {
control: 'text',
defaultValue: { summary: 'none' },
description: 'Defines the maximum height of the component.',
},
width: {
control: 'text',
defaultValue: { summary: '100%' },
description: 'Defines the width of the component.',
},
maxWidth: {
control: 'text',
defaultValue: { summary: 'none' },
description: 'Defines the maximum width of the component.',
},
height: {
control: 'text',
defaultValue: { summary: 'auto' },
description: 'Defines the height of the component.',
},
};

export default {
title: 'shared/Flex',
component: Flex,
tags: ['autodocs'],
argTypes: flexArgTypes,
} as Meta;
116 changes: 116 additions & 0 deletions client/src/shared/ui/flex/flex.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import React from 'react';

import styles from './flex.module.scss';

export interface FlexProps {
/**
* [props.align] - The align-items property defines the default behavior for how items are laid out along the cross axis (perpendicular to the main axis). Default is 'normal'.
*/
align?: string;
/**
* [props.justify] - The justify-content property defines how the browser distributes space between and around content items along the main axis of their container. Default is 'normal'.
*/
justify?: string;
/**
* [props.gap] - The gap property defines the space between flex items. Default is 0.
*/
gap?: string | number;
/**
* [props.margin] - The margin property defines the space around the component. Default is 0.
*/
margin?: string | number;
/**
* [props.padding] - The padding property defines the space inside the component. Default is 0.
*/
padding?: string | number;
/**
* [props.direction] - The flex-direction property defines in which direction the container wants to stack the flex items. Default is 'row'.
*/
direction?: 'row' | 'column';
/**
* [props.maxHeight] - The max-height property defines the maximum height of the component. Default is 'none'.
*/
maxHeight?: string;
/**
* [props.position] - The position property specifies the type of positioning method used for an element. Default is 'static'.
*/
position?: string;
/**
* [props.width] - The width property defines the width of the component. Default is 'auto'.
*/
width?: string;
/**
* [props.maxWidth] - The max-width property defines the maximum width of the component. Default is 'none'.
*/
maxWidth?: string;
/**
* [props.height] - The height property defines the height of the component. Default is 'auto'.
*/
height?: string;
/**
* props.children - The content to be laid out.
*/
children: React.ReactNode;
}

/**
* The `Flex` component is a flexible box layout component that provides a more efficient way to lay out, align, and distribute space among items in a container, even when their sizes are unknown or dynamic.
*
* Example usage:
*
* ```tsx
* <Flex
* align="center"
* justify="space-between"
* gap={10}
* margin={20}
* padding={20}
* direction="row"
* maxHeight="500px"
* position="relative"
* width="100%"
* maxWidth="500px"
* height="auto"
* >
* <div>Item 1</div>
* <div>Item 2</div>
* <div>Item 3</div>
* </Flex>
* ```
*/
export const Flex: React.FC<FlexProps> = props => {
const {
align,
justify,
gap,
margin,
padding,
direction,
maxHeight,
position,
width,
maxWidth,
height,
children,
} = props;

const style = {
'--align': align,
'--justify': justify,
'--gap': gap,
'--margin': margin,
'--padding': padding,
'--direction': direction,
'--maxHeight': maxHeight,
'--position': position,
'--width': width,
'--maxWidth': maxWidth,
'--height': height,
} as React.CSSProperties;

return (
<div className={styles.flexWrapper} style={style}>
{children}
</div>
);
};
1 change: 1 addition & 0 deletions client/src/shared/ui/flex/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Flex } from './flex';
15 changes: 15 additions & 0 deletions client/src/shared/ui/icon-wrapper/icon-wrapper.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.iconWrapper {
cursor: var(--cursor, default);
width: var(--width, auto);
height: var(--height, auto);
padding: var(--padding, 0);
margin: var(--margin, 0);
display: flex;
justify-content: center;
align-items: center;

svg {
width: var(--svg-width, auto);
height: var(--svg-height, auto);
}
}
Loading

2 comments on commit a946bd3

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deploy preview for teameights ready!

✅ Preview
https://teameights-knyv9aah2-exortme1ster.vercel.app

Built with commit a946bd3.
This pull request is being automatically deployed with vercel-action

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deploy preview for teameights-storybook ready!

✅ Preview
https://teameights-storybook-r9cwzk746-exortme1ster.vercel.app

Built with commit a946bd3.
This pull request is being automatically deployed with vercel-action

Please sign in to comment.