@richardmcquiston01/dashboard-widgets-toolkit 0.1.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +113 -8
- package/dist/core.cjs +690 -64
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +87 -18
- package/dist/core.d.ts +87 -18
- package/dist/core.js +666 -65
- package/dist/core.js.map +1 -1
- package/dist/index.cjs +690 -64
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +666 -65
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +1594 -72
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +164 -14
- package/dist/react.d.ts +164 -14
- package/dist/react.js +1592 -74
- package/dist/react.js.map +1 -1
- package/dist/{scale-WlRozDCf.d.cts → scale-dWDGE1zW.d.cts} +327 -108
- package/dist/{scale-WlRozDCf.d.ts → scale-dWDGE1zW.d.ts} +327 -108
- package/dist/styles.css +156 -6
- package/package.json +1 -1
package/dist/react.d.cts
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
2
|
-
import { D as DashboardWidget, W as WidgetSize, G as GraphWidgetData, N as NiceDomain, L as Locale,
|
|
1
|
+
import { ReactNode, RefObject } from 'react';
|
|
2
|
+
import { D as DashboardWidget, W as WidgetSize, a as WidgetFill, G as GraphWidgetData, N as NiceDomain, b as WidgetDefinition, c as DetailProviderOptions, d as DetailData, e as DetailQuery, L as Locale, f as DashboardLayout, A as AlertListWidgetData, B as BarListWidgetData, g as GaugeWidgetData, K as KpiWidgetData, T as TableWidgetData, h as TextWidgetData, i as WidgetData, R as ResolveOptions, j as WidgetContext, k as WidgetProviders } from './scale-dWDGE1zW.cjs';
|
|
3
3
|
|
|
4
4
|
interface WidgetCardProps {
|
|
5
5
|
readonly title: string;
|
|
6
6
|
readonly description?: string;
|
|
7
|
-
/** Extra controls in the header (move, hide...), before the
|
|
7
|
+
/** Extra controls in the header (move, hide...), before the minimize toggle. */
|
|
8
8
|
readonly actions?: ReactNode;
|
|
9
9
|
readonly minimized?: boolean;
|
|
10
|
-
/** Shows the
|
|
10
|
+
/** Shows the minimize/expand toggle when given. */
|
|
11
11
|
readonly onToggleMinimized?: () => void;
|
|
12
|
+
/**
|
|
13
|
+
* Opens the widget's detail view. Adds a "View" icon button to the header
|
|
14
|
+
* actions and makes the title clickable (for mouse and touch; the button is
|
|
15
|
+
* the accessible control).
|
|
16
|
+
*/
|
|
17
|
+
readonly onView?: () => void;
|
|
12
18
|
/** Default 'ok', which renders `children`. */
|
|
13
19
|
readonly status?: 'ok' | 'loading' | 'empty' | 'error';
|
|
14
20
|
readonly emptyText?: string;
|
|
@@ -17,6 +23,20 @@ interface WidgetCardProps {
|
|
|
17
23
|
readonly onRetry?: () => void;
|
|
18
24
|
readonly footer?: ReactNode;
|
|
19
25
|
readonly size?: WidgetSize;
|
|
26
|
+
/** Fill free space in the grid row (height, width or both). */
|
|
27
|
+
readonly fill?: WidgetFill;
|
|
28
|
+
/**
|
|
29
|
+
* Explicit grid column span, set by `Dashboard` and `WidgetGrid` to give a
|
|
30
|
+
* width-filling card the columns left over in its row.
|
|
31
|
+
*/
|
|
32
|
+
readonly columnSpan?: number;
|
|
33
|
+
/** 12-column width (see `WidgetDefinition.width`); sets `--dwt-width`. */
|
|
34
|
+
readonly width?: number;
|
|
35
|
+
/**
|
|
36
|
+
* The widget's key, rendered as `data-widget-key` so `useWidgets` can tell
|
|
37
|
+
* which card scrolled into view. `ResolvedWidgetCard` sets it for you.
|
|
38
|
+
*/
|
|
39
|
+
readonly widgetKey?: string;
|
|
20
40
|
/** 2 to 6; default 2. */
|
|
21
41
|
readonly headingLevel?: 2 | 3 | 4 | 5 | 6;
|
|
22
42
|
readonly className?: string;
|
|
@@ -24,16 +44,22 @@ interface WidgetCardProps {
|
|
|
24
44
|
}
|
|
25
45
|
/**
|
|
26
46
|
* The frame every widget sits in: title, optional description and actions,
|
|
27
|
-
* a
|
|
47
|
+
* a minimize toggle, and loading, empty and error states.
|
|
28
48
|
*/
|
|
29
|
-
declare function WidgetCard({ title, description, actions, minimized, onToggleMinimized, status, emptyText, error, onRetry, footer, size, headingLevel, className, children, }: WidgetCardProps): ReactNode;
|
|
49
|
+
declare function WidgetCard({ title, description, actions, minimized, onToggleMinimized, onView, status, emptyText, error, onRetry, footer, size, fill, columnSpan, width, widgetKey, headingLevel, className, children, }: WidgetCardProps): ReactNode;
|
|
30
50
|
/** The title to show: alert lists add their total, e.g. "Low stock (3)". */
|
|
31
51
|
declare function widgetTitle(widget: DashboardWidget): string;
|
|
32
52
|
interface ResolvedWidgetCardProps {
|
|
33
53
|
readonly widget: DashboardWidget;
|
|
54
|
+
/** See `WidgetCardProps.columnSpan`. */
|
|
55
|
+
readonly columnSpan?: number;
|
|
56
|
+
/** 12-column width (see `WidgetDefinition.width`); sets `--dwt-width`. */
|
|
57
|
+
readonly width?: number;
|
|
34
58
|
readonly actions?: ReactNode;
|
|
35
59
|
readonly minimized?: boolean;
|
|
36
60
|
readonly onToggleMinimized?: () => void;
|
|
61
|
+
/** See `WidgetCardProps.onView`. */
|
|
62
|
+
readonly onView?: () => void;
|
|
37
63
|
readonly onRetry?: () => void;
|
|
38
64
|
readonly headingLevel?: 2 | 3 | 4 | 5 | 6;
|
|
39
65
|
readonly className?: string;
|
|
@@ -59,8 +85,65 @@ declare function GraphWidget({ data, title, }: {
|
|
|
59
85
|
readonly title?: string;
|
|
60
86
|
}): ReactNode;
|
|
61
87
|
|
|
88
|
+
/**
|
|
89
|
+
* Loads a widget's full detail data. Close over your own context (a Prisma
|
|
90
|
+
* client, a fetch) here; the package never fetches. See `DetailProvider`.
|
|
91
|
+
*/
|
|
92
|
+
type DetailLoader = (definition: WidgetDefinition, options: DetailProviderOptions) => DetailData | Promise<DetailData>;
|
|
93
|
+
interface WidgetDetailProps {
|
|
94
|
+
/** Table caption: the widget's title. */
|
|
95
|
+
readonly title: string;
|
|
96
|
+
/** The rows to show. Absent while `status` is `loading` or `error`. */
|
|
97
|
+
readonly data?: DetailData;
|
|
98
|
+
/** Controlled: you own the query, so you can keep it in the URL. */
|
|
99
|
+
readonly query: DetailQuery;
|
|
100
|
+
readonly onQueryChange: (query: DetailQuery) => void;
|
|
101
|
+
/** Default `ok`. */
|
|
102
|
+
readonly status?: 'ok' | 'loading' | 'error';
|
|
103
|
+
readonly error?: string;
|
|
104
|
+
readonly onRetry?: () => void;
|
|
105
|
+
/** Heading level of the title, 2 to 6. Default 2. */
|
|
106
|
+
readonly headingLevel?: 2 | 3 | 4 | 5 | 6;
|
|
107
|
+
/** Id of the heading, so a dialog can label itself with it. */
|
|
108
|
+
readonly headingId?: string;
|
|
109
|
+
readonly className?: string;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* The detail view of a widget: search and column filters, a sortable table
|
|
113
|
+
* and paging, over data you give it (client mode: it filters, sorts and pages
|
|
114
|
+
* in memory with `queryRows`). Controlled by `query`. Use it on its own as a
|
|
115
|
+
* page, or inside `WidgetDetailDialog`.
|
|
116
|
+
*/
|
|
117
|
+
declare function WidgetDetail({ title, data, query, onQueryChange, status, error, onRetry, headingLevel, headingId, className, }: WidgetDetailProps): ReactNode;
|
|
118
|
+
interface WidgetDetailDialogProps {
|
|
119
|
+
readonly title: string;
|
|
120
|
+
readonly open: boolean;
|
|
121
|
+
/** Called on Esc, the Close button and a click on the backdrop. */
|
|
122
|
+
readonly onClose: () => void;
|
|
123
|
+
readonly children: ReactNode;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* A native modal `<dialog>`: focus is trapped, Esc closes it, the page behind
|
|
127
|
+
* is inert, and focus returns to the control that opened it.
|
|
128
|
+
*/
|
|
129
|
+
declare function WidgetDetailDialog({ title, open, onClose, children, }: WidgetDetailDialogProps): ReactNode;
|
|
130
|
+
interface DetailLoadState {
|
|
131
|
+
readonly status: 'loading' | 'ok' | 'error';
|
|
132
|
+
readonly data?: DetailData;
|
|
133
|
+
readonly error?: string;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Loads a widget's detail data while `enabled`: calls `load` with an abort
|
|
137
|
+
* signal (aborted on close, retry or unmount), validates the result and
|
|
138
|
+
* reports loading, ok or error. `reload` runs it again.
|
|
139
|
+
*/
|
|
140
|
+
declare function useDetailData(definition: WidgetDefinition, load: DetailLoader | undefined, enabled: boolean): {
|
|
141
|
+
readonly state: DetailLoadState;
|
|
142
|
+
readonly reload: () => void;
|
|
143
|
+
};
|
|
144
|
+
|
|
62
145
|
/** Every element that carries a stable `dwt-*` class, for `classNames`. */
|
|
63
|
-
type DashboardClassSlot = 'dashboard' | 'hiddenBar' | 'grid' | 'card' | 'cardHeader' | 'cardTitle' | 'cardDescription' | 'cardActions' | 'cardBody' | 'cardFooter' | 'button' | 'status' | 'empty' | 'error' | 'text' | 'kpi' | 'gauge' | 'table' | 'barList' | 'alertList' | 'chart' | 'legend' | 'tooltip' | 'tableTwin';
|
|
146
|
+
type DashboardClassSlot = 'dashboard' | 'hiddenBar' | 'grid' | 'card' | 'cardHeader' | 'cardTitle' | 'cardDescription' | 'cardActions' | 'cardBody' | 'cardFooter' | 'button' | 'status' | 'empty' | 'error' | 'text' | 'kpi' | 'gauge' | 'table' | 'barList' | 'alertList' | 'chart' | 'legend' | 'tooltip' | 'tableTwin' | 'detail';
|
|
64
147
|
/**
|
|
65
148
|
* Extra classes per slot, appended to the `dwt-*` class (never replacing
|
|
66
149
|
* it), e.g. `{ card: 'rounded-lg shadow-sm' }` for Tailwind.
|
|
@@ -78,6 +161,22 @@ interface DashboardLabels {
|
|
|
78
161
|
readonly moveEarlier: (title: string) => string;
|
|
79
162
|
readonly moveLater: (title: string) => string;
|
|
80
163
|
readonly hiddenWidgets: string;
|
|
164
|
+
readonly minimizedWidgets: string;
|
|
165
|
+
/** Added to the accessible name of links that open in a new tab. */
|
|
166
|
+
readonly opensInNewTab: string;
|
|
167
|
+
/** The card's View button, opening the detail view. */
|
|
168
|
+
readonly view: (title: string) => string;
|
|
169
|
+
readonly close: string;
|
|
170
|
+
readonly search: string;
|
|
171
|
+
readonly filterBy: (column: string) => string;
|
|
172
|
+
readonly sortBy: (column: string) => string;
|
|
173
|
+
readonly noResults: string;
|
|
174
|
+
/** e.g. "Showing 1–25 of 312 results". */
|
|
175
|
+
readonly showingRows: (from: number, to: number, total: number) => string;
|
|
176
|
+
readonly previousPage: string;
|
|
177
|
+
readonly nextPage: string;
|
|
178
|
+
readonly pageOf: (page: number, pageCount: number) => string;
|
|
179
|
+
readonly pagination: string;
|
|
81
180
|
readonly allHidden: string;
|
|
82
181
|
readonly noWidgets: string;
|
|
83
182
|
readonly andMore: (count: number) => string;
|
|
@@ -122,28 +221,40 @@ interface DashboardProps extends WidgetSettings {
|
|
|
122
221
|
/** The viewer's saved layout. Default: none saved. */
|
|
123
222
|
readonly layout?: DashboardLayout;
|
|
124
223
|
/**
|
|
125
|
-
* Called with the next layout after a move, hide, show,
|
|
224
|
+
* Called with the next layout after a move, hide, show, minimize or
|
|
126
225
|
* restore; persist it. Without it the layout is read-only (no controls).
|
|
127
226
|
*/
|
|
128
227
|
readonly onLayoutChange?: (layout: DashboardLayout) => void;
|
|
129
228
|
readonly onRetry?: (key: string) => void;
|
|
229
|
+
/**
|
|
230
|
+
* Loads the full data for a widget's detail view (widgets whose definition
|
|
231
|
+
* sets `detail`). Close over your own context. Without it, TABLE widgets
|
|
232
|
+
* with no footer and BAR_LIST widgets show their card data; other widgets
|
|
233
|
+
* get no View button.
|
|
234
|
+
*/
|
|
235
|
+
readonly loadDetail?: DetailLoader;
|
|
236
|
+
/**
|
|
237
|
+
* Called with the widget key when the viewer opens a detail view, instead
|
|
238
|
+
* of the built-in dialog: navigate to your own page.
|
|
239
|
+
*/
|
|
240
|
+
readonly onOpenDetail?: (key: string) => void;
|
|
130
241
|
readonly headingLevel?: 2 | 3 | 4 | 5 | 6;
|
|
131
242
|
readonly className?: string;
|
|
132
243
|
}
|
|
133
244
|
/**
|
|
134
245
|
* A full dashboard: widgets ordered by the viewer's layout, with move,
|
|
135
|
-
* hide/show and
|
|
246
|
+
* hide/show and minimize controls when `onLayoutChange` is given. Settings
|
|
136
247
|
* (locale, link target, classNames, labels) apply to every widget inside.
|
|
137
248
|
*/
|
|
138
249
|
declare function Dashboard({ locale, linkTarget, classNames, labels, ...props }: DashboardProps): ReactNode;
|
|
139
250
|
|
|
140
251
|
/**
|
|
141
|
-
* Default
|
|
252
|
+
* Default colors, used as `var(--dwt-*, fallback)` so charts read correctly
|
|
142
253
|
* without the stylesheet. `styles.css` redefines them for dark mode, and an
|
|
143
254
|
* app can override any of them with its own CSS custom properties.
|
|
144
255
|
*
|
|
145
256
|
* The categorical order is the dataviz reference palette, validated for
|
|
146
|
-
*
|
|
257
|
+
* color-vision deficiency on adjacent pairs in light and dark modes. Slots
|
|
147
258
|
* are assigned in this fixed order, never cycled, and follow the series
|
|
148
259
|
* (its position in the payload), never its rank.
|
|
149
260
|
*/
|
|
@@ -171,7 +282,7 @@ declare function TextWidget({ data, }: {
|
|
|
171
282
|
}): ReactNode;
|
|
172
283
|
/**
|
|
173
284
|
* KPI: a stat tile. The change against the previous period carries an arrow
|
|
174
|
-
* and signed text as well as
|
|
285
|
+
* and signed text as well as color, so it never relies on color alone.
|
|
175
286
|
*/
|
|
176
287
|
declare function KpiWidget({ data, }: {
|
|
177
288
|
readonly data: KpiWidgetData;
|
|
@@ -185,7 +296,7 @@ declare function TableWidget({ data, }: {
|
|
|
185
296
|
readonly data: TableWidgetData;
|
|
186
297
|
}): ReactNode;
|
|
187
298
|
/**
|
|
188
|
-
* BAR_LIST: labelled horizontal bars. One series, so one
|
|
299
|
+
* BAR_LIST: labelled horizontal bars. One series, so one color (slot 1)
|
|
189
300
|
* for every bar; the value text sits beside the bar, never inside it.
|
|
190
301
|
*/
|
|
191
302
|
declare function BarListWidget({ data, }: {
|
|
@@ -200,4 +311,43 @@ declare function WidgetContent({ data, }: {
|
|
|
200
311
|
readonly data: WidgetData;
|
|
201
312
|
}): ReactNode;
|
|
202
313
|
|
|
203
|
-
|
|
314
|
+
interface UseWidgetsOptions extends ResolveOptions {
|
|
315
|
+
/**
|
|
316
|
+
* When each widget's provider starts. `'mount'` (default): right after the
|
|
317
|
+
* first render, so the page and the dashboard shell appear first and each
|
|
318
|
+
* card fills in as its data arrives. `'visible'`: only once the card is
|
|
319
|
+
* near the viewport (attach `gridRef` to an element around the cards).
|
|
320
|
+
*/
|
|
321
|
+
readonly loadWhen?: 'mount' | 'visible';
|
|
322
|
+
/** `IntersectionObserver` margin for `loadWhen: 'visible'`. Default `'200px'`. */
|
|
323
|
+
readonly rootMargin?: string;
|
|
324
|
+
/**
|
|
325
|
+
* Reload started widgets every this many ms. Ticks are skipped while the
|
|
326
|
+
* tab is hidden, and a widget still loading is not restarted.
|
|
327
|
+
*/
|
|
328
|
+
readonly refreshMs?: number;
|
|
329
|
+
}
|
|
330
|
+
interface UseWidgetsResult {
|
|
331
|
+
/** Pass to `Dashboard` or `WidgetGrid`: placeholders first, then results. */
|
|
332
|
+
readonly widgets: readonly DashboardWidget[];
|
|
333
|
+
/** Reload one widget (for example from the error card's Retry) or all. */
|
|
334
|
+
readonly refresh: (key?: string) => void;
|
|
335
|
+
/**
|
|
336
|
+
* For `loadWhen: 'visible'`: attach to any element that contains the cards,
|
|
337
|
+
* for example a wrapper `<div ref={gridRef}>` around `Dashboard`.
|
|
338
|
+
*/
|
|
339
|
+
readonly gridRef: RefObject<HTMLDivElement | null>;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Loads widget data after the page has rendered and returns widgets for
|
|
343
|
+
* `Dashboard`. The first render never waits for data (so server rendering
|
|
344
|
+
* and first paint are unaffected); every widget starts as `loading`, loads
|
|
345
|
+
* independently, and replaces its placeholder when its own data arrives.
|
|
346
|
+
*
|
|
347
|
+
* Keep `definitions`, `providers`, `context` and `options.cache` referentially
|
|
348
|
+
* stable (module constants or `useMemo`): a changed value restarts loading,
|
|
349
|
+
* aborting whatever is in flight.
|
|
350
|
+
*/
|
|
351
|
+
declare function useWidgets<C extends WidgetContext>(definitions: readonly WidgetDefinition[], providers: WidgetProviders<C>, context: C, options?: UseWidgetsOptions): UseWidgetsResult;
|
|
352
|
+
|
|
353
|
+
export { AlertListWidget, BarListWidget, DEFAULT_LABELS, DEFAULT_SERIES_COLORS, Dashboard, type DashboardClassNames, type DashboardClassSlot, type DashboardLabels, type DashboardProps, type DetailLoadState, type DetailLoader, GaugeWidget, GraphWidget, KpiWidget, ResolvedWidgetCard, type ResolvedWidgetCardProps, TableWidget, TextWidget, Thumbnail, type UseWidgetsOptions, type UseWidgetsResult, WidgetCard, type WidgetCardProps, WidgetContent, WidgetDetail, WidgetDetailDialog, type WidgetDetailDialogProps, type WidgetDetailProps, WidgetGrid, type WidgetGridProps, WidgetLink, type WidgetSettings, WidgetSettingsProvider, barPath, buildChartModel, describeChart, joinClassNames, seriesColor, useDetailData, useWidgetSettings, useWidgets, widgetTitle };
|
package/dist/react.d.ts
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
|
-
import { ReactNode } from 'react';
|
|
2
|
-
import { D as DashboardWidget, W as WidgetSize, G as GraphWidgetData, N as NiceDomain, L as Locale,
|
|
1
|
+
import { ReactNode, RefObject } from 'react';
|
|
2
|
+
import { D as DashboardWidget, W as WidgetSize, a as WidgetFill, G as GraphWidgetData, N as NiceDomain, b as WidgetDefinition, c as DetailProviderOptions, d as DetailData, e as DetailQuery, L as Locale, f as DashboardLayout, A as AlertListWidgetData, B as BarListWidgetData, g as GaugeWidgetData, K as KpiWidgetData, T as TableWidgetData, h as TextWidgetData, i as WidgetData, R as ResolveOptions, j as WidgetContext, k as WidgetProviders } from './scale-dWDGE1zW.js';
|
|
3
3
|
|
|
4
4
|
interface WidgetCardProps {
|
|
5
5
|
readonly title: string;
|
|
6
6
|
readonly description?: string;
|
|
7
|
-
/** Extra controls in the header (move, hide...), before the
|
|
7
|
+
/** Extra controls in the header (move, hide...), before the minimize toggle. */
|
|
8
8
|
readonly actions?: ReactNode;
|
|
9
9
|
readonly minimized?: boolean;
|
|
10
|
-
/** Shows the
|
|
10
|
+
/** Shows the minimize/expand toggle when given. */
|
|
11
11
|
readonly onToggleMinimized?: () => void;
|
|
12
|
+
/**
|
|
13
|
+
* Opens the widget's detail view. Adds a "View" icon button to the header
|
|
14
|
+
* actions and makes the title clickable (for mouse and touch; the button is
|
|
15
|
+
* the accessible control).
|
|
16
|
+
*/
|
|
17
|
+
readonly onView?: () => void;
|
|
12
18
|
/** Default 'ok', which renders `children`. */
|
|
13
19
|
readonly status?: 'ok' | 'loading' | 'empty' | 'error';
|
|
14
20
|
readonly emptyText?: string;
|
|
@@ -17,6 +23,20 @@ interface WidgetCardProps {
|
|
|
17
23
|
readonly onRetry?: () => void;
|
|
18
24
|
readonly footer?: ReactNode;
|
|
19
25
|
readonly size?: WidgetSize;
|
|
26
|
+
/** Fill free space in the grid row (height, width or both). */
|
|
27
|
+
readonly fill?: WidgetFill;
|
|
28
|
+
/**
|
|
29
|
+
* Explicit grid column span, set by `Dashboard` and `WidgetGrid` to give a
|
|
30
|
+
* width-filling card the columns left over in its row.
|
|
31
|
+
*/
|
|
32
|
+
readonly columnSpan?: number;
|
|
33
|
+
/** 12-column width (see `WidgetDefinition.width`); sets `--dwt-width`. */
|
|
34
|
+
readonly width?: number;
|
|
35
|
+
/**
|
|
36
|
+
* The widget's key, rendered as `data-widget-key` so `useWidgets` can tell
|
|
37
|
+
* which card scrolled into view. `ResolvedWidgetCard` sets it for you.
|
|
38
|
+
*/
|
|
39
|
+
readonly widgetKey?: string;
|
|
20
40
|
/** 2 to 6; default 2. */
|
|
21
41
|
readonly headingLevel?: 2 | 3 | 4 | 5 | 6;
|
|
22
42
|
readonly className?: string;
|
|
@@ -24,16 +44,22 @@ interface WidgetCardProps {
|
|
|
24
44
|
}
|
|
25
45
|
/**
|
|
26
46
|
* The frame every widget sits in: title, optional description and actions,
|
|
27
|
-
* a
|
|
47
|
+
* a minimize toggle, and loading, empty and error states.
|
|
28
48
|
*/
|
|
29
|
-
declare function WidgetCard({ title, description, actions, minimized, onToggleMinimized, status, emptyText, error, onRetry, footer, size, headingLevel, className, children, }: WidgetCardProps): ReactNode;
|
|
49
|
+
declare function WidgetCard({ title, description, actions, minimized, onToggleMinimized, onView, status, emptyText, error, onRetry, footer, size, fill, columnSpan, width, widgetKey, headingLevel, className, children, }: WidgetCardProps): ReactNode;
|
|
30
50
|
/** The title to show: alert lists add their total, e.g. "Low stock (3)". */
|
|
31
51
|
declare function widgetTitle(widget: DashboardWidget): string;
|
|
32
52
|
interface ResolvedWidgetCardProps {
|
|
33
53
|
readonly widget: DashboardWidget;
|
|
54
|
+
/** See `WidgetCardProps.columnSpan`. */
|
|
55
|
+
readonly columnSpan?: number;
|
|
56
|
+
/** 12-column width (see `WidgetDefinition.width`); sets `--dwt-width`. */
|
|
57
|
+
readonly width?: number;
|
|
34
58
|
readonly actions?: ReactNode;
|
|
35
59
|
readonly minimized?: boolean;
|
|
36
60
|
readonly onToggleMinimized?: () => void;
|
|
61
|
+
/** See `WidgetCardProps.onView`. */
|
|
62
|
+
readonly onView?: () => void;
|
|
37
63
|
readonly onRetry?: () => void;
|
|
38
64
|
readonly headingLevel?: 2 | 3 | 4 | 5 | 6;
|
|
39
65
|
readonly className?: string;
|
|
@@ -59,8 +85,65 @@ declare function GraphWidget({ data, title, }: {
|
|
|
59
85
|
readonly title?: string;
|
|
60
86
|
}): ReactNode;
|
|
61
87
|
|
|
88
|
+
/**
|
|
89
|
+
* Loads a widget's full detail data. Close over your own context (a Prisma
|
|
90
|
+
* client, a fetch) here; the package never fetches. See `DetailProvider`.
|
|
91
|
+
*/
|
|
92
|
+
type DetailLoader = (definition: WidgetDefinition, options: DetailProviderOptions) => DetailData | Promise<DetailData>;
|
|
93
|
+
interface WidgetDetailProps {
|
|
94
|
+
/** Table caption: the widget's title. */
|
|
95
|
+
readonly title: string;
|
|
96
|
+
/** The rows to show. Absent while `status` is `loading` or `error`. */
|
|
97
|
+
readonly data?: DetailData;
|
|
98
|
+
/** Controlled: you own the query, so you can keep it in the URL. */
|
|
99
|
+
readonly query: DetailQuery;
|
|
100
|
+
readonly onQueryChange: (query: DetailQuery) => void;
|
|
101
|
+
/** Default `ok`. */
|
|
102
|
+
readonly status?: 'ok' | 'loading' | 'error';
|
|
103
|
+
readonly error?: string;
|
|
104
|
+
readonly onRetry?: () => void;
|
|
105
|
+
/** Heading level of the title, 2 to 6. Default 2. */
|
|
106
|
+
readonly headingLevel?: 2 | 3 | 4 | 5 | 6;
|
|
107
|
+
/** Id of the heading, so a dialog can label itself with it. */
|
|
108
|
+
readonly headingId?: string;
|
|
109
|
+
readonly className?: string;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* The detail view of a widget: search and column filters, a sortable table
|
|
113
|
+
* and paging, over data you give it (client mode: it filters, sorts and pages
|
|
114
|
+
* in memory with `queryRows`). Controlled by `query`. Use it on its own as a
|
|
115
|
+
* page, or inside `WidgetDetailDialog`.
|
|
116
|
+
*/
|
|
117
|
+
declare function WidgetDetail({ title, data, query, onQueryChange, status, error, onRetry, headingLevel, headingId, className, }: WidgetDetailProps): ReactNode;
|
|
118
|
+
interface WidgetDetailDialogProps {
|
|
119
|
+
readonly title: string;
|
|
120
|
+
readonly open: boolean;
|
|
121
|
+
/** Called on Esc, the Close button and a click on the backdrop. */
|
|
122
|
+
readonly onClose: () => void;
|
|
123
|
+
readonly children: ReactNode;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* A native modal `<dialog>`: focus is trapped, Esc closes it, the page behind
|
|
127
|
+
* is inert, and focus returns to the control that opened it.
|
|
128
|
+
*/
|
|
129
|
+
declare function WidgetDetailDialog({ title, open, onClose, children, }: WidgetDetailDialogProps): ReactNode;
|
|
130
|
+
interface DetailLoadState {
|
|
131
|
+
readonly status: 'loading' | 'ok' | 'error';
|
|
132
|
+
readonly data?: DetailData;
|
|
133
|
+
readonly error?: string;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Loads a widget's detail data while `enabled`: calls `load` with an abort
|
|
137
|
+
* signal (aborted on close, retry or unmount), validates the result and
|
|
138
|
+
* reports loading, ok or error. `reload` runs it again.
|
|
139
|
+
*/
|
|
140
|
+
declare function useDetailData(definition: WidgetDefinition, load: DetailLoader | undefined, enabled: boolean): {
|
|
141
|
+
readonly state: DetailLoadState;
|
|
142
|
+
readonly reload: () => void;
|
|
143
|
+
};
|
|
144
|
+
|
|
62
145
|
/** Every element that carries a stable `dwt-*` class, for `classNames`. */
|
|
63
|
-
type DashboardClassSlot = 'dashboard' | 'hiddenBar' | 'grid' | 'card' | 'cardHeader' | 'cardTitle' | 'cardDescription' | 'cardActions' | 'cardBody' | 'cardFooter' | 'button' | 'status' | 'empty' | 'error' | 'text' | 'kpi' | 'gauge' | 'table' | 'barList' | 'alertList' | 'chart' | 'legend' | 'tooltip' | 'tableTwin';
|
|
146
|
+
type DashboardClassSlot = 'dashboard' | 'hiddenBar' | 'grid' | 'card' | 'cardHeader' | 'cardTitle' | 'cardDescription' | 'cardActions' | 'cardBody' | 'cardFooter' | 'button' | 'status' | 'empty' | 'error' | 'text' | 'kpi' | 'gauge' | 'table' | 'barList' | 'alertList' | 'chart' | 'legend' | 'tooltip' | 'tableTwin' | 'detail';
|
|
64
147
|
/**
|
|
65
148
|
* Extra classes per slot, appended to the `dwt-*` class (never replacing
|
|
66
149
|
* it), e.g. `{ card: 'rounded-lg shadow-sm' }` for Tailwind.
|
|
@@ -78,6 +161,22 @@ interface DashboardLabels {
|
|
|
78
161
|
readonly moveEarlier: (title: string) => string;
|
|
79
162
|
readonly moveLater: (title: string) => string;
|
|
80
163
|
readonly hiddenWidgets: string;
|
|
164
|
+
readonly minimizedWidgets: string;
|
|
165
|
+
/** Added to the accessible name of links that open in a new tab. */
|
|
166
|
+
readonly opensInNewTab: string;
|
|
167
|
+
/** The card's View button, opening the detail view. */
|
|
168
|
+
readonly view: (title: string) => string;
|
|
169
|
+
readonly close: string;
|
|
170
|
+
readonly search: string;
|
|
171
|
+
readonly filterBy: (column: string) => string;
|
|
172
|
+
readonly sortBy: (column: string) => string;
|
|
173
|
+
readonly noResults: string;
|
|
174
|
+
/** e.g. "Showing 1–25 of 312 results". */
|
|
175
|
+
readonly showingRows: (from: number, to: number, total: number) => string;
|
|
176
|
+
readonly previousPage: string;
|
|
177
|
+
readonly nextPage: string;
|
|
178
|
+
readonly pageOf: (page: number, pageCount: number) => string;
|
|
179
|
+
readonly pagination: string;
|
|
81
180
|
readonly allHidden: string;
|
|
82
181
|
readonly noWidgets: string;
|
|
83
182
|
readonly andMore: (count: number) => string;
|
|
@@ -122,28 +221,40 @@ interface DashboardProps extends WidgetSettings {
|
|
|
122
221
|
/** The viewer's saved layout. Default: none saved. */
|
|
123
222
|
readonly layout?: DashboardLayout;
|
|
124
223
|
/**
|
|
125
|
-
* Called with the next layout after a move, hide, show,
|
|
224
|
+
* Called with the next layout after a move, hide, show, minimize or
|
|
126
225
|
* restore; persist it. Without it the layout is read-only (no controls).
|
|
127
226
|
*/
|
|
128
227
|
readonly onLayoutChange?: (layout: DashboardLayout) => void;
|
|
129
228
|
readonly onRetry?: (key: string) => void;
|
|
229
|
+
/**
|
|
230
|
+
* Loads the full data for a widget's detail view (widgets whose definition
|
|
231
|
+
* sets `detail`). Close over your own context. Without it, TABLE widgets
|
|
232
|
+
* with no footer and BAR_LIST widgets show their card data; other widgets
|
|
233
|
+
* get no View button.
|
|
234
|
+
*/
|
|
235
|
+
readonly loadDetail?: DetailLoader;
|
|
236
|
+
/**
|
|
237
|
+
* Called with the widget key when the viewer opens a detail view, instead
|
|
238
|
+
* of the built-in dialog: navigate to your own page.
|
|
239
|
+
*/
|
|
240
|
+
readonly onOpenDetail?: (key: string) => void;
|
|
130
241
|
readonly headingLevel?: 2 | 3 | 4 | 5 | 6;
|
|
131
242
|
readonly className?: string;
|
|
132
243
|
}
|
|
133
244
|
/**
|
|
134
245
|
* A full dashboard: widgets ordered by the viewer's layout, with move,
|
|
135
|
-
* hide/show and
|
|
246
|
+
* hide/show and minimize controls when `onLayoutChange` is given. Settings
|
|
136
247
|
* (locale, link target, classNames, labels) apply to every widget inside.
|
|
137
248
|
*/
|
|
138
249
|
declare function Dashboard({ locale, linkTarget, classNames, labels, ...props }: DashboardProps): ReactNode;
|
|
139
250
|
|
|
140
251
|
/**
|
|
141
|
-
* Default
|
|
252
|
+
* Default colors, used as `var(--dwt-*, fallback)` so charts read correctly
|
|
142
253
|
* without the stylesheet. `styles.css` redefines them for dark mode, and an
|
|
143
254
|
* app can override any of them with its own CSS custom properties.
|
|
144
255
|
*
|
|
145
256
|
* The categorical order is the dataviz reference palette, validated for
|
|
146
|
-
*
|
|
257
|
+
* color-vision deficiency on adjacent pairs in light and dark modes. Slots
|
|
147
258
|
* are assigned in this fixed order, never cycled, and follow the series
|
|
148
259
|
* (its position in the payload), never its rank.
|
|
149
260
|
*/
|
|
@@ -171,7 +282,7 @@ declare function TextWidget({ data, }: {
|
|
|
171
282
|
}): ReactNode;
|
|
172
283
|
/**
|
|
173
284
|
* KPI: a stat tile. The change against the previous period carries an arrow
|
|
174
|
-
* and signed text as well as
|
|
285
|
+
* and signed text as well as color, so it never relies on color alone.
|
|
175
286
|
*/
|
|
176
287
|
declare function KpiWidget({ data, }: {
|
|
177
288
|
readonly data: KpiWidgetData;
|
|
@@ -185,7 +296,7 @@ declare function TableWidget({ data, }: {
|
|
|
185
296
|
readonly data: TableWidgetData;
|
|
186
297
|
}): ReactNode;
|
|
187
298
|
/**
|
|
188
|
-
* BAR_LIST: labelled horizontal bars. One series, so one
|
|
299
|
+
* BAR_LIST: labelled horizontal bars. One series, so one color (slot 1)
|
|
189
300
|
* for every bar; the value text sits beside the bar, never inside it.
|
|
190
301
|
*/
|
|
191
302
|
declare function BarListWidget({ data, }: {
|
|
@@ -200,4 +311,43 @@ declare function WidgetContent({ data, }: {
|
|
|
200
311
|
readonly data: WidgetData;
|
|
201
312
|
}): ReactNode;
|
|
202
313
|
|
|
203
|
-
|
|
314
|
+
interface UseWidgetsOptions extends ResolveOptions {
|
|
315
|
+
/**
|
|
316
|
+
* When each widget's provider starts. `'mount'` (default): right after the
|
|
317
|
+
* first render, so the page and the dashboard shell appear first and each
|
|
318
|
+
* card fills in as its data arrives. `'visible'`: only once the card is
|
|
319
|
+
* near the viewport (attach `gridRef` to an element around the cards).
|
|
320
|
+
*/
|
|
321
|
+
readonly loadWhen?: 'mount' | 'visible';
|
|
322
|
+
/** `IntersectionObserver` margin for `loadWhen: 'visible'`. Default `'200px'`. */
|
|
323
|
+
readonly rootMargin?: string;
|
|
324
|
+
/**
|
|
325
|
+
* Reload started widgets every this many ms. Ticks are skipped while the
|
|
326
|
+
* tab is hidden, and a widget still loading is not restarted.
|
|
327
|
+
*/
|
|
328
|
+
readonly refreshMs?: number;
|
|
329
|
+
}
|
|
330
|
+
interface UseWidgetsResult {
|
|
331
|
+
/** Pass to `Dashboard` or `WidgetGrid`: placeholders first, then results. */
|
|
332
|
+
readonly widgets: readonly DashboardWidget[];
|
|
333
|
+
/** Reload one widget (for example from the error card's Retry) or all. */
|
|
334
|
+
readonly refresh: (key?: string) => void;
|
|
335
|
+
/**
|
|
336
|
+
* For `loadWhen: 'visible'`: attach to any element that contains the cards,
|
|
337
|
+
* for example a wrapper `<div ref={gridRef}>` around `Dashboard`.
|
|
338
|
+
*/
|
|
339
|
+
readonly gridRef: RefObject<HTMLDivElement | null>;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Loads widget data after the page has rendered and returns widgets for
|
|
343
|
+
* `Dashboard`. The first render never waits for data (so server rendering
|
|
344
|
+
* and first paint are unaffected); every widget starts as `loading`, loads
|
|
345
|
+
* independently, and replaces its placeholder when its own data arrives.
|
|
346
|
+
*
|
|
347
|
+
* Keep `definitions`, `providers`, `context` and `options.cache` referentially
|
|
348
|
+
* stable (module constants or `useMemo`): a changed value restarts loading,
|
|
349
|
+
* aborting whatever is in flight.
|
|
350
|
+
*/
|
|
351
|
+
declare function useWidgets<C extends WidgetContext>(definitions: readonly WidgetDefinition[], providers: WidgetProviders<C>, context: C, options?: UseWidgetsOptions): UseWidgetsResult;
|
|
352
|
+
|
|
353
|
+
export { AlertListWidget, BarListWidget, DEFAULT_LABELS, DEFAULT_SERIES_COLORS, Dashboard, type DashboardClassNames, type DashboardClassSlot, type DashboardLabels, type DashboardProps, type DetailLoadState, type DetailLoader, GaugeWidget, GraphWidget, KpiWidget, ResolvedWidgetCard, type ResolvedWidgetCardProps, TableWidget, TextWidget, Thumbnail, type UseWidgetsOptions, type UseWidgetsResult, WidgetCard, type WidgetCardProps, WidgetContent, WidgetDetail, WidgetDetailDialog, type WidgetDetailDialogProps, type WidgetDetailProps, WidgetGrid, type WidgetGridProps, WidgetLink, type WidgetSettings, WidgetSettingsProvider, barPath, buildChartModel, describeChart, joinClassNames, seriesColor, useDetailData, useWidgetSettings, useWidgets, widgetTitle };
|