@basiln/utils 0.1.0 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/CHANGELOG.md +125 -5
  2. package/dist/Choose.js +50 -0
  3. package/dist/Choose.js.map +1 -0
  4. package/dist/Choose.mjs +7 -0
  5. package/dist/Choose.mjs.map +1 -0
  6. package/dist/Flex.js +70 -0
  7. package/dist/Flex.js.map +1 -0
  8. package/dist/Flex.mjs +10 -0
  9. package/dist/Flex.mjs.map +1 -0
  10. package/dist/If.js +35 -0
  11. package/dist/If.js.map +1 -0
  12. package/dist/If.mjs +7 -0
  13. package/dist/If.mjs.map +1 -0
  14. package/dist/SafeArea.js +91 -0
  15. package/dist/SafeArea.js.map +1 -0
  16. package/dist/SafeArea.mjs +10 -0
  17. package/dist/SafeArea.mjs.map +1 -0
  18. package/dist/Spacing.js +49 -0
  19. package/dist/Spacing.js.map +1 -0
  20. package/dist/Spacing.mjs +8 -0
  21. package/dist/Spacing.mjs.map +1 -0
  22. package/dist/Validate.js +43 -0
  23. package/dist/Validate.js.map +1 -0
  24. package/dist/Validate.mjs +7 -0
  25. package/dist/Validate.mjs.map +1 -0
  26. package/dist/chunk-7WNTKDNW.mjs +26 -0
  27. package/dist/chunk-7WNTKDNW.mjs.map +1 -0
  28. package/dist/chunk-C7VOPXT2.mjs +23 -0
  29. package/dist/chunk-C7VOPXT2.mjs.map +1 -0
  30. package/dist/chunk-FUGA35PJ.mjs +22 -0
  31. package/dist/chunk-FUGA35PJ.mjs.map +1 -0
  32. package/dist/chunk-GQPOYY4X.mjs +77 -0
  33. package/dist/chunk-GQPOYY4X.mjs.map +1 -0
  34. package/dist/chunk-LKUAG7PE.mjs +22 -0
  35. package/dist/chunk-LKUAG7PE.mjs.map +1 -0
  36. package/dist/chunk-OIJ4AVT7.mjs +37 -0
  37. package/dist/chunk-OIJ4AVT7.mjs.map +1 -0
  38. package/dist/chunk-Q3B6WSD7.mjs +42 -0
  39. package/dist/chunk-Q3B6WSD7.mjs.map +1 -0
  40. package/dist/chunk-QD5QDTUG.mjs +14 -0
  41. package/dist/chunk-QD5QDTUG.mjs.map +1 -0
  42. package/dist/chunk-R23KSR7N.mjs +19 -0
  43. package/dist/chunk-R23KSR7N.mjs.map +1 -0
  44. package/dist/chunk-SJJHTYZC.mjs +30 -0
  45. package/dist/chunk-SJJHTYZC.mjs.map +1 -0
  46. package/dist/chunk-T7K7QYTL.mjs +9 -0
  47. package/dist/chunk-T7K7QYTL.mjs.map +1 -0
  48. package/dist/chunk-U4T3KW7L.mjs +67 -0
  49. package/dist/chunk-U4T3KW7L.mjs.map +1 -0
  50. package/dist/chunk-UFRXNT2I.mjs +11 -0
  51. package/dist/chunk-UFRXNT2I.mjs.map +1 -0
  52. package/dist/chunk-WHYNBO2G.mjs +12 -0
  53. package/dist/chunk-WHYNBO2G.mjs.map +1 -0
  54. package/dist/chunk-WOYL5AA5.mjs +39 -0
  55. package/dist/chunk-WOYL5AA5.mjs.map +1 -0
  56. package/dist/chunk-XBGZ3YNL.mjs +20 -0
  57. package/dist/chunk-XBGZ3YNL.mjs.map +1 -0
  58. package/dist/chunk-Z4QPISK7.mjs +36 -0
  59. package/dist/chunk-Z4QPISK7.mjs.map +1 -0
  60. package/dist/coerceCssPixelValue.js +33 -0
  61. package/dist/coerceCssPixelValue.js.map +1 -0
  62. package/dist/coerceCssPixelValue.mjs +7 -0
  63. package/dist/coerceCssPixelValue.mjs.map +1 -0
  64. package/dist/composeEventHandlers.js +38 -0
  65. package/dist/composeEventHandlers.js.map +1 -0
  66. package/dist/composeEventHandlers.mjs +7 -0
  67. package/dist/composeEventHandlers.mjs.map +1 -0
  68. package/dist/constants/josa.js +105 -0
  69. package/dist/constants/josa.js.map +1 -0
  70. package/dist/constants/josa.mjs +15 -0
  71. package/dist/constants/josa.mjs.map +1 -0
  72. package/dist/createContext.js +56 -0
  73. package/dist/createContext.js.map +1 -0
  74. package/dist/createContext.mjs +7 -0
  75. package/dist/createContext.mjs.map +1 -0
  76. package/dist/ellipsis.js +45 -0
  77. package/dist/ellipsis.js.map +1 -0
  78. package/dist/ellipsis.mjs +9 -0
  79. package/dist/ellipsis.mjs.map +1 -0
  80. package/dist/getVar.js +36 -0
  81. package/dist/getVar.js.map +1 -0
  82. package/dist/getVar.mjs +7 -0
  83. package/dist/getVar.mjs.map +1 -0
  84. package/dist/hasBatchim.js +111 -0
  85. package/dist/hasBatchim.js.map +1 -0
  86. package/dist/hasBatchim.mjs +8 -0
  87. package/dist/hasBatchim.mjs.map +1 -0
  88. package/dist/hexToRgba.js +61 -0
  89. package/dist/hexToRgba.js.map +1 -0
  90. package/dist/hexToRgba.mjs +7 -0
  91. package/dist/hexToRgba.mjs.map +1 -0
  92. package/dist/index.d.ts +174 -0
  93. package/dist/index.js +456 -0
  94. package/dist/index.js.map +1 -0
  95. package/dist/index.mjs +64 -0
  96. package/dist/index.mjs.map +1 -0
  97. package/dist/josa.js +133 -0
  98. package/dist/josa.js.map +1 -0
  99. package/dist/josa.mjs +9 -0
  100. package/dist/josa.mjs.map +1 -0
  101. package/dist/queryString.js +91 -0
  102. package/dist/queryString.js.map +1 -0
  103. package/dist/queryString.mjs +7 -0
  104. package/dist/queryString.mjs.map +1 -0
  105. package/dist/useSafeArea.js +49 -0
  106. package/dist/useSafeArea.js.map +1 -0
  107. package/dist/useSafeArea.mjs +8 -0
  108. package/dist/useSafeArea.mjs.map +1 -0
  109. package/package.json +6 -4
  110. package/src/Choose.tsx +18 -10
  111. package/src/Flex.tsx +51 -0
  112. package/src/If.tsx +6 -2
  113. package/src/SafeArea.tsx +46 -0
  114. package/src/Spacing.tsx +30 -0
  115. package/src/Validate.ts +25 -0
  116. package/src/coerceCssPixelValue.ts +5 -0
  117. package/src/composeEventHandlers.ts +1 -1
  118. package/src/constants/josa.ts +72 -0
  119. package/src/createContext.tsx +5 -5
  120. package/src/ellipsis.ts +19 -0
  121. package/src/getVar.ts +1 -1
  122. package/src/hasBatchim.ts +31 -0
  123. package/src/hexToRgba.ts +45 -0
  124. package/src/index.ts +34 -3
  125. package/src/josa.ts +50 -0
  126. package/src/queryString.ts +134 -0
  127. package/src/useSafeArea.ts +24 -0
  128. package/tsup.config.ts +5 -5
  129. package/LICENSE +0 -21
  130. package/src/types/Choose.ts +0 -14
  131. package/src/types/If.ts +0 -6
  132. package/src/types/getVar.ts +0 -1
  133. package/src/types/index.ts +0 -9
package/dist/index.mjs ADDED
@@ -0,0 +1,64 @@
1
+ import {
2
+ createContext
3
+ } from "./chunk-Z4QPISK7.mjs";
4
+ import {
5
+ ellipsis,
6
+ multiLineEllipsis
7
+ } from "./chunk-XBGZ3YNL.mjs";
8
+ import {
9
+ getVar
10
+ } from "./chunk-WHYNBO2G.mjs";
11
+ import {
12
+ hexToRgba
13
+ } from "./chunk-OIJ4AVT7.mjs";
14
+ import {
15
+ josa
16
+ } from "./chunk-SJJHTYZC.mjs";
17
+ import "./chunk-C7VOPXT2.mjs";
18
+ import "./chunk-GQPOYY4X.mjs";
19
+ import {
20
+ queryString
21
+ } from "./chunk-U4T3KW7L.mjs";
22
+ import {
23
+ Choose
24
+ } from "./chunk-7WNTKDNW.mjs";
25
+ import {
26
+ Flex
27
+ } from "./chunk-Q3B6WSD7.mjs";
28
+ import {
29
+ If
30
+ } from "./chunk-UFRXNT2I.mjs";
31
+ import {
32
+ SafeArea
33
+ } from "./chunk-WOYL5AA5.mjs";
34
+ import {
35
+ useSafeArea
36
+ } from "./chunk-FUGA35PJ.mjs";
37
+ import {
38
+ Spacing
39
+ } from "./chunk-LKUAG7PE.mjs";
40
+ import {
41
+ Validate
42
+ } from "./chunk-R23KSR7N.mjs";
43
+ import "./chunk-T7K7QYTL.mjs";
44
+ import {
45
+ composeEventHandlers
46
+ } from "./chunk-QD5QDTUG.mjs";
47
+ export {
48
+ Choose,
49
+ Flex,
50
+ If,
51
+ SafeArea,
52
+ Spacing,
53
+ Validate,
54
+ composeEventHandlers,
55
+ createContext,
56
+ ellipsis,
57
+ getVar,
58
+ hexToRgba,
59
+ josa,
60
+ multiLineEllipsis,
61
+ queryString,
62
+ useSafeArea
63
+ };
64
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/dist/josa.js ADDED
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/josa.ts
21
+ var josa_exports = {};
22
+ __export(josa_exports, {
23
+ josa: () => josa
24
+ });
25
+ module.exports = __toCommonJS(josa_exports);
26
+
27
+ // src/constants/josa.ts
28
+ var COMPLETE_HANGUL_START_CHARCODE = "\uAC00".charCodeAt(0);
29
+ var COMPLETE_HANGUL_END_CHARCODE = "\uD7A3".charCodeAt(0);
30
+ var NUMBER_OF_JONGSEONG = 28;
31
+ var DISASSEMBLED_CONSONANTS_BY_CONSONANT = {
32
+ "": "",
33
+ \u3131: "\u3131",
34
+ \u3132: "\u3132",
35
+ \u3133: "\u3131\u3145",
36
+ \u3134: "\u3134",
37
+ \u3135: "\u3134\u3148",
38
+ \u3136: "\u3134\u314E",
39
+ \u3137: "\u3137",
40
+ \u3138: "\u3138",
41
+ \u3139: "\u3139",
42
+ \u313A: "\u3139\u3131",
43
+ \u313B: "\u3139\u3141",
44
+ \u313C: "\u3139\u3142",
45
+ \u313D: "\u3139\u3145",
46
+ \u313E: "\u3139\u314C",
47
+ \u313F: "\u3139\u314D",
48
+ \u3140: "\u3139\u314E",
49
+ \u3141: "\u3141",
50
+ \u3142: "\u3142",
51
+ \u3143: "\u3143",
52
+ \u3144: "\u3142\u3145",
53
+ \u3145: "\u3145",
54
+ \u3146: "\u3146",
55
+ \u3147: "\u3147",
56
+ \u3148: "\u3148",
57
+ \u3149: "\u3149",
58
+ \u314A: "\u314A",
59
+ \u314B: "\u314B",
60
+ \u314C: "\u314C",
61
+ \u314D: "\u314D",
62
+ \u314E: "\u314E"
63
+ };
64
+ var JONGSEONGS = [
65
+ "",
66
+ "\u3131",
67
+ "\u3132",
68
+ "\u3133",
69
+ "\u3134",
70
+ "\u3135",
71
+ "\u3136",
72
+ "\u3137",
73
+ "\u3139",
74
+ "\u313A",
75
+ "\u313B",
76
+ "\u313C",
77
+ "\u313D",
78
+ "\u313E",
79
+ "\u313F",
80
+ "\u3140",
81
+ "\u3141",
82
+ "\u3142",
83
+ "\u3144",
84
+ "\u3145",
85
+ "\u3146",
86
+ "\u3147",
87
+ "\u3148",
88
+ "\u314A",
89
+ "\u314B",
90
+ "\u314C",
91
+ "\u314D",
92
+ "\u314E"
93
+ ].map((consonant) => DISASSEMBLED_CONSONANTS_BY_CONSONANT[consonant]);
94
+
95
+ // src/hasBatchim.ts
96
+ function hasBatchim(str) {
97
+ const lastChar = str[str.length - 1];
98
+ if (!lastChar)
99
+ return false;
100
+ const charCode = lastChar.charCodeAt(0);
101
+ if (charCode < COMPLETE_HANGUL_START_CHARCODE || charCode > COMPLETE_HANGUL_END_CHARCODE) {
102
+ return false;
103
+ }
104
+ const batchimCode = (charCode - COMPLETE_HANGUL_START_CHARCODE) % NUMBER_OF_JONGSEONG;
105
+ return batchimCode > 0;
106
+ }
107
+
108
+ // src/josa.ts
109
+ function josa(props) {
110
+ const { word, josa: josa2 } = props;
111
+ if (!word) {
112
+ return word;
113
+ }
114
+ return `${word}${josaPicker({
115
+ word,
116
+ josa: josa2
117
+ })}`;
118
+ }
119
+ function josaPicker(props) {
120
+ const { word, josa: josa2 } = props;
121
+ if (!word) {
122
+ return josa2.split("/")[0];
123
+ }
124
+ const has\uBC1B\uCE68 = hasBatchim(word);
125
+ const index = has\uBC1B\uCE68 ? 0 : 1;
126
+ return josa2.split("/")[index];
127
+ }
128
+ josa.pick = josaPicker;
129
+ // Annotate the CommonJS export names for ESM import in node:
130
+ 0 && (module.exports = {
131
+ josa
132
+ });
133
+ //# sourceMappingURL=josa.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/josa.ts","../src/constants/josa.ts","../src/hasBatchim.ts"],"sourcesContent":["import { hasBatchim } from './hasBatchim';\n\ntype JosaOption = '이/가' | '을/를' | '은/는';\n\ntype ExtractJosaOption<T> = T extends `${infer A}/${infer B}` ? A | B : never;\n\nexport type JosaProps<U extends JosaOption> = {\n word: string;\n josa: U;\n};\n\n/**\n * 주어진 단어와 조사 옵션을 기반으로 올바른 조사를 반환합니다.\n * @returns 단어와 올바른 조사가 결합된 문자열\n */\nexport function josa<U extends JosaOption>(\n props: JosaProps<U>\n): `${JosaProps<U>['word']}${ExtractJosaOption<U>}` {\n const { word, josa } = props;\n\n if (!word) {\n return word as `${JosaProps<U>['word']}${ExtractJosaOption<U>}`;\n }\n\n return `${word}${josaPicker({\n word,\n josa,\n })}` as `${JosaProps<U>['word']}${ExtractJosaOption<U>}`;\n}\n\n/**\n * 주어진 단어와 조사 옵션을 기반으로 올바른 조사를 선택합니다.\n * @returns 올바른 조사\n */\nfunction josaPicker<U extends JosaOption>(\n props: JosaProps<U>\n): ExtractJosaOption<U> {\n const { word, josa } = props;\n\n if (!word) {\n return josa.split('/')[0] as ExtractJosaOption<U>;\n }\n\n const has받침 = hasBatchim(word);\n const index = has받침 ? 0 : 1;\n\n return josa.split('/')[index] as ExtractJosaOption<U>;\n}\n\njosa.pick = josaPicker;\n","export const COMPLETE_HANGUL_START_CHARCODE = '가'.charCodeAt(0);\nexport const COMPLETE_HANGUL_END_CHARCODE = '힣'.charCodeAt(0);\n\nexport const NUMBER_OF_JONGSEONG = 28;\nexport const NUMBER_OF_JUNGSEONG = 21;\n\nconst DISASSEMBLED_CONSONANTS_BY_CONSONANT = {\n '': '',\n ㄱ: 'ㄱ',\n ㄲ: 'ㄲ',\n ㄳ: 'ㄱㅅ',\n ㄴ: 'ㄴ',\n ㄵ: 'ㄴㅈ',\n ㄶ: 'ㄴㅎ',\n ㄷ: 'ㄷ',\n ㄸ: 'ㄸ',\n ㄹ: 'ㄹ',\n ㄺ: 'ㄹㄱ',\n ㄻ: 'ㄹㅁ',\n ㄼ: 'ㄹㅂ',\n ㄽ: 'ㄹㅅ',\n ㄾ: 'ㄹㅌ',\n ㄿ: 'ㄹㅍ',\n ㅀ: 'ㄹㅎ',\n ㅁ: 'ㅁ',\n ㅂ: 'ㅂ',\n ㅃ: 'ㅃ',\n ㅄ: 'ㅂㅅ',\n ㅅ: 'ㅅ',\n ㅆ: 'ㅆ',\n ㅇ: 'ㅇ',\n ㅈ: 'ㅈ',\n ㅉ: 'ㅉ',\n ㅊ: 'ㅊ',\n ㅋ: 'ㅋ',\n ㅌ: 'ㅌ',\n ㅍ: 'ㅍ',\n ㅎ: 'ㅎ',\n} as const;\n\nexport const JONGSEONGS = (\n [\n '',\n 'ㄱ',\n 'ㄲ',\n 'ㄳ',\n 'ㄴ',\n 'ㄵ',\n 'ㄶ',\n 'ㄷ',\n 'ㄹ',\n 'ㄺ',\n 'ㄻ',\n 'ㄼ',\n 'ㄽ',\n 'ㄾ',\n 'ㄿ',\n 'ㅀ',\n 'ㅁ',\n 'ㅂ',\n 'ㅄ',\n 'ㅅ',\n 'ㅆ',\n 'ㅇ',\n 'ㅈ',\n 'ㅊ',\n 'ㅋ',\n 'ㅌ',\n 'ㅍ',\n 'ㅎ',\n ] as const\n).map((consonant) => DISASSEMBLED_CONSONANTS_BY_CONSONANT[consonant]);\n","import {\n COMPLETE_HANGUL_END_CHARCODE,\n COMPLETE_HANGUL_START_CHARCODE,\n NUMBER_OF_JONGSEONG,\n} from './constants/josa';\n\n/**\n * 한글 음절의 받침 유무를 확인합니다.\n * @param str - 검사할 문자열\n * @returns 받침이 있으면 true, 없으면 false\n */\nexport function hasBatchim(str: string): boolean {\n const lastChar = str[str.length - 1];\n if (!lastChar) return false;\n\n const charCode = lastChar.charCodeAt(0);\n\n // 한글 완성형 문자인지 확인\n if (\n charCode < COMPLETE_HANGUL_START_CHARCODE ||\n charCode > COMPLETE_HANGUL_END_CHARCODE\n ) {\n return false;\n }\n\n // 받침 코드 계산\n const batchimCode =\n (charCode - COMPLETE_HANGUL_START_CHARCODE) % NUMBER_OF_JONGSEONG;\n\n return batchimCode > 0; // 받침이 있으면 true\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAO,IAAM,iCAAiC,SAAI,WAAW,CAAC;AACvD,IAAM,+BAA+B,SAAI,WAAW,CAAC;AAErD,IAAM,sBAAsB;AAGnC,IAAM,uCAAuC;AAAA,EAC3C,IAAI;AAAA,EACJ,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AAAA,EACH,QAAG;AACL;AAEO,IAAM,aACX;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,EACA,IAAI,CAAC,cAAc,qCAAqC,SAAS,CAAC;;;AC5D7D,SAAS,WAAW,KAAsB;AAC/C,QAAM,WAAW,IAAI,IAAI,SAAS,CAAC;AACnC,MAAI,CAAC;AAAU,WAAO;AAEtB,QAAM,WAAW,SAAS,WAAW,CAAC;AAGtC,MACE,WAAW,kCACX,WAAW,8BACX;AACA,WAAO;AAAA,EACT;AAGA,QAAM,eACH,WAAW,kCAAkC;AAEhD,SAAO,cAAc;AACvB;;;AFfO,SAAS,KACd,OACkD;AAClD,QAAM,EAAE,MAAM,MAAAA,MAAK,IAAI;AAEvB,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AAEA,SAAO,GAAG,OAAO,WAAW;AAAA,IAC1B;AAAA,IACA,MAAAA;AAAA,EACF,CAAC;AACH;AAMA,SAAS,WACP,OACsB;AACtB,QAAM,EAAE,MAAM,MAAAA,MAAK,IAAI;AAEvB,MAAI,CAAC,MAAM;AACT,WAAOA,MAAK,MAAM,GAAG,EAAE,CAAC;AAAA,EAC1B;AAEA,QAAM,kBAAQ,WAAW,IAAI;AAC7B,QAAM,QAAQ,kBAAQ,IAAI;AAE1B,SAAOA,MAAK,MAAM,GAAG,EAAE,KAAK;AAC9B;AAEA,KAAK,OAAO;","names":["josa"]}
package/dist/josa.mjs ADDED
@@ -0,0 +1,9 @@
1
+ import {
2
+ josa
3
+ } from "./chunk-SJJHTYZC.mjs";
4
+ import "./chunk-C7VOPXT2.mjs";
5
+ import "./chunk-GQPOYY4X.mjs";
6
+ export {
7
+ josa
8
+ };
9
+ //# sourceMappingURL=josa.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/queryString.ts
21
+ var queryString_exports = {};
22
+ __export(queryString_exports, {
23
+ queryString: () => queryString
24
+ });
25
+ module.exports = __toCommonJS(queryString_exports);
26
+ function createSearchParamString(params) {
27
+ return new URLSearchParams(
28
+ Object.entries(params).filter(([, value]) => value != null).map(([key, value]) => {
29
+ if (Array.isArray(value)) {
30
+ return value.map((x) => [key, x]);
31
+ }
32
+ return [[key, value]];
33
+ }).flat()
34
+ ).toString().replace(/\+/g, "%20");
35
+ }
36
+ function createQueryString(params) {
37
+ const queryString2 = createSearchParamString(params);
38
+ if (queryString2 === "") {
39
+ return "";
40
+ }
41
+ return `?${queryString2}`;
42
+ }
43
+ function fromEntries(iterable) {
44
+ const result = {};
45
+ for (const [key, value] of Array.from(iterable)) {
46
+ if (result[key]) {
47
+ if (Array.isArray(result[key])) {
48
+ result[key].push(value);
49
+ } else {
50
+ result[key] = [result[key], value];
51
+ }
52
+ } else {
53
+ result[key] = value;
54
+ }
55
+ }
56
+ return result;
57
+ }
58
+ function parseQueryString(queryString2 = typeof location !== "undefined" ? location.search : "") {
59
+ const query = queryString2.trim().replace(/^[?#&]/, "");
60
+ return fromEntries(new URLSearchParams(query));
61
+ }
62
+ function getQueryString(name, parser) {
63
+ const value = queryString.parse()[name];
64
+ if (parser == null || value == null) {
65
+ return value;
66
+ } else {
67
+ return parser(value);
68
+ }
69
+ }
70
+ function setQueryString({
71
+ qs,
72
+ key,
73
+ value
74
+ }) {
75
+ const parsed = parseQueryString(qs);
76
+ return createQueryString({
77
+ ...parsed,
78
+ [key]: value
79
+ });
80
+ }
81
+ var queryString = {
82
+ create: createQueryString,
83
+ parse: parseQueryString,
84
+ get: getQueryString,
85
+ set: setQueryString
86
+ };
87
+ // Annotate the CommonJS export names for ESM import in node:
88
+ 0 && (module.exports = {
89
+ queryString
90
+ });
91
+ //# sourceMappingURL=queryString.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/queryString.ts"],"sourcesContent":["/**\n * @description 쿼리 스트링을 생성합니다.\n * @example createSearchParamString({ a: 1, b: 2, c: 3 }) // 'a=1&b=2&c=3'\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction createSearchParamString(params: Record<string, any>) {\n return (\n new URLSearchParams(\n Object.entries(params)\n .filter(([, value]) => value != null)\n .map(([key, value]) => {\n if (Array.isArray(value)) {\n return value.map((x) => [key, x]);\n }\n return [[key, value]];\n })\n .flat()\n )\n .toString()\n // Convert space characters to '%20' according to RFC3986 spec, from RFC1738.\n .replace(/\\+/g, '%20')\n );\n}\n\n/**\n * @description 물음표를 포함한 쿼리 스트링을 생성합니다.\n * @example createQueryString({ a: 1, b: 2, c: 3 }) // '?a=1&b=2&c=3'\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction createQueryString(params: Record<string, any>) {\n const queryString = createSearchParamString(params);\n\n if (queryString === '') {\n return '';\n }\n\n return `?${queryString}`;\n}\n\n/**\n * @description 이터러블에서 키와 값을 가진 객체로 변환합니다.\n * @example fromEntries([['a', 1], ['b', 2], ['c', 3]]) // { a: 1, b: 2, c: 3 }\n */\nfunction fromEntries<T extends readonly [string | number, unknown]>(\n iterable: Iterable<T>\n) {\n const result: Record<string | number | symbol, T[1]> = {};\n\n for (const [key, value] of Array.from(iterable)) {\n if (result[key]) {\n if (Array.isArray(result[key])) {\n (result[key] as Array<string | number>).push(value as string | number);\n } else {\n result[key] = [result[key], value];\n }\n } else {\n result[key] = value;\n }\n }\n\n return result;\n}\n\n/**\n * @description 쿼리 스트링을 객체로 변환합니다.\n * @example parseQueryString('?a=1&b=2&c=3') // { a: '1', b: '2', c: '3' }\n */\nfunction parseQueryString<Result = Record<string, string>>(\n queryString: string = typeof location !== 'undefined' ? location.search : ''\n): Result {\n const query = queryString.trim().replace(/^[?#&]/, '');\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return fromEntries(new URLSearchParams(query)) as any;\n}\n\n/**\n * @description 쿼리 스트링에서 특정 키의 값을 가져옵니다.\n *\n * @param name 가져올 쿼리 스트링의 키\n * @param parser 가져온 값을 파싱할 함수\n * @returns 파싱된 값\n *\n * @example\n * url: 'http://example.com/?a=1'\n * getQueryString('a') // '1'\n * getQueryString('a', parseInt) // 1\n * getQueryString('b') // undefined\n * getQueryString('b', parseInt) // undefined\n */\nfunction getQueryString(name: string): string | undefined;\nfunction getQueryString<T>(\n name: string,\n parser: (val: string) => T\n): T | undefined;\nfunction getQueryString<T = string>(name: string, parser?: (val: string) => T) {\n const value = queryString.parse<{ [name: string]: string | undefined }>()[\n name\n ];\n\n if (parser == null || value == null) {\n return value;\n } else {\n return parser(value);\n }\n}\n\n/**\n * @description 기존 쿼리 스트링에 새로운 쿼리 스트링을 추가합니다.\n * @example setQueryString({ qs: '?a=1', key: 'b', value: '2' }) // '?a=1&b=2'\n */\nfunction setQueryString({\n qs,\n key,\n value,\n}: {\n qs: string;\n key: string;\n value: string;\n}) {\n const parsed = parseQueryString(qs);\n\n return createQueryString({\n ...parsed,\n [key]: value,\n });\n}\n\nexport const queryString = {\n create: createQueryString,\n parse: parseQueryString,\n get: getQueryString,\n set: setQueryString,\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,SAAS,wBAAwB,QAA6B;AAC5D,SACE,IAAI;AAAA,IACF,OAAO,QAAQ,MAAM,EAClB,OAAO,CAAC,CAAC,EAAE,KAAK,MAAM,SAAS,IAAI,EACnC,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM;AACrB,UAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,eAAO,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAAA,MAClC;AACA,aAAO,CAAC,CAAC,KAAK,KAAK,CAAC;AAAA,IACtB,CAAC,EACA,KAAK;AAAA,EACV,EACG,SAAS,EAET,QAAQ,OAAO,KAAK;AAE3B;AAOA,SAAS,kBAAkB,QAA6B;AACtD,QAAMA,eAAc,wBAAwB,MAAM;AAElD,MAAIA,iBAAgB,IAAI;AACtB,WAAO;AAAA,EACT;AAEA,SAAO,IAAIA;AACb;AAMA,SAAS,YACP,UACA;AACA,QAAM,SAAiD,CAAC;AAExD,aAAW,CAAC,KAAK,KAAK,KAAK,MAAM,KAAK,QAAQ,GAAG;AAC/C,QAAI,OAAO,GAAG,GAAG;AACf,UAAI,MAAM,QAAQ,OAAO,GAAG,CAAC,GAAG;AAC9B,QAAC,OAAO,GAAG,EAA6B,KAAK,KAAwB;AAAA,MACvE,OAAO;AACL,eAAO,GAAG,IAAI,CAAC,OAAO,GAAG,GAAG,KAAK;AAAA,MACnC;AAAA,IACF,OAAO;AACL,aAAO,GAAG,IAAI;AAAA,IAChB;AAAA,EACF;AAEA,SAAO;AACT;AAMA,SAAS,iBACPA,eAAsB,OAAO,aAAa,cAAc,SAAS,SAAS,IAClE;AACR,QAAM,QAAQA,aAAY,KAAK,EAAE,QAAQ,UAAU,EAAE;AAGrD,SAAO,YAAY,IAAI,gBAAgB,KAAK,CAAC;AAC/C;AAqBA,SAAS,eAA2B,MAAc,QAA6B;AAC7E,QAAM,QAAQ,YAAY,MAA8C,EACtE,IACF;AAEA,MAAI,UAAU,QAAQ,SAAS,MAAM;AACnC,WAAO;AAAA,EACT,OAAO;AACL,WAAO,OAAO,KAAK;AAAA,EACrB;AACF;AAMA,SAAS,eAAe;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,SAAS,iBAAiB,EAAE;AAElC,SAAO,kBAAkB;AAAA,IACvB,GAAG;AAAA,IACH,CAAC,GAAG,GAAG;AAAA,EACT,CAAC;AACH;AAEO,IAAM,cAAc;AAAA,EACzB,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,KAAK;AAAA,EACL,KAAK;AACP;","names":["queryString"]}
@@ -0,0 +1,7 @@
1
+ import {
2
+ queryString
3
+ } from "./chunk-U4T3KW7L.mjs";
4
+ export {
5
+ queryString
6
+ };
7
+ //# sourceMappingURL=queryString.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/useSafeArea.ts
21
+ var useSafeArea_exports = {};
22
+ __export(useSafeArea_exports, {
23
+ useSafeArea: () => useSafeArea
24
+ });
25
+ module.exports = __toCommonJS(useSafeArea_exports);
26
+
27
+ // src/coerceCssPixelValue.ts
28
+ function coerceCssPixelValue(value) {
29
+ return typeof value === "string" ? value : `${value}px`;
30
+ }
31
+
32
+ // src/useSafeArea.ts
33
+ var useSafeArea = ({
34
+ top: T = 0,
35
+ bottom: B = 0,
36
+ left: L = 0,
37
+ right: R = 0
38
+ } = {}) => {
39
+ const top = `max(${coerceCssPixelValue(T)}, env(safe-area-inset-top))`;
40
+ const bottom = `max(${coerceCssPixelValue(B)}, env(safe-area-inset-bottom))`;
41
+ const left = `max(${coerceCssPixelValue(L)}, env(safe-area-inset-left))`;
42
+ const right = `max(${coerceCssPixelValue(R)}, env(safe-area-inset-right))`;
43
+ return { top, bottom, left, right };
44
+ };
45
+ // Annotate the CommonJS export names for ESM import in node:
46
+ 0 && (module.exports = {
47
+ useSafeArea
48
+ });
49
+ //# sourceMappingURL=useSafeArea.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/useSafeArea.ts","../src/coerceCssPixelValue.ts"],"sourcesContent":["import { coerceCssPixelValue, type CSSPixelValue } from './coerceCssPixelValue';\n\nexport type SafeAreaCssValueProps = {\n top?: CSSPixelValue;\n bottom?: CSSPixelValue;\n left?: CSSPixelValue;\n right?: CSSPixelValue;\n};\n\nconst useSafeArea = ({\n top: T = 0,\n bottom: B = 0,\n left: L = 0,\n right: R = 0,\n}: SafeAreaCssValueProps = {}) => {\n const top = `max(${coerceCssPixelValue(T)}, env(safe-area-inset-top))`;\n const bottom = `max(${coerceCssPixelValue(B)}, env(safe-area-inset-bottom))`;\n const left = `max(${coerceCssPixelValue(L)}, env(safe-area-inset-left))`;\n const right = `max(${coerceCssPixelValue(R)}, env(safe-area-inset-right))`;\n\n return { top, bottom, left, right };\n};\n\nexport { useSafeArea };\n","export type CSSPixelValue = string | number;\n\nexport function coerceCssPixelValue(value: CSSPixelValue): string {\n return typeof value === 'string' ? value : `${value}px`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEO,SAAS,oBAAoB,OAA8B;AAChE,SAAO,OAAO,UAAU,WAAW,QAAQ,GAAG;AAChD;;;ADKA,IAAM,cAAc,CAAC;AAAA,EACnB,KAAK,IAAI;AAAA,EACT,QAAQ,IAAI;AAAA,EACZ,MAAM,IAAI;AAAA,EACV,OAAO,IAAI;AACb,IAA2B,CAAC,MAAM;AAChC,QAAM,MAAM,OAAO,oBAAoB,CAAC;AACxC,QAAM,SAAS,OAAO,oBAAoB,CAAC;AAC3C,QAAM,OAAO,OAAO,oBAAoB,CAAC;AACzC,QAAM,QAAQ,OAAO,oBAAoB,CAAC;AAE1C,SAAO,EAAE,KAAK,QAAQ,MAAM,MAAM;AACpC;","names":[]}
@@ -0,0 +1,8 @@
1
+ import {
2
+ useSafeArea
3
+ } from "./chunk-FUGA35PJ.mjs";
4
+ import "./chunk-T7K7QYTL.mjs";
5
+ export {
6
+ useSafeArea
7
+ };
8
+ //# sourceMappingURL=useSafeArea.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@basiln/utils",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "exports": {
5
5
  ".": "./src/index.ts",
6
6
  "./package.json": "./package.json"
@@ -29,6 +29,7 @@
29
29
  "@types/node": "^22.9.1",
30
30
  "@types/react": "^18.3.12",
31
31
  "@types/react-dom": "^18.3.1",
32
+ "@types/styled-components": "^5.1.34",
32
33
  "@typescript-eslint/eslint-plugin": "^5.49.0",
33
34
  "@typescript-eslint/parser": "^5.49.0",
34
35
  "eslint": "^8.33.0",
@@ -38,12 +39,13 @@
38
39
  "eslint-plugin-no-relative-import-paths": "^1.5.5",
39
40
  "eslint-plugin-react-hooks": "^5.0.0",
40
41
  "eslint-plugin-react-refresh": "^0.4.14",
42
+ "styled-components": "^6.1.13",
41
43
  "tsup": "^6.5.0",
42
44
  "typescript": "^4.9.5"
43
45
  },
44
46
  "peerDependencies": {
45
47
  "react": "^18",
46
- "react-dom": "^18"
47
- },
48
- "gitHead": "dfa7ad216f0cd4359b92e63301de82980780f765"
48
+ "react-dom": "^18",
49
+ "styled-components": "^6"
50
+ }
49
51
  }
package/src/Choose.tsx CHANGED
@@ -1,18 +1,26 @@
1
- import React, { isValidElement, type FC } from 'react';
2
- import type {
3
- ChooseOtherwiseProps,
4
- ChooseProps,
5
- ChooseWhenProps,
6
- } from './types';
1
+ import { isValidElement, type ReactNode, type FC, Children } from 'react';
2
+
3
+ export type ChooseWhenProps = {
4
+ condition: boolean;
5
+ children: ReactNode;
6
+ };
7
+
8
+ export type ChooseProps = {
9
+ children: ReactNode;
10
+ };
11
+
12
+ export type ChooseOtherwiseProps = {
13
+ children: ReactNode;
14
+ };
7
15
 
8
16
  export function Choose({ children }: ChooseProps) {
9
- const validChildren = React.Children.toArray(children);
17
+ const validChildren = Children.toArray(children);
10
18
 
11
19
  const matchingChild = validChildren.find(
12
- child =>
20
+ (child) =>
13
21
  isValidElement<ChooseWhenProps>(child) &&
14
22
  child.type === Choose.When &&
15
- child.props.condition,
23
+ child.props.condition
16
24
  );
17
25
 
18
26
  if (matchingChild) {
@@ -20,7 +28,7 @@ export function Choose({ children }: ChooseProps) {
20
28
  }
21
29
 
22
30
  const otherwiseChild = validChildren.find(
23
- child => React.isValidElement(child) && child.type === Choose.Otherwise,
31
+ (child) => isValidElement(child) && child.type === Choose.Otherwise
24
32
  );
25
33
 
26
34
  return otherwiseChild || <></>;
package/src/Flex.tsx ADDED
@@ -0,0 +1,51 @@
1
+ import { memo, type CSSProperties, type HTMLAttributes } from 'react';
2
+ import { styled } from 'styled-components';
3
+
4
+ import { coerceCssPixelValue, type CSSPixelValue } from './coerceCssPixelValue';
5
+
6
+ type Justify = CSSProperties['justifyContent'];
7
+ type Align = CSSProperties['alignItems'];
8
+ type Direction = CSSProperties['flexDirection'];
9
+
10
+ export type FlexProps = HTMLAttributes<HTMLDivElement> & {
11
+ gap?: CSSPixelValue;
12
+ justify?: Justify;
13
+ align?: Align;
14
+ direction?: Direction;
15
+ };
16
+
17
+ export const Flex = memo(function Flex(props: FlexProps) {
18
+ const {
19
+ gap = 0,
20
+ justify = 'center',
21
+ align = 'center',
22
+ direction = 'row',
23
+ children,
24
+ ...restProps
25
+ } = props;
26
+
27
+ return (
28
+ <Container
29
+ $gap={gap}
30
+ $justify={justify}
31
+ $align={align}
32
+ $direction={direction}
33
+ {...restProps}
34
+ >
35
+ {children}
36
+ </Container>
37
+ );
38
+ });
39
+
40
+ export const Container = styled.div<{
41
+ $gap: CSSPixelValue;
42
+ $justify: Justify;
43
+ $align: Align;
44
+ $direction: Direction;
45
+ }>`
46
+ display: flex;
47
+ flex-direction: ${({ $direction }) => $direction};
48
+ gap: ${({ $gap }) => coerceCssPixelValue($gap)};
49
+ align-items: ${({ $align }) => $align};
50
+ justify-content: ${({ $justify }) => $justify};
51
+ `;
package/src/If.tsx CHANGED
@@ -1,5 +1,9 @@
1
- import React from 'react';
2
- import type { IfProps } from './types';
1
+ import { type ReactNode } from 'react';
2
+
3
+ export type IfProps = {
4
+ condition: boolean;
5
+ children: ReactNode;
6
+ };
3
7
 
4
8
  export function If(props: IfProps) {
5
9
  const { condition, children } = props;
@@ -0,0 +1,46 @@
1
+ import React, {
2
+ memo,
3
+ type ComponentPropsWithoutRef,
4
+ type ReactNode,
5
+ } from 'react';
6
+
7
+ import { Spacing } from './Spacing';
8
+ import { useSafeArea } from './useSafeArea';
9
+
10
+ export type SafeAreaProps<T extends React.ElementType = 'div'> = {
11
+ as?: T;
12
+ children: ReactNode;
13
+ } & ComponentPropsWithoutRef<T>;
14
+
15
+ export const SafeArea = <T extends React.ElementType = 'div'>({
16
+ as,
17
+ children,
18
+ ...props
19
+ }: SafeAreaProps<T>) => {
20
+ const Component = as || 'div';
21
+
22
+ return (
23
+ <Component {...props}>
24
+ <SafeAreaTop />
25
+ {children}
26
+ <SafeAreaBottom />
27
+ </Component>
28
+ );
29
+ };
30
+
31
+ const SafeAreaTop = memo(function SafeAreaTop(
32
+ props: Omit<ComponentPropsWithoutRef<typeof Spacing>, 'size'>
33
+ ) {
34
+ const { top } = useSafeArea();
35
+ return <Spacing {...props} size={top} />;
36
+ });
37
+
38
+ const SafeAreaBottom = memo(function SafeAreaBottom(
39
+ props: Omit<ComponentPropsWithoutRef<typeof Spacing>, 'size'>
40
+ ) {
41
+ const { bottom } = useSafeArea();
42
+ return <Spacing {...props} size={bottom} />;
43
+ });
44
+
45
+ SafeArea.Top = SafeAreaTop;
46
+ SafeArea.Bottom = SafeAreaBottom;
@@ -0,0 +1,30 @@
1
+ import { memo, type HTMLAttributes } from 'react';
2
+ import { styled } from 'styled-components';
3
+
4
+ import { coerceCssPixelValue, type CSSPixelValue } from './coerceCssPixelValue';
5
+
6
+ type AxisDirection = 'vertical' | 'horizontal';
7
+
8
+ export type SpacingProps = Omit<HTMLAttributes<HTMLDivElement>, 'children'> & {
9
+ direction?: AxisDirection;
10
+ size: CSSPixelValue;
11
+ };
12
+
13
+ export const Spacing = memo(function Spacing(props: SpacingProps) {
14
+ const { direction = 'horizontal', size, ...restProps } = props;
15
+
16
+ return (
17
+ <SpacingContainer $direction={direction} $size={size} {...restProps} />
18
+ );
19
+ });
20
+
21
+ const SpacingContainer = styled.div<{
22
+ $direction: SpacingProps['direction'];
23
+ $size: SpacingProps['size'];
24
+ }>`
25
+ flex: none;
26
+ width: ${({ $direction, $size }) =>
27
+ $direction === 'horizontal' ? coerceCssPixelValue($size) : undefined};
28
+ height: ${({ $direction, $size }) =>
29
+ $direction === 'vertical' ? coerceCssPixelValue($size) : undefined};
30
+ `;
@@ -0,0 +1,25 @@
1
+ /**
2
+ *
3
+ * @see 이메일 주소가 RFC 5322 표준을 따르는지 검사합니다. {@link https://emailregex.com/}
4
+ */
5
+ function isEmail(email: string) {
6
+ const regExp =
7
+ /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
8
+ return regExp.test(email);
9
+ }
10
+
11
+ function isPhoneNumber(phoneNumber: string) {
12
+ // 하이픈 있는 형식
13
+ const regExpWithHyphen = /^01([0|1|6|7|8|9])-([0-9]{3,4})-([0-9]{4})$/;
14
+ // 하이픈 없는 형식
15
+ const regExpWithoutHyphen = /^01([0|1|6|7|8|9])([0-9]{3,4})([0-9]{4})$/;
16
+
17
+ return (
18
+ regExpWithHyphen.test(phoneNumber) || regExpWithoutHyphen.test(phoneNumber)
19
+ );
20
+ }
21
+
22
+ export const Validate = {
23
+ email: isEmail,
24
+ phoneNumber: isPhoneNumber,
25
+ };
@@ -0,0 +1,5 @@
1
+ export type CSSPixelValue = string | number;
2
+
3
+ export function coerceCssPixelValue(value: CSSPixelValue): string {
4
+ return typeof value === 'string' ? value : `${value}px`;
5
+ }