@pythia-software/query-table-ui 0.2.0 → 0.4.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/README.md +31 -0
- package/dist/FormulaEditor-YCPICDIH.js +251 -0
- package/dist/FormulaEditor-YCPICDIH.js.map +1 -0
- package/dist/index.d.ts +23 -4
- package/dist/index.js +1612 -477
- package/dist/index.js.map +1 -1
- package/dist/theme.css +566 -1
- package/dist/theme.css.map +1 -1
- package/package.json +9 -3
package/README.md
CHANGED
|
@@ -55,6 +55,11 @@ current query, including a saved default query. Configure `useQueryTable` with
|
|
|
55
55
|
`syncUrl: true` so recipients load shared query URLs. Query tokens are encoded,
|
|
56
56
|
not encrypted, and may contain raw filter values.
|
|
57
57
|
|
|
58
|
+
`SelectionToolbar` action callbacks receive `(selectedIds, selection)`, so
|
|
59
|
+
consumer-owned bulk actions can call `selection.replace(ids)` or
|
|
60
|
+
`selection.retain(ids)` atomically. Existing callbacks that use only the first
|
|
61
|
+
argument remain compatible.
|
|
62
|
+
|
|
58
63
|
## Mobile behavior
|
|
59
64
|
|
|
60
65
|
The bundled theme keeps the table as a horizontally scrollable grid on narrow
|
|
@@ -72,3 +77,29 @@ providing their own responsive and touch-target styles.
|
|
|
72
77
|
|
|
73
78
|
See the [repository README](https://github.com/Pythia-Software/query-table#readme)
|
|
74
79
|
for customization and backend integration details.
|
|
80
|
+
|
|
81
|
+
## SELECT editor
|
|
82
|
+
|
|
83
|
+
`QueryBuilder` includes an **Edit columns** action. The exported `SelectColumnEditor` also accepts `{ api, onClose }` for standalone use. It supports draft column ordering, a searchable catalogue, sampled value frequencies, and a lazy-loaded CodeMirror formula editor with grouped live previews and regex inspection. Shared-definition saves and query-layout application are separate actions.
|
|
84
|
+
|
|
85
|
+
### Filter value presentation
|
|
86
|
+
|
|
87
|
+
Queries keep stable string keys while consumers can display names and rich badges.
|
|
88
|
+
Static options accept either strings (the existing API) or `{ value, label }` objects.
|
|
89
|
+
Wrap the table and query builder in `FilterValueProvider` to supply presentation for
|
|
90
|
+
current values, suggestions, and cell quick filters:
|
|
91
|
+
|
|
92
|
+
```tsx
|
|
93
|
+
<FilterValueProvider value={{
|
|
94
|
+
label: (field, key) => lookup(field, key)?.name ?? key,
|
|
95
|
+
render: (field, key) => <Badge value={lookup(field, key)} fallback={key} />,
|
|
96
|
+
}}>
|
|
97
|
+
<QueryBuilder api={api} fields={schema.fields} total={api.total} />
|
|
98
|
+
<DataTable {...tableProps} />
|
|
99
|
+
</FilterValueProvider>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
The searchable static picker matches both labels and keys. Selection emits the
|
|
103
|
+
canonical `value` only; presentation is never serialized into queries. A resolver
|
|
104
|
+
can present a current value even when it is absent from the options. Strings without
|
|
105
|
+
a presentation provider retain the existing select control.
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
// src/FormulaEditor.tsx
|
|
2
|
+
import { useEffect, useRef, useState } from "react";
|
|
3
|
+
import { EditorState } from "@codemirror/state";
|
|
4
|
+
import {
|
|
5
|
+
EditorView,
|
|
6
|
+
keymap,
|
|
7
|
+
lineNumbers,
|
|
8
|
+
hoverTooltip
|
|
9
|
+
} from "@codemirror/view";
|
|
10
|
+
import { defaultKeymap, history, historyKeymap } from "@codemirror/commands";
|
|
11
|
+
import {
|
|
12
|
+
autocompletion,
|
|
13
|
+
completionKeymap,
|
|
14
|
+
closeBrackets,
|
|
15
|
+
closeBracketsKeymap
|
|
16
|
+
} from "@codemirror/autocomplete";
|
|
17
|
+
import { linter } from "@codemirror/lint";
|
|
18
|
+
import {
|
|
19
|
+
StreamLanguage,
|
|
20
|
+
syntaxHighlighting,
|
|
21
|
+
defaultHighlightStyle,
|
|
22
|
+
bracketMatching
|
|
23
|
+
} from "@codemirror/language";
|
|
24
|
+
import {
|
|
25
|
+
FORMULA_FUNCTIONS,
|
|
26
|
+
FormulaError
|
|
27
|
+
} from "@pythia-software/query-table-core";
|
|
28
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
29
|
+
var language = StreamLanguage.define({
|
|
30
|
+
token(stream) {
|
|
31
|
+
if (stream.eatSpace()) return null;
|
|
32
|
+
if (stream.match(/^"(?:[^"\\]|\\.)*"?/)) return "string";
|
|
33
|
+
if (stream.match(/^\[(?:[^\]]|\]\])*\]/)) return "variableName";
|
|
34
|
+
if (stream.match(/^(?:\d+(?:\.\d*)?|\.\d+)/)) return "number";
|
|
35
|
+
if (stream.match(/^(?:AND|OR|NOT|IN|BETWEEN|NULL|TRUE|FALSE)\b/i))
|
|
36
|
+
return "keyword";
|
|
37
|
+
if (stream.match(/^[a-zA-Z_][a-zA-Z_0-9]*/))
|
|
38
|
+
return "function(variableName)";
|
|
39
|
+
stream.next();
|
|
40
|
+
return "operator";
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
function signatureAt(text) {
|
|
44
|
+
const stack = [];
|
|
45
|
+
let quoted = false, field = false;
|
|
46
|
+
for (let i = 0; i < text.length; i++) {
|
|
47
|
+
const c = text[i];
|
|
48
|
+
if (quoted) {
|
|
49
|
+
if (c === "\\") i++;
|
|
50
|
+
else if (c === '"') quoted = false;
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (field) {
|
|
54
|
+
if (c === "]") {
|
|
55
|
+
if (text[i + 1] === "]") i++;
|
|
56
|
+
else field = false;
|
|
57
|
+
}
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (c === '"') {
|
|
61
|
+
quoted = true;
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (c === "[") {
|
|
65
|
+
field = true;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (c === "(")
|
|
69
|
+
stack.push({
|
|
70
|
+
name: text.slice(0, i).match(/([A-Za-z_]+)\s*$/)?.[1]?.toUpperCase() ?? "",
|
|
71
|
+
argument: 1
|
|
72
|
+
});
|
|
73
|
+
else if (c === ")") stack.pop();
|
|
74
|
+
else if (c === "," && stack.length) stack[stack.length - 1].argument++;
|
|
75
|
+
}
|
|
76
|
+
const call = stack[stack.length - 1], spec = FORMULA_FUNCTIONS.find((f) => f.name === call?.name);
|
|
77
|
+
return spec && call ? `${spec.signature} \xB7 Argument ${call.argument} \u2014 ${spec.description}` : "Use [field] references. Ctrl+Space opens suggestions.";
|
|
78
|
+
}
|
|
79
|
+
function FormulaEditor({
|
|
80
|
+
value,
|
|
81
|
+
onChange,
|
|
82
|
+
fields,
|
|
83
|
+
compile
|
|
84
|
+
}) {
|
|
85
|
+
const [hint, setHint] = useState(
|
|
86
|
+
"Use [field] references. Ctrl+Space opens suggestions."
|
|
87
|
+
);
|
|
88
|
+
const parent = useRef(null), editor = useRef();
|
|
89
|
+
const latest = useRef({ onChange, fields, compile });
|
|
90
|
+
latest.current = { onChange, fields, compile };
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
if (!parent.current) return;
|
|
93
|
+
const view = new EditorView({
|
|
94
|
+
parent: parent.current,
|
|
95
|
+
state: EditorState.create({
|
|
96
|
+
doc: value,
|
|
97
|
+
extensions: [
|
|
98
|
+
lineNumbers(),
|
|
99
|
+
history(),
|
|
100
|
+
language,
|
|
101
|
+
syntaxHighlighting(defaultHighlightStyle),
|
|
102
|
+
bracketMatching(),
|
|
103
|
+
closeBrackets(),
|
|
104
|
+
EditorView.lineWrapping,
|
|
105
|
+
EditorView.contentAttributes.of({
|
|
106
|
+
"aria-label": "Computed column formula",
|
|
107
|
+
spellcheck: "false"
|
|
108
|
+
}),
|
|
109
|
+
keymap.of([
|
|
110
|
+
...closeBracketsKeymap,
|
|
111
|
+
...completionKeymap,
|
|
112
|
+
...defaultKeymap,
|
|
113
|
+
...historyKeymap
|
|
114
|
+
]),
|
|
115
|
+
autocompletion({
|
|
116
|
+
override: [
|
|
117
|
+
(context) => {
|
|
118
|
+
const word = context.matchBefore(
|
|
119
|
+
/\[[^\]]*|[a-zA-Z_][a-zA-Z_0-9]*/
|
|
120
|
+
);
|
|
121
|
+
if (!word && !context.explicit) return null;
|
|
122
|
+
return {
|
|
123
|
+
from: word?.from ?? context.pos,
|
|
124
|
+
options: [
|
|
125
|
+
...latest.current.fields.map((f) => ({
|
|
126
|
+
label: `[${f.name.replace(/\]/g, "]]")}]`,
|
|
127
|
+
displayLabel: f.label,
|
|
128
|
+
detail: f.type,
|
|
129
|
+
type: "variable",
|
|
130
|
+
info: f.name
|
|
131
|
+
})),
|
|
132
|
+
...FORMULA_FUNCTIONS.map((f) => ({
|
|
133
|
+
label: f.name,
|
|
134
|
+
type: "function",
|
|
135
|
+
detail: f.signature,
|
|
136
|
+
info: f.description,
|
|
137
|
+
apply: `${f.name}(`
|
|
138
|
+
})),
|
|
139
|
+
...[
|
|
140
|
+
"TRUE",
|
|
141
|
+
"FALSE",
|
|
142
|
+
"NULL",
|
|
143
|
+
"AND",
|
|
144
|
+
"OR",
|
|
145
|
+
"NOT",
|
|
146
|
+
"IN",
|
|
147
|
+
"BETWEEN"
|
|
148
|
+
].map((label) => ({ label, type: "keyword" }))
|
|
149
|
+
]
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
]
|
|
153
|
+
}),
|
|
154
|
+
linter(
|
|
155
|
+
(view2) => {
|
|
156
|
+
try {
|
|
157
|
+
latest.current.compile(view2.state.doc.toString());
|
|
158
|
+
return [];
|
|
159
|
+
} catch (e) {
|
|
160
|
+
return [
|
|
161
|
+
{
|
|
162
|
+
from: Math.min(
|
|
163
|
+
e instanceof FormulaError ? e.from : 0,
|
|
164
|
+
view2.state.doc.length
|
|
165
|
+
),
|
|
166
|
+
to: Math.min(
|
|
167
|
+
e instanceof FormulaError ? e.to : view2.state.doc.length,
|
|
168
|
+
view2.state.doc.length
|
|
169
|
+
),
|
|
170
|
+
severity: "error",
|
|
171
|
+
message: e instanceof Error ? e.message : String(e)
|
|
172
|
+
}
|
|
173
|
+
];
|
|
174
|
+
}
|
|
175
|
+
},
|
|
176
|
+
{ delay: 250 }
|
|
177
|
+
),
|
|
178
|
+
hoverTooltip((view2, pos) => {
|
|
179
|
+
const line = view2.state.doc.lineAt(pos);
|
|
180
|
+
const left = line.text.slice(0, pos - line.from).match(/[A-Za-z_0-9]*$/)?.[0] ?? "";
|
|
181
|
+
const right = line.text.slice(pos - line.from).match(/^[A-Za-z_0-9]*/)?.[0] ?? "";
|
|
182
|
+
const spec = FORMULA_FUNCTIONS.find(
|
|
183
|
+
(f) => f.name === (left + right).toUpperCase()
|
|
184
|
+
);
|
|
185
|
+
if (!spec) return null;
|
|
186
|
+
return {
|
|
187
|
+
pos: pos - left.length,
|
|
188
|
+
end: pos + right.length,
|
|
189
|
+
create() {
|
|
190
|
+
const dom = document.createElement("div");
|
|
191
|
+
dom.className = "qt-function-help";
|
|
192
|
+
dom.textContent = `${spec.signature} \u2014 ${spec.description}`;
|
|
193
|
+
return { dom };
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
}),
|
|
197
|
+
EditorView.updateListener.of((update) => {
|
|
198
|
+
if (update.docChanged)
|
|
199
|
+
latest.current.onChange(update.state.doc.toString());
|
|
200
|
+
if (update.docChanged || update.selectionSet)
|
|
201
|
+
setHint(
|
|
202
|
+
signatureAt(
|
|
203
|
+
update.state.doc.sliceString(
|
|
204
|
+
0,
|
|
205
|
+
update.state.selection.main.head
|
|
206
|
+
)
|
|
207
|
+
)
|
|
208
|
+
);
|
|
209
|
+
}),
|
|
210
|
+
EditorView.theme({
|
|
211
|
+
"&": {
|
|
212
|
+
fontSize: "13px",
|
|
213
|
+
border: "1px solid var(--qt-border, #cbd5e1)",
|
|
214
|
+
borderRadius: "6px"
|
|
215
|
+
},
|
|
216
|
+
".cm-scroller": {
|
|
217
|
+
minHeight: "130px",
|
|
218
|
+
maxHeight: "260px",
|
|
219
|
+
fontFamily: "ui-monospace, monospace"
|
|
220
|
+
},
|
|
221
|
+
".cm-content": { padding: "12px 0" },
|
|
222
|
+
".cm-gutters": {
|
|
223
|
+
background: "var(--qt-bg-muted, #f8fafc)",
|
|
224
|
+
color: "var(--qt-muted, #64748b)"
|
|
225
|
+
}
|
|
226
|
+
})
|
|
227
|
+
]
|
|
228
|
+
})
|
|
229
|
+
});
|
|
230
|
+
editor.current = view;
|
|
231
|
+
return () => {
|
|
232
|
+
view.destroy();
|
|
233
|
+
editor.current = void 0;
|
|
234
|
+
};
|
|
235
|
+
}, []);
|
|
236
|
+
useEffect(() => {
|
|
237
|
+
const view = editor.current;
|
|
238
|
+
if (view && view.state.doc.toString() !== value)
|
|
239
|
+
view.dispatch({
|
|
240
|
+
changes: { from: 0, to: view.state.doc.length, insert: value }
|
|
241
|
+
});
|
|
242
|
+
}, [value]);
|
|
243
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
244
|
+
/* @__PURE__ */ jsx("div", { ref: parent }),
|
|
245
|
+
/* @__PURE__ */ jsx("p", { className: "qt-formula-hint", "aria-live": "polite", children: hint })
|
|
246
|
+
] });
|
|
247
|
+
}
|
|
248
|
+
export {
|
|
249
|
+
FormulaEditor as default
|
|
250
|
+
};
|
|
251
|
+
//# sourceMappingURL=FormulaEditor-YCPICDIH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/FormulaEditor.tsx"],"sourcesContent":["import { useEffect, useRef, useState } from \"react\";\nimport { EditorState } from \"@codemirror/state\";\nimport {\n EditorView,\n keymap,\n lineNumbers,\n hoverTooltip,\n} from \"@codemirror/view\";\nimport { defaultKeymap, history, historyKeymap } from \"@codemirror/commands\";\nimport {\n autocompletion,\n completionKeymap,\n closeBrackets,\n closeBracketsKeymap,\n} from \"@codemirror/autocomplete\";\nimport { linter } from \"@codemirror/lint\";\nimport {\n StreamLanguage,\n syntaxHighlighting,\n defaultHighlightStyle,\n bracketMatching,\n} from \"@codemirror/language\";\nimport {\n FORMULA_FUNCTIONS,\n FormulaError,\n type FieldDef,\n type FormulaPlan,\n} from \"@pythia-software/query-table-core\";\n\nexport interface FormulaEditorProps {\n value: string;\n onChange: (value: string) => void;\n fields: FieldDef[];\n compile: (value: string) => FormulaPlan;\n}\nconst language = StreamLanguage.define({\n token(stream) {\n if (stream.eatSpace()) return null;\n if (stream.match(/^\"(?:[^\"\\\\]|\\\\.)*\"?/)) return \"string\";\n if (stream.match(/^\\[(?:[^\\]]|\\]\\])*\\]/)) return \"variableName\";\n if (stream.match(/^(?:\\d+(?:\\.\\d*)?|\\.\\d+)/)) return \"number\";\n if (stream.match(/^(?:AND|OR|NOT|IN|BETWEEN|NULL|TRUE|FALSE)\\b/i))\n return \"keyword\";\n if (stream.match(/^[a-zA-Z_][a-zA-Z_0-9]*/))\n return \"function(variableName)\";\n stream.next();\n return \"operator\";\n },\n});\nfunction signatureAt(text: string): string {\n const stack: { name: string; argument: number }[] = [];\n let quoted = false,\n field = false;\n for (let i = 0; i < text.length; i++) {\n const c = text[i];\n if (quoted) {\n if (c === \"\\\\\") i++;\n else if (c === '\"') quoted = false;\n continue;\n }\n if (field) {\n if (c === \"]\") {\n if (text[i + 1] === \"]\") i++;\n else field = false;\n }\n continue;\n }\n if (c === '\"') {\n quoted = true;\n continue;\n }\n if (c === \"[\") {\n field = true;\n continue;\n }\n if (c === \"(\")\n stack.push({\n name:\n text\n .slice(0, i)\n .match(/([A-Za-z_]+)\\s*$/)?.[1]\n ?.toUpperCase() ?? \"\",\n argument: 1,\n });\n else if (c === \")\") stack.pop();\n else if (c === \",\" && stack.length) stack[stack.length - 1]!.argument++;\n }\n const call = stack[stack.length - 1],\n spec = FORMULA_FUNCTIONS.find((f) => f.name === call?.name);\n return spec && call\n ? `${spec.signature} · Argument ${call.argument} — ${spec.description}`\n : \"Use [field] references. Ctrl+Space opens suggestions.\";\n}\nexport default function FormulaEditor({\n value,\n onChange,\n fields,\n compile,\n}: FormulaEditorProps) {\n const [hint, setHint] = useState(\n \"Use [field] references. Ctrl+Space opens suggestions.\",\n );\n const parent = useRef<HTMLDivElement>(null),\n editor = useRef<EditorView>();\n const latest = useRef({ onChange, fields, compile });\n latest.current = { onChange, fields, compile };\n useEffect(() => {\n if (!parent.current) return;\n const view = new EditorView({\n parent: parent.current,\n state: EditorState.create({\n doc: value,\n extensions: [\n lineNumbers(),\n history(),\n language,\n syntaxHighlighting(defaultHighlightStyle),\n bracketMatching(),\n closeBrackets(),\n EditorView.lineWrapping,\n EditorView.contentAttributes.of({\n \"aria-label\": \"Computed column formula\",\n spellcheck: \"false\",\n }),\n keymap.of([\n ...closeBracketsKeymap,\n ...completionKeymap,\n ...defaultKeymap,\n ...historyKeymap,\n ]),\n autocompletion({\n override: [\n (context) => {\n const word = context.matchBefore(\n /\\[[^\\]]*|[a-zA-Z_][a-zA-Z_0-9]*/,\n );\n if (!word && !context.explicit) return null;\n return {\n from: word?.from ?? context.pos,\n options: [\n ...latest.current.fields.map((f) => ({\n label: `[${f.name.replace(/\\]/g, \"]]\")}]`,\n displayLabel: f.label,\n detail: f.type,\n type: \"variable\",\n info: f.name,\n })),\n ...FORMULA_FUNCTIONS.map((f) => ({\n label: f.name,\n type: \"function\",\n detail: f.signature,\n info: f.description,\n apply: `${f.name}(`,\n })),\n ...[\n \"TRUE\",\n \"FALSE\",\n \"NULL\",\n \"AND\",\n \"OR\",\n \"NOT\",\n \"IN\",\n \"BETWEEN\",\n ].map((label) => ({ label, type: \"keyword\" })),\n ],\n };\n },\n ],\n }),\n linter(\n (view) => {\n try {\n latest.current.compile(view.state.doc.toString());\n return [];\n } catch (e) {\n return [\n {\n from: Math.min(\n e instanceof FormulaError ? e.from : 0,\n view.state.doc.length,\n ),\n to: Math.min(\n e instanceof FormulaError ? e.to : view.state.doc.length,\n view.state.doc.length,\n ),\n severity: \"error\" as const,\n message: e instanceof Error ? e.message : String(e),\n },\n ];\n }\n },\n { delay: 250 },\n ),\n hoverTooltip((view, pos) => {\n const line = view.state.doc.lineAt(pos);\n const left =\n line.text\n .slice(0, pos - line.from)\n .match(/[A-Za-z_0-9]*$/)?.[0] ?? \"\";\n const right =\n line.text.slice(pos - line.from).match(/^[A-Za-z_0-9]*/)?.[0] ??\n \"\";\n const spec = FORMULA_FUNCTIONS.find(\n (f) => f.name === (left + right).toUpperCase(),\n );\n if (!spec) return null;\n return {\n pos: pos - left.length,\n end: pos + right.length,\n create() {\n const dom = document.createElement(\"div\");\n dom.className = \"qt-function-help\";\n dom.textContent = `${spec.signature} — ${spec.description}`;\n return { dom };\n },\n };\n }),\n EditorView.updateListener.of((update) => {\n if (update.docChanged)\n latest.current.onChange(update.state.doc.toString());\n if (update.docChanged || update.selectionSet)\n setHint(\n signatureAt(\n update.state.doc.sliceString(\n 0,\n update.state.selection.main.head,\n ),\n ),\n );\n }),\n EditorView.theme({\n \"&\": {\n fontSize: \"13px\",\n border: \"1px solid var(--qt-border, #cbd5e1)\",\n borderRadius: \"6px\",\n },\n \".cm-scroller\": {\n minHeight: \"130px\",\n maxHeight: \"260px\",\n fontFamily: \"ui-monospace, monospace\",\n },\n \".cm-content\": { padding: \"12px 0\" },\n \".cm-gutters\": {\n background: \"var(--qt-bg-muted, #f8fafc)\",\n color: \"var(--qt-muted, #64748b)\",\n },\n }),\n ],\n }),\n });\n editor.current = view;\n return () => {\n view.destroy();\n editor.current = undefined;\n };\n }, []);\n useEffect(() => {\n const view = editor.current;\n if (view && view.state.doc.toString() !== value)\n view.dispatch({\n changes: { from: 0, to: view.state.doc.length, insert: value },\n });\n }, [value]);\n return (\n <>\n <div ref={parent} />\n <p className=\"qt-formula-hint\" aria-live=\"polite\">\n {hint}\n </p>\n </>\n );\n}\n"],"mappings":"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","names":["view"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
1
2
|
import { ReactNode, SetStateAction } from 'react';
|
|
2
3
|
import { FieldDef, QueryState, RowId, FieldStats, WhereClause } from '@pythia-software/query-table-core';
|
|
3
4
|
import { SelectionApi, ColumnDragApi, QueryTableApi, AggregationsApi, SavedQueriesApi } from '@pythia-software/query-table-react';
|
|
5
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
6
|
|
|
5
7
|
interface CellContext<Row = any, V = unknown> {
|
|
6
8
|
value: V;
|
|
@@ -153,9 +155,9 @@ declare function CellMenu<Row>({ field, value, x, y, onAddFilter, onClose, class
|
|
|
153
155
|
|
|
154
156
|
interface SelectionToolbarProps {
|
|
155
157
|
selection: SelectionApi;
|
|
156
|
-
/** Consumer-rendered action buttons. Receives the selected ids
|
|
157
|
-
*
|
|
158
|
-
actions: (selectedIds: RowId[]) => ReactNode;
|
|
158
|
+
/** Consumer-rendered action buttons. Receives the selected ids and the public
|
|
159
|
+
* selection API. Existing callbacks that accept only ids remain supported. */
|
|
160
|
+
actions: (selectedIds: RowId[], selection: SelectionApi) => ReactNode;
|
|
159
161
|
/** Hidden when nothing is selected unless `alwaysShow`. */
|
|
160
162
|
alwaysShow?: boolean;
|
|
161
163
|
className?: string;
|
|
@@ -169,4 +171,21 @@ interface SavedQueriesModalProps {
|
|
|
169
171
|
}
|
|
170
172
|
declare function SavedQueriesModal({ saved, onClose, onLoad }: SavedQueriesModalProps): ReactNode;
|
|
171
173
|
|
|
172
|
-
|
|
174
|
+
interface SelectColumnEditorProps<Row> {
|
|
175
|
+
api: QueryTableApi<Row>;
|
|
176
|
+
onClose: () => void;
|
|
177
|
+
}
|
|
178
|
+
declare function SelectColumnEditor<Row>({ api, onClose, }: SelectColumnEditorProps<Row>): react_jsx_runtime.JSX.Element;
|
|
179
|
+
|
|
180
|
+
/** Consumer-owned presentation; canonical values remain in queries and URLs. */
|
|
181
|
+
interface FilterValuePresentation {
|
|
182
|
+
label?: (field: string, value: string) => string;
|
|
183
|
+
render?: (field: string, value: string) => ReactNode;
|
|
184
|
+
}
|
|
185
|
+
declare const FilterValueProvider: react.Provider<FilterValuePresentation>;
|
|
186
|
+
declare function PresentedFilterValue({ field, value }: {
|
|
187
|
+
field: string;
|
|
188
|
+
value: string;
|
|
189
|
+
}): react_jsx_runtime.JSX.Element;
|
|
190
|
+
|
|
191
|
+
export { type CellContext, CellMenu, type CellMenuProps, type CellRenderer, DataTable, type DataTableProps, FieldPicker, type FieldPickerProps, type FilterValuePresentation, FilterValueProvider, type MenuClassNames, MetricsPanel, type MetricsPanelProps, PresentedFilterValue, QueryBuilder, type QueryBuilderClassNames, type QueryBuilderProps, type RenderRegistry, SavedQueriesModal, type SavedQueriesModalProps, SelectColumnEditor, type SelectColumnEditorProps, SelectionToolbar, type SelectionToolbarProps, type TableClassNames, defaultRenderers, resolveRenderer, safeLinkHref };
|