@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.
Files changed (56) hide show
  1. package/CHANGELOG.md +8750 -0
  2. package/README.md +5 -3
  3. package/dist/custom/button-group.d.ts +1 -1
  4. package/dist/custom/combobox.d.ts +2 -4
  5. package/dist/custom/empty.d.ts +16 -4
  6. package/dist/custom/field.d.ts +1 -1
  7. package/dist/custom/filter-builder.d.ts +198 -66
  8. package/dist/custom/index.d.ts +0 -1
  9. package/dist/custom/item.d.ts +1 -1
  10. package/dist/custom/kbd.d.ts +1 -1
  11. package/dist/custom/mobile-dialog-content.d.ts +22 -1
  12. package/dist/custom/navigation-overlay.d.ts +105 -0
  13. package/dist/custom/refresh-indicator.d.ts +8 -2
  14. package/dist/custom/view-states.d.ts +74 -1
  15. package/dist/hooks/related-count-store.d.ts +26 -28
  16. package/dist/index.css +157 -363
  17. package/dist/index.d.ts +3 -3
  18. package/dist/index.js +6603 -5987
  19. package/dist/index.umd.cjs +10 -15
  20. package/dist/lib/close-label.d.ts +1 -2
  21. package/dist/lib/date-fns-locale.d.ts +41 -0
  22. package/dist/lib/lazy-icon.d.ts +32 -1
  23. package/dist/lib/lucide-record-icon-names.d.ts +30 -0
  24. package/dist/lib/utils.d.ts +113 -0
  25. package/dist/renderers/action/action-bar.d.ts +8 -36
  26. package/dist/renderers/action/action-button.d.ts +15 -4
  27. package/dist/renderers/action/action-group.d.ts +5 -4
  28. package/dist/renderers/action/action-icon.d.ts +12 -2
  29. package/dist/renderers/action/action-menu.d.ts +5 -2
  30. package/dist/renderers/action/auto-trigger.d.ts +19 -4
  31. package/dist/renderers/action/resolve-icon.d.ts +27 -2
  32. package/dist/renderers/action/static-params.d.ts +79 -0
  33. package/dist/renderers/action/visibility-gate.d.ts +11 -3
  34. package/dist/renderers/basic/elements.d.ts +3 -0
  35. package/dist/renderers/basic/html-elements.d.ts +7 -3
  36. package/dist/renderers/basic/readProps.d.ts +60 -0
  37. package/dist/renderers/complex/data-table.d.ts +31 -14
  38. package/dist/renderers/complex/dataTableBindDiagnostic.d.ts +187 -0
  39. package/dist/renderers/layout/box.d.ts +8 -0
  40. package/dist/renderers/layout/containers.d.ts +1 -10
  41. package/dist/renderers/layout/react-page.d.ts +4 -0
  42. package/dist/renderers/navigation/sidebar.d.ts +31 -0
  43. package/dist/ui/badge.d.ts +1 -1
  44. package/dist/ui/button.d.ts +1 -1
  45. package/dist/ui/calendar.d.ts +2 -1
  46. package/dist/ui/command.d.ts +7 -7
  47. package/dist/ui/index.d.ts +0 -1
  48. package/dist/ui/input-otp.d.ts +2 -2
  49. package/dist/ui/sheet.d.ts +1 -1
  50. package/dist/ui/sidebar.d.ts +2 -1
  51. package/package.json +13 -14
  52. package/dist/SchemaRenderer.d.ts +0 -4
  53. package/dist/custom/export-progress-dialog.d.ts +0 -43
  54. package/dist/hooks/use-export-job.d.ts +0 -34
  55. package/dist/ui/chart.d.ts +0 -56
  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, an empty-`source` envelope and any
38
- * non-predicate value are therefore NOT declared, and one definition in core
39
- * says so for the renderers, `SchemaRenderer` and the execution entry alike.
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 / code / label
15
- * and the semantic sectioning tags are registered elsewhere; this module fills
16
- * in the rest of the safe flow/inline set.
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
- * A gate counts as DECLARED by `!= null && !== ''`, never by truthiness
46
- * (objectui#3758). Truthiness cannot answer the question: `visible: false` is a
47
- * declared gate that excludes every row, and testing `!action.visible`
48
- * classified it as *ungated* — so the most explicit way to say "never show this"
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
- * `''` is grouped with `null` deliberately: an empty predicate is nothing to
57
- * evaluate, so it must not hide the item from everyone either.
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>): boolean;
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;
@@ -0,0 +1,8 @@
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
+ export {};
@@ -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
+ */
@@ -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" | "destructive" | "outline" | "secondary" | null | undefined;
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
  }
@@ -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" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
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> {
@@ -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;
@@ -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> | "asChild"> & {
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>>, "onChange" | "value" | "type"> & {
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> | "asChild"> & {
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> | "asChild"> & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<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> | "asChild">, "heading" | "value"> & {
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> | "asChild"> & {
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> | "asChild">, "onSelect" | "disabled" | "value"> & {
96
+ }, "key" | "asChild" | keyof React.HTMLAttributes<HTMLDivElement>>, "disabled" | "value" | "onSelect"> & {
97
97
  disabled?: boolean;
98
98
  onSelect?: (value: string) => void;
99
99
  value?: string;
@@ -16,7 +16,6 @@ export * from './button.js';
16
16
  export * from './calendar.js';
17
17
  export * from './card.js';
18
18
  export * from './carousel.js';
19
- export * from './chart.js';
20
19
  export * from './checkbox.js';
21
20
  export * from './collapsible.js';
22
21
  export * from './command.js';
@@ -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>, "onChange" | "value" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
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>, "onChange" | "value" | "maxLength" | "textAlign" | "onComplete" | "pushPasswordManagerStrategy" | "pasteTransformer" | "containerClassName" | "noScriptCSSFallback"> & {
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;
@@ -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?: "left" | "right" | "top" | "bottom" | null | undefined;
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;
@@ -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, };