Skip to content

Commit

Permalink
feat(hooks): Added useBattery, useClickAway, and `useCopyToClipbo…
Browse files Browse the repository at this point in the history
…ard` hooks
  • Loading branch information
sullivanpj committed Oct 24, 2024
1 parent babb4b0 commit 556db4d
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 3 deletions.
2 changes: 1 addition & 1 deletion packages/date-time/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ This package is part of the ⚡<b>Storm Stack</b> monorepo. Storm Stack packages

<h3 align="center">💻 Visit <a href="https://stormsoftware.com" target="_blank">stormsoftware.com</a> to stay up to date with this developer</h3><br />

[![Version](https://img.shields.io/badge/version-1.31.0-1fb2a6.svg?style=for-the-badge&color=1fb2a6)](https://prettier.io/)&nbsp;[![Nx](https://img.shields.io/badge/Nx-17.0.2-lightgrey?style=for-the-badge&logo=nx&logoWidth=20&&color=1fb2a6)](http://nx.dev/)&nbsp;[![NextJs](https://img.shields.io/badge/Next.js-14.0.2-lightgrey?style=for-the-badge&logo=nextdotjs&logoWidth=20&color=1fb2a6)](https://nextjs.org/)&nbsp;[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg?style=for-the-badge&logo=commitlint&color=1fb2a6)](http://commitizen.github.io/cz-cli/)&nbsp;![Semantic-Release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=for-the-badge&color=1fb2a6)&nbsp;[![documented with Fumadocs](https://img.shields.io/badge/documented_with-fumadocs-success.svg?style=for-the-badge&logo=readthedocs&color=1fb2a6)](https://fumadocs.vercel.app/)&nbsp;![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/storm-software/storm-stack/cr.yml?style=for-the-badge&logo=github-actions&color=1fb2a6)
[![Version](https://img.shields.io/badge/version-1.32.0-1fb2a6.svg?style=for-the-badge&color=1fb2a6)](https://prettier.io/)&nbsp;[![Nx](https://img.shields.io/badge/Nx-17.0.2-lightgrey?style=for-the-badge&logo=nx&logoWidth=20&&color=1fb2a6)](http://nx.dev/)&nbsp;[![NextJs](https://img.shields.io/badge/Next.js-14.0.2-lightgrey?style=for-the-badge&logo=nextdotjs&logoWidth=20&color=1fb2a6)](https://nextjs.org/)&nbsp;[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg?style=for-the-badge&logo=commitlint&color=1fb2a6)](http://commitizen.github.io/cz-cli/)&nbsp;![Semantic-Release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=for-the-badge&color=1fb2a6)&nbsp;[![documented with Fumadocs](https://img.shields.io/badge/documented_with-fumadocs-success.svg?style=for-the-badge&logo=readthedocs&color=1fb2a6)](https://fumadocs.vercel.app/)&nbsp;![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/storm-software/storm-stack/cr.yml?style=for-the-badge&logo=github-actions&color=1fb2a6)


> [!IMPORTANT]
Expand Down
84 changes: 84 additions & 0 deletions packages/hooks/src/use-battery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*-------------------------------------------------------------------
⚡ Storm Software - Storm Stack
This code was released as part of the Storm Stack project. Storm Stack
is maintained by Storm Software under the Apache-2.0 License, and is
free for commercial and private use. For more information, please visit
our licensing page.
Website: https://stormsoftware.com
Repository: https://github.com/storm-software/storm-stack
Documentation: https://stormsoftware.com/projects/storm-stack/docs
Contact: https://stormsoftware.com/contact
License: https://stormsoftware.com/projects/storm-stack/license
-------------------------------------------------------------------*/

import { isFunction } from "@storm-stack/types/type-checks/is-function";
import { BatteryManager } from "@storm-stack/types/utility-types/navigator";
import React from "react";

const defaultBatteryManagerState = {
supported: true,
loading: true,
level: null,
charging: null,
chargingTime: null,
dischargingTime: null
};

/**
* Listens for updates to the mobile/desktop battery status
*/
export function useBattery() {
const [state, setState] = React.useState<
Omit<BatteryManager, "addEventListener" | "removeEventListener">
>(defaultBatteryManagerState);

const key = "getBattery" as keyof typeof navigator;
const getBattery = navigator[key] as () => Promise<BatteryManager>;

React.useEffect(() => {
if (!isFunction(getBattery)) {
setState(s => ({
...s,
supported: false,
loading: false
}));
return;
}

let battery = null as BatteryManager | null;

const handleChange = () => {
setState({
...defaultBatteryManagerState,
supported: true,
loading: false,
...battery
});
};

getBattery().then(b => {
battery = b;
handleChange();

b?.addEventListener("levelchange", handleChange);
b?.addEventListener("chargingchange", handleChange);
b?.addEventListener("chargingtimechange", handleChange);
b?.addEventListener("dischargingtimechange", handleChange);
});

return () => {
if (battery) {
battery.removeEventListener("levelchange", handleChange);
battery.removeEventListener("chargingchange", handleChange);
battery.removeEventListener("chargingtimechange", handleChange);
battery.removeEventListener("dischargingtimechange", handleChange);
}
};
}, []);

return state;
}
52 changes: 52 additions & 0 deletions packages/hooks/src/use-click-away.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*-------------------------------------------------------------------
⚡ Storm Software - Storm Stack
This code was released as part of the Storm Stack project. Storm Stack
is maintained by Storm Software under the Apache-2.0 License, and is
free for commercial and private use. For more information, please visit
our licensing page.
Website: https://stormsoftware.com
Repository: https://github.com/storm-software/storm-stack
Documentation: https://stormsoftware.com/projects/storm-stack/docs
Contact: https://stormsoftware.com/contact
License: https://stormsoftware.com/projects/storm-stack/license
-------------------------------------------------------------------*/

import { useEffect, useLayoutEffect, useRef } from "react";

/**
* Listens for when a click is away from the element
*
* @param cb - Callback function
* @returns A Ref object
*/
export function useClickAway(cb: any) {
const ref = useRef<HTMLElement | null>(null);
const refCb = useRef(cb);

useLayoutEffect(() => {
refCb.current = cb;
});

useEffect(() => {
const handler = (e: { target: any }) => {
const element = ref.current;
if (element && !element.contains(e.target)) {
refCb.current(e);
}
};

document.addEventListener("mousedown", handler);
document.addEventListener("touchstart", handler);

return () => {
document.removeEventListener("mousedown", handler);
document.removeEventListener("touchstart", handler);
};
}, []);

return ref;
}
57 changes: 57 additions & 0 deletions packages/hooks/src/use-copy-to-clipboard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*-------------------------------------------------------------------
⚡ Storm Software - Storm Stack
This code was released as part of the Storm Stack project. Storm Stack
is maintained by Storm Software under the Apache-2.0 License, and is
free for commercial and private use. For more information, please visit
our licensing page.
Website: https://stormsoftware.com
Repository: https://github.com/storm-software/storm-stack
Documentation: https://stormsoftware.com/projects/storm-stack/docs
Contact: https://stormsoftware.com/contact
License: https://stormsoftware.com/projects/storm-stack/license
-------------------------------------------------------------------*/

import { EMPTY_STRING } from "@storm-stack/types/utility-types/base";
import { useCallback, useState } from "react";

function oldSchoolCopy(text: string) {
const tempTextArea = document.createElement("textarea");
tempTextArea.value = text;
document.body.appendChild(tempTextArea);
tempTextArea.select();
document.execCommand("copy");
document.body.removeChild(tempTextArea);
}

/**
* Copies a value to the clipboard
*
* @returns A tuple with the copied value and a function to copy a value to the clipboard
*/
export function useCopyToClipboard() {
const [state, setState] = useState<string | null>(null);

const copyToClipboard = useCallback((value: string | null) => {
const handleCopy = async () => {
try {
if (navigator?.clipboard?.writeText) {
await navigator.clipboard.writeText(value ?? EMPTY_STRING);
setState(value ?? EMPTY_STRING);
} else {
throw new Error("writeText not supported");
}
} catch (e) {
oldSchoolCopy(value ?? EMPTY_STRING);
setState(value ?? EMPTY_STRING);
}
};

handleCopy();
}, []);

return [state, copyToClipboard];
}
1 change: 1 addition & 0 deletions packages/hooks/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"skipLibCheck": true,
"lib": ["ESNext", "DOM"]
},
"include": ["src/**/*.ts", "src/**/*.tsx"],
Expand Down
2 changes: 1 addition & 1 deletion packages/serialization/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ This package is part of the ⚡<b>Storm Stack</b> monorepo. Storm Stack packages

<h3 align="center">💻 Visit <a href="https://stormsoftware.com" target="_blank">stormsoftware.com</a> to stay up to date with this developer</h3><br />

[![Version](https://img.shields.io/badge/version-1.29.0-1fb2a6.svg?style=for-the-badge&color=1fb2a6)](https://prettier.io/)&nbsp;[![Nx](https://img.shields.io/badge/Nx-17.0.2-lightgrey?style=for-the-badge&logo=nx&logoWidth=20&&color=1fb2a6)](http://nx.dev/)&nbsp;[![NextJs](https://img.shields.io/badge/Next.js-14.0.2-lightgrey?style=for-the-badge&logo=nextdotjs&logoWidth=20&color=1fb2a6)](https://nextjs.org/)&nbsp;[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg?style=for-the-badge&logo=commitlint&color=1fb2a6)](http://commitizen.github.io/cz-cli/)&nbsp;![Semantic-Release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=for-the-badge&color=1fb2a6)&nbsp;[![documented with Fumadocs](https://img.shields.io/badge/documented_with-fumadocs-success.svg?style=for-the-badge&logo=readthedocs&color=1fb2a6)](https://fumadocs.vercel.app/)&nbsp;![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/storm-software/storm-stack/cr.yml?style=for-the-badge&logo=github-actions&color=1fb2a6)
[![Version](https://img.shields.io/badge/version-1.30.0-1fb2a6.svg?style=for-the-badge&color=1fb2a6)](https://prettier.io/)&nbsp;[![Nx](https://img.shields.io/badge/Nx-17.0.2-lightgrey?style=for-the-badge&logo=nx&logoWidth=20&&color=1fb2a6)](http://nx.dev/)&nbsp;[![NextJs](https://img.shields.io/badge/Next.js-14.0.2-lightgrey?style=for-the-badge&logo=nextdotjs&logoWidth=20&color=1fb2a6)](https://nextjs.org/)&nbsp;[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg?style=for-the-badge&logo=commitlint&color=1fb2a6)](http://commitizen.github.io/cz-cli/)&nbsp;![Semantic-Release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=for-the-badge&color=1fb2a6)&nbsp;[![documented with Fumadocs](https://img.shields.io/badge/documented_with-fumadocs-success.svg?style=for-the-badge&logo=readthedocs&color=1fb2a6)](https://fumadocs.vercel.app/)&nbsp;![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/storm-software/storm-stack/cr.yml?style=for-the-badge&logo=github-actions&color=1fb2a6)


> [!IMPORTANT]
Expand Down
2 changes: 1 addition & 1 deletion packages/types/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ This package is part of the ⚡<b>Storm Stack</b> monorepo. Storm Stack packages

<h3 align="center">💻 Visit <a href="https://stormsoftware.com" target="_blank">stormsoftware.com</a> to stay up to date with this developer</h3><br />

[![Version](https://img.shields.io/badge/version-0.17.0-1fb2a6.svg?style=for-the-badge&color=1fb2a6)](https://prettier.io/)&nbsp;[![Nx](https://img.shields.io/badge/Nx-17.0.2-lightgrey?style=for-the-badge&logo=nx&logoWidth=20&&color=1fb2a6)](http://nx.dev/)&nbsp;[![NextJs](https://img.shields.io/badge/Next.js-14.0.2-lightgrey?style=for-the-badge&logo=nextdotjs&logoWidth=20&color=1fb2a6)](https://nextjs.org/)&nbsp;[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg?style=for-the-badge&logo=commitlint&color=1fb2a6)](http://commitizen.github.io/cz-cli/)&nbsp;![Semantic-Release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=for-the-badge&color=1fb2a6)&nbsp;[![documented with Fumadocs](https://img.shields.io/badge/documented_with-fumadocs-success.svg?style=for-the-badge&logo=readthedocs&color=1fb2a6)](https://fumadocs.vercel.app/)&nbsp;![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/storm-software/storm-stack/cr.yml?style=for-the-badge&logo=github-actions&color=1fb2a6)
[![Version](https://img.shields.io/badge/version-0.18.0-1fb2a6.svg?style=for-the-badge&color=1fb2a6)](https://prettier.io/)&nbsp;[![Nx](https://img.shields.io/badge/Nx-17.0.2-lightgrey?style=for-the-badge&logo=nx&logoWidth=20&&color=1fb2a6)](http://nx.dev/)&nbsp;[![NextJs](https://img.shields.io/badge/Next.js-14.0.2-lightgrey?style=for-the-badge&logo=nextdotjs&logoWidth=20&color=1fb2a6)](https://nextjs.org/)&nbsp;[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg?style=for-the-badge&logo=commitlint&color=1fb2a6)](http://commitizen.github.io/cz-cli/)&nbsp;![Semantic-Release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=for-the-badge&color=1fb2a6)&nbsp;[![documented with Fumadocs](https://img.shields.io/badge/documented_with-fumadocs-success.svg?style=for-the-badge&logo=readthedocs&color=1fb2a6)](https://fumadocs.vercel.app/)&nbsp;![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/storm-software/storm-stack/cr.yml?style=for-the-badge&logo=github-actions&color=1fb2a6)


> [!IMPORTANT]
Expand Down
1 change: 1 addition & 0 deletions packages/types/src/utility-types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export * from "./form";
export * from "./json";
export * from "./logic";
export * from "./messages";
export * from "./navigator";
export * from "./object";
export * from "./package-json";
export * from "./string";
Expand Down
10 changes: 10 additions & 0 deletions packages/types/src/utility-types/navigator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export type BatteryManager = {
supported: boolean;
loading: boolean;
level: number | null;
charging: boolean | null;
chargingTime: number | null;
dischargingTime: number | null;
addEventListener: (type: string, listener: () => void) => void;
removeEventListener: (type: string, listener: () => void) => void;
};

0 comments on commit 556db4d

Please sign in to comment.