@object-ui/plugin-dashboard 17.2.0 → 17.5.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/CHANGELOG.md +1004 -0
- package/README.md +52 -15
- package/dist/DashboardFilterBar.d.ts.map +1 -1
- package/dist/DashboardGridLayout.d.ts +27 -0
- package/dist/DashboardGridLayout.d.ts.map +1 -1
- package/dist/DashboardRenderer.d.ts +46 -4
- package/dist/DashboardRenderer.d.ts.map +1 -1
- package/dist/DashboardWithConfig.d.ts.map +1 -1
- package/dist/DatasetWidget.d.ts +186 -6
- package/dist/DatasetWidget.d.ts.map +1 -1
- package/dist/MetricCard.d.ts +29 -10
- package/dist/MetricCard.d.ts.map +1 -1
- package/dist/MetricWidget.d.ts +82 -17
- package/dist/MetricWidget.d.ts.map +1 -1
- package/dist/ObjectDataTable.d.ts.map +1 -1
- package/dist/ObjectMetricWidget.d.ts +10 -7
- package/dist/ObjectMetricWidget.d.ts.map +1 -1
- package/dist/RecordDetailDrawer.d.ts.map +1 -1
- package/dist/WidgetConfigPanel.d.ts.map +1 -1
- package/dist/colorVariants.d.ts +56 -0
- package/dist/colorVariants.d.ts.map +1 -0
- package/dist/domPassthroughPins.d.ts +9 -0
- package/dist/domPassthroughPins.d.ts.map +1 -0
- package/dist/index.d.ts +9 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1541 -1297
- package/dist/index.umd.cjs +2 -2
- package/dist/legacyRetiredWidget.d.ts +41 -0
- package/dist/legacyRetiredWidget.d.ts.map +1 -0
- package/dist/recordFields.d.ts +1 -1
- package/dist/recordFields.d.ts.map +1 -1
- package/dist/schemaHostProps.d.ts +80 -0
- package/dist/schemaHostProps.d.ts.map +1 -0
- package/dist/utils.d.ts +34 -0
- package/dist/utils.d.ts.map +1 -1
- package/package.json +15 -14
package/README.md
CHANGED
|
@@ -219,21 +219,36 @@ into each bound widget's inline query (`AND`-combined with the widget's own
|
|
|
219
219
|
"field": "region", // default binding target
|
|
220
220
|
"label": "Region",
|
|
221
221
|
"type": "select", // text | select | date | number | lookup
|
|
222
|
-
|
|
222
|
+
// Canonical @objectstack/spec pair form — the only form the platform
|
|
223
|
+
// accepts at publish. The bare-string shorthand (["EMEA", …]) is
|
|
224
|
+
// deprecated: still lifted at runtime, now warns (objectui#4356).
|
|
225
|
+
"options": [
|
|
226
|
+
{ "value": "EMEA", "label": "EMEA" },
|
|
227
|
+
{ "value": "APAC", "label": "APAC" },
|
|
228
|
+
{ "value": "AMER", "label": "AMER" }
|
|
229
|
+
]
|
|
223
230
|
// or dynamic: "optionsFrom": { "object": "accounts", "valueField": "region" }
|
|
224
231
|
}
|
|
225
232
|
],
|
|
226
233
|
"widgets": [
|
|
234
|
+
// Widgets bind a semantic-layer dataset (ADR-0021) and select its
|
|
235
|
+
// dimensions/measures by name. The pre-ADR-0021 top-level `object` +
|
|
236
|
+
// `categoryField`/`valueField`/`aggregate` shape was REMOVED — a widget
|
|
237
|
+
// still carrying it renders "This widget uses a retired data format.
|
|
238
|
+
// Edit it to bind a dataset." instead of a chart. A renderer-internal
|
|
239
|
+
// query lives under `options.data` as `{ provider: 'object', object,
|
|
240
|
+
// aggregate }`; an `options.data` array is fixed demo data.
|
|
241
|
+
//
|
|
227
242
|
// Default binding: the filter's own `field` (dateRange → created_at).
|
|
228
|
-
{ "id": "w1", "type": "bar", "
|
|
243
|
+
{ "id": "w1", "type": "bar", "dataset": "invoices", "dimensions": ["status"], "values": ["count"] },
|
|
229
244
|
// Explicit binding: map each filter to THIS widget's own field.
|
|
230
245
|
{
|
|
231
|
-
"id": "w2", "type": "line", "
|
|
246
|
+
"id": "w2", "type": "line", "dataset": "accounts", "dimensions": ["signed_month"], "values": ["count"],
|
|
232
247
|
"filterBindings": { "dateRange": "signed_at", "region": "sales_region" }
|
|
233
248
|
},
|
|
234
249
|
// Opt out of a filter with `false`.
|
|
235
250
|
{
|
|
236
|
-
"id": "w3", "type": "metric", "
|
|
251
|
+
"id": "w3", "type": "metric", "dataset": "invoices", "values": ["count"],
|
|
237
252
|
"filterBindings": { "region": false }
|
|
238
253
|
}
|
|
239
254
|
]
|
|
@@ -267,6 +282,39 @@ Notes:
|
|
|
267
282
|
warning instead of emitting a query that matches nothing. Explicit
|
|
268
283
|
`filterBindings` strings are always honoured as written.
|
|
269
284
|
|
|
285
|
+
## Widget accent colour (`colorVariant`)
|
|
286
|
+
|
|
287
|
+
A KPI widget can declare a semantic accent. The vocabulary is
|
|
288
|
+
`@objectstack/spec`'s `WidgetColorVariantSchema` enum — `default`, `blue`,
|
|
289
|
+
`teal`, `orange`, `purple`, `success`, `warning`, `danger` — the same eight
|
|
290
|
+
tokens the designer's swatch picker offers:
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
{
|
|
294
|
+
id: 'kpi_at_risk',
|
|
295
|
+
type: 'metric',
|
|
296
|
+
title: 'At-Risk Projects',
|
|
297
|
+
dataset: 'project_health',
|
|
298
|
+
values: ['project_count'],
|
|
299
|
+
filter: { health: 'red' },
|
|
300
|
+
colorVariant: 'danger', // tints the value; card chrome stays neutral
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Where the accent lands depends on the layout, not on the token:
|
|
305
|
+
|
|
306
|
+
| Layout | Accent |
|
|
307
|
+
| --- | --- |
|
|
308
|
+
| Card chrome (`MetricWidget`, inline `object-metric`) | the icon chip's background + foreground |
|
|
309
|
+
| Chrome-less (`MetricWidget variant: 'bare'`, and every dataset-bound `metric`) | the big number's text colour |
|
|
310
|
+
|
|
311
|
+
Both read one shared table (`src/colorVariants.ts`), so the same declaration
|
|
312
|
+
reads the same on either surface. `default` — and omitting the key — means "no
|
|
313
|
+
accent"; the widget renders in the ambient foreground colour. A token outside
|
|
314
|
+
the enum gets no accent and is not aliased to a nearby colour: it is invalid
|
|
315
|
+
metadata, rejected where it is authored and published rather than reinterpreted
|
|
316
|
+
here.
|
|
317
|
+
|
|
270
318
|
## TypeScript Support
|
|
271
319
|
|
|
272
320
|
```typescript
|
|
@@ -386,17 +434,6 @@ file system, …) per the protocol-agnostic architecture rule.
|
|
|
386
434
|
> dashboards. If you still want a browser-local cache for a demo, do it
|
|
387
435
|
> in the parent inside `onSchemaChange`.
|
|
388
436
|
|
|
389
|
-
<!-- release-metadata:v3.3.0 -->
|
|
390
|
-
|
|
391
|
-
## Compatibility
|
|
392
|
-
|
|
393
|
-
- **React:** 18.x or 19.x
|
|
394
|
-
- **Node.js:** ≥ 18
|
|
395
|
-
- **TypeScript:** ≥ 5.0 (strict mode)
|
|
396
|
-
- **`@objectstack/spec`:** ^3.3.0
|
|
397
|
-
- **`@objectstack/client`:** ^3.3.0
|
|
398
|
-
- **Tailwind CSS:** ≥ 3.4 (for packages with UI)
|
|
399
|
-
|
|
400
437
|
## Links
|
|
401
438
|
|
|
402
439
|
- 📚 [Documentation](https://www.objectui.org/docs/plugins/plugin-dashboard)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DashboardFilterBar.d.ts","sourceRoot":"","sources":["../src/DashboardFilterBar.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;GAQG;AAEH,OAAO,KAAuC,MAAM,OAAO,CAAC;AAiB5D,OAAO,EAEL,KAAK,kBAAkB,EAExB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"DashboardFilterBar.d.ts","sourceRoot":"","sources":["../src/DashboardFilterBar.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;GAQG;AAEH,OAAO,KAAuC,MAAM,OAAO,CAAC;AAiB5D,OAAO,EAEL,KAAK,kBAAkB,EAExB,MAAM,iBAAiB,CAAC;AAoCzB,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,kBAAkB,EAAE,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,CAAC;IAC7C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAkSD,wBAAgB,kBAAkB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,uBAAuB,4BAyCrH"}
|
|
@@ -4,6 +4,33 @@ import * as React from 'react';
|
|
|
4
4
|
export interface DashboardGridLayoutProps {
|
|
5
5
|
schema: DashboardComponentSchema;
|
|
6
6
|
className?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Data-source adapter for the widgets this grid renders, handed to
|
|
9
|
+
* `DatasetWidget` for ADR-0021 dataset-bound widgets (objectui#4614).
|
|
10
|
+
*
|
|
11
|
+
* Typed `unknown`, not `any`. The sibling declares `dataSource?: any`
|
|
12
|
+
* (`DashboardRenderer.tsx:198`) for a reason that is explicitly historical —
|
|
13
|
+
* "that is precisely what it resolved to before", via the index signature that
|
|
14
|
+
* used to answer for it — and this is a NEW declaration with no prior
|
|
15
|
+
* resolution to preserve. `unknown` is what the consumer itself declares
|
|
16
|
+
* (`DatasetWidget.tsx:655`, `dataSource: unknown`), so the value is forwarded
|
|
17
|
+
* to exactly the type that receives it, and no call site is held to anything
|
|
18
|
+
* new: every value is assignable to `unknown`. Narrowing it further to a real
|
|
19
|
+
* adapter type is a separate change with its own consumer sweep, on both
|
|
20
|
+
* surfaces at once.
|
|
21
|
+
*
|
|
22
|
+
* Optional, and the omitted case is a SUPPORTED one rather than an oversight:
|
|
23
|
+
* `dashboard-grid`'s SDUI registration declares only `title` / `className`
|
|
24
|
+
* inputs, so schema-driven hosts render this component with no adapter at all.
|
|
25
|
+
* A dataset-bound widget arriving that way renders `DatasetWidget`'s own
|
|
26
|
+
* no-capability diagnostic — a visible state, never a blank tile.
|
|
27
|
+
*
|
|
28
|
+
* `SchemaRenderer` forwards this as a React prop (its `...props` spread, last:
|
|
29
|
+
* `SchemaRenderer.tsx:632`). It cannot be shadowed by the spec's per-element
|
|
30
|
+
* `dataSource` BINDING, which is stripped from the schema before that spread
|
|
31
|
+
* for exactly this reason (`SchemaRenderer.tsx:564-575`, objectstack#5576).
|
|
32
|
+
*/
|
|
33
|
+
dataSource?: unknown;
|
|
7
34
|
/**
|
|
8
35
|
* Fires on every drag/resize tick with the raw react-grid-layout payload.
|
|
9
36
|
* Useful for live previews; NOT a persistence hook.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DashboardGridLayout.d.ts","sourceRoot":"","sources":["../src/DashboardGridLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAA2C,KAAK,UAAU,IAAI,SAAS,EAAuC,MAAM,mBAAmB,CAAC;AAC/I,OAAO,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"DashboardGridLayout.d.ts","sourceRoot":"","sources":["../src/DashboardGridLayout.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAA2C,KAAK,UAAU,IAAI,SAAS,EAAuC,MAAM,mBAAmB,CAAC;AAC/I,OAAO,kCAAkC,CAAC;AAK1C,OAAO,KAAK,EAAc,wBAAwB,EAAyB,MAAM,kBAAkB,CAAC;AA8BpG,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,wBAAwB,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,IAAI,CAAC;IAC/C;;;;;;;;;OASG;IACH,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,wBAAwB,KAAK,IAAI,CAAC;IAC5D,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;CACxB;AAED,iFAAiF;AACjF,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,wBAAwB,EAChC,MAAM,EAAE,SAAS,EAAE,GAClB,wBAAwB,CAa1B;AAcD,eAAO,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CA+blE,CAAC"}
|
|
@@ -1,8 +1,51 @@
|
|
|
1
1
|
import { DashboardComponentSchema, DashboardWidgetSchema } from '@object-ui/types';
|
|
2
|
-
import { ActionDef, ActionResult, ActionContext, ModalHandler } from '@object-ui/core';
|
|
3
|
-
|
|
2
|
+
import { ActionDef, ActionResult, ActionContext, ModalHandler, SduiDomPassThroughKey } from '@object-ui/core';
|
|
3
|
+
import { HTMLAttributes } from 'react';
|
|
4
|
+
/**
|
|
5
|
+
* The dashboard renderer's props.
|
|
6
|
+
*
|
|
7
|
+
* ## Why there is no `[key: string]: any` here (objectui#4528)
|
|
8
|
+
*
|
|
9
|
+
* There used to be one, and it erased this entire interface. A string index
|
|
10
|
+
* signature puts `string` into `keyof Props`, so `'ref' extends keyof Props` is
|
|
11
|
+
* always true and React's `PropsWithoutRef` takes its `Omit` branch — and
|
|
12
|
+
* `Omit` over a type carrying a string index signature keeps ONLY the index
|
|
13
|
+
* signature. Every declared property above was dropped from the resolved type:
|
|
14
|
+
* `keyof React.ComponentProps< typeof DashboardRenderer >` measured as
|
|
15
|
+
* `string | number`, and `onWidgetClick` measured as `any` at every JSX call
|
|
16
|
+
* site, while this interface went on declaring
|
|
17
|
+
* `(widgetId: string | null) => void`. The declaration was right and no
|
|
18
|
+
* consumer was held to it — a prop typo or a wrong-arity handler type-checked.
|
|
19
|
+
*
|
|
20
|
+
* The same trap, in `packages/components`, is objectui#4422 / PR #4438; this is
|
|
21
|
+
* the sweep of the two packages that issue left unswept.
|
|
22
|
+
*
|
|
23
|
+
* ## How the DOM pass-through survives without it
|
|
24
|
+
*
|
|
25
|
+
* `SchemaRenderer` hands this component the authored node's own keys, so the
|
|
26
|
+
* render function still collects an open rest object — but what may reach the
|
|
27
|
+
* element is decided by `toDomProps`' WHITELIST (objectui#4432), not by this
|
|
28
|
+
* type. The keys that whitelist forwards are therefore declared here BY NAME,
|
|
29
|
+
* derived from the whitelist constant itself so the two cannot drift, which is
|
|
30
|
+
* exactly what `@object-ui/core`'s `dom-props` doctrine asks for: "Deliberate
|
|
31
|
+
* DOM pass-through beyond this set stays available the objectui#4435 way —
|
|
32
|
+
* DECLARE it and forward it by name. Do not reopen the spread."
|
|
33
|
+
*/
|
|
34
|
+
export interface DashboardRendererProps extends Pick<HTMLAttributes<HTMLDivElement>, SduiDomPassThroughKey> {
|
|
4
35
|
schema: DashboardComponentSchema;
|
|
5
36
|
className?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Data-source adapter for the widgets this dashboard renders.
|
|
39
|
+
*
|
|
40
|
+
* Destructured by the render function and handed to `DatasetWidget` /
|
|
41
|
+
* `SchemaRenderer`, and passed by both in-repo hosts (`DashboardView`,
|
|
42
|
+
* `DashboardPreview`) — but never declared until objectui#4528, because the
|
|
43
|
+
* index signature above was answering for it. Typed `any` deliberately: that
|
|
44
|
+
* is precisely what it resolved to before, so declaring it changes what is
|
|
45
|
+
* DECLARED without changing what any call site is held to. Narrowing it to a
|
|
46
|
+
* real adapter type is a separate change with its own consumer sweep.
|
|
47
|
+
*/
|
|
48
|
+
dataSource?: any;
|
|
6
49
|
/** Callback invoked when dashboard refresh is triggered (manual or auto) */
|
|
7
50
|
onRefresh?: () => void;
|
|
8
51
|
/** Total record count to display */
|
|
@@ -37,7 +80,6 @@ export interface DashboardRendererProps {
|
|
|
37
80
|
* title/subtitle so we don't display them twice.
|
|
38
81
|
*/
|
|
39
82
|
hideHeaderText?: boolean;
|
|
40
|
-
[key: string]: any;
|
|
41
83
|
}
|
|
42
84
|
/**
|
|
43
85
|
* DashboardRenderer — the public dashboard renderer.
|
|
@@ -54,5 +96,5 @@ export interface DashboardRendererProps {
|
|
|
54
96
|
* stay readable inside widget subtrees, and only a same-named filter shadows
|
|
55
97
|
* the outer variable.
|
|
56
98
|
*/
|
|
57
|
-
export declare const DashboardRenderer: import('react').ForwardRefExoticComponent<
|
|
99
|
+
export declare const DashboardRenderer: import('react').ForwardRefExoticComponent<DashboardRendererProps & import('react').RefAttributes<HTMLDivElement>>;
|
|
58
100
|
//# sourceMappingURL=DashboardRenderer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DashboardRenderer.d.ts","sourceRoot":"","sources":["../src/DashboardRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"DashboardRenderer.d.ts","sourceRoot":"","sources":["../src/DashboardRenderer.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAc,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAGpG,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAUnH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AAmI5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,WAAW,sBACf,SAAQ,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,qBAAqB,CAAC;IACnE,MAAM,EAAE,wBAAwB,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,oCAAoC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,WAAW,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACrE,kEAAkE;IAClE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gDAAgD;IAChD,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,uDAAuD;IACvD,aAAa,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAClD;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,qBAAqB,EAAE,KAAK,IAAI,CAAC;IAC9D,mGAAmG;IACnG,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,wGAAwG;IACxG,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,KAAK,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY,CAAC,CAAC;IACrH;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAg3BD;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iBAAiB,mHAiB7B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DashboardWithConfig.d.ts","sourceRoot":"","sources":["../src/DashboardWithConfig.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EAAE,wBAAwB,EAAyB,MAAM,kBAAkB,CAAC;AAKxF,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAMnE,MAAM,WAAW,wBAAwB;IACvC,qCAAqC;IACrC,MAAM,EAAE,wBAAwB,CAAC;IACjC,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,6DAA6D;IAC7D,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IACpD,iEAAiE;IACjE,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IACvE,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,yBAAyB;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iDAAiD;IACjD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,yBAAyB,EAAE,CAAC;IACvC,oDAAoD;IACpD,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,MAAM,EACN,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,WAAW,EACX,iBAAyB,EACzB,SAAS,EACT,QAAQ,EACR,eAAe,GAChB,EAAE,wBAAwB,
|
|
1
|
+
{"version":3,"file":"DashboardWithConfig.d.ts","sourceRoot":"","sources":["../src/DashboardWithConfig.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EAAE,wBAAwB,EAAyB,MAAM,kBAAkB,CAAC;AAKxF,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAMnE,MAAM,WAAW,wBAAwB;IACvC,qCAAqC;IACrC,MAAM,EAAE,wBAAwB,CAAC;IACjC,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,6DAA6D;IAC7D,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IACpD,iEAAiE;IACjE,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAK,IAAI,CAAC;IACvE,2DAA2D;IAC3D,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,yBAAyB;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iDAAiD;IACjD,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,yBAAyB,EAAE,CAAC;IACvC,oDAAoD;IACpD,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,MAAM,EACN,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,WAAW,EACX,iBAAyB,EACzB,SAAS,EACT,QAAQ,EACR,eAAe,GAChB,EAAE,wBAAwB,qBAuK1B"}
|
package/dist/DatasetWidget.d.ts
CHANGED
|
@@ -1,19 +1,44 @@
|
|
|
1
|
-
import { buildDatasetDrillFilter } from '@object-ui/core';
|
|
1
|
+
import { buildDatasetDrillFilter, pivotCellKey, ChartSeriesBinding } from '@object-ui/core';
|
|
2
2
|
/**
|
|
3
3
|
* Build the record-list filter for a drilled row. Re-exported for back-compat;
|
|
4
4
|
* the implementation now lives in `@object-ui/core` (`buildDatasetDrillFilter`)
|
|
5
5
|
* so the dashboard and the report renderer drill identically.
|
|
6
6
|
*/
|
|
7
7
|
export declare const buildDrillFilter: typeof buildDatasetDrillFilter;
|
|
8
|
+
/**
|
|
9
|
+
* The pivot key encoders, re-exported for back-compat; the implementations now
|
|
10
|
+
* live in `@object-ui/core` (`pivotBucketId` / `pivotCellKey`) so this widget
|
|
11
|
+
* and the report renderer's cross-tab key their buckets identically. See that
|
|
12
|
+
* module for why both are `JSON.stringify` rather than a delimiter character,
|
|
13
|
+
* and why an empty value encodes as JSON `null` rather than a placeholder
|
|
14
|
+
* string (objectui#4056).
|
|
15
|
+
*
|
|
16
|
+
* Every consumer of a bucket id — the cell index below, the row-total lookup
|
|
17
|
+
* AND the column-total lookup in the cross-tab renderer — must build its key
|
|
18
|
+
* with these, over values normalized by `pivotDimensionValue`; a second,
|
|
19
|
+
* hand-rolled encoding of the same id is what made the old bug invisible.
|
|
20
|
+
*
|
|
21
|
+
* `pivotRowId` is the historical name of the axis-neutral encoder, kept as an
|
|
22
|
+
* alias so this package's published surface does not change.
|
|
23
|
+
*/
|
|
24
|
+
declare const pivotRowId: (dimensionValues: Array<string | null>) => string;
|
|
25
|
+
export { pivotRowId, pivotCellKey };
|
|
8
26
|
/**
|
|
9
27
|
* Pivot flat dataset rows into a cross-tab: `rowDims` go DOWN, `colDim` spreads
|
|
10
28
|
* ACROSS. Returns ordered row/column headers (display labels from the rows) and
|
|
11
|
-
* a map from a
|
|
12
|
-
* that combination's measure values. No re-aggregation — the dataset
|
|
13
|
-
* grouped by every dimension, so each cell maps to exactly one row (the
|
|
14
|
-
* is also what drill-through uses to read `drillRawRows`).
|
|
29
|
+
* a map from a `pivotCellKey(rowId, colId)` cell key to the FLAT row index
|
|
30
|
+
* holding that combination's measure values. No re-aggregation — the dataset
|
|
31
|
+
* already grouped by every dimension, so each cell maps to exactly one row (the
|
|
32
|
+
* index is also what drill-through uses to read `drillRawRows`).
|
|
33
|
+
*
|
|
34
|
+
* `locale` is the display-locale tag the header LABELS are formatted in
|
|
35
|
+
* (objectui#4566) — this is a plain exported function, not a component, so it
|
|
36
|
+
* cannot read `useDisplayLocale()` itself. It affects `rowHeaders`/`colHeaders`
|
|
37
|
+
* only; the `id`s are opaque keys built by `pivotBucketId` from the RAW values
|
|
38
|
+
* and are deliberately untouched by it, so a locale change can never re-key a
|
|
39
|
+
* cell (which would break the `cellIndex` lookup and drill-through with it).
|
|
15
40
|
*/
|
|
16
|
-
export declare function buildPivot(rows: Array<Record<string, unknown>>, rowDims: string[], colDim: string): {
|
|
41
|
+
export declare function buildPivot(rows: Array<Record<string, unknown>>, rowDims: string[], colDim: string, locale?: string): {
|
|
17
42
|
rowHeaders: Array<{
|
|
18
43
|
id: string;
|
|
19
44
|
labels: string[];
|
|
@@ -26,6 +51,161 @@ export declare function buildPivot(rows: Array<Record<string, unknown>>, rowDims
|
|
|
26
51
|
};
|
|
27
52
|
/** Serialize a 2D array (first row = headers) to CSV text. */
|
|
28
53
|
export declare function toCsv(rows: Array<Array<string | number | null | undefined>>): string;
|
|
54
|
+
/** A `DatasetSelection.timeDimensions` entry stating a bounded window. */
|
|
55
|
+
export interface DatasetTimeWindow {
|
|
56
|
+
dimension: string;
|
|
57
|
+
dateRange: [string, string];
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Split a RESOLVED runtime filter into the bounded date windows it states and
|
|
61
|
+
* the rest of the filter (objectui#3337 point 5).
|
|
62
|
+
*
|
|
63
|
+
* The executor shifts exactly one thing for a `compareTo`: a `timeDimensions`
|
|
64
|
+
* entry carrying a `dateRange`. A widget states its window in its own `filter`
|
|
65
|
+
* instead (a date macro, or the dashboard's date-range filter merged in by
|
|
66
|
+
* `DashboardRenderer`), which is why forwarding a structured `compareTo` alone
|
|
67
|
+
* still came back "compareTo needs a dated window to shift".
|
|
68
|
+
*
|
|
69
|
+
* Windows are **moved, not copied**: the comparison pass re-runs with the
|
|
70
|
+
* shifted `timeDimensions` but the SAME `runtimeFilter`, so a copy left behind
|
|
71
|
+
* would intersect the shifted window with the current one and every
|
|
72
|
+
* `<measure>__compare` column would come back empty.
|
|
73
|
+
*
|
|
74
|
+
* Only CONJUNCTIVE positions are walked — the top level and `$and` members. A
|
|
75
|
+
* window inside `$or` / `$not` is not a window the whole query runs in, so it
|
|
76
|
+
* stays in the filter untouched.
|
|
77
|
+
*
|
|
78
|
+
* **Which dimension gets shifted is not decided here.** Every window found is
|
|
79
|
+
* lowered under the name the author wrote. Zero of them, or two, is the
|
|
80
|
+
* executor's error to raise — it names the candidates (`resolveCompareDimension`).
|
|
81
|
+
* Guessing one renderer-side would trade a loud error for a quietly wrong
|
|
82
|
+
* window, which is the failure class objectstack#5011 set out to end.
|
|
83
|
+
*/
|
|
84
|
+
export declare function extractDateWindows(filter: unknown): {
|
|
85
|
+
windows: DatasetTimeWindow[];
|
|
86
|
+
rest: Record<string, unknown> | undefined;
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* Lower a dashboard widget's declared `chartConfig` (spec `ChartConfigSchema` —
|
|
90
|
+
* the same shape a report block and a react `<ObjectChart>` parse) onto the
|
|
91
|
+
* chart schema this widget hands to the renderer.
|
|
92
|
+
*
|
|
93
|
+
* ## Why this is a whitelist and not a spread
|
|
94
|
+
*
|
|
95
|
+
* Until #3135 NONE of `chartConfig` reached the renderer: this widget read
|
|
96
|
+
* `options` and nothing else, so an author who wrote `showLegend: false` still
|
|
97
|
+
* got a legend and one who wrote `true` only got one because "on" is the
|
|
98
|
+
* renderer's default. #3135 lowered that single flag and left the rest declared
|
|
99
|
+
* and inert. objectstack#7016 lowers the rest of the keys that are actually
|
|
100
|
+
* DELIVERED, admitting a key only when both of these hold:
|
|
101
|
+
*
|
|
102
|
+
* 1. **The chart block draws it end to end on this path.** `{ type: 'chart' }`
|
|
103
|
+
* resolves to `ChartRenderer` → `AdvancedChartImpl`, which draws
|
|
104
|
+
* `title`/`subtitle` in its ChartFrame, turns `description` into the chart
|
|
105
|
+
* container's `role="img"` + `aria-label`, applies `height` as that
|
|
106
|
+
* container's inline height, reads `colors` as the positional palette,
|
|
107
|
+
* prints `showDataLabels` as a Recharts `LabelList`, draws `annotations` as
|
|
108
|
+
* ReferenceLine/ReferenceArea and honours `interaction` as the tooltip
|
|
109
|
+
* toggle plus `Brush`. Forwarding a key the renderer ignores would only
|
|
110
|
+
* move declared-but-not-delivered one layer down, which is the failure this
|
|
111
|
+
* change exists to remove.
|
|
112
|
+
* 2. **It does not fight the dataset derivation.** `type` stays out: the
|
|
113
|
+
* widget's own `type` already picks the family through `CHART_TYPE_MAP`,
|
|
114
|
+
* which is the dataset path's chart-family channel.
|
|
115
|
+
*
|
|
116
|
+
* ## Where `xAxis` / `yAxis` / `series` go — the ruled split (#4229)
|
|
117
|
+
*
|
|
118
|
+
* Those three used to be refused here under the same criterion 2, on the
|
|
119
|
+
* grounds that they are "DERIVED from the dataset selection". That belief was
|
|
120
|
+
* **half right, and the half it got wrong silently dropped authored intent**:
|
|
121
|
+
* a widget authoring the spec's own combo shape — `series[].type` plus
|
|
122
|
+
* `series[].yAxis: 'left'|'right'` and two `yAxis` entries — rendered as
|
|
123
|
+
* grouped bars on one axis, because the per-series mark and the axis binding
|
|
124
|
+
* never left this function (#4229, measured in the DOM: 2 bars / 0 lines / 1
|
|
125
|
+
* axis where 1 bar + 1 line + 2 axes were authored).
|
|
126
|
+
*
|
|
127
|
+
* The ruling: **the dataset owns DATA, the author owns PRESENTATION.**
|
|
128
|
+
*
|
|
129
|
+
* - **Data (derived, never forwarded)** — series MEMBERSHIP (which columns
|
|
130
|
+
* become series, which rows, which buckets) and the column each binding
|
|
131
|
+
* reads. Concretely: `buildChartSeries`'s `dataKey`s, `xAxisKey`, and the
|
|
132
|
+
* spec's two binding keys `series[].name` and `ChartAxis.field`.
|
|
133
|
+
* - **Presentation (authored, merged forward)** — everything else on those
|
|
134
|
+
* same objects: `series[].type` (the per-series mark), `series[].yAxis`
|
|
135
|
+
* (which axis it binds to), `label`/`color`/`stack`/`variant`/`dashArray`/
|
|
136
|
+
* `opacity`, and the axis definitions' `title`/`format`/`min`/`max`/
|
|
137
|
+
* `stepSize`/`showGridLines`/`position`/`logarithmic`.
|
|
138
|
+
*
|
|
139
|
+
* This is #2880's S2 rule — dual axes are `yAxis[].position` plus
|
|
140
|
+
* `series[].yAxis`, and a combo assigns its axes by EXPLICIT binding first,
|
|
141
|
+
* falling back to the per-series-type guess only where the author bound
|
|
142
|
+
* nothing — extended from `ObjectChart` (where PR #2883 landed it) to the
|
|
143
|
+
* dataset path, which never carried it over. {@link mergeAuthoredPresentation}
|
|
144
|
+
* is the ONE place that merge happens; see it for the match rule and for why
|
|
145
|
+
* membership is safe.
|
|
146
|
+
*
|
|
147
|
+
* `aria` is the one declared key with **no reader at all** on this path:
|
|
148
|
+
* `AdvancedChartImpl` has no `aria` prop, and `SchemaRenderer`'s ARIA injection
|
|
149
|
+
* reads the FLAT `ariaLabel`/`ariaDescribedBy`/`role`, never a nested `aria`
|
|
150
|
+
* object. It is therefore left unforwarded on purpose (criterion 1) and
|
|
151
|
+
* reported back to objectstack#5175's narrowing half rather than papered over
|
|
152
|
+
* with a dashboard-only flattening that would also collide with the accessible
|
|
153
|
+
* name `description` already sets.
|
|
154
|
+
*
|
|
155
|
+
* @param raw the widget's `chartConfig` as authored (anything, incl. absent)
|
|
156
|
+
* @param fieldCategoryColors per-category colours resolved from the category
|
|
157
|
+
* dimension's own select/lookup option colours, merged UNDER an explicit
|
|
158
|
+
* author map (see the `colors` note below)
|
|
159
|
+
* @returns only the keys that resolved, so the caller can spread it over the
|
|
160
|
+
* derived chart schema and every undeclared key keeps the renderer's default
|
|
161
|
+
*/
|
|
162
|
+
export declare function chartConfigPresentation(raw: unknown, fieldCategoryColors?: Record<string, string> | null): Record<string, unknown>;
|
|
163
|
+
/** Authored spec `ChartSeries` presentation, in the renderer's internal spelling. */
|
|
164
|
+
export interface AuthoredSeriesPresentation {
|
|
165
|
+
label?: string;
|
|
166
|
+
/** Spec `ChartSeries.type`, narrowed — see {@link seriesPresentation}. */
|
|
167
|
+
chartType?: 'bar' | 'line' | 'area';
|
|
168
|
+
yAxis?: 'left' | 'right';
|
|
169
|
+
color?: string;
|
|
170
|
+
stack?: string;
|
|
171
|
+
variant?: 'primary' | 'comparison';
|
|
172
|
+
dashArray?: string;
|
|
173
|
+
opacity?: number;
|
|
174
|
+
}
|
|
175
|
+
/** A derived series binding with the author's presentation merged onto it. */
|
|
176
|
+
export type MergedChartSeries = ChartSeriesBinding & AuthoredSeriesPresentation;
|
|
177
|
+
/**
|
|
178
|
+
* Merge the authored `chartConfig`'s PRESENTATION onto the series and axes the
|
|
179
|
+
* dataset selection derived — the one place that happens (#4229).
|
|
180
|
+
*
|
|
181
|
+
* The match rule is **by name/key**: an authored `series[].name` is paired with
|
|
182
|
+
* the derived binding whose `dataKey` it equals, and the pairing decides
|
|
183
|
+
* nothing but presentation:
|
|
184
|
+
*
|
|
185
|
+
* - an authored entry naming a measure that is NOT in the dataset selection is
|
|
186
|
+
* **ignored** — membership belongs to the dataset, so an author cannot add,
|
|
187
|
+
* remove or re-point a series from `chartConfig`;
|
|
188
|
+
* - a derived series with no authored entry keeps the family default, so every
|
|
189
|
+
* dashboard that never wrote `chartConfig.series` renders byte-for-byte as
|
|
190
|
+
* before;
|
|
191
|
+
* - where both exist the **explicit binding wins** (#2880 S2), which is the
|
|
192
|
+
* whole point: `type: 'line'` + `yAxis: 'right'` is how the spec says "this
|
|
193
|
+
* measure is a line on the secondary axis".
|
|
194
|
+
*
|
|
195
|
+
* Matching on `name` only is deliberate: `name` is the spec's authorable key
|
|
196
|
+
* for a series (`dataKey` is a declared ALIAS of it, resolved where the
|
|
197
|
+
* metadata is parsed), so reading a second spelling here would fossilize a
|
|
198
|
+
* dialect this renderer has no business accepting (AGENTS.md #0.1).
|
|
199
|
+
*
|
|
200
|
+
* @param derived the bindings `buildChartSeries` produced from the selection
|
|
201
|
+
* @param raw the widget's `chartConfig` as authored (anything, incl. absent)
|
|
202
|
+
* @returns the merged series, plus the presentation-only axes to spread onto
|
|
203
|
+
* the chart schema (absent when the author declared none)
|
|
204
|
+
*/
|
|
205
|
+
export declare function mergeAuthoredPresentation(derived: ChartSeriesBinding[], raw: unknown): {
|
|
206
|
+
series: MergedChartSeries[];
|
|
207
|
+
axes: Record<string, unknown>;
|
|
208
|
+
};
|
|
29
209
|
export declare function DatasetWidget({ widget, dataSource }: {
|
|
30
210
|
widget: any;
|
|
31
211
|
dataSource: unknown;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DatasetWidget.d.ts","sourceRoot":"","sources":["../src/DatasetWidget.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"DatasetWidget.d.ts","sourceRoot":"","sources":["../src/DatasetWidget.tsx"],"names":[],"mappings":"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"}
|
package/dist/MetricCard.d.ts
CHANGED
|
@@ -1,17 +1,36 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
import { I18nLabel } from '@object-ui/types';
|
|
3
|
+
import { SchemaHostProps } from './schemaHostProps';
|
|
4
|
+
/**
|
|
5
|
+
* DOM PASS-THROUGH (objectui#4426) — see `MetricWidget.tsx`'s interface header
|
|
6
|
+
* for the full argument; this is the same widening on the same spread, onto the
|
|
7
|
+
* same Shadcn `Card` (`div`).
|
|
8
|
+
*
|
|
9
|
+
* `title` is the one key `Omit`-ed, and the omission is the accurate contract
|
|
10
|
+
* rather than a workaround. HTML's `title` is a tooltip string; this card's
|
|
11
|
+
* `title` is its HEADING, in the `I18nLabel` vocabulary — an incompatible type,
|
|
12
|
+
* and one the component destructures out and renders into `CardTitle`, so no
|
|
13
|
+
* `title` attribute has ever reached this element. Declaring the inherited DOM
|
|
14
|
+
* `title` here would be the "declared but not delivered" failure this repo
|
|
15
|
+
* treats as first-class (objectui#3290, objectui#3222): it would type-check,
|
|
16
|
+
* read as a supported tooltip, and silently do nothing. `MetricWidget` has no
|
|
17
|
+
* such collision — its heading is `label` — so it extends the DOM attributes
|
|
18
|
+
* whole. The repo's spelling for this carve-out is `ComboboxProps`
|
|
19
|
+
* (`extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "value" | "onChange">`),
|
|
20
|
+
* omitted there for the same reason: the component's own contract owns the name.
|
|
21
|
+
*/
|
|
22
|
+
export interface MetricCardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> {
|
|
23
|
+
/**
|
|
24
|
+
* Card heading, in @objectstack/spec's `I18nLabel` vocabulary — a plain
|
|
25
|
+
* string or an inline per-locale map. See `MetricWidget.label` for why the
|
|
26
|
+
* retired `{ key, defaultValue }` form is no longer accepted (objectui#4032).
|
|
27
|
+
*/
|
|
28
|
+
title?: string | I18nLabel;
|
|
7
29
|
value: string | number;
|
|
8
30
|
icon?: string;
|
|
9
31
|
trend?: 'up' | 'down' | 'neutral';
|
|
10
32
|
trendValue?: string;
|
|
11
|
-
description?: string |
|
|
12
|
-
key?: string;
|
|
13
|
-
defaultValue?: string;
|
|
14
|
-
};
|
|
33
|
+
description?: string | I18nLabel;
|
|
15
34
|
className?: string;
|
|
16
35
|
/** When true, the card is in a loading state (fetching data from server). */
|
|
17
36
|
loading?: boolean;
|
|
@@ -22,5 +41,5 @@ export interface MetricCardProps {
|
|
|
22
41
|
* MetricCard - Standalone metric card component for dashboard KPIs
|
|
23
42
|
* Displays a metric value with optional icon, trend indicator, and description
|
|
24
43
|
*/
|
|
25
|
-
export declare const MetricCard: React.FC<MetricCardProps>;
|
|
44
|
+
export declare const MetricCard: React.FC<MetricCardProps & SchemaHostProps>;
|
|
26
45
|
//# sourceMappingURL=MetricCard.d.ts.map
|
package/dist/MetricCard.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MetricCard.d.ts","sourceRoot":"","sources":["../src/MetricCard.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"MetricCard.d.ts","sourceRoot":"","sources":["../src/MetricCard.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAAC,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAC1F;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6EAA6E;IAC7E,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,uFAAuF;IACvF,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,GAAG,eAAe,CA6ElE,CAAC"}
|
package/dist/MetricWidget.d.ts
CHANGED
|
@@ -1,25 +1,74 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
import { I18nLabel } from '@object-ui/types';
|
|
3
|
+
import { MetricColorVariant } from './colorVariants';
|
|
4
|
+
import { SchemaHostProps } from './schemaHostProps';
|
|
5
|
+
/**
|
|
6
|
+
* The variant vocabulary and its two class tables now live in
|
|
7
|
+
* `./colorVariants` — the dataset-bound KPI (`DatasetWidget`, objectui#3359)
|
|
8
|
+
* paints the SAME accents, and two copies of a palette is how a
|
|
9
|
+
* declared-but-unenforced key becomes two disagreeing declarations. Re-exported
|
|
10
|
+
* here because this module was the type's original home.
|
|
11
|
+
*/
|
|
12
|
+
export type { MetricColorVariant };
|
|
13
|
+
/**
|
|
14
|
+
* DOM PASS-THROUGH (objectui#4426). `MetricWidget` ends its prop list with a
|
|
15
|
+
* `...domProps` spread onto the Shadcn `Card` — a `div` — so `id`, `role`,
|
|
16
|
+
* `aria-*`, `data-*`, `tabIndex`, `title` and the DOM event handlers reach the
|
|
17
|
+
* element. objectui#4357 (PR #4428) deliberately KEPT that spread: it is the
|
|
18
|
+
* component's only accessibility passthrough, and removing it would delete the
|
|
19
|
+
* only way a host can put an `id` or an `aria-label` on a KPI card.
|
|
20
|
+
*
|
|
21
|
+
* Until now the type refused what the runtime accepted. A TypeScript consumer
|
|
22
|
+
* importing the component directly could not write `<MetricWidget id="revenue"
|
|
23
|
+
* role="region" aria-label="Revenue KPI" … />` without a cast, while a JS
|
|
24
|
+
* consumer and every SDUI author going through `SchemaRenderer` (untyped at
|
|
25
|
+
* that boundary) got the passthrough for free. This `extends` is that
|
|
26
|
+
* declaration — the mirror image of #4357, closing the same question from the
|
|
27
|
+
* other side: renderer metadata was reaching the DOM because the spread is
|
|
28
|
+
* open; DOM attributes were unreachable because the type was closed.
|
|
29
|
+
*
|
|
30
|
+
* Measured convention, not an invented spelling: an exported `*Props` interface
|
|
31
|
+
* that spreads onto a host element extends `React.HTMLAttributes<HTMLDivElement>`
|
|
32
|
+
* here — `PageHeaderComponentProps` (whose own doc says "it extends
|
|
33
|
+
* `HTMLAttributes` so every DOM prop rides along"), `ChatbotProps`,
|
|
34
|
+
* `ChatbotEnhancedProps`, `TypingIndicatorProps`, `RefreshIndicatorProps`,
|
|
35
|
+
* `FieldProps`, and shadcn's own `BadgeProps`.
|
|
36
|
+
*
|
|
37
|
+
* What this does NOT declare, deliberately: the schema-shaped keys
|
|
38
|
+
* `SchemaRenderer` injects (`schema` / `bind` / `events` / `props` /
|
|
39
|
+
* `ariaLabel` / `ariaDescribedBy` / `dataSource`). None of them is an HTML
|
|
40
|
+
* attribute name, all seven are destructured out and never reach the DOM, and
|
|
41
|
+
* declaring them here would re-assert as a public contract exactly what #4357
|
|
42
|
+
* stripped. They stay in `SchemaHostProps`, intersected in at the component's
|
|
43
|
+
* own signature — the renderer's private door, not the consumer's front door.
|
|
44
|
+
* The narrower `FieldWidgetDomProps` shape (objectui#3221) is the other spelling
|
|
45
|
+
* in this repo, but it exists to be bound key-by-key to a runtime whitelist
|
|
46
|
+
* (`toDomProps`) in both directions; this component has no such whitelist, and
|
|
47
|
+
* inventing a half of one here would declare a set the spread does not enforce.
|
|
48
|
+
* Whether plugin widgets should get that whitelist is objectui#4425.
|
|
49
|
+
*/
|
|
50
|
+
export interface MetricWidgetProps extends React.HTMLAttributes<HTMLDivElement> {
|
|
51
|
+
/**
|
|
52
|
+
* The KPI's heading, in @objectstack/spec's `I18nLabel` vocabulary — a plain
|
|
53
|
+
* string or an inline per-locale map (`{ en: 'Revenue', 'zh-CN': '收入' }`).
|
|
54
|
+
*
|
|
55
|
+
* Was `string | { key?, defaultValue? }` — the key-reference form
|
|
56
|
+
* objectstack#5055 RETIRED. It is not accepted here any more because the spec
|
|
57
|
+
* rejects it at authoring time, and because reading it was never the point:
|
|
58
|
+
* the private resolver behind it ended `defaultValue || key` and never
|
|
59
|
+
* consulted a bundle, so the escape hatch was declared and inert
|
|
60
|
+
* (objectui#4032).
|
|
61
|
+
*/
|
|
62
|
+
label: string | I18nLabel;
|
|
8
63
|
value: string | number;
|
|
9
64
|
trend?: {
|
|
10
65
|
value: number;
|
|
11
|
-
label?: string |
|
|
12
|
-
key?: string;
|
|
13
|
-
defaultValue?: string;
|
|
14
|
-
};
|
|
66
|
+
label?: string | I18nLabel;
|
|
15
67
|
direction?: 'up' | 'down' | 'neutral';
|
|
16
68
|
};
|
|
17
69
|
icon?: React.ReactNode | string;
|
|
18
70
|
className?: string;
|
|
19
|
-
description?: string |
|
|
20
|
-
key?: string;
|
|
21
|
-
defaultValue?: string;
|
|
22
|
-
};
|
|
71
|
+
description?: string | I18nLabel;
|
|
23
72
|
/** When true, the widget is in a loading state (fetching data from server). */
|
|
24
73
|
loading?: boolean;
|
|
25
74
|
/** Error message from a failed data fetch. When set, the widget shows an error state. */
|
|
@@ -30,11 +79,27 @@ export interface MetricWidgetProps {
|
|
|
30
79
|
format?: string;
|
|
31
80
|
/** ISO currency code (e.g. `'USD'`); enables currency formatting on numeric values. */
|
|
32
81
|
currency?: string;
|
|
33
|
-
/**
|
|
82
|
+
/**
|
|
83
|
+
* Static prefix appended in front of the formatted value (e.g. `'$'`, `'¥'`).
|
|
84
|
+
*
|
|
85
|
+
* Same name, same `string` type as the inherited RDFa `prefix` attribute, and
|
|
86
|
+
* this declaration wins: the component reads it and destructures it out, so
|
|
87
|
+
* it never reaches the DOM. That is the accurate contract — it was already
|
|
88
|
+
* true before this interface declared its passthrough.
|
|
89
|
+
*/
|
|
34
90
|
prefix?: string;
|
|
35
91
|
/** Static suffix appended after the formatted value (e.g. `' /mo'`). */
|
|
36
92
|
suffix?: string;
|
|
37
|
-
/**
|
|
93
|
+
/**
|
|
94
|
+
* When set, the entire card becomes clickable and emits this handler.
|
|
95
|
+
*
|
|
96
|
+
* Deliberately NARROWER than the inherited `MouseEventHandler<HTMLDivElement>`:
|
|
97
|
+
* the KPI card treats a click as "the tile was activated" and wires the same
|
|
98
|
+
* handler to Enter/Space, where there is no mouse event to hand over. A
|
|
99
|
+
* zero-arg function is assignable to the inherited signature, so consumers
|
|
100
|
+
* already passing `(e) => …` keep compiling; this only stops the component
|
|
101
|
+
* from promising an event object its keyboard path cannot produce.
|
|
102
|
+
*/
|
|
38
103
|
onClick?: () => void;
|
|
39
104
|
/**
|
|
40
105
|
* Layout variant. `'card'` (default) is the bordered KPI card; `'bare'` drops
|
|
@@ -43,5 +108,5 @@ export interface MetricWidgetProps {
|
|
|
43
108
|
*/
|
|
44
109
|
variant?: 'card' | 'bare';
|
|
45
110
|
}
|
|
46
|
-
export declare const MetricWidget: ({ label, value, trend, icon, className, description, loading, error, colorVariant, format, currency, prefix, suffix, onClick, variant,
|
|
111
|
+
export declare const MetricWidget: ({ label, value, trend, icon, className, description, loading, error, colorVariant, format, currency, prefix, suffix, onClick, variant, schema: _schema, bind: _bind, events: _events, props: _propsBag, ariaLabel: _ariaLabel, ariaDescribedBy: _ariaDescribedBy, dataSource: _dataSource, ...domProps }: MetricWidgetProps & SchemaHostProps) => React.JSX.Element;
|
|
47
112
|
//# sourceMappingURL=MetricWidget.d.ts.map
|