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