@ctlyst.id/internal-ui 3.4.5 → 3.5.0

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.mjs CHANGED
@@ -1289,6 +1289,7 @@ var data_table_default = DataTable;
1289
1289
  import { FormControl as FormControl3, FormErrorMessage as FormErrorMessage3, FormHelperText as FormHelperText3, IconButton as IconButton4 } from "@chakra-ui/react";
1290
1290
  import { cx as cx8 } from "@chakra-ui/shared-utils";
1291
1291
  import { Calendar, Close as Close3 } from "@ctlyst.id/internal-icon";
1292
+ import { offset } from "@floating-ui/react";
1292
1293
  import ReactDatePicker from "react-datepicker";
1293
1294
 
1294
1295
  // ../../node_modules/.pnpm/date-fns@3.6.0/node_modules/date-fns/locale/_lib/buildFormatLongFn.mjs
@@ -1941,16 +1942,10 @@ var Styles = ({ showHeader }) => {
1941
1942
  .react-datepicker-popper {
1942
1943
  z-index: 1;
1943
1944
  }
1944
- .react-datepicker-popper[data-placement^=bottom] {
1945
- padding-top: 10px;
1946
- }
1947
1945
  .react-datepicker-popper[data-placement=bottom-end] .react-datepicker__triangle, .react-datepicker-popper[data-placement=top-end] .react-datepicker__triangle {
1948
1946
  left: auto;
1949
1947
  right: 50px;
1950
1948
  }
1951
- .react-datepicker-popper[data-placement^=top] {
1952
- padding-bottom: 10px;
1953
- }
1954
1949
  .react-datepicker-popper[data-placement^=right] {
1955
1950
  padding-left: 8px;
1956
1951
  }
@@ -2757,6 +2752,20 @@ var Datepicker = ({
2757
2752
  id: id2,
2758
2753
  name,
2759
2754
  selected,
2755
+ popperModifiers: [
2756
+ offset(4),
2757
+ {
2758
+ name: "placement",
2759
+ fn: (state) => {
2760
+ const { placement, y } = state;
2761
+ return {
2762
+ ...state,
2763
+ y: placement.startsWith("bottom") ? y - 10 : y + 10
2764
+ // condition for auto placement
2765
+ };
2766
+ }
2767
+ }
2768
+ ],
2760
2769
  customInput: /* @__PURE__ */ jsx27(
2761
2770
  input_field_default,
2762
2771
  {
@@ -5638,7 +5647,7 @@ import {
5638
5647
  UnorderedList as UnorderedList2
5639
5648
  } from "@chakra-ui/react";
5640
5649
  import { Close as X, Plus } from "@ctlyst.id/internal-icon";
5641
- import { useCallback as useCallback2, useEffect as useEffect4, useRef as useRef3, useState as useState5 } from "react";
5650
+ import { useCallback as useCallback2, useEffect as useEffect4, useState as useState5 } from "react";
5642
5651
  import { useDropzone } from "react-dropzone";
5643
5652
 
5644
5653
  // src/components/uploader/constants.ts
@@ -5667,9 +5676,48 @@ var concatList = (list) => {
5667
5676
  };
5668
5677
  var formatValidationMessage = (extension) => `Foto harus dalam format ${concatList(extension.map((ext) => `.${ext}`))}.`;
5669
5678
 
5679
+ // src/components/uploader/utils/error-code.ts
5680
+ var ErrorCode = /* @__PURE__ */ ((ErrorCode2) => {
5681
+ ErrorCode2["FileInvalidType"] = "file-invalid-type";
5682
+ ErrorCode2["FileTooLarge"] = "file-too-large";
5683
+ ErrorCode2["FileTooSmall"] = "file-too-small";
5684
+ ErrorCode2["TooManyFiles"] = "too-many-files";
5685
+ ErrorCode2["FileInvalidDimension"] = "file-invalid-dimension";
5686
+ return ErrorCode2;
5687
+ })(ErrorCode || {});
5688
+ var error_code_default = ErrorCode;
5689
+
5690
+ // src/components/uploader/utils/handler.ts
5691
+ var defaultOnHandleRejections = (fileRejection, config2, handleRejection) => {
5692
+ var _a, _b, _c, _d;
5693
+ const { file, errors: errors3 } = fileRejection[0];
5694
+ switch (errors3[0].code) {
5695
+ case error_code_default.FileInvalidType: {
5696
+ const fileFormat = file.name.split(".").pop();
5697
+ if (!(config2 == null ? void 0 : config2.acceptFormat)) return;
5698
+ if (!((_a = config2 == null ? void 0 : config2.acceptFormat) == null ? void 0 : _a.validate.includes(fileFormat))) {
5699
+ handleRejection(
5700
+ (_d = (_b = config2.acceptFormat) == null ? void 0 : _b.message) != null ? _d : formatValidationMessage((_c = config2.acceptFormat) == null ? void 0 : _c.validate),
5701
+ file,
5702
+ null
5703
+ );
5704
+ }
5705
+ break;
5706
+ }
5707
+ case error_code_default.FileTooLarge: {
5708
+ if (config2.maxFileSize) {
5709
+ handleRejection(config2.maxFileSize.message, file, null);
5710
+ }
5711
+ break;
5712
+ }
5713
+ default:
5714
+ handleRejection(errors3[0].message, file, null);
5715
+ break;
5716
+ }
5717
+ };
5718
+
5670
5719
  // src/components/uploader/components/uploader.tsx
5671
5720
  import { Fragment as Fragment12, jsx as jsx66, jsxs as jsxs31 } from "react/jsx-runtime";
5672
- import { createElement } from "react";
5673
5721
  var Uploader = ({
5674
5722
  onHandleUploadFile,
5675
5723
  onHandleRejections,
@@ -5696,9 +5744,9 @@ var Uploader = ({
5696
5744
  errorText,
5697
5745
  isShowReupload = true,
5698
5746
  size: size2 = "lg",
5747
+ validatorExt,
5699
5748
  ...props
5700
5749
  }) => {
5701
- const inputRef = useRef3(null);
5702
5750
  const [filePreview, setFilePreview] = useState5();
5703
5751
  const toast2 = useToast();
5704
5752
  const handleRejection = useCallback2(
@@ -5713,33 +5761,21 @@ var Uploader = ({
5713
5761
  // eslint-disable-next-line react-hooks/exhaustive-deps
5714
5762
  [onHandleRejections]
5715
5763
  );
5716
- const onDrop = useCallback2(
5764
+ const onDropAccepted = useCallback2(
5717
5765
  (files) => {
5718
- var _a;
5719
5766
  const file = files[0];
5720
- const fileFormat = file.name.split(".").pop();
5721
- if (!(acceptFormat == null ? void 0 : acceptFormat.validate.includes(fileFormat))) {
5722
- return handleRejection((_a = acceptFormat.message) != null ? _a : formatValidationMessage(acceptFormat.validate), file, null);
5723
- }
5724
5767
  const imageUrl = URL.createObjectURL(file);
5725
5768
  const img = new Image();
5726
5769
  img.src = imageUrl;
5727
5770
  img.onload = () => {
5728
- var _a2;
5729
5771
  const imgWidth = img.width;
5730
5772
  const imgheight = img.height;
5731
5773
  if (customValidation && customValidation(file, img) !== null) {
5732
5774
  return handleRejection(customValidation(file, img), file, img);
5733
5775
  }
5734
- if (!acceptFormat.validate.includes(fileFormat)) {
5735
- return handleRejection((_a2 = acceptFormat.message) != null ? _a2 : formatValidationMessage(acceptFormat.validate), file, img);
5736
- }
5737
5776
  if (dimension && (imgWidth !== dimension.validate[0] || imgheight !== dimension.validate[1])) {
5738
5777
  return handleRejection(dimension.message, file, img);
5739
5778
  }
5740
- if (maxFileSize && file.size > maxFileSize.validate) {
5741
- return handleRejection(maxFileSize.message, file, null);
5742
- }
5743
5779
  onHandleUploadFile == null ? void 0 : onHandleUploadFile(file, img);
5744
5780
  setFilePreview(URL.createObjectURL(file));
5745
5781
  return null;
@@ -5748,12 +5784,36 @@ var Uploader = ({
5748
5784
  },
5749
5785
  [acceptFormat, customValidation, dimension, handleRejection, maxFileSize, onHandleUploadFile]
5750
5786
  );
5751
- const { getRootProps, getInputProps, isDragActive, acceptedFiles } = useDropzone({
5752
- onDrop,
5787
+ const onDropRejected = useCallback2((fileRejections) => {
5788
+ defaultOnHandleRejections(fileRejections, { acceptFormat, maxFileSize }, handleRejection);
5789
+ }, []);
5790
+ const validator = useCallback2(
5791
+ (file) => {
5792
+ if (validatorExt) {
5793
+ const result = [];
5794
+ validatorExt.forEach((validatorFn) => {
5795
+ const error = validatorFn(file);
5796
+ if (Array.isArray(error)) {
5797
+ result.push(...error);
5798
+ } else if (error) result.push(error);
5799
+ });
5800
+ return result;
5801
+ }
5802
+ return null;
5803
+ },
5804
+ [validatorExt]
5805
+ );
5806
+ const { getRootProps, getInputProps, isDragActive, acceptedFiles, open } = useDropzone({
5807
+ onDropAccepted,
5808
+ onDropRejected,
5809
+ accept: {
5810
+ "image/*": [...acceptFormat.validate]
5811
+ },
5753
5812
  maxFiles: 1,
5813
+ maxSize: maxFileSize == null ? void 0 : maxFileSize.validate,
5754
5814
  noClick: isDisabled,
5755
- disabled: !!filePreview,
5756
- noDrag: isDisabled
5815
+ noDrag: isDisabled,
5816
+ validator
5757
5817
  });
5758
5818
  const renderHelperText = () => {
5759
5819
  if (Array.isArray(helperText)) {
@@ -5855,66 +5915,79 @@ var Uploader = ({
5855
5915
  )
5856
5916
  }
5857
5917
  ) }),
5858
- !filePreview && /* @__PURE__ */ jsxs31(Fragment12, { children: [
5859
- /* @__PURE__ */ jsx66(
5860
- "input",
5861
- {
5862
- "data-test-id": `CT_component_base-image-uploader_input-file${testId ? `_${testId}` : ""}`,
5863
- ...getInputProps()
5864
- }
5865
- ),
5866
- isDragActive ? /* @__PURE__ */ jsx66(Text18, { children: dragActiveText != null ? dragActiveText : messages.dragActive }) : /* @__PURE__ */ jsxs31(Flex19, { gap: 2, flexDirection: "column", alignItems: "center", color: isError ? "danger.500" : color, children: [
5867
- size2 === "sm" && /* @__PURE__ */ jsx66(Plus, { size: 6, color }),
5868
- /* @__PURE__ */ jsxs31(Box30, { children: [
5869
- !filePreview && /* @__PURE__ */ jsx66(
5870
- Heading2,
5871
- {
5872
- fontWeight: "400",
5873
- fontSize: size2 === "sm" ? "text.md" : "text.xl",
5874
- mb: size2 === "sm" ? "0" : "2",
5875
- textAlign: "center",
5876
- children: uploadFileText && size2 === "lg" ? uploadFileText : "Upload"
5877
- }
5878
- ),
5879
- size2 === "lg" && /* @__PURE__ */ jsx66(Text18, { fontSize: 12, children: filePreview ? dragReplaceText != null ? dragReplaceText : messages.dragReplace : dragInActiveText != null ? dragInActiveText : messages.dragInActive })
5880
- ] })
5918
+ !filePreview && /* @__PURE__ */ jsx66(Fragment12, { children: isDragActive ? /* @__PURE__ */ jsx66(Text18, { children: dragActiveText != null ? dragActiveText : messages.dragActive }) : /* @__PURE__ */ jsxs31(Flex19, { gap: 2, flexDirection: "column", alignItems: "center", color: isError ? "danger.500" : color, children: [
5919
+ size2 === "sm" && /* @__PURE__ */ jsx66(Plus, { size: 6, color }),
5920
+ /* @__PURE__ */ jsxs31(Box30, { children: [
5921
+ !filePreview && /* @__PURE__ */ jsx66(
5922
+ Heading2,
5923
+ {
5924
+ fontWeight: "400",
5925
+ fontSize: size2 === "sm" ? "text.md" : "text.xl",
5926
+ mb: size2 === "sm" ? "0" : "2",
5927
+ textAlign: "center",
5928
+ children: uploadFileText && size2 === "lg" ? uploadFileText : "Upload"
5929
+ }
5930
+ ),
5931
+ size2 === "lg" && /* @__PURE__ */ jsx66(Text18, { fontSize: 12, children: filePreview ? dragReplaceText != null ? dragReplaceText : messages.dragReplace : dragInActiveText != null ? dragInActiveText : messages.dragInActive })
5881
5932
  ] })
5882
- ] })
5933
+ ] }) })
5883
5934
  ]
5884
5935
  }
5885
5936
  ),
5886
- filePreview && !isSmall && /* @__PURE__ */ jsxs31(Flex19, { align: "center", justify: "center", my: 2, children: [
5887
- /* @__PURE__ */ createElement(
5888
- "input",
5889
- {
5890
- ...getInputProps(),
5891
- key: Math.random(),
5892
- ref: inputRef,
5893
- accept: "image/*",
5894
- "data-test-id": `CT_component_base-image-uploader_change-img${testId ? `_${testId}` : ""}`
5895
- }
5896
- ),
5897
- isShowReupload && /* @__PURE__ */ jsx66(
5898
- Button7,
5899
- {
5900
- "data-test-id": `CT_component_base-image-uploader_change-img-btn${testId ? `_${testId}` : ""}`,
5901
- type: "button",
5902
- size: "sm",
5903
- variant: "outline",
5904
- onClick: () => {
5905
- var _a;
5906
- (_a = inputRef == null ? void 0 : inputRef.current) == null ? void 0 : _a.click();
5907
- },
5908
- children: "Ubah Foto"
5909
- }
5910
- )
5911
- ] }),
5937
+ /* @__PURE__ */ jsx66(
5938
+ "input",
5939
+ {
5940
+ ...getInputProps(),
5941
+ "data-test-id": `CT_component_base-image-uploader_change-img${testId ? `_${testId}` : ""}`
5942
+ }
5943
+ ),
5944
+ filePreview && !isSmall && /* @__PURE__ */ jsx66(Flex19, { align: "center", justify: "center", my: 2, children: isShowReupload && /* @__PURE__ */ jsx66(
5945
+ Button7,
5946
+ {
5947
+ "data-test-id": `CT_component_base-image-uploader_change-img-btn${testId ? `_${testId}` : ""}`,
5948
+ type: "button",
5949
+ size: "sm",
5950
+ variant: "outline",
5951
+ onClick: open,
5952
+ children: "Ubah Foto"
5953
+ }
5954
+ ) }),
5912
5955
  renderErrorText(errorText),
5913
5956
  renderHelperText()
5914
5957
  ] });
5915
5958
  };
5916
5959
  var uploader_default = Uploader;
5917
5960
 
5961
+ // src/components/uploader/utils/is-ratio-equal.ts
5962
+ var isRatioEqual = (base, img) => {
5963
+ const baseRatio = (base.width / base.height).toFixed(2);
5964
+ const imgRatio = (img.width / img.height).toFixed(2);
5965
+ return baseRatio === imgRatio;
5966
+ };
5967
+
5968
+ // src/components/uploader/components/validator.ts
5969
+ var dimensionValidator = (dimension, message) => {
5970
+ return (file) => {
5971
+ const imageUrl = URL.createObjectURL(file);
5972
+ const img = new Image();
5973
+ img.src = imageUrl;
5974
+ img.onload = () => {
5975
+ };
5976
+ const isRatioValid = isRatioEqual(
5977
+ { width: dimension[0], height: dimension[1] },
5978
+ { width: img.width, height: img.height }
5979
+ );
5980
+ console.log("log", isRatioValid);
5981
+ if (isRatioValid) {
5982
+ return null;
5983
+ }
5984
+ return {
5985
+ code: error_code_default.FileInvalidDimension,
5986
+ message: message != null ? message : "File has invalid dimension"
5987
+ };
5988
+ };
5989
+ };
5990
+
5918
5991
  // src/components/index.ts
5919
5992
  import {
5920
5993
  Avatar as Avatar2,
@@ -7611,7 +7684,7 @@ import { useMemo as useMemo5 } from "react";
7611
7684
 
7612
7685
  // src/provider/components/provider.tsx
7613
7686
  import axios from "axios";
7614
- import { createContext as createContext2, useContext, useEffect as useEffect5, useMemo as useMemo4, useRef as useRef4 } from "react";
7687
+ import { createContext as createContext2, useContext, useEffect as useEffect5, useMemo as useMemo4, useRef as useRef3 } from "react";
7615
7688
  import { ToastContainer as ToastContainer2 } from "react-toastify";
7616
7689
  import { jsx as jsx67, jsxs as jsxs32 } from "react/jsx-runtime";
7617
7690
  var ProviderContext = createContext2({
@@ -7622,7 +7695,7 @@ var useInternalUI = () => {
7622
7695
  return { instance };
7623
7696
  };
7624
7697
  var Provider = ({ children, config: config2, requestInterceptors, responseInterceptors }) => {
7625
- const instanceRef = useRef4(axios.create(config2));
7698
+ const instanceRef = useRef3(axios.create(config2));
7626
7699
  useEffect5(() => {
7627
7700
  requestInterceptors == null ? void 0 : requestInterceptors.forEach((interceptor) => {
7628
7701
  instanceRef.current.interceptors.request.use(interceptor);
@@ -7772,6 +7845,7 @@ export {
7772
7845
  DrawerProps,
7773
7846
  DropdownIndicator,
7774
7847
  empty_state_default as EmptyState,
7848
+ error_code_default as ErrorCode,
7775
7849
  Fade,
7776
7850
  FadeProps,
7777
7851
  field_default as Field,
@@ -7995,12 +8069,15 @@ export {
7995
8069
  WrapProps,
7996
8070
  XMSLogo,
7997
8071
  createExtendTheme,
8072
+ defaultOnHandleRejections,
8073
+ dimensionValidator,
7998
8074
  extendTheme,
7999
8075
  forwardRef13 as forwardRef,
8000
8076
  getSelectAllCheckboxState,
8001
8077
  getTheme,
8002
8078
  id,
8003
8079
  isCellDisabled,
8080
+ isRatioEqual,
8004
8081
  selectStyles,
8005
8082
  theme4 as theme,
8006
8083
  themeSelect,