podo-ui 0.1.29

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 (138) hide show
  1. package/.next/app-build-manifest.json +16 -0
  2. package/.next/build-manifest.json +19 -0
  3. package/.next/cache/.tsbuildinfo +1 -0
  4. package/.next/cache/config.json +7 -0
  5. package/.next/cache/webpack/client-development/0.pack.gz +0 -0
  6. package/.next/cache/webpack/client-development/1.pack.gz +0 -0
  7. package/.next/cache/webpack/client-development/index.pack.gz +0 -0
  8. package/.next/cache/webpack/client-development/index.pack.gz.old +0 -0
  9. package/.next/cache/webpack/client-production/0.pack +0 -0
  10. package/.next/cache/webpack/client-production/1.pack +0 -0
  11. package/.next/cache/webpack/client-production/2.pack +0 -0
  12. package/.next/cache/webpack/client-production/index.pack +0 -0
  13. package/.next/cache/webpack/client-production/index.pack.old +0 -0
  14. package/.next/cache/webpack/edge-server-development/0.pack.gz +0 -0
  15. package/.next/cache/webpack/edge-server-development/index.pack.gz +0 -0
  16. package/.next/cache/webpack/server-development/0.pack.gz +0 -0
  17. package/.next/cache/webpack/server-development/index.pack.gz +0 -0
  18. package/.next/cache/webpack/server-production/0.pack +0 -0
  19. package/.next/cache/webpack/server-production/1.pack +0 -0
  20. package/.next/cache/webpack/server-production/2.pack +0 -0
  21. package/.next/cache/webpack/server-production/index.pack +0 -0
  22. package/.next/cache/webpack/server-production/index.pack.old +0 -0
  23. package/.next/package.json +1 -0
  24. package/.next/react-loadable-manifest.json +1 -0
  25. package/.next/server/app/page.js +5057 -0
  26. package/.next/server/app/page_client-reference-manifest.js +1 -0
  27. package/.next/server/app-paths-manifest.json +3 -0
  28. package/.next/server/edge-runtime-webpack.js +1171 -0
  29. package/.next/server/middleware-build-manifest.js +1 -0
  30. package/.next/server/middleware-manifest.json +28 -0
  31. package/.next/server/middleware-react-loadable-manifest.js +1 -0
  32. package/.next/server/next-font-manifest.js +1 -0
  33. package/.next/server/next-font-manifest.json +1 -0
  34. package/.next/server/pages-manifest.json +1 -0
  35. package/.next/server/server-reference-manifest.js +1 -0
  36. package/.next/server/server-reference-manifest.json +5 -0
  37. package/.next/server/static/webpack/633457081244afec._.hot-update.json +1 -0
  38. package/.next/static/chunks/_app-pages-browser_react_atom_editor_tsx.js +692 -0
  39. package/.next/static/chunks/app/layout.js +72 -0
  40. package/.next/static/chunks/app/page.js +233 -0
  41. package/.next/static/chunks/app-pages-internals.js +127 -0
  42. package/.next/static/chunks/main-app.js +1875 -0
  43. package/.next/static/chunks/polyfills.js +1 -0
  44. package/.next/static/chunks/webpack.js +1427 -0
  45. package/.next/static/css/_app-pages-browser_react_atom_editor_tsx.css +124 -0
  46. package/.next/static/css/app/layout.css +20357 -0
  47. package/.next/static/css/app/page.css +4282 -0
  48. package/.next/static/development/_buildManifest.js +1 -0
  49. package/.next/static/development/_ssgManifest.js +1 -0
  50. package/.next/static/media/Pretendard-Black.4aeaaf12.woff2 +0 -0
  51. package/.next/static/media/Pretendard-Bold.e00e15f4.woff2 +0 -0
  52. package/.next/static/media/Pretendard-ExtraBold.dd3e76c5.woff2 +0 -0
  53. package/.next/static/media/Pretendard-ExtraLight.b6885b7a.woff2 +0 -0
  54. package/.next/static/media/Pretendard-Light.e725ed3d.woff2 +0 -0
  55. package/.next/static/media/Pretendard-Medium.12f0acdc.woff2 +0 -0
  56. package/.next/static/media/Pretendard-Regular.119cf01b.woff2 +0 -0
  57. package/.next/static/media/Pretendard-SemiBold.cfa29e4f.woff2 +0 -0
  58. package/.next/static/media/Pretendard-Thin.fc2b22d5.woff2 +0 -0
  59. package/.next/static/media/icon.e529ac0f.woff +0 -0
  60. package/.next/static/webpack/633457081244afec._.hot-update.json +1 -0
  61. package/.next/trace +28 -0
  62. package/.next/types/app/layout.ts +79 -0
  63. package/.next/types/app/page.ts +79 -0
  64. package/.next/types/package.json +1 -0
  65. package/.prettierignore +9 -0
  66. package/.prettierrc +8 -0
  67. package/SECURITY.md +21 -0
  68. package/cli/icon-scss.js +56 -0
  69. package/eslint.config.js +26 -0
  70. package/global.scss +58 -0
  71. package/index.html +12 -0
  72. package/mixin.scss +27 -0
  73. package/next-env.d.ts +5 -0
  74. package/next.config.mjs +10 -0
  75. package/next.ts +20 -0
  76. package/package.json +52 -0
  77. package/react/atom/editor-view.tsx +12 -0
  78. package/react/atom/editor.module.scss +134 -0
  79. package/react/atom/editor.tsx +171 -0
  80. package/react/atom/input.module.scss +42 -0
  81. package/react/atom/input.tsx +67 -0
  82. package/react/atom/textarea.module.scss +17 -0
  83. package/react/atom/textarea.tsx +51 -0
  84. package/react/molecule/field.module.scss +22 -0
  85. package/react/molecule/field.tsx +78 -0
  86. package/react.ts +16 -0
  87. package/readme.md +199 -0
  88. package/scss/button/class.scss +190 -0
  89. package/scss/button/layout.scss +37 -0
  90. package/scss/color/class.scss +50 -0
  91. package/scss/color/function.scss +3 -0
  92. package/scss/color/theme.scss +177 -0
  93. package/scss/form/checkbox-radio.scss +148 -0
  94. package/scss/form/file.scss +67 -0
  95. package/scss/form/input.scss +189 -0
  96. package/scss/form/label.scss +25 -0
  97. package/scss/form/select.scss +57 -0
  98. package/scss/form/textarea.scss +52 -0
  99. package/scss/form/toggle.scss +67 -0
  100. package/scss/icon/font/icon.woff +0 -0
  101. package/scss/icon/function.scss +5 -0
  102. package/scss/icon/icon-name.scss +118 -0
  103. package/scss/icon/icon.scss +38 -0
  104. package/scss/layout/bg-elevation.scss +52 -0
  105. package/scss/layout/border.scss +20 -0
  106. package/scss/layout/device.scss +28 -0
  107. package/scss/layout/grid.scss +69 -0
  108. package/scss/layout/hide.scss +23 -0
  109. package/scss/layout/radius.scss +23 -0
  110. package/scss/layout/spacing.scss +56 -0
  111. package/scss/molecule/pagination.scss +0 -0
  112. package/scss/molecule/tab.scss +46 -0
  113. package/scss/molecule/table.scss +54 -0
  114. package/scss/reset.scss +55 -0
  115. package/scss/typo/font/Pretendard-Black.woff2 +0 -0
  116. package/scss/typo/font/Pretendard-Bold.woff2 +0 -0
  117. package/scss/typo/font/Pretendard-ExtraBold.woff2 +0 -0
  118. package/scss/typo/font/Pretendard-ExtraLight.woff2 +0 -0
  119. package/scss/typo/font/Pretendard-Light.woff2 +0 -0
  120. package/scss/typo/font/Pretendard-Medium.woff2 +0 -0
  121. package/scss/typo/font/Pretendard-Regular.woff2 +0 -0
  122. package/scss/typo/font/Pretendard-SemiBold.woff2 +0 -0
  123. package/scss/typo/font/Pretendard-Thin.woff2 +0 -0
  124. package/scss/typo/font-family.scss +80 -0
  125. package/scss/typo/font-size.scss +30 -0
  126. package/scss/typo/mixin.scss +173 -0
  127. package/scss/typo/typo.scss +102 -0
  128. package/scss/typo/util.scss +0 -0
  129. package/src/app/layout.tsx +18 -0
  130. package/src/app/page.module.scss +71 -0
  131. package/src/app/page.tsx +2712 -0
  132. package/src/styles/custom.scss +11 -0
  133. package/src/styles/font-family.scss +80 -0
  134. package/src/styles/icon.scss +5 -0
  135. package/src/vite-env.d.ts +1 -0
  136. package/system.scss +0 -0
  137. package/tsconfig.json +26 -0
  138. package/wrangler.toml +4 -0
@@ -0,0 +1,171 @@
1
+ import { useEffect, useRef, useState } from 'react';
2
+ import { v4 as uuid } from 'uuid';
3
+ import suneditor from 'suneditor';
4
+ import 'suneditor/dist/css/suneditor.min.css';
5
+ import styles from './editor.module.scss';
6
+ import lang from 'suneditor/src/lang';
7
+ import {
8
+ blockquote,
9
+ align,
10
+ font,
11
+ fontSize,
12
+ fontColor,
13
+ hiliteColor,
14
+ horizontalRule,
15
+ list,
16
+ formatBlock,
17
+ lineHeight,
18
+ template,
19
+ paragraphStyle,
20
+ textStyle,
21
+ link,
22
+ image,
23
+ video,
24
+ table,
25
+ } from 'suneditor/src/plugins';
26
+ import { z } from 'zod';
27
+
28
+ interface Props {
29
+ value: string;
30
+ width?: string;
31
+ height?: string;
32
+ onChange: (content: string) => void;
33
+ imageUploadUrl?: string;
34
+ imageUploadHeader?: Record<string, string>;
35
+ validator?: z.ZodType<unknown>;
36
+ }
37
+
38
+ const SunEditor = ({
39
+ value = '',
40
+ width = '100%',
41
+ height = '600px',
42
+ onChange,
43
+ imageUploadUrl,
44
+ imageUploadHeader,
45
+ validator,
46
+ }: Props) => {
47
+ const [message, setMessage] = useState('');
48
+ const [statusClass, setStatusClass] = useState('');
49
+ const editorRef = useRef<HTMLTextAreaElement>(null);
50
+ const editorID = `f${uuid()}`;
51
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
52
+ const ref = useRef<any>();
53
+
54
+ const validateHandler = (content: string) => {
55
+ setMessage('');
56
+ setStatusClass('');
57
+ if (validator && content.length > 0) {
58
+ try {
59
+ validator.parse(content);
60
+ setStatusClass('success');
61
+ } catch (e) {
62
+ if (e instanceof z.ZodError) {
63
+ setMessage(e.errors[0].message);
64
+ setStatusClass('danger');
65
+ }
66
+ }
67
+ }
68
+ };
69
+ const toolbar = [
70
+ ['undo', 'redo'],
71
+ ['formatBlock', 'bold', 'underline', 'italic', 'strike'],
72
+ ['fontColor', 'hiliteColor'],
73
+ ['align', 'list', 'table'],
74
+ ['link', 'image', 'video'],
75
+ ['fullScreen', 'codeView'],
76
+ ];
77
+ const editorOptions = {
78
+ lang: lang.ko,
79
+ plugins: {
80
+ blockquote,
81
+ align,
82
+ font,
83
+ fontSize,
84
+ fontColor,
85
+ hiliteColor,
86
+ horizontalRule,
87
+ list,
88
+ table,
89
+ formatBlock,
90
+ lineHeight,
91
+ template,
92
+ paragraphStyle,
93
+ textStyle,
94
+ link,
95
+ image,
96
+ video,
97
+ },
98
+ width: width,
99
+ height: height,
100
+ buttonList: toolbar,
101
+ formats: [
102
+ 'h1',
103
+ 'h2',
104
+ 'h3',
105
+ {
106
+ tag: 'p',
107
+ name: '๋ณธ๋ฌธ',
108
+ command: 'replace',
109
+ class: '',
110
+ },
111
+ {
112
+ tag: 'div',
113
+ name: '์ธ์šฉ๊ตฌ',
114
+ command: 'range',
115
+ class: '__se__format__range__quote',
116
+ },
117
+ ],
118
+ resizingBar: false,
119
+ imageUploadUrl,
120
+ imageUploadHeader,
121
+ icons: {
122
+ undo: '<i class="editor undo">์‹คํ–‰์ทจ์†Œ</i>',
123
+ redo: '<i class="editor redo">๋‹ค์‹œ์‹คํ–‰</i>',
124
+ bold: '<i class="editor bold">๊ตต๊ฒŒ</i>',
125
+ underline: '<i class="editor underline">๋ฐ‘์ค„</i>',
126
+ italic: '<i class="editor italic">๊ธฐ์šธ์ด๊ธฐ</i>',
127
+ strike: '<i class="editor strike">๊ฐ€์šด๋ฐ์„ </i>',
128
+ font_color: '<i class="editor font">๊ธ€์ž์ƒ‰</i>',
129
+ highlight_color: '<i class="editor highlighter">๋ฐฐ๊ฒฝ์ƒ‰</i>',
130
+ align_left: '<i class="editor align-left">์™ผ์ชฝ ์ •๋ ฌ</i>',
131
+ align_center: '<i class="editor align-center">๊ฐ€์šด๋ฐ ์ •๋ ฌ</i>',
132
+ align_right: '<i class="editor align-right">์šฐ์ธก ์ •๋ ฌ</i>',
133
+ align_justify: '<i class="editor align-justify">์–‘์ชฝ ์ •๋ ฌ</i>',
134
+
135
+ list_bullets: '<i class="editor list-ul">๋ชฉ๋ก</i>',
136
+ list_number: '<i class="editor list-ol">์ˆซ์ž ๋ชฉ๋ก</i>',
137
+ table: '<i class="editor table">ํ…Œ์ด๋ธ”</i>',
138
+ link: '<i class="editor link">๋งํฌ</i>',
139
+ image: '<i class="editor image">์‚ฌ์ง„</i>',
140
+ video: '<i class="editor video">๋น„๋””์˜ค</i>',
141
+ expansion: '<i class="editor expand">ํ™•์žฅ</i>',
142
+ code_view: '<i class="editor code">์ฝ”๋“œ</i>',
143
+ },
144
+ };
145
+
146
+ useEffect(() => {
147
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
148
+ ref.current = suneditor.create(editorID, editorOptions as any);
149
+
150
+ ref.current.onChange = function (content: string) {
151
+ onChange(content);
152
+ validateHandler(content);
153
+ };
154
+
155
+ return () => {
156
+ ref.current.destroy();
157
+ };
158
+ // eslint-disable-next-line react-hooks/exhaustive-deps
159
+ }, []);
160
+
161
+ return (
162
+ <div className={`${styles.editor} ${statusClass}`}>
163
+ <textarea ref={editorRef} id={editorID} defaultValue={value} />
164
+ {validator && message && (
165
+ <div className={styles.validator}>{message}</div>
166
+ )}
167
+ </div>
168
+ );
169
+ };
170
+
171
+ export default SunEditor;
@@ -0,0 +1,42 @@
1
+ @use '../../mixin.scss' as *;
2
+ .style {
3
+ display: flex;
4
+ flex-direction: column;
5
+ gap: s(3);
6
+ &:global {
7
+ > input {
8
+ width: 300px;
9
+ }
10
+ > div.validator {
11
+ @include p4;
12
+ & {
13
+ color: color('text-sub');
14
+ }
15
+ }
16
+ > div{
17
+ position: relative;
18
+ width: fit-content;
19
+ > span.unit {
20
+ position: absolute;
21
+ right: s(3);
22
+ top: 50%;
23
+ transform: translateY(-50%);
24
+ color: color('text-sub');
25
+ pointer-events: none;
26
+ }
27
+ > input {
28
+ /* Chrome, Safari, Edge, Opera */
29
+ &::-webkit-outer-spin-button,
30
+ &::-webkit-inner-spin-button {
31
+ -webkit-appearance: none;
32
+ margin: 0;
33
+ }
34
+
35
+ /* Firefox */
36
+ &[type='number'] {
37
+ -moz-appearance: textfield;
38
+ }
39
+ }
40
+ }
41
+ }
42
+ }
@@ -0,0 +1,67 @@
1
+ import { useState, useEffect, useCallback } from 'react';
2
+ import { z } from 'zod';
3
+ import styles from './input.module.scss';
4
+
5
+ interface InputWrapperProps extends React.ComponentProps<'input'> {
6
+ value?: string | number;
7
+ className?: string;
8
+ validator?: z.ZodType<unknown>;
9
+ withIcon?: string;
10
+ withRightIcon?: string;
11
+ unit?: string;
12
+ }
13
+
14
+ const Input: React.FC<InputWrapperProps> = ({
15
+ validator,
16
+ value,
17
+ className,
18
+ withIcon,
19
+ withRightIcon,
20
+ unit,
21
+ ...rest
22
+ }) => {
23
+ const [message, setMessage] = useState('');
24
+ const [statusClass, setStatusClass] = useState('');
25
+
26
+ const validateHandler = useCallback(() => {
27
+ setMessage('');
28
+ setStatusClass('');
29
+ if (validator && value) {
30
+ try {
31
+ validator.parse(value);
32
+ setStatusClass('success');
33
+ } catch (e) {
34
+ if (e instanceof z.ZodError) {
35
+ setMessage(e.errors[0].message);
36
+ setStatusClass('danger');
37
+ }
38
+ }
39
+ }
40
+ }, [validator, value]);
41
+
42
+ useEffect(() => {
43
+ validateHandler();
44
+ }, [validateHandler, value]);
45
+
46
+ return (
47
+ <div className={`${styles.style} ${className || ''}`}>
48
+ <div
49
+ className={`${className || ''} ${withIcon ? 'with-icon' : ''} ${withRightIcon ? 'with-right-icon' : ''}`}
50
+ >
51
+ {withIcon && <i className={withIcon} />}
52
+ <input
53
+ {...rest}
54
+ value={value ?? ''}
55
+ className={`${statusClass} ${className || ''}`}
56
+ />
57
+ {withRightIcon && <i className={withRightIcon} />}
58
+ {unit && <span className="unit">{unit}</span>}
59
+ </div>
60
+ {validator && message !== '' && (
61
+ <div className="validator">{message}</div>
62
+ )}
63
+ </div>
64
+ );
65
+ };
66
+
67
+ export default Input;
@@ -0,0 +1,17 @@
1
+ @use '../../mixin.scss' as *;
2
+ .style {
3
+ display: flex;
4
+ flex-direction: column;
5
+ gap: s(3);
6
+ &:global {
7
+ > textarea {
8
+ width: 100%;
9
+ }
10
+ > div.validator {
11
+ @include p4;
12
+ & {
13
+ color: color('text-sub');
14
+ }
15
+ }
16
+ }
17
+ }
@@ -0,0 +1,51 @@
1
+ import { useState } from 'react';
2
+ import { z } from 'zod';
3
+ import styles from './textarea.module.scss';
4
+
5
+ interface TextareaWrapperProps extends React.ComponentProps<'textarea'> {
6
+ value: string;
7
+ className?: string;
8
+ validator?: z.ZodType<unknown>;
9
+ }
10
+
11
+ const Textarea: React.FC<TextareaWrapperProps> = ({
12
+ validator,
13
+ value,
14
+ className,
15
+ ...rest
16
+ }) => {
17
+ const [message, setMessage] = useState('');
18
+ const [statusClass, setStatusClass] = useState('');
19
+
20
+ const validateHandler = () => {
21
+ setMessage('');
22
+ setStatusClass('');
23
+ if (validator && value.length > 0) {
24
+ try {
25
+ validator.parse(value);
26
+ setStatusClass('success');
27
+ } catch (e) {
28
+ if (e instanceof z.ZodError) {
29
+ setMessage(e.errors[0].message);
30
+ setStatusClass('danger');
31
+ }
32
+ }
33
+ }
34
+ };
35
+
36
+ return (
37
+ <div className={`${styles.style} ${className}`}>
38
+ <textarea
39
+ {...rest}
40
+ value={value}
41
+ className={`${statusClass} ${className}`}
42
+ onKeyUp={validateHandler}
43
+ />
44
+ {validator && message !== '' && (
45
+ <div className="validator">{message}</div>
46
+ )}
47
+ </div>
48
+ );
49
+ };
50
+
51
+ export default Textarea;
@@ -0,0 +1,22 @@
1
+ @use '../../mixin.scss' as *;
2
+ .style {
3
+ width: 100%;
4
+ display: flex;
5
+ flex-direction: column;
6
+ gap: s(3);
7
+ &:global {
8
+ > div.child {
9
+ width: 100%;
10
+ > :not(:last-child) {
11
+ display: inline-block;
12
+ margin-right: s(5);
13
+ }
14
+ }
15
+ > div.helper {
16
+ @include p4;
17
+ & {
18
+ color: color('text-sub');
19
+ }
20
+ }
21
+ }
22
+ }
@@ -0,0 +1,78 @@
1
+ import { z } from 'zod';
2
+ import styles from './field.module.scss';
3
+ import { useCallback, useEffect, useState } from 'react';
4
+
5
+ interface Props {
6
+ label?: string;
7
+ labelClass?: string;
8
+ required?: boolean;
9
+ helper?: string;
10
+ helperClass?: string;
11
+ children?: React.ReactNode;
12
+ validator?: z.ZodType<unknown>;
13
+ value?: string;
14
+ setClassName?: React.Dispatch<React.SetStateAction<string>>;
15
+ className?: string;
16
+ }
17
+
18
+ const Field = ({
19
+ label,
20
+ labelClass,
21
+ required,
22
+ helper,
23
+ helperClass,
24
+ children,
25
+ validator,
26
+ value,
27
+ setClassName,
28
+ className,
29
+ }: Props) => {
30
+ const [message, setMessage] = useState('');
31
+
32
+ const validateHandler = useCallback(() => {
33
+ setMessage('');
34
+ if (setClassName) {
35
+ setClassName('');
36
+ }
37
+ if (validator && value && value.length > 0) {
38
+ try {
39
+ validator.parse(value);
40
+ if (setClassName) {
41
+ setClassName('success');
42
+ }
43
+ } catch (e) {
44
+ if (e instanceof z.ZodError) {
45
+ setMessage(e.errors[0].message);
46
+ if (setClassName) {
47
+ setClassName('danger');
48
+ }
49
+ }
50
+ }
51
+ }
52
+ }, [validator, value, setClassName]);
53
+
54
+ useEffect(() => {
55
+ validateHandler();
56
+ }, [validateHandler]);
57
+
58
+ return (
59
+ <div className={`${styles.style} ${className || ''}`}>
60
+ {label && (
61
+ <label className={labelClass}>
62
+ {label}
63
+
64
+ {required && <span className="required">*</span>}
65
+ </label>
66
+ )}
67
+ <div className="child">{children}</div>
68
+ {helper ||
69
+ (validator && message !== '' && (
70
+ <div className={`helper ${helperClass || ''}`}>
71
+ {message || helper}
72
+ </div>
73
+ ))}
74
+ </div>
75
+ );
76
+ };
77
+
78
+ export default Field;
package/react.ts ADDED
@@ -0,0 +1,16 @@
1
+ import Input from './react/atom/input';
2
+ import Textarea from './react/atom/textarea';
3
+ import Editor from './react/atom/editor';
4
+ import EditorView from './react/atom/editor-view';
5
+ import Field from './react/molecule/field';
6
+ const Form = {
7
+ Input,
8
+ Textarea,
9
+ Editor,
10
+ EditorView,
11
+ Field,
12
+ };
13
+
14
+ export default Form;
15
+
16
+ export { Input, Textarea, Editor, EditorView, Field };
package/readme.md ADDED
@@ -0,0 +1,199 @@
1
+ # Podo-ui
2
+ - SCSS Module ๊ธฐ๋ฐ˜ ๋””์ž์ธ ์‹œ์Šคํ…œ
3
+
4
+
5
+ # SCSS
6
+
7
+ ## ๊ธฐ๋ณธ ์ ์šฉ
8
+
9
+ ```js
10
+ import 'podo-ui/global.scss';
11
+ ```
12
+
13
+ ### SCSS Module ๋‚ด์—์„œ ๋ณ€์ˆ˜, ํ•จ์ˆ˜, ๋ฏน์Šค์ธ ํ™œ์šฉ
14
+
15
+ ๐Ÿ‘‰ ํŒŒ์ผ์˜ ์ตœ์ƒ๋‹จ์— ์•„๋ž˜ ํŒŒ์ผ ์„ ์–ธ
16
+
17
+ ```scss
18
+ @use 'podo-ui/mixin' as *;
19
+ ```
20
+
21
+ ## Variables
22
+
23
+ ### Color Tone
24
+
25
+ ๐Ÿ‘‰ ํšŒ์ƒ‰์˜ ํ†ค์„ ๊ฒฐ์ •ํ•จ. ๊ธฐ๋ณธ๊ฐ’(๋ฏธ์„ค์ •) ๊ณผ warm์œผ๋กœ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Œ.
26
+ ๐Ÿ‘‰ js์—์„œ ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •(warm)
27
+
28
+ ```js
29
+ // ๊ธฐ๋ณธ๊ฐ’
30
+ document.documentElement.setAttribute('data-color-tone', '');
31
+
32
+ // warm ํ†ค
33
+ document.documentElement.setAttribute('data-color-tone', 'warm');
34
+ ```
35
+
36
+ ### Dark Mode
37
+
38
+ ๐Ÿ‘‰ ๋‹คํฌ๋ชจ๋“œ๋ฅผ ์„ค์ •ํ•จ. ๊ธฐ๋ณธ๊ฐ’(์ž๋™, ๋ธŒ๋ผ์šฐ์ € ์„ค์ •์— ๋”ฐ๋ฆ„)๊ณผ 'light', 'dark'๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Œ.
39
+
40
+ ```js
41
+ // ๊ธฐ๋ณธ๊ฐ’(์ž๋™)
42
+ document.documentElement.setAttribute('data-color-mode', '');
43
+
44
+ // light ๋ชจ๋“œ
45
+ document.documentElement.setAttribute('data-color-mode', 'light');
46
+
47
+ // dark ๋ชจ๋“œ
48
+ document.documentElement.setAttribute('data-color-mode', 'dark');
49
+ ```
50
+
51
+ ### Font family
52
+
53
+ ๐Ÿ‘‰ font-family๋ฅผ ์„ค์ •. scss์—์„œ ๋ฎ์–ด์“ฐ๊ธฐ
54
+
55
+ ```scss
56
+ :root {
57
+ --base-font-family: 'Pretendard', sans-serif;
58
+ }
59
+ ```
60
+
61
+ ## ์ƒ‰์ƒ
62
+
63
+ ### ์ ์šฉ ์ƒ‰์ƒ ์ข…๋ฅ˜
64
+
65
+ ๐Ÿ‘‰ ์„ ํƒ ๊ฐ€๋Šฅํ•œ ์ƒ‰์ƒ ์ข…๋ฅ˜ : primary, default, default-deep, info, link, success, warning, danger
66
+ ๐Ÿ‘‰ ์„ ํƒ ๊ฐ€๋Šฅํ•œ ์ƒ‰์ƒ์˜ ํ•˜์œ„ ์ƒ‰์ƒ์œผ๋กœ ์ƒ‰์ƒ๋ช…-fill๊ณผ ์ƒ‰์ƒ๋ช…-reverse๊ฐ€ ์กด์žฌํ•œ๋‹ค.
67
+ ๐Ÿ‘‰ ์œ„ ์„ ํƒ์ž์— ์—†๋Š” text, border, bg, bg-elevation์€ ์‹œ์Šคํ…œ ๋‚ด ์ž๋™ ์ ์šฉํ•œ๋‹ค.
68
+
69
+ ### CSS ์„ ํƒ์ž ์‚ฌ์šฉ
70
+
71
+ ๐Ÿ‘‰ ์•„๋ž˜์™€ ๊ฐ™์ด ์ง์ ‘ ์„ ํƒ์ž๋ฅผ ๋„ฃ์–ด ์‚ฌ์šฉ
72
+
73
+ ```html
74
+ <div className="primary">primary color</div>
75
+ <div className="bg-primary">primary background color</div>
76
+ ```
77
+
78
+ ### SCSS ๋‚ด์—์„œ ํ•จ์ˆ˜ ์‚ฌ์šฉ
79
+
80
+ ```scss
81
+ p {
82
+ color: color(๊ฐ’);
83
+ }
84
+ ```
85
+
86
+ ### ์ปค์Šค์ปด ์ปฌ๋Ÿฌ
87
+
88
+ ๐Ÿ‘‰ ์•„๋ž˜ ํ˜•ํƒœ๋กœ css ๋ณ€์ˆ˜๋ฅผ ์ปค์Šคํ…€ํ•˜์—ฌ ์‚ฌ์šฉ
89
+
90
+ ```scss
91
+ :root {
92
+ --color-primary: #f34a35;
93
+ --color-primary-hover: #dd2d0f;
94
+ --color-primary-pressed: #c9280c;
95
+ --color-primary-focus: #dd2d0f;
96
+ --color-primary-fill: #fff8f7;
97
+ --color-primary-reverse: #ffffff;
98
+ }
99
+ html[data-color-mode='dark'] {
100
+ --color-primary: #ff5d49;
101
+ --color-primary-hover: #ff7564;
102
+ --color-primary-pressed: #ff5d49;
103
+ --color-primary-focus: #ff7564;
104
+ --color-primary-fill: #1c1c20;
105
+ }
106
+ ```
107
+
108
+ ## ๊ทธ๋ฆฌ๋“œ
109
+
110
+ ### ๊ธฐ๋ณธ ๊ทธ๋ฆฌ๋“œ ์‹œ์Šคํ…œ ( 4 ~ 12 columns / auto wrap)
111
+
112
+ ๐Ÿ‘‰ css์—์„œ .grid ์†์„ฑ์œผ๋กœ ๊ธฐ๋ณธ ๊ทธ๋ฆฌ๋“œ ์‹œ์Šคํ…œ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
113
+
114
+ ```html
115
+ <section className="grid">
116
+ <div className="w-4">w-4</div>
117
+ <div className="w-4">w-4</div>
118
+ <div className="w-4">w-4</div>
119
+ </section>
120
+ ```
121
+
122
+ ๐Ÿ‘‰ ๊ทธ๋ฆฌ๋“œ ๋‚ด ํ•˜์œ„ ์š”์†Œ๊ฐ€ ์ค‘๋‹จ์  ์ด์ƒ์ผ ๊ฒฝ์šฐ ์ž๋™์œผ๋กœ ์ค„๋ฐ”๊ฟˆ ํ•ฉ๋‹ˆ๋‹ค.
123
+ ๐Ÿ‘‰ w-{์ˆซ์ž} ํ˜•ํƒœ๋กœ ์ด๋ฃจ์–ด์ ธ์žˆ์œผ๋ฉฐ 1~12 ๊ทธ๋ฆฌ๋“œ๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.
124
+ ๐Ÿ‘‰ {์ˆซ์ž} / 12 \* 100% ํ•œ ๊ฐ’์„ ์ „์ฒด ๊ทธ๋ฆฌ๋“œ ๋‚ด์˜ ๋น„์œจ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
125
+ ๐Ÿ‘‰ ์˜ˆ: w-1์€ 1 / 12 \* 100 = 8.333% ํฌ๊ธฐ, w-6์€ 6 / 12 \* 100 = 50% ํฌ๊ธฐ๋ฅผ ์ฐจ์ง€ํ•ฉ๋‹ˆ๋‹ค.
126
+ ๐Ÿ‘‰ PC๋Š” 12 ๊ทธ๋ฆฌ๋“œ, Tablet์€ 6 ๊ทธ๋ฆฌ๋“œ, Mobile์€ 4 ๊ทธ๋ฆฌ๋“œ๋ฅผ ๊ธฐ๋ณธ์œผ๋กœ ํ•œ๋‹ค.
127
+
128
+ ### ๊ณ ์ • ๊ทธ๋ฆฌ๋“œ ์‹œ์Šคํ…œ
129
+
130
+ ๐Ÿ‘‰ ๋””๋ฐ”์ด์Šค์— ๊ด€๊ณ„์—†์ด ๋””๋ฐ”์ด์Šค์˜ ๋„ˆ๋น„๋ฅผ ์œ ์ง€ํ•˜๊ณ  ์ค„๋ฐ”๊ฟˆ์„ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
131
+ ๐Ÿ‘‰ css์—์„œ grid-fix-2 ~ grid-gix-6 ๋กœ 2 ~ 6๊ฐœ์˜ ์ปฌ๋Ÿผ์„ ๊ฐ€์ง„ ๊ทธ๋ฆฌ๋“œ ์‹œ์Šคํ…œ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.
132
+ ๐Ÿ‘‰ 4๊ทธ๋ฆฌ๋“œ์ผ ๊ฒฝ์šฐ CSS์—์„œ ํ•˜์œ„ ๊ตฌ์„ฑ์š”์†Œ๋Š” w-1_4, w-2_4, w-3_4๊ฐ€ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค.w-1_4์€ 1/4(25%)
133
+ ๐Ÿ‘‰ ํฌ๊ธฐ, w-2_4๋Š” 2/4(50%) ํฌ๊ธฐ, w-3_4๋Š” 3/4(75%) ํฌ๊ธฐ๋ฅผ ์ฐจ์ง€ํ•ฉ๋‹ˆ๋‹ค.
134
+ ๐Ÿ‘‰ Fixed wrap grid์—์„œ๋Š” w-full๋กœ ํ•˜์œ„ ๊ตฌ์„ฑ์š”์†Œ๋ฅผ ๊ทธ๋ฆฌ๋“œ ์‹œ์Šคํ…œ๋‚ด์— 100% ํฌ๊ธฐ๋ฅผ ์ฐจ์ง€ํ•˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
135
+
136
+ ## ๋ ˆ์ด์•„์›ƒ
137
+
138
+ ### ํ…Œ๋‘๋ฆฌ ๋‘๊ป˜ (border)
139
+
140
+ ๐Ÿ‘‰ border ํ•จ์ˆ˜ ํ˜น์€ class ์‚ฌ์šฉ ์‚ฌ์šฉ (0 ~ 4)
141
+
142
+ ```scss
143
+ p {
144
+ margin: border(๊ฐ’);
145
+ }
146
+ ```
147
+
148
+ ```html
149
+ <p className="border-4">border-4</p>
150
+ ```
151
+
152
+ ### ํ…Œ๋‘๋ฆฌ ๋ฐ˜๊ฒฝ (border radius)
153
+
154
+ ๐Ÿ‘‰ r ํ•จ์ˆ˜ ํ˜น์€ class ์‚ฌ์šฉ (0 ~ 6, 'full')
155
+
156
+ ```scss
157
+ p {
158
+ margin: r(๊ฐ’);
159
+ }
160
+ ```
161
+
162
+ ```html
163
+ <p className="r-4">r-4</p>
164
+ ```
165
+
166
+ ### ์—ฌ๋ฐฑ (spacing)
167
+
168
+ ๐Ÿ‘‰ spacing ํ•จ์ˆ˜ ํ˜น์€ class ์‚ฌ์šฉ (0 ~ 13)
169
+
170
+ ```scss
171
+ p {
172
+ margin: s(๊ฐ’);
173
+ }
174
+ ```
175
+
176
+ ```html
177
+ <p className="spacing-4">spacing-4</p>
178
+ ```
179
+
180
+ ## ์ž…๋ ฅ์š”์†Œ
181
+
182
+ ### ํ† ๊ธ€ (toggle)
183
+
184
+ ๐Ÿ‘‰ checkbox์— .toggle ํด๋ž˜์Šค ์‚ฌ์šฉ
185
+
186
+ ```html
187
+ <input type="checkbox" className="toggle" />
188
+ ```
189
+
190
+ ## ์•„์ด์ฝ˜ ์ƒ์„ฑ ๋ฐฉ๋ฒ•
191
+
192
+ ๐Ÿ‘‰ ๋””์ž์ธ ์‹œ์Šคํ…œ ํ”ผ๊ทธ๋งˆ์—์„œ ์ƒํƒœ๋ฅผ ์„ ํƒํ•œ ํ›„ svg๋กœ export ํ•  ๊ฒƒ
193
+ ๐Ÿ‘‰ ํฐํŠธํฌ์ง€์—์„œ icon.woff ํฐํŠธ ์ƒ์„ฑ
194
+ ๐Ÿ‘‰ /scss/icon/font ๊ฒฝ๋กœ์— icon.woff ๋ณต์‚ฌ
195
+ ๐Ÿ‘‰ ์‰˜์—์„œ ์•„๋ž˜ ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰
196
+
197
+ ```sh
198
+ npm run icon
199
+ ```