@object-ui/components 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.
- package/CHANGELOG.md +8750 -0
- package/README.md +5 -3
- package/dist/custom/button-group.d.ts +1 -1
- package/dist/custom/combobox.d.ts +2 -4
- package/dist/custom/empty.d.ts +16 -4
- package/dist/custom/field.d.ts +1 -1
- package/dist/custom/filter-builder.d.ts +198 -66
- package/dist/custom/index.d.ts +0 -1
- package/dist/custom/item.d.ts +1 -1
- package/dist/custom/kbd.d.ts +1 -1
- package/dist/custom/mobile-dialog-content.d.ts +22 -1
- package/dist/custom/navigation-overlay.d.ts +105 -0
- package/dist/custom/refresh-indicator.d.ts +8 -2
- package/dist/custom/view-states.d.ts +74 -1
- package/dist/hooks/related-count-store.d.ts +26 -28
- package/dist/index.css +157 -363
- package/dist/index.d.ts +3 -3
- package/dist/index.js +6603 -5987
- package/dist/index.umd.cjs +10 -15
- package/dist/lib/close-label.d.ts +1 -2
- package/dist/lib/date-fns-locale.d.ts +41 -0
- package/dist/lib/lazy-icon.d.ts +32 -1
- package/dist/lib/lucide-record-icon-names.d.ts +30 -0
- package/dist/lib/utils.d.ts +113 -0
- package/dist/renderers/action/action-bar.d.ts +8 -36
- package/dist/renderers/action/action-button.d.ts +15 -4
- package/dist/renderers/action/action-group.d.ts +5 -4
- package/dist/renderers/action/action-icon.d.ts +12 -2
- package/dist/renderers/action/action-menu.d.ts +5 -2
- package/dist/renderers/action/auto-trigger.d.ts +19 -4
- package/dist/renderers/action/resolve-icon.d.ts +27 -2
- package/dist/renderers/action/static-params.d.ts +79 -0
- package/dist/renderers/action/visibility-gate.d.ts +11 -3
- package/dist/renderers/basic/elements.d.ts +3 -0
- package/dist/renderers/basic/html-elements.d.ts +7 -3
- package/dist/renderers/basic/readProps.d.ts +60 -0
- package/dist/renderers/complex/data-table.d.ts +31 -14
- package/dist/renderers/complex/dataTableBindDiagnostic.d.ts +187 -0
- package/dist/renderers/layout/box.d.ts +8 -0
- package/dist/renderers/layout/containers.d.ts +1 -10
- package/dist/renderers/layout/react-page.d.ts +4 -0
- package/dist/renderers/navigation/sidebar.d.ts +31 -0
- package/dist/ui/badge.d.ts +1 -1
- package/dist/ui/button.d.ts +1 -1
- package/dist/ui/calendar.d.ts +2 -1
- package/dist/ui/command.d.ts +7 -7
- package/dist/ui/index.d.ts +0 -1
- package/dist/ui/input-otp.d.ts +2 -2
- package/dist/ui/sheet.d.ts +1 -1
- package/dist/ui/sidebar.d.ts +2 -1
- package/package.json +13 -14
- package/dist/SchemaRenderer.d.ts +0 -4
- package/dist/custom/export-progress-dialog.d.ts +0 -43
- package/dist/hooks/use-export-job.d.ts +0 -34
- package/dist/ui/chart.d.ts +0 -56
- package/dist/ui/toast.d.ts +0 -22
|
@@ -34,9 +34,13 @@
|
|
|
34
34
|
* scope (objectui#3848).
|
|
35
35
|
*
|
|
36
36
|
* The ruling: a gate is declared when normalization still leaves a condition to
|
|
37
|
-
* evaluate. `''`, a whitespace-only string
|
|
38
|
-
*
|
|
39
|
-
*
|
|
37
|
+
* evaluate. `''`, a whitespace-only string and an empty-`source` envelope are
|
|
38
|
+
* therefore NOT declared, and one definition in core says so for the
|
|
39
|
+
* renderers, `SchemaRenderer` and the execution entry alike. (A non-predicate
|
|
40
|
+
* value — `0`, `{}`, an array, an `ast`-only envelope — was in that list until
|
|
41
|
+
* objectui#11358, which made it a DECLARED gate that cannot be evaluated: the
|
|
42
|
+
* normalizer keeps it, the evaluator faults on it, and each leg fails it in
|
|
43
|
+
* its key's fault direction — `visible` hidden, `disabled` greyed out.)
|
|
40
44
|
*
|
|
41
45
|
* The NAME is kept (`hasDeclaredVisibilityGate`) and this module keeps
|
|
42
46
|
* re-exporting it: the five member-action call sites — `action:button`,
|
|
@@ -68,6 +72,10 @@
|
|
|
68
72
|
* | `{ source: '' }` | shown → shown | GREY → on | on → on |
|
|
69
73
|
* | `' '` (whitespace) | HIDDEN → shown | on → on | GREY → on |
|
|
70
74
|
* | `0` / `{}` (not a predicate) | shown → shown | GREY → on | on → on |
|
|
75
|
+
*
|
|
76
|
+
* (The table is objectui#3850's measurement. Since objectui#11358 the `0` /
|
|
77
|
+
* `{}` row reads HIDDEN / GREY / on: declared and faulting, each leg's fault
|
|
78
|
+
* direction — pinned in `__tests__/action-empty-predicate-scope.test.tsx`.)
|
|
71
79
|
* | `true` / `false` / CEL / `${…}`| unchanged | unchanged | unchanged |
|
|
72
80
|
*
|
|
73
81
|
* The whitespace row is the one that moves on `visible`, and it moves toward the
|
|
@@ -22,5 +22,8 @@
|
|
|
22
22
|
* All props are read off `schema.properties` per the spec's
|
|
23
23
|
* `UIComponent.properties` convention; `schema.props` is also accepted
|
|
24
24
|
* as a fallback so authors transitioning between conventions keep working.
|
|
25
|
+
* `element:number` also reads the node-level `dataSource` binding: its
|
|
26
|
+
* `object` wins over the flat one, and its filter is AND-combined with the
|
|
27
|
+
* flat one (objectui#10909).
|
|
25
28
|
*/
|
|
26
29
|
export {};
|
|
@@ -11,9 +11,13 @@
|
|
|
11
11
|
* PARSED (never executed) into the SDUI tree. For that tier to live up to its
|
|
12
12
|
* name, the everyday HTML tags an author reaches for — headings, paragraphs,
|
|
13
13
|
* lists, links, images, emphasis — must each resolve to a renderer (otherwise
|
|
14
|
-
* the parser flags them `unknown-component`). div / span / table /
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* the parser flags them `unknown-component`). div / span / table / label and
|
|
15
|
+
* the semantic sectioning tags are registered elsewhere; this module fills in
|
|
16
|
+
* the rest of the safe flow/inline set — `code` included (objectui#10756): the
|
|
17
|
+
* bare `code` key used to be the `field:code` widget's namespace fallback, so
|
|
18
|
+
* `<code>inline</code>` on an html page drew a code EDITOR and dropped its
|
|
19
|
+
* text. The widget now stands down from the bare key (`FIELD_TYPES_SKIP_FALLBACK`
|
|
20
|
+
* in `@object-ui/fields`) and stays reachable as `field:code`.
|
|
17
21
|
*
|
|
18
22
|
* Safety: these render real DOM, but the html tier never executes JS, so props
|
|
19
23
|
* are static literals from the parser. As defense-in-depth the passthrough
|
|
@@ -0,0 +1,60 @@
|
|
|
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 config bag an `element:*` renderer reads — THE one definition of it in
|
|
10
|
+
* `@object-ui/components` (objectui#6783).
|
|
11
|
+
*
|
|
12
|
+
* Per spec, element components carry their config in `schema.properties`;
|
|
13
|
+
* `schema.props` is tolerated as the legacy alias so JSON written either way
|
|
14
|
+
* works. `properties` wins a contested key — the 2026-08-18 cross-channel
|
|
15
|
+
* ruling (objectui#5123), whose spread order is preserved here verbatim and
|
|
16
|
+
* pinned by `packages/components/src/__tests__/alias-precedence-cross-channel.test.tsx`.
|
|
17
|
+
*
|
|
18
|
+
* ## The third channel (objectui#6783)
|
|
19
|
+
*
|
|
20
|
+
* This body used to be copied into five renderer modules — `elements.tsx`,
|
|
21
|
+
* `data-list.tsx`, `text-input.tsx`, `record-picker.tsx`,
|
|
22
|
+
* `metadata-viewer.tsx` — each spelling the two halves as
|
|
23
|
+
* `(schema?.properties ?? {}) as T`. `??` only replaces `null`/`undefined`, so
|
|
24
|
+
* a DEGENERATE bag (a string, a number, an array) went straight into the
|
|
25
|
+
* object spread and was re-read as its own indexed keys: for
|
|
26
|
+
* `properties: 'not-a-bag'` the bag a renderer received was
|
|
27
|
+
* `{ '0': 'n', '1': 'o', … '8': 'g' }` — nine keys nobody authored.
|
|
28
|
+
*
|
|
29
|
+
* That is the same hazard objectui#6752 and objectui#6760 closed in
|
|
30
|
+
* `packages/react/src/SchemaRenderer.tsx` on the two channels UPSTREAM of this
|
|
31
|
+
* one (the `props` evaluation memo plus `propsWithoutCanonicalKeys`, and the
|
|
32
|
+
* `properties` hoist). Those guards do not reach here, and are not meant to:
|
|
33
|
+
* what they buy is that the AUTHORED value's shape survives into the node, so
|
|
34
|
+
* a renderer downstream still receives `schema.properties === 'not-a-bag'` and
|
|
35
|
+
* gets to answer the question for itself. The three channels are in SERIES.
|
|
36
|
+
*
|
|
37
|
+
* ## Why it asks `isConfigBag` rather than carrying its own predicate
|
|
38
|
+
*
|
|
39
|
+
* Because a copy that DRIFTS produces no error — each spelling is a boolean
|
|
40
|
+
* expression, so two channels answering "is this a real config bag?"
|
|
41
|
+
* differently is silent by construction. objectui#6761 ended that inside
|
|
42
|
+
* `@object-ui/react` by converging six occurrences behind one exported
|
|
43
|
+
* definition and pinning it (`utils/configBag.pin.test.ts` fails on a seventh
|
|
44
|
+
* spelling); `@object-ui/components` depends on `@object-ui/react` — every one
|
|
45
|
+
* of the five modules above already imports from it — so the reachable answer
|
|
46
|
+
* here is to READ that definition, not to write the seventh spelling one
|
|
47
|
+
* package over where its pin cannot see it.
|
|
48
|
+
*
|
|
49
|
+
* ## What the guard buys, measured
|
|
50
|
+
*
|
|
51
|
+
* Not a rendered pixel, on today's tree: all five renderers read NAMED keys
|
|
52
|
+
* off this bag, and the one onward spread (`metadata-viewer`'s
|
|
53
|
+
* `<StateMachineView {...props} />`) hands them to components that destructure
|
|
54
|
+
* named fields, so the indexed keys were computed and then discarded. What it
|
|
55
|
+
* buys is the same thing objectui#6752 measured its own guard buys — the
|
|
56
|
+
* authored value's shape is not reinterpreted — one channel further down,
|
|
57
|
+
* which is exactly the property that stops mattering only until the first of
|
|
58
|
+
* these five spreads its bag onto a DOM element.
|
|
59
|
+
*/
|
|
60
|
+
export declare function readProps<T extends Record<string, any>>(schema: any): T;
|
|
@@ -40,26 +40,43 @@ type BuiltinRowPredicates = NonNullable<DataTableSchema['rowEditPredicates'] | D
|
|
|
40
40
|
export declare function isBuiltinRowActionVisible(predicates: Pick<BuiltinRowPredicates, 'visibleWhen'> | undefined, name: 'edit' | 'delete', row: any, scope: Record<string, unknown>): boolean;
|
|
41
41
|
/**
|
|
42
42
|
* Does this schema-driven custom row action render for THIS row? Same
|
|
43
|
-
* single-definition rule as the built-ins above
|
|
43
|
+
* single-definition rule as the built-ins above, and the ONE definition for
|
|
44
|
+
* every row menu: this file's (the related list's data table) and
|
|
45
|
+
* plugin-grid's `RowActionMenu` (its "⋮" items, its inline primary buttons and
|
|
46
|
+
* its "⋮" guard), which imports it from the `@object-ui/components` barrel
|
|
47
|
+
* rather than keeping a twin (objectui#11294).
|
|
44
48
|
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* rendered the item for everyone, and counted toward the "⋮" guard. This is the
|
|
50
|
-
* invariant objectui#3492 established for the selection bar (plugin-grid's
|
|
51
|
-
* `hasVisibilityGate`), and the same `!= null` posture the built-in `visibleWhen`
|
|
52
|
-
* gate above has always had. The boolean then decides in
|
|
53
|
-
* {@link evalRowActionVisibility}, which short-circuits it instead of handing it
|
|
54
|
-
* to the engine.
|
|
49
|
+
* Whether a gate is DECLARED at all is asked with `hasDeclaredVisibilityGate`,
|
|
50
|
+
* the action family's one definition (objectui#3812): the related list's
|
|
51
|
+
* toolbar, `action:*`, `DeclaredActionsBar` and the rest ask it too, so an
|
|
52
|
+
* action cannot show in a list's header and be missing from its rows.
|
|
55
53
|
*
|
|
56
|
-
* `
|
|
57
|
-
*
|
|
54
|
+
* - `visible: false` is a declared gate that excludes every row. Truthiness
|
|
55
|
+
* cannot answer the question: testing `!action.visible` read it as ungated
|
|
56
|
+
* and rendered the item for everyone (objectui#3758). The boolean then
|
|
57
|
+
* decides in {@link evalRowActionVisibility}, which short-circuits it instead
|
|
58
|
+
* of handing it to the engine.
|
|
59
|
+
* - A blank predicate is no gate, so the action shows: `''`, a whitespace-only
|
|
60
|
+
* string, and an envelope whose `source` is blank. The blank is still
|
|
61
|
+
* reported (ADR-0137 D4) through the family's one `[blank]` report, once per
|
|
62
|
+
* blank spelling rather than once per row. This test used to be
|
|
63
|
+
* `pred == null || pred === ''`, so a whitespace-only `visible` counted as
|
|
64
|
+
* declared, was evaluated, and failed closed: the action showed in a related
|
|
65
|
+
* list's toolbar and was missing from its rows (objectui#11294).
|
|
66
|
+
* - A value that is not a predicate at all (`0`, `{}`, an array, an
|
|
67
|
+
* `ast`-only envelope) IS a declared gate, one that cannot be evaluated
|
|
68
|
+
* (objectui#11358): the family's definition answers "declared", the row fold
|
|
69
|
+
* faults on it and fails closed, so the action is hidden and the fault is
|
|
70
|
+
* reported — as on every other member of the family.
|
|
71
|
+
*
|
|
72
|
+
* `fields` is the object's field definitions, for a caller that has them:
|
|
73
|
+
* plugin-grid passes them so a relation compares as its stored foreign key
|
|
74
|
+
* (see `evalRowPredicate`). This file's own callers pass none.
|
|
58
75
|
*/
|
|
59
76
|
export declare function isCustomRowActionVisible(action: {
|
|
60
77
|
name?: string;
|
|
61
78
|
visible?: unknown;
|
|
62
|
-
} | undefined, row: any, scope: Record<string, unknown
|
|
79
|
+
} | undefined, row: any, scope: Record<string, unknown>, fields?: unknown): boolean;
|
|
63
80
|
/** What the row overflow menu will actually render for ONE row. */
|
|
64
81
|
export interface DataTableRowMenuPlan {
|
|
65
82
|
/** The built-in Edit item renders for this row. */
|
|
@@ -0,0 +1,187 @@
|
|
|
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 diagnostics that say out loud what `data-table` has always done silently
|
|
10
|
+
* with a key the AUTHOR wrote.
|
|
11
|
+
*
|
|
12
|
+
* TWO questions, one channel. The file is named for the first because it came
|
|
13
|
+
* first (objectui#6575); it was never limited to it.
|
|
14
|
+
*
|
|
15
|
+
* 1. `bind` was authored — and `data-table` does not read `bind` at all
|
|
16
|
+
* (objectui#6575, maintainer ruling 2026-08-27, option A: 「同意」).
|
|
17
|
+
* 2. `data` was authored and is NOT an array — so the renderer dropped it to
|
|
18
|
+
* zero rows at `data-table.tsx`'s
|
|
19
|
+
* `Array.isArray(rawData) ? rawData : EMPTY_ROWS` (objectui#6665).
|
|
20
|
+
*
|
|
21
|
+
* They are deliberately two predicates asking two questions, not one widened
|
|
22
|
+
* predicate. The nodes that trip #2 carry no `bind` AT ALL, so #6575 staying
|
|
23
|
+
* silent on them is correct behaviour rather than a gap — the triage ruling on
|
|
24
|
+
* objectui#6665 is explicit about that, and widening #6575's question would
|
|
25
|
+
* have made its silence look like the defect. See {@link describeNonArrayData}.
|
|
26
|
+
*
|
|
27
|
+
* ## The first defect this names
|
|
28
|
+
*
|
|
29
|
+
* `bind` is the data-scope binding vocabulary: a path string resolved by
|
|
30
|
+
* `useDataScope()`. `list`, `tree-view` and the `object-*` plugin widgets read
|
|
31
|
+
* it. `DataTableRenderer` does NOT — it takes its rows from `data: rawData =
|
|
32
|
+
* EMPTY_ROWS` off the node, and the file calls no such hook.
|
|
33
|
+
*
|
|
34
|
+
* A `bind` on a `data-table` is nevertheless accepted by every gate: the TS
|
|
35
|
+
* side by `BaseSchema`'s `[key: string]: any`, the zod side by `BaseSchema`
|
|
36
|
+
* being `.passthrough()` (which `DataTableSchema.extend(…)` inherits). So the
|
|
37
|
+
* author gets a table drawing a correct-looking header over the "No results
|
|
38
|
+
* found" empty state, with no error, no warning and no diagnostic — the
|
|
39
|
+
* hardest failure shape for a human OR an AI author to self-check, because a
|
|
40
|
+
* rendered header reads as a success receipt.
|
|
41
|
+
*
|
|
42
|
+
* The platform was already paying a teaching cost for it rather than a
|
|
43
|
+
* diagnostic cost: `skills/objectui/rules/protocol.md` documents the pothole
|
|
44
|
+
* verbatim, and `skill-guide-data-table-binding.test.tsx` pins the behaviour.
|
|
45
|
+
* This module moves the warning from the docs to the console, where the author
|
|
46
|
+
* who did not read the docs is standing.
|
|
47
|
+
*
|
|
48
|
+
* ## What it deliberately does NOT do
|
|
49
|
+
*
|
|
50
|
+
* It changes NO behaviour. `data-table` still does not read `bind`, and the
|
|
51
|
+
* ruling is explicit that it must not start: making it a `useDataScope` reader
|
|
52
|
+
* (option B) is a separate published-surface question needing its own ruling.
|
|
53
|
+
* Refusing the key at parse (option C) stays blocked on the `.passthrough()`
|
|
54
|
+
* ceiling (objectui#5155 / objectui#6269). So the trap stops being silent; it
|
|
55
|
+
* does not stop being a trap.
|
|
56
|
+
*
|
|
57
|
+
* ⭐ The `data`-vs-`bind` PRECEDENCE half of that open question DISSOLVED at
|
|
58
|
+
* objectui#9308 rather than being answered. While `useDataScope` walked the
|
|
59
|
+
* injected adapter, `bind` and the node's own `data` were two spellings of one
|
|
60
|
+
* idea — "where this table's rows come from" — and a reader of both would have
|
|
61
|
+
* needed a rule. Since that ruling `bind` resolves a path in the ambient
|
|
62
|
+
* predicate scope and `data` is an inline array on the node: different
|
|
63
|
+
* channels, different questions, no precedence to decide. objectui#6575's
|
|
64
|
+
* ruling that `data-table` must not read `bind` is untouched by that, and this
|
|
65
|
+
* diagnostic's job is unchanged.
|
|
66
|
+
*
|
|
67
|
+
* ## Why a console warning, and only a console warning
|
|
68
|
+
*
|
|
69
|
+
* The same channel `plugin-grid`'s `columnSpellingDiagnostics.ts` uses for the
|
|
70
|
+
* identical shape of failure ("you declared something and the renderer dropped
|
|
71
|
+
* it"): a pure `describe…` function returning `string | null`, called from a
|
|
72
|
+
* `useEffect` keyed on the schema slice, one `console.warn`, no NODE_ENV
|
|
73
|
+
* branch. Deliberately the SAME shape rather than a second, differently-shaped
|
|
74
|
+
* one next to it. Rendering an in-table message instead would be user-facing
|
|
75
|
+
* copy needing all ten locale packs in `@object-ui/i18n`; a throw would take
|
|
76
|
+
* the surrounding page down for a defect that costs one table.
|
|
77
|
+
*
|
|
78
|
+
* The rate limit is the `useEffect` key, and that is enough HERE for a reason
|
|
79
|
+
* `visibilityDiagnostic.ts` does not have available: a node gate is evaluated
|
|
80
|
+
* once per row, so it needs a module-level dedupe `Set` to keep one authoring
|
|
81
|
+
* bug from printing N lines. A `data-table` is one node rendered once — the
|
|
82
|
+
* effect key is one line per mount per distinct `bind`, which is already the
|
|
83
|
+
* "one line per distinct authoring bug" ceiling that `Set` exists to buy.
|
|
84
|
+
*
|
|
85
|
+
* ## The message never asserts something it did not check
|
|
86
|
+
*
|
|
87
|
+
* A node can carry BOTH an inline `data` array and a `bind`. That table is not
|
|
88
|
+
* empty, so the "header over an empty body" consequence would be false there —
|
|
89
|
+
* and a diagnostic that overstates its own consequence teaches authors to
|
|
90
|
+
* distrust it. The two cases get two different consequence clauses, decided by
|
|
91
|
+
* looking at the rows the renderer actually resolved.
|
|
92
|
+
*/
|
|
93
|
+
/** Prefix for every `bind` line — the handle tests and greps hold. */
|
|
94
|
+
export declare const DATA_TABLE_BIND_DIAGNOSTIC_PREFIX = "[ObjectUI] DataTable bind:";
|
|
95
|
+
/** The key `data-table` really reads its rows from. */
|
|
96
|
+
export declare const DECLARED_ROWS_KEY = "data";
|
|
97
|
+
/** Where the offending node lives, for the first line of either message. */
|
|
98
|
+
export interface DataTableNodeAddress {
|
|
99
|
+
/** The schema node's `type` — `data-table`, or an alias that routes here. */
|
|
100
|
+
blockType?: unknown;
|
|
101
|
+
/** The node's `id`, when it has one. */
|
|
102
|
+
id?: unknown;
|
|
103
|
+
/** The table's authored caption — often the only human-readable name. */
|
|
104
|
+
caption?: unknown;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Was a `bind` authored on this node?
|
|
108
|
+
*
|
|
109
|
+
* `undefined` is absence — a destructuring default or an omitted key. Every
|
|
110
|
+
* other value, including `null` and the empty string, is something the author
|
|
111
|
+
* WROTE, and writing it bought nothing. Exported so the renderer's effect key
|
|
112
|
+
* and this judgement cannot drift apart: one predicate, two readers.
|
|
113
|
+
*/
|
|
114
|
+
export declare function hasAuthoredBind(bind: unknown): boolean;
|
|
115
|
+
/**
|
|
116
|
+
* The message for a `data-table` node carrying a `bind`, or `null` when there
|
|
117
|
+
* is nothing to say.
|
|
118
|
+
*
|
|
119
|
+
* `rows` is what the renderer resolved for the body — passed in rather than
|
|
120
|
+
* re-derived, so the consequence sentence is measured against the same array
|
|
121
|
+
* the reader is looking at.
|
|
122
|
+
*
|
|
123
|
+
* Naming the ADDRESS is the point: which node, which path it spells, what the
|
|
124
|
+
* renderer did instead, and what to write to get the rows on screen. A message
|
|
125
|
+
* that only said something went wrong would leave the author where the silence
|
|
126
|
+
* did.
|
|
127
|
+
*/
|
|
128
|
+
export declare function describeIgnoredBind(bind: unknown, rows: unknown, address: DataTableNodeAddress): string | null;
|
|
129
|
+
/** Prefix for every non-array `data` line — the handle tests and greps hold. */
|
|
130
|
+
export declare const DATA_TABLE_DATA_DIAGNOSTIC_PREFIX = "[ObjectUI] DataTable data:";
|
|
131
|
+
/**
|
|
132
|
+
* Was `data` authored as something that is not an array?
|
|
133
|
+
*
|
|
134
|
+
* `undefined` is absence — an omitted key, or the renderer's destructuring
|
|
135
|
+
* default. Everything else the author WROTE, and `data-table.tsx` reduces every
|
|
136
|
+
* non-array value of it to `EMPTY_ROWS` without a word.
|
|
137
|
+
*
|
|
138
|
+
* ## Why this is not {@link hasAuthoredBind}'s question
|
|
139
|
+
*
|
|
140
|
+
* That one asks "was a `bind` authored?" — a key `data-table` does not read at
|
|
141
|
+
* all. This asks about `data`, the key it genuinely does read, and asks a
|
|
142
|
+
* SHAPE question about it rather than a presence one. The nodes that trip this
|
|
143
|
+
* carry no `bind`, so #6575's predicate is correctly silent on them; that
|
|
144
|
+
* silence is precisely why a second question had to be asked here instead of
|
|
145
|
+
* the first one being widened.
|
|
146
|
+
*
|
|
147
|
+
* ## Why the predicate is not keyed on the `${...}` shape
|
|
148
|
+
*
|
|
149
|
+
* The expression string is the spelling that was REPORTED, but it is not the
|
|
150
|
+
* defect. `Array.isArray(rawData) ? rawData : EMPTY_ROWS` swallows a number, an
|
|
151
|
+
* object, a `null` and a plain string exactly as silently, so a predicate that
|
|
152
|
+
* only caught `${...}` would leave the next non-array spelling to arrive as a
|
|
153
|
+
* fresh card. The shape only chooses the wording (see {@link TEMPLATE_SHAPE}).
|
|
154
|
+
*
|
|
155
|
+
* Exported so the renderer and this judgement cannot drift apart: one
|
|
156
|
+
* predicate, two readers.
|
|
157
|
+
*/
|
|
158
|
+
export declare function hasNonArrayAuthoredData(rawData: unknown): boolean;
|
|
159
|
+
/**
|
|
160
|
+
* The message for a `data-table` node whose `data` is not an array, or `null`
|
|
161
|
+
* when there is nothing to say.
|
|
162
|
+
*
|
|
163
|
+
* ## Why no measured-consequence clause, unlike {@link describeIgnoredBind}
|
|
164
|
+
*
|
|
165
|
+
* That one has to look at the rows the renderer resolved, because a node can
|
|
166
|
+
* carry BOTH a `bind` and a real inline `data` array — "header over an empty
|
|
167
|
+
* body" would be false there. Here it cannot be: `data` is the ONLY row source
|
|
168
|
+
* `data-table` has, and this function is called exactly when that source is not
|
|
169
|
+
* an array, so the body is `EMPTY_ROWS` by construction. The consequence is
|
|
170
|
+
* stated because the predicate already established it, not asserted on faith.
|
|
171
|
+
*
|
|
172
|
+
* ## What it deliberately does NOT say
|
|
173
|
+
*
|
|
174
|
+
* It does not tell the author to move the expression under `properties`. The
|
|
175
|
+
* same expression IS evaluated there — that contrast is what makes this a
|
|
176
|
+
* defect rather than a design — but whether `properties` is an authoring
|
|
177
|
+
* channel for the `ui:*` / `page:*` namespaces is an open contract question,
|
|
178
|
+
* recorded in `skills/objectui/rules/protocol.md` rather than recommended by
|
|
179
|
+
* it. A console line is the wrong place to settle that, so the message teaches
|
|
180
|
+
* the one route the guides do teach: the host resolves the rows.
|
|
181
|
+
*
|
|
182
|
+
* It also changes NO behaviour. Making node-level `data` evaluate expressions
|
|
183
|
+
* is a behaviour change on a published component; the objectui#6665 triage
|
|
184
|
+
* ruling put that arm on the maintainer floor and dispatched only this one.
|
|
185
|
+
* The trap stops being silent; it does not stop being a trap.
|
|
186
|
+
*/
|
|
187
|
+
export declare function describeNonArrayData(rawData: unknown, address: DataTableNodeAddress): string | null;
|
|
@@ -17,13 +17,4 @@
|
|
|
17
17
|
* - PageContainerProps -> page:footer / page:sidebar / page:section
|
|
18
18
|
* (the thin wrappers; one shared `children` slot)
|
|
19
19
|
*/
|
|
20
|
-
|
|
21
|
-
* Strip dangling connectors that survive when a `titleFormat` interpolates
|
|
22
|
-
* with one side empty — e.g. `{number} - {name}` becomes `CTR-0001 -` when
|
|
23
|
-
* `name` is blank. Removes a trailing/leading hyphen / middle-dot / colon /
|
|
24
|
-
* slash / pipe (optionally surrounded by whitespace) and collapses
|
|
25
|
-
* adjacent whitespace into a single space. Idempotent.
|
|
26
|
-
*
|
|
27
|
-
* Exported for unit tests.
|
|
28
|
-
*/
|
|
29
|
-
export declare function cleanupTitleSeparators(s: string): string;
|
|
20
|
+
export {};
|
|
@@ -25,6 +25,10 @@
|
|
|
25
25
|
* expressed in HTML are injected.
|
|
26
26
|
* - `Block` — escape hatch: `<Block type="object-grid" .../>`.
|
|
27
27
|
* - `useAdapter` — live data hook: query/create/update objects.
|
|
28
|
+
* - `useDataInvalidation` — the data-invalidation bus reader: a nonce that
|
|
29
|
+
* moves when a write to the named object is reported on the bus. A page
|
|
30
|
+
* names it in the effect that reads through `useAdapter`, so that read
|
|
31
|
+
* re-runs in place (objectui#10887).
|
|
28
32
|
* - `data` / `variables` — page data + local variables, for convenience.
|
|
29
33
|
*
|
|
30
34
|
* Styling — page source is metadata, not build input. A react page styles with
|
|
@@ -6,3 +6,34 @@
|
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
8
|
export {};
|
|
9
|
+
/**
|
|
10
|
+
* ⛔ The ten `sidebar-*` node type keys are RETIRED (objectui#10859 batch 8,
|
|
11
|
+
* phase 2d, the seat's fork ruling on that card, by the objectui#10393 /
|
|
12
|
+
* objectui#8760 route): `sidebar-provider`, `sidebar-header`,
|
|
13
|
+
* `sidebar-content`, `sidebar-group`, `sidebar-menu`, `sidebar-menu-item`,
|
|
14
|
+
* `sidebar-menu-button`, `sidebar-footer`, `sidebar-inset` and
|
|
15
|
+
* `sidebar-trigger`. The shadcn components behind them (`SidebarProvider`,
|
|
16
|
+
* `SidebarHeader`, `SidebarMenuButton`, `SidebarTrigger` and the rest) stay
|
|
17
|
+
* exported from `../../ui` for JSX composition; only the node keys went.
|
|
18
|
+
*
|
|
19
|
+
* ## What was here, and why it went
|
|
20
|
+
*
|
|
21
|
+
* Ten registrations in the `ui` namespace, one per shadcn part, each storing
|
|
22
|
+
* `ui:KEY` and the bare `KEY` fallback. (Described rather than quoted: source
|
|
23
|
+
* readers such as `@object-ui/types`' node-slot test take a quoted call in a
|
|
24
|
+
* comment for a live one.) Nine rendered their child list into the matching
|
|
25
|
+
* shadcn part; `sidebar-group` also drew a resolved `label`,
|
|
26
|
+
* `sidebar-menu-button` passed `size` / `tooltip` through the form-control DOM
|
|
27
|
+
* declaration, and `sidebar-trigger` rendered the collapse button and no child
|
|
28
|
+
* list. No `@object-ui/types` arm claims any of them, so `objectui validate`
|
|
29
|
+
* refused each at `type` while the registry mounted it.
|
|
30
|
+
*
|
|
31
|
+
* ## Why unregistering is the whole retirement
|
|
32
|
+
*
|
|
33
|
+
* The mainstream ships one app-level sidebar region, not author-composable
|
|
34
|
+
* parts (the seat's ruling), and nothing wrote these nodes except the four
|
|
35
|
+
* `components-basic-sidebar` catalog documents, rewritten in the same change to
|
|
36
|
+
* the `sidebar` node above, which now supplies its own provider. Re-measured
|
|
37
|
+
* for phase 2d: 0 other producers in source, docs, examples or objectstack, and
|
|
38
|
+
* 0 runtime emission.
|
|
39
|
+
*/
|
package/dist/ui/badge.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { VariantProps } from 'class-variance-authority';
|
|
|
8
8
|
*/
|
|
9
9
|
import * as React from "react";
|
|
10
10
|
declare const badgeVariants: (props?: ({
|
|
11
|
-
variant?: "default" | "
|
|
11
|
+
variant?: "default" | "secondary" | "outline" | "destructive" | null | undefined;
|
|
12
12
|
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
13
13
|
export interface BadgeProps extends React.HTMLAttributes<HTMLDivElement>, VariantProps<typeof badgeVariants> {
|
|
14
14
|
}
|
package/dist/ui/button.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { VariantProps } from 'class-variance-authority';
|
|
|
8
8
|
*/
|
|
9
9
|
import * as React from "react";
|
|
10
10
|
declare const buttonVariants: (props?: ({
|
|
11
|
-
variant?: "link" | "default" | "
|
|
11
|
+
variant?: "link" | "default" | "secondary" | "outline" | "ghost" | "destructive" | null | undefined;
|
|
12
12
|
size?: "default" | "sm" | "lg" | "icon" | null | undefined;
|
|
13
13
|
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
14
14
|
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
package/dist/ui/calendar.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DayButton, DayPicker } from 'react-day-picker';
|
|
2
|
+
import { CalendarLocaleTagProps } from '../lib/date-fns-locale.js';
|
|
2
3
|
import { Button } from './button.js';
|
|
3
4
|
/**
|
|
4
5
|
* ObjectUI
|
|
@@ -8,7 +9,7 @@ import { Button } from './button.js';
|
|
|
8
9
|
* LICENSE file in the root directory of this source tree.
|
|
9
10
|
*/
|
|
10
11
|
import * as React from "react";
|
|
11
|
-
declare function Calendar({ className, classNames, showOutsideDays, captionLayout, buttonVariant, formatters, components, ...props }: React.ComponentProps<typeof DayPicker> & {
|
|
12
|
+
declare function Calendar({ className, classNames, showOutsideDays, captionLayout, buttonVariant, formatters, components, localeTag, ...props }: React.ComponentProps<typeof DayPicker> & CalendarLocaleTagProps & {
|
|
12
13
|
buttonVariant?: React.ComponentProps<typeof Button>["variant"];
|
|
13
14
|
}): React.JSX.Element;
|
|
14
15
|
declare function CalendarDayButton({ className, day, modifiers, ...props }: React.ComponentProps<typeof DayButton>): React.JSX.Element;
|
package/dist/ui/command.d.ts
CHANGED
|
@@ -33,7 +33,7 @@ declare const Command: React.ForwardRefExoticComponent<Omit<{
|
|
|
33
33
|
ref?: React.Ref<HTMLDivElement>;
|
|
34
34
|
} & {
|
|
35
35
|
asChild?: boolean;
|
|
36
|
-
}, "key" | keyof React.HTMLAttributes<HTMLDivElement
|
|
36
|
+
}, "key" | "asChild" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
37
37
|
label?: string;
|
|
38
38
|
shouldFilter?: boolean;
|
|
39
39
|
filter?: (value: string, search: string, keywords?: string[]) => number;
|
|
@@ -49,7 +49,7 @@ declare const CommandInput: React.ForwardRefExoticComponent<Omit<Omit<Pick<Pick<
|
|
|
49
49
|
ref?: React.Ref<HTMLInputElement>;
|
|
50
50
|
} & {
|
|
51
51
|
asChild?: boolean;
|
|
52
|
-
}, "key" | "asChild" | keyof React.InputHTMLAttributes<HTMLInputElement>>, "
|
|
52
|
+
}, "key" | "asChild" | keyof React.InputHTMLAttributes<HTMLInputElement>>, "type" | "value" | "onChange"> & {
|
|
53
53
|
value?: string;
|
|
54
54
|
onValueChange?: (search: string) => void;
|
|
55
55
|
} & React.RefAttributes<HTMLInputElement>, "ref"> & React.RefAttributes<HTMLInputElement>>;
|
|
@@ -59,7 +59,7 @@ declare const CommandList: React.ForwardRefExoticComponent<Omit<{
|
|
|
59
59
|
ref?: React.Ref<HTMLDivElement>;
|
|
60
60
|
} & {
|
|
61
61
|
asChild?: boolean;
|
|
62
|
-
}, "key" | keyof React.HTMLAttributes<HTMLDivElement
|
|
62
|
+
}, "key" | "asChild" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
63
63
|
label?: string;
|
|
64
64
|
} & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
65
65
|
declare const CommandEmpty: React.ForwardRefExoticComponent<Omit<{
|
|
@@ -68,14 +68,14 @@ declare const CommandEmpty: React.ForwardRefExoticComponent<Omit<{
|
|
|
68
68
|
ref?: React.Ref<HTMLDivElement>;
|
|
69
69
|
} & {
|
|
70
70
|
asChild?: boolean;
|
|
71
|
-
}, "key" | keyof React.HTMLAttributes<HTMLDivElement
|
|
71
|
+
}, "key" | "asChild" | keyof React.HTMLAttributes<HTMLDivElement>> & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
72
72
|
declare const CommandGroup: React.ForwardRefExoticComponent<Omit<{
|
|
73
73
|
children?: React.ReactNode;
|
|
74
74
|
} & Omit<Pick<Pick<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
75
75
|
ref?: React.Ref<HTMLDivElement>;
|
|
76
76
|
} & {
|
|
77
77
|
asChild?: boolean;
|
|
78
|
-
}, "key" | keyof React.HTMLAttributes<HTMLDivElement
|
|
78
|
+
}, "key" | "asChild" | keyof React.HTMLAttributes<HTMLDivElement>>, "value" | "heading"> & {
|
|
79
79
|
heading?: React.ReactNode;
|
|
80
80
|
value?: string;
|
|
81
81
|
forceMount?: boolean;
|
|
@@ -84,7 +84,7 @@ declare const CommandSeparator: React.ForwardRefExoticComponent<Omit<Pick<Pick<R
|
|
|
84
84
|
ref?: React.Ref<HTMLDivElement>;
|
|
85
85
|
} & {
|
|
86
86
|
asChild?: boolean;
|
|
87
|
-
}, "key" | keyof React.HTMLAttributes<HTMLDivElement
|
|
87
|
+
}, "key" | "asChild" | keyof React.HTMLAttributes<HTMLDivElement>> & {
|
|
88
88
|
alwaysRender?: boolean;
|
|
89
89
|
} & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
90
90
|
declare const CommandItem: React.ForwardRefExoticComponent<Omit<{
|
|
@@ -93,7 +93,7 @@ declare const CommandItem: React.ForwardRefExoticComponent<Omit<{
|
|
|
93
93
|
ref?: React.Ref<HTMLDivElement>;
|
|
94
94
|
} & {
|
|
95
95
|
asChild?: boolean;
|
|
96
|
-
}, "key" | keyof React.HTMLAttributes<HTMLDivElement
|
|
96
|
+
}, "key" | "asChild" | keyof React.HTMLAttributes<HTMLDivElement>>, "disabled" | "value" | "onSelect"> & {
|
|
97
97
|
disabled?: boolean;
|
|
98
98
|
onSelect?: (value: string) => void;
|
|
99
99
|
value?: string;
|
package/dist/ui/index.d.ts
CHANGED
package/dist/ui/input-otp.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* LICENSE file in the root directory of this source tree.
|
|
7
7
|
*/
|
|
8
8
|
import * as React from "react";
|
|
9
|
-
declare const InputOTP: React.ForwardRefExoticComponent<(Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "
|
|
9
|
+
declare const InputOTP: React.ForwardRefExoticComponent<(Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "onChange" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
|
|
10
10
|
value?: string;
|
|
11
11
|
onChange?: (newValue: string) => unknown;
|
|
12
12
|
maxLength: number;
|
|
@@ -19,7 +19,7 @@ declare const InputOTP: React.ForwardRefExoticComponent<(Omit<Omit<React.InputHT
|
|
|
19
19
|
} & {
|
|
20
20
|
render: (props: import('input-otp').RenderProps) => React.ReactNode;
|
|
21
21
|
children?: never;
|
|
22
|
-
} & React.RefAttributes<HTMLInputElement>, "ref"> | Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "
|
|
22
|
+
} & React.RefAttributes<HTMLInputElement>, "ref"> | Omit<Omit<React.InputHTMLAttributes<HTMLInputElement>, "value" | "onChange" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
|
|
23
23
|
value?: string;
|
|
24
24
|
onChange?: (newValue: string) => unknown;
|
|
25
25
|
maxLength: number;
|
package/dist/ui/sheet.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ declare const SheetClose: React.ForwardRefExoticComponent<SheetPrimitive.DialogC
|
|
|
14
14
|
declare const SheetPortal: React.FC<SheetPrimitive.DialogPortalProps>;
|
|
15
15
|
declare const SheetOverlay: React.ForwardRefExoticComponent<Omit<SheetPrimitive.DialogOverlayProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
|
|
16
16
|
declare const sheetVariants: (props?: ({
|
|
17
|
-
side?: "
|
|
17
|
+
side?: "top" | "bottom" | "left" | "right" | null | undefined;
|
|
18
18
|
} & import('class-variance-authority/types').ClassProp) | undefined) => string;
|
|
19
19
|
interface SheetContentProps extends React.ComponentPropsWithoutRef<typeof SheetPrimitive.Content>, VariantProps<typeof sheetVariants> {
|
|
20
20
|
hideOverlay?: boolean;
|
package/dist/ui/sidebar.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ type SidebarContextProps = {
|
|
|
18
18
|
toggleSidebar: () => void;
|
|
19
19
|
};
|
|
20
20
|
declare function useSidebar(): SidebarContextProps;
|
|
21
|
+
declare function useOptionalSidebar(): SidebarContextProps | null;
|
|
21
22
|
declare const SidebarProvider: React.ForwardRefExoticComponent<Omit<React.ClassAttributes<HTMLDivElement> & React.HTMLAttributes<HTMLDivElement> & {
|
|
22
23
|
defaultOpen?: boolean;
|
|
23
24
|
open?: boolean;
|
|
@@ -69,4 +70,4 @@ declare const SidebarMenuSubButton: React.ForwardRefExoticComponent<Omit<React.C
|
|
|
69
70
|
size?: "sm" | "md";
|
|
70
71
|
isActive?: boolean;
|
|
71
72
|
}, "ref"> & React.RefAttributes<HTMLAnchorElement>>;
|
|
72
|
-
export { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, useSidebar, };
|
|
73
|
+
export { Sidebar, SidebarContent, SidebarFooter, SidebarGroup, SidebarGroupAction, SidebarGroupContent, SidebarGroupLabel, SidebarHeader, SidebarInput, SidebarInset, SidebarMenu, SidebarMenuAction, SidebarMenuBadge, SidebarMenuButton, SidebarMenuItem, SidebarMenuSkeleton, SidebarMenuSub, SidebarMenuSubButton, SidebarMenuSubItem, SidebarProvider, SidebarRail, SidebarSeparator, SidebarTrigger, useSidebar, useOptionalSidebar, };
|