anyfamily-react
v2.2.0
Published
React hooks for the any* family — useAnywhen, useAnyamount, useAnyamountSymbol, useAnymany, useAnyaround, useAnylong, useAnyplural, useAnyword, useAnylocale, with live-updating relative time and a shared locale provider.
Maintainers
Keywords
Readme
anyfamily-react
React hooks for the any* family:
anywhen,
anyamount,
anymany,
anyaround,
anylong,
anyplural,
anyword and
anylocale as hooks, sharing one
locale and keeping relative time fresh without hand-rolled setInterval
plumbing.
npm install anyfamily-reactAlso published to GitHub Packages, where names must carry the owner's scope:
@kirilinsky/anyfamily-react. GitHub requires auth even for public packages, so add a
token with read:packages to your .npmrc:
@kirilinsky:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${GITHUB_TOKEN}npm install @kirilinsky/anyfamily-reactSame code, same version, different name — npmjs is the primary registry.
import { AnyfamilyProvider, useAnywhen, useAnyamount } from "anyfamily-react";
function App() {
return (
<AnyfamilyProvider locale="en">
<Post publishedAt={post.createdAt} price={1999} />
</AnyfamilyProvider>
);
}
function Post({ publishedAt, price }: { publishedAt: Date; price: number }) {
const when = useAnywhen(publishedAt, { mode: "relative" }); // "3 hours ago", ticks itself
const cost = useAnyamount(price, { mode: "currency", currency: "EUR" });
return <p>{cost} — {when}</p>;
}why hooks and not just the functions
AnyfamilyProvider— setlocaleonce, every hook below picks it up. A hook's ownoptions.localealways wins over the provider. Changing the provider'slocalere-renders every hook under it, same as any React context.defaultsfor the settings that never vary — a currency, a time zone, a style, repeated at forty call sites, set once instead. One slot per hook family; a call site's own options win key by key.<AnyfamilyProvider locale="de-DE" defaults={{ anyamount: { mode: "currency", currency: "EUR" }, anywhen: { refresh: 30_000 }, }} >useAnyamount(1999); // "1.999,00 €" useAnyamount(1999, { mode: "currency", currency: "USD" }); // the call wins useAnyamount(3.2, { mode: "unit", unit: "gigabyte" }); // another mode: the // default's currency is dropped rather than carried in. Only `locale` crosses // modes.useAnyfamilyDefaults()reads them back, for wrapping a hook of your own.useAnywhenticks itself — relative output ("3 minutes ago") goes stale the instant the component stops re-rendering. The hook re-renders on an interval (default 60s,refreshto override,refresh: falseto disable) so it doesn't. No tick in"absolute"mode or once a date is over a day old — nothing left that a minute-granularity poll would change. The default tick is a fixed poll, not synced to unit boundaries: a transition like "59 seconds ago" → "1 minute ago" can lag up to one tick behind. Pass an explicitrefreshif you need tighter alignment.
hooks
useAnywhen(date, options?)— seeanywhen.options.refreshcontrols the tick interval.useAnyamount(value, options?)— seeanyamount.useAnyamountSymbol(currency, options?)— seeanyamount.symbol. The bare currency symbol, for labels and input affixes where the amount is rendered separately.useAnymany(items, options?)— seeanymany.useAnyaround(code, options?)— seeanyaround.useAnylong(input, options?)— seeanylong.anylongSupportedis re-exported for the same feature-detection anylong itself provides.useAnyplural(count, forms, options?)— seeanyplural.useAnyword(text, options?)— seeanyword. Returnsstring[], memoized on the text and the options' contents, so the array keeps its reference between renders and is safe as an effect dependency.useAnywordCount(text, options?)— seeanyword.count.useAnywordTruncate(text, limit, options?)— seeanyword.truncate.anywordSupportedis re-exported for feature-detectingIntl.Segmenter, which all three anyword hooks require.useAnylocale(tag?)— seeanylocale. Unlike the others it takes the tag as its argument, so with no argument it falls back to the provider's locale and then to the runtime's. Returns an object, memoized on the tag, so it is safe as an effect dependency.anylocaleSupportedis re-exported for feature-detectingIntl.Localeinfo.
useAnyfamilyLocale() reads the locale from the nearest provider directly,
for anything not covered by the hooks above.
the plain functions, too
All eight are re-exported, so formatting outside a hook — in an event handler,
inside a useMemo, in a callback handed downward — doesn't need the underlying
package as a second dependency:
import { anywhen, anyword } from "anyfamily-react";
<button onClick={() => copy(anywhen(post.createdAt, { mode: "absolute" }))}>They are the same bindings the hooks call, extras included — anyword.count,
anyamount.symbol, anylong.supported. They carry this package's
"use client" boundary with them: to format in a server component, import from
anyfamily instead.
anywhen · anyamount · anymany · anyaround · anylong · anyplural · anyword · anylocale
license
MIT © kirilinsky
