sales-frontend-components 0.0.36 → 0.0.37
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.
- package/dist/camera/camera.module.scss +187 -0
- package/dist/index.cjs.js +232 -16
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +59 -2
- package/dist/index.esm.js +231 -18
- package/dist/index.esm.js.map +1 -1
- package/package.json +9 -9
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
@use 'sales-frontend-design-system/design-system-context' as *;
|
|
2
|
+
|
|
3
|
+
.content-wrapper {
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.step-content {
|
|
9
|
+
display: flex;
|
|
10
|
+
flex-direction: column;
|
|
11
|
+
gap: 1.5rem;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.step-description {
|
|
15
|
+
color: colors(text-body_3);
|
|
16
|
+
|
|
17
|
+
@include apply-typography(body2);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.description {
|
|
21
|
+
line-height: 1.6;
|
|
22
|
+
color: colors(text-body_3);
|
|
23
|
+
|
|
24
|
+
@include apply-typography(body2);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.form-field-wrapper {
|
|
28
|
+
display: flex;
|
|
29
|
+
flex-direction: column;
|
|
30
|
+
gap: 0.5rem;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.error {
|
|
34
|
+
margin-top: 0.25rem;
|
|
35
|
+
color: colors(additional-semantic_2);
|
|
36
|
+
|
|
37
|
+
@include apply-typography(body2);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.error-caption {
|
|
41
|
+
margin-top: 0.25rem;
|
|
42
|
+
color: colors(additional-semantic_2);
|
|
43
|
+
|
|
44
|
+
@include apply-typography(caption);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// 서류 첨부 스텝 스타일
|
|
48
|
+
.document-complete-content {
|
|
49
|
+
display: flex;
|
|
50
|
+
flex-direction: column;
|
|
51
|
+
gap: margin(title-xlarge);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.photo-grid {
|
|
55
|
+
display: grid;
|
|
56
|
+
grid-template-columns: 1fr 1fr;
|
|
57
|
+
gap: margin(divider-xsmall);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.photo-single {
|
|
61
|
+
display: flex;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.single-photo-item {
|
|
65
|
+
position: relative;
|
|
66
|
+
width: 100%;
|
|
67
|
+
aspect-ratio: 1;
|
|
68
|
+
overflow: hidden;
|
|
69
|
+
border-radius: radius-basic(xlarge);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.photo-item {
|
|
73
|
+
position: relative;
|
|
74
|
+
aspect-ratio: 1;
|
|
75
|
+
overflow: hidden;
|
|
76
|
+
border-radius: radius-basic(xlarge);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.photo-placeholder {
|
|
80
|
+
display: flex;
|
|
81
|
+
align-items: center;
|
|
82
|
+
justify-content: center;
|
|
83
|
+
width: 100%;
|
|
84
|
+
height: 100%;
|
|
85
|
+
background-color: #f5f5f5;
|
|
86
|
+
border: 1px solid colors(border-neutral_4);
|
|
87
|
+
border-radius: radius-basic(xlarge);
|
|
88
|
+
|
|
89
|
+
.photo-image {
|
|
90
|
+
width: 100%;
|
|
91
|
+
height: 100%;
|
|
92
|
+
object-fit: cover;
|
|
93
|
+
border-radius: radius-basic(xlarge);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.photo-content {
|
|
98
|
+
color: colors(text-body_3);
|
|
99
|
+
|
|
100
|
+
@include apply-typography(body2);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.remove-button {
|
|
104
|
+
position: absolute;
|
|
105
|
+
top: padding(medium);
|
|
106
|
+
right: padding(medium);
|
|
107
|
+
display: flex;
|
|
108
|
+
align-items: center;
|
|
109
|
+
justify-content: center;
|
|
110
|
+
width: 32px;
|
|
111
|
+
height: 32px;
|
|
112
|
+
font-size: 1.25rem;
|
|
113
|
+
line-height: 1;
|
|
114
|
+
color: colors(surface-neutral);
|
|
115
|
+
cursor: pointer;
|
|
116
|
+
background-color: colors(text-neutral_1);
|
|
117
|
+
border: none;
|
|
118
|
+
border-radius: 50%;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.add-photo-item {
|
|
122
|
+
.add-photo-button {
|
|
123
|
+
position: relative;
|
|
124
|
+
display: flex;
|
|
125
|
+
flex-direction: column;
|
|
126
|
+
gap: padding(xxxsmall);
|
|
127
|
+
align-items: center;
|
|
128
|
+
justify-content: center;
|
|
129
|
+
width: 100%;
|
|
130
|
+
height: 100%;
|
|
131
|
+
color: colors(text-body);
|
|
132
|
+
cursor: pointer;
|
|
133
|
+
background-color: colors(background-neutral);
|
|
134
|
+
border: 1px solid colors(border-neutral_3);
|
|
135
|
+
border-radius: radius-basic(xlarge);
|
|
136
|
+
|
|
137
|
+
@include apply-typography(body3);
|
|
138
|
+
|
|
139
|
+
&:hover {
|
|
140
|
+
background-color: colors(surface-neutral_2);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// 카메라 아이콘 크기 조정
|
|
144
|
+
svg {
|
|
145
|
+
width: 40px;
|
|
146
|
+
height: 40px;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.add-photo-button-single {
|
|
152
|
+
position: relative;
|
|
153
|
+
display: flex;
|
|
154
|
+
flex-direction: column;
|
|
155
|
+
gap: padding(xxxsmall);
|
|
156
|
+
align-items: center;
|
|
157
|
+
justify-content: center;
|
|
158
|
+
width: 100%;
|
|
159
|
+
height: 100%;
|
|
160
|
+
color: colors(text-body);
|
|
161
|
+
cursor: pointer;
|
|
162
|
+
background-color: colors(background-neutral);
|
|
163
|
+
border: 1px solid colors(border-neutral_3);
|
|
164
|
+
border-radius: radius-basic(xlarge);
|
|
165
|
+
|
|
166
|
+
@include apply-typography(body3);
|
|
167
|
+
|
|
168
|
+
&:hover {
|
|
169
|
+
background-color: colors(surface-neutral_2);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// 카메라 아이콘 크기 조정
|
|
173
|
+
svg {
|
|
174
|
+
width: 40px;
|
|
175
|
+
height: 40px;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.photo-count {
|
|
180
|
+
color: colors(text-body);
|
|
181
|
+
|
|
182
|
+
@include apply-typography(body3);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.photo-count-number {
|
|
186
|
+
color: colors(text-primary);
|
|
187
|
+
}
|
package/dist/index.cjs.js
CHANGED
|
@@ -8,6 +8,8 @@ var React = require('react');
|
|
|
8
8
|
var reactHookForm = require('react-hook-form');
|
|
9
9
|
var styles$1 = require('./form/form-signautre/form-signature.module.scss');
|
|
10
10
|
var styles$2 = require('./step-indicator/step-indicator.module.scss');
|
|
11
|
+
var path = require('@/constants/path');
|
|
12
|
+
var styles$3 = require('./camera/camera.module.scss');
|
|
11
13
|
|
|
12
14
|
function getDefaultExportFromCjs (x) {
|
|
13
15
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
@@ -100,7 +102,7 @@ function requireBind () {
|
|
|
100
102
|
var bindExports = requireBind();
|
|
101
103
|
var classNames = /*@__PURE__*/getDefaultExportFromCjs(bindExports);
|
|
102
104
|
|
|
103
|
-
const cx$
|
|
105
|
+
const cx$3 = classNames.bind(styles);
|
|
104
106
|
const DataTable = ({ table, isError, isLoading, msgText, ...props }) => {
|
|
105
107
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
106
108
|
salesFrontendDesignSystem.Table,
|
|
@@ -115,7 +117,7 @@ const DataTable = ({ table, isError, isLoading, msgText, ...props }) => {
|
|
|
115
117
|
"th",
|
|
116
118
|
{
|
|
117
119
|
colSpan: header.colSpan,
|
|
118
|
-
className: cx$
|
|
120
|
+
className: cx$3({
|
|
119
121
|
"is-resizing": header.column.getIsResizing()
|
|
120
122
|
// 3. 리사이징 중일 때 클래스 추가
|
|
121
123
|
}),
|
|
@@ -127,7 +129,7 @@ const DataTable = ({ table, isError, isLoading, msgText, ...props }) => {
|
|
|
127
129
|
{
|
|
128
130
|
onMouseDown: header.getResizeHandler(),
|
|
129
131
|
onTouchStart: header.getResizeHandler(),
|
|
130
|
-
className: cx$
|
|
132
|
+
className: cx$3("resize-handle")
|
|
131
133
|
}
|
|
132
134
|
)
|
|
133
135
|
]
|
|
@@ -148,7 +150,7 @@ const DataTable = ({ table, isError, isLoading, msgText, ...props }) => {
|
|
|
148
150
|
},
|
|
149
151
|
cell.id
|
|
150
152
|
)) }, row.id)
|
|
151
|
-
)) : /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { className: cx$
|
|
153
|
+
)) : /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { className: cx$3("feedback-cell"), colSpan: table.getVisibleLeafColumns().length, children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx("div", { children: "Loading..." }) : /* @__PURE__ */ jsxRuntime.jsx("div", { children: msgText || (isError ? "Error" : "No data") }) }) }) })
|
|
152
154
|
]
|
|
153
155
|
}
|
|
154
156
|
);
|
|
@@ -297,7 +299,7 @@ const FormTextField = ({
|
|
|
297
299
|
);
|
|
298
300
|
};
|
|
299
301
|
|
|
300
|
-
const cx$
|
|
302
|
+
const cx$2 = classNames.bind(styles$1);
|
|
301
303
|
const FormSignature = ({
|
|
302
304
|
label,
|
|
303
305
|
error,
|
|
@@ -532,9 +534,9 @@ const FormSignature = ({
|
|
|
532
534
|
[handleSubmit, clearSignature, getSignatureDataObject, validateForm]
|
|
533
535
|
);
|
|
534
536
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
535
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx$
|
|
537
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx$2("form-label"), children: [
|
|
536
538
|
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "typo-subtitle3 text-body_1", children: label }),
|
|
537
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx$
|
|
539
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx$2("form-label-button-box"), children: [
|
|
538
540
|
isShowResetButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
539
541
|
salesFrontendDesignSystem.Button,
|
|
540
542
|
{
|
|
@@ -561,7 +563,7 @@ const FormSignature = ({
|
|
|
561
563
|
)
|
|
562
564
|
] })
|
|
563
565
|
] }),
|
|
564
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cx$
|
|
566
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cx$2("form-signature", error && "is-error"), ref: containerRef, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
565
567
|
"canvas",
|
|
566
568
|
{
|
|
567
569
|
ref: canvasRef,
|
|
@@ -576,7 +578,7 @@ const FormSignature = ({
|
|
|
576
578
|
onMouseLeave: handleMouseLeave
|
|
577
579
|
}
|
|
578
580
|
) }),
|
|
579
|
-
error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cx$
|
|
581
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cx$2("error-msg-box"), children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx$2("error-msg"), children: errorMsg || "\uC11C\uBA85\uC744 \uC785\uB825\uD574 \uC8FC\uC138\uC694." }) })
|
|
580
582
|
] });
|
|
581
583
|
};
|
|
582
584
|
|
|
@@ -688,7 +690,7 @@ const useFormSignature = ({ onSubmit, onError, onClear, minLength = 100 } = {})
|
|
|
688
690
|
};
|
|
689
691
|
};
|
|
690
692
|
|
|
691
|
-
const cx = classNames.bind(styles$2);
|
|
693
|
+
const cx$1 = classNames.bind(styles$2);
|
|
692
694
|
const StepIndicator = ({
|
|
693
695
|
items,
|
|
694
696
|
onClickItem,
|
|
@@ -704,28 +706,242 @@ const StepIndicator = ({
|
|
|
704
706
|
}
|
|
705
707
|
});
|
|
706
708
|
}, [items, defaultValue]);
|
|
707
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("stepper-layout"), children: [
|
|
708
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cx("stepper"), children: items.map((item, idx) => /* @__PURE__ */ jsxRuntime.jsxs(React.Fragment, { children: [
|
|
709
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx$1("stepper-layout"), children: [
|
|
710
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cx$1("stepper"), children: items.map((item, idx) => /* @__PURE__ */ jsxRuntime.jsxs(React.Fragment, { children: [
|
|
709
711
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
710
712
|
"div",
|
|
711
713
|
{
|
|
712
|
-
className: cx("circle", (defaultValue === item.value || current === idx) && "active"),
|
|
714
|
+
className: cx$1("circle", (defaultValue === item.value || current === idx) && "active"),
|
|
713
715
|
onClick: () => onClickItem?.(item),
|
|
714
|
-
children: item.isCompleted || idx < current ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx("completed") }) : ++idx
|
|
716
|
+
children: item.isCompleted || idx < current ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx$1("completed") }) : ++idx
|
|
715
717
|
}
|
|
716
718
|
),
|
|
717
|
-
idx < items.length && Array.from({ length: dotCount }).map((_, dotIdx) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx("dot") }, `dot-${idx}-${dotIdx}`))
|
|
719
|
+
idx < items.length && Array.from({ length: dotCount }).map((_, dotIdx) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx$1("dot") }, `dot-${idx}-${dotIdx}`))
|
|
718
720
|
] }, `num-${idx}`)) }),
|
|
719
|
-
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: cx("step-labels"), children: items.map((item, idx) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: cx((defaultValue === item.value || current === idx) && "active"), children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: item.label ?? item.value }) }, `label-${idx}`)) })
|
|
721
|
+
/* @__PURE__ */ jsxRuntime.jsx("ul", { className: cx$1("step-labels"), children: items.map((item, idx) => /* @__PURE__ */ jsxRuntime.jsx("li", { className: cx$1((defaultValue === item.value || current === idx) && "active"), children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: item.label ?? item.value }) }, `label-${idx}`)) })
|
|
720
722
|
] });
|
|
721
723
|
};
|
|
722
724
|
|
|
725
|
+
const cx = classNames.bind(styles$3);
|
|
726
|
+
function Attachement({ photos, onAddPhoto, onRemovePhoto, show, type = "multiple" }) {
|
|
727
|
+
const handleAddPhoto = () => {
|
|
728
|
+
onAddPhoto();
|
|
729
|
+
};
|
|
730
|
+
const handleRemovePhoto = (id) => {
|
|
731
|
+
onRemovePhoto(id);
|
|
732
|
+
};
|
|
733
|
+
const renderPhotoSingle = () => {
|
|
734
|
+
if (photos.length === 0) {
|
|
735
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cx("single-photo-item", "add-photo-item"), children: /* @__PURE__ */ jsxRuntime.jsxs("button", { className: cx("add-photo-button-single"), onClick: handleAddPhoto, children: [
|
|
736
|
+
/* @__PURE__ */ jsxRuntime.jsx(salesFrontendDesignSystem.Icon, { name: "camera", src: `${path.IMG_PREFIX}/dsp/assets/icons/illust/camera.svg` }),
|
|
737
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "\uC0AC\uC9C4 \uCCA8\uBD80\uD558\uAE30" })
|
|
738
|
+
] }) });
|
|
739
|
+
}
|
|
740
|
+
return photos.map((photo) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("single-photo-item"), children: [
|
|
741
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cx("photo-placeholder"), children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: photo.src, alt: photo.name, className: cx("photo-image") }) }),
|
|
742
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { className: cx("remove-button"), onClick: () => handleRemovePhoto(photo.id), "aria-label": "\uC0AC\uC9C4 \uC0AD\uC81C", children: "\xD7" })
|
|
743
|
+
] }, photo.id));
|
|
744
|
+
};
|
|
745
|
+
const renderPhotoGrid = () => {
|
|
746
|
+
const maxPhotos = type === "single" ? 1 : 4;
|
|
747
|
+
const gridItems = [];
|
|
748
|
+
if (photos.length < maxPhotos) {
|
|
749
|
+
gridItems.push(
|
|
750
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cx("photo-item", "add-photo-item"), children: /* @__PURE__ */ jsxRuntime.jsxs("button", { className: cx("add-photo-button"), onClick: handleAddPhoto, children: [
|
|
751
|
+
/* @__PURE__ */ jsxRuntime.jsx(salesFrontendDesignSystem.Icon, { name: "camera", src: `${path.IMG_PREFIX}/dsp/assets/icons/illust/camera.svg` }),
|
|
752
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "\uCCA8\uBD80\uD558\uAE30" }),
|
|
753
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: cx("photo-count"), children: [
|
|
754
|
+
"(",
|
|
755
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cx("photo-count-number"), children: photos.length }),
|
|
756
|
+
"/",
|
|
757
|
+
maxPhotos,
|
|
758
|
+
")"
|
|
759
|
+
] })
|
|
760
|
+
] }) }, "add-photo")
|
|
761
|
+
);
|
|
762
|
+
}
|
|
763
|
+
photos.forEach((photo) => {
|
|
764
|
+
gridItems.push(
|
|
765
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("photo-item"), children: [
|
|
766
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cx("photo-placeholder"), children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: photo.src, alt: photo.name, className: cx("photo-image") }) }),
|
|
767
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { className: cx("remove-button"), onClick: () => handleRemovePhoto(photo.id), "aria-label": "\uC0AC\uC9C4 \uC0AD\uC81C", children: "\xD7" })
|
|
768
|
+
] }, photo.id)
|
|
769
|
+
);
|
|
770
|
+
});
|
|
771
|
+
return gridItems;
|
|
772
|
+
};
|
|
773
|
+
const isVisible = show || !show && photos.length > 0;
|
|
774
|
+
if (!isVisible) {
|
|
775
|
+
return null;
|
|
776
|
+
}
|
|
777
|
+
if (type === "single") {
|
|
778
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cx("photo-single"), children: renderPhotoSingle() });
|
|
779
|
+
}
|
|
780
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cx("photo-grid"), children: renderPhotoGrid() });
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
const maxImageSize = 3 * 1024 * 1024;
|
|
784
|
+
function resize(image, options = { ext: "jpeg", filesize: maxImageSize }) {
|
|
785
|
+
return new Promise((resolve, reject) => {
|
|
786
|
+
const canvas = document.createElement("canvas");
|
|
787
|
+
const ctx = canvas.getContext("2d");
|
|
788
|
+
if (!ctx) {
|
|
789
|
+
reject(new Error("Canvas context\uB97C \uC0DD\uC131\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
790
|
+
return;
|
|
791
|
+
}
|
|
792
|
+
const img = new Image();
|
|
793
|
+
img.crossOrigin = "anonymous";
|
|
794
|
+
img.onload = () => {
|
|
795
|
+
let { width, height } = img;
|
|
796
|
+
const { filesize, ext } = options;
|
|
797
|
+
if (filesize) {
|
|
798
|
+
const originalSize = width * height * 4;
|
|
799
|
+
if (originalSize > filesize) {
|
|
800
|
+
const ratio = Math.sqrt(filesize / originalSize);
|
|
801
|
+
width = Math.floor(width * ratio);
|
|
802
|
+
height = Math.floor(height * ratio);
|
|
803
|
+
}
|
|
804
|
+
} else {
|
|
805
|
+
const { width: targetWidth, height: targetHeight } = options;
|
|
806
|
+
if (targetWidth && targetHeight) {
|
|
807
|
+
width = targetWidth;
|
|
808
|
+
height = targetHeight;
|
|
809
|
+
} else if (targetWidth) {
|
|
810
|
+
const ratio = targetWidth / width;
|
|
811
|
+
width = targetWidth;
|
|
812
|
+
height = Math.floor(height * ratio);
|
|
813
|
+
} else if (targetHeight) {
|
|
814
|
+
const ratio = targetHeight / height;
|
|
815
|
+
height = targetHeight;
|
|
816
|
+
width = Math.floor(width * ratio);
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
canvas.width = width;
|
|
820
|
+
canvas.height = height;
|
|
821
|
+
ctx.drawImage(img, 0, 0, width, height);
|
|
822
|
+
if (typeof image === "string") {
|
|
823
|
+
const mimeType = ext === "png" ? "image/png" : "image/jpeg";
|
|
824
|
+
const quality = ext === "png" ? 1 : 0.8;
|
|
825
|
+
const base64 = canvas.toDataURL(mimeType, quality);
|
|
826
|
+
resolve(base64);
|
|
827
|
+
} else {
|
|
828
|
+
canvas.toBlob(
|
|
829
|
+
(blob) => {
|
|
830
|
+
if (!blob) {
|
|
831
|
+
reject(new Error("Blob\uC744 \uC0DD\uC131\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
832
|
+
return;
|
|
833
|
+
}
|
|
834
|
+
const mimeType = ext === "png" ? "image/png" : "image/jpeg";
|
|
835
|
+
const fileName = image.name ? image.name.replace(/\.[^/.]+$/, "") + "." + ext : "resized." + ext;
|
|
836
|
+
const resizedFile = new File([blob], fileName, { type: mimeType });
|
|
837
|
+
resolve(resizedFile);
|
|
838
|
+
},
|
|
839
|
+
ext === "png" ? "image/png" : "image/jpeg",
|
|
840
|
+
ext === "png" ? 1 : 0.8
|
|
841
|
+
);
|
|
842
|
+
}
|
|
843
|
+
};
|
|
844
|
+
img.onerror = () => {
|
|
845
|
+
reject(new Error("\uC774\uBBF8\uC9C0\uB97C \uB85C\uB4DC\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
846
|
+
};
|
|
847
|
+
if (typeof image === "string") {
|
|
848
|
+
img.src = image;
|
|
849
|
+
} else {
|
|
850
|
+
const reader = new FileReader();
|
|
851
|
+
reader.onload = (e) => {
|
|
852
|
+
if (e.target?.result) {
|
|
853
|
+
img.src = e.target.result;
|
|
854
|
+
} else {
|
|
855
|
+
reject(new Error("\uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
856
|
+
}
|
|
857
|
+
};
|
|
858
|
+
reader.onerror = () => {
|
|
859
|
+
reject(new Error("\uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
860
|
+
};
|
|
861
|
+
reader.readAsDataURL(image);
|
|
862
|
+
}
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
|
|
866
|
+
const genImageId = () => `camera-${Date.now()}-${Math.random()}`;
|
|
867
|
+
function useCamera({
|
|
868
|
+
onChange,
|
|
869
|
+
resize: resizeOption,
|
|
870
|
+
cameraOnly,
|
|
871
|
+
onDelete,
|
|
872
|
+
show,
|
|
873
|
+
type = "multiple"
|
|
874
|
+
} = {}) {
|
|
875
|
+
const [attachedPhotos, setAttachedPhotos] = React.useState([]);
|
|
876
|
+
const findImage = (imageId) => {
|
|
877
|
+
return attachedPhotos.find((image) => image.id === imageId);
|
|
878
|
+
};
|
|
879
|
+
const onClick = () => {
|
|
880
|
+
const input = document.createElement("input");
|
|
881
|
+
input.type = "file";
|
|
882
|
+
input.accept = "image/*";
|
|
883
|
+
if (cameraOnly) {
|
|
884
|
+
input.capture = "camera";
|
|
885
|
+
}
|
|
886
|
+
input.addEventListener("change", async (event) => {
|
|
887
|
+
const target = event.target;
|
|
888
|
+
const files = target.files;
|
|
889
|
+
if (files && files.length > 0) {
|
|
890
|
+
const file = files[0];
|
|
891
|
+
if (file) {
|
|
892
|
+
const resizedFile = await resize(file, resizeOption);
|
|
893
|
+
const newPhoto = {
|
|
894
|
+
id: genImageId(),
|
|
895
|
+
src: URL.createObjectURL(resizedFile),
|
|
896
|
+
name: `\uC11C\uB958\uC0AC\uC9C4_${attachedPhotos.length + 1}`
|
|
897
|
+
};
|
|
898
|
+
setAttachedPhotos([...attachedPhotos, newPhoto]);
|
|
899
|
+
onChange && onChange(file);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
document.body.removeChild(input);
|
|
903
|
+
});
|
|
904
|
+
input.style.display = "none";
|
|
905
|
+
document.body.appendChild(input);
|
|
906
|
+
input.click();
|
|
907
|
+
};
|
|
908
|
+
const deleteImage = (imageId) => {
|
|
909
|
+
const imageIndex = attachedPhotos.findIndex((image) => image.id === imageId);
|
|
910
|
+
if (imageIndex > -1) {
|
|
911
|
+
const item = attachedPhotos.splice(imageIndex, 1);
|
|
912
|
+
URL.revokeObjectURL(item[0].src);
|
|
913
|
+
setAttachedPhotos([...attachedPhotos]);
|
|
914
|
+
onDelete && onDelete(imageId);
|
|
915
|
+
}
|
|
916
|
+
};
|
|
917
|
+
const CameraComponent = React.useCallback(() => {
|
|
918
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Attachement, { show: true, onAddPhoto: onClick, onRemovePhoto: deleteImage, photos: attachedPhotos, type });
|
|
919
|
+
}, [attachedPhotos, onClick, deleteImage, show]);
|
|
920
|
+
React.useEffect(() => {
|
|
921
|
+
return () => {
|
|
922
|
+
attachedPhotos.forEach((image) => {
|
|
923
|
+
URL.revokeObjectURL(image.src);
|
|
924
|
+
});
|
|
925
|
+
};
|
|
926
|
+
}, []);
|
|
927
|
+
return {
|
|
928
|
+
onClick,
|
|
929
|
+
getImage: findImage,
|
|
930
|
+
deleteImage,
|
|
931
|
+
attachedPhotos,
|
|
932
|
+
Attachment: CameraComponent
|
|
933
|
+
};
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
exports.Attachement = Attachement;
|
|
723
937
|
exports.DataTable = DataTable;
|
|
724
938
|
exports.FormDatePicker = FormDatePicker;
|
|
725
939
|
exports.FormSegmentGroup = FormSegmentGroup;
|
|
726
940
|
exports.FormSignature = FormSignature;
|
|
727
941
|
exports.FormTextField = FormTextField;
|
|
728
942
|
exports.StepIndicator = StepIndicator;
|
|
943
|
+
exports.resize = resize;
|
|
944
|
+
exports.useCamera = useCamera;
|
|
729
945
|
exports.useFormSignature = useFormSignature;
|
|
730
946
|
exports.useTable = useTable;
|
|
731
947
|
//# sourceMappingURL=index.cjs.js.map
|