@ctlyst.id/internal-ui 3.4.6 → 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,11 +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
- noDrag: isDisabled
5815
+ noDrag: isDisabled,
5816
+ validator
5756
5817
  });
5757
5818
  const renderHelperText = () => {
5758
5819
  if (Array.isArray(helperText)) {
@@ -5873,13 +5934,10 @@ var Uploader = ({
5873
5934
  ]
5874
5935
  }
5875
5936
  ),
5876
- /* @__PURE__ */ createElement(
5937
+ /* @__PURE__ */ jsx66(
5877
5938
  "input",
5878
5939
  {
5879
5940
  ...getInputProps(),
5880
- key: Math.random(),
5881
- ref: inputRef,
5882
- accept: "image/*",
5883
5941
  "data-test-id": `CT_component_base-image-uploader_change-img${testId ? `_${testId}` : ""}`
5884
5942
  }
5885
5943
  ),
@@ -5890,10 +5948,7 @@ var Uploader = ({
5890
5948
  type: "button",
5891
5949
  size: "sm",
5892
5950
  variant: "outline",
5893
- onClick: () => {
5894
- var _a;
5895
- (_a = inputRef == null ? void 0 : inputRef.current) == null ? void 0 : _a.click();
5896
- },
5951
+ onClick: open,
5897
5952
  children: "Ubah Foto"
5898
5953
  }
5899
5954
  ) }),
@@ -5903,6 +5958,36 @@ var Uploader = ({
5903
5958
  };
5904
5959
  var uploader_default = Uploader;
5905
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
+
5906
5991
  // src/components/index.ts
5907
5992
  import {
5908
5993
  Avatar as Avatar2,
@@ -7599,7 +7684,7 @@ import { useMemo as useMemo5 } from "react";
7599
7684
 
7600
7685
  // src/provider/components/provider.tsx
7601
7686
  import axios from "axios";
7602
- 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";
7603
7688
  import { ToastContainer as ToastContainer2 } from "react-toastify";
7604
7689
  import { jsx as jsx67, jsxs as jsxs32 } from "react/jsx-runtime";
7605
7690
  var ProviderContext = createContext2({
@@ -7610,7 +7695,7 @@ var useInternalUI = () => {
7610
7695
  return { instance };
7611
7696
  };
7612
7697
  var Provider = ({ children, config: config2, requestInterceptors, responseInterceptors }) => {
7613
- const instanceRef = useRef4(axios.create(config2));
7698
+ const instanceRef = useRef3(axios.create(config2));
7614
7699
  useEffect5(() => {
7615
7700
  requestInterceptors == null ? void 0 : requestInterceptors.forEach((interceptor) => {
7616
7701
  instanceRef.current.interceptors.request.use(interceptor);
@@ -7760,6 +7845,7 @@ export {
7760
7845
  DrawerProps,
7761
7846
  DropdownIndicator,
7762
7847
  empty_state_default as EmptyState,
7848
+ error_code_default as ErrorCode,
7763
7849
  Fade,
7764
7850
  FadeProps,
7765
7851
  field_default as Field,
@@ -7983,12 +8069,15 @@ export {
7983
8069
  WrapProps,
7984
8070
  XMSLogo,
7985
8071
  createExtendTheme,
8072
+ defaultOnHandleRejections,
8073
+ dimensionValidator,
7986
8074
  extendTheme,
7987
8075
  forwardRef13 as forwardRef,
7988
8076
  getSelectAllCheckboxState,
7989
8077
  getTheme,
7990
8078
  id,
7991
8079
  isCellDisabled,
8080
+ isRatioEqual,
7992
8081
  selectStyles,
7993
8082
  theme4 as theme,
7994
8083
  themeSelect,