📱전화번호
export const formatPhoneNumber = (number: string): string => {
const trimmed = number.replace(/\D/g, "");
if (trimmed.length >= 11) {
return trimmed.replace(/(\d{3})(\d{4})(\d{4})/, "$1-$2-$3");
} else if (trimmed.length === 10) {
return trimmed.replace(/(\d{3})(\d{3})(\d{4})/, "$1-$2-$3");
} else {
return trimmed.replace(/(\d{3})(\d+)/, "$1-$2");
}
};
export const isPhone = (phone: string): boolean =>
/^(01[016789]{1}|02|0[3-9]{1}[0-9]{1})-?[0-9]{3,4}-?[0-9]{4}$/.test(phone);
export const formatFullNumber = (
countryCode?: string,
number?: string,
): string => {
let result = "";
if (countryCode) result += `+${countryCode} `;
if (number) result += formatPhoneNumber(number);
return result;
};
export const priceFormatterUntilTwo = (price: number) => {
return `$${price.toFixed(2)}`;
};
export const isOnlyNumber = (target: unknown): Error | true => {
const regex = /^[0-9]+$|^$/;
if (!regex.test(target as string)) {
return {
id: "not-number",
message: "숫자 값만 입력 가능합니다.",
};
}
return true;
};
// 키보드 누를 시 바로 적용되는 함수 : onKeyPress 이용
onKeyPress={handleKeyPressNumber}
maxLength={13}
onChange={(e) => setPhoneInput(e.target.value)}
export const handleKeyPressNumber = (e: any) => {
if (e.target.value.length === 3 || e.target.value.length === 8) {
e.target.value += "-";
}
if (/^\D*$/.test(e.key)) {
e.target.value = e.target.value.replace(/[^0-9|\-]/g, "");
}
const regex = `/\d{${e.target.value.length}}/`;
if (!new RegExp(regex).test(e.target.value)) {
e.target.value = e.target.value.replace(/[^0-9|\-]/g, "");
}
};
💸 가격 export const usdPriceFormat = (price: number): string => {
let priceString = price >= 0 ? "$" : "- $";
priceString += Math.abs(price).toLocaleString();
return priceString;
};
export const numberWithCommas = x => {
return x
.toFixed(2)
.toString()
.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
};
export const roundUpPrice = price => {
let roundPrice = Math.ceil(price * 100) / 100;
return roundPrice.toFixed(2) * 1;
};
export const formatPriceNumber = (number: number): string => {
let price = number >= 0 ? "₩ " : "- ₩ ";
price += Math.abs(number).toLocaleString();
return price;
};
🗓 날짜 (moment.js)
export const formatChatDate = (date: string): string => {
const now = moment();
const target = moment(date);
if (target.isSame(now, "day")) {
return target.format("h:mm A");
} else if (target.isSame(now, "year")) {
return target.format("MM/DD h:mm A");
} else {
return target.format("MM/DD/YYYY h:mm A");
}
};
🔠 문자열 export const capitalizeFirstLetter = (s: string): string => {
if (!s || typeof s !== "string") {
return "";
}
return s.charAt(0).toUpperCase() + s.slice(1);
};
export const onCapitalize = (val: any) => {
const value = val.target.value;
const onlyEng = value ? value.replace(/[^A-Za-z|^0-9]/gi, "") : "";
return onlyEng.toUpperCase();
};
export const validationKorean = (value: string): boolean => {
const regex = /^[ㄱ-ㅎ가-힣0-9\s]+$/;
return regex.test(value);
};
export const validationEnglish = (value: string): boolean => {
const regex = /^[a-zA-Z0-9\s']+$/;
return regex.test(value);
};
export const validationKoreanAndCharacter = (value: string): boolean => {
const regex = /^[ㄱ-ㅎ가-힣0-9\][@#-_$%^&*()\s]+$/;
return regex.test(value);
};
export const validateEnglishAndCharacter = (value: string): boolean => {
const regex = /^[a-zA-Z0-9\][@#-_$%^&*()\s']+$/;
return regex.test(value);
};
export const emailValidation = (value: string) => {
const re = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/;
return re.test(value);
};
export const isEmail = (email: string): boolean =>
/^([\w_\.\-\+])+\@([\w\-]+\.)+([\w]{2,10})+$/.test(email);
export const formatBytes = (bytes: number, decimals = 2) => {
if (bytes === 0) return "0 Bytes";
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + " " + sizes[i];
};
const checkSearchedWord = (keyword: any) => {
if (keyword?.length > 0) {
//특수문자 제거
const expText = /[%=><]/;
if (expText.test(keyword) == true) {
//FIXME alert 경고창 변경하기
alert("특수문자를 입력 할수 없습니다.");
keyword = keyword.split(expText).join("");
return false;
}
//특정문자열(sql예약어의 앞뒤공백포함) 제거
const sqlArray = [
//sql 예약어
"OR",
"SELECT",
"INSERT",
"DELETE",
"UPDATE",
"CREATE",
"DROP",
"EXEC",
"UNION",
"FETCH",
"DECLARE",
"TRUNCATE",
];
let regex;
for (let i = 0; i < sqlArray.length; i++) {
regex = new RegExp(sqlArray[i], "gi");
if (regex.test(keyword)) {
alert(
'"' + sqlArray[i] + '"와(과) 같은 특정문자로 검색할 수 없습니다.',
);
keyword = keyword.replace(regex, "");
return false;
}
}
}
return true;
};
export default checkSearchedWord;
export const formatStringWithEnter = (str: string): string => {
return str.replaceAll("<br/>", "\n");
};
🎮 콘솔 헬퍼 export const ConsoleDIR = (data: any) => {
if (process.env.NODE_ENV === "production") return;
console.dir(data);
};
export const ConsoleLOG = ({ data }: any) => {
if (process.env.NODE_ENV === "production") return;
console.log(data);
};
// eslint-disable-next-line import/no-anonymous-default-export
export default { ConsoleDIR, ConsoleLOG };
🔒 비밀번호
//최소 8 자, 하나 이상의 문자와 하나의 숫자 정규식
var reg = "^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$";
var txt = "aaaa";
if( !reg.test(txt) ) {
alert("비밀번호 정규식 규칙 위반!!");
return false;
}
//최소 8 자, 하나 이상의 문자, 하나의 숫자 및 하나의 특수 문자 정규식
var reg = /^(?=.*[a-zA-Z])((?=.*\d)|(?=.*\W)).{6,}$/;
var txt = "aaaa";
if( !reg.test(txt) ) {
alert("비밀번호 정규식 규칙 위반!!");
return false;
}
//최소 8 자, 하나 이상의 대문자, 하나의 소문자, 하나의 숫자 및 하나의 특수 문자 정규식
var reg = "^(?=.*[A-Za-z])(?=.*\d)(?=.*[@$!%*#?&])[A-Za-z\d@$!%*#?&]{8,}$";
var txt = "aaaa";
if( !reg.test(txt) ) {
alert("비밀번호 정규식 규칙 위반!!");
return false;
}
🎨color const hexToRGB = (hex, alpha = 1) => {
let parseString = hex
if (hex.startsWith('#')) {
parseString = hex.slice(1, 7)
}
if (parseString.length !== 6) {
return null
}
const r = parseInt(parseString.slice(0, 2), 16)
const g = parseInt(parseString.slice(2, 4), 16)
const b = parseInt(parseString.slice(4, 6), 16)
if (isNaN(r) || isNaN(g) || isNaN(b)) {
return null
}
return `rgba(${r}, ${g}, ${b}, ${alpha})`
}
menu dropdown 애니메이션 #menu #list {
max-height: 0;
transition: max-height 0.15s ease-out;
overflow: hidden;
background: #d5d5d5;
}
#menu:hover #list {
max-height: 500px;
transition: max-height 0.25s ease-in;
}
<div id="menu">
<a>hover me</a>
<ul id="list">
<!-- Create a bunch, or not a bunch, of li's to see the timing. -->
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
<li>item</li>
</ul>
</div>