/use-global-boolean

A React hook for globally managing Boolean state without using context. Allows passing and accessing state in any component.

Primary LanguageTypeScriptMIT LicenseMIT

useGlobalBoolean

GitHub NPM Version

useGlobalBoolean is a hook for managing global boolean variables. It can be used to open modals, sidebars, disable elements on a page, hide elements, and pass any arguments.

🔧 Installation

# Using yarn.
yarn add use-global-boolean

# Using npm.
npm install use-global-boolean

Examples

Static Badge Static Badge

If you want to explore a complex example, follow the link.
Описание изображения

🔎 Usage

To use this hook, you'll need useGlobalBoolean and useBooleanController:

// At the top of your file.
import { useGlobalBoolean, useBooleanController } from "use-global-boolean";

// First, register a modal with a unique name.
const WelcomeModal = () => {
    const [opened, { setFalse }] = useBooleanController('modal_welcome');

    return (
        <dialog open={opened}>
            <button type="button" onClick={setFalse}>Close</button>
        </dialog>
    );
}

// Now, trigger our modal from anywhere in the application.
const Header = () => {
    const { setTrue } = useGlobalBoolean();

    return (
        <header>
            {/* ... */}
            <div role="menu">
                <button type="button" onClick={() => setTrue('modal_welcome')}>Welcome modal</button>
                <button type="button">Logout</button>
            </div>
        </header>
    );
}

const App = () => {
    return (
        <>
            <Header />
            <WelcomeModal />
        </>
    );
}

export default App

🫱🏿🫲🏿 Passing arguments

In addition to a boolean value, you can also pass data as a second argument, which can be of any type. Data can be passed as the second argument to onTrue and onToggle from useGlobalBoolean, as well as to globalBooleanActions.setTrue() and globalBooleanActions.toggle()

import { useGlobalBoolean, useBooleanController } from "use-global-boolean";

const EmailModal = () => {
    // Register the modal with a unique identifier and initial parameters
    const [opened, { data, setFalse }] = useBooleanController('email_modal', false, { email: '' });

    return (
      <dialog open={opened}>
         <input value={data.email} />
         <button type="button" onClick={setFalse}>Close</button>
         <button type="submit">Send email</button>
      </dialog>
    )
}

const Button = () => {
    const { setTrue } = useGlobalBoolean();

    // Button to open the email modal, passing parameters
    return <button onClick={() => setTrue('email_modal', { email: 'hello@world.com' })}>Open modal</button>
}

const App = () => (
    <>
        <Button />
        <EmailModal />
    </>
);

👀 watchBoolean / useWatchBoolean

We can break our components into smaller parts and track the changed state in a separate component using watchBoolean from useGlobalBoolean or the useWatchBoolean hook.

import { useGlobalBoolean, useBooleanController, useWatchBoolean } from "use-global-boolean";

const Form = () => {
    // Using watchBoolean from useGlobalBoolean
    const { watchBoolean } = useGlobalBoolean();
    const [isEnabled] = watchBoolean('enable_form');

    // Or using useWatchBoolean directly
    // const [isEnabled] = useWatchBoolean('enable_form');


    return isEnabled && (
        <form>
            <label htmlFor="fname">First name:</label>
            <br />
            <input type="text" id="fname" name="fname" defaultValue="John" />
            <br />
            <label htmlFor="lname">Last name:</label>
            <br />
            <input type="text" id="lname" name="lname" defaultValue="Doe" />
            <br />
            <br />
            <input type="submit" value="Submit" />
        </form>
    );
}

const EnableForm = () => {
    const [checked, { toggle }] = useBooleanController('enable_form');

    return (
        <label>
            <input
                type="checkbox"
                checked={checked}
                onChange={() => toggle()}
            />
            Enable form
        </label>
       
    );
}

const App = () => {
    return (
        <>
            {/* ... */}
            <EnableForm />
            <Form />
            {/* ... */}
        </>
    );
}

export default App

🎛️ WatchController

If we prefer not to break the component into smaller parts and instead want to write all the logic within a single component, we can ensure that only the parts we want to re-render will be updated. Let's refactor the above example to use WatchController.

import { WatchController } from "use-global-boolean";

const App = () => {
    return (
        <>
            <WatchController name="enable_form">
                {(props) => {
                    const [checked, { toggle }] = props.localState;
                    return (
                        <label>
                            <input type="checkbox" checked={checked} onChange={() => toggle()} />
                            Enable form
                        </label>
                    );
                }}
            </WatchController>
            <WatchController>
                {(props) => {
                    const [isEnabled] = props.globalMethods.watchBoolean('enable_form');

                    return (
                        isEnabled && (
                            <form>
                                <label htmlFor="fname">First name:</label>
                                <br />
                                <input type="text" id="fname" name="fname" defaultValue="John" />
                                <br />
                                <label htmlFor="lname">Last name:</label>
                                <br />
                                <input type="text" id="lname" name="lname" defaultValue="Doe" />
                                <br />
                                <br />
                                <input type="submit" value="Submit" />
                            </form>
                        )
                    );
                }}
            </WatchController>
        </>
    );
}

export default App

💪🏼 globalBooleanActions

If you need to change the state outside of a component.

import { useEffect } from 'react';
import { globalBooleanActions } from 'use-global-boolean';

const externalLogic = () => {
    /* Logic... */

    globalBooleanActions.setTrue('dialog');
};

const Dialog = () => {
    const [show] = useBooleanController('dialog');

    return (
        <dialog open={show}>
            <p>This is a modal dialog controlled by external logic.</p>
        </dialog>
    );
};

const App = () => {
    useEffect(() => {
        // Call the external logic after the component is mounted
        externalLogic();
    }, []);

    return <Dialog />;
};

export default App;

TypeScript TypeScript

// use-global-boolean.d.ts
import 'use-global-boolean';

declare module "use-global-boolean" {
    interface ListBooleanNames {
        modal1: string;
        modal2: string;
        modal3: string;
    }
}

// Modal.tsx
import { useGlobalBoolean, useBooleanController, useWatchBoolean } from "use-global-boolean";

// Now TypeScript will provide suggestions:
useBooleanController('modal1'); // 'modal1', 'modal2', 'modal3'

const { setTrue, toggle, setFalse, watch } = useGlobalBoolean();
setTrue('modal1'); // 'modal1', 'modal2', 'modal3'
toggle('modal1'); // 'modal1', 'modal2', 'modal3'
setFalse('modal1'); // 'modal1', 'modal2', 'modal3'
watchBoolean('modal1'); // 'modal1', 'modal2', 'modal3'

useWatchBoolean('modal1'); // 'modal1', 'modal2', 'modal3'

Описание изображения