useDateFormat
Provider-agnostic date / datetime / time formatting context for Docyrus UI components. Wired automatically by DocyrusTenantProvider, but works with any date library.
Installation
pnpm dlx @docyrus/cli add @docyrus/hooks-use-date-formatThe module exports useDateFormat() (hook) and <DateFormatProvider> (provider). It has zero runtime dependencies — the formatter itself is supplied by you (or by a parent <DocyrusTenantProvider>).
Overview
useDateFormat() is the read side of a small provider-agnostic context. Components inside the tree call it to get { formatDate, formatDateTime, formatTime }; the provider above the tree decides how the formatting actually happens.
- No provider mounted → the hook returns a built-in sentinel that renders raw strings (
String(value)for strings,.toISOString()forDateobjects). Data-grid / data-table hooks detect this and skip injecting the formatter so the cell's own legacy fallback (formatDateForDisplay) still runs. <DocyrusTenantProvider>mounted → the provider installsformatDate/formatDateTime/formatTimebacked by the tenant'sdateUtils(from@docyrus/app-utils), so every cell / calendar event / side-filter chip respects the tenant'sdateFormat,dateTimeFormat,longDateFormat, andtimeZonesettings.- Custom provider mounted → you decide. Wrap any library (date-fns, dayjs, Luxon, Intl) with
<DateFormatProvider>and components inside the tree pick it up the same way.
Usage
Consume in a component
import { useDateFormat } from '@docyrus/ui/hooks/use-date-format';
function EventRow({ startsAt }: { startsAt: string }) {
const { formatDateTime } = useDateFormat();
return <span>{formatDateTime(startsAt)}</span>;
}Standard setup — let <DocyrusTenantProvider> do it
If your app already wraps its root in <DocyrusTenantProvider>, you don't have to do anything. Tenant-aware formatDate / formatDateTime / formatTime are already wired.
Custom provider (date-fns example)
import { format } from 'date-fns';
import { DateFormatProvider } from '@docyrus/ui/hooks/use-date-format';
function App({ children }) {
return (
<DateFormatProvider
formatDate={v => format(new Date(v as string), 'dd/MM/yyyy')}
formatDateTime={v => format(new Date(v as string), 'dd/MM/yyyy HH:mm')}
formatTime={v => format(new Date(v as string), 'HH:mm')}>
{children}
</DateFormatProvider>
);
}The same pattern works with dayjs, next-intl, or any other library.
API Reference
useDateFormat()
Returns DateFormatContextValue.
| Field | Type | Description |
|---|---|---|
formatDate | (value: unknown) => string | Date-only output. |
formatDateTime | (value: unknown) => string | Date + time output. |
formatTime | (value: unknown) => string | Time-only output. |
<DateFormatProvider>
| Prop | Type | Description |
|---|---|---|
formatDate | DateFormatFn | Required. Backs formatDate inside the tree. |
formatDateTime | DateFormatFn | Required. Backs formatDateTime inside the tree. |
formatTime | DateFormatFn | Required. Backs formatTime inside the tree. |
children | ReactNode | Tree to wrap. |
isDefaultDateFormatContext(ctx)
Returns true when the value returned by useDateFormat() is the built-in no-provider sentinel (raw string renderer) rather than a real provider. Internal hooks use this to avoid shadowing a cell's own fallback when no provider is mounted. Most apps don't need to call it directly.
Type Exports
| Type | Description |
|---|---|
DateFormatFn | Signature of each formatter function ((value: unknown) => string). |
DateFormatContextValue | Shape returned by useDateFormat(). |
useDataExport
Project an in-memory array of rows through a column definition and trigger a browser download as CSV, JSON, Markdown, or XLSX.
useDocyrusAdaptiveCardItemDetail
Generate an Adaptive Card JSON payload from a Docyrus field list + a single record — mapping Docyrus field types onto the Adaptive Cards element vocabulary — and render it with the shared AdaptiveCard renderer.