@object-ui/plugin-detail 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 +6741 -0
- package/README.md +404 -71
- package/dist/ActivityTimeline.d.ts.map +1 -1
- package/dist/CommentAttachment.d.ts.map +1 -1
- package/dist/ConcurrentUpdateDialog.d.ts +17 -1
- package/dist/ConcurrentUpdateDialog.d.ts.map +1 -1
- package/dist/DetailSection.d.ts.map +1 -1
- package/dist/DetailSectionNode.d.ts +97 -0
- package/dist/DetailSectionNode.d.ts.map +1 -0
- package/dist/DetailView.d.ts.map +1 -1
- package/dist/HeaderHighlight.d.ts.map +1 -1
- package/dist/HistoryTimeline.d.ts +8 -1
- package/dist/HistoryTimeline.d.ts.map +1 -1
- package/dist/InlineEditSaveBar.d.ts +68 -0
- package/dist/InlineEditSaveBar.d.ts.map +1 -1
- package/dist/InlineFieldInput.d.ts +79 -6
- package/dist/InlineFieldInput.d.ts.map +1 -1
- package/dist/ReactionPicker.d.ts.map +1 -1
- package/dist/RecordActivityTimeline.d.ts +19 -4
- package/dist/RecordActivityTimeline.d.ts.map +1 -1
- package/dist/RecordChatterPanel.d.ts +6 -1
- package/dist/RecordChatterPanel.d.ts.map +1 -1
- package/dist/RecordComments.d.ts +1 -0
- package/dist/RecordComments.d.ts.map +1 -1
- package/dist/RecordDetailDrawer.d.ts +20 -6
- package/dist/RecordDetailDrawer.d.ts.map +1 -1
- package/dist/RecordDetailPanel.d.ts +101 -0
- package/dist/RecordDetailPanel.d.ts.map +1 -0
- package/dist/RecordMetaFooter.d.ts +1 -1
- package/dist/RecordMetaFooter.d.ts.map +1 -1
- package/dist/RelatedList.d.ts +83 -10
- package/dist/RelatedList.d.ts.map +1 -1
- package/dist/ThreadedReplies.d.ts +1 -1
- package/dist/ThreadedReplies.d.ts.map +1 -1
- package/dist/emptiness.d.ts +142 -0
- package/dist/emptiness.d.ts.map +1 -0
- package/dist/fieldEnrichment.d.ts +44 -4
- package/dist/fieldEnrichment.d.ts.map +1 -1
- package/dist/headerColor.d.ts +20 -0
- package/dist/headerColor.d.ts.map +1 -0
- package/dist/index.d.ts +94 -77
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4883 -5255
- package/dist/index.umd.cjs +2 -5
- package/dist/renderers/record-activity.d.ts.map +1 -1
- package/dist/renderers/record-alert.d.ts +23 -3
- package/dist/renderers/record-alert.d.ts.map +1 -1
- package/dist/renderers/record-alert.readProps.d.ts +40 -0
- package/dist/renderers/record-alert.readProps.d.ts.map +1 -0
- package/dist/renderers/record-chatter.d.ts.map +1 -1
- package/dist/renderers/record-details.d.ts +2 -0
- package/dist/renderers/record-details.d.ts.map +1 -1
- package/dist/renderers/record-highlights.d.ts.map +1 -1
- package/dist/renderers/record-history.d.ts +1 -1
- package/dist/renderers/record-history.d.ts.map +1 -1
- package/dist/renderers/record-path.d.ts.map +1 -1
- package/dist/renderers/record-quick-actions.d.ts +16 -6
- package/dist/renderers/record-quick-actions.d.ts.map +1 -1
- package/dist/renderers/record-reference-rail.d.ts +40 -0
- package/dist/renderers/record-reference-rail.d.ts.map +1 -1
- package/dist/renderers/record-related-list.d.ts +37 -3
- package/dist/renderers/record-related-list.d.ts.map +1 -1
- package/dist/renderers/recordActivityFeed.d.ts +272 -20
- package/dist/renderers/recordActivityFeed.d.ts.map +1 -1
- package/dist/renderers/recordComponentAria.d.ts +44 -0
- package/dist/renderers/recordComponentAria.d.ts.map +1 -0
- package/dist/renderers/relatedListActions.d.ts +102 -0
- package/dist/renderers/relatedListActions.d.ts.map +1 -0
- package/dist/summaryChipPercent.d.ts +83 -0
- package/dist/summaryChipPercent.d.ts.map +1 -0
- package/dist/summaryChipRenderers.d.ts +83 -0
- package/dist/summaryChipRenderers.d.ts.map +1 -0
- package/dist/synth/buildDefaultPageSchema.d.ts +98 -17
- package/dist/synth/buildDefaultPageSchema.d.ts.map +1 -1
- package/dist/useDetailTranslation.d.ts.map +1 -1
- package/dist/useRecordEditable.d.ts +1 -1
- package/dist/useRecordEditable.d.ts.map +1 -1
- package/package.json +19 -18
- package/dist/CommentInput.d.ts +0 -24
- package/dist/CommentInput.d.ts.map +0 -1
- package/dist/DiffView.d.ts +0 -24
- package/dist/DiffView.d.ts.map +0 -1
- package/dist/InlineCreateRelated.d.ts +0 -32
- package/dist/InlineCreateRelated.d.ts.map +0 -1
- package/dist/MentionAutocomplete.d.ts +0 -43
- package/dist/MentionAutocomplete.d.ts.map +0 -1
- package/dist/PointInTimeRestore.d.ts +0 -28
- package/dist/PointInTimeRestore.d.ts.map +0 -1
- package/dist/RecordNavigationEnhanced.d.ts +0 -18
- package/dist/RecordNavigationEnhanced.d.ts.map +0 -1
- package/dist/RelationshipGraph.d.ts +0 -23
- package/dist/RelationshipGraph.d.ts.map +0 -1
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
import { DataSource } from '@object-ui/types';
|
|
3
|
+
/**
|
|
4
|
+
* Field names hidden from the quick-look overlay / inline edit form.
|
|
5
|
+
*
|
|
6
|
+
* Scope: this is the OVERLAY allow-list — used to keep the slim panel UI
|
|
7
|
+
* focused on author-defined business fields. The full record detail page
|
|
8
|
+
* (`RecordDetailView`) surfaces audit fields via a compact
|
|
9
|
+
* `<RecordMetaFooter>` (single-line, muted) rather than a heavy panel, so
|
|
10
|
+
* users can still see who/when created or last touched a record.
|
|
11
|
+
*
|
|
12
|
+
* Derived from the shared `SYSTEM_MANAGED_FIELD_NAMES` — the same set the grid's
|
|
13
|
+
* default-column derivation uses — so it stays in lockstep with the fields
|
|
14
|
+
* `applySystemFields` injects (audit `*_at`/`*_by`, the ownership/tenant FKs,
|
|
15
|
+
* soft-delete bookkeeping). Callers can still override via the `systemFields` prop.
|
|
16
|
+
*/
|
|
17
|
+
export declare const DEFAULT_SYSTEM_FIELDS: Set<string>;
|
|
18
|
+
export interface RecordDetailPanelProps {
|
|
19
|
+
/** The record being displayed. */
|
|
20
|
+
record: Record<string, any>;
|
|
21
|
+
/** Logical object name used by the data source. */
|
|
22
|
+
objectName: string;
|
|
23
|
+
/** Record id (string-coerced before issuing update/delete). */
|
|
24
|
+
recordId: string | number;
|
|
25
|
+
/** Active data source — used for inline updates and deletion. */
|
|
26
|
+
dataSource?: DataSource;
|
|
27
|
+
/**
|
|
28
|
+
* Optional objectSchema (as returned by `dataSource.getObjectSchema`).
|
|
29
|
+
* When provided the panel infers field types so dates / picklists /
|
|
30
|
+
* currency render with their proper widgets.
|
|
31
|
+
*/
|
|
32
|
+
objectSchema?: {
|
|
33
|
+
fields?: Record<string, any>;
|
|
34
|
+
} | null;
|
|
35
|
+
/** Number of columns the field grid should use. Default `2`. */
|
|
36
|
+
columns?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Optional override for the SYSTEM_FIELDS filter. Defaults to a
|
|
39
|
+
* standard set (id, timestamps, audit fields).
|
|
40
|
+
*/
|
|
41
|
+
systemFields?: Set<string>;
|
|
42
|
+
/**
|
|
43
|
+
* Persist an inline field edit. Plugins usually update local state
|
|
44
|
+
* here so the panel stays in sync after the network round-trip.
|
|
45
|
+
*/
|
|
46
|
+
onFieldSave?: (field: string, value: unknown) => void | Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Persist record deletion. Plugins are expected to remove the record
|
|
49
|
+
* from their local state; the host is asked to close via `onClose`
|
|
50
|
+
* after this resolves.
|
|
51
|
+
*/
|
|
52
|
+
onDelete?: () => void | Promise<void>;
|
|
53
|
+
/**
|
|
54
|
+
* Dismiss the overlay. Called after a successful delete. The shell owns
|
|
55
|
+
* every other way of closing.
|
|
56
|
+
*/
|
|
57
|
+
onClose?: () => void;
|
|
58
|
+
/**
|
|
59
|
+
* Optional URL to the full record page. When provided, the panel adds an
|
|
60
|
+
* "Open in new tab" entry to `DetailView`'s header overflow menu.
|
|
61
|
+
* Typically `/console/apps/{appName}/{objectName}/record/{recordId}`.
|
|
62
|
+
*/
|
|
63
|
+
fullPageHref?: string;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Build `DetailView`'s typed field list from an object schema.
|
|
67
|
+
*
|
|
68
|
+
* Exported because the derivation — not just the JSX — is what the five
|
|
69
|
+
* renderers share; a second hand-written copy is exactly the fork this card
|
|
70
|
+
* exists to remove.
|
|
71
|
+
*/
|
|
72
|
+
export declare function buildRecordDetailFields(record: Record<string, any>, objectSchema: {
|
|
73
|
+
fields?: Record<string, any>;
|
|
74
|
+
} | null | undefined, systemFields: Set<string>): Array<Record<string, any>>;
|
|
75
|
+
/**
|
|
76
|
+
* The default overlay width, and the single code home of this literal
|
|
77
|
+
* repo-wide.
|
|
78
|
+
*
|
|
79
|
+
* The gantt, kanban and calendar renderers deliberately spell no `width` of
|
|
80
|
+
* their own and let an unauthored `navigation.width` fall through to this
|
|
81
|
+
* value. Converging it on the `size: 'lg'` bucket (`min(92vw, 960px)` — up to
|
|
82
|
+
* 53% wider below a 1600px viewport) was RULED AGAINST: objectui#6584,
|
|
83
|
+
* 2026-08-27 — stays on the CSS literal; no bucket convergence. The question is
|
|
84
|
+
* CLOSED, not open.
|
|
85
|
+
*
|
|
86
|
+
* ⚠️ It became an EXPORT with objectui#9299. Before that it was
|
|
87
|
+
* `RecordDetailDrawer`'s default parameter, reached by passing `undefined`;
|
|
88
|
+
* the renderers no longer go through that component, so they read the constant
|
|
89
|
+
* instead. ⛔ Do not re-spell the literal at a call site — four copies of a
|
|
90
|
+
* ruled-on number is how the four surfaces drift apart.
|
|
91
|
+
*
|
|
92
|
+
* `NavigationOverlay` treats an authored width as a FLOOR
|
|
93
|
+
* (`max(WIDTH, min(60vw, 880px))`), and for this value that expression reduces
|
|
94
|
+
* to `min(60vw, 960px)` at every viewport — i.e. the same pixels the old
|
|
95
|
+
* inline style set.
|
|
96
|
+
*/
|
|
97
|
+
export declare const RECORD_OVERLAY_DEFAULT_WIDTH = "min(960px, 60vw)";
|
|
98
|
+
/** The record overlay payload — shell-free by construction. */
|
|
99
|
+
export declare function RecordDetailPanel({ record, objectName, recordId, dataSource, objectSchema, columns, systemFields, onFieldSave, onDelete, onClose, fullPageHref, }: RecordDetailPanelProps): React.JSX.Element;
|
|
100
|
+
export default RecordDetailPanel;
|
|
101
|
+
//# sourceMappingURL=RecordDetailPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RecordDetailPanel.d.ts","sourceRoot":"","sources":["../src/RecordDetailPanel.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAOnD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qBAAqB,aAAsC,CAAC;AAEzE,MAAM,WAAW,sBAAsB;IACrC,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC5B,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,iEAAiE;IACjE,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB;;;;OAIG;IACH,YAAY,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;KAAE,GAAG,IAAI,CAAC;IACvD,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B;;;OAGG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC3B,YAAY,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,EACjE,YAAY,EAAE,GAAG,CAAC,MAAM,CAAC,GACxB,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CA8F5B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,4BAA4B,qBAAqB,CAAC;AAE/D,+DAA+D;AAC/D,wBAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,UAAU,EACV,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,OAAW,EACX,YAAoC,EACpC,WAAW,EACX,QAAQ,EACR,OAAO,EACP,YAAY,GACb,EAAE,sBAAsB,qBAyExB;AAED,eAAe,iBAAiB,CAAC"}
|
|
@@ -9,7 +9,7 @@ import * as React from 'react';
|
|
|
9
9
|
export interface RecordMetaFooterProps {
|
|
10
10
|
/** The current record data; expected to contain audit fields when available. */
|
|
11
11
|
data: Record<string, any> | null | undefined;
|
|
12
|
-
/** Resolved object schema (used to read
|
|
12
|
+
/** Resolved object schema (used to read `reference` for created_by/updated_by). */
|
|
13
13
|
objectSchema?: any;
|
|
14
14
|
/** Object name for future i18n hooks (currently unused). */
|
|
15
15
|
objectName?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RecordMetaFooter.d.ts","sourceRoot":"","sources":["../src/RecordMetaFooter.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"RecordMetaFooter.d.ts","sourceRoot":"","sources":["../src/RecordMetaFooter.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAgB/B,MAAM,WAAW,qBAAqB;IACpC,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,GAAG,SAAS,CAAC;IAC7C,mFAAmF;IACnF,YAAY,CAAC,EAAE,GAAG,CAAC;IACnB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAsKD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAiE5D,CAAC"}
|
package/dist/RelatedList.d.ts
CHANGED
|
@@ -64,11 +64,27 @@ export interface RelatedListProps {
|
|
|
64
64
|
linkField?: string;
|
|
65
65
|
label?: string;
|
|
66
66
|
};
|
|
67
|
-
/** Callback when a row is clicked (opens record detail) */
|
|
68
|
-
onRowClick?: (row: any) => void;
|
|
69
67
|
/**
|
|
70
|
-
*
|
|
71
|
-
*
|
|
68
|
+
* Callback when a row is clicked (opens record detail).
|
|
69
|
+
*
|
|
70
|
+
* TWO parameters since objectui#9357, and the second is not decoration: this
|
|
71
|
+
* prop reaches `useNavigationOverlay` as its `onRowClick`, and `handleClick`
|
|
72
|
+
* invokes it as `onRowClick(record, event)` — the modifier payload a host
|
|
73
|
+
* needs to implement Cmd/Ctrl/middle-click for itself. Declaring one
|
|
74
|
+
* parameter hid the second on the ONE line a host reads. Spelled `any` and
|
|
75
|
+
* not `HandleClickModifiers` for the reason objectui#9341 measured on
|
|
76
|
+
* `ObjectKanbanSchema.onCardClick`: that interface lives in
|
|
77
|
+
* `@object-ui/react`, the published twins in `@object-ui/types` may not name
|
|
78
|
+
* it, and a host that discovered the payload from the implementation
|
|
79
|
+
* annotated it `React.MouseEvent` — which a narrower declaration refuses
|
|
80
|
+
* contravariantly. `BaseSchema`'s own `onClick` / `onChange` / `onSubmit`
|
|
81
|
+
* already use this spelling for exactly this situation.
|
|
82
|
+
*/
|
|
83
|
+
onRowClick?: (row: any, event?: any) => void;
|
|
84
|
+
/**
|
|
85
|
+
* Child-object row actions (`locations` `list_item`, or `record_related`
|
|
86
|
+
* inside a parent record — objectui#11270), already localized by the host.
|
|
87
|
+
* Rendered in each row's overflow menu alongside Edit/Delete.
|
|
72
88
|
*/
|
|
73
89
|
rowActions?: RelatedRowActionDef[];
|
|
74
90
|
/** Execute one of {@link rowActions} against the clicked row. */
|
|
@@ -81,6 +97,26 @@ export interface RelatedListProps {
|
|
|
81
97
|
toolbarActions?: RelatedRowActionDef[];
|
|
82
98
|
/** Execute one of {@link toolbarActions} (no row context). */
|
|
83
99
|
onToolbarAction?: (action: RelatedRowActionDef) => void | Promise<void>;
|
|
100
|
+
/**
|
|
101
|
+
* Field names this list must never show, whatever decided its columns
|
|
102
|
+
* (objectui#9053).
|
|
103
|
+
*
|
|
104
|
+
* The block-level authoring preference `record:related_list` reads as
|
|
105
|
+
* `redactFields`, pushed down to the component that actually decides
|
|
106
|
+
* columns. It used to be applied only where the block could apply it — over
|
|
107
|
+
* the AUTHORED `columns` array — and this component has two more paths that
|
|
108
|
+
* decide columns on their own (`highlightFields` prominence and the
|
|
109
|
+
* heuristic field walk), which that list never reached. Redacting EVERY
|
|
110
|
+
* authored column therefore emptied the array, the empty array read as "no
|
|
111
|
+
* columns were authored", and the derived set brought the redacted field
|
|
112
|
+
* straight back: applying the control maximally switched it off.
|
|
113
|
+
*
|
|
114
|
+
* ⚠️ This is an AUTHORING preference, not the permission boundary. Field
|
|
115
|
+
* security is enforced independently and unconditionally through
|
|
116
|
+
* `perms.checkField(..., 'read')` on every path below; a field that must be
|
|
117
|
+
* unreachable belongs in FLS, not here.
|
|
118
|
+
*/
|
|
119
|
+
redactFields?: string[];
|
|
84
120
|
/** Maximum number of columns to auto-generate. Default 6. */
|
|
85
121
|
maxColumns?: number;
|
|
86
122
|
/** Page size for pagination (enables pagination when set) */
|
|
@@ -104,6 +140,9 @@ export interface RelatedListProps {
|
|
|
104
140
|
* since objectui#3106 they sort the collection rather than the page, so the
|
|
105
141
|
* button row above them would be a second control over the same order.
|
|
106
142
|
*
|
|
143
|
+
* A masked column (a `password` / `secret` field, or any column while the
|
|
144
|
+
* object's field types are still unknown) gets no button (objectui#10728).
|
|
145
|
+
*
|
|
107
146
|
* @default false
|
|
108
147
|
*/
|
|
109
148
|
sortable?: boolean;
|
|
@@ -130,7 +169,12 @@ export interface RelatedListProps {
|
|
|
130
169
|
* second conversion dialect appears.
|
|
131
170
|
*/
|
|
132
171
|
filter?: ViewFilterRule[] | FilterNode;
|
|
133
|
-
/**
|
|
172
|
+
/**
|
|
173
|
+
* Enable text filtering. The box keeps a row when a column the list shows
|
|
174
|
+
* contains the term; a masked column (a `password` / `secret` field, or any
|
|
175
|
+
* column while the object's field types are still unknown) and a field no
|
|
176
|
+
* column shows are not searched (objectui#10728).
|
|
177
|
+
*/
|
|
134
178
|
filterable?: boolean;
|
|
135
179
|
/** Whether the card is collapsible */
|
|
136
180
|
collapsible?: boolean;
|
|
@@ -140,15 +184,32 @@ export interface RelatedListProps {
|
|
|
140
184
|
* Foreign-key field name on child records pointing back to the parent.
|
|
141
185
|
* The renderer hides this column from the table and from the schema-derived
|
|
142
186
|
* column list, since the parent record is already implicit context.
|
|
143
|
-
* Used in combination with `parentId` to scope the auto-fetch query
|
|
187
|
+
* Used in combination with `parentId` to scope the auto-fetch query — its
|
|
188
|
+
* ARITY on the child object decides how that condition is compiled, see
|
|
189
|
+
* `parentId` below.
|
|
144
190
|
*/
|
|
145
191
|
referenceField?: string;
|
|
146
192
|
/**
|
|
147
193
|
* Primary-key value of the parent record. When both `parentId` and
|
|
148
|
-
* `referenceField` are set, the auto-fetch query is scoped
|
|
149
|
-
*
|
|
150
|
-
*
|
|
151
|
-
*
|
|
194
|
+
* `referenceField` are set, the auto-fetch query is scoped to this parent's
|
|
195
|
+
* children so only true children are returned. Without this scope the list
|
|
196
|
+
* would dump the entire target object table.
|
|
197
|
+
*
|
|
198
|
+
* The condition is compiled to match the relationship field's ARITY on the
|
|
199
|
+
* child object (objectui#7299), because the two arities are two different
|
|
200
|
+
* questions about the stored value:
|
|
201
|
+
*
|
|
202
|
+
* - single-valued → `$filter: { [referenceField]: parentId }` — equality,
|
|
203
|
+
* byte for byte what this component has always sent;
|
|
204
|
+
* - `multiple: true` → `$filter: { [referenceField]: { $contains: parentId } }`
|
|
205
|
+
* — MEMBERSHIP, because the stored value is an ARRAY of ids and equality
|
|
206
|
+
* asks whether the whole array IS one id.
|
|
207
|
+
*
|
|
208
|
+
* The verdict is `@objectstack/spec/data`'s own `isMultiValueField`, not a
|
|
209
|
+
* local rule, and it is reached through `@object-ui/core`'s
|
|
210
|
+
* {@link composeParentScopeFilter} — the ONE compiler of this condition,
|
|
211
|
+
* shared with the tab-badge count probe that used to carry a second one
|
|
212
|
+
* (objectui#8882).
|
|
152
213
|
*/
|
|
153
214
|
parentId?: string | number;
|
|
154
215
|
/** Lucide icon name (kebab-case) to render next to the section title. */
|
|
@@ -168,6 +229,18 @@ export interface RelatedListProps {
|
|
|
168
229
|
* `invite_user` (`visible: "features.organization != false"`) hides when its
|
|
169
230
|
* predicate is false. `features`/`user` resolve from the ambient
|
|
170
231
|
* ExpressionProvider scope.
|
|
232
|
+
*
|
|
233
|
+
* The verdict fails CLOSED on a predicate that FAULTS (`throwOnError`), as
|
|
234
|
+
* every action `visible` leg does (objectui#11212, Rider 1 of objectui#4421):
|
|
235
|
+
* a precondition that cannot be evaluated — `current_user.can(…)` before the
|
|
236
|
+
* permissions payload has loaded, an unbound root — hides the button and is
|
|
237
|
+
* reported once, instead of showing an action whose guard is broken. This leg
|
|
238
|
+
* used to fail SOFT to `true`.
|
|
239
|
+
*
|
|
240
|
+
* Whether a gate is DECLARED at all is asked with `hasDeclaredVisibilityGate`,
|
|
241
|
+
* as every other member of the action family asks it (objectui#3812,
|
|
242
|
+
* objectui#11244), never by truthiness: `visible: false` is a declared gate and
|
|
243
|
+
* hides the button, while a blank predicate (`''`, whitespace) is no gate.
|
|
171
244
|
*/
|
|
172
245
|
export declare const RelatedToolbarButton: React.FC<{
|
|
173
246
|
action: RelatedRowActionDef;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RelatedList.d.ts","sourceRoot":"","sources":["../src/RelatedList.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"RelatedList.d.ts","sourceRoot":"","sources":["../src/RelatedList.tsx"],"names":[],"mappings":"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"}
|
|
@@ -12,7 +12,7 @@ export interface ThreadedRepliesProps {
|
|
|
12
12
|
parentItem: FeedItem;
|
|
13
13
|
/** Reply feed items (children) */
|
|
14
14
|
replies: FeedItem[];
|
|
15
|
-
/** Called when a reply is submitted */
|
|
15
|
+
/** Called when a reply is submitted. A rejection means it was not written: the draft is kept. */
|
|
16
16
|
onAddReply?: (parentId: string | number, text: string) => void | Promise<void>;
|
|
17
17
|
/** Whether to show the reply input */
|
|
18
18
|
showReplyInput?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThreadedReplies.d.ts","sourceRoot":"","sources":["../src/ThreadedReplies.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"ThreadedReplies.d.ts","sourceRoot":"","sources":["../src/ThreadedReplies.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAIjD,MAAM,WAAW,oBAAoB;IACnC,sCAAsC;IACtC,UAAU,EAAE,QAAQ,CAAC;IACrB,kCAAkC;IAClC,OAAO,EAAE,QAAQ,EAAE,CAAC;IACpB,iGAAiG;IACjG,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/E,sCAAsC;IACtC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA2BD;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAuH1D,CAAC"}
|
|
@@ -0,0 +1,142 @@
|
|
|
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
|
+
* Does this cell have anything to render? **THE** definition of emptiness on
|
|
10
|
+
* the `record:details` page (objectui#8376, widened to the whole package by
|
|
11
|
+
* objectui#8394).
|
|
12
|
+
*
|
|
13
|
+
* ## Readers
|
|
14
|
+
*
|
|
15
|
+
* Every band of the record page that draws a placeholder instead of a value, or
|
|
16
|
+
* omits a slot because there is no value, asks THIS — never its own
|
|
17
|
+
* `null | undefined | ''`:
|
|
18
|
+
*
|
|
19
|
+
* - `DetailSection` — `isEmptyValue` (the row filter behind `emptyCount`, the
|
|
20
|
+
* "Show N empty fields" toggle and the auto-hide heuristic), the `isEmpty`
|
|
21
|
+
* branch of `displayValue` (the muted em-dash + `No value` affordance), and
|
|
22
|
+
* `canCopy` (a row that says `No value` must not offer to copy it);
|
|
23
|
+
* - `HeaderHighlight` — the ADR-0085 highlight strip's `isEmpty`, the same
|
|
24
|
+
* em-dash affordance one band higher on the same screen;
|
|
25
|
+
* - `DetailView` — the `summaryFields` chips beside the page H1, BOTH the
|
|
26
|
+
* auto-detection that picks which field becomes a chip and the render that
|
|
27
|
+
* skips a valueless one. Those two must agree or the derivation spends the
|
|
28
|
+
* one status slot on a field the render then drops, and no chip appears;
|
|
29
|
+
* - `HistoryTimeline` — `formatDiffValue`'s `'—'` placeholder for an audit
|
|
30
|
+
* value;
|
|
31
|
+
* - `RecordMetaFooter` — whether `created_by` / `updated_by` is an actor at
|
|
32
|
+
* all (see the note at its call site: the footer normalizes at the READ,
|
|
33
|
+
* because the label, the `·` separator and the renderer are three consumers
|
|
34
|
+
* of one answer).
|
|
35
|
+
*
|
|
36
|
+
* They MUST agree. Before objectui#8350 / #8376 / #8394 each spelled the test
|
|
37
|
+
* out for itself, none trimmed, and the page contradicted itself in one
|
|
38
|
+
* screenful: the H1 called a whitespace-only field empty, the body grid painted
|
|
39
|
+
* a blank cell, the strip between them painted a blank chip. Raw tests that
|
|
40
|
+
* happen to agree can stop agreeing; one definition cannot.
|
|
41
|
+
*
|
|
42
|
+
* ## Why the scalar half DELEGATES (objectui#8350's authority)
|
|
43
|
+
*
|
|
44
|
+
* None of those tests TRIMMED, so `' '` counted as FILLED while
|
|
45
|
+
* `@object-ui/core`'s `recordDisplayValueAt` — the definition the page H1 and
|
|
46
|
+
* the `record:details` dedupe ladder both read — calls it EMPTY. The
|
|
47
|
+
* consequences were not cosmetic: a row painted a visually blank cell (the exact
|
|
48
|
+
* UI the em-dash exists to prevent), it escaped `emptyCount` so the toggle read
|
|
49
|
+
* one too low, and because `shouldAutoHideEmpty` only needs `filledCount > 0`
|
|
50
|
+
* ONE such value suppressed the all-empty skeleton and hid every genuinely empty
|
|
51
|
+
* row in its section. So the scalar answer is not re-spelled here: it is the
|
|
52
|
+
* authority's, and a `.trim()` written at a call site would be the second
|
|
53
|
+
* implementation that drifts next.
|
|
54
|
+
*
|
|
55
|
+
* ## Why the OBJECT half does NOT delegate — measured, not assumed
|
|
56
|
+
*
|
|
57
|
+
* `recordDisplayValueAt` answers "does this resolve to a NAME", so an object
|
|
58
|
+
* value goes through `displayNameOfEmbeddedObject` and is EMPTY whenever that
|
|
59
|
+
* Salesforce-style chain yields nothing. That is right for a title and WRONG for
|
|
60
|
+
* a cell: here an object value is handed to a TYPE-AWARE renderer that knows how
|
|
61
|
+
* to draw it. `{ latitude, longitude }` renders as coordinates
|
|
62
|
+
* (`LocationCellRenderer`), `{ street, city, … }` as a formatted postal address
|
|
63
|
+
* (`AddressCellRenderer`, objectui#4037), `['alpha','beta']` as select badges,
|
|
64
|
+
* an expanded `{ id, name }` reference through `LookupCellRenderer`'s own
|
|
65
|
+
* display chain, any other object as JSON — none of which carries a name-ish key
|
|
66
|
+
* in the general case, so delegating this half would replace populated cells
|
|
67
|
+
* with `No value`, drop them out of `filledCount`, and let auto-hide bury them.
|
|
68
|
+
* A POPULATED object is therefore a VALUE here.
|
|
69
|
+
*
|
|
70
|
+
* ## The one object shape that is NOT a value: `[]` (objectui#8474)
|
|
71
|
+
*
|
|
72
|
+
* That member now arrives from the SHARED FLOOR rather than from a clause
|
|
73
|
+
* written here — `isEmptyValue` in `@object-ui/core` (objectui#8496). The
|
|
74
|
+
* reasoning below is what MEASURED it, and it is kept because it is the reason
|
|
75
|
+
* the floor may be asked here at all; the four members themselves are no longer
|
|
76
|
+
* this file's to spell.
|
|
77
|
+
*
|
|
78
|
+
* Every example above is a POPULATED object. `typeof [] === 'object'`, so until
|
|
79
|
+
* objectui#8474 an EMPTY array took the same branch and was a value — and there
|
|
80
|
+
* the reasoning stops holding, because the type-aware renderer has nothing to
|
|
81
|
+
* draw. `SelectCellRenderer` tests `value == null || value === ''`, which `[]`
|
|
82
|
+
* passes, and then maps it over zero entries: the cell renders as
|
|
83
|
+
* `<div class="flex flex-wrap gap-1"></div>`, a visually blank cell — the exact
|
|
84
|
+
* UI the em-dash exists to prevent, reached through the function that exists to
|
|
85
|
+
* prevent it. And it brought the whole objectui#8376 triple with it: the row
|
|
86
|
+
* escaped `emptyCount` so the toggle read one too low, `canCopy` offered to copy
|
|
87
|
+
* it, and because `shouldAutoHideEmpty` only needs `filledCount > 0` a section
|
|
88
|
+
* whose one non-null value was `[]` auto-hid every genuinely empty row around it
|
|
89
|
+
* and rendered a lone label over a blank.
|
|
90
|
+
*
|
|
91
|
+
* ⚠️ The declared cost, measured rather than waved past: a `json`-family field
|
|
92
|
+
* holding `[]` used to render the literal two-character text `[]` through
|
|
93
|
+
* `JsonCellRenderer`, and now draws the `No value` placeholder. That is
|
|
94
|
+
* intended — "no items" is what the placeholder says — but it IS a render
|
|
95
|
+
* change, and it is pinned as one.
|
|
96
|
+
*
|
|
97
|
+
* ## Why `{}` is NOT included — measured on this surface, not argued by symmetry
|
|
98
|
+
*
|
|
99
|
+
* `{}` is a VALUE here, and that is a measurement rather than an oversight.
|
|
100
|
+
* Rendered in a real `DetailSection`, `{}` on a `json`, an `object` and a
|
|
101
|
+
* `location` field all draw the literal `{}` through `JsonCellRenderer`
|
|
102
|
+
* (`location` falls back to it when the lat/lng chain yields nothing) — a terse
|
|
103
|
+
* cell, but a DRAWN one. There is no blank cell, so there is no defect of the
|
|
104
|
+
* kind above to fix, and turning a visible `{}` into an em-dash would be a taste
|
|
105
|
+
* change dressed up as a bug fix.
|
|
106
|
+
*
|
|
107
|
+
* ⛔ And the shape that would sweep `{}` in is actively unsafe here:
|
|
108
|
+
* `Object.keys(value).length === 0` is ALSO true of `new Date(0)`, of a
|
|
109
|
+
* populated `Map`, of a populated `Set`, and of any class instance whose state
|
|
110
|
+
* sits behind getters (all four measured). Widening that way would call those
|
|
111
|
+
* EMPTY — a false-empty on values that render, strictly worse than the bug it
|
|
112
|
+
* set out to fix. So this function moves whitespace-only strings and empty
|
|
113
|
+
* arrays, and nothing else.
|
|
114
|
+
*
|
|
115
|
+
* ## Agreement with `RelatedList`'s local predicate (objectui#8459)
|
|
116
|
+
*
|
|
117
|
+
* `RelatedList.isValueEmpty` has drawn this finer line for some time, and
|
|
118
|
+
* objectui#8459 / PR #8476 measured it as the better-shaped answer for a grid,
|
|
119
|
+
* declining to delegate here BECAUSE of this hole. After objectui#8474 the two
|
|
120
|
+
* agree on every probe measured (`[]` empty; `{}`, `[1]`, `{ a: 1 }`, `0` and a
|
|
121
|
+
* `Date` all values). ⛔ Note the DIRECTION: the SHARED authority moved toward
|
|
122
|
+
* the local predicate. `RelatedList.isValueEmpty` is untouched and must stay
|
|
123
|
+
* that way — a grid column and a record row ask this at two granularities, and
|
|
124
|
+
* the local one is pinned in its own file.
|
|
125
|
+
*
|
|
126
|
+
* ## Not every emptiness question on this page is THIS question
|
|
127
|
+
*
|
|
128
|
+
* ⛔ Do not widen the reader list by pattern-matching on the shape of a test.
|
|
129
|
+
* `ConcurrentUpdateDialog`'s `formatValue` deliberately renders `''` as `""`
|
|
130
|
+
* rather than as a placeholder — a conflict dialog is reporting what is STORED,
|
|
131
|
+
* where "empty string" and "absent" are different facts the reader must be able
|
|
132
|
+
* to tell apart. Converging it would delete information rather than add it.
|
|
133
|
+
*
|
|
134
|
+
* Pinned end-to-end (DOM, not predicate) in
|
|
135
|
+
* `__tests__/DetailSection.emptinessAuthority-8376.test.tsx`,
|
|
136
|
+
* `__tests__/detailPage.emptinessAuthority-8394.test.tsx` and
|
|
137
|
+
* `__tests__/DetailSection.emptyArray-8474.test.tsx`, whose NON-REGRESSION
|
|
138
|
+
* cases are red for a wholesale delegation and red for an emptiness test that
|
|
139
|
+
* answers EMPTY for everything.
|
|
140
|
+
*/
|
|
141
|
+
export declare function hasCellValue(value: unknown): boolean;
|
|
142
|
+
//# sourceMappingURL=emptiness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emptiness.d.ts","sourceRoot":"","sources":["../src/emptiness.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CA0BpD"}
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
/**
|
|
9
9
|
* Field types the PLATFORM computes — the value is machine-owned and no user
|
|
10
|
-
* write is legitimate. They carry a `
|
|
10
|
+
* write is legitimate. They carry a `reference` for relational metadata but
|
|
11
11
|
* have no editor of their own.
|
|
12
12
|
*
|
|
13
13
|
* One set, three readers, so they cannot drift: `InlineFieldInput` renders them
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
* type: `plugin-form` lists both in each of its non-input sets, and this is the
|
|
27
27
|
* shape that was missing here. The gap was not academic — the reader that has
|
|
28
28
|
* no host gate in front of it is `InlineFieldInput`'s reference fallback
|
|
29
|
-
* (`!!field.
|
|
30
|
-
* exported public API, so a spec-spelled auto-number carrying a `
|
|
29
|
+
* (`!!field.reference && !TEXTUAL_REF_FALLBACK_TYPES.has(type)`), on
|
|
30
|
+
* exported public API, so a spec-spelled auto-number carrying a `reference`
|
|
31
31
|
* resolved into the RECORD PICKER — a list of records offered as replacements
|
|
32
32
|
* for a machine-generated identity. The editability half of the same report is
|
|
33
33
|
* held by the alias-aware shared exclusion since #4228; the two gates are a
|
|
@@ -73,6 +73,20 @@ export declare function isComputedFieldType(viewFieldType: unknown, objectFieldT
|
|
|
73
73
|
* widgets the record form uses, added deliberately so inline edit could preview,
|
|
74
74
|
* replace and remove files instead of showing a bare storage URL.
|
|
75
75
|
*
|
|
76
|
+
* `markdown` is exempt on the same footing (objectui#11541). The shared set
|
|
77
|
+
* excludes it among the "Heavy / full editors — better in the record form than
|
|
78
|
+
* a cell", which is again an argument about a CELL. #4228 kept it out of the
|
|
79
|
+
* detail row for the reason it recorded there: "a one-line text box is lossy".
|
|
80
|
+
* That box was the only editor the row then had for it — the terminal text
|
|
81
|
+
* input, which is one line, so the browser strips every line break from the
|
|
82
|
+
* value it is seeded with and the next keystroke writes the flattened text
|
|
83
|
+
* back. A markdown value is a plain string, so a MULTI-line editor loses
|
|
84
|
+
* nothing, and `InlineFieldInput` routes it to `TextAreaField`, the fields
|
|
85
|
+
* package's multi-line widget (the one a `textarea` field edits with in the
|
|
86
|
+
* record form and in a grid cell), never to that terminal input. The grid
|
|
87
|
+
* keeps the exclusion for `markdown`. `html` and
|
|
88
|
+
* `richtext` are not exempt: they stay excluded, unchanged.
|
|
89
|
+
*
|
|
76
90
|
* The credential and container members are excluded for a VALUE reason — masked
|
|
77
91
|
* on read, or object-shaped — and that argument transfers to the detail page
|
|
78
92
|
* verbatim, because the detail fallback is the same plain text input the grid's
|
|
@@ -105,6 +119,32 @@ export declare const DETAIL_ROUTED_INLINE_TYPES: Set<string>;
|
|
|
105
119
|
* locked: the exemption is consulted per type, before the union.
|
|
106
120
|
*/
|
|
107
121
|
export declare function isInlineExcludedDetailFieldType(viewFieldType: unknown, objectFieldType: unknown): boolean;
|
|
122
|
+
/**
|
|
123
|
+
* Is this row's cell drawn as a mask, given the type authored on the view entry
|
|
124
|
+
* and the type declared on the object schema?
|
|
125
|
+
*
|
|
126
|
+
* The rule itself is NOT restated here — it is `isMaskedFieldType()` from
|
|
127
|
+
* `@object-ui/fields`, the package that owns the mask registrations
|
|
128
|
+
* (objectui#8686). This file used to keep its own two-member copy of the
|
|
129
|
+
* masked types (objectui#8440), documented as a mirror with two accepted
|
|
130
|
+
* costs: a masked type added to the fields package would render masked and
|
|
131
|
+
* stay copy-interactive here, and `registerFieldRenderer('password', …)`
|
|
132
|
+
* could replace the mask at runtime without this copy seeing it. Reading the
|
|
133
|
+
* authority closes both: a type the fields package masks, declared or
|
|
134
|
+
* registered, refuses the copy here with no edit to this file. The same shape
|
|
135
|
+
* {@link isInlineExcludedDetailFieldType} already has for the write direction.
|
|
136
|
+
*
|
|
137
|
+
* **Narrow-only, like {@link isComputedFieldType} and
|
|
138
|
+
* {@link isInlineExcludedDetailFieldType}** — the answer is the UNION of the
|
|
139
|
+
* two, so an authored display `type` can withdraw the copy affordance but never
|
|
140
|
+
* restore it (objectui#3355). The direction matters here more than anywhere: an
|
|
141
|
+
* object column declared `secret` keeps its refusal even when a view authors
|
|
142
|
+
* `type: 'text'` over it, because a PRESENTATION override has no business
|
|
143
|
+
* widening access to a credential. The declared cost of the union is the mirror
|
|
144
|
+
* case — an object `text` column authored as `password` masks AND refuses the
|
|
145
|
+
* copy, which is the same answer the cell already gives.
|
|
146
|
+
*/
|
|
147
|
+
export declare function isMaskedDetailFieldType(viewFieldType: unknown, objectFieldType: unknown): boolean;
|
|
108
148
|
/**
|
|
109
149
|
* Object-metadata keys carried onto a detail-view field so the read cell and
|
|
110
150
|
* the inline editor see the SAME resolved field shape the object form does.
|
|
@@ -119,7 +159,7 @@ export declare function isInlineExcludedDetailFieldType(viewFieldType: unknown,
|
|
|
119
159
|
*
|
|
120
160
|
* Ordering is documentation only; the copy is key-by-key.
|
|
121
161
|
*/
|
|
122
|
-
export declare const ENRICHED_FIELD_METADATA_KEYS: readonly ["options", "currency", "currencyConfig", "precision", "scale", "min", "max", "step", "format", "widget", "dueLike", "multiple", "reference_field", "
|
|
162
|
+
export declare const ENRICHED_FIELD_METADATA_KEYS: readonly ["options", "currency", "currencyConfig", "precision", "scale", "useGrouping", "min", "max", "step", "format", "widget", "dueLike", "multiple", "reference_field", "displayField", "descriptionField", "idField", "allow_create", "allowCreate", "lookup_columns", "lookupColumns", "lookup_page_size", "lookupPageSize", "lookupFilters", "picker", "subtitle", "avatar_field", "avatarField", "depends_on", "dependsOn"];
|
|
123
163
|
/**
|
|
124
164
|
* Merge a detail-view field with its object-schema metadata.
|
|
125
165
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fieldEnrichment.d.ts","sourceRoot":"","sources":["../src/fieldEnrichment.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,0BAA0B,aAMrC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,OAAO,EACtB,eAAe,EAAE,OAAO,GACvB,OAAO,CAKT;AAED
|
|
1
|
+
{"version":3,"file":"fieldEnrichment.d.ts","sourceRoot":"","sources":["../src/fieldEnrichment.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,0BAA0B,aAMrC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,OAAO,EACtB,eAAe,EAAE,OAAO,GACvB,OAAO,CAKT;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,eAAO,MAAM,0BAA0B,aAQrC,CAAC;AAEH;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,+BAA+B,CAC7C,aAAa,EAAE,OAAO,EACtB,eAAe,EAAE,OAAO,GACvB,OAAO,CAET;AAQD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,uBAAuB,CACrC,aAAa,EAAE,OAAO,EACtB,eAAe,EAAE,OAAO,GACvB,OAAO,CAET;AAMD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,4BAA4B,qaAkD/B,CAAC;AAEX;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC9B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS,GAAG,IAAI,GACrD,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CA2BrB"}
|
|
@@ -0,0 +1,20 @@
|
|
|
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
|
+
/** The declared vocabulary, for tests and for callers that enumerate it. */
|
|
9
|
+
export declare const headerColorVocabulary: Readonly<Record<string, string>>;
|
|
10
|
+
/**
|
|
11
|
+
* Resolve an authored `headerColor` to a class the stylesheet actually
|
|
12
|
+
* carries, or `undefined` when there is none — never a concatenated guess.
|
|
13
|
+
*
|
|
14
|
+
* A value that is already a complete `bg-*` class is handed through
|
|
15
|
+
* untouched, exactly as `useRowColor` does. It then renders on the same terms
|
|
16
|
+
* as any `className` a schema carries: the host app's Tailwind build has to
|
|
17
|
+
* generate it.
|
|
18
|
+
*/
|
|
19
|
+
export declare function headerColorClass(headerColor: string | undefined): string | undefined;
|
|
20
|
+
//# sourceMappingURL=headerColor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"headerColor.d.ts","sourceRoot":"","sources":["../src/headerColor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA6DH,4EAA4E;AAC5E,eAAO,MAAM,qBAAqB,kCAAuB,CAAC;AAE1D;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAYpF"}
|