@xwadex/fesd-next 0.3.24 → 0.3.26

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.
@@ -1,48 +1,44 @@
1
1
  "use client";
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- import { useCallback, useMemo, memo, useEffect } from "react";
3
+ import { useCallback, useMemo, memo, useEffect, startTransition } from "react";
4
4
  import { AccordionsContext } from "./accordionsContext";
5
5
  import { useCollapse } from "../../hooks/index.js";
6
6
  const AccordionsBase = (props) => {
7
- const { as, children, defaultActive = false, active, time, ease, onInit, onChange, onExpand, onClose, ...othersProps } = props;
7
+ const { as, children, defaultActive = false, active, transDuration, transTiming, transMode, transDelay, onInit, onChange, onExpand, onClose, ...othersProps } = props;
8
8
  const RootComponent = as || "div";
9
9
  const isActive = typeof active == "boolean";
10
10
  const defaultOpen = isActive ? active : defaultActive;
11
- const { contentRef, setOpen, open, } = useCollapse({
11
+ const { setOpen, open, contentRef, } = useCollapse({
12
12
  defaultOpen,
13
- time,
14
- ease,
13
+ transDuration,
14
+ transTiming,
15
+ transMode,
16
+ transDelay,
15
17
  onInit,
16
18
  onChange,
17
19
  onExpand,
18
20
  onClose
19
21
  });
20
- const isExpand = isActive ? active : open;
22
+ const isOpen = isActive ? active : open;
21
23
  const setExpand = useCallback((state) => {
22
- const nextState = typeof state === "boolean" ? state : !isExpand;
23
- if (nextState === isExpand)
24
+ const nextOpen = typeof state === "boolean" ? state : !isOpen;
25
+ if (nextOpen === isOpen)
24
26
  return;
25
27
  if (!isActive)
26
- setOpen(nextState);
27
- setOpen(nextState);
28
- }, [isExpand, isActive, setOpen]);
28
+ return setOpen(nextOpen);
29
+ startTransition(() => setOpen(nextOpen));
30
+ }, [isOpen, isActive, setOpen]);
29
31
  useEffect(() => {
30
32
  if ((isActive && active) || defaultActive)
31
33
  setOpen(true);
32
34
  }, []);
33
35
  useEffect(() => {
34
- setOpen(isExpand);
35
- }, [isExpand]);
36
+ setOpen(isOpen);
37
+ }, [isOpen]);
36
38
  const contextValue = useMemo(() => ({
37
39
  contentRef,
38
- time,
39
- ease,
40
40
  setExpand
41
- }), [
42
- time,
43
- ease,
44
- setExpand
45
- ]);
41
+ }), [setExpand]);
46
42
  return (_jsx(AccordionsContext, { value: contextValue, children: _jsx(RootComponent, { ...othersProps, children: children }) }));
47
43
  };
48
44
  const Accordions = memo(AccordionsBase);
@@ -1,7 +1,7 @@
1
1
  export interface AccordionsContextType {
2
2
  time?: number;
3
3
  timingFunction?: string;
4
- contentRef: React.RefObject<null>;
4
+ contentRef: React.RefObject<HTMLDivElement | null>;
5
5
  defaultActive?: boolean;
6
6
  isActive?: boolean;
7
7
  setExpand: (state?: boolean) => void;
@@ -1,4 +1,3 @@
1
- export * from "./myComponents";
2
1
  export * from "./accordions";
3
2
  export * from "./dragResize";
4
3
  export * from "./dragSortable";
@@ -1,4 +1,3 @@
1
- export * from "./myComponents";
2
1
  export * from "./accordions";
3
2
  export * from "./dragResize";
4
3
  export * from "./dragSortable";
@@ -1,14 +1,16 @@
1
1
  export interface CollapseTypes {
2
2
  defaultOpen?: boolean;
3
- time?: number;
4
- ease?: string;
3
+ transDuration?: number;
4
+ transTiming?: string;
5
+ transMode?: "fade" | "normal";
6
+ transDelay?: number;
5
7
  onInit?: (isInit: boolean) => void;
6
8
  onChange?: (isOpen: boolean) => void;
7
9
  onExpand?: (isOpen: boolean) => void;
8
10
  onClose?: (isOpen: boolean) => void;
9
11
  }
10
- export declare function useCollapse({ defaultOpen, time, ease, onInit, onChange, onExpand, onClose, }: CollapseTypes): {
11
- contentRef: import("react").RefObject<null>;
12
- setOpen: import("react").Dispatch<import("react").SetStateAction<boolean>>;
12
+ export declare function useCollapse({ defaultOpen, transDuration, transTiming, transMode, transDelay, onInit, onChange, onExpand, onClose, }: CollapseTypes): {
13
+ setOpen: (state: boolean) => void;
14
+ contentRef: import("react").RefObject<HTMLDivElement | null>;
13
15
  open: boolean;
14
16
  };
@@ -1,55 +1,74 @@
1
1
  "use client";
2
- import { useCallback, useState, useRef, useEffect } from "react";
2
+ import { useCallback, useState, useRef, useEffect, startTransition } from "react";
3
3
  import { getDomTransTime, sleep } from "../utils/index.js";
4
- export function useCollapse({ defaultOpen = false, time = 0.3, ease = "Cubic-Bezier(0.05, 0.8, 0.1, 0.95)", onInit, onChange, onExpand, onClose, }) {
4
+ export function useCollapse({ defaultOpen = false, transDuration = 0.3, transTiming = "cubic-bezier(.24,0,0,.99)", transMode = "normal", transDelay = 0, onInit, onChange, onExpand, onClose, }) {
5
5
  const contentRef = useRef(null);
6
- const isMounted = useRef(false);
6
+ const isMountedRef = useRef(false);
7
+ const isAnimatingRef = useRef(false);
8
+ const nextOpenRef = useRef(null);
7
9
  const [open, setOpen] = useState(defaultOpen);
8
- const [isAnimating, setAnimating] = useState(false);
9
- const setExpandHeight = useCallback((height) => {
10
- if (!contentRef.current)
11
- return;
10
+ const setOpenState = useCallback((state) => {
11
+ if (!isAnimatingRef.current)
12
+ return setOpen(state);
13
+ nextOpenRef.current = state;
14
+ }, [open]);
15
+ const setExpandTransition = useCallback((events) => {
12
16
  const target = contentRef.current;
13
- const nextHeight = height == "none" ? height : height + "px";
14
- target.style.maxHeight = nextHeight;
17
+ if (!target)
18
+ return;
19
+ if (events === "start") {
20
+ target.style.maxHeight = target.scrollHeight + "px";
21
+ target.style.opacity = transMode == "fade" ? "1" : "";
22
+ }
23
+ if (events === "open") {
24
+ target.style.maxHeight = "none";
25
+ target.style.opacity = transMode == "fade" ? "1" : "";
26
+ }
27
+ if (events === "close") {
28
+ target.style.maxHeight = "0";
29
+ target.style.opacity = transMode == "fade" ? "0" : "";
30
+ }
15
31
  target.offsetHeight; // hack to force reflow
16
- }, []);
17
- const eventCallbacks = useCallback((state) => state
18
- ? onExpand?.(state)
19
- : onClose?.(state), [onExpand, onClose]);
32
+ }, [transMode]);
20
33
  const expandAnimate = useCallback(async (state) => {
21
- if (isAnimating || !contentRef?.current)
34
+ if (!contentRef?.current)
22
35
  return;
23
- setAnimating(true);
36
+ isAnimatingRef.current = true;
24
37
  onChange?.(state);
38
+ setExpandTransition("start");
25
39
  const target = contentRef.current;
26
- setExpandHeight(target.scrollHeight);
27
- await sleep(!state ? 0 : getDomTransTime(target));
28
- setExpandHeight(state ? "none" : "0");
29
- eventCallbacks(state);
30
- setAnimating(false);
31
- }, [isAnimating, onChange, eventCallbacks]);
32
- useEffect(() => {
33
- if (!contentRef.current)
40
+ await sleep(state ? getDomTransTime(target) : 0);
41
+ setExpandTransition(state ? "open" : "close");
42
+ state ? onExpand?.(state) : onClose?.(state);
43
+ isAnimatingRef.current = false;
44
+ const nextState = nextOpenRef.current;
45
+ if (nextState == null || nextState == state)
34
46
  return;
47
+ nextOpenRef.current = null;
48
+ setOpen(nextState);
49
+ }, [setExpandTransition, onChange, onExpand, onClose]);
50
+ useEffect(() => {
35
51
  const target = contentRef.current;
36
- target.style.transition = time + "s";
37
- target.style.transitionTimingFunction = ease;
38
- if (!defaultOpen)
52
+ if (!target)
39
53
  return;
40
- setExpandHeight(target.scrollHeight);
54
+ target.style.overflow = "hidden";
55
+ target.style.transition = transDuration + "s";
56
+ target.style.transitionDelay = transDelay + "s";
57
+ target.style.transitionTimingFunction = transTiming;
58
+ if (defaultOpen)
59
+ startTransition(() => setExpandTransition("start"));
41
60
  }, []);
42
61
  useEffect(() => {
43
- if (!isMounted.current) {
44
- isMounted.current = true;
62
+ if (!isMountedRef.current) {
63
+ isMountedRef.current = true;
45
64
  onInit?.(true);
46
65
  return;
47
66
  }
48
- expandAnimate(open);
67
+ startTransition(() => expandAnimate(open));
49
68
  }, [open]);
50
69
  return {
70
+ setOpen: setOpenState,
51
71
  contentRef,
52
- setOpen,
53
- open,
72
+ open
54
73
  };
55
74
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xwadex/fesd-next",
3
- "version": "0.3.24",
3
+ "version": "0.3.26",
4
4
  "private": false,
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,2 +0,0 @@
1
- declare const MyComponent: () => import("react/jsx-runtime").JSX.Element;
2
- export default MyComponent;
@@ -1,4 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import styles from './MyComponent.module.scss';
3
- const MyComponent = () => (_jsx("div", { className: styles.container, children: "Hello World" }));
4
- export default MyComponent;
@@ -1,3 +0,0 @@
1
- .container {
2
- color: red;
3
- }
@@ -1 +0,0 @@
1
- export { default as MyComponent } from './MyComponent';
@@ -1 +0,0 @@
1
- export { default as MyComponent } from './MyComponent';