react-validate-component 0.1.1 → 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.
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare function vColor(): React.JSX.Element;
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare function vDate(): React.JSX.Element;
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare function vEmail(): React.JSX.Element;
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare function vRadio(): React.JSX.Element;
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare function vRange(): React.JSX.Element;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ import { VTEXT_PARAMS } from './vText';
3
+ export declare function VText({ vState, vType, vClassName, vShowMessage, vMessage, vLocateMessage, vMessageClass, vIsAnimate, props, }: VTEXT_PARAMS): React.JSX.Element;
@@ -1,10 +1,11 @@
1
- import propsType from './vprops';
1
+ import propsType from '../types/vprops';
2
2
  export interface VTEXT_PARAMS {
3
3
  readonly vState: boolean;
4
+ readonly vType: // 유효성 메시지를 출력할 타입
5
+ 'inner' | 'outer' | 'tooltip';
4
6
  vClassName?: string;
5
7
  readonly vShowMessage: boolean;
6
8
  vMessage?: string;
7
- vIsInnerMessage?: boolean;
8
9
  vLocateMessage?: 'top-left' | 'top' | 'top-right' | 'center-left' | 'center' | 'center-right' | 'bottom-left' | 'bottom' | 'bottom-right';
9
10
  vMessageClass?: string;
10
11
  vIsAnimate?: boolean;
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare function vURL(): React.JSX.Element;
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.1.1",
2
+ "version": "0.1.2",
3
3
  "license": "MIT",
4
4
  "main": "dist/index.js",
5
5
  "typings": "dist/index.d.ts",
@@ -13,7 +13,7 @@
13
13
  "scripts": {
14
14
  "start": "tsdx watch",
15
15
  "build": "tsdx build",
16
- "test": "tsdx test --passWithNoTests",
16
+ "test": "jest",
17
17
  "lint": "tsdx lint",
18
18
  "prepare": "tsdx build",
19
19
  "size": "size-limit",
@@ -27,6 +27,9 @@
27
27
  "pre-commit": "tsdx lint"
28
28
  }
29
29
  },
30
+ "jest": {
31
+ "testEnvironment": "jsdom"
32
+ },
30
33
  "prettier": {
31
34
  "printWidth": 80,
32
35
  "semi": true,
@@ -51,6 +54,8 @@
51
54
  "@types/react": "^18.3.3",
52
55
  "@types/react-dom": "^18.3.0",
53
56
  "husky": "^9.1.4",
57
+ "jest": "^29.7.0",
58
+ "jest-environment-jsdom": "^29.7.0",
54
59
  "react": "^18.3.1",
55
60
  "react-dom": "^18.3.1",
56
61
  "size-limit": "^11.1.4",
@@ -59,10 +64,18 @@
59
64
  "typescript": "^3.9.10"
60
65
  },
61
66
  "dependencies": {
67
+ "@babel/cli": "^7.24.8",
62
68
  "@babel/core": "^7.25.2",
69
+ "@babel/plugin-transform-arrow-functions": "^7.24.7",
63
70
  "@babel/plugin-transform-runtime": "^7.24.7",
71
+ "@babel/plugin-transform-template-literals": "^7.24.7",
64
72
  "@babel/preset-env": "^7.25.3",
73
+ "@babel/preset-react": "^7.24.7",
65
74
  "babel-jest": "^29.7.0",
66
- "rollup-plugin-postcss": "^4.0.2"
75
+ "babel-loader": "^9.1.3",
76
+ "rollup-plugin-postcss": "^4.0.2",
77
+ "webpack": "^5.93.0",
78
+ "webpack-cli": "^5.1.4",
79
+ "webpack-dev-server": "^5.0.4"
67
80
  }
68
81
  }
package/src/index.ts ADDED
@@ -0,0 +1,10 @@
1
+ import { VText } from './vText';
2
+ import { VCheckbox } from './vCheckbox';
3
+ import { vColor } from './vColor';
4
+ import { vDate } from './vDate';
5
+ import { vEmail } from './vEmail';
6
+ import { vRadio } from './vRadio';
7
+ import { vRange } from './vRange';
8
+ import { vURL } from './vURL';
9
+
10
+ export { VText, VCheckbox, vColor, vDate, vEmail, vRadio, vRange, vURL };
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+
3
+ export function VCheckbox() {
4
+ return <input type="checkbox" />;
5
+ }
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+
3
+ export function vColor() {
4
+ return <input type="color" />;
5
+ }
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+
3
+ export function vDate() {
4
+ return <input type="date" />;
5
+ }
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+
3
+ export function vEmail() {
4
+ return <input type="email" />;
5
+ }
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+
3
+ export function vRadio() {
4
+ return <input type="radio" />;
5
+ }
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+
3
+ export function vRange() {
4
+ return <input type="range" />;
5
+ }
@@ -0,0 +1,210 @@
1
+ .invalid {
2
+ border: 2px solid red;
3
+ outline: none;
4
+ }
5
+ .invalid:focus,
6
+ .invalid:focus-visible,
7
+ .invalid:focus-within {
8
+ border: 2px solid red;
9
+ }
10
+
11
+ /* vType === 'outer' */
12
+ .vinput {
13
+ display: flex;
14
+ }
15
+ .vinput-top-left {
16
+ flex-direction: column-reverse;
17
+ align-items: flex-start;
18
+ justify-content: center;
19
+ }
20
+ .vinput-top {
21
+ flex-direction: column-reverse;
22
+ align-items: center;
23
+ justify-content: center;
24
+ }
25
+ .vinput-top-right {
26
+ flex-direction: column-reverse;
27
+ align-items: flex-end;
28
+ justify-content: center;
29
+ }
30
+ .vinput-center-left {
31
+ flex-direction: row-reverse;
32
+ align-items: center;
33
+ justify-content: center;
34
+ }
35
+ .vinput-center-right {
36
+ align-items: center;
37
+ justify-content: center;
38
+ }
39
+ .vinput-bottom-left {
40
+ flex-direction: column;
41
+ align-items: flex-start;
42
+ justify-content: center;
43
+ }
44
+ .vinput-bottom {
45
+ flex-direction: column;
46
+ align-items: center;
47
+ justify-content: center;
48
+ }
49
+ .vinput-bottom-right {
50
+ flex-direction: column;
51
+ align-items: flex-end;
52
+ justify-content: center;
53
+ }
54
+
55
+ /* vType === 'inner' */
56
+ .innerMessage {
57
+ position: absolute;
58
+ font-size: 12px;
59
+ margin: 0;
60
+ padding: 2px 5px;
61
+ display: flex;
62
+ }
63
+ .innerMessage-top-left {
64
+ align-items: flex-start;
65
+ justify-content: flex-start;
66
+ }
67
+ .innerMessage-top {
68
+ align-items: flex-start;
69
+ justify-content: center;
70
+ }
71
+ .innerMessage-top-right {
72
+ align-items: flex-start;
73
+ justify-content: flex-end;
74
+ }
75
+ .innerMessage-center-left {
76
+ align-items: center;
77
+ justify-content: flex-start;
78
+ }
79
+ .innerMessage-center {
80
+ align-items: center;
81
+ justify-content: center;
82
+ }
83
+ .innerMessage-center-right {
84
+ align-items: center;
85
+ justify-content: flex-end;
86
+ }
87
+ .innerMessage-bottom-left {
88
+ align-items: flex-end;
89
+ justify-content: flex-start;
90
+ }
91
+ .innerMessage-bottom {
92
+ align-items: flex-end;
93
+ justify-content: center;
94
+ }
95
+ .innerMessage-bottom-right {
96
+ align-items: flex-end;
97
+ justify-content: flex-end;
98
+ }
99
+
100
+ /* vType === 'tooltip' */
101
+ .tooltipMessage {
102
+ position: absolute;
103
+ margin: 0;
104
+ padding: 10px 20px;
105
+ border: 1px solid transparent;
106
+ border-radius: 10px;
107
+ background-color: black;
108
+ }
109
+ p[class*='tooltipMessage-top'] {
110
+ transform: translateY(calc(-100% - 10px));
111
+ }
112
+ p[class*='tooltipMessage-top']::after {
113
+ content: '';
114
+ position: absolute;
115
+ bottom: 0;
116
+ border: 10px solid transparent;
117
+ border-top-color: black;
118
+ border-bottom: 0;
119
+ margin-bottom: -11px;
120
+ }
121
+ .vinput.tooltipMessage-top-left {
122
+ justify-content: flex-start;
123
+ }
124
+ p.tooltipMessage-top-left::after {
125
+ left: 3%;
126
+ }
127
+ .vinput.tooltipMessage-top {
128
+ justify-content: center;
129
+ }
130
+ p.tooltipMessage-top::after {
131
+ left: 44%;
132
+ }
133
+ .tooltipMessage-top-right {
134
+ justify-content: flex-end;
135
+ }
136
+ p.tooltipMessage-top-right::after {
137
+ left: 87%;
138
+ }
139
+ p[class*='tooltipMessage-center'] {
140
+ /* transform: translateY(calc(-100% - 10px)); */
141
+ }
142
+ p[class*='tooltipMessage-center']::after {
143
+ content: '';
144
+ position: absolute;
145
+ border: 10px solid transparent;
146
+ }
147
+ .vinput.tooltipMessage-center-right {
148
+ justify-content: flex-end;
149
+ }
150
+ p.tooltipMessage-center-right {
151
+ transform: translateX(calc(100% + 10px));
152
+ }
153
+ p.tooltipMessage-center-right::after {
154
+ border-right-color: black;
155
+ left: -10%;
156
+ }
157
+ .vinput.tooltipMessage-center-left {
158
+ justify-content: flex-start;
159
+ }
160
+ p.tooltipMessage-center-left {
161
+ transform: translateX(calc(-100% - 10px));
162
+ }
163
+ p.tooltipMessage-center-left::after {
164
+ border-left-color: black;
165
+ left: 100%;
166
+ }
167
+
168
+ p[class*='tooltipMessage-bottom'] {
169
+ transform: translateY(calc(120% + 10px));
170
+ }
171
+ p[class*='tooltipMessage-bottom']::after {
172
+ content: '';
173
+ position: absolute;
174
+ top: 0;
175
+ border: 10px solid transparent;
176
+ border-bottom-color: black;
177
+ border-top: 0;
178
+ margin-top: -11px;
179
+ }
180
+ .vinput.tooltipMessage-bottom-left {
181
+ justify-content: flex-start;
182
+ }
183
+ p.tooltipMessage-bottom-left::after {
184
+ left: 3%;
185
+ }
186
+ .vinput.tooltipMessage-bottom {
187
+ justify-content: center;
188
+ }
189
+ p.tooltipMessage-bottom::after {
190
+ left: 44%;
191
+ }
192
+ .tooltipMessage-bottom-right {
193
+ justify-content: flex-end;
194
+ }
195
+ p.tooltipMessage-bottom-right::after {
196
+ left: 87%;
197
+ }
198
+
199
+ .animateMessage {
200
+ animation: fade-in 1s ease-in-out;
201
+ }
202
+
203
+ @keyframes fade-in {
204
+ 0% {
205
+ opacity: 0;
206
+ }
207
+ 100% {
208
+ opacity: 1;
209
+ }
210
+ }
@@ -0,0 +1,93 @@
1
+ import React from 'react';
2
+ import styles from './index.module.css';
3
+ import { VTEXT_PARAMS } from './vText';
4
+
5
+ // Text
6
+ export function VText({
7
+ vState = false,
8
+ vType = 'outer',
9
+ vClassName = '',
10
+ vShowMessage = false,
11
+ vMessage = '',
12
+ vLocateMessage = 'bottom',
13
+ vMessageClass = '',
14
+ vIsAnimate = false,
15
+ props = {},
16
+ }: VTEXT_PARAMS) {
17
+ switch (vType) {
18
+ case 'outer':
19
+ return (
20
+ <div
21
+ className={`${styles.vinput} ${styles[`vinput-${vLocateMessage}`]}`}
22
+ >
23
+ <input
24
+ type="text"
25
+ {...props}
26
+ defaultValue={props?.defaultValue ?? ''}
27
+ className={`${props?.className} ${
28
+ vState ? vClassName || styles.invalid : ''
29
+ }`}
30
+ ></input>
31
+ {vState && vShowMessage ? (
32
+ <p
33
+ className={`${vMessageClass} ${
34
+ vIsAnimate ? styles.animateMessage : ''
35
+ }`}
36
+ >
37
+ {vMessage}
38
+ </p>
39
+ ) : null}
40
+ </div>
41
+ );
42
+ case 'inner':
43
+ return (
44
+ <div className={styles.vinput}>
45
+ <input
46
+ type="text"
47
+ {...props}
48
+ defaultValue={props?.defaultValue ?? ''}
49
+ className={`${props?.className} ${
50
+ vState ? vClassName || styles.invalid : ''
51
+ }`}
52
+ ></input>
53
+ {vState && vShowMessage ? (
54
+ <p
55
+ className={`${vMessageClass} ${styles.innerMessage} ${
56
+ styles[`innerMessage-${vLocateMessage}`]
57
+ } ${vIsAnimate ? styles.animateMessage : ''}`}
58
+ >
59
+ {vMessage}
60
+ </p>
61
+ ) : null}
62
+ </div>
63
+ );
64
+ case 'tooltip':
65
+ return (
66
+ <div
67
+ className={`${styles.vinput} ${
68
+ styles[`tooltipMessage-${vLocateMessage}`]
69
+ }`}
70
+ >
71
+ <input
72
+ type="text"
73
+ {...props}
74
+ defaultValue={props?.defaultValue ?? ''}
75
+ className={`${props?.className} ${
76
+ vState ? vClassName || styles.invalid : ''
77
+ }`}
78
+ ></input>
79
+ {vState && vShowMessage ? (
80
+ <p
81
+ className={`${vMessageClass} ${styles.tooltipMessage} ${
82
+ styles[`tooltipMessage-${vLocateMessage}`]
83
+ } ${vIsAnimate ? styles.animateMessage : ''}`}
84
+ >
85
+ {vMessage}
86
+ </p>
87
+ ) : null}
88
+ </div>
89
+ );
90
+ default:
91
+ return <div></div>;
92
+ }
93
+ }
@@ -1,12 +1,13 @@
1
- import propsType from './vprops';
1
+ import propsType from '../types/vprops';
2
2
 
3
3
  // VText 파라미터
4
4
  export interface VTEXT_PARAMS {
5
5
  readonly vState: boolean; // 유효성 상태 값
6
+ readonly vType: // 유효성 메시지를 출력할 타입
7
+ 'inner' | 'outer' | 'tooltip';
6
8
  vClassName?: string; // 유효성 입힐 class 명
7
9
  readonly vShowMessage: boolean; // 유효성 메시지 출력할지
8
10
  vMessage?: string; // 유효성 메시지
9
- vIsInnerMessage?: boolean; // 유효성 메시지를 element 안에 넣을지 (absolute)
10
11
  vLocateMessage?: // 유효성 메시지를 element 어디에 붙일지
11
12
  | 'top-left'
12
13
  | 'top'
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+
3
+ export function vURL() {
4
+ return <input type="url" />;
5
+ }
@@ -1,103 +0,0 @@
1
- .invalid {
2
- border: 2px solid red;
3
- }
4
-
5
- /* 유효성 메시지 locate */
6
- .vinput {
7
- display: flex;
8
- }
9
- .vinput-top-left {
10
- flex-direction: column-reverse;
11
- align-items: flex-start;
12
- justify-content: center;
13
- }
14
- .vinput-top {
15
- flex-direction: column-reverse;
16
- align-items: center;
17
- justify-content: center;
18
- }
19
- .vinput-top-right {
20
- flex-direction: column-reverse;
21
- align-items: flex-end;
22
- justify-content: center;
23
- }
24
- .vinput-center-left {
25
- flex-direction: row-reverse;
26
- align-items: center;
27
- justify-content: center;
28
- }
29
- .vinput-center-right {
30
- align-items: center;
31
- justify-content: center;
32
- }
33
- .vinput-bottom-left {
34
- flex-direction: column;
35
- align-items: flex-start;
36
- justify-content: center;
37
- }
38
- .vinput-bottom {
39
- flex-direction: column;
40
- align-items: center;
41
- justify-content: center;
42
- }
43
- .vinput-bottom-right {
44
- flex-direction: column;
45
- align-items: flex-end;
46
- justify-content: center;
47
- }
48
- .innerMessage {
49
- position: absolute;
50
- font-size: 12px;
51
- margin: 0;
52
- padding: 2px 5px;
53
- display: flex;
54
- }
55
- .innerMessage-top-left {
56
- align-items: flex-start;
57
- justify-content: flex-start;
58
- }
59
- .innerMessage-top {
60
- align-items: flex-start;
61
- justify-content: center;
62
- }
63
- .innerMessage-top-right {
64
- align-items: flex-start;
65
- justify-content: flex-end;
66
- }
67
- .innerMessage-center-left {
68
- align-items: center;
69
- justify-content: flex-start;
70
- }
71
- .innerMessage-center {
72
- align-items: center;
73
- justify-content: center;
74
- }
75
- .innerMessage-center-right {
76
- align-items: center;
77
- justify-content: flex-end;
78
- }
79
- .innerMessage-bottom-left {
80
- align-items: flex-end;
81
- justify-content: flex-start;
82
- }
83
- .innerMessage-bottom {
84
- align-items: flex-end;
85
- justify-content: center;
86
- }
87
- .innerMessage-bottom-right {
88
- align-items: flex-end;
89
- justify-content: flex-end;
90
- }
91
-
92
- .animateMessage {
93
- animation: fade-in 1s ease-in-out;
94
- }
95
-
96
- @keyframes fade-in {
97
- 0% {
98
- opacity: 0;
99
- }
100
- 100% {
101
- opacity: 1;
102
- }
103
- }
package/src/index.tsx DELETED
@@ -1,79 +0,0 @@
1
- import React from 'react';
2
- import styles from './index.module.css';
3
- import { VTEXT_PARAMS } from './types/vinput';
4
-
5
- // Text
6
- export const VText = ({
7
- vState = false,
8
- vClassName = '',
9
- vShowMessage = false,
10
- vMessage = '',
11
- vIsInnerMessage = false,
12
- vLocateMessage = 'bottom',
13
- vMessageClass = '',
14
- vIsAnimate = false,
15
- props = {},
16
- }: VTEXT_PARAMS) => {
17
- const Result: JSX.Element = (
18
- <div className={`${styles.vinput} ${styles[`vinput-${vLocateMessage}`]}`}>
19
- <input
20
- type="text"
21
- {...props}
22
- defaultValue={props?.defaultValue ?? ''}
23
- className={`${props?.className} ${
24
- vState ? vClassName || styles.invalid : ''
25
- }`}
26
- ></input>
27
- {vState && vShowMessage ? (
28
- <p
29
- className={`${vMessageClass} ${
30
- vIsInnerMessage
31
- ? `${props?.className} ${styles.innerMessage} ${
32
- styles[`innerMessage-${vLocateMessage}`]
33
- }`
34
- : ''
35
- } ${vIsAnimate ? styles.animateMessage : ''}`}
36
- >
37
- {vMessage}
38
- </p>
39
- ) : null}
40
- </div>
41
- );
42
-
43
- return Result;
44
- };
45
-
46
- // Checkbox
47
- export const VCheckbox = () => {
48
- return <input type="checkbox" />;
49
- };
50
-
51
- // Radio
52
- export const VRadio = () => {
53
- return <input type="radio" />;
54
- };
55
-
56
- // Date
57
- export const VDate = () => {
58
- return <input type="date" />;
59
- };
60
-
61
- // Color
62
- export const VColor = () => {
63
- return <input type="color" />;
64
- };
65
-
66
- // Email
67
- export const VEmail = () => {
68
- return <input type="email" />;
69
- };
70
-
71
- // Range
72
- export const VRange = () => {
73
- return <input type="range" />;
74
- };
75
-
76
- // Url
77
- export const VUrl = () => {
78
- return <input type="url" />;
79
- };