@ai-matrx/design-system 0.21.14 → 0.22.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 +37 -0
- package/dist/data-table/copy-helpers.d.cts +2 -1
- package/dist/data-table/copy-helpers.d.ts +2 -1
- package/dist/data-table/filter-engine.d.cts +2 -1
- package/dist/data-table/filter-engine.d.ts +2 -1
- package/dist/data-table/host.d.cts +2 -1
- package/dist/data-table/host.d.ts +2 -1
- package/dist/data-table/index.cjs +1525 -398
- package/dist/data-table/index.cjs.map +1 -1
- package/dist/data-table/index.d.cts +91 -3
- package/dist/data-table/index.d.ts +91 -3
- package/dist/data-table/index.js +1526 -395
- package/dist/data-table/index.js.map +1 -1
- package/dist/data-table/infer-filter.d.cts +2 -1
- package/dist/data-table/infer-filter.d.ts +2 -1
- package/dist/data-table/layered-filters.d.cts +2 -1
- package/dist/data-table/layered-filters.d.ts +2 -1
- package/dist/data-table/query-control.d.cts +2 -1
- package/dist/data-table/query-control.d.ts +2 -1
- package/dist/data-table/types.cjs.map +1 -1
- package/dist/data-table/types.d.cts +2 -1
- package/dist/data-table/types.d.ts +2 -1
- package/dist/data-table/url-state.d.cts +2 -1
- package/dist/data-table/url-state.d.ts +2 -1
- package/dist/data-table/xlsx.d.cts +2 -1
- package/dist/data-table/xlsx.d.ts +2 -1
- package/dist/field-formats/index.cjs +741 -0
- package/dist/field-formats/index.cjs.map +1 -0
- package/dist/field-formats/index.d.cts +45 -0
- package/dist/field-formats/index.d.ts +45 -0
- package/dist/field-formats/index.js +723 -0
- package/dist/field-formats/index.js.map +1 -0
- package/dist/types-BdbvlF9-.d.cts +204 -0
- package/dist/types-BdbvlF9-.d.ts +204 -0
- package/dist/{types-emLxze_m.d.ts → types-D-flTpK0.d.ts} +230 -1
- package/dist/{types-BgqIKbhq.d.cts → types-Sn249eoy.d.cts} +230 -1
- package/package.json +11 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ContentTransferReference } from './content-transfer.js';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { AiVariant, AiCustomSource, CopyExportConfig } from './data-table/copy-types.js';
|
|
4
|
+
import { b as FieldFormatConfig } from './types-BdbvlF9-.js';
|
|
4
5
|
|
|
5
6
|
type TableSearchRole = "id" | "name" | "description" | "other";
|
|
6
7
|
interface TableSearchScope {
|
|
@@ -80,6 +81,151 @@ declare function columnFiltersToLayeredRules(filters: ColumnFiltersState, fieldI
|
|
|
80
81
|
declare function layeredFilterMatchesValue(value: unknown, rule: LayeredFilterRule): boolean;
|
|
81
82
|
declare function layeredFilterRuleSummary(rule: LayeredFilterRule, fields: readonly LayeredFilterField[]): string;
|
|
82
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Table style — colors on a user data table, the Airtable way.
|
|
86
|
+
*
|
|
87
|
+
* WHAT IS ALLOWED, AND WHY ONLY THIS. A typed dataset is not a canvas; the
|
|
88
|
+
* platform already has Workbooks (Univer) for arbitrary per-cell formatting.
|
|
89
|
+
* Here, color carries MEANING and stays out of the data:
|
|
90
|
+
*
|
|
91
|
+
* 1. COLOR BY A COLUMN — a choice column's option colors (or a boolean's
|
|
92
|
+
* true/false) tint the row or that column's cells. Zero configuration:
|
|
93
|
+
* the Status column already knows "Blocked" is red.
|
|
94
|
+
* 2. RULES — "when Amount > 1000, tint the row amber". Evaluated live, so a
|
|
95
|
+
* tint is never stale.
|
|
96
|
+
* 3. MANUAL HIGHLIGHTS — a small palette on a cell, a row, or a column, for
|
|
97
|
+
* the "look at this one" gesture. The same palette the choice chips use,
|
|
98
|
+
* so the table never has two vocabularies of color.
|
|
99
|
+
*
|
|
100
|
+
* WHERE IT LIVES. This module is the MODEL only — pure, no React, no DOM, no
|
|
101
|
+
* network. Each consumer names its own home for the same document and writes it
|
|
102
|
+
* surgically BY PATH (`stylePath.*`), so two editors highlighting different
|
|
103
|
+
* cells never overwrite each other:
|
|
104
|
+
*
|
|
105
|
+
* - user data tables (`/data`): `udt_datasets.metadata.style`, written by
|
|
106
|
+
* `public.udt_set_table_style(p_table_id, p_path, p_value)`.
|
|
107
|
+
* - the record store: the table's saved view / Table settings document,
|
|
108
|
+
* written by `custom.table_style_set(p_table, p_path, p_value)`.
|
|
109
|
+
*
|
|
110
|
+
* Copy, export, agents and the data itself never see the style.
|
|
111
|
+
*
|
|
112
|
+
* PRECEDENCE (most deliberate wins): a manual cell highlight > a cell rule >
|
|
113
|
+
* color-by targeting cells > a manual column highlight, for the CELL; a manual
|
|
114
|
+
* row highlight > a row rule > color-by targeting rows, for the ROW. A cell
|
|
115
|
+
* tint always paints over the row tint underneath it.
|
|
116
|
+
*
|
|
117
|
+
* Pure module: no React, no DOM, no Supabase.
|
|
118
|
+
*/
|
|
119
|
+
declare const TABLE_STYLE_VERSION: 1;
|
|
120
|
+
/**
|
|
121
|
+
* The highlight palette.
|
|
122
|
+
*
|
|
123
|
+
* These are the SAME seven names the choice-chip palette uses minus "neutral"
|
|
124
|
+
* (which means "no color"), spelled out here so the model carries no import at
|
|
125
|
+
* all. Names, never raw hex: a name is legible on both grounds because each one
|
|
126
|
+
* ships its own `dark:` class below, and a retired name degrades to "no color"
|
|
127
|
+
* instead of to an unreadable swatch. A consumer that also draws choice chips
|
|
128
|
+
* must keep its chip palette on these names, or the table grows two vocabularies
|
|
129
|
+
* of color.
|
|
130
|
+
*/
|
|
131
|
+
declare const STYLE_COLORS: readonly ["slate", "green", "amber", "red", "blue", "violet", "teal"];
|
|
132
|
+
type StyleColor = (typeof STYLE_COLORS)[number];
|
|
133
|
+
declare function isStyleColor(v: unknown): v is StyleColor;
|
|
134
|
+
declare const COLOR_RULE_OPS: readonly ["is", "is_not", "contains", "is_empty", "not_empty", "is_true", "is_false", "gt", "gte", "lt", "lte"];
|
|
135
|
+
type ColorRuleOp = (typeof COLOR_RULE_OPS)[number];
|
|
136
|
+
/** Which ops take a value to compare against. */
|
|
137
|
+
declare const OPS_WITH_VALUE: readonly ColorRuleOp[];
|
|
138
|
+
declare const COLOR_RULE_OP_LABELS: Record<ColorRuleOp, string>;
|
|
139
|
+
type StyleTarget = "row" | "cell";
|
|
140
|
+
type ColorRule = {
|
|
141
|
+
id: string;
|
|
142
|
+
/** Machine field name the condition reads. */
|
|
143
|
+
field: string;
|
|
144
|
+
op: ColorRuleOp;
|
|
145
|
+
/** Compared as text for `is` / `is_not` / `contains`, as a number for gt/lt. */
|
|
146
|
+
value?: string;
|
|
147
|
+
color: StyleColor;
|
|
148
|
+
/** Tint the whole row, or only this column's cell. */
|
|
149
|
+
target: StyleTarget;
|
|
150
|
+
};
|
|
151
|
+
type ColorBy = {
|
|
152
|
+
field: string;
|
|
153
|
+
target: StyleTarget;
|
|
154
|
+
};
|
|
155
|
+
type TableStyle = {
|
|
156
|
+
version: typeof TABLE_STYLE_VERSION;
|
|
157
|
+
colorBy?: ColorBy | null;
|
|
158
|
+
rules?: ColorRule[];
|
|
159
|
+
/** Manual row highlights, by row id. */
|
|
160
|
+
rows?: Record<string, StyleColor>;
|
|
161
|
+
/** Manual cell highlights, by row id then field name. */
|
|
162
|
+
cells?: Record<string, Record<string, StyleColor>>;
|
|
163
|
+
/** Manual column highlights, by field name. */
|
|
164
|
+
columns?: Record<string, StyleColor>;
|
|
165
|
+
};
|
|
166
|
+
declare const EMPTY_TABLE_STYLE: TableStyle;
|
|
167
|
+
/** The conventional key the style document lives under on a table's own metadata. */
|
|
168
|
+
declare const TABLE_STYLE_METADATA_KEY = "style";
|
|
169
|
+
/** True when nothing in the style would paint anything. */
|
|
170
|
+
declare function tableStyleIsEmpty(style: TableStyle): boolean;
|
|
171
|
+
/**
|
|
172
|
+
* Read a style off table metadata. Tolerant by design: an unknown key, a
|
|
173
|
+
* retired color name or a malformed rule is dropped, never thrown, because a
|
|
174
|
+
* table must still render when its style is stale.
|
|
175
|
+
*/
|
|
176
|
+
declare function parseTableStyle(raw: unknown): TableStyle;
|
|
177
|
+
/** Style out of a table-metadata blob (or null / undefined). */
|
|
178
|
+
declare function tableStyleFromMetadata(metadata: unknown): TableStyle;
|
|
179
|
+
/** Does `value` satisfy `rule`? Text ops compare case-insensitively; number ops parse both sides. */
|
|
180
|
+
declare function evaluateRule(rule: ColorRule, value: unknown): boolean;
|
|
181
|
+
/**
|
|
182
|
+
* The color a choice / boolean column gives a value, for color-by. The caller
|
|
183
|
+
* supplies the lookup because option colors live on the resolved choice list
|
|
184
|
+
* (which may come from a structured list), not on the style.
|
|
185
|
+
*/
|
|
186
|
+
type ChoiceColorLookup = (fieldName: string, value: unknown) => StyleColor | undefined;
|
|
187
|
+
/**
|
|
188
|
+
* The color an option paints with. An option that DECLARED a color uses it; an
|
|
189
|
+
* option without one gets a stable color from its position in the list, so
|
|
190
|
+
* "color rows by Status" always paints something — Airtable assigns every
|
|
191
|
+
* option a color for the same reason. A column whose options were never
|
|
192
|
+
* colored would otherwise look like color-by did nothing at all.
|
|
193
|
+
*/
|
|
194
|
+
declare function colorForChoice(choices: readonly {
|
|
195
|
+
value: string;
|
|
196
|
+
color?: string;
|
|
197
|
+
}[] | undefined, value: unknown): StyleColor | undefined;
|
|
198
|
+
/**
|
|
199
|
+
* Boolean columns have no option list; color-by paints true green and leaves
|
|
200
|
+
* false untinted, which is the "done / not done" reading every checklist has.
|
|
201
|
+
*/
|
|
202
|
+
declare const BOOLEAN_TRUE_COLOR: StyleColor;
|
|
203
|
+
/** The tint for a whole row, or null for none. */
|
|
204
|
+
declare function resolveRowColor(style: TableStyle, row: {
|
|
205
|
+
id: string;
|
|
206
|
+
data: Record<string, unknown>;
|
|
207
|
+
}, choiceColorFor: ChoiceColorLookup): StyleColor | null;
|
|
208
|
+
/** The tint for one cell (painted over the row tint), or null for none. */
|
|
209
|
+
declare function resolveCellColor(style: TableStyle, row: {
|
|
210
|
+
id: string;
|
|
211
|
+
data: Record<string, unknown>;
|
|
212
|
+
}, fieldName: string, choiceColorFor: ChoiceColorLookup): StyleColor | null;
|
|
213
|
+
declare const ROW_TINT_CLASS: Record<StyleColor, string>;
|
|
214
|
+
declare const CELL_TINT_CLASS: Record<StyleColor, string>;
|
|
215
|
+
/** A solid swatch for palette menus. */
|
|
216
|
+
declare const SWATCH_CLASS: Record<StyleColor, string>;
|
|
217
|
+
declare const STYLE_COLOR_LABELS: Record<StyleColor, string>;
|
|
218
|
+
type StylePath = readonly string[];
|
|
219
|
+
declare const stylePath: {
|
|
220
|
+
colorBy: () => StylePath;
|
|
221
|
+
rules: () => StylePath;
|
|
222
|
+
row: (rowId: string) => StylePath;
|
|
223
|
+
cell: (rowId: string, fieldName: string) => StylePath;
|
|
224
|
+
column: (fieldName: string) => StylePath;
|
|
225
|
+
};
|
|
226
|
+
/** Apply a path write locally, so the grid repaints before the round trip returns. */
|
|
227
|
+
declare function applyStylePath(style: TableStyle, path: StylePath, value: unknown): TableStyle;
|
|
228
|
+
|
|
83
229
|
/** How a column's filter UI behaves. `auto` infers from sample values. */
|
|
84
230
|
type ColumnFilterKind = "auto" | "text" | "select" | "boolean" | "number" | false;
|
|
85
231
|
type SortDirection = "asc" | "desc";
|
|
@@ -259,6 +405,36 @@ interface MatrxColumnDef<T> {
|
|
|
259
405
|
/** Force non-navigable for this column. */
|
|
260
406
|
forbidden?: boolean | ((id: string, row: T) => boolean);
|
|
261
407
|
};
|
|
408
|
+
/**
|
|
409
|
+
* How this column's value READS — money, percent, a date style, decimal
|
|
410
|
+
* places. The vocabulary is the platform's one field-format registry
|
|
411
|
+
* (`@ai-matrx/design-system/field-formats`), the same `{id, options}` a user
|
|
412
|
+
* data table stores on its column and the record store stores on its Field,
|
|
413
|
+
* so `$1,234.56` is the same `$1,234.56` on every table in the product.
|
|
414
|
+
*
|
|
415
|
+
* A declarative format, not another render function, because a `cell`
|
|
416
|
+
* callback is invisible to everything else: with `format` the column also
|
|
417
|
+
* right-aligns itself, and a consumer's own `cell` asks the primitive for the
|
|
418
|
+
* same text through `formatColumnValue(col, value)` rather than growing a
|
|
419
|
+
* second money formatter beside this one.
|
|
420
|
+
*
|
|
421
|
+
* THE FALLBACK LAW travels with it: a value that does not fit the declared
|
|
422
|
+
* format is never blanked and never throws — it renders its base-type text in
|
|
423
|
+
* amber with the reason on hover, so the person SEES the mismatch.
|
|
424
|
+
*
|
|
425
|
+
* `cell` still wins when both are set.
|
|
426
|
+
*/
|
|
427
|
+
format?: FieldFormatConfig;
|
|
428
|
+
/**
|
|
429
|
+
* Keep this column in place while the rest of the table scrolls sideways.
|
|
430
|
+
*
|
|
431
|
+
* Only the LEADING RUN freezes, only from `sm:` up, and only when the widths
|
|
432
|
+
* the offsets need are known — `./frozen-columns.ts` says why each of those
|
|
433
|
+
* three is a rule and not a default. Give a frozen column an explicit
|
|
434
|
+
* `width`; without one the table declines to freeze anything rather than pin
|
|
435
|
+
* a column at a guessed offset.
|
|
436
|
+
*/
|
|
437
|
+
frozen?: boolean;
|
|
262
438
|
className?: string;
|
|
263
439
|
headerClassName?: string;
|
|
264
440
|
width?: string | number;
|
|
@@ -579,6 +755,17 @@ interface TableViewSnapshot {
|
|
|
579
755
|
hidden: string[];
|
|
580
756
|
widths?: Record<string, number>;
|
|
581
757
|
};
|
|
758
|
+
/**
|
|
759
|
+
* The view's COLORS — color-by-a-column, rules, and manual highlights
|
|
760
|
+
* (`./table-style.ts`). Optional so every view saved before colors existed
|
|
761
|
+
* still parses; absent means "this view paints nothing".
|
|
762
|
+
*
|
|
763
|
+
* Colors belong to the VIEW and not to the data, for the same reason the
|
|
764
|
+
* filters do: two people can read one table two ways, and neither reading is
|
|
765
|
+
* a fact about the records. That is also why this snapshot is the only place
|
|
766
|
+
* a style is carried — copy, export and agents read the rows, never this.
|
|
767
|
+
*/
|
|
768
|
+
style?: TableStyle;
|
|
582
769
|
}
|
|
583
770
|
/** Host port for durable named views. The host owns actor, tenancy and CRUD. */
|
|
584
771
|
interface TableSavedViewsProps {
|
|
@@ -855,6 +1042,28 @@ interface MatrxDataTableMobileCardControls {
|
|
|
855
1042
|
expandedDetail: ReactNode;
|
|
856
1043
|
}
|
|
857
1044
|
type MatrxDataTableDensity = "condensed" | "normal" | "spacious";
|
|
1045
|
+
/**
|
|
1046
|
+
* What the table needs in order to paint a `TableStyle` itself.
|
|
1047
|
+
*
|
|
1048
|
+
* `fieldOf` exists because a style names DATA fields ("tint the row when
|
|
1049
|
+
* `status` is Blocked") while the table addresses COLUMNS. In the common case
|
|
1050
|
+
* the column id IS the field name and the default is right; a table whose
|
|
1051
|
+
* column ids are decorated (`records-grid-notes`) maps them here.
|
|
1052
|
+
*/
|
|
1053
|
+
interface MatrxDataTableStyleConfig<T> {
|
|
1054
|
+
/** The style document. */
|
|
1055
|
+
style: TableStyle;
|
|
1056
|
+
/** The row's data as the rules read it. Defaults to the row itself. */
|
|
1057
|
+
documentOf?: (row: T) => Record<string, unknown>;
|
|
1058
|
+
/** Column id to the field name a rule would name. Defaults to identity. */
|
|
1059
|
+
fieldOf?: (columnId: string) => string;
|
|
1060
|
+
/**
|
|
1061
|
+
* The color a choice column's option paints with, for color-by. The consumer
|
|
1062
|
+
* supplies it because option colors live on the resolved option list, which
|
|
1063
|
+
* may come from a shared pick list this package cannot reach.
|
|
1064
|
+
*/
|
|
1065
|
+
choiceColorFor?: ChoiceColorLookup;
|
|
1066
|
+
}
|
|
858
1067
|
interface MatrxDataTableProps<T> {
|
|
859
1068
|
data: T[];
|
|
860
1069
|
columns: MatrxColumnDef<T>[];
|
|
@@ -964,6 +1173,26 @@ interface MatrxDataTableProps<T> {
|
|
|
964
1173
|
footerRows?: T[];
|
|
965
1174
|
/** Per-row presentation class, after canonical selection/highlight state. */
|
|
966
1175
|
rowClassName?: (row: T, index: number) => string | undefined;
|
|
1176
|
+
/**
|
|
1177
|
+
* Per-CELL presentation class, after the column's own static `className`.
|
|
1178
|
+
*
|
|
1179
|
+
* The primitive had `rowClassName` and a static per-column `className`, and
|
|
1180
|
+
* nothing in between — so every table that needed to say something about ONE
|
|
1181
|
+
* cell had to grow a `cell` render function and paint inside it, where the
|
|
1182
|
+
* table can no longer see it. This is the missing rung, and `tableStyle`
|
|
1183
|
+
* below is the declarative thing built on top of it.
|
|
1184
|
+
*/
|
|
1185
|
+
cellClassName?: (row: T, columnId: string, index: number) => string | undefined;
|
|
1186
|
+
/**
|
|
1187
|
+
* COLORS, declaratively — color by a column, rules, manual highlights.
|
|
1188
|
+
*
|
|
1189
|
+
* The model is `./table-style.ts`: one document, evaluated live on every
|
|
1190
|
+
* render so a tint is never stale, with a documented precedence between the
|
|
1191
|
+
* three ways a cell can earn a color. Pass the document and the table paints
|
|
1192
|
+
* itself; the consumer owns only where that document is STORED and how a
|
|
1193
|
+
* person edits it.
|
|
1194
|
+
*/
|
|
1195
|
+
tableStyle?: MatrxDataTableStyleConfig<T>;
|
|
967
1196
|
/** Highlight an index in the currently rendered page without selecting it. */
|
|
968
1197
|
highlightedIndex?: number | undefined;
|
|
969
1198
|
/** Receives the complete visible local view after local processing, before paging. Attaching after absence receives one snapshot; callback identity changes alone do not notify. */
|
|
@@ -1029,4 +1258,4 @@ interface MatrxDataTableProps<T> {
|
|
|
1029
1258
|
onRowOpen?: (row: T) => void;
|
|
1030
1259
|
}
|
|
1031
1260
|
|
|
1032
|
-
export {
|
|
1261
|
+
export { TABLE_STYLE_METADATA_KEY as $, type AnyOfColumnSearch as A, BOOLEAN_TRUE_COLOR as B, type ColumnFiltersState as C, type MatrxDataTableHierarchyMove as D, EMPTY_TABLE_STYLE as E, type MatrxDataTableMobileCardControls as F, type MatrxDataTableQueryControl as G, type MatrxDataTableSelectionConfig as H, type MatrxDataTableSourceProcessing as I, type MatrxDataTableStyleConfig as J, type MatrxDataTableToolbar as K, type LayeredFilterRule as L, type MatrxColumnDef as M, type MatrxDataTableUrlStateConfig as N, type MatrxDataTableWindowConfig as O, type MatrxTablePagination as P, OPS_WITH_VALUE as Q, ROW_TINT_CLASS as R, type SortState as S, type TableSearchMatchMode as T, STYLE_COLORS as U, STYLE_COLOR_LABELS as V, SWATCH_CLASS as W, type SortDirection as X, type StyleColor as Y, type StylePath as Z, type StyleTarget as _, type ColumnFilterValue as a, TABLE_STYLE_VERSION as a0, type TableRankedSearchOptions as a1, type TableSearchRole as a2, type TableSearchScope as a3, type TableStyle as a4, type TableViewQuery as a5, type TextFilterMode as a6, type ToolbarFacet as a7, applyStylePath as a8, colorForChoice as a9, evaluateRule as aa, inferTableSearchRole as ab, isStyleColor as ac, parseTableStyle as ad, rankTableSearchRows as ae, resolveCellColor as af, resolveRowColor as ag, resolveTableSearchScopes as ah, stylePath as ai, tableStyleFromMetadata as aj, tableStyleIsEmpty as ak, LAYERED_FILTER_OPERATORS as al, LAYERED_FILTER_OPERATOR_LABELS as am, type LayeredFilterField as an, type LayeredFilterOperator as ao, columnFiltersToLayeredRules as ap, completeLayeredFilterRules as aq, decodeLayeredFilterRules as ar, encodeLayeredFilterRules as as, isCompleteLayeredFilterRule as at, isLayeredFilterOperator as au, layeredFilterMatchesValue as av, layeredFilterNeedsValue as aw, layeredFilterRuleSummary as ax, operatorsForLayeredField as ay, type TableSavedViewsProps as b, type MatrxDataTableRecordControls as c, type MatrxDataTableDensity as d, type MatrxDataTableQueryState as e, type ColumnFilterKind as f, type MatrxDataTableCopyConfig as g, type MatrxDataTableProps as h, type TableViewSnapshot as i, type ColumnMarker as j, CELL_TINT_CLASS as k, COLOR_RULE_OPS as l, COLOR_RULE_OP_LABELS as m, type CellEditType as n, type CellEditsMap as o, type ChoiceColorLookup as p, type ColorBy as q, type ColorRule as r, type ColorRuleOp as s, type MatrxDataTableContextMenuConfig as t, type MatrxDataTableDetailConfig as u, type MatrxDataTableEditConfig as v, type MatrxDataTableEmptyState as w, type MatrxDataTableExpandedDetailConfig as x, type MatrxDataTableFilterUi as y, type MatrxDataTableHierarchyConfig as z };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ContentTransferReference } from './content-transfer.cjs';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
3
|
import { AiVariant, AiCustomSource, CopyExportConfig } from './data-table/copy-types.cjs';
|
|
4
|
+
import { b as FieldFormatConfig } from './types-BdbvlF9-.cjs';
|
|
4
5
|
|
|
5
6
|
type TableSearchRole = "id" | "name" | "description" | "other";
|
|
6
7
|
interface TableSearchScope {
|
|
@@ -80,6 +81,151 @@ declare function columnFiltersToLayeredRules(filters: ColumnFiltersState, fieldI
|
|
|
80
81
|
declare function layeredFilterMatchesValue(value: unknown, rule: LayeredFilterRule): boolean;
|
|
81
82
|
declare function layeredFilterRuleSummary(rule: LayeredFilterRule, fields: readonly LayeredFilterField[]): string;
|
|
82
83
|
|
|
84
|
+
/**
|
|
85
|
+
* Table style — colors on a user data table, the Airtable way.
|
|
86
|
+
*
|
|
87
|
+
* WHAT IS ALLOWED, AND WHY ONLY THIS. A typed dataset is not a canvas; the
|
|
88
|
+
* platform already has Workbooks (Univer) for arbitrary per-cell formatting.
|
|
89
|
+
* Here, color carries MEANING and stays out of the data:
|
|
90
|
+
*
|
|
91
|
+
* 1. COLOR BY A COLUMN — a choice column's option colors (or a boolean's
|
|
92
|
+
* true/false) tint the row or that column's cells. Zero configuration:
|
|
93
|
+
* the Status column already knows "Blocked" is red.
|
|
94
|
+
* 2. RULES — "when Amount > 1000, tint the row amber". Evaluated live, so a
|
|
95
|
+
* tint is never stale.
|
|
96
|
+
* 3. MANUAL HIGHLIGHTS — a small palette on a cell, a row, or a column, for
|
|
97
|
+
* the "look at this one" gesture. The same palette the choice chips use,
|
|
98
|
+
* so the table never has two vocabularies of color.
|
|
99
|
+
*
|
|
100
|
+
* WHERE IT LIVES. This module is the MODEL only — pure, no React, no DOM, no
|
|
101
|
+
* network. Each consumer names its own home for the same document and writes it
|
|
102
|
+
* surgically BY PATH (`stylePath.*`), so two editors highlighting different
|
|
103
|
+
* cells never overwrite each other:
|
|
104
|
+
*
|
|
105
|
+
* - user data tables (`/data`): `udt_datasets.metadata.style`, written by
|
|
106
|
+
* `public.udt_set_table_style(p_table_id, p_path, p_value)`.
|
|
107
|
+
* - the record store: the table's saved view / Table settings document,
|
|
108
|
+
* written by `custom.table_style_set(p_table, p_path, p_value)`.
|
|
109
|
+
*
|
|
110
|
+
* Copy, export, agents and the data itself never see the style.
|
|
111
|
+
*
|
|
112
|
+
* PRECEDENCE (most deliberate wins): a manual cell highlight > a cell rule >
|
|
113
|
+
* color-by targeting cells > a manual column highlight, for the CELL; a manual
|
|
114
|
+
* row highlight > a row rule > color-by targeting rows, for the ROW. A cell
|
|
115
|
+
* tint always paints over the row tint underneath it.
|
|
116
|
+
*
|
|
117
|
+
* Pure module: no React, no DOM, no Supabase.
|
|
118
|
+
*/
|
|
119
|
+
declare const TABLE_STYLE_VERSION: 1;
|
|
120
|
+
/**
|
|
121
|
+
* The highlight palette.
|
|
122
|
+
*
|
|
123
|
+
* These are the SAME seven names the choice-chip palette uses minus "neutral"
|
|
124
|
+
* (which means "no color"), spelled out here so the model carries no import at
|
|
125
|
+
* all. Names, never raw hex: a name is legible on both grounds because each one
|
|
126
|
+
* ships its own `dark:` class below, and a retired name degrades to "no color"
|
|
127
|
+
* instead of to an unreadable swatch. A consumer that also draws choice chips
|
|
128
|
+
* must keep its chip palette on these names, or the table grows two vocabularies
|
|
129
|
+
* of color.
|
|
130
|
+
*/
|
|
131
|
+
declare const STYLE_COLORS: readonly ["slate", "green", "amber", "red", "blue", "violet", "teal"];
|
|
132
|
+
type StyleColor = (typeof STYLE_COLORS)[number];
|
|
133
|
+
declare function isStyleColor(v: unknown): v is StyleColor;
|
|
134
|
+
declare const COLOR_RULE_OPS: readonly ["is", "is_not", "contains", "is_empty", "not_empty", "is_true", "is_false", "gt", "gte", "lt", "lte"];
|
|
135
|
+
type ColorRuleOp = (typeof COLOR_RULE_OPS)[number];
|
|
136
|
+
/** Which ops take a value to compare against. */
|
|
137
|
+
declare const OPS_WITH_VALUE: readonly ColorRuleOp[];
|
|
138
|
+
declare const COLOR_RULE_OP_LABELS: Record<ColorRuleOp, string>;
|
|
139
|
+
type StyleTarget = "row" | "cell";
|
|
140
|
+
type ColorRule = {
|
|
141
|
+
id: string;
|
|
142
|
+
/** Machine field name the condition reads. */
|
|
143
|
+
field: string;
|
|
144
|
+
op: ColorRuleOp;
|
|
145
|
+
/** Compared as text for `is` / `is_not` / `contains`, as a number for gt/lt. */
|
|
146
|
+
value?: string;
|
|
147
|
+
color: StyleColor;
|
|
148
|
+
/** Tint the whole row, or only this column's cell. */
|
|
149
|
+
target: StyleTarget;
|
|
150
|
+
};
|
|
151
|
+
type ColorBy = {
|
|
152
|
+
field: string;
|
|
153
|
+
target: StyleTarget;
|
|
154
|
+
};
|
|
155
|
+
type TableStyle = {
|
|
156
|
+
version: typeof TABLE_STYLE_VERSION;
|
|
157
|
+
colorBy?: ColorBy | null;
|
|
158
|
+
rules?: ColorRule[];
|
|
159
|
+
/** Manual row highlights, by row id. */
|
|
160
|
+
rows?: Record<string, StyleColor>;
|
|
161
|
+
/** Manual cell highlights, by row id then field name. */
|
|
162
|
+
cells?: Record<string, Record<string, StyleColor>>;
|
|
163
|
+
/** Manual column highlights, by field name. */
|
|
164
|
+
columns?: Record<string, StyleColor>;
|
|
165
|
+
};
|
|
166
|
+
declare const EMPTY_TABLE_STYLE: TableStyle;
|
|
167
|
+
/** The conventional key the style document lives under on a table's own metadata. */
|
|
168
|
+
declare const TABLE_STYLE_METADATA_KEY = "style";
|
|
169
|
+
/** True when nothing in the style would paint anything. */
|
|
170
|
+
declare function tableStyleIsEmpty(style: TableStyle): boolean;
|
|
171
|
+
/**
|
|
172
|
+
* Read a style off table metadata. Tolerant by design: an unknown key, a
|
|
173
|
+
* retired color name or a malformed rule is dropped, never thrown, because a
|
|
174
|
+
* table must still render when its style is stale.
|
|
175
|
+
*/
|
|
176
|
+
declare function parseTableStyle(raw: unknown): TableStyle;
|
|
177
|
+
/** Style out of a table-metadata blob (or null / undefined). */
|
|
178
|
+
declare function tableStyleFromMetadata(metadata: unknown): TableStyle;
|
|
179
|
+
/** Does `value` satisfy `rule`? Text ops compare case-insensitively; number ops parse both sides. */
|
|
180
|
+
declare function evaluateRule(rule: ColorRule, value: unknown): boolean;
|
|
181
|
+
/**
|
|
182
|
+
* The color a choice / boolean column gives a value, for color-by. The caller
|
|
183
|
+
* supplies the lookup because option colors live on the resolved choice list
|
|
184
|
+
* (which may come from a structured list), not on the style.
|
|
185
|
+
*/
|
|
186
|
+
type ChoiceColorLookup = (fieldName: string, value: unknown) => StyleColor | undefined;
|
|
187
|
+
/**
|
|
188
|
+
* The color an option paints with. An option that DECLARED a color uses it; an
|
|
189
|
+
* option without one gets a stable color from its position in the list, so
|
|
190
|
+
* "color rows by Status" always paints something — Airtable assigns every
|
|
191
|
+
* option a color for the same reason. A column whose options were never
|
|
192
|
+
* colored would otherwise look like color-by did nothing at all.
|
|
193
|
+
*/
|
|
194
|
+
declare function colorForChoice(choices: readonly {
|
|
195
|
+
value: string;
|
|
196
|
+
color?: string;
|
|
197
|
+
}[] | undefined, value: unknown): StyleColor | undefined;
|
|
198
|
+
/**
|
|
199
|
+
* Boolean columns have no option list; color-by paints true green and leaves
|
|
200
|
+
* false untinted, which is the "done / not done" reading every checklist has.
|
|
201
|
+
*/
|
|
202
|
+
declare const BOOLEAN_TRUE_COLOR: StyleColor;
|
|
203
|
+
/** The tint for a whole row, or null for none. */
|
|
204
|
+
declare function resolveRowColor(style: TableStyle, row: {
|
|
205
|
+
id: string;
|
|
206
|
+
data: Record<string, unknown>;
|
|
207
|
+
}, choiceColorFor: ChoiceColorLookup): StyleColor | null;
|
|
208
|
+
/** The tint for one cell (painted over the row tint), or null for none. */
|
|
209
|
+
declare function resolveCellColor(style: TableStyle, row: {
|
|
210
|
+
id: string;
|
|
211
|
+
data: Record<string, unknown>;
|
|
212
|
+
}, fieldName: string, choiceColorFor: ChoiceColorLookup): StyleColor | null;
|
|
213
|
+
declare const ROW_TINT_CLASS: Record<StyleColor, string>;
|
|
214
|
+
declare const CELL_TINT_CLASS: Record<StyleColor, string>;
|
|
215
|
+
/** A solid swatch for palette menus. */
|
|
216
|
+
declare const SWATCH_CLASS: Record<StyleColor, string>;
|
|
217
|
+
declare const STYLE_COLOR_LABELS: Record<StyleColor, string>;
|
|
218
|
+
type StylePath = readonly string[];
|
|
219
|
+
declare const stylePath: {
|
|
220
|
+
colorBy: () => StylePath;
|
|
221
|
+
rules: () => StylePath;
|
|
222
|
+
row: (rowId: string) => StylePath;
|
|
223
|
+
cell: (rowId: string, fieldName: string) => StylePath;
|
|
224
|
+
column: (fieldName: string) => StylePath;
|
|
225
|
+
};
|
|
226
|
+
/** Apply a path write locally, so the grid repaints before the round trip returns. */
|
|
227
|
+
declare function applyStylePath(style: TableStyle, path: StylePath, value: unknown): TableStyle;
|
|
228
|
+
|
|
83
229
|
/** How a column's filter UI behaves. `auto` infers from sample values. */
|
|
84
230
|
type ColumnFilterKind = "auto" | "text" | "select" | "boolean" | "number" | false;
|
|
85
231
|
type SortDirection = "asc" | "desc";
|
|
@@ -259,6 +405,36 @@ interface MatrxColumnDef<T> {
|
|
|
259
405
|
/** Force non-navigable for this column. */
|
|
260
406
|
forbidden?: boolean | ((id: string, row: T) => boolean);
|
|
261
407
|
};
|
|
408
|
+
/**
|
|
409
|
+
* How this column's value READS — money, percent, a date style, decimal
|
|
410
|
+
* places. The vocabulary is the platform's one field-format registry
|
|
411
|
+
* (`@ai-matrx/design-system/field-formats`), the same `{id, options}` a user
|
|
412
|
+
* data table stores on its column and the record store stores on its Field,
|
|
413
|
+
* so `$1,234.56` is the same `$1,234.56` on every table in the product.
|
|
414
|
+
*
|
|
415
|
+
* A declarative format, not another render function, because a `cell`
|
|
416
|
+
* callback is invisible to everything else: with `format` the column also
|
|
417
|
+
* right-aligns itself, and a consumer's own `cell` asks the primitive for the
|
|
418
|
+
* same text through `formatColumnValue(col, value)` rather than growing a
|
|
419
|
+
* second money formatter beside this one.
|
|
420
|
+
*
|
|
421
|
+
* THE FALLBACK LAW travels with it: a value that does not fit the declared
|
|
422
|
+
* format is never blanked and never throws — it renders its base-type text in
|
|
423
|
+
* amber with the reason on hover, so the person SEES the mismatch.
|
|
424
|
+
*
|
|
425
|
+
* `cell` still wins when both are set.
|
|
426
|
+
*/
|
|
427
|
+
format?: FieldFormatConfig;
|
|
428
|
+
/**
|
|
429
|
+
* Keep this column in place while the rest of the table scrolls sideways.
|
|
430
|
+
*
|
|
431
|
+
* Only the LEADING RUN freezes, only from `sm:` up, and only when the widths
|
|
432
|
+
* the offsets need are known — `./frozen-columns.ts` says why each of those
|
|
433
|
+
* three is a rule and not a default. Give a frozen column an explicit
|
|
434
|
+
* `width`; without one the table declines to freeze anything rather than pin
|
|
435
|
+
* a column at a guessed offset.
|
|
436
|
+
*/
|
|
437
|
+
frozen?: boolean;
|
|
262
438
|
className?: string;
|
|
263
439
|
headerClassName?: string;
|
|
264
440
|
width?: string | number;
|
|
@@ -579,6 +755,17 @@ interface TableViewSnapshot {
|
|
|
579
755
|
hidden: string[];
|
|
580
756
|
widths?: Record<string, number>;
|
|
581
757
|
};
|
|
758
|
+
/**
|
|
759
|
+
* The view's COLORS — color-by-a-column, rules, and manual highlights
|
|
760
|
+
* (`./table-style.ts`). Optional so every view saved before colors existed
|
|
761
|
+
* still parses; absent means "this view paints nothing".
|
|
762
|
+
*
|
|
763
|
+
* Colors belong to the VIEW and not to the data, for the same reason the
|
|
764
|
+
* filters do: two people can read one table two ways, and neither reading is
|
|
765
|
+
* a fact about the records. That is also why this snapshot is the only place
|
|
766
|
+
* a style is carried — copy, export and agents read the rows, never this.
|
|
767
|
+
*/
|
|
768
|
+
style?: TableStyle;
|
|
582
769
|
}
|
|
583
770
|
/** Host port for durable named views. The host owns actor, tenancy and CRUD. */
|
|
584
771
|
interface TableSavedViewsProps {
|
|
@@ -855,6 +1042,28 @@ interface MatrxDataTableMobileCardControls {
|
|
|
855
1042
|
expandedDetail: ReactNode;
|
|
856
1043
|
}
|
|
857
1044
|
type MatrxDataTableDensity = "condensed" | "normal" | "spacious";
|
|
1045
|
+
/**
|
|
1046
|
+
* What the table needs in order to paint a `TableStyle` itself.
|
|
1047
|
+
*
|
|
1048
|
+
* `fieldOf` exists because a style names DATA fields ("tint the row when
|
|
1049
|
+
* `status` is Blocked") while the table addresses COLUMNS. In the common case
|
|
1050
|
+
* the column id IS the field name and the default is right; a table whose
|
|
1051
|
+
* column ids are decorated (`records-grid-notes`) maps them here.
|
|
1052
|
+
*/
|
|
1053
|
+
interface MatrxDataTableStyleConfig<T> {
|
|
1054
|
+
/** The style document. */
|
|
1055
|
+
style: TableStyle;
|
|
1056
|
+
/** The row's data as the rules read it. Defaults to the row itself. */
|
|
1057
|
+
documentOf?: (row: T) => Record<string, unknown>;
|
|
1058
|
+
/** Column id to the field name a rule would name. Defaults to identity. */
|
|
1059
|
+
fieldOf?: (columnId: string) => string;
|
|
1060
|
+
/**
|
|
1061
|
+
* The color a choice column's option paints with, for color-by. The consumer
|
|
1062
|
+
* supplies it because option colors live on the resolved option list, which
|
|
1063
|
+
* may come from a shared pick list this package cannot reach.
|
|
1064
|
+
*/
|
|
1065
|
+
choiceColorFor?: ChoiceColorLookup;
|
|
1066
|
+
}
|
|
858
1067
|
interface MatrxDataTableProps<T> {
|
|
859
1068
|
data: T[];
|
|
860
1069
|
columns: MatrxColumnDef<T>[];
|
|
@@ -964,6 +1173,26 @@ interface MatrxDataTableProps<T> {
|
|
|
964
1173
|
footerRows?: T[];
|
|
965
1174
|
/** Per-row presentation class, after canonical selection/highlight state. */
|
|
966
1175
|
rowClassName?: (row: T, index: number) => string | undefined;
|
|
1176
|
+
/**
|
|
1177
|
+
* Per-CELL presentation class, after the column's own static `className`.
|
|
1178
|
+
*
|
|
1179
|
+
* The primitive had `rowClassName` and a static per-column `className`, and
|
|
1180
|
+
* nothing in between — so every table that needed to say something about ONE
|
|
1181
|
+
* cell had to grow a `cell` render function and paint inside it, where the
|
|
1182
|
+
* table can no longer see it. This is the missing rung, and `tableStyle`
|
|
1183
|
+
* below is the declarative thing built on top of it.
|
|
1184
|
+
*/
|
|
1185
|
+
cellClassName?: (row: T, columnId: string, index: number) => string | undefined;
|
|
1186
|
+
/**
|
|
1187
|
+
* COLORS, declaratively — color by a column, rules, manual highlights.
|
|
1188
|
+
*
|
|
1189
|
+
* The model is `./table-style.ts`: one document, evaluated live on every
|
|
1190
|
+
* render so a tint is never stale, with a documented precedence between the
|
|
1191
|
+
* three ways a cell can earn a color. Pass the document and the table paints
|
|
1192
|
+
* itself; the consumer owns only where that document is STORED and how a
|
|
1193
|
+
* person edits it.
|
|
1194
|
+
*/
|
|
1195
|
+
tableStyle?: MatrxDataTableStyleConfig<T>;
|
|
967
1196
|
/** Highlight an index in the currently rendered page without selecting it. */
|
|
968
1197
|
highlightedIndex?: number | undefined;
|
|
969
1198
|
/** Receives the complete visible local view after local processing, before paging. Attaching after absence receives one snapshot; callback identity changes alone do not notify. */
|
|
@@ -1029,4 +1258,4 @@ interface MatrxDataTableProps<T> {
|
|
|
1029
1258
|
onRowOpen?: (row: T) => void;
|
|
1030
1259
|
}
|
|
1031
1260
|
|
|
1032
|
-
export {
|
|
1261
|
+
export { TABLE_STYLE_METADATA_KEY as $, type AnyOfColumnSearch as A, BOOLEAN_TRUE_COLOR as B, type ColumnFiltersState as C, type MatrxDataTableHierarchyMove as D, EMPTY_TABLE_STYLE as E, type MatrxDataTableMobileCardControls as F, type MatrxDataTableQueryControl as G, type MatrxDataTableSelectionConfig as H, type MatrxDataTableSourceProcessing as I, type MatrxDataTableStyleConfig as J, type MatrxDataTableToolbar as K, type LayeredFilterRule as L, type MatrxColumnDef as M, type MatrxDataTableUrlStateConfig as N, type MatrxDataTableWindowConfig as O, type MatrxTablePagination as P, OPS_WITH_VALUE as Q, ROW_TINT_CLASS as R, type SortState as S, type TableSearchMatchMode as T, STYLE_COLORS as U, STYLE_COLOR_LABELS as V, SWATCH_CLASS as W, type SortDirection as X, type StyleColor as Y, type StylePath as Z, type StyleTarget as _, type ColumnFilterValue as a, TABLE_STYLE_VERSION as a0, type TableRankedSearchOptions as a1, type TableSearchRole as a2, type TableSearchScope as a3, type TableStyle as a4, type TableViewQuery as a5, type TextFilterMode as a6, type ToolbarFacet as a7, applyStylePath as a8, colorForChoice as a9, evaluateRule as aa, inferTableSearchRole as ab, isStyleColor as ac, parseTableStyle as ad, rankTableSearchRows as ae, resolveCellColor as af, resolveRowColor as ag, resolveTableSearchScopes as ah, stylePath as ai, tableStyleFromMetadata as aj, tableStyleIsEmpty as ak, LAYERED_FILTER_OPERATORS as al, LAYERED_FILTER_OPERATOR_LABELS as am, type LayeredFilterField as an, type LayeredFilterOperator as ao, columnFiltersToLayeredRules as ap, completeLayeredFilterRules as aq, decodeLayeredFilterRules as ar, encodeLayeredFilterRules as as, isCompleteLayeredFilterRule as at, isLayeredFilterOperator as au, layeredFilterMatchesValue as av, layeredFilterNeedsValue as aw, layeredFilterRuleSummary as ax, operatorsForLayeredField as ay, type TableSavedViewsProps as b, type MatrxDataTableRecordControls as c, type MatrxDataTableDensity as d, type MatrxDataTableQueryState as e, type ColumnFilterKind as f, type MatrxDataTableCopyConfig as g, type MatrxDataTableProps as h, type TableViewSnapshot as i, type ColumnMarker as j, CELL_TINT_CLASS as k, COLOR_RULE_OPS as l, COLOR_RULE_OP_LABELS as m, type CellEditType as n, type CellEditsMap as o, type ChoiceColorLookup as p, type ColorBy as q, type ColorRule as r, type ColorRuleOp as s, type MatrxDataTableContextMenuConfig as t, type MatrxDataTableDetailConfig as u, type MatrxDataTableEditConfig as v, type MatrxDataTableEmptyState as w, type MatrxDataTableExpandedDetailConfig as x, type MatrxDataTableFilterUi as y, type MatrxDataTableHierarchyConfig as z };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-matrx/design-system",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.22.0",
|
|
4
4
|
"description": "AI Matrx semantic React primitives shared across Vite, Next.js, desktop, and customer-built applications.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -78,6 +78,16 @@
|
|
|
78
78
|
"default": "./dist/data-table/index.cjs"
|
|
79
79
|
}
|
|
80
80
|
},
|
|
81
|
+
"./field-formats": {
|
|
82
|
+
"import": {
|
|
83
|
+
"types": "./dist/field-formats/index.d.ts",
|
|
84
|
+
"default": "./dist/field-formats/index.js"
|
|
85
|
+
},
|
|
86
|
+
"require": {
|
|
87
|
+
"types": "./dist/field-formats/index.d.cts",
|
|
88
|
+
"default": "./dist/field-formats/index.cjs"
|
|
89
|
+
}
|
|
90
|
+
},
|
|
81
91
|
"./data-table/host": {
|
|
82
92
|
"import": {
|
|
83
93
|
"types": "./dist/data-table/host.d.ts",
|