@object-ui/core 17.5.0 → 17.6.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 +794 -0
- package/README.md +36 -22
- package/dist/actions/ActionEngine.d.ts +1 -1
- package/dist/actions/ActionEngine.js +1 -2
- package/dist/actions/ActionRunner.d.ts +82 -10
- package/dist/actions/ActionRunner.js +128 -22
- package/dist/actions/actionKeys.d.ts +68 -8
- package/dist/actions/actionKeys.js +81 -9
- package/dist/actions/actionResponse.js +1 -1
- package/dist/actions/index.d.ts +1 -0
- package/dist/actions/index.js +1 -0
- package/dist/actions/recordIdParam.d.ts +77 -0
- package/dist/actions/recordIdParam.js +37 -0
- package/dist/actions/serverActionHandler.d.ts +1 -1
- package/dist/actions/serverActionHandler.js +1 -1
- package/dist/evaluator/ExpressionEvaluator.d.ts +42 -1
- package/dist/evaluator/ExpressionEvaluator.js +42 -1
- package/dist/evaluator/SafeExpressionParser.js +0 -4
- package/dist/evaluator/declaredPredicate.js +1 -1
- package/dist/evaluator/fieldRules.d.ts +19 -0
- package/dist/evaluator/fieldRules.js +30 -6
- package/dist/evaluator/index.d.ts +1 -0
- package/dist/evaluator/index.js +1 -0
- package/dist/evaluator/listConditional.d.ts +49 -2
- package/dist/evaluator/listConditional.js +70 -6
- package/dist/evaluator/optionRules.d.ts +55 -0
- package/dist/evaluator/optionRules.js +60 -0
- package/dist/evaluator/rowPredicateCanon.d.ts +67 -0
- package/dist/evaluator/rowPredicateCanon.js +208 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +17 -0
- package/dist/registry/Registry.d.ts +41 -19
- package/dist/theme/index.d.ts +1 -1
- package/dist/theme/index.js +1 -1
- package/dist/types/index.d.ts +92 -13
- package/dist/utils/chart-presentation.d.ts +205 -0
- package/dist/utils/chart-presentation.js +280 -0
- package/dist/utils/chart-series.d.ts +140 -26
- package/dist/utils/chart-series.js +380 -39
- package/dist/utils/column-identity.d.ts +43 -0
- package/dist/utils/column-identity.js +47 -1
- package/dist/utils/dataset-format.js +18 -6
- package/dist/utils/debug.js +7 -0
- package/dist/utils/expand-fields.d.ts +97 -7
- package/dist/utils/expand-fields.js +97 -7
- package/dist/utils/filter-tokens.js +0 -1
- package/dist/utils/freeze-schema.d.ts +38 -1
- package/dist/utils/freeze-schema.js +10 -0
- package/dist/utils/humanize-label.d.ts +60 -0
- package/dist/utils/humanize-label.js +62 -0
- package/dist/utils/managedBy.d.ts +27 -2
- package/dist/utils/normalize-list-view.d.ts +10 -0
- package/dist/utils/normalize-list-view.js +63 -1
- package/dist/utils/number-display.d.ts +7 -3
- package/dist/utils/predicate-fields.d.ts +29 -4
- package/dist/utils/predicate-fields.js +44 -4
- package/dist/utils/retired-field-types.d.ts +90 -0
- package/dist/utils/retired-field-types.js +124 -0
- package/dist/utils/sort-query.d.ts +12 -10
- package/dist/utils/unmaterialized-fields.d.ts +52 -0
- package/dist/utils/unmaterialized-fields.js +57 -0
- package/dist/validation/index.d.ts +1 -0
- package/dist/validation/index.js +1 -0
- package/dist/validation/schema-validator.js +105 -0
- package/dist/validation/server-owned-value.d.ts +62 -0
- package/dist/validation/server-owned-value.js +99 -0
- package/dist/validation/validators/object-validation-engine.js +0 -2
- package/package.json +4 -4
- package/dist/__benchmarks__/core.bench.d.ts +0 -8
- package/dist/__benchmarks__/core.bench.js +0 -53
|
@@ -5,22 +5,30 @@
|
|
|
5
5
|
* This source code is licensed under the MIT license found in the
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
|
-
import type {
|
|
8
|
+
import type { ComponentInput } from '@object-ui/types';
|
|
9
9
|
export type ComponentRenderer<T = any> = T;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
10
|
+
/**
|
|
11
|
+
* What a registration DECLARES about one authorable prop.
|
|
12
|
+
*
|
|
13
|
+
* This is the declaration the component registrations themselves import, so it
|
|
14
|
+
* is the one an author's manifest is ultimately built from — and it is now
|
|
15
|
+
* RE-EXPORTED from `@object-ui/types` rather than restated here
|
|
16
|
+
* (objectui#4972), the disposition objectui#4580 ruled for the identical
|
|
17
|
+
* shape: *a structural copy would reproduce the defect the moment either side
|
|
18
|
+
* moved.* This package already depends on `@object-ui/types`, so the edge
|
|
19
|
+
* exists and adds no cycle, and `src/types/index.ts` re-exports `SchemaNode`
|
|
20
|
+
* from there the same way.
|
|
21
|
+
*
|
|
22
|
+
* The copy this replaces had ALREADY moved, which is why the card is not
|
|
23
|
+
* hypothetical: it carried nine keys while `base.ts` carried thirteen, so
|
|
24
|
+
* `min` / `max` / `step` / `placeholder` were missing from *the copy every
|
|
25
|
+
* registration actually imports*. Those four keys were therefore unwritable at
|
|
26
|
+
* any real registration — a plain TS error — while `ComponentInputSchema` (the
|
|
27
|
+
* zod schema) and `ComponentMeta.inputs` both accepted them. The publication
|
|
28
|
+
* face advertised four keys the authoring face rejected; the divergence was
|
|
29
|
+
* dormant only because no registration had tried to write one yet.
|
|
30
|
+
*/
|
|
31
|
+
export type { ComponentInput } from '@object-ui/types';
|
|
24
32
|
export type ComponentMeta = {
|
|
25
33
|
label?: string;
|
|
26
34
|
icon?: string;
|
|
@@ -45,7 +53,11 @@ export type ComponentMeta = {
|
|
|
45
53
|
skipFallback?: boolean;
|
|
46
54
|
/**
|
|
47
55
|
* How a HOST must associate its own visible label with what this component
|
|
48
|
-
* renders (objectui#3961). Read by the form
|
|
56
|
+
* renders (objectui#3961, extended by objectui#4857). Read by the form
|
|
57
|
+
* renderer; absent ⇒ `'control'`. This closed three-value vocabulary is the
|
|
58
|
+
* single repo-wide answer to "how does a host learn what a widget will
|
|
59
|
+
* render" (maintainer ruling of 2026-08-17, joint with objectui#4871) — no
|
|
60
|
+
* host may keep a local variant of it.
|
|
49
61
|
*
|
|
50
62
|
* - `'control'` — the component's outermost rendered element is a LABELABLE
|
|
51
63
|
* HTML element (`input` / `textarea` / `select` / `button` / …), so the host
|
|
@@ -58,7 +70,18 @@ export type ComponentMeta = {
|
|
|
58
70
|
* nothing and contributes no accessible name (`HTMLLabelElement.control` is
|
|
59
71
|
* `null`) — so the host must instead give its label an `id` and hand the
|
|
60
72
|
* component `aria-labelledby`, which associates by IDREF and works on any
|
|
61
|
-
* element.
|
|
73
|
+
* element. The COMPONENT consumes those keys on its own surface.
|
|
74
|
+
* - `'display'` — the rendered surface is a pure display in EVERY state:
|
|
75
|
+
* there is no focusable control and the component itself spreads nothing
|
|
76
|
+
* (computed / system-generated values such as `formula` / `summary` /
|
|
77
|
+
* `auto_number` / `vector`). The host must not emit a `<label for>` at all
|
|
78
|
+
* — no labelable element will ever exist for it to reach, in the editable
|
|
79
|
+
* state as much as the readonly one — and instead wraps the component's
|
|
80
|
+
* output in the host's own container carrying the field id,
|
|
81
|
+
* `aria-labelledby`, `aria-describedby` and `role="group"` (the
|
|
82
|
+
* objectui#4788 channel, driven by this declaration rather than by
|
|
83
|
+
* `readonly` alone). Unlike `'group'`, the WIDGET is not expected to
|
|
84
|
+
* consume anything: the host's wrapper is the named surface.
|
|
62
85
|
*
|
|
63
86
|
* This is a DECLARATION, not a guess: the host cannot infer it from the DOM a
|
|
64
87
|
* widget happens to render, and a widget that fails to declare it falls back
|
|
@@ -66,10 +89,9 @@ export type ComponentMeta = {
|
|
|
66
89
|
* label-association tests (objectui#3952) instead of silently producing an
|
|
67
90
|
* unlabelled group.
|
|
68
91
|
*/
|
|
69
|
-
labelling?: 'control' | 'group';
|
|
92
|
+
labelling?: 'control' | 'group' | 'display';
|
|
70
93
|
inputs?: ComponentInput[];
|
|
71
94
|
defaultProps?: Record<string, any>;
|
|
72
|
-
defaultChildren?: SchemaNode[];
|
|
73
95
|
examples?: Record<string, any>;
|
|
74
96
|
isContainer?: boolean;
|
|
75
97
|
resizable?: boolean;
|
package/dist/theme/index.d.ts
CHANGED
|
@@ -5,4 +5,4 @@
|
|
|
5
5
|
* This source code is licensed under the MIT license found in the
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
|
-
export { hexToHSL, toCSSColor, generateColorVars, generateTypographyVars, generateBorderRadiusVars, generateShadowVars, generateThemeVars, mergeThemes, resolveThemeInheritance, resolveMode, contrastRatio, meetsContrastLevel, } from './ThemeEngine';
|
|
8
|
+
export { hexToHSL, toCSSColor, generateColorVars, generateTypographyVars, generateBorderRadiusVars, generateShadowVars, generateThemeVars, mergeThemes, resolveThemeInheritance, resolveMode, contrastRatio, meetsContrastLevel, } from './ThemeEngine.js';
|
package/dist/theme/index.js
CHANGED
|
@@ -11,4 +11,4 @@ export { hexToHSL, toCSSColor, generateColorVars, generateTypographyVars, genera
|
|
|
11
11
|
// 17.0.0-rc.3 (objectstack#5021) — see ThemeEngine's RETIRED THEME BLOCKS
|
|
12
12
|
// note. `theme.customVars` is the declared door for a `--duration-*` or
|
|
13
13
|
// `--z-*` now.
|
|
14
|
-
generateThemeVars, mergeThemes, resolveThemeInheritance, resolveMode, contrastRatio, meetsContrastLevel, } from './ThemeEngine';
|
|
14
|
+
generateThemeVars, mergeThemes, resolveThemeInheritance, resolveMode, contrastRatio, meetsContrastLevel, } from './ThemeEngine.js';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -30,24 +30,103 @@
|
|
|
30
30
|
* rather than restated, so there is exactly one declaration left to disagree
|
|
31
31
|
* with — a structural copy would reproduce the defect the moment either side
|
|
32
32
|
* moved. This package already depends on `@object-ui/types`, so the edge exists
|
|
33
|
-
* and adds no cycle
|
|
34
|
-
*
|
|
33
|
+
* and adds no cycle.
|
|
34
|
+
*
|
|
35
|
+
* ## The entry-surface sentence that used to close this block is WITHDRAWN
|
|
36
|
+
*
|
|
37
|
+
* It read: *core's own entry surface is unchanged (`dist/index.d.ts` is
|
|
38
|
+
* byte-identical across the change — measured, both rounds)*. The reading was
|
|
39
|
+
* real, and it certified nothing (objectui#5673).
|
|
40
|
+
*
|
|
41
|
+
* `core/dist/index.d.ts` is emitted from a barrel that only FORWARDS this
|
|
42
|
+
* symbol, and forwarding never restates a shape — not `export *`, and not the
|
|
43
|
+
* `export type { SchemaNode, … } from './types/index.js'` line that names it.
|
|
44
|
+
* Only the module that DECLARES the symbol can move. So that file is
|
|
45
|
+
* byte-identical under any change to a re-exported declaration's shape, naming
|
|
46
|
+
* the symbol or not, and a gauge that cannot fail for the change class it is
|
|
47
|
+
* quoted against has discharged nothing.
|
|
48
|
+
*
|
|
49
|
+
* ## The gauge that can fail — and how to prove it can, before believing it
|
|
50
|
+
*
|
|
51
|
+
* 1. Watch the emitted `.d.ts` of the module that DECLARES the symbol. For
|
|
52
|
+
* `SchemaNode` that is `@object-ui/types`' `dist/base.d.ts`, in another
|
|
53
|
+
* package — not core's entry, and not core's own `dist/types/index.d.ts`
|
|
54
|
+
* either, which forwards exactly as the entry does. For the shape claim
|
|
55
|
+
* itself, resolve the symbol through the TypeScript CHECKER from
|
|
56
|
+
* `core/dist/index.d.ts`.
|
|
57
|
+
* 2. Build both legs from a cleared `dist/` AND a cleared
|
|
58
|
+
* `tsconfig.tsbuildinfo` — the build info lives outside `dist/`, so
|
|
59
|
+
* composite `tsc` skips emit if it survives and two stale trees compare
|
|
60
|
+
* equal for free.
|
|
61
|
+
* 3. CALIBRATE: inject a probe key into the declaring module, rebuild, and
|
|
62
|
+
* require the hash you are watching to MOVE; drop the probe, rebuild, and
|
|
63
|
+
* require it to come back to its original value. A probe that leaves your
|
|
64
|
+
* hash unmoved means the gauge is not wired to this symbol — that is what
|
|
65
|
+
* failure looks like here, and no "byte-identical" sentence may be written
|
|
66
|
+
* from a gauge that just failed it.
|
|
67
|
+
*
|
|
68
|
+
* Run against this file's own claim — probe: one additive optional key on
|
|
69
|
+
* `BaseSchema`, the shape `SchemaNode` publishes — `@object-ui/types`'
|
|
70
|
+
* `dist/base.d.ts` moved and came back, while `core/dist/index.d.ts` and
|
|
71
|
+
* `core/dist/types/index.d.ts` held one hash across all three legs. The
|
|
72
|
+
* withdrawn sentence was watching the two files that cannot move.
|
|
35
73
|
*
|
|
36
74
|
* The collision is only observable from a package that resolves BOTH through
|
|
37
75
|
* `node_modules`; the pin therefore lives in `@object-ui/react`
|
|
38
76
|
* (`src/__tests__/SchemaNode.reconciliation.test.ts`), not here.
|
|
39
77
|
*/
|
|
40
78
|
export type { SchemaNode } from '@object-ui/types';
|
|
41
|
-
import type { SchemaNode } from '@object-ui/types';
|
|
42
79
|
/**
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
80
|
+
* One `ComponentRendererProps` (objectui#4594).
|
|
81
|
+
*
|
|
82
|
+
* This package used to hand-declare `interface ComponentRendererProps
|
|
83
|
+
* { schema: SchemaNode; [key: string]: any }` here — two lines below `SchemaNode`
|
|
84
|
+
* and against `@object-ui/types`' generic
|
|
85
|
+
* `ComponentRendererProps< TSchema extends BaseSchema = BaseSchema >`. Same name,
|
|
86
|
+
* two packages the same consumers import together: the second such pair in this
|
|
87
|
+
* one file, and the third across this fault line after `SchemaNode` (#4580) and
|
|
88
|
+
* `ComponentInput` (#4972).
|
|
89
|
+
*
|
|
90
|
+
* **`@object-ui/types`' generic declaration wins**, and is RE-EXPORTED rather
|
|
91
|
+
* than restated, so there is exactly one declaration left to disagree with — a
|
|
92
|
+
* structural copy would reproduce the defect the moment either side moved.
|
|
93
|
+
*
|
|
94
|
+
* Reconciled now, at **zero consumers** — re-verified on the merged ref rather
|
|
95
|
+
* than inherited from the card: repo-wide, `ComponentRendererProps` occurred only
|
|
96
|
+
* at the two declarations, each package's own entry re-export, and one line of
|
|
97
|
+
* `packages/components/CHANGELOG.md` recording that nothing used it. Zero
|
|
98
|
+
* consumers is why this is cheap today and would not stay cheap: the day someone
|
|
99
|
+
* imports it, which declaration they get decides whether a primitive node is
|
|
100
|
+
* admissible.
|
|
101
|
+
*
|
|
102
|
+
* ## What the re-export moves, and how that was measured
|
|
103
|
+
*
|
|
104
|
+
* It is NOT surface-neutral, and the gauge that would have said so is vacuous.
|
|
105
|
+
* `core/dist/index.d.ts` is emitted from a barrel that only FORWARDS this
|
|
106
|
+
* symbol — its `export type { … }` line names it, and naming is not restating
|
|
107
|
+
* — so that file is byte-identical under ANY change to a re-exported
|
|
108
|
+
* declaration's shape and cannot fail for this change class (objectui#5673,
|
|
109
|
+
* where the `SchemaNode` block above withdraws the same reading and carries the
|
|
110
|
+
* probe calibration that tells a live gauge from this one).
|
|
111
|
+
*
|
|
112
|
+
* Measured instead by resolving the symbol through the TypeScript CHECKER from
|
|
113
|
+
* `core/dist/index.d.ts`, over a `dist/` + `tsconfig.tsbuildinfo` clean rebuild
|
|
114
|
+
* on both legs (the build info lives outside `dist/`, so composite `tsc` skips
|
|
115
|
+
* emit if it survives and two stale trees compare equal for free):
|
|
116
|
+
*
|
|
117
|
+
* ```
|
|
118
|
+
* before ComponentRendererProps schema: BaseSchema | string | number | boolean | null | undefined
|
|
119
|
+
* after ComponentRendererProps<TSchema> schema: TSchema (TSchema extends BaseSchema = BaseSchema)
|
|
120
|
+
* ```
|
|
121
|
+
*
|
|
122
|
+
* So `schema` NARROWS back to the object form — core's copy had silently widened
|
|
123
|
+
* when #4608 made `SchemaNode` a re-export of types' union, which is the interim
|
|
124
|
+
* state this card closes — and the type gains a parameter. Nothing downstream
|
|
125
|
+
* can observe either move, because nothing imports it.
|
|
126
|
+
*
|
|
127
|
+
* The collision is only observable from a package that resolves BOTH through
|
|
128
|
+
* `node_modules`; the pin therefore lives in `@object-ui/react`
|
|
129
|
+
* (`src/__tests__/ComponentRendererProps.reconciliation.test.ts`), not here —
|
|
130
|
+
* same position, same reason, as `SchemaNode`'s pin above.
|
|
49
131
|
*/
|
|
50
|
-
export
|
|
51
|
-
schema: SchemaNode;
|
|
52
|
-
[key: string]: any;
|
|
53
|
-
}
|
|
132
|
+
export type { ComponentRendererProps } from '@object-ui/types';
|
|
@@ -0,0 +1,205 @@
|
|
|
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
|
+
* chart-presentation — the AUTHORED half of a dataset-bound chart, lowered onto
|
|
10
|
+
* the bindings {@link buildChartSeries} derived from the dataset selection.
|
|
11
|
+
*
|
|
12
|
+
* `chart-series.ts` beside this file owns the DATA half: which columns become
|
|
13
|
+
* series, which rows, which buckets. This file owns everything the author gets
|
|
14
|
+
* to say about how that data LOOKS — the ruled data/presentation split of
|
|
15
|
+
* objectui#4229, stated once:
|
|
16
|
+
*
|
|
17
|
+
* - **Data (derived, never forwarded)** — series MEMBERSHIP and the column each
|
|
18
|
+
* binding reads. Concretely `buildChartSeries`' `dataKey`s, `xAxisKey`, and
|
|
19
|
+
* the spec's two binding keys `ChartSeries.name` and `ChartAxis.field`.
|
|
20
|
+
* - **Presentation (authored, merged forward)** — everything else on those same
|
|
21
|
+
* objects: `series[].type` (the per-series mark), `series[].yAxis` (which
|
|
22
|
+
* axis it binds to), `label`/`color`/`stack`/`variant`/`dashArray`/`opacity`,
|
|
23
|
+
* the axis definitions' `title`/`format`/`min`/`max`/`stepSize`/
|
|
24
|
+
* `showGridLines`/`position`/`logarithmic`, and the chart chrome
|
|
25
|
+
* (`showLegend`, `showDataLabels`, `colors`, `annotations`, …).
|
|
26
|
+
*
|
|
27
|
+
* ## Why it lives in `@object-ui/core` rather than in one plugin
|
|
28
|
+
*
|
|
29
|
+
* It was written for `plugin-dashboard`'s `DatasetWidget` (#3135 → objectstack#7016
|
|
30
|
+
* → #4229) and lifted here by objectui#4877, when `plugin-report`'s embedded
|
|
31
|
+
* report chart turned out to need the SAME merge over the same spec shapes: the
|
|
32
|
+
* report was forwarding six keys and dropping every authored chrome key the
|
|
33
|
+
* schema declares, and re-deriving this beside the dashboard's copy is exactly
|
|
34
|
+
* the duplication objectui#4389 filed as a defect (two longhand copies of the
|
|
35
|
+
* analytics label net, one per plugin, drifting apart).
|
|
36
|
+
*
|
|
37
|
+
* Everything here is a pure data transform over plain records, so it sits below
|
|
38
|
+
* both plugins with no React and no i18n — the same layering `chart-series.ts`
|
|
39
|
+
* already has (see {@link OptionLabelTranslator} there for why an i18n-resolved
|
|
40
|
+
* string always arrives as an ARGUMENT rather than being read here).
|
|
41
|
+
*
|
|
42
|
+
* ## Two entry points, because the two surfaces declare axes differently
|
|
43
|
+
*
|
|
44
|
+
* A dashboard widget's `chartConfig` spells its axes as spec `ChartAxis`
|
|
45
|
+
* OBJECTS. A report's `chart.xAxis` / `chart.yAxis` are bare dimension/measure
|
|
46
|
+
* NAME strings — on that surface the axes are pure DATA (they ARE the selection)
|
|
47
|
+
* and carry no presentation at all. So:
|
|
48
|
+
*
|
|
49
|
+
* - {@link mergeAuthoredPresentation} is the object-axis entry point: series
|
|
50
|
+
* merge + axis presentation, for a caller whose axes are `ChartAxis` objects.
|
|
51
|
+
* - {@link mergeAuthoredSeries} is the series merge ALONE, for a caller whose
|
|
52
|
+
* axes are names. That split is structural, not a guard: handing a bare
|
|
53
|
+
* string to {@link mergeAuthoredPresentation} would run it through
|
|
54
|
+
* `axisPresentation`, which reads nothing off a string and would synthesise a
|
|
55
|
+
* `yAxis: [{}]` entry — a y-axis declaring nothing but its own existence,
|
|
56
|
+
* which is precisely how the COUNT of entries turns on a secondary axis. A
|
|
57
|
+
* surface that cannot author axis presentation should not be able to reach
|
|
58
|
+
* the code that reads it.
|
|
59
|
+
*/
|
|
60
|
+
import type { ChartSeriesBinding } from './chart-series.js';
|
|
61
|
+
/** Authored spec `ChartSeries` presentation, in the renderer's internal spelling. */
|
|
62
|
+
export interface AuthoredSeriesPresentation {
|
|
63
|
+
label?: string;
|
|
64
|
+
/** Spec `ChartSeries.type`, narrowed — see {@link seriesPresentation}. */
|
|
65
|
+
chartType?: 'bar' | 'line' | 'area';
|
|
66
|
+
yAxis?: 'left' | 'right';
|
|
67
|
+
color?: string;
|
|
68
|
+
stack?: string;
|
|
69
|
+
variant?: 'primary' | 'comparison';
|
|
70
|
+
dashArray?: string;
|
|
71
|
+
opacity?: number;
|
|
72
|
+
}
|
|
73
|
+
/** A derived series binding with the author's presentation merged onto it. */
|
|
74
|
+
export type MergedChartSeries = ChartSeriesBinding & AuthoredSeriesPresentation;
|
|
75
|
+
/**
|
|
76
|
+
* One authored `ChartSeries`, minus its `name` — i.e. everything about it that
|
|
77
|
+
* is presentation rather than membership.
|
|
78
|
+
*
|
|
79
|
+
* `type` is narrowed to the three families that COMPOSE on one cartesian plot,
|
|
80
|
+
* because this array reaches the renderer already speaking the internal shape
|
|
81
|
+
* (`ChartRenderer` forwards a `dataKey`-shaped array untouched, so
|
|
82
|
+
* `normalizeChartSchema`'s own identical narrowing never sees it). Without the
|
|
83
|
+
* narrowing a `type: 'pie'` would not merely be inert — it would count as a
|
|
84
|
+
* family disagreement in `effectiveChartFamily`, flip the whole chart into a
|
|
85
|
+
* combo, and then draw that series as a bar anyway.
|
|
86
|
+
*/
|
|
87
|
+
export declare function seriesPresentation(raw: Record<string, unknown>): AuthoredSeriesPresentation;
|
|
88
|
+
/**
|
|
89
|
+
* One authored `ChartAxis`, minus its `field` — the axis's presentation.
|
|
90
|
+
*
|
|
91
|
+
* `field` is the one DATA key on an axis (it names the plotted column), and
|
|
92
|
+
* dropping it here is what keeps membership with the dataset **structurally**
|
|
93
|
+
* rather than by a guard: `normalizeChartSchema` synthesises series out of
|
|
94
|
+
* `yAxis[].field` when a chart declares no series, so a forwarded `field`
|
|
95
|
+
* would be a live membership channel on an empty selection. With it gone the
|
|
96
|
+
* axis carries scale and chrome only, and the count of entries — which is what
|
|
97
|
+
* turns on the secondary axis (`yAxes.length > 1`) — survives, including for
|
|
98
|
+
* an entry that declares nothing but its own existence.
|
|
99
|
+
*
|
|
100
|
+
* Keys the renderer does not read on a given axis are dropped by
|
|
101
|
+
* `normalizeChartSchema`, the ONE normalization layer (#2880 S1): today it
|
|
102
|
+
* keeps `format`/`title`/`showGridLines` on the x-axis and the full set on the
|
|
103
|
+
* y-axes. That narrowing is deliberately NOT mirrored here — a second copy
|
|
104
|
+
* would drift from the renderer's real capability the moment it grew.
|
|
105
|
+
*/
|
|
106
|
+
export declare function axisPresentation(raw: unknown): Record<string, unknown>;
|
|
107
|
+
/**
|
|
108
|
+
* Merge an authored `series[]` array's PRESENTATION onto the bindings the
|
|
109
|
+
* dataset selection derived — the series half of #4229's split, and the whole
|
|
110
|
+
* of it for a surface whose axes are names rather than objects (see the file
|
|
111
|
+
* header).
|
|
112
|
+
*
|
|
113
|
+
* The match rule is **by name/key**: an authored `series[].name` is paired with
|
|
114
|
+
* the derived binding whose `dataKey` it equals, and the pairing decides
|
|
115
|
+
* nothing but presentation:
|
|
116
|
+
*
|
|
117
|
+
* - an authored entry naming a measure that is NOT in the dataset selection is
|
|
118
|
+
* **ignored** — membership belongs to the dataset, so an author cannot add,
|
|
119
|
+
* remove or re-point a series from the chart config;
|
|
120
|
+
* - a derived series with no authored entry keeps the family default, so every
|
|
121
|
+
* surface that never wrote `series` renders byte-for-byte as before;
|
|
122
|
+
* - where both exist the **explicit binding wins** (#2880 S2), which is the
|
|
123
|
+
* whole point: `type: 'line'` + `yAxis: 'right'` is how the spec says "this
|
|
124
|
+
* measure is a line on the secondary axis".
|
|
125
|
+
*
|
|
126
|
+
* Matching on `name` only is deliberate: `name` is the spec's authorable key
|
|
127
|
+
* for a series (`dataKey` is a declared ALIAS of it, resolved where the
|
|
128
|
+
* metadata is parsed), so reading a second spelling here would fossilize a
|
|
129
|
+
* dialect this renderer has no business accepting (AGENTS.md #0.1).
|
|
130
|
+
*
|
|
131
|
+
* The FIRST entry naming a measure wins; a later duplicate cannot silently
|
|
132
|
+
* reconfigure a series the author already described.
|
|
133
|
+
*
|
|
134
|
+
* @param derived the bindings {@link buildChartSeries} produced from the selection
|
|
135
|
+
* @param authoredSeries the authored `series` array (anything, incl. absent)
|
|
136
|
+
*/
|
|
137
|
+
export declare function mergeAuthoredSeries(derived: ChartSeriesBinding[], authoredSeries: unknown): MergedChartSeries[];
|
|
138
|
+
/**
|
|
139
|
+
* Merge an authored chart config's PRESENTATION onto the series and axes the
|
|
140
|
+
* dataset selection derived — the one place that happens for a surface whose
|
|
141
|
+
* axes are spec `ChartAxis` OBJECTS (#4229).
|
|
142
|
+
*
|
|
143
|
+
* The series half is {@link mergeAuthoredSeries}; see it for the match rule and
|
|
144
|
+
* for why membership is safe. The axes half reads `xAxis` / `yAxis` through
|
|
145
|
+
* {@link axisPresentation}, which is why a surface spelling those as bare NAME
|
|
146
|
+
* strings must call `mergeAuthoredSeries` directly instead (file header).
|
|
147
|
+
*
|
|
148
|
+
* @param derived the bindings {@link buildChartSeries} produced from the selection
|
|
149
|
+
* @param raw the authored chart config (anything, incl. absent)
|
|
150
|
+
* @returns the merged series, plus the presentation-only axes to spread onto
|
|
151
|
+
* the chart schema (absent when the author declared none)
|
|
152
|
+
*/
|
|
153
|
+
export declare function mergeAuthoredPresentation(derived: ChartSeriesBinding[], raw: unknown): {
|
|
154
|
+
series: MergedChartSeries[];
|
|
155
|
+
axes: Record<string, unknown>;
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* Lower an authored chart config's CHROME (spec `ChartConfigSchema` /
|
|
159
|
+
* `ReportChartSchema` — the same keys on both) onto the chart schema a
|
|
160
|
+
* dataset-bound surface hands the renderer.
|
|
161
|
+
*
|
|
162
|
+
* ## Why this is a whitelist and not a spread
|
|
163
|
+
*
|
|
164
|
+
* Until #3135 NONE of a dashboard widget's `chartConfig` reached the renderer:
|
|
165
|
+
* the widget read `options` and nothing else, so an author who wrote
|
|
166
|
+
* `showLegend: false` still got a legend and one who wrote `true` only got one
|
|
167
|
+
* because "on" is the renderer's default. #3135 lowered that single flag and
|
|
168
|
+
* left the rest declared and inert. objectstack#7016 lowered the rest of the
|
|
169
|
+
* keys that are actually DELIVERED, admitting a key only when both of these
|
|
170
|
+
* hold:
|
|
171
|
+
*
|
|
172
|
+
* 1. **The chart block draws it end to end.** `{ type: 'chart' }` resolves to
|
|
173
|
+
* `ChartRenderer` → `AdvancedChartImpl`, which draws `title`/`subtitle` in
|
|
174
|
+
* its ChartFrame, turns `description` into the chart container's
|
|
175
|
+
* `role="img"` + `aria-label`, applies `height` as that container's inline
|
|
176
|
+
* height, reads `colors` as the positional palette, prints
|
|
177
|
+
* `showDataLabels` as a Recharts `LabelList`, draws `annotations` as
|
|
178
|
+
* ReferenceLine/ReferenceArea and honours `interaction` as the tooltip
|
|
179
|
+
* toggle plus `Brush`. Forwarding a key the renderer ignores would only
|
|
180
|
+
* move declared-but-not-delivered one layer down, which is the failure this
|
|
181
|
+
* exists to remove.
|
|
182
|
+
* 2. **It does not fight the dataset derivation.** `type` stays out: the
|
|
183
|
+
* calling surface's own type already picks the chart family, which is the
|
|
184
|
+
* dataset path's chart-family channel.
|
|
185
|
+
*
|
|
186
|
+
* `aria` is the one declared key with **no reader at all**: `AdvancedChartImpl`
|
|
187
|
+
* has no `aria` prop, and `SchemaRenderer`'s ARIA injection reads the FLAT
|
|
188
|
+
* `ariaLabel`/`ariaDescribedBy`/`role`, never a nested `aria` object. It is
|
|
189
|
+
* therefore left unforwarded on purpose (criterion 1) rather than papered over
|
|
190
|
+
* with a caller-side flattening that would also collide with the accessible
|
|
191
|
+
* name `description` already sets — reported back to objectstack#5175's
|
|
192
|
+
* narrowing half instead.
|
|
193
|
+
*
|
|
194
|
+
* `title` IS emitted here. A caller that paints the title itself (the report
|
|
195
|
+
* renderer's own `h3` above the chart) must drop it from the result, or the
|
|
196
|
+
* chart draws a second one.
|
|
197
|
+
*
|
|
198
|
+
* @param raw the authored chart config (anything, incl. absent)
|
|
199
|
+
* @param fieldCategoryColors per-category colours resolved from the category
|
|
200
|
+
* dimension's own select/lookup option colours, merged UNDER an explicit
|
|
201
|
+
* author map (see the `colors` note below)
|
|
202
|
+
* @returns only the keys that resolved, so the caller can spread it over the
|
|
203
|
+
* derived chart schema and every undeclared key keeps the renderer's default
|
|
204
|
+
*/
|
|
205
|
+
export declare function chartConfigPresentation(raw: unknown, fieldCategoryColors?: Record<string, string> | null): Record<string, unknown>;
|