mirror of
https://github.com/Nezumi-2711/react-training.git
synced 2026-09-22 13:38:51 +00:00
Add common component and helpers
This commit is contained in:
@@ -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>;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user