sales-frontend-components 0.0.36 → 0.0.38
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 +231 -16
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +59 -2
- package/dist/index.esm.js +230 -18
- package/dist/index.esm.js.map +1 -1
- package/package.json +8 -8
|
@@ -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,7 @@ 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 styles$3 = require('./camera/camera.module.scss');
|
|
11
12
|
|
|
12
13
|
function getDefaultExportFromCjs (x) {
|
|
13
14
|
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
|
@@ -100,7 +101,7 @@ function requireBind () {
|
|
|
100
101
|
var bindExports = requireBind();
|
|
101
102
|
var classNames = /*@__PURE__*/getDefaultExportFromCjs(bindExports);
|
|
102
103
|
|
|
103
|
-
const cx$
|
|
104
|
+
const cx$3 = classNames.bind(styles);
|
|
104
105
|
const DataTable = ({ table, isError, isLoading, msgText, ...props }) => {
|
|
105
106
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
106
107
|
salesFrontendDesignSystem.Table,
|
|
@@ -115,7 +116,7 @@ const DataTable = ({ table, isError, isLoading, msgText, ...props }) => {
|
|
|
115
116
|
"th",
|
|
116
117
|
{
|
|
117
118
|
colSpan: header.colSpan,
|
|
118
|
-
className: cx$
|
|
119
|
+
className: cx$3({
|
|
119
120
|
"is-resizing": header.column.getIsResizing()
|
|
120
121
|
// 3. 리사이징 중일 때 클래스 추가
|
|
121
122
|
}),
|
|
@@ -127,7 +128,7 @@ const DataTable = ({ table, isError, isLoading, msgText, ...props }) => {
|
|
|
127
128
|
{
|
|
128
129
|
onMouseDown: header.getResizeHandler(),
|
|
129
130
|
onTouchStart: header.getResizeHandler(),
|
|
130
|
-
className: cx$
|
|
131
|
+
className: cx$3("resize-handle")
|
|
131
132
|
}
|
|
132
133
|
)
|
|
133
134
|
]
|
|
@@ -148,7 +149,7 @@ const DataTable = ({ table, isError, isLoading, msgText, ...props }) => {
|
|
|
148
149
|
},
|
|
149
150
|
cell.id
|
|
150
151
|
)) }, row.id)
|
|
151
|
-
)) : /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx("td", { className: cx$
|
|
152
|
+
)) : /* @__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
153
|
]
|
|
153
154
|
}
|
|
154
155
|
);
|
|
@@ -297,7 +298,7 @@ const FormTextField = ({
|
|
|
297
298
|
);
|
|
298
299
|
};
|
|
299
300
|
|
|
300
|
-
const cx$
|
|
301
|
+
const cx$2 = classNames.bind(styles$1);
|
|
301
302
|
const FormSignature = ({
|
|
302
303
|
label,
|
|
303
304
|
error,
|
|
@@ -532,9 +533,9 @@ const FormSignature = ({
|
|
|
532
533
|
[handleSubmit, clearSignature, getSignatureDataObject, validateForm]
|
|
533
534
|
);
|
|
534
535
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
|
|
535
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx$
|
|
536
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx$2("form-label"), children: [
|
|
536
537
|
/* @__PURE__ */ jsxRuntime.jsx("label", { className: "typo-subtitle3 text-body_1", children: label }),
|
|
537
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx$
|
|
538
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx$2("form-label-button-box"), children: [
|
|
538
539
|
isShowResetButton && /* @__PURE__ */ jsxRuntime.jsx(
|
|
539
540
|
salesFrontendDesignSystem.Button,
|
|
540
541
|
{
|
|
@@ -561,7 +562,7 @@ const FormSignature = ({
|
|
|
561
562
|
)
|
|
562
563
|
] })
|
|
563
564
|
] }),
|
|
564
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cx$
|
|
565
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cx$2("form-signature", error && "is-error"), ref: containerRef, children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
565
566
|
"canvas",
|
|
566
567
|
{
|
|
567
568
|
ref: canvasRef,
|
|
@@ -576,7 +577,7 @@ const FormSignature = ({
|
|
|
576
577
|
onMouseLeave: handleMouseLeave
|
|
577
578
|
}
|
|
578
579
|
) }),
|
|
579
|
-
error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: cx$
|
|
580
|
+
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
581
|
] });
|
|
581
582
|
};
|
|
582
583
|
|
|
@@ -688,7 +689,7 @@ const useFormSignature = ({ onSubmit, onError, onClear, minLength = 100 } = {})
|
|
|
688
689
|
};
|
|
689
690
|
};
|
|
690
691
|
|
|
691
|
-
const cx = classNames.bind(styles$2);
|
|
692
|
+
const cx$1 = classNames.bind(styles$2);
|
|
692
693
|
const StepIndicator = ({
|
|
693
694
|
items,
|
|
694
695
|
onClickItem,
|
|
@@ -704,28 +705,242 @@ const StepIndicator = ({
|
|
|
704
705
|
}
|
|
705
706
|
});
|
|
706
707
|
}, [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: [
|
|
708
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx$1("stepper-layout"), children: [
|
|
709
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cx$1("stepper"), children: items.map((item, idx) => /* @__PURE__ */ jsxRuntime.jsxs(React.Fragment, { children: [
|
|
709
710
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
710
711
|
"div",
|
|
711
712
|
{
|
|
712
|
-
className: cx("circle", (defaultValue === item.value || current === idx) && "active"),
|
|
713
|
+
className: cx$1("circle", (defaultValue === item.value || current === idx) && "active"),
|
|
713
714
|
onClick: () => onClickItem?.(item),
|
|
714
|
-
children: item.isCompleted || idx < current ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx("completed") }) : ++idx
|
|
715
|
+
children: item.isCompleted || idx < current ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx$1("completed") }) : ++idx
|
|
715
716
|
}
|
|
716
717
|
),
|
|
717
|
-
idx < items.length && Array.from({ length: dotCount }).map((_, dotIdx) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx("dot") }, `dot-${idx}-${dotIdx}`))
|
|
718
|
+
idx < items.length && Array.from({ length: dotCount }).map((_, dotIdx) => /* @__PURE__ */ jsxRuntime.jsx("span", { className: cx$1("dot") }, `dot-${idx}-${dotIdx}`))
|
|
718
719
|
] }, `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}`)) })
|
|
720
|
+
/* @__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
721
|
] });
|
|
721
722
|
};
|
|
722
723
|
|
|
724
|
+
const cx = classNames.bind(styles$3);
|
|
725
|
+
function Attachement({ photos, onAddPhoto, onRemovePhoto, show, type = "multiple" }) {
|
|
726
|
+
const handleAddPhoto = () => {
|
|
727
|
+
onAddPhoto();
|
|
728
|
+
};
|
|
729
|
+
const handleRemovePhoto = (id) => {
|
|
730
|
+
onRemovePhoto(id);
|
|
731
|
+
};
|
|
732
|
+
const renderPhotoSingle = () => {
|
|
733
|
+
if (photos.length === 0) {
|
|
734
|
+
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: [
|
|
735
|
+
/* @__PURE__ */ jsxRuntime.jsx(salesFrontendDesignSystem.Icon, { name: "illust/camera" }),
|
|
736
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "\uC0AC\uC9C4 \uCCA8\uBD80\uD558\uAE30" })
|
|
737
|
+
] }) });
|
|
738
|
+
}
|
|
739
|
+
return photos.map((photo) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("single-photo-item"), children: [
|
|
740
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cx("photo-placeholder"), children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: photo.src, alt: photo.name, className: cx("photo-image") }) }),
|
|
741
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { className: cx("remove-button"), onClick: () => handleRemovePhoto(photo.id), "aria-label": "\uC0AC\uC9C4 \uC0AD\uC81C", children: "\xD7" })
|
|
742
|
+
] }, photo.id));
|
|
743
|
+
};
|
|
744
|
+
const renderPhotoGrid = () => {
|
|
745
|
+
const maxPhotos = type === "single" ? 1 : 4;
|
|
746
|
+
const gridItems = [];
|
|
747
|
+
if (photos.length < maxPhotos) {
|
|
748
|
+
gridItems.push(
|
|
749
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cx("photo-item", "add-photo-item"), children: /* @__PURE__ */ jsxRuntime.jsxs("button", { className: cx("add-photo-button"), onClick: handleAddPhoto, children: [
|
|
750
|
+
/* @__PURE__ */ jsxRuntime.jsx(salesFrontendDesignSystem.Icon, { name: "camera", src: `${IMG_PREFIX}/dsp/assets/icons/illust/camera.svg` }),
|
|
751
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { children: "\uCCA8\uBD80\uD558\uAE30" }),
|
|
752
|
+
/* @__PURE__ */ jsxRuntime.jsxs("span", { className: cx("photo-count"), children: [
|
|
753
|
+
"(",
|
|
754
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: cx("photo-count-number"), children: photos.length }),
|
|
755
|
+
"/",
|
|
756
|
+
maxPhotos,
|
|
757
|
+
")"
|
|
758
|
+
] })
|
|
759
|
+
] }) }, "add-photo")
|
|
760
|
+
);
|
|
761
|
+
}
|
|
762
|
+
photos.forEach((photo) => {
|
|
763
|
+
gridItems.push(
|
|
764
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cx("photo-item"), children: [
|
|
765
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cx("photo-placeholder"), children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: photo.src, alt: photo.name, className: cx("photo-image") }) }),
|
|
766
|
+
/* @__PURE__ */ jsxRuntime.jsx("button", { className: cx("remove-button"), onClick: () => handleRemovePhoto(photo.id), "aria-label": "\uC0AC\uC9C4 \uC0AD\uC81C", children: "\xD7" })
|
|
767
|
+
] }, photo.id)
|
|
768
|
+
);
|
|
769
|
+
});
|
|
770
|
+
return gridItems;
|
|
771
|
+
};
|
|
772
|
+
const isVisible = show || !show && photos.length > 0;
|
|
773
|
+
if (!isVisible) {
|
|
774
|
+
return null;
|
|
775
|
+
}
|
|
776
|
+
if (type === "single") {
|
|
777
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cx("photo-single"), children: renderPhotoSingle() });
|
|
778
|
+
}
|
|
779
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: cx("photo-grid"), children: renderPhotoGrid() });
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
const maxImageSize = 3 * 1024 * 1024;
|
|
783
|
+
function resize(image, options = { ext: "jpeg", filesize: maxImageSize }) {
|
|
784
|
+
return new Promise((resolve, reject) => {
|
|
785
|
+
const canvas = document.createElement("canvas");
|
|
786
|
+
const ctx = canvas.getContext("2d");
|
|
787
|
+
if (!ctx) {
|
|
788
|
+
reject(new Error("Canvas context\uB97C \uC0DD\uC131\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
const img = new Image();
|
|
792
|
+
img.crossOrigin = "anonymous";
|
|
793
|
+
img.onload = () => {
|
|
794
|
+
let { width, height } = img;
|
|
795
|
+
const { filesize, ext } = options;
|
|
796
|
+
if (filesize) {
|
|
797
|
+
const originalSize = width * height * 4;
|
|
798
|
+
if (originalSize > filesize) {
|
|
799
|
+
const ratio = Math.sqrt(filesize / originalSize);
|
|
800
|
+
width = Math.floor(width * ratio);
|
|
801
|
+
height = Math.floor(height * ratio);
|
|
802
|
+
}
|
|
803
|
+
} else {
|
|
804
|
+
const { width: targetWidth, height: targetHeight } = options;
|
|
805
|
+
if (targetWidth && targetHeight) {
|
|
806
|
+
width = targetWidth;
|
|
807
|
+
height = targetHeight;
|
|
808
|
+
} else if (targetWidth) {
|
|
809
|
+
const ratio = targetWidth / width;
|
|
810
|
+
width = targetWidth;
|
|
811
|
+
height = Math.floor(height * ratio);
|
|
812
|
+
} else if (targetHeight) {
|
|
813
|
+
const ratio = targetHeight / height;
|
|
814
|
+
height = targetHeight;
|
|
815
|
+
width = Math.floor(width * ratio);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
canvas.width = width;
|
|
819
|
+
canvas.height = height;
|
|
820
|
+
ctx.drawImage(img, 0, 0, width, height);
|
|
821
|
+
if (typeof image === "string") {
|
|
822
|
+
const mimeType = ext === "png" ? "image/png" : "image/jpeg";
|
|
823
|
+
const quality = ext === "png" ? 1 : 0.8;
|
|
824
|
+
const base64 = canvas.toDataURL(mimeType, quality);
|
|
825
|
+
resolve(base64);
|
|
826
|
+
} else {
|
|
827
|
+
canvas.toBlob(
|
|
828
|
+
(blob) => {
|
|
829
|
+
if (!blob) {
|
|
830
|
+
reject(new Error("Blob\uC744 \uC0DD\uC131\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
const mimeType = ext === "png" ? "image/png" : "image/jpeg";
|
|
834
|
+
const fileName = image.name ? image.name.replace(/\.[^/.]+$/, "") + "." + ext : "resized." + ext;
|
|
835
|
+
const resizedFile = new File([blob], fileName, { type: mimeType });
|
|
836
|
+
resolve(resizedFile);
|
|
837
|
+
},
|
|
838
|
+
ext === "png" ? "image/png" : "image/jpeg",
|
|
839
|
+
ext === "png" ? 1 : 0.8
|
|
840
|
+
);
|
|
841
|
+
}
|
|
842
|
+
};
|
|
843
|
+
img.onerror = () => {
|
|
844
|
+
reject(new Error("\uC774\uBBF8\uC9C0\uB97C \uB85C\uB4DC\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
845
|
+
};
|
|
846
|
+
if (typeof image === "string") {
|
|
847
|
+
img.src = image;
|
|
848
|
+
} else {
|
|
849
|
+
const reader = new FileReader();
|
|
850
|
+
reader.onload = (e) => {
|
|
851
|
+
if (e.target?.result) {
|
|
852
|
+
img.src = e.target.result;
|
|
853
|
+
} else {
|
|
854
|
+
reject(new Error("\uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
855
|
+
}
|
|
856
|
+
};
|
|
857
|
+
reader.onerror = () => {
|
|
858
|
+
reject(new Error("\uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
859
|
+
};
|
|
860
|
+
reader.readAsDataURL(image);
|
|
861
|
+
}
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
const genImageId = () => `camera-${Date.now()}-${Math.random()}`;
|
|
866
|
+
function useCamera({
|
|
867
|
+
onChange,
|
|
868
|
+
resize: resizeOption,
|
|
869
|
+
cameraOnly,
|
|
870
|
+
onDelete,
|
|
871
|
+
show,
|
|
872
|
+
type = "multiple"
|
|
873
|
+
} = {}) {
|
|
874
|
+
const [attachedPhotos, setAttachedPhotos] = React.useState([]);
|
|
875
|
+
const findImage = (imageId) => {
|
|
876
|
+
return attachedPhotos.find((image) => image.id === imageId);
|
|
877
|
+
};
|
|
878
|
+
const onClick = () => {
|
|
879
|
+
const input = document.createElement("input");
|
|
880
|
+
input.type = "file";
|
|
881
|
+
input.accept = "image/*";
|
|
882
|
+
if (cameraOnly) {
|
|
883
|
+
input.capture = "camera";
|
|
884
|
+
}
|
|
885
|
+
input.addEventListener("change", async (event) => {
|
|
886
|
+
const target = event.target;
|
|
887
|
+
const files = target.files;
|
|
888
|
+
if (files && files.length > 0) {
|
|
889
|
+
const file = files[0];
|
|
890
|
+
if (file) {
|
|
891
|
+
const resizedFile = await resize(file, resizeOption);
|
|
892
|
+
const newPhoto = {
|
|
893
|
+
id: genImageId(),
|
|
894
|
+
src: URL.createObjectURL(resizedFile),
|
|
895
|
+
name: `\uC11C\uB958\uC0AC\uC9C4_${attachedPhotos.length + 1}`
|
|
896
|
+
};
|
|
897
|
+
setAttachedPhotos([...attachedPhotos, newPhoto]);
|
|
898
|
+
onChange && onChange(file);
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
document.body.removeChild(input);
|
|
902
|
+
});
|
|
903
|
+
input.style.display = "none";
|
|
904
|
+
document.body.appendChild(input);
|
|
905
|
+
input.click();
|
|
906
|
+
};
|
|
907
|
+
const deleteImage = (imageId) => {
|
|
908
|
+
const imageIndex = attachedPhotos.findIndex((image) => image.id === imageId);
|
|
909
|
+
if (imageIndex > -1) {
|
|
910
|
+
const item = attachedPhotos.splice(imageIndex, 1);
|
|
911
|
+
URL.revokeObjectURL(item[0].src);
|
|
912
|
+
setAttachedPhotos([...attachedPhotos]);
|
|
913
|
+
onDelete && onDelete(imageId);
|
|
914
|
+
}
|
|
915
|
+
};
|
|
916
|
+
const CameraComponent = React.useCallback(() => {
|
|
917
|
+
return /* @__PURE__ */ jsxRuntime.jsx(Attachement, { show: true, onAddPhoto: onClick, onRemovePhoto: deleteImage, photos: attachedPhotos, type });
|
|
918
|
+
}, [attachedPhotos, onClick, deleteImage, show]);
|
|
919
|
+
React.useEffect(() => {
|
|
920
|
+
return () => {
|
|
921
|
+
attachedPhotos.forEach((image) => {
|
|
922
|
+
URL.revokeObjectURL(image.src);
|
|
923
|
+
});
|
|
924
|
+
};
|
|
925
|
+
}, []);
|
|
926
|
+
return {
|
|
927
|
+
onClick,
|
|
928
|
+
getImage: findImage,
|
|
929
|
+
deleteImage,
|
|
930
|
+
attachedPhotos,
|
|
931
|
+
Attachment: CameraComponent
|
|
932
|
+
};
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
exports.Attachement = Attachement;
|
|
723
936
|
exports.DataTable = DataTable;
|
|
724
937
|
exports.FormDatePicker = FormDatePicker;
|
|
725
938
|
exports.FormSegmentGroup = FormSegmentGroup;
|
|
726
939
|
exports.FormSignature = FormSignature;
|
|
727
940
|
exports.FormTextField = FormTextField;
|
|
728
941
|
exports.StepIndicator = StepIndicator;
|
|
942
|
+
exports.resize = resize;
|
|
943
|
+
exports.useCamera = useCamera;
|
|
729
944
|
exports.useFormSignature = useFormSignature;
|
|
730
945
|
exports.useTable = useTable;
|
|
731
946
|
//# sourceMappingURL=index.cjs.js.map
|