@object-ui/plugin-dashboard 17.6.0 → 17.7.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.
Files changed (53) hide show
  1. package/CHANGELOG.md +4519 -0
  2. package/README.md +424 -83
  3. package/dist/DashboardConfigPanel.d.ts +1 -1
  4. package/dist/DashboardFilterBar.d.ts.map +1 -1
  5. package/dist/DashboardGridLayout.d.ts +3 -2
  6. package/dist/DashboardGridLayout.d.ts.map +1 -1
  7. package/dist/DashboardRenderer.d.ts +32 -2
  8. package/dist/DashboardRenderer.d.ts.map +1 -1
  9. package/dist/DashboardWithConfig.d.ts +1 -1
  10. package/dist/DashboardWithConfig.d.ts.map +1 -1
  11. package/dist/DatasetWidget.d.ts +42 -14
  12. package/dist/DatasetWidget.d.ts.map +1 -1
  13. package/dist/DrillDownDrawer.d.ts +14 -5
  14. package/dist/DrillDownDrawer.d.ts.map +1 -1
  15. package/dist/MetricCard.d.ts +1 -1
  16. package/dist/MetricWidget.d.ts +27 -2
  17. package/dist/MetricWidget.d.ts.map +1 -1
  18. package/dist/ObjectDataTable.d.ts +407 -18
  19. package/dist/ObjectDataTable.d.ts.map +1 -1
  20. package/dist/ObjectMetricWidget.d.ts +35 -8
  21. package/dist/ObjectMetricWidget.d.ts.map +1 -1
  22. package/dist/ObjectPivotTable.d.ts +46 -7
  23. package/dist/ObjectPivotTable.d.ts.map +1 -1
  24. package/dist/PivotTable.d.ts +20 -3
  25. package/dist/PivotTable.d.ts.map +1 -1
  26. package/dist/RecordDetailDrawer.d.ts +8 -0
  27. package/dist/RecordDetailDrawer.d.ts.map +1 -1
  28. package/dist/WidgetConfigPanel.d.ts +2 -2
  29. package/dist/WidgetConfigPanel.d.ts.map +1 -1
  30. package/dist/WidgetEmptyState.d.ts +27 -0
  31. package/dist/WidgetEmptyState.d.ts.map +1 -0
  32. package/dist/domPassthroughPins.d.ts.map +1 -1
  33. package/dist/index.d.ts +22 -21
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +1733 -1570
  36. package/dist/index.umd.cjs +2 -2
  37. package/dist/legacyRetiredWidget.d.ts +5 -3
  38. package/dist/legacyRetiredWidget.d.ts.map +1 -1
  39. package/dist/measureRefusal.d.ts +50 -0
  40. package/dist/measureRefusal.d.ts.map +1 -0
  41. package/dist/recordFields.d.ts +119 -8
  42. package/dist/recordFields.d.ts.map +1 -1
  43. package/dist/retired-node-types.d.ts +29 -0
  44. package/dist/retired-node-types.d.ts.map +1 -0
  45. package/dist/useDashboardAutoRefresh.d.ts +47 -0
  46. package/dist/useDashboardAutoRefresh.d.ts.map +1 -0
  47. package/dist/utils.d.ts +36 -7
  48. package/dist/utils.d.ts.map +1 -1
  49. package/dist/widgetDispatch.d.ts +144 -18
  50. package/dist/widgetDispatch.d.ts.map +1 -1
  51. package/dist/widgetSubCaption.d.ts +40 -0
  52. package/dist/widgetSubCaption.d.ts.map +1 -0
  53. package/package.json +15 -16
@@ -0,0 +1,50 @@
1
+ /**
2
+ * ObjectUI
3
+ * Copyright (c) 2024-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ /**
9
+ * objectui#8894 — what the widget door says about a widget's MEASURES.
10
+ *
11
+ * Returns the message of the `custom` issue objectui's authoring door raises at
12
+ * `values` for this type, these measures and these dimensions, or `undefined`
13
+ * when the door accepts them. The door is `DashboardWidgetSchema` from
14
+ * `@object-ui/types/zod`, which re-attaches the spec's own object-level checks,
15
+ * so its verdict and its message are the spec's (pinned by
16
+ * `packages/types/src/__tests__/dashboard-widget-metric-measure-door-8894.test.ts`).
17
+ *
18
+ * The door is ASKED, never restated: no widget-type list lives here. Whichever
19
+ * types the spec refuses a second measure on — the metric family since
20
+ * `@objectstack/spec` 17.5.0 (`checkDashboardWidgetMetricMeasureArity`), and
21
+ * any further shape once a spec release refuses it and the mirror re-attaches
22
+ * that check (objectstack#20958 is the pending one) — the authoring pickers that
23
+ * read this follow without an edit here.
24
+ *
25
+ * Only the keys a measure rule reads go into the probe — `id` (the message
26
+ * names it), `type`, `values` and `dimensions` — each kept to a shape the door
27
+ * accepts. zod skips object-level checks once a field-level issue aborts the
28
+ * parse, and a draft in an editor is half-written by nature: measured on the
29
+ * mirror, a numeric `id`, a non-string dimension or a malformed `title`
30
+ * anywhere in the document each hide the measure verdict completely, which
31
+ * would read as "accepted". The probe keeps those faults out of the question it
32
+ * asks.
33
+ *
34
+ * Module-private to this package (not re-exported from its index).
35
+ */
36
+ export declare function measureRefusal(widget: {
37
+ id?: unknown;
38
+ type?: unknown;
39
+ values?: unknown;
40
+ dimensions?: unknown;
41
+ }): string | undefined;
42
+ /**
43
+ * A stand-in for "one more measure", used to ask the door whether a picker may
44
+ * offer another one before the author has chosen which. The door's measure
45
+ * rules judge how many measures a widget declares, not their names (whether a
46
+ * measure exists in the bound dataset is out of the widget schema's reach), so
47
+ * any name the widget does not already carry asks the same question.
48
+ */
49
+ export declare const NEXT_MEASURE_PROBE = "__next_measure__";
50
+ //# sourceMappingURL=measureRefusal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"measureRefusal.d.ts","sourceRoot":"","sources":["../src/measureRefusal.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE;IACrC,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,GAAG,MAAM,GAAG,SAAS,CAgBrB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,qBAAqB,CAAC"}
@@ -8,6 +8,74 @@ export declare const SYSTEM_FIELDS: Set<string>;
8
8
  export declare function isSystemField(name: string, def?: any): boolean;
9
9
  /** Numeric-flavoured field types (right-aligned in tables). */
10
10
  export declare const NUMERIC_FIELD_TYPES: Set<string>;
11
+ /**
12
+ * The override vocabulary this package's two field surfaces share.
13
+ *
14
+ * ⚠️ This type is a DERIVATION SOURCE, not only a shape: `ObjectDataTable`'s
15
+ * two column bands are both `Exclude<keyof FieldMeta, …>` — `EnrichedColumn`'s
16
+ * write-side tombstones (objectui#6373) and `AuthoredColumnOverrides`' read-side
17
+ * refusal band (objectui#6425). So a member REMOVED here silently leaves both
18
+ * bands, and any refusal that rode on its membership stops enforcing with
19
+ * nothing going red. A member being retired must therefore be re-refused
20
+ * explicitly at that seam before it leaves this type — see
21
+ * `ObjectDataTableRetiredDecimalsTombstone` in `ObjectDataTable.tsx`, which is
22
+ * what `decimals` left behind.
23
+ *
24
+ * ⛔ `decimals` was RETIRED from this type by objectui#6625 — written from the
25
+ * schema def on every call and read by nothing (zero `.decimals` member reads
26
+ * across `@object-ui/fields`, `@object-ui/i18n`, `@object-ui/components`,
27
+ * `@object-ui/core` and this package, measured against a `.scale` positive
28
+ * control that hits `NumberField.tsx` / `GridField.tsx` / `index.tsx`). If a
29
+ * reader is ever wanted here it reads `scale` — the field def's decimal-places
30
+ * key, which is what the retired write resolved to anyway and what
31
+ * `NumberCellRenderer` already reads (`precision` is the total digit count, a
32
+ * different question — objectui#2131). ⛔ Do not resurrect `decimals`.
33
+ *
34
+ * ⛔ `referenceTo` was RETIRED from this type by objectui#6597 (enforce-or-remove,
35
+ * withdraw branch — maintainer's standing startup-stage rule, 2026-08-27: no
36
+ * measured demand retires immediately). It was documented by this package's
37
+ * README as an author-facing column override, but the promise was never kept:
38
+ * `LookupCellRenderer` (`@object-ui/fields`) resolves its lookup target from
39
+ * `field.reference_to` / `field.reference` — never `field.referenceTo` — and
40
+ * `computeLookupExpand` (`ObjectDataTable.tsx`) builds `$expand` from the OBJECT
41
+ * SCHEMA's field types, never from an authored override. Measured with the
42
+ * `referenceTo`-vs-`options` positive control in
43
+ * `ObjectDataTable.overrideSource-6425.test.tsx`: `options` (a live override)
44
+ * separates two equal-valued columns, `referenceTo` does not — an authored
45
+ * override renders byte-identical to its absence. No authoring story survived
46
+ * the search either: the sibling `ObjectGrid` producer's own relational-meta
47
+ * pass-through (`applyRelationalMeta`, `plugin-grid/src/ObjectGrid.tsx`) copies
48
+ * `reference_to` / `reference` from the SCHEMA field def only, never from an
49
+ * authored column override, and no example/doc/fixture in this repo shows a
50
+ * table column pinning a lookup's target to something other than what its
51
+ * schema field already says. If a reader for the resolved reference target is
52
+ * ever wanted here, it reads `reference_to` / `reference` off the schema field
53
+ * def directly — the spelling `LookupCellRenderer` and `computeLookupExpand`
54
+ * actually use. ⛔ Do not resurrect `referenceTo`.
55
+ *
56
+ * ⭐ That reader ARRIVED (objectui#6694): `reference` / `displayField` below
57
+ * (with `reference_to` beside them until objectui#11070 round 4 retired it,
58
+ * and `display_field` until objectui#11070's text-family round did), copied
59
+ * from the SCHEMA field def by {@link buildFieldMeta} and justified per key on
60
+ * `CELL_RELATIONAL_META_KEYS`.
61
+ * They are the "future reader" both retirement notes predicted, in the spelling
62
+ * they named, and they change neither verdict — the source is the schema field
63
+ * def, never an authored column override, which is the exact distinction
64
+ * objectui#6597 measured and withdrew on.
65
+ *
66
+ * ⚠️ Being `FieldMeta` members they GROW both derived bands in
67
+ * `ObjectDataTable.tsx` — `EnrichedColumn`'s emit tombstones and
68
+ * `UnheldFieldMetaOverrideKey`'s read-side refusal. `reference_to` left the
69
+ * type in objectui#11070 round 4 and `display_field` in its text-family round,
70
+ * so — by the rule at the top of this docblock — each one's refusal is
71
+ * re-stated by hand there (`ObjectDataTableRetiredReferenceToSnakeTombstone`,
72
+ * `ObjectDataTableRetiredDisplayFieldSnakeTombstone`). That is the intended
73
+ * verdict rather than a side effect: an AUTHORED column may not source a
74
+ * lookup's reference target (objectui#6597 measured no authoring story for
75
+ * one), while the schema-derived write is reached by neither band. They landed
76
+ * in both without anyone editing a list — the property this derivation exists
77
+ * for.
78
+ */
11
79
  export interface FieldMeta {
12
80
  name: string;
13
81
  label: string;
@@ -17,10 +85,34 @@ export interface FieldMeta {
17
85
  label: string;
18
86
  color?: string;
19
87
  }>;
20
- referenceTo?: unknown;
21
88
  format?: string;
22
89
  currency?: string;
23
- decimals?: number;
90
+ /**
91
+ * The field def's declared upper bound, which on a `percent` field is its
92
+ * STORAGE statement: the spec's `percentScaleOf` reads a fraction unless
93
+ * `max` is above 1 (objectui#11475). Copied from the SCHEMA field def by
94
+ * {@link buildFieldMeta} so the percent cell and the `%` branch of
95
+ * {@link renderFieldValue} read the field's storage rather than guess it
96
+ * from the value. Never an authored column override: as a `FieldMeta`
97
+ * member it lands in `ObjectDataTable`'s read-side refusal band, which is
98
+ * the intended verdict — a column may not restate how its field stores.
99
+ */
100
+ max?: number;
101
+ /**
102
+ * Lookup target object — the spelling `@objectstack/spec`'s `FieldSchema`
103
+ * declares and the only one `LookupCellRenderer` reads. Its snake_case twin
104
+ * `reference_to` was RETIRED from this type by objectui#11070 round 4.
105
+ */
106
+ reference?: string;
107
+ /**
108
+ * Author-declared display field on the lookup, in the SPEC spelling
109
+ * (`FieldSchema.displayField`) — it beats every resolver in the cell. The
110
+ * first leg of `LookupCellRenderer`'s `displayField || reference_field`
111
+ * chain, and the only leg a spec-compliant producer can emit
112
+ * (objectui#6875). Its snake_case twin `display_field` was RETIRED from this
113
+ * type by objectui#11070's text-family round: no reader read it.
114
+ */
115
+ displayField?: string;
24
116
  }
25
117
  /**
26
118
  * Normalize an object schema's `fields` into a `{ name → def }` map. Accepts
@@ -37,20 +129,39 @@ export interface BuildFieldMetaParams {
37
129
  objectName?: string;
38
130
  /** Translator for per-option labels (from `useSafeFieldLabel`). */
39
131
  fieldOptionLabel?: (objectName: string, field: string, value: string, fallback: string) => string;
40
- /** Per-column overrides (table columns may pin type/format/options). */
132
+ /**
133
+ * Per-column overrides (table columns may pin type/format/options).
134
+ *
135
+ * A subset of {@link FieldMeta}, which is what makes that type the pool
136
+ * `ObjectDataTable`'s refusal band derives from. `decimals` left with the
137
+ * member (objectui#6625): its last feeder went when objectui#6425's ruling
138
+ * removed the authored read from `ObjectDataTable.enrich()`, and
139
+ * `RecordDetailDrawer` — the only other caller — passes no overrides at all.
140
+ * `referenceTo` left the same way (objectui#6597): `ObjectDataTable.enrich()`
141
+ * no longer reads it off the authored column, and `RecordDetailDrawer` never
142
+ * did.
143
+ */
41
144
  overrides?: {
42
145
  type?: string;
43
146
  format?: string;
44
147
  options?: any;
45
- referenceTo?: unknown;
46
148
  currency?: string;
47
- decimals?: number;
48
149
  };
49
150
  }
50
151
  /**
51
- * Build the `FieldMeta` for a single field, resolving `referenceTo`, currency
52
- * and decimals from the schema field def and translating select options.
53
- * Column-level overrides win over schema-derived values.
152
+ * Build the `FieldMeta` for a single field, resolving currency from the
153
+ * schema field def and translating select options. Column-level overrides
154
+ * win over schema-derived values.
155
+ *
156
+ * The field def's currency goes through `resolveFieldCurrency`
157
+ * (`@object-ui/i18n`) rather than a chain of this helper's own (objectui#10463).
158
+ * The resolver is what reads `currencyConfig`, the spec's one fixed-currency
159
+ * declaration, and only under `currencyMode: 'fixed'`. The chain it replaced
160
+ * read the flat `currency` / `defaultCurrency` spellings only, so a fixed
161
+ * field painted in the tenant currency in both the table cell and the record
162
+ * drawer. The call passes NO tenant default: `renderFieldValue` backstops with
163
+ * the tenant only after the symbol it infers from a `format`, and a tenant code
164
+ * resolved here would jump ahead of that symbol.
54
165
  */
55
166
  export declare function buildFieldMeta(params: BuildFieldMetaParams): FieldMeta;
56
167
  /** Whether a `FieldMeta` should be right-aligned (numeric / currency / percent). */
@@ -1 +1 @@
1
- {"version":3,"file":"recordFields.d.ts","sourceRoot":"","sources":["../src/recordFields.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAoB1B;;;GAGG;AACH,eAAO,MAAM,aAAa,aAIxB,CAAC;AAEH,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,GAAG,OAAO,CAG9D;AAKD,+DAA+D;AAC/D,eAAO,MAAM,mBAAmB,aAE9B,CAAC;AAEH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAUxE;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;IAClG,wEAAwE;IACxE,SAAS,CAAC,EAAE;QACV,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,GAAG,CAAC;QACd,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,oBAAoB,GAAG,SAAS,CAoCtE;AAED,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,CAAC,GAAG,OAAO,CAKzF;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,GAAG,EACV,SAAS,EAAE,SAAS,EACpB,cAAc,CAAC,EAAE,MAAM,EAKvB,aAAa,CAAC,EAAE,MAAM,GACrB,KAAK,CAAC,SAAS,CAiDjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAMhD"}
1
+ {"version":3,"file":"recordFields.d.ts","sourceRoot":"","sources":["../src/recordFields.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAyB1B;;;GAGG;AACH,eAAO,MAAM,aAAa,aAIxB,CAAC;AAEH,kFAAkF;AAClF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,GAAG,OAAO,CAG9D;AAKD,+DAA+D;AAC/D,eAAO,MAAM,mBAAmB,aAE9B,CAAC;AAyIH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmEG;AACH,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;;;;OASG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAUxE;AAED,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,2DAA2D;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;IAClG;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,EAAE;QACV,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,GAAG,CAAC;QACd,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,oBAAoB,GAAG,SAAS,CA8CtE;AAED,oFAAoF;AACpF,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,CAAC,GAAG,OAAO,CAKzF;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,GAAG,EACV,SAAS,EAAE,SAAS,EACpB,cAAc,CAAC,EAAE,MAAM,EAKvB,aAAa,CAAC,EAAE,MAAM,GACrB,KAAK,CAAC,SAAS,CA4EjB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAMhD"}
@@ -0,0 +1,29 @@
1
+ import { default as React } from 'react';
2
+ /**
3
+ * The bare name of every retired spelling, mapped to the refusal text the
4
+ * tombstone renders and logs. Keyed by the BARE name because that is what
5
+ * `ComponentRegistry.register` takes; the namespace is spelled at the call.
6
+ *
7
+ * The message names BOTH halves deliberately — the spelling that was written
8
+ * and the spelling that replaces it. A refusal that only says "unknown" is the
9
+ * one this table exists to stop being.
10
+ */
11
+ export declare const RETIRED_DASHBOARD_NODE_TYPES: Readonly<Record<string, string>>;
12
+ /**
13
+ * Log a retired node-type spelling once. Exported for the pin test, which has
14
+ * to be able to observe a SECOND occurrence being suppressed without inventing
15
+ * its own copy of the set.
16
+ */
17
+ export declare function reportRetiredDashboardNodeType(spelling: string): void;
18
+ /** Test seam: forget what has been reported, so a pin can measure the first one. */
19
+ export declare function resetRetiredDashboardNodeTypeReports(): void;
20
+ /**
21
+ * The widget a RETIRED dashboard node-type spelling renders.
22
+ *
23
+ * The rendered text and the logged text are the SAME string, read from
24
+ * {@link RETIRED_DASHBOARD_NODE_TYPES}. A pin that asserts only "nothing
25
+ * rendered" cannot tell this refusal apart from the key having been deleted
26
+ * outright, which is why the text is part of the contract and not decoration.
27
+ */
28
+ export declare const RetiredDashboardNodeTombstone: React.FC<Record<string, unknown>>;
29
+ //# sourceMappingURL=retired-node-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retired-node-types.d.ts","sourceRoot":"","sources":["../src/retired-node-types.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B;;;;;;;;GAQG;AACH,eAAO,MAAM,4BAA4B,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAOxE,CAAC;AAKH;;;;GAIG;AACH,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAOrE;AAED,oFAAoF;AACpF,wBAAgB,oCAAoC,IAAI,IAAI,CAE3D;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,6BAA6B,EAAE,KAAK,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAwB3E,CAAC"}
@@ -0,0 +1,47 @@
1
+ import { DashboardComponentSchema } from '@object-ui/types';
2
+ /**
3
+ * The dashboard auto-refresh timer: ONE implementation, two mount points
4
+ * (objectui#8820).
5
+ *
6
+ * `DashboardGridLayout` and `DashboardRenderer` each used to carry their own
7
+ * copy of the same three things: a `refreshing` flag, a `handleRefresh`
8
+ * callback shared by the manual "Refresh All" button and the timer, and an
9
+ * effect that read the authored period and drove `setInterval`. The copies were
10
+ * identical in logic, and two copies of one rule is two places to change and
11
+ * one place to forget: the `refreshInterval` to `refreshIntervalSeconds` rename
12
+ * (objectui#7783) had to be made twice, and a copy that drifted would still
13
+ * pass its own component's tests.
14
+ *
15
+ * This hook is that logic, moved here. Both surfaces call it, so the authored
16
+ * period is read in exactly one place.
17
+ *
18
+ * - The period is `refreshIntervalSeconds`, in seconds, and nothing else. The
19
+ * retired `refreshInterval` spelling is refused by the spec's
20
+ * `DashboardSchema`, so no fallback reads it (AGENTS.md #0.1).
21
+ * - The timer runs only when the host wired `onRefresh` AND the period is
22
+ * greater than zero: an absent period, `0` and a negative value all mean
23
+ * "off".
24
+ * - The interval is armed on VALUES only: the period and whether a handler is
25
+ * wired. The handler itself is read through a ref when a run happens, so a
26
+ * new handler identity, from the host or from React discarding a memo, never
27
+ * re-arms the interval or moves its phase, and the run still calls the
28
+ * CURRENT handler (AGENTS.md #10, objectui#11004).
29
+ * - The indicator clears itself 600ms after each run, manual or timed.
30
+ *
31
+ * `__tests__/dashboardAutoRefreshTimer.test.tsx` mounts both surfaces and
32
+ * counts `onRefresh` calls under fake timers. It pins the first three points,
33
+ * the third under a forced memo discard; nothing pins the 600ms indicator.
34
+ */
35
+ /** What a dashboard surface needs to drive its refresh affordance. */
36
+ export interface DashboardAutoRefresh {
37
+ /** True while a refresh is in flight; drives the spinner and disables the button. */
38
+ refreshing: boolean;
39
+ /** Run a refresh now. Wired to both the manual button and the timer. */
40
+ handleRefresh: () => void;
41
+ }
42
+ /**
43
+ * Owns the refresh indicator, the manual refresh handler, and the auto-refresh
44
+ * interval for one dashboard surface.
45
+ */
46
+ export declare function useDashboardAutoRefresh(schema: DashboardComponentSchema, onRefresh?: () => void): DashboardAutoRefresh;
47
+ //# sourceMappingURL=useDashboardAutoRefresh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDashboardAutoRefresh.d.ts","sourceRoot":"","sources":["../src/useDashboardAutoRefresh.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAEjE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,sEAAsE;AACtE,MAAM,WAAW,oBAAoB;IACnC,qFAAqF;IACrF,UAAU,EAAE,OAAO,CAAC;IACpB,wEAAwE;IACxE,aAAa,EAAE,MAAM,IAAI,CAAC;CAC3B;AAoBD;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,wBAAwB,EAChC,SAAS,CAAC,EAAE,MAAM,IAAI,GACrB,oBAAoB,CAsCtB"}
package/dist/utils.d.ts CHANGED
@@ -1,10 +1,4 @@
1
- /**
2
- * ObjectUI
3
- * Copyright (c) 2024-present ObjectStack Inc.
4
- *
5
- * This source code is licensed under the MIT license found in the
6
- * LICENSE file in the root directory of this source tree.
7
- */
1
+ import { useObjectLabel, useObjectTranslation } from '@object-ui/i18n';
8
2
  /** Returns true when the widget data config uses provider: 'object' (async data source). */
9
3
  export declare function isObjectProvider(widgetData: unknown): widgetData is {
10
4
  provider: 'object';
@@ -21,6 +15,41 @@ export declare function isObjectProvider(widgetData: unknown): widgetData is {
21
15
  * path derives headers with it when no columns were declared at all.
22
16
  */
23
17
  export declare function humanizeFieldKey(key: string): string;
18
+ /**
19
+ * Resolve a chart series label — the SINGLE authority both dashboard relays
20
+ * (`DashboardRenderer`, `DashboardGridLayout`) call, so the three-arm decision
21
+ * below lives once instead of as two copies that could drift.
22
+ *
23
+ * Originated as a `DashboardRenderer`-local `useCallback` (objectui#9055,
24
+ * which fixed arms 2 and 3 there). `DashboardGridLayout` composed
25
+ * `series: [{ dataKey }]` with no `label` key on either of its branches — the
26
+ * legend and tooltip rendered the raw field key while the sibling relay's
27
+ * chart for the same widget rendered the humanized one (objectui#9172). That
28
+ * card is what moved this here rather than growing a second copy of the
29
+ * three-arm logic: a helper duplicated across the two relays is exactly the
30
+ * "one value, two spellings" class `56f4e34c0` ruled out.
31
+ *
32
+ * ⭐ THREE ARMS, and only the last two derive a display string from a FIELD
33
+ * KEY:
34
+ *
35
+ * arm 1 synthetic y-field ('value' / 'count' / '') + an aggregate function
36
+ * -> an i18n'd aggregate name (Count / Sum / Average …), so a
37
+ * fieldless count aggregate doesn't leak the placeholder 'value' /
38
+ * 'count' string into the legend / tooltip.
39
+ * arm 2 a real object + a real field -> `fieldLabel`'s bundle lookup, with
40
+ * the HUMANIZED key (not the raw one) as its fallback.
41
+ * arm 3 no object name at all (a static-data chart) -> the humanized key
42
+ * outright.
43
+ *
44
+ * `t` and `fieldLabel` are injected rather than the hooks themselves, so this
45
+ * stays a plain function callable from either relay's own
46
+ * `useObjectTranslation()` / `useObjectLabel()` instances — no shared hook
47
+ * identity to manage, and each relay keeps memoizing its own `useCallback`
48
+ * wrapper over this (objectui#10's caution against depending on a memo's
49
+ * IDENTITY is about correctness, not about composing plain functions like
50
+ * this one).
51
+ */
52
+ export declare function composeSeriesLabel(t: ReturnType<typeof useObjectTranslation>['t'], fieldLabel: ReturnType<typeof useObjectLabel>['fieldLabel'], objectName: string | undefined, yField: string, aggFn: string | undefined): string;
24
53
  /**
25
54
  * Columns for a STATIC (inline `options.data`) table widget whose author
26
55
  * declared none — objectui#4618.
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,4FAA4F;AAC5F,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,OAAO,GAAG,UAAU,IAAI;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,GAAG,CAAC;IAAC,MAAM,CAAC,EAAE,GAAG,CAAA;CAAE,CAO1I;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CASpD;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,OAAO,GAAG,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAOtG;AAUD,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAG/E,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,KAAK,eAAe,GACrB,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAClC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAClC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAAA;CAAE,GAAG,IAAI,CAkBhE"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE5E,4FAA4F;AAC5F,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,OAAO,GAAG,UAAU,IAAI;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,GAAG,CAAC;IAAC,MAAM,CAAC,EAAE,GAAG,CAAA;CAAE,CAO1I;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CASpD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,kBAAkB,CAChC,CAAC,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC,GAAG,CAAC,EAC/C,UAAU,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC,YAAY,CAAC,EAC3D,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,MAAM,CAUR;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,OAAO,GAAG,KAAK,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CAOtG;AAUD,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAG/E,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,KAAK,eAAe,GACrB,MAAM,iBAAiB,CAAC;AAEzB;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAClC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAClC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,SAAS,CAAA;CAAE,GAAG,IAAI,CAkBhE"}
@@ -1,26 +1,66 @@
1
+ import { BaseSchema, DashboardComponentSchema, DashboardWidgetSchema, DashboardWidgetSlotComponentSchema, DashboardWidgetTypeName } from '@object-ui/types';
2
+ import { MetricWidgetProps } from './MetricWidget.js';
1
3
  /**
2
- * ObjectUI
3
- * Copyright (c) 2024-present ObjectStack Inc.
4
+ * One entry of a dashboard's `widgets[]`: the slot's element type, a widget or
5
+ * a component node placed directly in the slot (the 2026-08-14 `metric-card`
6
+ * slot ruling, objectstack#8593). Read off `DashboardComponentSchema.widgets`,
7
+ * so it is the slot's own declaration, not a restatement.
4
8
  *
5
- * This source code is licensed under the MIT license found in the
6
- * LICENSE file in the root directory of this source tree.
9
+ * Every dashboard surface reads `widgets[]` entries by this type
10
+ * (objectui#11514). The widget arm, `DashboardWidgetSchema`, is not a read type
11
+ * for an entry: since objectui#11483's closure its `type` names the widget
12
+ * vocabulary only, so the component arm is not assignable to it.
7
13
  */
14
+ export type DashboardWidgetSlotEntry = DashboardComponentSchema['widgets'][number];
15
+ export declare function specDefaultWidgetType(): DashboardWidgetTypeName;
8
16
  /**
9
- * Widget-type → dispatch family, shared by every dashboard surface.
17
+ * The `type` a dashboard surface draws a `widgets[]` entry as: the authored
18
+ * `type`, or {@link specDefaultWidgetType} when the entry names none
19
+ * (objectui#11514, Q2 A). Every read of an entry's `type` on the two surfaces
20
+ * goes through it — the dispatch, the metric span and chrome, the mobile
21
+ * metric row — so a typeless widget draws exactly as the same widget with
22
+ * `type: 'metric'` does. It used to reach the slot-component passthrough and
23
+ * draw the registry's red OBJUI-001 panel.
10
24
  *
11
- * Three surfaces used to restate this knowledge independently and disagree:
12
- * `DatasetWidget` covered all 19 `ChartTypeSchema` values, `DashboardRenderer`
13
- * covered 15, and `DashboardGridLayout` 8. A type the surface didn't name fell
14
- * through to `{ ...widget }`, whose `type` no component registers — so
15
- * `SchemaRenderer` rendered a red `role="alert"` panel dumping the widget JSON
16
- * (#2943).
17
- *
18
- * The single-value families were the sharpest case: `DashboardRenderer` already
19
- * had `METRIC_LIKE_TYPES = ['gauge','solid-gauge','kpi','bullet']` with a
20
- * docstring saying they "render as a metric card rather than a chart" — and
21
- * consulted it only to pick a grid span. The tile was sized correctly and the
22
- * widget was never routed.
25
+ * ⛔ Not for the legacy `component` envelope (`{ id, component, layout }`,
26
+ * objectui's own format, which the spec's widget has no member for). It draws
27
+ * its node, never a family, so the spec's default `type` says nothing about it:
28
+ * an envelope that names no `type` keeps `undefined` here and draws, chrome
29
+ * included, as it always did.
30
+ */
31
+ export declare function resolveWidgetType(entry: DashboardWidgetSlotEntry): DashboardWidgetSlotEntry['type'];
32
+ /**
33
+ * The node an entry's legacy `component` envelope holds, typed as the widget
34
+ * arm declares that member (`DashboardWidgetSchema['component']`). Read off the
35
+ * entry whichever arm it is, as the surfaces always read it. The component arm
36
+ * declares no `component`, so a bare `entry.component` on the slot entry reads
37
+ * through `BaseSchema`'s index signature and is `any` — which made each
38
+ * surface's whole `getComponentSchema` return `any` (objectui#11514).
39
+ */
40
+ export declare function entryComponent(entry: DashboardWidgetSlotEntry): DashboardWidgetSchema['component'];
41
+ /**
42
+ * Whether a slot entry is the component arm, `DashboardWidgetSlotComponentSchema`:
43
+ * its `type` is a member of the closed `DASHBOARD_COMPONENT_WIDGET_TYPES`, which
44
+ * no widget `type` names (objectui#11483). Read at runtime, so a stored entry
45
+ * whose `type` is a string outside every vocabulary is NOT the component arm.
46
+ */
47
+ export declare function isSlotComponentEntry(entry: DashboardWidgetSlotEntry): entry is DashboardWidgetSlotComponentSchema;
48
+ /**
49
+ * The labelled placeholder a dashboard surface draws for a widget `type` it
50
+ * has no renderer for: a known family with no renderer yet
51
+ * (`UNSUPPORTED_CHART_TYPES`), and, since objectui#11514 (Q2 A), a `type` that
52
+ * names no family at all — stale metadata both validator faces refuse at
53
+ * `type`, which used to fall through to the slot-component passthrough and
54
+ * draw the registry's red OBJUI-001 panel dumping the widget. One declaration
55
+ * for both surfaces, which each spelled it out before.
23
56
  */
57
+ export declare function unsupportedWidgetSchema(widgetType: string | undefined): {
58
+ readonly type: "text";
59
+ readonly content: `\u300C${string}\u300Dchart type is not supported yet`;
60
+ readonly variant: "caption";
61
+ readonly align: "center";
62
+ readonly className: "flex h-full w-full items-center justify-center rounded border border-dashed bg-muted/20 p-4 text-muted-foreground";
63
+ };
24
64
  /**
25
65
  * Spec chart families that only render as another family. Normalizing them
26
66
  * here is what lets one branch serve `column` and `bar` (the spec's own
@@ -28,6 +68,16 @@
28
68
  */
29
69
  export declare const CHART_TYPE_ALIASES: Record<string, string>;
30
70
  /** Cartesian / categorical / flow families the chart renderer draws. */
71
+ declare const SERIES_CHART_FAMILIES: readonly ["bar", "horizontal-bar", "line", "area", "pie", "donut", "scatter", "funnel", "radar", "treemap", "sankey", "combo"];
72
+ /**
73
+ * A family {@link SERIES_CHART_TYPES} names, as a literal union: the
74
+ * `chartType` a `series` dispatch carries. Each member is one of the families
75
+ * `ObjectChartSchema.chartType` declares (objectui#11513), so the `object-chart`
76
+ * node a surface builds from a dispatch names its family with no cast
77
+ * (objectui#11514). Pinned by `__tests__/dashboard-producer-node-types-11514.test.ts`.
78
+ */
79
+ export type SeriesChartFamily = (typeof SERIES_CHART_FAMILIES)[number];
80
+ /** Cartesian / categorical / flow families the chart renderer draws. */
31
81
  export declare const SERIES_CHART_TYPES: ReadonlySet<string>;
32
82
  /**
33
83
  * Single-value "performance" families — one number, optionally against a
@@ -65,7 +115,7 @@ export type WidgetDispatchFamily =
65
115
  export interface WidgetDispatch {
66
116
  family: WidgetDispatchFamily;
67
117
  /** For `series`: the alias-resolved base family to draw. */
68
- chartType?: string;
118
+ chartType?: SeriesChartFamily;
69
119
  }
70
120
  /**
71
121
  * Classify a widget `type` into its dispatch family. Exported for the
@@ -73,4 +123,80 @@ export interface WidgetDispatch {
73
123
  * `passthrough` (the branch that produces the red box).
74
124
  */
75
125
  export declare function classifyWidgetType(widgetType: string | undefined): WidgetDispatch;
126
+ /**
127
+ * The node key a dashboard surface hands `SchemaRenderer` for each component
128
+ * this package registers with `skipFallback: true` (objectui#10859 batch 8,
129
+ * phase 2b, seat ruling M3 option A).
130
+ *
131
+ * `metric` and `metric-card` are two vocabularies that happened to share one
132
+ * spelling: the dashboard WIDGET type (the spec's `ChartTypeSchema` value
133
+ * `metric`; the 2026-08-14 slot ruling's `metric-card`, objectstack#8593) and
134
+ * the internal NODE key the dashboard renders that widget through. The widget
135
+ * vocabulary is untouched. Only the node key moved: the registrations publish
136
+ * `plugin-dashboard:metric` / `plugin-dashboard:metric-card` and no bare
137
+ * fallback, so nothing authors a bare `metric` / `metric-card` NODE that the
138
+ * registry mounts while `objectui validate` refuses it at `type`.
139
+ *
140
+ * ⛔ Both surfaces (`DashboardRenderer`, `DashboardGridLayout`) emit through
141
+ * this table, so they cannot drift apart; a new `skipFallback` registration in
142
+ * this package that a widget can reach gets its row here in the same edit.
143
+ *
144
+ * The values are literal types (objectui#11466), so a node a surface builds
145
+ * under `DASHBOARD_NODE_TYPES.metric` is discriminated by its key and checked
146
+ * against {@link DashboardMetricNodeSchema}, the `CustomNodeRegistry` entry
147
+ * below. A lookup by an authored `type` string goes through the string-keyed
148
+ * view {@link toDashboardNodeType} reads.
149
+ */
150
+ export declare const DASHBOARD_NODE_TYPES: {
151
+ readonly metric: "plugin-dashboard:metric";
152
+ readonly 'metric-card': "plugin-dashboard:metric-card";
153
+ };
154
+ /**
155
+ * The `plugin-dashboard:metric` node: what both dashboard surfaces hand
156
+ * `SchemaRenderer` for a `metric` widget drawn inline, and what the `metric`
157
+ * registration (`skipFallback: true`) mounts as `MetricWidget`.
158
+ *
159
+ * Declared in `@object-ui/types`' `CustomNodeRegistry` (objectui#11466, as
160
+ * objectui#11479's Q1 A ruled), the registry an application augments for the
161
+ * node types it registers that `@object-ui/types` does not declare. So the
162
+ * producers name a declared node type, and `SchemaRenderer` takes the node
163
+ * with no cast. The key is this package's: `@object-ui/types` cannot name a
164
+ * plugin's namespace.
165
+ *
166
+ * Its keys are the ones `MetricWidget` reads off the node, typed by that
167
+ * component's props so the two cannot disagree. Host state (`loading`,
168
+ * `error`) and the `onClick` handler are props, ⛔ not node keys.
169
+ */
170
+ export interface DashboardMetricNodeSchema extends BaseSchema {
171
+ type: typeof DASHBOARD_NODE_TYPES.metric;
172
+ label: MetricWidgetProps['label'];
173
+ value: MetricWidgetProps['value'];
174
+ description?: MetricWidgetProps['description'];
175
+ trend?: MetricWidgetProps['trend'];
176
+ /** A Lucide icon name. A React element is a host prop, never a node key. */
177
+ icon?: string;
178
+ colorVariant?: MetricWidgetProps['colorVariant'];
179
+ format?: MetricWidgetProps['format'];
180
+ currency?: MetricWidgetProps['currency'];
181
+ prefix?: MetricWidgetProps['prefix'];
182
+ suffix?: MetricWidgetProps['suffix'];
183
+ variant?: MetricWidgetProps['variant'];
184
+ }
185
+ declare module '@object-ui/types' {
186
+ interface CustomNodeRegistry {
187
+ 'plugin-dashboard:metric': DashboardMetricNodeSchema;
188
+ }
189
+ }
190
+ /**
191
+ * `node` with its `type` moved onto the namespaced key {@link
192
+ * DASHBOARD_NODE_TYPES} names, or `node` itself when the type has no row.
193
+ *
194
+ * Applied where a surface forwards a node it did not build: the slot-component
195
+ * passthrough (`{ type: 'metric-card', ... }` directly in `widgets[]`) and an
196
+ * author-supplied `widget.component`. Both are widget-vocabulary positions,
197
+ * which keep their spelling; this is the boundary where the widget becomes a
198
+ * node.
199
+ */
200
+ export declare function toDashboardNodeType<T>(node: T): T;
201
+ export {};
76
202
  //# sourceMappingURL=widgetDispatch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"widgetDispatch.d.ts","sourceRoot":"","sources":["../src/widgetDispatch.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;GAeG;AAEH;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAUrD,CAAC;AAEF,wEAAwE;AACxE,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CASjD,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAEhD,CAAC;AAEH,0DAA0D;AAC1D,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAA8B,CAAC;AAEhF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,MAAM,CAGtD,CAAC;AAEH,6DAA6D;AAC7D,MAAM,MAAM,oBAAoB;AAC9B,mEAAmE;AACjE,QAAQ;AACV,kCAAkC;GAChC,QAAQ;AACV,uBAAuB;GACrB,OAAO;AACT,6EAA6E;GAC3E,OAAO;AACT,iDAAiD;GAC/C,QAAQ;AACV,wDAAwD;GACtD,aAAa;AACf,sEAAsE;GACpE,aAAa,CAAC;AAElB,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,oBAAoB,CAAC;IAC7B,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,CAUjF"}
1
+ {"version":3,"file":"widgetDispatch.d.ts","sourceRoot":"","sources":["../src/widgetDispatch.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAoBH,OAAO,KAAK,EACV,UAAU,EACV,wBAAwB,EACxB,qBAAqB,EACrB,kCAAkC,EAClC,uBAAuB,EAExB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,wBAAwB,GAAG,wBAAwB,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AAenF,wBAAgB,qBAAqB,IAAI,uBAAuB,CAK/D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,wBAAwB,GAAG,wBAAwB,CAAC,MAAM,CAAC,CAGnG;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,wBAAwB,GAAG,qBAAqB,CAAC,WAAW,CAAC,CAElG;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,wBAAwB,GAAG,KAAK,IAAI,kCAAkC,CAEjH;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS;;;;;;EAQrE;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAUrD,CAAC;AAEF,wEAAwE;AACxE,QAAA,MAAM,qBAAqB,gIASjB,CAAC;AAEX;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvE,wEAAwE;AACxE,eAAO,MAAM,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAA0C,CAAC;AAO9F;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAEhD,CAAC;AAEH,0DAA0D;AAC1D,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAA8B,CAAC;AAEhF;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,WAAW,CAAC,MAAM,CAGtD,CAAC;AAEH,6DAA6D;AAC7D,MAAM,MAAM,oBAAoB;AAC9B,mEAAmE;AACjE,QAAQ;AACV,kCAAkC;GAChC,QAAQ;AACV,uBAAuB;GACrB,OAAO;AACT,6EAA6E;GAC3E,OAAO;AACT,iDAAiD;GAC/C,QAAQ;AACV,wDAAwD;GACtD,aAAa;AACf,sEAAsE;GACpE,aAAa,CAAC;AAElB,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,oBAAoB,CAAC;IAC7B,4DAA4D;IAC5D,SAAS,CAAC,EAAE,iBAAiB,CAAC;CAC/B;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,cAAc,CAUjF;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,eAAO,MAAM,oBAAoB;;;CAGvB,CAAC;AAKX;;;;;;;;;;;;;;;GAeG;AACH,MAAM,WAAW,yBAA0B,SAAQ,UAAU;IAC3D,IAAI,EAAE,OAAO,oBAAoB,CAAC,MAAM,CAAC;IACzC,KAAK,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAClC,KAAK,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAClC,WAAW,CAAC,EAAE,iBAAiB,CAAC,aAAa,CAAC,CAAC;IAC/C,KAAK,CAAC,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;IACnC,4EAA4E;IAC5E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAC;IACjD,MAAM,CAAC,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACrC,QAAQ,CAAC,EAAE,iBAAiB,CAAC,UAAU,CAAC,CAAC;IACzC,MAAM,CAAC,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACrC,MAAM,CAAC,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACrC,OAAO,CAAC,EAAE,iBAAiB,CAAC,SAAS,CAAC,CAAC;CACxC;AAED,OAAO,QAAQ,kBAAkB,CAAC;IAChC,UAAU,kBAAkB;QAC1B,yBAAyB,EAAE,yBAAyB,CAAC;KACtD;CACF;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,CAKjD"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * ObjectUI
3
+ * Copyright (c) 2024-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ /**
9
+ * The structural minimum this resolution reads. Deliberately not
10
+ * `DashboardWidgetSchema`: the two surfaces hold their widgets at two different
11
+ * static types (the grid holds the `DashboardWidgetSlotComponentSchema |
12
+ * DashboardWidgetSchema` union its `widgets` slot declares), and both satisfy
13
+ * this shape. `options` is `unknown` because that is what
14
+ * `DashboardWidgetSchema` declares it as.
15
+ */
16
+ export interface SubCaptionWidget {
17
+ id?: string;
18
+ options?: unknown;
19
+ }
20
+ /**
21
+ * Resolve a dataset/metric widget's sub-caption for the active UI language.
22
+ *
23
+ * `dashName` is the dashboard schema's `name` — the segment every convention
24
+ * key on this surface is built from. Without it (or without a widget `id`)
25
+ * there is no key to look up, so the authored limb answers alone; that is the
26
+ * same silent degradation `tWidgetTitle` / `tWidgetDescription` perform, not a
27
+ * new one.
28
+ *
29
+ * `localized` is the host's word that the document was served already
30
+ * translated (`DashboardRendererProps.localized`): the authored limb then
31
+ * answers alone, because the served value IS the translation.
32
+ *
33
+ * Provider-safe: `useObjectLabel` and `useObjectTranslation` both degrade to a
34
+ * no-instance stand-in when no `I18nProvider` is mounted (objectui#5564), which
35
+ * `DashboardGridLayout` depends on — it is a separately exported component a
36
+ * host mounts standalone (its `dashboard-grid` node key was retired by
37
+ * objectui#10859 batch 8).
38
+ */
39
+ export declare function useWidgetSubCaption(dashName: string | undefined, localized?: boolean): (widget: SubCaptionWidget) => string | undefined;
40
+ //# sourceMappingURL=widgetSubCaption.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"widgetSubCaption.d.ts","sourceRoot":"","sources":["../src/widgetSubCaption.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA4EH;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,SAAS,UAAQ,GAChB,CAAC,MAAM,EAAE,gBAAgB,KAAK,MAAM,GAAG,SAAS,CAalD"}