@object-ui/core 17.3.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 +2018 -0
- package/README.md +38 -34
- package/dist/actions/ActionEngine.d.ts +43 -26
- package/dist/actions/ActionEngine.js +67 -54
- package/dist/actions/ActionRunner.d.ts +281 -31
- package/dist/actions/ActionRunner.js +458 -36
- package/dist/actions/actionKeys.d.ts +163 -27
- package/dist/actions/actionKeys.js +238 -27
- 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/data-scope/ViewDataProvider.d.ts +37 -12
- package/dist/data-scope/ViewDataProvider.js +83 -5
- package/dist/data-scope/element-data-source.d.ts +113 -0
- package/dist/data-scope/element-data-source.js +216 -0
- package/dist/data-scope/index.d.ts +2 -1
- package/dist/data-scope/index.js +1 -0
- 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.d.ts +119 -0
- package/dist/evaluator/declaredPredicate.js +152 -0
- package/dist/evaluator/fieldRules.d.ts +35 -0
- package/dist/evaluator/fieldRules.js +79 -20
- package/dist/evaluator/index.d.ts +2 -0
- package/dist/evaluator/index.js +2 -0
- package/dist/evaluator/listConditional.d.ts +54 -4
- package/dist/evaluator/listConditional.js +125 -19
- package/dist/evaluator/optionRules.d.ts +55 -0
- package/dist/evaluator/optionRules.js +60 -0
- package/dist/evaluator/predicateInput.d.ts +51 -3
- package/dist/evaluator/predicateInput.js +62 -5
- package/dist/evaluator/rowPredicateCanon.d.ts +67 -0
- package/dist/evaluator/rowPredicateCanon.js +208 -0
- package/dist/index.d.ts +8 -1
- package/dist/index.js +31 -1
- package/dist/protocols/DndProtocol.d.ts +42 -1
- package/dist/protocols/KeyboardProtocol.d.ts +31 -1
- package/dist/protocols/SharingProtocol.d.ts +11 -1
- package/dist/registry/Registry.d.ts +62 -16
- package/dist/theme/ThemeEngine.d.ts +0 -8
- package/dist/theme/ThemeEngine.js +22 -103
- package/dist/theme/index.d.ts +1 -1
- package/dist/theme/index.js +7 -1
- package/dist/types/index.d.ts +125 -12
- package/dist/utils/chart-presentation.d.ts +205 -0
- package/dist/utils/chart-presentation.js +280 -0
- package/dist/utils/chart-series.d.ts +390 -23
- package/dist/utils/chart-series.js +776 -32
- package/dist/utils/column-identity.d.ts +43 -0
- package/dist/utils/column-identity.js +47 -1
- package/dist/utils/compare-to.d.ts +40 -13
- package/dist/utils/compare-to.js +4 -32
- package/dist/utils/dashboard-filters.d.ts +54 -8
- package/dist/utils/dashboard-filters.js +261 -12
- package/dist/utils/dataset-format.d.ts +73 -14
- package/dist/utils/dataset-format.js +142 -9
- package/dist/utils/dataset-pivot.d.ts +28 -7
- package/dist/utils/dataset-pivot.js +27 -6
- package/dist/utils/debug.js +7 -0
- package/dist/utils/dom-props.d.ts +137 -0
- package/dist/utils/dom-props.js +153 -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 +36 -6
- package/dist/utils/normalize-list-view.js +93 -9
- package/dist/utils/number-display.d.ts +155 -0
- package/dist/utils/number-display.js +71 -0
- package/dist/utils/predicate-fields.d.ts +29 -4
- package/dist/utils/predicate-fields.js +44 -4
- package/dist/utils/resolve-view-id.d.ts +31 -0
- package/dist/utils/resolve-view-id.js +45 -0
- 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 +57 -0
- package/dist/utils/sort-query.js +35 -0
- 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 +5 -5
- package/dist/__benchmarks__/core.bench.d.ts +0 -8
- package/dist/__benchmarks__/core.bench.js +0 -53
- package/dist/utils/merge-views-into-objects.d.ts +0 -19
- package/dist/utils/merge-views-into-objects.js +0 -39
|
@@ -0,0 +1,208 @@
|
|
|
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 row-predicate spelling CANON, and the Phase-1 deprecation warning for the
|
|
10
|
+
* two spellings that are not it (objectui#5330).
|
|
11
|
+
*
|
|
12
|
+
* ## The canon (maintainer ruling, 2026-08-20 — option B)
|
|
13
|
+
*
|
|
14
|
+
* A row predicate — `visible` / `disabled` / `enabled` on an action renderer, a
|
|
15
|
+
* row scope, a `record:alert` — binds the row THREE ways today: canonical
|
|
16
|
+
* `record.status`, bare shorthand `status`, and legacy `data.status`
|
|
17
|
+
* (objectui#4075 / PR #4079 bound all four action renderers all three ways to
|
|
18
|
+
* restore consistency, deliberately without deciding which of them is
|
|
19
|
+
* CONTRACT). This module is where that decision now lives:
|
|
20
|
+
*
|
|
21
|
+
* > **The canon is `record.*`.** The bare shorthand and `data.*` are
|
|
22
|
+
* > client-side tolerances in a deprecation window, kept because stored
|
|
23
|
+
* > metadata carries them, warned about here, and removable only after a
|
|
24
|
+
* > stored-metadata survey sizes the window (⛔ no removal before the survey).
|
|
25
|
+
*
|
|
26
|
+
* It mirrors the objectstack#7917 option-② precedent for the identical shape (a
|
|
27
|
+
* renderer tolerance quietly becoming a second de-facto contract — AGENTS.md
|
|
28
|
+
* #0.1), whose objectui half is `utils/dashboard-filters.ts`' bare-string
|
|
29
|
+
* `options` shorthand: same three phases, same reason the warning is not
|
|
30
|
+
* decoration (ADR-0078 — nothing silently inert; a tolerance nothing ever
|
|
31
|
+
* reports can never be retired, because nothing would ever show that the last
|
|
32
|
+
* document carrying it is gone).
|
|
33
|
+
*
|
|
34
|
+
* ## The canon states the SERVER's accept set, not this client's
|
|
35
|
+
*
|
|
36
|
+
* The ruling made that the dev's first measurement, because a canon that only
|
|
37
|
+
* describes the renderer would be the very thing it exists to end. Measured
|
|
38
|
+
* against `@objectstack/formula@17.1.0` — the engine the server evaluates with,
|
|
39
|
+
* and the one `fieldRules.ts` already delegates to:
|
|
40
|
+
*
|
|
41
|
+
* | spelling | server runtime (`buildScope` + `celEngine`) | server authoring oracle |
|
|
42
|
+
* |---|---|---|
|
|
43
|
+
* | `record.status` | ✅ `{ ok: true, value: true }` | ✅ accepted |
|
|
44
|
+
* | bare `status` | ❌ `Unknown variable: status` | ❌ refused (`'status'`) |
|
|
45
|
+
* | `data.status` | ❌ `Unknown variable: data` | ⚠️ **silently accepted** |
|
|
46
|
+
*
|
|
47
|
+
* `buildScope({ record })` mounts exactly `['record']` — `data` is never bound
|
|
48
|
+
* and the row's fields are never flattened to top level. So **the server
|
|
49
|
+
* accepts `record.*` and nothing else**; both other spellings fault there. The
|
|
50
|
+
* three-way binding is a client tolerance with no server counterpart, which is
|
|
51
|
+
* precisely why it is the client's job to warn.
|
|
52
|
+
*
|
|
53
|
+
* ⚠️ The `data.*` row is the dangerous one and the reason this warning exists
|
|
54
|
+
* at all. `data` IS in `@objectstack/formula`'s `SCOPE_ROOTS`, so the server's
|
|
55
|
+
* bare-identifier oracle waves `data.status` through — that list is a
|
|
56
|
+
* deliberately generous "never faults" LINT BASELINE, not the runtime accept
|
|
57
|
+
* set. A `data.*` row predicate therefore passes every authoring gate the
|
|
58
|
+
* platform has and then binds nothing at runtime: it is not an error, it is a
|
|
59
|
+
* constant `false`, and a `visible` that is constantly false is a button that
|
|
60
|
+
* silently never appears. That is the #4075 fail-closed family's exact
|
|
61
|
+
* signature, and this client is the only layer positioned to catch it.
|
|
62
|
+
*
|
|
63
|
+
* ## `data.*` is DEPRECATED HERE, not everywhere — the canon is layer-scoped
|
|
64
|
+
*
|
|
65
|
+
* `data` is the CANONICAL root one layer over, in a metadata-editing form (the
|
|
66
|
+
* row under edit): objectstack's `CANONICAL_ROOT_BY_LAYER` reads
|
|
67
|
+
* `{ runtime: 'record', metadata: 'data' }` (ADR-0089 D3), and objectui's own
|
|
68
|
+
* `app-shell` metadata-admin `SchemaForm` binds `{ data: row }` on purpose. So
|
|
69
|
+
* `data.*` is not a legacy alias to be deprecated platform-wide — it is a
|
|
70
|
+
* WRONG-LAYER paste on a runtime record surface, and only that is what this
|
|
71
|
+
* module reports. Stating the deprecation unqualified would contradict
|
|
72
|
+
* ADR-0089 D3 and break the metadata-editing layer's own contract.
|
|
73
|
+
*
|
|
74
|
+
* ## Why the detection reuses the server's oracle instead of a regex
|
|
75
|
+
*
|
|
76
|
+
* `collectCelRootIdentifiers` and `firstUndeclaredReference` are
|
|
77
|
+
* `@objectstack/formula` exports — the same two oracles objectstack's
|
|
78
|
+
* `visibility-bare-identifier` gate uses. Reading roots off the canonical AST
|
|
79
|
+
* rather than pattern-matching the source is what keeps this from inventing a
|
|
80
|
+
* second dialect judgement client-side: a string this module cannot parse is
|
|
81
|
+
* NOT this module's verdict to give (syntax belongs to the gates that own it),
|
|
82
|
+
* and it stands down rather than guessing.
|
|
83
|
+
*/
|
|
84
|
+
import { collectCelRootIdentifiers, firstUndeclaredReference } from '@objectstack/formula';
|
|
85
|
+
/** The one canonical row-predicate root. */
|
|
86
|
+
export const ROW_PREDICATE_CANONICAL_ROOT = 'record';
|
|
87
|
+
/**
|
|
88
|
+
* The metadata-editing-form root (ADR-0089 D3). Canonical on THAT layer, and a
|
|
89
|
+
* wrong-layer paste on a runtime record surface — see the module note.
|
|
90
|
+
*/
|
|
91
|
+
const METADATA_LAYER_ROOT = 'data';
|
|
92
|
+
/**
|
|
93
|
+
* Detect a non-canonical spelling in ONE row predicate, or `null` when the
|
|
94
|
+
* predicate is already canonical (or is not this module's verdict to give).
|
|
95
|
+
*
|
|
96
|
+
* Deliberately conservative in both arms — every condition below can only
|
|
97
|
+
* REMOVE a finding, never invent one, because a false deprecation warning sends
|
|
98
|
+
* an author to rewrite a predicate that was correct:
|
|
99
|
+
*
|
|
100
|
+
* - **Unparseable source** → `null`. Syntax is another gate's verdict.
|
|
101
|
+
* - **Bare shorthand** is reported only when the undeclared identifier is an own
|
|
102
|
+
* key of THIS row. That is what makes it unambiguously the #4075 shorthand
|
|
103
|
+
* rather than a host-scope global this module cannot see (a deployment key
|
|
104
|
+
* that is simply not in `SCOPE_ROOTS` would otherwise read as a bare field).
|
|
105
|
+
* - **`data.*`** is reported only when the caller confirms `data` names the row
|
|
106
|
+
* (`dataNamesRow`). A surface whose `data` is the host scope's own — a
|
|
107
|
+
* `rowless` dialog, a metadata-editing form — is a legitimate `data.*` site
|
|
108
|
+
* and is left alone.
|
|
109
|
+
*
|
|
110
|
+
* Only the FIRST finding is returned, and the bare-shorthand arm is checked
|
|
111
|
+
* first: it is the arm the server refuses outright (`visibility-bare-identifier`
|
|
112
|
+
* is an `error` there, while a mis-layered root is a `warning`), so when a
|
|
113
|
+
* predicate manages both it is the one the author must fix to have anything
|
|
114
|
+
* evaluate at all.
|
|
115
|
+
*
|
|
116
|
+
* @param source The predicate's CEL text. Callers must have already
|
|
117
|
+
* routed legacy `${…}`-dialect strings elsewhere — in that
|
|
118
|
+
* dialect `data.*` is the NORMAL spelling, and reporting it
|
|
119
|
+
* here would be a false positive on every legacy predicate.
|
|
120
|
+
* @param row The row the predicate is bound against.
|
|
121
|
+
* @param dataNamesRow Whether `data` is bound to that same row on this surface.
|
|
122
|
+
*/
|
|
123
|
+
export function detectNonCanonicalRowSpelling(source, row, dataNamesRow) {
|
|
124
|
+
if (typeof source !== 'string' || !source.trim())
|
|
125
|
+
return null;
|
|
126
|
+
const roots = collectCelRootIdentifiers(source);
|
|
127
|
+
// Not parseable through the canonical front end — not our verdict.
|
|
128
|
+
if (!roots || roots.ok !== true)
|
|
129
|
+
return null;
|
|
130
|
+
// (1) Bare shorthand — the arm the server refuses outright.
|
|
131
|
+
const bare = firstUndeclaredReference(source);
|
|
132
|
+
if (typeof bare === 'string' &&
|
|
133
|
+
row != null &&
|
|
134
|
+
typeof row === 'object' &&
|
|
135
|
+
Object.prototype.hasOwnProperty.call(row, bare)) {
|
|
136
|
+
return {
|
|
137
|
+
kind: 'bare-shorthand',
|
|
138
|
+
identifier: bare,
|
|
139
|
+
canonical: `${ROW_PREDICATE_CANONICAL_ROOT}.${bare}`,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
// (2) Wrong-layer `data.*` root — silent at runtime on the server.
|
|
143
|
+
if (dataNamesRow && Array.isArray(roots.roots) && roots.roots.includes(METADATA_LAYER_ROOT)) {
|
|
144
|
+
return {
|
|
145
|
+
kind: 'metadata-layer-root',
|
|
146
|
+
identifier: METADATA_LAYER_ROOT,
|
|
147
|
+
canonical: ROW_PREDICATE_CANONICAL_ROOT,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Dev-mode gate, matching `utils/dashboard-filters.ts` and `actions/actionKeys.ts`
|
|
154
|
+
* — a deprecation warning that floods a production console is a warning that
|
|
155
|
+
* gets muted.
|
|
156
|
+
*/
|
|
157
|
+
const isDev = () => globalThis.process?.env
|
|
158
|
+
?.NODE_ENV !== 'production';
|
|
159
|
+
/**
|
|
160
|
+
* Warn-once memo, keyed by the `(label, predicate source)` pair — the same
|
|
161
|
+
* identity `warnEvalError` uses, and JSON-encoded for the same reason: the
|
|
162
|
+
* separator that boundary once used was a raw U+0000, which made the file
|
|
163
|
+
* carrying it binary to grep (objectstack#5450). Keying on the source alone
|
|
164
|
+
* would report the first surface carrying a shorthand `status` predicate and
|
|
165
|
+
* stay silent about every other one; the label is what sends the author to the
|
|
166
|
+
* right screen.
|
|
167
|
+
*
|
|
168
|
+
* Module scope, not per-call: these predicates are re-evaluated on every row of
|
|
169
|
+
* every render, so per-call state would warn once per frame — the flood the
|
|
170
|
+
* dedupe exists to prevent.
|
|
171
|
+
*/
|
|
172
|
+
const warnedSpellings = new Set();
|
|
173
|
+
/** Reset the row-predicate spelling warn-once memo. Exported for tests. */
|
|
174
|
+
export function resetRowPredicateCanonWarnings() {
|
|
175
|
+
warnedSpellings.clear();
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Report a non-canonical row-predicate spelling once, in dev.
|
|
179
|
+
*
|
|
180
|
+
* Phase 1 of the objectui#5330 window: the binding is UNCHANGED and every
|
|
181
|
+
* spelling still resolves — this only says so out loud, so the stored
|
|
182
|
+
* population stops growing and a later survey has something to count. It is a
|
|
183
|
+
* warning and deliberately not a refusal: turning it into one would move the
|
|
184
|
+
* accept/reject set, which this card is explicitly not entitled to do.
|
|
185
|
+
*/
|
|
186
|
+
export function warnNonCanonicalRowSpelling(source, row, dataNamesRow, label) {
|
|
187
|
+
if (!isDev())
|
|
188
|
+
return;
|
|
189
|
+
const finding = detectNonCanonicalRowSpelling(source, row, dataNamesRow);
|
|
190
|
+
if (!finding)
|
|
191
|
+
return;
|
|
192
|
+
const key = JSON.stringify([label ?? '', source, finding.kind]);
|
|
193
|
+
if (warnedSpellings.has(key))
|
|
194
|
+
return;
|
|
195
|
+
warnedSpellings.add(key);
|
|
196
|
+
const where = label ? ` (${label})` : '';
|
|
197
|
+
const detail = finding.kind === 'bare-shorthand'
|
|
198
|
+
? `it references the bare field ${JSON.stringify(finding.identifier)}; ` +
|
|
199
|
+
`the server refuses that spelling outright ("Unknown variable: ${finding.identifier}")`
|
|
200
|
+
: 'it is rooted at `data.`, which is the metadata-editing-form root — on a ' +
|
|
201
|
+
'record surface the server binds no `data` at all, so the predicate is a ' +
|
|
202
|
+
'constant false there rather than an error';
|
|
203
|
+
console.warn(`[object-ui] A row predicate${where} uses a DEPRECATED spelling: ` +
|
|
204
|
+
`${JSON.stringify(source)} — ${detail}. The canon is \`record.*\` ` +
|
|
205
|
+
`(objectui#5330, ruled 2026-08-20): write \`${finding.canonical}\`. ` +
|
|
206
|
+
'This still evaluates here for now; the tolerance retires after a ' +
|
|
207
|
+
'stored-metadata survey.');
|
|
208
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -13,12 +13,17 @@ export * from './registry/PluginScopeImpl.js';
|
|
|
13
13
|
export * from './registry/WidgetRegistry.js';
|
|
14
14
|
export * from './validation/index.js';
|
|
15
15
|
export * from './builder/schema-builder.js';
|
|
16
|
+
export * from './utils/dom-props.js';
|
|
16
17
|
export * from './utils/filter-converter.js';
|
|
17
18
|
export * from './utils/managedBy.js';
|
|
18
19
|
export * from './utils/extract-records.js';
|
|
19
20
|
export * from './utils/expand-fields.js';
|
|
21
|
+
export * from './utils/retired-field-types.js';
|
|
22
|
+
export * from './utils/unmaterialized-fields.js';
|
|
20
23
|
export * from './utils/column-identity.js';
|
|
21
24
|
export * from './utils/sort-values.js';
|
|
25
|
+
export * from './utils/sort-query.js';
|
|
26
|
+
export * from './utils/resolve-view-id.js';
|
|
22
27
|
export * from './evaluator/index.js';
|
|
23
28
|
export * from './actions/index.js';
|
|
24
29
|
export * from './query/index.js';
|
|
@@ -28,7 +33,6 @@ export * from './data-scope/index.js';
|
|
|
28
33
|
export * from './errors/index.js';
|
|
29
34
|
export * from './utils/debug.js';
|
|
30
35
|
export * from './utils/debug-collector.js';
|
|
31
|
-
export * from './utils/merge-views-into-objects.js';
|
|
32
36
|
export * from './utils/freeze-schema.js';
|
|
33
37
|
export * from './protocols/index.js';
|
|
34
38
|
export * from './styling/scoped-styles.js';
|
|
@@ -47,6 +51,8 @@ export * from './utils/dashboard-filters.js';
|
|
|
47
51
|
export * from './utils/merge-filters.js';
|
|
48
52
|
export * from './utils/compare-to.js';
|
|
49
53
|
export * from './utils/chart-series.js';
|
|
54
|
+
export * from './utils/chart-presentation.js';
|
|
55
|
+
export * from './utils/number-display.js';
|
|
50
56
|
export * from './utils/dataset-format.js';
|
|
51
57
|
export * from './utils/dataset-pivot.js';
|
|
52
58
|
export * from './utils/record-title.js';
|
|
@@ -55,3 +61,4 @@ export * from './utils/reference-keys.js';
|
|
|
55
61
|
export * from './utils/predicate-record.js';
|
|
56
62
|
export * from './utils/predicate-fields.js';
|
|
57
63
|
export * from './utils/normalize-list-view.js';
|
|
64
|
+
export * from './utils/humanize-label.js';
|
package/dist/index.js
CHANGED
|
@@ -12,12 +12,27 @@ export * from './registry/PluginScopeImpl.js';
|
|
|
12
12
|
export * from './registry/WidgetRegistry.js';
|
|
13
13
|
export * from './validation/index.js';
|
|
14
14
|
export * from './builder/schema-builder.js';
|
|
15
|
+
// The DOM pass-through whitelist of the SDUI widget prop contract
|
|
16
|
+
// (objectui#4425 phase 2): a registered widget's host element receives only
|
|
17
|
+
// what `toDomProps` passes — everything else is consumed or dropped.
|
|
18
|
+
// `@object-ui/fields` executes the SAME mechanism against its own declared key
|
|
19
|
+
// list (`pickDomProps`), so there is one judge, not two.
|
|
20
|
+
export * from './utils/dom-props.js';
|
|
15
21
|
export * from './utils/filter-converter.js';
|
|
16
22
|
export * from './utils/managedBy.js';
|
|
17
23
|
export * from './utils/extract-records.js';
|
|
18
24
|
export * from './utils/expand-fields.js';
|
|
25
|
+
// The RETIREMENT gate (objectui#4914, maintainer ruling B). Homed here rather
|
|
26
|
+
// than in `@object-ui/fields` because `@object-ui/components` is one of its six
|
|
27
|
+
// consumers and `fields` depends on `components` — see the module's docblock
|
|
28
|
+
// for why a second copy was not an option. `@object-ui/fields` re-exports every
|
|
29
|
+
// name, so its published surface is unchanged.
|
|
30
|
+
export * from './utils/retired-field-types.js';
|
|
31
|
+
export * from './utils/unmaterialized-fields.js';
|
|
19
32
|
export * from './utils/column-identity.js';
|
|
20
33
|
export * from './utils/sort-values.js';
|
|
34
|
+
export * from './utils/sort-query.js';
|
|
35
|
+
export * from './utils/resolve-view-id.js';
|
|
21
36
|
export * from './evaluator/index.js';
|
|
22
37
|
export * from './actions/index.js';
|
|
23
38
|
export * from './query/index.js';
|
|
@@ -27,7 +42,6 @@ export * from './data-scope/index.js';
|
|
|
27
42
|
export * from './errors/index.js';
|
|
28
43
|
export * from './utils/debug.js';
|
|
29
44
|
export * from './utils/debug-collector.js';
|
|
30
|
-
export * from './utils/merge-views-into-objects.js';
|
|
31
45
|
export * from './utils/freeze-schema.js';
|
|
32
46
|
export * from './protocols/index.js';
|
|
33
47
|
export * from './styling/scoped-styles.js';
|
|
@@ -49,6 +63,16 @@ export * from './utils/dashboard-filters.js';
|
|
|
49
63
|
export * from './utils/merge-filters.js';
|
|
50
64
|
export * from './utils/compare-to.js';
|
|
51
65
|
export * from './utils/chart-series.js';
|
|
66
|
+
// The AUTHORED half of a dataset-bound chart (objectui#4229's data/presentation
|
|
67
|
+
// split), shared by the dashboard widget and the report's embedded chart so the
|
|
68
|
+
// same spec keys are lowered identically on both (objectui#4877).
|
|
69
|
+
export * from './utils/chart-presentation.js';
|
|
70
|
+
// The ONE number-display formatter (objectui#4033) — grouping policy, display
|
|
71
|
+
// locale and the percent convention. It lived in `@object-ui/i18n` until
|
|
72
|
+
// objectui#4576; it is pure, and living above `core` was what kept
|
|
73
|
+
// `dataset-format` below from reaching it (so the two drifted). `@object-ui/i18n`
|
|
74
|
+
// re-exports these names unchanged, so both import paths name the same symbol.
|
|
75
|
+
export * from './utils/number-display.js';
|
|
52
76
|
export * from './utils/dataset-format.js';
|
|
53
77
|
// Pivot lookup-key encoders, shared by every cross-tab renderer so the
|
|
54
78
|
// dashboard widget and the report renderer key their buckets identically
|
|
@@ -66,3 +90,9 @@ export * from './utils/predicate-record.js';
|
|
|
66
90
|
// which the column-derived `$select` never asked the server for.
|
|
67
91
|
export * from './utils/predicate-fields.js';
|
|
68
92
|
export * from './utils/normalize-list-view.js';
|
|
93
|
+
// The single home for the VALUE fallback prettifier (a stored value becomes a
|
|
94
|
+
// display string when nothing resolves it). `@object-ui/fields` and
|
|
95
|
+
// `@object-ui/plugin-charts` each carried a byte-identical private copy;
|
|
96
|
+
// both now re-export this one (objectui#5444). Its docstring also records why
|
|
97
|
+
// it stays distinct from `humanizeFieldKey`, the KEY fallback.
|
|
98
|
+
export * from './utils/humanize-label.js';
|
|
@@ -14,7 +14,48 @@
|
|
|
14
14
|
* @module protocols/DndProtocol
|
|
15
15
|
* @packageDocumentation
|
|
16
16
|
*/
|
|
17
|
-
|
|
17
|
+
/** How a drag is initiated. */
|
|
18
|
+
export type DragHandle = 'element' | 'handle' | 'grip_icon';
|
|
19
|
+
/** The `dropEffect` advertised to assistive technology and DnD libraries. */
|
|
20
|
+
export type DropEffect = 'none' | 'link' | 'move' | 'copy';
|
|
21
|
+
/** Movement constraints applied to a drag. */
|
|
22
|
+
export interface DragConstraint {
|
|
23
|
+
axis: 'x' | 'y' | 'both';
|
|
24
|
+
bounds: 'none' | 'parent' | 'viewport';
|
|
25
|
+
grid?: [number, number];
|
|
26
|
+
}
|
|
27
|
+
/** A draggable item's declaration. */
|
|
28
|
+
export interface DragItem {
|
|
29
|
+
type: string;
|
|
30
|
+
label?: string;
|
|
31
|
+
handle: DragHandle;
|
|
32
|
+
constraint?: DragConstraint;
|
|
33
|
+
preview: 'custom' | 'none' | 'element';
|
|
34
|
+
disabled: boolean;
|
|
35
|
+
ariaLabel?: string;
|
|
36
|
+
ariaDescribedBy?: string;
|
|
37
|
+
role?: string;
|
|
38
|
+
}
|
|
39
|
+
/** A drop target's declaration. */
|
|
40
|
+
export interface DropZone {
|
|
41
|
+
label?: string;
|
|
42
|
+
accept: string[];
|
|
43
|
+
maxItems?: number;
|
|
44
|
+
highlightOnDragOver: boolean;
|
|
45
|
+
dropEffect: DropEffect;
|
|
46
|
+
ariaLabel?: string;
|
|
47
|
+
ariaDescribedBy?: string;
|
|
48
|
+
role?: string;
|
|
49
|
+
}
|
|
50
|
+
/** Top-level drag-and-drop configuration. */
|
|
51
|
+
export interface DndConfig {
|
|
52
|
+
enabled: boolean;
|
|
53
|
+
dragItem?: DragItem;
|
|
54
|
+
dropZone?: DropZone;
|
|
55
|
+
sortable: boolean;
|
|
56
|
+
autoScroll: boolean;
|
|
57
|
+
touchDelay: number;
|
|
58
|
+
}
|
|
18
59
|
/** Fully resolved DnD configuration with all defaults applied. */
|
|
19
60
|
export interface ResolvedDndConfig {
|
|
20
61
|
enabled: boolean;
|
|
@@ -15,7 +15,37 @@
|
|
|
15
15
|
* @module protocols/KeyboardProtocol
|
|
16
16
|
* @packageDocumentation
|
|
17
17
|
*/
|
|
18
|
-
|
|
18
|
+
/** A single keyboard shortcut binding. */
|
|
19
|
+
export interface KeyboardShortcut {
|
|
20
|
+
key: string;
|
|
21
|
+
action: string;
|
|
22
|
+
description?: string;
|
|
23
|
+
scope: 'global' | 'form' | 'modal' | 'view' | 'list';
|
|
24
|
+
}
|
|
25
|
+
/** Focus trap declaration for a modal-like region. */
|
|
26
|
+
export interface FocusTrapConfig {
|
|
27
|
+
enabled: boolean;
|
|
28
|
+
initialFocus?: string;
|
|
29
|
+
returnFocus: boolean;
|
|
30
|
+
escapeDeactivates: boolean;
|
|
31
|
+
}
|
|
32
|
+
/** Focus management declaration. */
|
|
33
|
+
export interface FocusManagement {
|
|
34
|
+
tabOrder: 'manual' | 'auto';
|
|
35
|
+
skipLinks: boolean;
|
|
36
|
+
focusVisible: boolean;
|
|
37
|
+
focusTrap?: FocusTrapConfig;
|
|
38
|
+
arrowNavigation: boolean;
|
|
39
|
+
}
|
|
40
|
+
/** Top-level keyboard navigation configuration. */
|
|
41
|
+
export interface KeyboardNavigationConfig {
|
|
42
|
+
shortcuts?: KeyboardShortcut[];
|
|
43
|
+
focusManagement?: FocusManagement;
|
|
44
|
+
rovingTabindex: boolean;
|
|
45
|
+
ariaLabel?: string;
|
|
46
|
+
ariaDescribedBy?: string;
|
|
47
|
+
role?: string;
|
|
48
|
+
}
|
|
19
49
|
/** Fully resolved keyboard navigation configuration. */
|
|
20
50
|
export interface ResolvedKeyboardConfig {
|
|
21
51
|
shortcuts: KeyboardShortcut[];
|
|
@@ -15,7 +15,17 @@
|
|
|
15
15
|
* @module protocols/SharingProtocol
|
|
16
16
|
* @packageDocumentation
|
|
17
17
|
*/
|
|
18
|
-
import type { SharingConfig
|
|
18
|
+
import type { SharingConfig } from '@object-ui/types';
|
|
19
|
+
/** An iframe embed declaration. */
|
|
20
|
+
export interface EmbedConfig {
|
|
21
|
+
enabled: boolean;
|
|
22
|
+
allowedOrigins?: string[];
|
|
23
|
+
width?: string;
|
|
24
|
+
height?: string;
|
|
25
|
+
showHeader?: boolean;
|
|
26
|
+
showNavigation?: boolean;
|
|
27
|
+
responsive?: boolean;
|
|
28
|
+
}
|
|
19
29
|
/** Fully resolved sharing configuration. */
|
|
20
30
|
export interface ResolvedSharingConfig {
|
|
21
31
|
enabled: boolean;
|
|
@@ -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;
|
|
@@ -43,9 +51,47 @@ export type ComponentMeta = {
|
|
|
43
51
|
* registry.register('form', FormView, { namespace: 'view', skipFallback: true });
|
|
44
52
|
*/
|
|
45
53
|
skipFallback?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* How a HOST must associate its own visible label with what this component
|
|
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.
|
|
61
|
+
*
|
|
62
|
+
* - `'control'` — the component's outermost rendered element is a LABELABLE
|
|
63
|
+
* HTML element (`input` / `textarea` / `select` / `button` / …), so the host
|
|
64
|
+
* associates its label the plain way: `<label for>` → the id the host handed
|
|
65
|
+
* down. This is the default and covers every single-control widget.
|
|
66
|
+
* - `'group'` — it is NOT labelable: either a real composite (several inputs
|
|
67
|
+
* under one container, e.g. `address`) or a single control that is not a
|
|
68
|
+
* labelable element (a `div[role="button"]` dropzone, e.g. `file`). A
|
|
69
|
+
* `<label for>` pointing at such an element is inert in HTML — it activates
|
|
70
|
+
* nothing and contributes no accessible name (`HTMLLabelElement.control` is
|
|
71
|
+
* `null`) — so the host must instead give its label an `id` and hand the
|
|
72
|
+
* component `aria-labelledby`, which associates by IDREF and works on any
|
|
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.
|
|
85
|
+
*
|
|
86
|
+
* This is a DECLARATION, not a guess: the host cannot infer it from the DOM a
|
|
87
|
+
* widget happens to render, and a widget that fails to declare it falls back
|
|
88
|
+
* to the `'control'` path where the dangling/inert `for` is caught by the
|
|
89
|
+
* label-association tests (objectui#3952) instead of silently producing an
|
|
90
|
+
* unlabelled group.
|
|
91
|
+
*/
|
|
92
|
+
labelling?: 'control' | 'group' | 'display';
|
|
46
93
|
inputs?: ComponentInput[];
|
|
47
94
|
defaultProps?: Record<string, any>;
|
|
48
|
-
defaultChildren?: SchemaNode[];
|
|
49
95
|
examples?: Record<string, any>;
|
|
50
96
|
isContainer?: boolean;
|
|
51
97
|
resizable?: boolean;
|
|
@@ -43,14 +43,6 @@ export declare function generateBorderRadiusVars(borderRadius: NonNullable<Theme
|
|
|
43
43
|
* Generate CSS custom properties from a Theme's shadow config.
|
|
44
44
|
*/
|
|
45
45
|
export declare function generateShadowVars(shadows: NonNullable<Theme['shadows']>): Record<string, string>;
|
|
46
|
-
/**
|
|
47
|
-
* Generate CSS custom properties from a Theme's animation config.
|
|
48
|
-
*/
|
|
49
|
-
export declare function generateAnimationVars(animation: NonNullable<Theme['animation']>): Record<string, string>;
|
|
50
|
-
/**
|
|
51
|
-
* Generate CSS custom properties from a Theme's z-index config.
|
|
52
|
-
*/
|
|
53
|
-
export declare function generateZIndexVars(zIndex: NonNullable<Theme['zIndex']>): Record<string, string>;
|
|
54
46
|
/**
|
|
55
47
|
* Generate ALL CSS custom properties from a complete Theme.
|
|
56
48
|
* This is the main entry point for theme → CSS conversion.
|