@creopse/react 0.0.2 → 0.0.4

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.cjs CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const React = require("react");
4
+ const reactDom = require("react-dom");
4
5
  function _interopNamespaceDefault(e) {
5
6
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
6
7
  if (e) {
@@ -7781,5 +7782,250 @@ const CustomTransition = ({
7781
7782
  }
7782
7783
  );
7783
7784
  };
7785
+ const MountedTeleport = ({
7786
+ to,
7787
+ children,
7788
+ disabled = false
7789
+ }) => {
7790
+ const [isMounted, setIsMounted] = React.useState(false);
7791
+ const [targetElement, setTargetElement] = React.useState(null);
7792
+ React.useEffect(() => {
7793
+ setIsMounted(true);
7794
+ return () => {
7795
+ setIsMounted(false);
7796
+ };
7797
+ }, []);
7798
+ React.useEffect(() => {
7799
+ if (!isMounted || disabled) {
7800
+ setTargetElement(null);
7801
+ return;
7802
+ }
7803
+ let target = null;
7804
+ if (typeof to === "string") {
7805
+ target = document.querySelector(to);
7806
+ if (!target) {
7807
+ console.warn(
7808
+ `MountedTeleport: Target element not found for selector "${to}"`
7809
+ );
7810
+ setTargetElement(null);
7811
+ return;
7812
+ }
7813
+ } else if (to instanceof HTMLElement) {
7814
+ target = to;
7815
+ } else {
7816
+ console.warn(
7817
+ "MountedTeleport: Invalid target type. Expected string selector or HTMLElement."
7818
+ );
7819
+ setTargetElement(null);
7820
+ return;
7821
+ }
7822
+ setTargetElement(target);
7823
+ }, [to, isMounted, disabled]);
7824
+ if (!isMounted || disabled || !targetElement) {
7825
+ return null;
7826
+ }
7827
+ return reactDom.createPortal(children, targetElement);
7828
+ };
7829
+ const ReadMore = ({
7830
+ moreStr = "Read more",
7831
+ lessStr = "Read less",
7832
+ link = "#",
7833
+ maxChars = 100,
7834
+ text,
7835
+ className = "",
7836
+ linkClassName = ""
7837
+ }) => {
7838
+ const [isExpanded, setIsExpanded] = React.useState(false);
7839
+ const formattedText = () => {
7840
+ if (!isExpanded && text.length > maxChars) {
7841
+ return text.substring(0, maxChars).trim() + "...";
7842
+ }
7843
+ return text;
7844
+ };
7845
+ const handleToggle = (event) => {
7846
+ event.preventDefault();
7847
+ setIsExpanded(!isExpanded);
7848
+ };
7849
+ if (!text) {
7850
+ return null;
7851
+ }
7852
+ const shouldShowToggle = text.length > maxChars;
7853
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className, children: [
7854
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: formattedText() }),
7855
+ shouldShowToggle && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
7856
+ " ",
7857
+ !isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(
7858
+ "a",
7859
+ {
7860
+ href: link,
7861
+ onClick: handleToggle,
7862
+ className: linkClassName,
7863
+ role: "button",
7864
+ tabIndex: 0,
7865
+ onKeyDown: (e) => {
7866
+ if (e.key === "Enter" || e.key === " ") {
7867
+ e.preventDefault();
7868
+ setIsExpanded(true);
7869
+ }
7870
+ },
7871
+ children: moreStr
7872
+ }
7873
+ ) : lessStr && /* @__PURE__ */ jsxRuntimeExports.jsx(
7874
+ "a",
7875
+ {
7876
+ href: link,
7877
+ onClick: handleToggle,
7878
+ className: linkClassName,
7879
+ role: "button",
7880
+ tabIndex: 0,
7881
+ onKeyDown: (e) => {
7882
+ if (e.key === "Enter" || e.key === " ") {
7883
+ e.preventDefault();
7884
+ setIsExpanded(false);
7885
+ }
7886
+ },
7887
+ children: lessStr
7888
+ }
7889
+ )
7890
+ ] })
7891
+ ] });
7892
+ };
7893
+ const StickyBottom = ({
7894
+ bottom = 0,
7895
+ zIndex = 1,
7896
+ className = "",
7897
+ children = /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Sticky Bottom" })
7898
+ }) => {
7899
+ const elRef = React.useRef(null);
7900
+ const [isSticky, setIsSticky] = React.useState(false);
7901
+ const [width, setWidth] = React.useState("auto");
7902
+ const [height, setHeight] = React.useState("auto");
7903
+ React.useEffect(() => {
7904
+ const handleScroll = () => {
7905
+ if (!elRef.current) return;
7906
+ const rect = elRef.current.getBoundingClientRect();
7907
+ const viewportHeight = window.innerHeight;
7908
+ const shouldStick = rect.bottom <= viewportHeight - bottom;
7909
+ if (shouldStick && !isSticky) {
7910
+ setWidth(rect.width + "px");
7911
+ setHeight(rect.height + "px");
7912
+ setIsSticky(true);
7913
+ } else if (!shouldStick && isSticky) {
7914
+ setIsSticky(false);
7915
+ setWidth("auto");
7916
+ }
7917
+ };
7918
+ const handleResize = () => {
7919
+ if (!isSticky && elRef.current) {
7920
+ const rect = elRef.current.getBoundingClientRect();
7921
+ setHeight(rect.height + "px");
7922
+ }
7923
+ };
7924
+ if (elRef.current) {
7925
+ const rect = elRef.current.getBoundingClientRect();
7926
+ setHeight(rect.height + "px");
7927
+ }
7928
+ window.addEventListener("scroll", handleScroll);
7929
+ window.addEventListener("resize", handleResize);
7930
+ handleScroll();
7931
+ return () => {
7932
+ window.removeEventListener("scroll", handleScroll);
7933
+ window.removeEventListener("resize", handleResize);
7934
+ };
7935
+ }, [bottom, isSticky]);
7936
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
7937
+ "div",
7938
+ {
7939
+ ref: elRef,
7940
+ style: {
7941
+ height: isSticky ? height : "auto",
7942
+ zIndex
7943
+ },
7944
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
7945
+ "div",
7946
+ {
7947
+ className,
7948
+ style: {
7949
+ position: isSticky ? "fixed" : "static",
7950
+ bottom: isSticky ? `${bottom}px` : "auto",
7951
+ width: isSticky ? width : "auto",
7952
+ zIndex
7953
+ },
7954
+ children
7955
+ }
7956
+ )
7957
+ }
7958
+ );
7959
+ };
7960
+ const StickyTop = ({
7961
+ top = 0,
7962
+ zIndex = 1,
7963
+ className = "",
7964
+ children = /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Sticky Top" })
7965
+ }) => {
7966
+ const elRef = React.useRef(null);
7967
+ const [isSticky, setIsSticky] = React.useState(false);
7968
+ const [width, setWidth] = React.useState("auto");
7969
+ const [height, setHeight] = React.useState("auto");
7970
+ React.useEffect(() => {
7971
+ const handleScroll = () => {
7972
+ if (!elRef.current) return;
7973
+ const rect = elRef.current.getBoundingClientRect();
7974
+ const shouldStick = rect.top <= top;
7975
+ if (shouldStick && !isSticky) {
7976
+ setWidth(rect.width + "px");
7977
+ setHeight(rect.height + "px");
7978
+ setIsSticky(true);
7979
+ } else if (!shouldStick && isSticky) {
7980
+ setIsSticky(false);
7981
+ setWidth("auto");
7982
+ }
7983
+ };
7984
+ const handleResize = () => {
7985
+ if (!isSticky && elRef.current) {
7986
+ const rect = elRef.current.getBoundingClientRect();
7987
+ setHeight(rect.height + "px");
7988
+ }
7989
+ };
7990
+ if (elRef.current) {
7991
+ const rect = elRef.current.getBoundingClientRect();
7992
+ setHeight(rect.height + "px");
7993
+ }
7994
+ window.addEventListener("scroll", handleScroll);
7995
+ window.addEventListener("resize", handleResize);
7996
+ handleScroll();
7997
+ return () => {
7998
+ window.removeEventListener("scroll", handleScroll);
7999
+ window.removeEventListener("resize", handleResize);
8000
+ };
8001
+ }, [top, isSticky]);
8002
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
8003
+ "div",
8004
+ {
8005
+ ref: elRef,
8006
+ style: {
8007
+ height: isSticky ? height : "auto",
8008
+ zIndex
8009
+ },
8010
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
8011
+ "div",
8012
+ {
8013
+ className,
8014
+ style: {
8015
+ position: isSticky ? "fixed" : "static",
8016
+ top: isSticky ? `${top}px` : "auto",
8017
+ width: isSticky ? width : "auto",
8018
+ zIndex
8019
+ },
8020
+ children
8021
+ }
8022
+ )
8023
+ }
8024
+ );
8025
+ };
7784
8026
  exports.AsyncImg = AsyncImg;
7785
8027
  exports.CustomTransition = CustomTransition;
8028
+ exports.MountedTeleport = MountedTeleport;
8029
+ exports.ReadMore = ReadMore;
8030
+ exports.StickyBottom = StickyBottom;
8031
+ exports.StickyTop = StickyTop;
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- var CreopseReactToolkit = function(exports, React2) {
1
+ var CreopseReactToolkit = function(exports, React2, reactDom) {
2
2
  "use strict";
3
3
  function _interopNamespaceDefault(e) {
4
4
  const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
@@ -7780,8 +7780,253 @@ var CreopseReactToolkit = function(exports, React2) {
7780
7780
  }
7781
7781
  );
7782
7782
  };
7783
+ const MountedTeleport = ({
7784
+ to,
7785
+ children,
7786
+ disabled = false
7787
+ }) => {
7788
+ const [isMounted, setIsMounted] = React2.useState(false);
7789
+ const [targetElement, setTargetElement] = React2.useState(null);
7790
+ React2.useEffect(() => {
7791
+ setIsMounted(true);
7792
+ return () => {
7793
+ setIsMounted(false);
7794
+ };
7795
+ }, []);
7796
+ React2.useEffect(() => {
7797
+ if (!isMounted || disabled) {
7798
+ setTargetElement(null);
7799
+ return;
7800
+ }
7801
+ let target = null;
7802
+ if (typeof to === "string") {
7803
+ target = document.querySelector(to);
7804
+ if (!target) {
7805
+ console.warn(
7806
+ `MountedTeleport: Target element not found for selector "${to}"`
7807
+ );
7808
+ setTargetElement(null);
7809
+ return;
7810
+ }
7811
+ } else if (to instanceof HTMLElement) {
7812
+ target = to;
7813
+ } else {
7814
+ console.warn(
7815
+ "MountedTeleport: Invalid target type. Expected string selector or HTMLElement."
7816
+ );
7817
+ setTargetElement(null);
7818
+ return;
7819
+ }
7820
+ setTargetElement(target);
7821
+ }, [to, isMounted, disabled]);
7822
+ if (!isMounted || disabled || !targetElement) {
7823
+ return null;
7824
+ }
7825
+ return reactDom.createPortal(children, targetElement);
7826
+ };
7827
+ const ReadMore = ({
7828
+ moreStr = "Read more",
7829
+ lessStr = "Read less",
7830
+ link = "#",
7831
+ maxChars = 100,
7832
+ text,
7833
+ className = "",
7834
+ linkClassName = ""
7835
+ }) => {
7836
+ const [isExpanded, setIsExpanded] = React2.useState(false);
7837
+ const formattedText = () => {
7838
+ if (!isExpanded && text.length > maxChars) {
7839
+ return text.substring(0, maxChars).trim() + "...";
7840
+ }
7841
+ return text;
7842
+ };
7843
+ const handleToggle = (event) => {
7844
+ event.preventDefault();
7845
+ setIsExpanded(!isExpanded);
7846
+ };
7847
+ if (!text) {
7848
+ return null;
7849
+ }
7850
+ const shouldShowToggle = text.length > maxChars;
7851
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className, children: [
7852
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: formattedText() }),
7853
+ shouldShowToggle && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
7854
+ " ",
7855
+ !isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(
7856
+ "a",
7857
+ {
7858
+ href: link,
7859
+ onClick: handleToggle,
7860
+ className: linkClassName,
7861
+ role: "button",
7862
+ tabIndex: 0,
7863
+ onKeyDown: (e) => {
7864
+ if (e.key === "Enter" || e.key === " ") {
7865
+ e.preventDefault();
7866
+ setIsExpanded(true);
7867
+ }
7868
+ },
7869
+ children: moreStr
7870
+ }
7871
+ ) : lessStr && /* @__PURE__ */ jsxRuntimeExports.jsx(
7872
+ "a",
7873
+ {
7874
+ href: link,
7875
+ onClick: handleToggle,
7876
+ className: linkClassName,
7877
+ role: "button",
7878
+ tabIndex: 0,
7879
+ onKeyDown: (e) => {
7880
+ if (e.key === "Enter" || e.key === " ") {
7881
+ e.preventDefault();
7882
+ setIsExpanded(false);
7883
+ }
7884
+ },
7885
+ children: lessStr
7886
+ }
7887
+ )
7888
+ ] })
7889
+ ] });
7890
+ };
7891
+ const StickyBottom = ({
7892
+ bottom = 0,
7893
+ zIndex = 1,
7894
+ className = "",
7895
+ children = /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Sticky Bottom" })
7896
+ }) => {
7897
+ const elRef = React2.useRef(null);
7898
+ const [isSticky, setIsSticky] = React2.useState(false);
7899
+ const [width, setWidth] = React2.useState("auto");
7900
+ const [height, setHeight] = React2.useState("auto");
7901
+ React2.useEffect(() => {
7902
+ const handleScroll = () => {
7903
+ if (!elRef.current) return;
7904
+ const rect = elRef.current.getBoundingClientRect();
7905
+ const viewportHeight = window.innerHeight;
7906
+ const shouldStick = rect.bottom <= viewportHeight - bottom;
7907
+ if (shouldStick && !isSticky) {
7908
+ setWidth(rect.width + "px");
7909
+ setHeight(rect.height + "px");
7910
+ setIsSticky(true);
7911
+ } else if (!shouldStick && isSticky) {
7912
+ setIsSticky(false);
7913
+ setWidth("auto");
7914
+ }
7915
+ };
7916
+ const handleResize = () => {
7917
+ if (!isSticky && elRef.current) {
7918
+ const rect = elRef.current.getBoundingClientRect();
7919
+ setHeight(rect.height + "px");
7920
+ }
7921
+ };
7922
+ if (elRef.current) {
7923
+ const rect = elRef.current.getBoundingClientRect();
7924
+ setHeight(rect.height + "px");
7925
+ }
7926
+ window.addEventListener("scroll", handleScroll);
7927
+ window.addEventListener("resize", handleResize);
7928
+ handleScroll();
7929
+ return () => {
7930
+ window.removeEventListener("scroll", handleScroll);
7931
+ window.removeEventListener("resize", handleResize);
7932
+ };
7933
+ }, [bottom, isSticky]);
7934
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
7935
+ "div",
7936
+ {
7937
+ ref: elRef,
7938
+ style: {
7939
+ height: isSticky ? height : "auto",
7940
+ zIndex
7941
+ },
7942
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
7943
+ "div",
7944
+ {
7945
+ className,
7946
+ style: {
7947
+ position: isSticky ? "fixed" : "static",
7948
+ bottom: isSticky ? `${bottom}px` : "auto",
7949
+ width: isSticky ? width : "auto",
7950
+ zIndex
7951
+ },
7952
+ children
7953
+ }
7954
+ )
7955
+ }
7956
+ );
7957
+ };
7958
+ const StickyTop = ({
7959
+ top = 0,
7960
+ zIndex = 1,
7961
+ className = "",
7962
+ children = /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Sticky Top" })
7963
+ }) => {
7964
+ const elRef = React2.useRef(null);
7965
+ const [isSticky, setIsSticky] = React2.useState(false);
7966
+ const [width, setWidth] = React2.useState("auto");
7967
+ const [height, setHeight] = React2.useState("auto");
7968
+ React2.useEffect(() => {
7969
+ const handleScroll = () => {
7970
+ if (!elRef.current) return;
7971
+ const rect = elRef.current.getBoundingClientRect();
7972
+ const shouldStick = rect.top <= top;
7973
+ if (shouldStick && !isSticky) {
7974
+ setWidth(rect.width + "px");
7975
+ setHeight(rect.height + "px");
7976
+ setIsSticky(true);
7977
+ } else if (!shouldStick && isSticky) {
7978
+ setIsSticky(false);
7979
+ setWidth("auto");
7980
+ }
7981
+ };
7982
+ const handleResize = () => {
7983
+ if (!isSticky && elRef.current) {
7984
+ const rect = elRef.current.getBoundingClientRect();
7985
+ setHeight(rect.height + "px");
7986
+ }
7987
+ };
7988
+ if (elRef.current) {
7989
+ const rect = elRef.current.getBoundingClientRect();
7990
+ setHeight(rect.height + "px");
7991
+ }
7992
+ window.addEventListener("scroll", handleScroll);
7993
+ window.addEventListener("resize", handleResize);
7994
+ handleScroll();
7995
+ return () => {
7996
+ window.removeEventListener("scroll", handleScroll);
7997
+ window.removeEventListener("resize", handleResize);
7998
+ };
7999
+ }, [top, isSticky]);
8000
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
8001
+ "div",
8002
+ {
8003
+ ref: elRef,
8004
+ style: {
8005
+ height: isSticky ? height : "auto",
8006
+ zIndex
8007
+ },
8008
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
8009
+ "div",
8010
+ {
8011
+ className,
8012
+ style: {
8013
+ position: isSticky ? "fixed" : "static",
8014
+ top: isSticky ? `${top}px` : "auto",
8015
+ width: isSticky ? width : "auto",
8016
+ zIndex
8017
+ },
8018
+ children
8019
+ }
8020
+ )
8021
+ }
8022
+ );
8023
+ };
7783
8024
  exports.AsyncImg = AsyncImg;
7784
8025
  exports.CustomTransition = CustomTransition;
8026
+ exports.MountedTeleport = MountedTeleport;
8027
+ exports.ReadMore = ReadMore;
8028
+ exports.StickyBottom = StickyBottom;
8029
+ exports.StickyTop = StickyTop;
7785
8030
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7786
8031
  return exports;
7787
- }({}, React);
8032
+ }({}, React, ReactDOM);
package/dist/index.mjs CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as React from "react";
2
2
  import React__default, { useState, useEffect, createContext, useRef, useLayoutEffect, useId, useContext, useInsertionEffect, useMemo, useCallback, Children, isValidElement, Fragment, createElement, forwardRef, Component } from "react";
3
+ import { createPortal } from "react-dom";
3
4
  var jsxRuntime = { exports: {} };
4
5
  var reactJsxRuntime_production = {};
5
6
  /**
@@ -7763,7 +7764,252 @@ const CustomTransition = ({
7763
7764
  }
7764
7765
  );
7765
7766
  };
7767
+ const MountedTeleport = ({
7768
+ to,
7769
+ children,
7770
+ disabled = false
7771
+ }) => {
7772
+ const [isMounted, setIsMounted] = useState(false);
7773
+ const [targetElement, setTargetElement] = useState(null);
7774
+ useEffect(() => {
7775
+ setIsMounted(true);
7776
+ return () => {
7777
+ setIsMounted(false);
7778
+ };
7779
+ }, []);
7780
+ useEffect(() => {
7781
+ if (!isMounted || disabled) {
7782
+ setTargetElement(null);
7783
+ return;
7784
+ }
7785
+ let target = null;
7786
+ if (typeof to === "string") {
7787
+ target = document.querySelector(to);
7788
+ if (!target) {
7789
+ console.warn(
7790
+ `MountedTeleport: Target element not found for selector "${to}"`
7791
+ );
7792
+ setTargetElement(null);
7793
+ return;
7794
+ }
7795
+ } else if (to instanceof HTMLElement) {
7796
+ target = to;
7797
+ } else {
7798
+ console.warn(
7799
+ "MountedTeleport: Invalid target type. Expected string selector or HTMLElement."
7800
+ );
7801
+ setTargetElement(null);
7802
+ return;
7803
+ }
7804
+ setTargetElement(target);
7805
+ }, [to, isMounted, disabled]);
7806
+ if (!isMounted || disabled || !targetElement) {
7807
+ return null;
7808
+ }
7809
+ return createPortal(children, targetElement);
7810
+ };
7811
+ const ReadMore = ({
7812
+ moreStr = "Read more",
7813
+ lessStr = "Read less",
7814
+ link = "#",
7815
+ maxChars = 100,
7816
+ text,
7817
+ className = "",
7818
+ linkClassName = ""
7819
+ }) => {
7820
+ const [isExpanded, setIsExpanded] = useState(false);
7821
+ const formattedText = () => {
7822
+ if (!isExpanded && text.length > maxChars) {
7823
+ return text.substring(0, maxChars).trim() + "...";
7824
+ }
7825
+ return text;
7826
+ };
7827
+ const handleToggle = (event) => {
7828
+ event.preventDefault();
7829
+ setIsExpanded(!isExpanded);
7830
+ };
7831
+ if (!text) {
7832
+ return null;
7833
+ }
7834
+ const shouldShowToggle = text.length > maxChars;
7835
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className, children: [
7836
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: formattedText() }),
7837
+ shouldShowToggle && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
7838
+ " ",
7839
+ !isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(
7840
+ "a",
7841
+ {
7842
+ href: link,
7843
+ onClick: handleToggle,
7844
+ className: linkClassName,
7845
+ role: "button",
7846
+ tabIndex: 0,
7847
+ onKeyDown: (e) => {
7848
+ if (e.key === "Enter" || e.key === " ") {
7849
+ e.preventDefault();
7850
+ setIsExpanded(true);
7851
+ }
7852
+ },
7853
+ children: moreStr
7854
+ }
7855
+ ) : lessStr && /* @__PURE__ */ jsxRuntimeExports.jsx(
7856
+ "a",
7857
+ {
7858
+ href: link,
7859
+ onClick: handleToggle,
7860
+ className: linkClassName,
7861
+ role: "button",
7862
+ tabIndex: 0,
7863
+ onKeyDown: (e) => {
7864
+ if (e.key === "Enter" || e.key === " ") {
7865
+ e.preventDefault();
7866
+ setIsExpanded(false);
7867
+ }
7868
+ },
7869
+ children: lessStr
7870
+ }
7871
+ )
7872
+ ] })
7873
+ ] });
7874
+ };
7875
+ const StickyBottom = ({
7876
+ bottom = 0,
7877
+ zIndex = 1,
7878
+ className = "",
7879
+ children = /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Sticky Bottom" })
7880
+ }) => {
7881
+ const elRef = useRef(null);
7882
+ const [isSticky, setIsSticky] = useState(false);
7883
+ const [width, setWidth] = useState("auto");
7884
+ const [height, setHeight] = useState("auto");
7885
+ useEffect(() => {
7886
+ const handleScroll = () => {
7887
+ if (!elRef.current) return;
7888
+ const rect = elRef.current.getBoundingClientRect();
7889
+ const viewportHeight = window.innerHeight;
7890
+ const shouldStick = rect.bottom <= viewportHeight - bottom;
7891
+ if (shouldStick && !isSticky) {
7892
+ setWidth(rect.width + "px");
7893
+ setHeight(rect.height + "px");
7894
+ setIsSticky(true);
7895
+ } else if (!shouldStick && isSticky) {
7896
+ setIsSticky(false);
7897
+ setWidth("auto");
7898
+ }
7899
+ };
7900
+ const handleResize = () => {
7901
+ if (!isSticky && elRef.current) {
7902
+ const rect = elRef.current.getBoundingClientRect();
7903
+ setHeight(rect.height + "px");
7904
+ }
7905
+ };
7906
+ if (elRef.current) {
7907
+ const rect = elRef.current.getBoundingClientRect();
7908
+ setHeight(rect.height + "px");
7909
+ }
7910
+ window.addEventListener("scroll", handleScroll);
7911
+ window.addEventListener("resize", handleResize);
7912
+ handleScroll();
7913
+ return () => {
7914
+ window.removeEventListener("scroll", handleScroll);
7915
+ window.removeEventListener("resize", handleResize);
7916
+ };
7917
+ }, [bottom, isSticky]);
7918
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
7919
+ "div",
7920
+ {
7921
+ ref: elRef,
7922
+ style: {
7923
+ height: isSticky ? height : "auto",
7924
+ zIndex
7925
+ },
7926
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
7927
+ "div",
7928
+ {
7929
+ className,
7930
+ style: {
7931
+ position: isSticky ? "fixed" : "static",
7932
+ bottom: isSticky ? `${bottom}px` : "auto",
7933
+ width: isSticky ? width : "auto",
7934
+ zIndex
7935
+ },
7936
+ children
7937
+ }
7938
+ )
7939
+ }
7940
+ );
7941
+ };
7942
+ const StickyTop = ({
7943
+ top = 0,
7944
+ zIndex = 1,
7945
+ className = "",
7946
+ children = /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: "Sticky Top" })
7947
+ }) => {
7948
+ const elRef = useRef(null);
7949
+ const [isSticky, setIsSticky] = useState(false);
7950
+ const [width, setWidth] = useState("auto");
7951
+ const [height, setHeight] = useState("auto");
7952
+ useEffect(() => {
7953
+ const handleScroll = () => {
7954
+ if (!elRef.current) return;
7955
+ const rect = elRef.current.getBoundingClientRect();
7956
+ const shouldStick = rect.top <= top;
7957
+ if (shouldStick && !isSticky) {
7958
+ setWidth(rect.width + "px");
7959
+ setHeight(rect.height + "px");
7960
+ setIsSticky(true);
7961
+ } else if (!shouldStick && isSticky) {
7962
+ setIsSticky(false);
7963
+ setWidth("auto");
7964
+ }
7965
+ };
7966
+ const handleResize = () => {
7967
+ if (!isSticky && elRef.current) {
7968
+ const rect = elRef.current.getBoundingClientRect();
7969
+ setHeight(rect.height + "px");
7970
+ }
7971
+ };
7972
+ if (elRef.current) {
7973
+ const rect = elRef.current.getBoundingClientRect();
7974
+ setHeight(rect.height + "px");
7975
+ }
7976
+ window.addEventListener("scroll", handleScroll);
7977
+ window.addEventListener("resize", handleResize);
7978
+ handleScroll();
7979
+ return () => {
7980
+ window.removeEventListener("scroll", handleScroll);
7981
+ window.removeEventListener("resize", handleResize);
7982
+ };
7983
+ }, [top, isSticky]);
7984
+ return /* @__PURE__ */ jsxRuntimeExports.jsx(
7985
+ "div",
7986
+ {
7987
+ ref: elRef,
7988
+ style: {
7989
+ height: isSticky ? height : "auto",
7990
+ zIndex
7991
+ },
7992
+ children: /* @__PURE__ */ jsxRuntimeExports.jsx(
7993
+ "div",
7994
+ {
7995
+ className,
7996
+ style: {
7997
+ position: isSticky ? "fixed" : "static",
7998
+ top: isSticky ? `${top}px` : "auto",
7999
+ width: isSticky ? width : "auto",
8000
+ zIndex
8001
+ },
8002
+ children
8003
+ }
8004
+ )
8005
+ }
8006
+ );
8007
+ };
7766
8008
  export {
7767
8009
  AsyncImg,
7768
- CustomTransition
8010
+ CustomTransition,
8011
+ MountedTeleport,
8012
+ ReadMore,
8013
+ StickyBottom,
8014
+ StickyTop
7769
8015
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@creopse/react",
3
3
  "description": "Creopse React Toolkit",
4
- "version": "0.0.2",
4
+ "version": "0.0.4",
5
5
  "private": false,
6
6
  "author": "Noé Gnanih <noegnanih@gmail.com>",
7
7
  "license": "MIT",
@@ -27,7 +27,7 @@
27
27
  "dev-types": "tsc --noEmit -p tsconfig.app.json --watch",
28
28
  "build": "pnpm build-lib && pnpm build-types",
29
29
  "build-lib": "vite build",
30
- "build-types": "rm -f *.tsbuildinfo && tsc --emitDeclarationOnly --declaration -p tsconfig.app.json",
30
+ "build-types": "rm -f *.tsbuildinfo && rm -rf types && tsc --emitDeclarationOnly --declaration -p tsconfig.app.json",
31
31
  "lint": "eslint .",
32
32
  "preview": "vite preview"
33
33
  },
@@ -1,5 +1,5 @@
1
1
  import React, { type CSSProperties } from 'react';
2
- export interface AsyncImgProps {
2
+ export interface Props {
3
3
  load: () => Promise<string>;
4
4
  alt?: string;
5
5
  width?: string | number;
@@ -8,4 +8,5 @@ export interface AsyncImgProps {
8
8
  loading?: 'lazy' | 'eager';
9
9
  style?: CSSProperties;
10
10
  }
11
- export declare const AsyncImg: React.FC<AsyncImgProps>;
11
+ declare const AsyncImg: React.FC<Props>;
12
+ export default AsyncImg;
@@ -1 +1 @@
1
- export { AsyncImg, type AsyncImgProps } from './AsyncImg';
1
+ export { default as AsyncImg, type Props as AsyncImgProps } from './AsyncImg';
@@ -1,12 +1,12 @@
1
1
  import React from 'react';
2
2
  type Animation = 'fade' | 'slide-fade' | 'bounce';
3
3
  type Mode = 'wait' | 'sync' | 'popLayout' | undefined;
4
- export interface CustomTransitionProps {
4
+ export interface Props {
5
5
  name?: Animation;
6
6
  mode?: Mode;
7
7
  appear?: boolean;
8
8
  children?: React.ReactNode;
9
9
  contentKey?: string | number;
10
10
  }
11
- export declare const CustomTransition: React.FC<CustomTransitionProps>;
12
- export {};
11
+ declare const CustomTransition: React.FC<Props>;
12
+ export default CustomTransition;
@@ -1 +1 @@
1
- export { CustomTransition, type CustomTransitionProps, } from './CustomTransition';
1
+ export { default as CustomTransition, type Props as CustomTransitionProps, } from './CustomTransition';
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ export interface Props {
3
+ to: string | HTMLElement;
4
+ children: React.ReactNode;
5
+ disabled?: boolean;
6
+ }
7
+ declare const MountedTeleport: React.FC<Props>;
8
+ export default MountedTeleport;
@@ -0,0 +1 @@
1
+ export { default as MountedTeleport, type Props as MountedTeleportProps, } from './MountedTeleport';
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ export interface Props {
3
+ moreStr?: string;
4
+ lessStr?: string;
5
+ text: string;
6
+ link?: string;
7
+ maxChars?: number;
8
+ className?: string;
9
+ linkClassName?: string;
10
+ }
11
+ declare const ReadMore: React.FC<Props>;
12
+ export default ReadMore;
@@ -0,0 +1 @@
1
+ export { default as ReadMore, type Props as ReadMoreProps } from './ReadMore';
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ export interface Props {
3
+ bottom?: number;
4
+ zIndex?: number;
5
+ className?: string;
6
+ children?: React.ReactNode;
7
+ }
8
+ declare const StickyBottom: React.FC<Props>;
9
+ export default StickyBottom;
@@ -0,0 +1 @@
1
+ export { default as StickyBottom, type Props as StickyBottomProps, } from './StickyBottom';
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ export interface Props {
3
+ top?: number;
4
+ zIndex?: number;
5
+ className?: string;
6
+ children?: React.ReactNode;
7
+ }
8
+ declare const StickyTop: React.FC<Props>;
9
+ export default StickyTop;
@@ -0,0 +1 @@
1
+ export { default as StickyTop, type Props as StickyTopProps } from './StickyTop';
package/types/index.d.ts CHANGED
@@ -1,2 +1,6 @@
1
1
  export { AsyncImg, type AsyncImgProps } from './components/widgets/AsyncImg';
2
2
  export { CustomTransition, type CustomTransitionProps, } from './components/widgets/CustomTransition';
3
+ export { MountedTeleport, type MountedTeleportProps, } from './components/widgets/MountedTeleport';
4
+ export { ReadMore, type ReadMoreProps } from './components/widgets/ReadMore';
5
+ export { StickyBottom, type StickyBottomProps, } from './components/widgets/StickyBottom';
6
+ export { StickyTop, type StickyTopProps } from './components/widgets/StickyTop';