@brandup/ui-helpers
v2.0.5
Published
JavaScript helpers
Maintainers
Readme
brandup-ui-helpers
Installation
Install NPM package @brandup/ui-helpers.
npm i @brandup/ui-helpers@latestHelper groups
The package exposes the following named helper groups:
| Import | Module |
| --- | --- |
| ObjectHelper | object property access by path |
| TypeHelper | runtime type checks |
| FuncHelper | timing / async helpers |
| WordHelper | word pluralization |
| Guid | GUID generation |
| formatText | string template formatting |
import { ObjectHelper, TypeHelper, FuncHelper, WordHelper, Guid, formatText } from "@brandup/ui-helpers";String helpers
formatText substitutes {...} placeholders in a template.
Format with model values (placeholders are dot-separated property paths):
import { formatText } from "@brandup/ui-helpers";
const result = formatText("Hello, {name}", { name: "Dmitry" }); // Hello, DmitryFormat with positional arguments (placeholders are zero-based indexes):
const result = formatText("Hello, {0}", "Dmitry"); // Hello, DmitryFormat text
formatText substitutes {...} placeholders in a template — by name from a model object, or by zero-based index from positional arguments.
import { formatText } from "@brandup/ui-helpers";
formatText("Hello, {name}", { name: "Dmitry" }); // "Hello, Dmitry"
formatText("Hello, {0}", "Dmitry"); // "Hello, Dmitry"Object helpers
ObjectHelper reads nested values by a dot-separated path.
import { ObjectHelper } from "@brandup/ui-helpers";
const model = { header: { value: "Item" } };
ObjectHelper.getProperty(model, "header.value"); // "Item"
ObjectHelper.hasProperty(model, "header.value"); // truegetProperty(obj, path)— returns the resolved value;nullwhenobjis falsy,undefinedwhen any path segment is missing or a mid-path value isnull/primitive.hasProperty(obj, path)— returnstrueif every segment of the path exists; safely returnsfalsewhen a mid-path value isnullor a primitive.
Type helpers
TypeHelper provides runtime type checks.
import { TypeHelper } from "@brandup/ui-helpers";
TypeHelper.isFunction(() => {}); // true
TypeHelper.isString("text"); // trueisFunction(value)—trueif the value is a function.isString(value)—truefor string primitives andStringinstances.
Word helpers
WordHelper.getWordEnd picks a grammatical ending that agrees with a count (Russian-style pluralization).
import { WordHelper } from "@brandup/ui-helpers";
WordHelper.getWordEnd(1, "товар", "", "а", "ов"); // товар
WordHelper.getWordEnd(3, "товар", "", "а", "ов"); // товара
WordHelper.getWordEnd(5, "товар", "", "а", "ов"); // товаровgetWordEnd(count, word, one?, two?, five?)— appendsonefor counts ending in 1,twofor 2–4, andfivefor 0/5–9 and 11–20.
Guid helpers
Guid generates and exposes UUID values.
import { Guid } from "@brandup/ui-helpers";
const id = Guid.createGuid(); // e.g. "3f2a1b4c-9d8e-4a23-b123-456789abcdef"
Guid.empty; // "00000000-0000-0000-0000-000000000000"createGuid()— a new RFC 4122 UUID v4 string (lowercase, usescrypto.randomUUID()).empty— the all-zero UUID constant.
Func helpers
FuncHelper contains timing and async utilities.
import { FuncHelper } from "@brandup/ui-helpers";
// Resolve after 500ms (cancellable via AbortSignal)
await FuncHelper.delay(500);
// Keep a loading state visible for at least 1000ms
const data = await FuncHelper.minWaitAsync(() => loadData(), 1000);
// Reject with TimeoutError if the request takes longer than 5000ms
const result = await FuncHelper.timeout(fetch("/api"), 5000);
// Make the wait abortable without stopping the underlying work
const value = await FuncHelper.abortable(longRunning(), abortController.signal);Detect a timeout by checking the error type:
import { FuncHelper } from "@brandup/ui-helpers";
try {
const result = await FuncHelper.timeout(fetch("/api"), 5000);
} catch (e) {
if (e instanceof FuncHelper.TimeoutError) {
console.log("Request timed out");
}
}minWait(func, minTime?)— wraps a callback so it runs no sooner thanminTimems after wrapping.minWaitAsync(func, minTime?, abort?)— awaits an async operation, padding so it settles no sooner thanminTimems. An already-aborted signal rejects immediately, beforefuncruns.delay(ms, abort?)— a promise resolved aftermsms; rejects on abort. Throws synchronously ifmsis negative (0is allowed).timeout(promise, ms, abort?)— racespromiseagainstmsms; rejects with aTimeoutErroron timeout, or with the signal's reason on abort. Throws synchronously ifms ≤ 0. The underlyingpromiseis not cancelled — only the wait ends.abortable(promise, abort?)— makes waiting forpromiseabortable: rejects with the signal's reason on abort. Does not stop the underlying work; without a signal the promise is awaited as-is.TimeoutError— error class thrown bytimeoutwhen the time limit is exceeded.
Polyfills
An opt-in, side-effect-only entry point fills in AbortSignal APIs that older runtimes may lack — AbortSignal.prototype.throwIfAborted, AbortSignal.timeout and AbortSignal.any. Import it once, as early as possible (e.g. in your entry module):
import "@brandup/ui-helpers/polyfill";Each implementation installs only when missing, so native behaviour is preserved where available. Types ship with the TypeScript ESNext lib; this module provides just the runtime. It is excluded from tree-shaking (sideEffects), so a bare import is never dropped by the bundler.
