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