Add common component and helpers

This commit is contained in:
2023-10-26 16:49:16 +07:00
parent f9f5990a4a
commit bd407bb933
10 changed files with 140 additions and 5 deletions
+25 -5
View File
@@ -1,15 +1,35 @@
import styled from 'styled-components';
import styled, { css } from 'styled-components';
const Button = styled.button`
interface IButtonStyle {
styled?: 'primary' | 'secondary';
}
const Button = styled.button<IButtonStyle>`
padding: 10px 20px;
background-color: var(--primary-color);
color: var(--light-text);
text-transform: uppercase;
font-weight: 500;
font-weight: 600;
cursor: pointer;
border-radius: var(--radius-md);
${(props) =>
props.styled === 'primary' &&
css`
background-color: var(--primary-color);
color: var(--light-text);
`}
${(props) =>
props.styled === 'secondary' &&
css`
background-color: var(--secondary-btn-color);
`}
`;
Button.defaultProps = {
styled: 'primary',
};
export default Button;
@@ -0,0 +1,12 @@
import { css } from 'styled-components';
const CommonInput = css`
border: 1px solid var(--border-color);
border-radius: var(--radius-sm);
padding: 10px 20px;
font-size: var(--fs-sm-x);
width: 200px;
`;
export default CommonInput;
@@ -0,0 +1,10 @@
import styled from 'styled-components';
// Styled
import CommonInput from './CommonInput';
const Input = styled.input`
${CommonInput}
`;
export default Input;
@@ -0,0 +1,10 @@
import styled from 'styled-components';
// Styled
import CommonInput from './CommonInput';
const TextArea = styled.textarea`
${CommonInput}
`;
export default TextArea;
@@ -19,3 +19,10 @@ export interface ITableBody<T> {
data?: T[];
render?: (value: T) => JSX.Element;
}
export interface IDialogProps {
title?: string;
children?: JSX.Element[] | JSX.Element;
onClose?: () => void;
ref?: React.MutableRefObject<HTMLDialogElement | undefined>;
}
+23
View File
@@ -6,3 +6,26 @@ export type TUser = {
phone: string;
roomId: string;
};
export type TStateSchema = {
[key: string]: {
value?: string;
error?: string;
};
};
export type TKeyValue = {
[key: string]: string | undefined | boolean;
};
export type TPropValues = 'value' | 'error' | boolean;
export type TValidator = {
[key: string]: {
required?: boolean;
validator?: {
func?: (value: string) => boolean;
error?: string;
};
};
};
+30
View File
@@ -0,0 +1,30 @@
import { TKeyValue, TPropValues, TStateSchema } from '../globals/types';
export const VALUE = 'value';
export const ERROR = 'error';
export const REQUIRED_FIELD_ERROR = 'This is required field';
function isBool(value: unknown) {
return typeof value === 'boolean';
}
const isObject = (value: unknown) => {
return typeof value === 'object' && value !== null;
};
const isRequired = (value: string | number, isRequired: unknown) => {
if (!value && isRequired) return REQUIRED_FIELD_ERROR;
return '';
};
const getPropValues = (stateSchema: TStateSchema, prop?: TPropValues) => {
return Object.keys(stateSchema).reduce((field, key) => {
field[key] = isBool(prop)
? prop
: stateSchema[key][prop as Exclude<TPropValues, boolean>];
return field;
}, {} as TKeyValue);
};
export { isObject, isRequired, getPropValues };
@@ -0,0 +1,11 @@
const isValidString = (value: string): boolean =>
/^[a-zA-Z]{4,}(?: [a-zA-Z]+){0,2}$/gm.test(value);
const isValidNumber = (value: string): boolean => /^[0-9]*$/.test(value);
const isValidPhoneNumber = (value: string): boolean =>
/(84|0[3|5|7|8|9])+([0-9]{8})\b/g.test(value);
const isValidAddress = (value: string): boolean => value.trim().length >= 10;
export { isValidString, isValidNumber, isValidPhoneNumber, isValidAddress };
@@ -1,10 +1,17 @@
:root {
--primary-color: #0010ba;
--header-table-color: #ebebeb;
--border-color: #8c8c8c;
--secondary-btn-color: #d1d1d1;
--disabled-btn-color: #7f82a6;
--hover-background-color: #f3f4f6;
--light-text: #fff;
--dark-text: #787878;
--error-text: #ff3d3d;
--radius-sm: 5px;
--radius-md: 10px;
@@ -15,4 +22,5 @@
--fs-lg: 40px;
--fs-sm: 18px;
--fs-sm-x: 16px;
--fs-sm-2x: 12px;
}