A react library for component & hooks.
npm install @letea/react
If you want to use components, please make sure your bundler includes the path of the library node_modules/@letea/react
to handle jsx compiling.
- useIsWindowEventTriggering
- useWindowBlur
- useWindowEvent
- useWindowEvents
- useWindowLoad
- useWindowOrientation
- useWindowSize
Allow you to have a fixed background image. Because of iOS Device does not support background-attachment: fixed.
defaultProps = {
image: "", // required
};
import BackgroundFixedImage from "@letea/react/components/BackgroundFixedImage";
function Example() {
return (
<>
<BackgroundFixedImage image="a.jpg" />
<YourComponent />
</>
);
}
A background with a gallery.
defaultProps = {
images: [], // required
duration: 3000, // optional
transition: 1000, // optional
};
import BackgroundGallery from "@letea/react/components/BackgroundGallery";
function Example() {
return (
<YourComponent>
<BackgroundGallery images={["a.jpg", "b.jpg", "c.jpg"]} />
</YourComponent>
);
}
A background with a gallery feature. Support two types(portrait and landscape).
defaultProps = {
portraitImages: [], // require
landscapeImages: [], // require
duration: 3000, // optional
transition: 1000, // optional
};
import BackgroundGalleryWithOrientation from "@letea/react/components/BackgroundGalleryWithOrientation";
function Example() {
return (
<YourComponent>
<BackgroundGallery
portraitImages={["a.jpg", "b.jpg", "c.jpg"]}
landscapeImages={["a.jpg", "b.jpg", "c.jpg"]}
/>
</YourComponent>
);
}
BackgroundGalleryWithOrientation
A background with a video.
defaultProps = {
video: "", // required
poster: "", // optional
isFixed: false, // optional, it will be position: absolute; if the value is false.
};
import BackgroundVideo from "@letea/react/components/BackgroundVideo";
function Example() {
return (
<>
<BackgroundVideo video="a.mp4" isFixed />
<YourComponent />
</>
);
}
A flashlight effect by canvas. You can control the flashlight by mouse/touch move.
defaultProps = {
defaultMouseX: window.innerWidth / 2, // optional
defaultMouseY: window.innerHeight / 2, // optional
};
import Flashlight from "@letea/react/components/Flashlight";
function Example() {
return <Flashlight />;
}
- Watch out!
A lighting flash effect by canvas.
import Lighting from "@letea/react/components/Lighting";
function Example() {
return <Lighting />;
}
- You will hate me.
Allow you to write p5.js in React.
defaultProps = {
sketch: null, // (p5) => { /* your code */ }
hasSoundLibrary: false, // Using p5.sound library or not
isIgnoreLoadingMessage: false, // Ignore Loading Message or not
isPositionFixed: false, // CSS default is absolute position
zIndex: null, // CSS default is 0
};
import Processing from "@letea/react/components/Processing";
function Example() {
const sketch = (p5) => {
p5.setup = () => {
p5.createCanvas(p5.windowWidth, p5.windowHeight);
p5.background(0);
};
p5.draw = () => {
p5.ellipse(p5.mouseX, p5.mouseY, 50, 50);
};
};
return <Processing sketch={sketch} />;
}
- If you want to create a canvas full fill with parent element, use "p5.canvas.parentElement" to get width and height.
- If you want to use Amplitude from p5.sound, use window.p5 instead of p5 from parameter.
A scratcher effect by canvas.
import Scratcher from "@letea/react/components/Scratcher";
function Example() {
return (
<>
<YourComponent />
<Scratcher />
</>
);
}
To detect if the element is in the view of the browser. It will pass the "isInView" variable to children.
defaultProps = {
isDebug: false, // optional, will return size of window, bounding client rect of element and position if value is true.
hasPosition: false, // optional, will return *xAxis and *yAxis if value is true. (the unit is percentage, xAxis is from left to right, yAxis is from top to bottom)
offsetTop: 0, // optional, to set offset *top for element in view. (the unit is percentage, the value is relative to element's height)
offsetRight: 0, // optional, to set offset *right for element in view. (the unit is percentage, the value is relative to element's width)
offsetBottom: 0, // optional, to set offset *bottom for element in view. (the unit is percentage, the value is relative to element's height)
offsetLeft: 0, // optional, to set offset *left for element in view. (the unit is percentage, the value is relative to element's width)
onReady: () => {}, // optional, trigger when component is ready.
onMove: () => {}, // optional, trigger when component moving.
onEnter: () => {}, // optional, trigger when component enter the browser's view.
onLeave: () => {}, // optional, trigger when component leave the browser's view.
};
import ElementInView from "@letea/react/components/ElementInView";
function Example() {
return (
<ElementInView hasPosition>
<TargetElement />
</ElementInView>
);
}
A horizontal scroll effect for mobile devices.
defaultProps = {
hideScrollbar: true, // optional
};
import HorizontalScroll from "@letea/react/components/HorizontalScroll";
function Example() {
return (
<HorizontalScroll>
<YourElement />
<YourElement />
<YourElement />
<YourElement />
<YourElement />
</HorizontalScroll>
);
}
- The children should be display: 'inline-block' or 'inline-flex'.
- iOS hide scrollbar natively.
A marquee slider.
defaultProps = {
animationDuration: 40000, // optional, the unit is millisecond.
isPausedOnHover: false, // optional
};
import Marquee from "@letea/react/components/Marquee";
function Example() {
return (
<Marquee animationDuration={40000}>
<YourElement />
<YourElement />
<YourElement />
<YourElement />
<YourElement />
</Marquee>
);
}
- The children should be 'display: inline-block' or 'inline-flex'.
A simple gallery.
defaultProps = {
images: [], // required
duration: 3000, // optional
transition: 1000, // optional
};
import Gallery from "@letea/react/components/Gallery";
function Example() {
return <Gallery images={["a.jpg", "b.jpg", "c.jpg"]} />;
}
A component loads images and gives you a callback when images are loaded.
defaultProps = {
images: [], // required
onEachLoad: (loadedImages) => {}, // optional
onAllLoad: (loadedImages) => {}, // optional
};
import ImageLoader from "@letea/react/components/ImageLoader";
function Example() {
return (
<ImageLoader
images={["a.jpg", "b.jpg", "c.jpg"]}
onEachLoad={(loadedImages) => {
// Do something...
}}
onAllLoad={(loadedImages) => {
// Do something...
}}
/>
);
}
Create a full-page layout and keeps the height of content is equal to or greater than the height of the window.
defaultProps = {
isDebug: false, // optional, it will display contrastive colors if the value is true.
enableMinWidth: 0, // optional
offsetHeight: 0, // optional, to adjust the size of height.
paddingTop: 0, // optional, add padding top to content.
paddingBottom: 0, // optional, add padding bottom to content.
};
import FullPage from "@letea/react/components/FullPage";
function Example() {
return (
<FullPage>
<YourComponent />
</FullPage>
);
}
Display a fullscreen loading.
// openFullscreenLoading
defaultProps = {
Spinner: null, // Your spinner component
zIndex: 9999, // optional
backgroundColor: "rgba(0, 0, 0, 0.75)", // optional
onClick: () => {}, // optional
};
// closeFullscreenLoading
defaultProps = {};
import FullscreenLoading from "@letea/react/components/FullscreenLoading";
function Example() {
return (
<>
<YourComponent
onClick={() => {
openFullscreenLoading();
}}
/>
<YourComponent
onClick={() => {
closeFullscreenLoading();
}}
/>
</>
);
}
Sometimes you want to hint users something. For example, browsing on the mobile web in the landscape is suck.
defaultProps = {
message: "", // optional
zIndex: 9999, // optional
};
import LandscapeTip from "@letea/react/components/LandscapeTip";
function Example() {
return <LandscapeTip message="Hello World!" />;
}
It's a layout of loading(load images), allow you to get user *permissions by click/touch after loaded. (ex. Autoplay video/audio with sound, vibrate API)
defaultProps = {
images: [], // optional
getUserPermission: false, // optional
onLoad: () => {}, // optional
zIndex: 9999, // optional
isFixed: true, // optional
};
import LayoutLoading from "@letea/react/components/LayoutLoading";
function Example() {
const [isLoaded, setIsLoaded] = useState(false);
return (
<>
{!isLoaded && (
<LayoutLoading
images={["a.jpg", "b.jpg", "c.jpg"]}
getUserPermission
onLoad={() => {
setIsLoaded(true);
}}
/>
)}
{isLoaded && <YourComponent />}
</>
);
}
A layout of transition.
defaultProps = {
start: false, // required
url: "", // required
duration: 1000, // optional, value of animation-duration, unit is millisecond.
frames: 0, // optional, value of animation-timing-function
reverse: false, // optional, value of animation-direction
infinite: false, // optional, value of animation-iteration-count
forwards: false, // optional, value of animation-fill-mode
onFinish: null, // optional, trigger on animation end.
};
import LayoutTransition from "@letea/react/components/LayoutTransition";
function Example() {
return (
<LayoutTransition
start={true}
url={"a.jpg"}
duration={1000}
frames={22}
reverse={false}
infinite={false}
forwards={false}
onFinish={() => {
// do something...
}}
/>
);
}
A mask covers the layout.
defaultProps = {
isFixed: false, // optional
zIndex: 9999, // optional
};
import Mask from "@letea/react/components/Mask";
function Example() {
return (
<>
<YourComponent />
<Mask />
</>
);
}
A video player uses the native interface.
defaultProps = {
src: "", // required
poster: "", // optional
hasControls: false, // optional
hasContextMenu: false, // optional
hasPreload: true, // optional
isAutoPlay: false, // optional
isPlaysInline: false, // optional
isMuted: false, // optional
isLoop: false, // optional
isPauseOnBlur: false, // optional
isCoverSize: false, // optional
onCanPlay: (event) => {}, // optional
onError: (event) => {}, // optional
onPlay: (event) => {}, // optional
onPlaying: (event) => {}, // optional
onTimeUpdate: (event) => {}, // optional
onPause: (event) => {}, // optional
onEnded: (event) => {}, // optional
onVolumeChange: (event) => {}, // optional
onFullscreen: () => {}, // optional
onFullscreenExit: () => {}, // optional
};
import VideoPlayer from "@letea/react/components/VideoPlayer";
function Example() {
return <VideoPlayer src="a.mp4" />;
}
Display a message at the corner.
import Toast from "@letea/react/components/Toast";
function Example() {
return (
<>
<YourComponent
onClick={() => {
toast("Hello There");
}}
/>
<YourComponent
onClick={() => {
toast({ message: "Hello There", duration: 1500 });
}}
/>
</>
);
}
Allow users to copy text.
defaultProps = {
text: "", // optional
isDebugMode: false, // optional
onSuccess: () => {}, // optional
onFail: () => {}, // optional
};
import Clipboard from "@letea/react/components/Clipboard";
function Example() {
return <Clipboard text="Hello World!">Copy Text</Clipboard>;
}
Display source code with syntax highlight.
defaultProps = {
code: "", // required
};
import Code from "@letea/react/components/Code";
function Example() {
return <Code code="console.log('Hello World!');" />;
}
- Import Hack Typeface in the head of HTML for the best experience.
Allow you to test javascript code via RunKit.
import EmbedRunKit from "@letea/react/components/EmbedRunKit";
function Example() {
return <EmbedRunKit source="console.log('Hello World!')" />;
}
Convert text to QR code.
defaultProps = {
text: "", // optional
width: 150, // optional
height: 150, // optional
};
import QRCode from "@letea/react/components/QRCode";
function Example() {
return <QRCode text="Hello World!" />;
}
Display FPS(Frame per Second).
defaultProps = {
isFixed: false, // optional, default position is absolute.
zIndex: 9999, // optional
};
import FPS from "@letea/react/components/FPS";
function Example() {
return <FPS />;
}
Display frame for developing layout, style is base on Storybook.
defaultProps = {
isFixed: false, // optional, default position is absolute.
zIndex: -1, // optional
};
import Frame from "@letea/react/components/Frame";
function Example() {
return <Frame />;
}
Display render counts.
import RenderCounter from "@letea/react/components/RenderCounter";
function Example() {
return (
<RenderCounter>
<YourComponent />
</RenderCounter>
);
}
Display the size of the window, base on Chrome's inspect style.
defaultProps = {
isFixed: true, // optional
zIndex: 9999, // optional
autoHide: false, // optional
hideDelay: 1000, // optional, it will enable if audHide is true.
};
import WindowSize from "@letea/react/components/WindowSize";
function Example() {
return <WindowSize />;
}
Allow you to get or update the title of the document.
import useDocumentTitle from "@letea/react/hooks/useDocumentTitle";
const [title, setTitle] = useDocumentTitle();
To detect if the element is in the view of the browser.
import useElementInView from "@letea/react/hooks/useElementInView";
// Basic
const element = useElementInView({
target: targetRef,
});
// element => {
// isInView // check is element in view.
// }
// Basic with Position
const element = useElementInView({
target: targetRef,
hasPosition: true,
});
// element => {
// isInView,
// xAxis, => the xAxis of element.
// yAxis => the yAxis of element.
// }
// Debug
const element = useElementInView({
target: targetRef,
isDebug: true,
});
// element => {
// isInView,
// xAxis,
// yAxis,
// windowWidth, => the width of window.
// windowHeight, => the height of window.
// top, => the top of element.
// right, => the right of element.
// bottom, => the bottom of element.
// left, => the left of element.
// width, => the width of element.
// height => the height of element.
// }
Add an event to an element. You don't need to remove it manually.
import useEvent from "@letea/react/hooks/useEvent";
useEvent({
eventName: "click",
target: targetRef,
callback: () => {
// Do something...
},
});
Add multiple events to elements. You don't need to remove it manually. The best part is you can let events share a/an method/element or use each of the methods/elements.
import useEvents from "@letea/react/hooks/useEvents";
useEvents({
eventNames: ["mousedown", "mouseup"],
targets: [aRef],
callbacks: [
() => {
// Do something for mousedown & mouseup
},
],
});
// Trigger when mousedown or mouseup, share with a function and an element.
useEvents({
eventNames: ["mousedown", "mouseup"],
targets: [aRef],
callbacks: [
() => {
// Do something for mousedown event.
},
() => {
// Do something for mouseup event.
},
],
});
// Trigger when mousedown or mouseup, use each of functions, share with an element.
- The length of eventNames should be equal to or greater than targets and callbacks.
Allow you to get or update the value of the checkbox.
import useInputCheckbox from "@letea/react/hooks/useInputCheckbox";
function Example() {
const [value, setValue] = useInputCheckbox(false);
return <input type="checkbox" defaultValue={value} onChange={setValue} />;
}
Allow you to get or update the value of the input.
import useInputNumber from "@letea/react/hooks/useInputNumber";
function Example() {
const [value, setValue] = useInputNumber(0);
return <input type="number" defaultValue={value} onChange={setValue} />;
}
Allow you to get or update the value of the input.
import useInputText from "@letea/react/hooks/useInputText";
function BasicExample() {
const [value, setValue] = useInputText("Message");
return <input type="text" defaultValue={value} onChange={setValue} />;
}
function AdvanceExample() {
const [value, setValue] = useInputText({
defaultValue: Message,
hasDebounce: true,
debounceTime: 600,
});
return <input type="text" defaultValue={value} onChange={setValue} />;
}
- If you want to use a checkbox, check out the useInputCheckbox.
Allow you to create a value control easily. The idea is base on Storybook addon-knobs.
import useKnobs from "@letea/react/hooks/useKnobs";
function Example() {
const textValue = text({ defaultValue: "Message", label: "Text" });
const numberValue = number({ defaultValue: 0, label: "Number" });
const booleanValue = boolean({ defaultValue: false, label: "Boolean" });
const { value: selectValue, index: selectIndex } = select({
options: ["Apple", "Banana", "Piapple"],
label: "Select",
});
button({
label: "Button",
handler: () => {
// Do something...
},
});
return (
<div>
{`Text: ${textValue}`}
<br />
{`Number: ${numberValue}`}
<br />
{`Boolean: ${booleanValue}`}
<br />
{`Select Value: ${selectValue}`}
<br />
{`Select Index: ${selectIndex}`}
<hr />
<KnobsContainer />
</div>
);
}
Allow you to get or update the index of the select.
import useSelect from "@letea/react/hooks/useSelect";
function Example() {
const [index, setIndex] = useSelect(0);
return (
<select onChange={setIndex}>
<option>a</option>
<option>b</option>
<option>c</option>
</select>
);
}
Get an image with status.
import useImage from "@letea/react/hooks/useImage";
const [image, status] = useImage({
url: "https://www.example.com/sample.jpg",
});
// image => "https://www.example.com/sample.jpg"
// status => "loading", "loaded", "failed"
Allow you to load script with URL.
import useScript from "@letea/react/hooks/useScript";
const isScriptLoaded = useScript("https://cdn.jsdelivr.net/npm/sweetalert2@10");
- Base on useScript from useHooks.
useState with debounce!
import useDebounceState from "@letea/react/hooks/useDebounceState";
const [value, setValue] = useDebounceState({
defaultValue: "Apple",
});
setValue("Banana");
useState with throttle!
import useThrottleState from "@letea/react/hooks/useThrottleState";
const [value, setValue] = useThrottleState({
defaultValue: "Apple",
});
setValue("Banana");
Create a countdown.
import useCountdown from "@letea/react/hooks/useCountdown";
const [counts, isFinish] = useCountdown({
defaultCounts: 999,
speed: 1000,
formatToHHMMSS: false,
});
// counts => 999
// isFinish => false, true
Allow you to use setInterval without handle clearInterval.
import useInterval from "@letea/react/hooks/useInterval";
useInterval({
callback: () => {
// Do something...
},
duration: 1000,
startInterval: true,
});
Allow you to use setTimeout without handle clearTimeout.
import useTimeout from "@letea/react/hooks/useTimeout";
useTimeout({
callback: () => {
// Do something...
},
duration: 1000,
startTimeout: true,
});
Get a value to check if the event of the window is triggering or not.
import useIsWindowEventTriggering from "@letea/react/hooks/useIsWindowEventTriggering";
const isResizing = useIsWindowEventTriggering({
eventName: "resize",
duration: 1500,
});
// isResizing => true, false
Get a value to check if the window is blurred or not.
import useWindowBlur from "@letea/react/hooks/useWindowBlur";
const isWindowBlurred = useWindowBlur();
// isWindowLoaded => true, false
Add an event of window, you don't need to remove it manually.
import useWindowEvent from "@letea/react/hooks/useWindowEvent";
useWindowEvent({
eventName: "click",
callback: () => {
// Do something...
},
});
Add multiple events to the window. You don't need to remove it manually. The best part is you can let events share a method or use each of the methods.
import useWindowEvents from "@letea/react/hooks/useWindowEvents";
useWindowEvents({
eventNames: ["mousedown", "mouseup"],
callbacks: [
() => {
// Do something...
},
],
});
// Trigger when mousedown or mouseup, share with a method.
useWindowEvents({
eventNames: ["mousedown", "mouseup"],
callbacks: [
() => {
// Do something for mousedown event.
},
() => {
// Do something for mouseup event.
},
],
});
// Trigger when mousedown or mouseup, use each of methods.
Get a value to check if the window is loaded or not.
import useWindowLoad from "@letea/react/hooks/useWindowLoad";
const isWindowLoaded = useWindowLoad();
// isWindowLoaded => true, false
Get the orientation of the window, including the resized window.
import useWindowOrientation from "@letea/react/hooks/useWindowOrientation";
const { isLandscape, isPortrait } = useWindowOrientation();
// isLandscape => true
// isPortrait => false
Get the size of the window, including the resized window.
import useWindowSize from "@letea/react/hooks/useWindowSize";
const { windowWidth, windowHeight } = useWindowSize();
// windowWidth => 1920
// windowHeight => 1080