npm install --save @darkobits/react-kit
render
lazy
assertIsBrowser
setCssVariable
hideCursor
/showCursor
emit
injectScript
jsonToBase64
/base64ToJson
getPlatformDetails
isMobile
isStandalone
prefetchImage
- Other Resources
// Import
import { render } from '@darkobits/react-kit/render';
// Signature
function render(selector: string, element: JSX.Element): () => void;
Shorthand for rendering a React root at the provided selector using react-dom/client
. This function
performs the following actions:
- Use
document.querySelector
to locate the target element indicated byselector
. - If no element was found, throw.
- Create a root using
createRoot
. - Call
root.render
, passing the providedelement
. - Return the root's
unmount
function.
⚠️ This package declaresreact-dom
as a peer dependency. However, you should still installreact-dom
as a dependency of your project, even if your package manager automatically installs peer dependencies.
index.tsx
import { render } from '@darkobits/react-kit/render';
import { App } from './App';
render('#root', <App />);
// Import
import { lazy } from '@darkobits/react-kit/lazy';
// Signature
function lazy<
M extends Record<string, any>,
K extends keyof M
>(loader: () => Promise<M>): AsPreLoadableLazyExotics<M>
Facilitates the lazy loading of React components with some extras:
- You can use destructuring to reference named exports.
- You may optionally optimistically pre-load components.
Assuming we have a file Components.tsx
that exports 2 React components and some other value:
Components.tsx
export const Foo = () => {
return (
<div>Foo</div>
)
};
export const Bar = () => {
return (
<div>Bar</div>
);
}
export const Baz = false;
Then, in another file, we can lazily import these components thusly:
App.tsx
import { lazy } from '@darkobits/react-kit/lazy';
// Foo, Bar are correctly typed as lazy React components with their typed props,
// if applicable.
const { Foo, Bar } = lazy(async () => import('./Components.tsx'));
// Type error; Baz is not a component.
const { Baz } = lazy(async () => import('./Components.tsx'));
export const App = () => {
return (
<Foo />
<Bar />
)
}
Pre-Loading
This function attaches a static preload
method to components that can be invoked to optimistically
pre-load a component. This method returns a Promise
that will resolve when the component has loaded.
import { lazy } from '@darkobits/react-kit/lazy';
const { Foo } = lazy(async () => import('./Components.tsx'));
await Foo.preload();
Caveats
- When using this (or other solutions) to circumvent the default export requirement, tree-shaking will not work on the imported module. In most cases, this should not be an issue.
// Import
import { assertIsBrowser } from '@darkobits/react-kit/assert-is-browser';
// Signature
function assertIsBrowser(label?: string): void;
Ensures the current context is a browser environment. Throws an error otherwise. Useful for writing functions that interact with browser APIs.
export function reticulateSplines() {
assertIsBrowser();
// Safely interact with window, document, etc.
}
This function accepts an optional argument, label
, that will be used as a prefix in the error message
should the function throw:
export function reticulateSplines() {
assertIsBrowser('reticulateSplines');
// Safely interact with window, document, etc.
}
This will throw errors with the message: [reticulateSplines] Not in a browser environment.
// Import
import { setCssVariable } from '@darkobits/react-kit/css-variable';
// Signature
function setCssVariable(varName: string, value: any, scope = ':root'): void;
Sets a CSS variable on all elements matching the provided scope
. The default scope is :root
, which
is equivalent to the html
element.
// Set on <html>, available globally.
setCssVariable('--color', 'rgba(128, 128, 128, 0.6)');
// Only set on element(s) matching the provided selector.
setCssVariable('--color', 'rgba(128, 128, 128, 0.6)', '.my-element');
// To unset a variable, pass `false`, `null`, or `undefined`:
setCssVariable('--color', false);
setCssVariable('--color', null);
setCssVariable('--color');
// Import
import { hideCursor, showCursor } from '@darkobits/react-kit/hide-cursor';
// Signatures
function hideCursor(): void;
function showCursor(): void;
Hides the cursor by adding a <style>
tag to the <head>
that sets the cursor to an image of a 1px by
1px transparent PNG. The cursor may be shown again by calling showCursor
, which removes the <style>
tag.
// To hide the cursor:
hideCursor();
// To show the cursor again:
showCursor();
// Import
import { emit } from '@darkobits/react-kit/emit';
// Signature
function emit(eventName: string, eventData?: any): void;
Emits a CustomEvent
on the window
with optional event data. Event data will be assigned to the detail
property of the CustomEvent
.
Type-Safe Events
To add type-safety to this function as well as window.addEventListener
and window.dispatchEvent
,
create a file with the .d.ts
extension (globals.d.ts
is common) in your project with the following:
interface WindowEventMap {
'custom-event': CustomEvent<{
kittens: true
}>;
}
The interface WindowEventMap
is what addEventListener
and dispatchEvent
use to look-up known event
names and their corresponding data. The definition above will be merged with the global definition
such that window.addEventListener
will now be aware of custom-event
and its event data.
// Import
import { injectScript } from '@darkobits/react-kit/inject-script';
// Signature
function injectScript(src: string, attrs?: OptionalAttributes): Promise<void>
Facilitates loading external scripts at runtime by injecting a <script>
tag into the <head>
. Returns
a Promise that resolves when the script has finished loading. By default, the script's type
is set to
text/javascript
and its async
flag is set to true
. An optional second argument may be provided to
override these settings and set additional attributes.
await injectScript('https://code.jquery.com/jquery-3.3.1.min.js');
await injectScript('https://code.jquery.com/jquery-3.3.1.min.js', {
integrity: 'sha384-tsQFqpEReu7ZLhBV2VZlAu7zcOV+rXbYlF2cqB8txI/8aZajjp4Bqd+V6D5IgvKT',
crossOrigin: 'anonymous'
});
// Import
import { jsonToBase64, base64ToJson } from '@darkobits/react-kit/json-base64';
// Signatures
function jsonToBase64(value: any): string;
function base64ToJson(value: string): any;
jsonToBase64
serializes the provided JSON value as a base-64-encoded string. base64ToJson
deserializes a similarly-encoded value.
jsonToBase64({ kittens: true }) //=> 'eyJraXR0ZW5zIjp0cnVlfQ=='
base64ToJson('eyJraXR0ZW5zIjp0cnVlfQ==') //=> { kittens: true }
// Import
import { getPlatformDetails } from '@darkobits/react-kit/platform';
// Signature
function getPlatformDetails(): Bowser.Parser.ParsedResult;
Returns details about the current browser, operating system, device, and rendering engine using
bowser
. This function creates a bowser
parser, parses the
current user agent string, then caches and returns the result. Subsequent invocations return the cached
result.
Example result:
{
browser: {
name: 'Internet Explorer'
version: '11.0'
},
os: {
name: 'Windows'
version: 'NT 6.3'
versionName: '8.1'
},
platform: {
type: 'desktop'
},
engine: {
name: 'Trident'
version: '7.0'
}
}
// Import
import { isMobile } from '@darkobits/react-kit/platform';
// Signature
function isMobile(): boolean;
Calls getPlatformDetails
(see above) and returns true
if the platform type is either mobile
or
tablet
.
// Import
import { isStandalone } from '@darkobits/react-kit/platform';
// Signature
function isStandalone(): boolean;
Returns true
if the page is currently being displayed in standalone
mode, relevant for Progressive Web Apps.
// Import
import { prefetchImage } from '@darkobits/react-kit/prefetch-image';
// Signature
function prefetchImage(imgUrl?: string): Promise<string>;
Pre-fetches an image by creating a new Image
. Returns a promise that resolves with the provided URL
when the image has finished loading. Useful for avoiding flicker / loading when adding images to the DOM
dynamically.
If this function is provided a falsy value, it will resolve with an empty string.
⚠️ This function is memoized; subsequent invocations using the same URL will return the first value.
getImageUrlSomehow()
.then(prefetchImage)
.then(doSomethingWithImageUrl);
-
react-use
- Comprehensive set of React hooks.