@undefine-ui/design-system 2.11.0 → 2.12.0

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/README.md CHANGED
@@ -232,13 +232,13 @@ Ideal for splash screens, loading overlays, or brand storytelling moments.
232
232
 
233
233
  Everything is re-exported from `src/index.ts`. Key groups:
234
234
 
235
- | Group | Exports |
236
- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
237
- | Components | `CopyButton`, `HookForm` helpers (`Form`, `Field`, `RHFSwitch`, etc.), `Icon`, `Logo`, `LoadingScreen`, `Table`, `Upload` |
238
- | Hooks | `useBoolean`, `useCopyToClipboard`, `useEventListener`, `useLocalStorage`, `useResponsive`, `useSettings`, `useSetState`, `useScrollOffsetTop`, `usePopover` |
239
- | Contexts | `SettingsProvider`, `SettingsContext`, `defaultSettings`, `SettingsValueProps` |
240
- | Theme | `ThemeProvider`, `createTheme`, `colorSchemes`, `components`, `palette`, `radius`, `shadows`, `customSpacing`, utilities such as `varAlpha`, `bgGradient`, `hideScrollX/Y` |
241
- | Utilities | `changeCase` helpers, `formatNumber`, `fullname-utils`, generic `helpers` |
235
+ | Group | Exports |
236
+ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
237
+ | Components | `CopyButton`, `HookForm` helpers (`Form`, `Field`, `RHFSwitch`, etc.), `Icon`, `Logo`, `LoadingScreen`, `Table`, `Upload` |
238
+ | Hooks | `useBoolean`, `useCopyToClipboard`, `useEventListener`, `useLocalStorage`, `useResponsive`, `useSettings`, `useSetState`, `useScrollOffsetTop`, `usePopover`, `useCountdown` |
239
+ | Contexts | `SettingsProvider`, `SettingsContext`, `defaultSettings`, `SettingsValueProps` |
240
+ | Theme | `ThemeProvider`, `createTheme`, `colorSchemes`, `components`, `palette`, `radius`, `shadows`, `customSpacing`, utilities such as `varAlpha`, `bgGradient`, `hideScrollX/Y` |
241
+ | Utilities | `changeCase` helpers, `formatNumber`, `fullname-utils`, generic `helpers` |
242
242
 
243
243
  You can also import the theme pieces directly to compose your own MUI theme or to extend tokens in Storybook.
244
244
 
package/dist/index.cjs CHANGED
@@ -157,6 +157,8 @@ __export(index_exports, {
157
157
  updateCoreWithSettings: () => updateCoreWithSettings,
158
158
  useBoolean: () => useBoolean,
159
159
  useCopyToClipboard: () => useCopyToClipboard,
160
+ useCountdownDate: () => useCountdownDate,
161
+ useCountdownSeconds: () => useCountdownSeconds,
160
162
  useEventListener: () => useEventListener,
161
163
  useLocalStorage: () => useLocalStorage,
162
164
  usePopover: () => usePopover,
@@ -788,13 +790,89 @@ var useSetState = (initialState) => {
788
790
  return memoizedValue;
789
791
  };
790
792
 
791
- // src/hooks/useResponsive.ts
793
+ // src/hooks/useCountdown.tsx
792
794
  var import_react7 = require("react");
795
+ var useCountdownDate = (date) => {
796
+ const targetTime = typeof date === "number" ? date : typeof date === "string" ? new Date(date).valueOf() : date.valueOf();
797
+ const [countdown, setCountdown] = (0, import_react7.useState)({
798
+ days: "00",
799
+ hours: "00",
800
+ minutes: "00",
801
+ seconds: "00"
802
+ });
803
+ const setNewTime = (0, import_react7.useCallback)(() => {
804
+ const now = Date.now();
805
+ const distanceToNow = targetTime - now;
806
+ if (distanceToNow <= 0) {
807
+ setCountdown({
808
+ days: "00",
809
+ hours: "00",
810
+ minutes: "00",
811
+ seconds: "00"
812
+ });
813
+ return;
814
+ }
815
+ const getDays = Math.floor(distanceToNow / (1e3 * 60 * 60 * 24));
816
+ const getHours = `0${Math.floor(distanceToNow % (1e3 * 60 * 60 * 24) / (1e3 * 60 * 60))}`.slice(-2);
817
+ const getMinutes = `0${Math.floor(distanceToNow % (1e3 * 60 * 60) / (1e3 * 60))}`.slice(-2);
818
+ const getSeconds = `0${Math.floor(distanceToNow % (1e3 * 60) / 1e3)}`.slice(-2);
819
+ setCountdown({
820
+ days: getDays < 10 ? `0${getDays}` : `${getDays}`,
821
+ hours: getHours,
822
+ minutes: getMinutes,
823
+ seconds: getSeconds
824
+ });
825
+ }, [targetTime]);
826
+ (0, import_react7.useEffect)(() => {
827
+ setNewTime();
828
+ const interval = setInterval(setNewTime, 1e3);
829
+ return () => clearInterval(interval);
830
+ }, [setNewTime]);
831
+ return countdown;
832
+ };
833
+ var useCountdownSeconds = (initCountdown) => {
834
+ const [countdown, setCountdown] = (0, import_react7.useState)(initCountdown);
835
+ const intervalIdRef = (0, import_react7.useRef)(null);
836
+ const remainingSecondsRef = (0, import_react7.useRef)(initCountdown);
837
+ const startCountdown = (0, import_react7.useCallback)(() => {
838
+ if (intervalIdRef.current) {
839
+ clearInterval(intervalIdRef.current);
840
+ }
841
+ remainingSecondsRef.current = initCountdown;
842
+ setCountdown(initCountdown);
843
+ intervalIdRef.current = setInterval(() => {
844
+ remainingSecondsRef.current -= 1;
845
+ if (remainingSecondsRef.current <= 0) {
846
+ if (intervalIdRef.current) clearInterval(intervalIdRef.current);
847
+ setCountdown(0);
848
+ } else {
849
+ setCountdown(remainingSecondsRef.current);
850
+ }
851
+ }, 1e3);
852
+ }, [initCountdown]);
853
+ (0, import_react7.useEffect)(() => {
854
+ return () => {
855
+ if (intervalIdRef.current) {
856
+ clearInterval(intervalIdRef.current);
857
+ }
858
+ };
859
+ }, []);
860
+ const counting = countdown > 0 && countdown < initCountdown;
861
+ return {
862
+ counting,
863
+ countdown,
864
+ startCountdown,
865
+ setCountdown
866
+ };
867
+ };
868
+
869
+ // src/hooks/useResponsive.ts
870
+ var import_react8 = require("react");
793
871
  var import_useMediaQuery = __toESM(require("@mui/material/useMediaQuery"), 1);
794
872
  var import_styles = require("@mui/material/styles");
795
873
  var useResponsive = (query, start, end) => {
796
874
  const theme = (0, import_styles.useTheme)();
797
- const getQuery = (0, import_react7.useMemo)(() => {
875
+ const getQuery = (0, import_react8.useMemo)(() => {
798
876
  switch (query) {
799
877
  case "up":
800
878
  return theme.breakpoints.up(start);
@@ -813,7 +891,7 @@ var useResponsive = (query, start, end) => {
813
891
  };
814
892
  var useWidth = () => {
815
893
  const theme = (0, import_styles.useTheme)();
816
- const keys = (0, import_react7.useMemo)(() => [...theme.breakpoints.keys].reverse(), [theme]);
894
+ const keys = (0, import_react8.useMemo)(() => [...theme.breakpoints.keys].reverse(), [theme]);
817
895
  const width = keys.reduce((output, key) => {
818
896
  const matches = (0, import_useMediaQuery.default)(theme.breakpoints.up(key));
819
897
  return !output && matches ? key : output;
@@ -822,19 +900,19 @@ var useWidth = () => {
822
900
  };
823
901
 
824
902
  // src/hooks/useEventListener.ts
825
- var import_react8 = require("react");
826
- var useIsomorphicLayoutEffect = typeof window !== "undefined" ? import_react8.useLayoutEffect : import_react8.useEffect;
903
+ var import_react9 = require("react");
904
+ var useIsomorphicLayoutEffect = typeof window !== "undefined" ? import_react9.useLayoutEffect : import_react9.useEffect;
827
905
  var useEventListener = ({
828
906
  eventName,
829
907
  handler,
830
908
  element,
831
909
  options
832
910
  }) => {
833
- const savedHandler = (0, import_react8.useRef)(handler);
911
+ const savedHandler = (0, import_react9.useRef)(handler);
834
912
  useIsomorphicLayoutEffect(() => {
835
913
  savedHandler.current = handler;
836
914
  }, [handler]);
837
- (0, import_react8.useEffect)(() => {
915
+ (0, import_react9.useEffect)(() => {
838
916
  const targetElement = element?.current || window;
839
917
  if (!(targetElement && targetElement.addEventListener)) {
840
918
  return;
@@ -848,11 +926,11 @@ var useEventListener = ({
848
926
  };
849
927
 
850
928
  // src/hooks/useCopyToClipboard.ts
851
- var import_react9 = require("react");
929
+ var import_react10 = require("react");
852
930
  var useCopyToClipboard = () => {
853
- const [copiedText, setCopiedText] = (0, import_react9.useState)("");
854
- const [isCopied, setIsCopied] = (0, import_react9.useState)(false);
855
- const copy = (0, import_react9.useCallback)(
931
+ const [copiedText, setCopiedText] = (0, import_react10.useState)("");
932
+ const [isCopied, setIsCopied] = (0, import_react10.useState)(false);
933
+ const copy = (0, import_react10.useCallback)(
856
934
  async (text2) => {
857
935
  if (!navigator?.clipboard) {
858
936
  console.warn("Clipboard not supported");
@@ -872,7 +950,7 @@ var useCopyToClipboard = () => {
872
950
  },
873
951
  [setCopiedText]
874
952
  );
875
- const memoizedValue = (0, import_react9.useMemo)(
953
+ const memoizedValue = (0, import_react10.useMemo)(
876
954
  () => ({ copy, copiedText, isCopied }),
877
955
  [copy, copiedText, isCopied]
878
956
  );
@@ -880,11 +958,11 @@ var useCopyToClipboard = () => {
880
958
  };
881
959
 
882
960
  // src/hooks/useScrollOffsetTop.ts
883
- var import_react10 = require("react");
961
+ var import_react11 = require("react");
884
962
  var useScrollOffSetTop = (top = 0) => {
885
- const elementRef = (0, import_react10.useRef)(null);
886
- const [offsetTop, setOffsetTop] = (0, import_react10.useState)(false);
887
- const handleScrollChange = (0, import_react10.useCallback)(() => {
963
+ const elementRef = (0, import_react11.useRef)(null);
964
+ const [offsetTop, setOffsetTop] = (0, import_react11.useState)(false);
965
+ const handleScrollChange = (0, import_react11.useCallback)(() => {
888
966
  const scrollHeight = Math.round(window.scrollY);
889
967
  if (elementRef?.current) {
890
968
  const rect = elementRef.current.getBoundingClientRect();
@@ -894,14 +972,14 @@ var useScrollOffSetTop = (top = 0) => {
894
972
  setOffsetTop(scrollHeight > top);
895
973
  }
896
974
  }, [top]);
897
- (0, import_react10.useEffect)(() => {
975
+ (0, import_react11.useEffect)(() => {
898
976
  handleScrollChange();
899
977
  window.addEventListener("scroll", handleScrollChange, { passive: true });
900
978
  return () => {
901
979
  window.removeEventListener("scroll", handleScrollChange);
902
980
  };
903
981
  }, [handleScrollChange]);
904
- const memoizedValue = (0, import_react10.useMemo)(() => ({ elementRef, offsetTop }), [offsetTop]);
982
+ const memoizedValue = (0, import_react11.useMemo)(() => ({ elementRef, offsetTop }), [offsetTop]);
905
983
  return memoizedValue;
906
984
  };
907
985
 
@@ -6346,7 +6424,7 @@ var UploadProgress = ({ progress: progress2 = 20 }) => {
6346
6424
  };
6347
6425
 
6348
6426
  // src/components/Upload/components/MultiFilePreview.tsx
6349
- var import_react11 = require("react");
6427
+ var import_react12 = require("react");
6350
6428
  var import_Box9 = __toESM(require("@mui/material/Box"), 1);
6351
6429
  var import_IconButton3 = __toESM(require("@mui/material/IconButton"), 1);
6352
6430
 
@@ -6414,7 +6492,7 @@ var DeleteButton = ({ sx, ...rest }) => {
6414
6492
  // src/components/Upload/components/MultiFilePreview.tsx
6415
6493
  var import_jsx_runtime48 = require("react/jsx-runtime");
6416
6494
  var MultiFilePreview = ({ files, onRemove }) => {
6417
- const scrollRef = (0, import_react11.useRef)(null);
6495
+ const scrollRef = (0, import_react12.useRef)(null);
6418
6496
  const handleScroll = (direction) => {
6419
6497
  if (scrollRef.current) {
6420
6498
  const scrollAmount = 300;
@@ -6867,7 +6945,7 @@ var RHFUpload = ({ name, multiple, helperText, ...rest }) => {
6867
6945
  var import_react_hook_form4 = require("react-hook-form");
6868
6946
 
6869
6947
  // src/components/OTPInput/index.tsx
6870
- var import_react12 = require("react");
6948
+ var import_react13 = require("react");
6871
6949
  var import_styles37 = require("@mui/material/styles");
6872
6950
  var import_Box13 = __toESM(require("@mui/material/Box"), 1);
6873
6951
  var import_FormHelperText3 = __toESM(require("@mui/material/FormHelperText"), 1);
@@ -6877,8 +6955,8 @@ var import_jsx_runtime53 = require("react/jsx-runtime");
6877
6955
  var OTPInput = (props) => {
6878
6956
  const { length = 6, onChange, onComplete, error: error2, helperText, containerProps, ...rest } = props;
6879
6957
  const theme = (0, import_styles37.useTheme)();
6880
- const [otp, setOtp] = (0, import_react12.useState)(Array(length).fill(""));
6881
- const inputsRef = (0, import_react12.useRef)([]);
6958
+ const [otp, setOtp] = (0, import_react13.useState)(Array(length).fill(""));
6959
+ const inputsRef = (0, import_react13.useRef)([]);
6882
6960
  const handleChange = (value, index) => {
6883
6961
  if (!/^[0-9]$/.test(value) && value !== "") return;
6884
6962
  const newOtp = [...otp];
@@ -7592,6 +7670,8 @@ var SplashScreen = ({ portal, sx, ...rest }) => {
7592
7670
  updateCoreWithSettings,
7593
7671
  useBoolean,
7594
7672
  useCopyToClipboard,
7673
+ useCountdownDate,
7674
+ useCountdownSeconds,
7595
7675
  useEventListener,
7596
7676
  useLocalStorage,
7597
7677
  usePopover,