@jielga/tmdatagrid 2.0.0-beta.9 → 2.0.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 +5 -212
- package/dist/index.d.ts +1281 -768
- package/dist/index.js +4607 -3250
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/docs/adding-rows.md +132 -0
- package/docs/anatomy.md +119 -0
- package/docs/card-view.md +108 -0
- package/docs/cell-selection.md +194 -0
- package/docs/column-layout.md +182 -0
- package/docs/column-menu.md +66 -0
- package/docs/columns.md +268 -0
- package/docs/components.md +311 -0
- package/docs/draft-store.md +242 -0
- package/docs/editing.md +303 -0
- package/docs/editors.md +250 -0
- package/docs/export.md +319 -0
- package/docs/filtering.md +362 -0
- package/docs/getting-started.md +123 -0
- package/docs/grouping.md +165 -0
- package/docs/loading-and-empty.md +92 -0
- package/docs/localization.md +79 -0
- package/docs/menu.md +143 -0
- package/docs/migrating-to-2.md +163 -0
- package/docs/pagination.md +144 -0
- package/docs/persistence.md +114 -0
- package/docs/portfolio-rebalancer.md +94 -0
- package/docs/query-builder.md +179 -0
- package/docs/quick-search.md +84 -0
- package/docs/row-details.md +115 -0
- package/docs/row-interaction.md +149 -0
- package/docs/row-pinning.md +132 -0
- package/docs/row-selection.md +136 -0
- package/docs/row-styling.md +133 -0
- package/docs/scrolling.md +112 -0
- package/docs/server-query.md +246 -0
- package/docs/server-side.md +206 -0
- package/docs/sorting.md +101 -0
- package/docs/styling.md +126 -0
- package/docs/summary-row.md +76 -0
- package/docs/testing.md +744 -0
- package/docs/toolbar.md +161 -0
- package/docs/use-tm-data-grid.md +361 -0
- package/package.json +22 -46
- package/skills/appearance/SKILL.md +72 -19
- package/skills/cell-selection/SKILL.md +46 -47
- package/skills/columns/SKILL.md +90 -34
- package/skills/data/SKILL.md +86 -16
- package/skills/editing/SKILL.md +67 -40
- package/skills/editing/references/common-mistakes.md +77 -69
- package/skills/editing/references/editing-api.md +22 -19
- package/skills/editing/references/editors-and-validation.md +24 -17
- package/skills/filtering/SKILL.md +148 -40
- package/skills/getting-started/SKILL.md +17 -15
- package/skills/grouping/SKILL.md +31 -16
- package/skills/options/SKILL.md +7 -7
- package/skills/rows/SKILL.md +22 -18
- package/skills/server-side/SKILL.md +170 -17
- package/skills/testing/SKILL.md +150 -32
- package/skills/testing-components/SKILL.md +230 -0
- package/skills/testing-editing/SKILL.md +240 -0
- package/src/{tmdatagrid/components → components}/TMDataGrid.tsx +38 -21
- package/src/{tmdatagrid/components → components}/TMDataGridCellEditor.tsx +54 -8
- package/src/{tmdatagrid/components → components}/TMDataGridColumnsPanel.module.css +5 -1
- package/src/{tmdatagrid/components → components}/TMDataGridColumnsPanel.tsx +47 -55
- package/src/{tmdatagrid/components → components}/TMDataGridDetailsColumn.tsx +5 -51
- package/src/{tmdatagrid/components → components}/TMDataGridDraftActions.tsx +41 -24
- package/src/{tmdatagrid/components → components}/TMDataGridEditColumn.tsx +12 -59
- package/src/{tmdatagrid/components → components}/TMDataGridEntryRows.tsx +164 -92
- package/src/components/TMDataGridExportPicker.module.css +77 -0
- package/src/components/TMDataGridExportPicker.tsx +234 -0
- package/src/components/TMDataGridFilterPanel.module.css +54 -0
- package/src/components/TMDataGridFilterPanel.tsx +348 -0
- package/src/{tmdatagrid/components → components}/TMDataGridFilterPills.tsx +15 -8
- package/src/components/TMDataGridFilterSurface.module.css +54 -0
- package/src/components/TMDataGridFilterSurface.tsx +167 -0
- package/src/{tmdatagrid/components → components}/TMDataGridFooter.tsx +53 -90
- package/src/{tmdatagrid/components → components}/TMDataGridGroupColumn.tsx +5 -69
- package/src/{tmdatagrid/components → components}/TMDataGridHeaderCell.module.css +12 -2
- package/src/{tmdatagrid/components → components}/TMDataGridHeaderCell.tsx +58 -21
- package/src/components/TMDataGridHeaderFilterRow.module.css +51 -0
- package/src/components/TMDataGridHeaderFilterRow.tsx +301 -0
- package/src/components/TMDataGridMenu.tsx +357 -0
- package/src/{tmdatagrid/components → components}/TMDataGridSelectColumn.tsx +11 -48
- package/src/{tmdatagrid/components → components}/TMDataGridTable.module.css +69 -56
- package/src/{tmdatagrid/components → components}/TMDataGridTable.tsx +240 -138
- package/src/{tmdatagrid/components → components}/TMDataGridToolbar.module.css +5 -0
- package/src/components/TMDataGridToolbar.tsx +181 -0
- package/src/{tmdatagrid/components → components}/editors/TMDataGridBooleanEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/TMDataGridDateEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/TMDataGridMultiSelectEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/TMDataGridNumberEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/TMDataGridSelectEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/TMDataGridStringEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/editorShared.ts +16 -2
- package/src/{tmdatagrid/components → components}/filters/DgAutocompleteFilter.tsx +5 -4
- package/src/{tmdatagrid/components → components}/filters/DgDateRangeFilter.tsx +22 -5
- package/src/{tmdatagrid/components → components}/filters/DgRangeSliderFilter.tsx +5 -1
- package/src/{tmdatagrid/components → components}/filters/DgTriStateFilter.tsx +5 -1
- package/src/{tmdatagrid/components → components}/filters/TMDataGridFilterValueInput.tsx +44 -28
- package/src/components/filters/controlLayout.ts +32 -0
- package/src/components/filters/filterControlFor.ts +65 -0
- package/src/components/generatedColumns.tsx +187 -0
- package/src/{tmdatagrid/components → components}/icons.ts +1 -0
- package/src/{tmdatagrid/components → components}/sticky.module.css +44 -0
- package/src/components/useHideableColumns.ts +52 -0
- package/src/{tmdatagrid/core → core}/autosize.ts +5 -2
- package/src/{tmdatagrid/core → core}/columnOptions.ts +60 -8
- package/src/{tmdatagrid/core → core}/columnOrdering.ts +33 -14
- package/src/{tmdatagrid/core → core}/columnUtils.ts +44 -5
- package/src/core/controlledStateSync.ts +108 -0
- package/src/core/deletedRows.ts +34 -0
- package/src/core/dom.ts +74 -0
- package/src/{tmdatagrid/core → core}/editEngine.ts +1107 -460
- package/src/core/export.ts +704 -0
- package/src/{tmdatagrid/core → core}/filterControls.ts +38 -1
- package/src/{tmdatagrid/core → core}/filterOperators.ts +64 -1
- package/src/core/filterSurface.ts +99 -0
- package/src/{tmdatagrid/core → core}/grouping.ts +21 -0
- package/src/{tmdatagrid/core → core}/labels.ts +51 -6
- package/src/{tmdatagrid/core → core}/labelsSv.ts +27 -6
- package/src/core/pageReset.ts +120 -0
- package/src/core/pagination.ts +81 -0
- package/src/{tmdatagrid/core → core}/persistence.ts +22 -5
- package/src/{tmdatagrid/core → core}/summary.ts +20 -4
- package/src/{tmdatagrid/index.ts → index.ts} +69 -35
- package/src/{tmdatagrid/useTMDataGrid.tsx → useTMDataGrid.tsx} +428 -109
- package/src/useTMDataGridExport.ts +78 -0
- package/src/tmdatagrid/components/TMDataGridFilterPanel.module.css +0 -35
- package/src/tmdatagrid/components/TMDataGridFilterPanel.tsx +0 -354
- package/src/tmdatagrid/components/TMDataGridToolbar.tsx +0 -161
- package/src/tmdatagrid/core/cellExport.ts +0 -320
- /package/src/{tmdatagrid/TMDataGridContext.ts → TMDataGridContext.ts} +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGrid.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridDetailsColumn.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridFilterPills.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridFooter.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridGroupColumn.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridRowNumberColumn.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridSearch.tsx +0 -0
- /package/src/{tmdatagrid/core → core}/capabilities.ts +0 -0
- /package/src/{tmdatagrid/core → core}/cellNavigation.ts +0 -0
- /package/src/{tmdatagrid/core → core}/cellRange.ts +0 -0
- /package/src/{tmdatagrid/core → core}/controlledState.ts +0 -0
- /package/src/{tmdatagrid/core → core}/draftCellContext.ts +0 -0
- /package/src/{tmdatagrid/core → core}/editorFocus.ts +0 -0
- /package/src/{tmdatagrid/core → core}/expanding.ts +0 -0
- /package/src/{tmdatagrid/core → core}/matchHighlight.ts +0 -0
- /package/src/{tmdatagrid/core → core}/quickSearch.ts +0 -0
- /package/src/{tmdatagrid/core → core}/resizePreview.ts +0 -0
- /package/src/{tmdatagrid/core → core}/rowPinning.ts +0 -0
- /package/src/{tmdatagrid/core → core}/rowSelection.ts +0 -0
- /package/src/{tmdatagrid/core → core}/sizes.ts +0 -0
- /package/src/{tmdatagrid/core → core}/useSettledTableState.ts +0 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
.title {
|
|
2
|
+
font-weight: 500;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.list {
|
|
6
|
+
display: flex;
|
|
7
|
+
flex-direction: column;
|
|
8
|
+
border: 1px solid var(--mantine-color-default-border);
|
|
9
|
+
border-radius: var(--mantine-radius-default);
|
|
10
|
+
overflow: hidden;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.listHeader {
|
|
14
|
+
display: flex;
|
|
15
|
+
align-items: center;
|
|
16
|
+
justify-content: space-between;
|
|
17
|
+
gap: var(--mantine-spacing-sm);
|
|
18
|
+
padding: var(--mantine-spacing-xs) var(--mantine-spacing-sm);
|
|
19
|
+
background-color: var(--mantine-color-default-hover);
|
|
20
|
+
border-bottom: 1px solid var(--mantine-color-default-border);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.headerLabel {
|
|
24
|
+
font-weight: 500;
|
|
25
|
+
cursor: pointer;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.rows {
|
|
29
|
+
display: flex;
|
|
30
|
+
flex-direction: column;
|
|
31
|
+
padding: calc(var(--mantine-spacing-xs) / 2) 0;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* Each column is one full-width row: the label stretches over the free space
|
|
35
|
+
so the whole row toggles the box, and the row highlights on hover like a
|
|
36
|
+
menu item. */
|
|
37
|
+
.row {
|
|
38
|
+
padding: 0 var(--mantine-spacing-sm);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.row:hover {
|
|
42
|
+
background-color: var(--mantine-color-default-hover);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.rowBody {
|
|
46
|
+
align-items: center;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.rowLabelWrapper {
|
|
50
|
+
flex: 1;
|
|
51
|
+
min-width: 0;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.rowLabel {
|
|
55
|
+
display: flex;
|
|
56
|
+
align-items: center;
|
|
57
|
+
justify-content: space-between;
|
|
58
|
+
gap: var(--mantine-spacing-sm);
|
|
59
|
+
padding-block: calc(var(--mantine-spacing-xs) * 0.75);
|
|
60
|
+
cursor: pointer;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.rowText {
|
|
64
|
+
overflow: hidden;
|
|
65
|
+
text-overflow: ellipsis;
|
|
66
|
+
white-space: nowrap;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.rowHint {
|
|
70
|
+
flex: none;
|
|
71
|
+
font-size: var(--mantine-font-size-xs);
|
|
72
|
+
color: var(--mantine-color-dimmed);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.empty {
|
|
76
|
+
padding: var(--mantine-spacing-xs) var(--mantine-spacing-sm);
|
|
77
|
+
}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Button,
|
|
3
|
+
Checkbox,
|
|
4
|
+
Group,
|
|
5
|
+
type MantineSize,
|
|
6
|
+
Modal,
|
|
7
|
+
ScrollArea,
|
|
8
|
+
Stack,
|
|
9
|
+
Text,
|
|
10
|
+
TextInput,
|
|
11
|
+
} from "@mantine/core";
|
|
12
|
+
import { useSelector } from "@tanstack/react-store";
|
|
13
|
+
import { useState } from "react";
|
|
14
|
+
import classes from "./TMDataGridExportPicker.module.css";
|
|
15
|
+
import { useTMDataGridContext } from "../TMDataGridContext";
|
|
16
|
+
import { getColumnLabel, showColumnSearch } from "../core/columnUtils";
|
|
17
|
+
import {
|
|
18
|
+
countSelectedExportRows,
|
|
19
|
+
getExportableColumns,
|
|
20
|
+
resolveExportOptions,
|
|
21
|
+
type TMDataGridExportPickerRequest,
|
|
22
|
+
} from "../core/export";
|
|
23
|
+
import type { TMDataGridSize } from "../core/sizes";
|
|
24
|
+
import { useTMDataGridExport } from "../useTMDataGridExport";
|
|
25
|
+
import { SearchIcon } from "./icons";
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The column picker behind `columns="custom"` on the export menu items: a
|
|
29
|
+
* list of every exportable column, the visible ones ticked and the hidden
|
|
30
|
+
* ones marked, a select-all row over the list, a search box once the list is
|
|
31
|
+
* long, and an Export button that downloads the ticked ones.
|
|
32
|
+
*
|
|
33
|
+
* Mounted once by the root and driven by `ui.state.exportPicker`, because the
|
|
34
|
+
* menu item that opens it unmounts with the dropdown on the click. The form
|
|
35
|
+
* inside is keyed on the request, so each opening starts from the visible
|
|
36
|
+
* columns again rather than from the last choice.
|
|
37
|
+
*/
|
|
38
|
+
export function TMDataGridExportPicker() {
|
|
39
|
+
const { ui, labels, size, controlSize, exportOptions } =
|
|
40
|
+
useTMDataGridContext();
|
|
41
|
+
const request = useSelector(ui, (state) => state.exportPicker);
|
|
42
|
+
const format = request
|
|
43
|
+
? resolveExportOptions(exportOptions, request.options).format
|
|
44
|
+
: null;
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<Modal
|
|
48
|
+
opened={request !== null}
|
|
49
|
+
onClose={() => ui.actions.closeExportPicker()}
|
|
50
|
+
title={
|
|
51
|
+
format && labels.exportPickerTitle(format.extension.toUpperCase())
|
|
52
|
+
}
|
|
53
|
+
size={MODAL_WIDTH[size]}
|
|
54
|
+
closeButtonProps={{ size: CLOSE_BUTTON_SIZE[controlSize] }}
|
|
55
|
+
classNames={{ title: classes.title }}
|
|
56
|
+
styles={{ title: { fontSize: `var(--mantine-font-size-${controlSize})` } }}
|
|
57
|
+
>
|
|
58
|
+
{request && <PickerForm request={request} />}
|
|
59
|
+
</Modal>
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Dialog width per grid size: the same three steps as the controls. */
|
|
64
|
+
const MODAL_WIDTH: Record<TMDataGridSize, MantineSize> = {
|
|
65
|
+
xs: "xs",
|
|
66
|
+
sm: "xs",
|
|
67
|
+
md: "sm",
|
|
68
|
+
lg: "sm",
|
|
69
|
+
xl: "md",
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
/** The close button one step above the controls, which is Mantine's own ratio. */
|
|
73
|
+
const CLOSE_BUTTON_SIZE: Record<string, MantineSize> = {
|
|
74
|
+
xs: "sm",
|
|
75
|
+
sm: "md",
|
|
76
|
+
md: "lg",
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
function PickerForm({ request }: { request: TMDataGridExportPickerRequest }) {
|
|
80
|
+
const { table, ui, labels, controlSize } = useTMDataGridContext();
|
|
81
|
+
const { exportAll, exportSelected } = useTMDataGridExport(request.options);
|
|
82
|
+
const columns = getExportableColumns(table);
|
|
83
|
+
const [search, setSearch] = useState("");
|
|
84
|
+
const [checked, setChecked] = useState<ReadonlySet<string>>(
|
|
85
|
+
() =>
|
|
86
|
+
new Set(
|
|
87
|
+
columns
|
|
88
|
+
.filter((column) => column.getIsVisible())
|
|
89
|
+
.map((column) => column.id),
|
|
90
|
+
),
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
const searchable = showColumnSearch("auto", columns.length);
|
|
94
|
+
const needle = search.trim().toLowerCase();
|
|
95
|
+
const listed = needle
|
|
96
|
+
? columns.filter((column) =>
|
|
97
|
+
getColumnLabel(column).toLowerCase().includes(needle),
|
|
98
|
+
)
|
|
99
|
+
: columns;
|
|
100
|
+
|
|
101
|
+
// Select all works on the listed columns: with a search active it ticks the
|
|
102
|
+
// matches and leaves the rest as they are, the way a filtered list reads.
|
|
103
|
+
const listedChecked = listed.filter((column) => checked.has(column.id));
|
|
104
|
+
const allListed = listed.length > 0 && listedChecked.length === listed.length;
|
|
105
|
+
const someListed = listedChecked.length > 0 && !allListed;
|
|
106
|
+
|
|
107
|
+
const toggle = (columnId: string, on: boolean) =>
|
|
108
|
+
setChecked((previous) => {
|
|
109
|
+
const next = new Set(previous);
|
|
110
|
+
if (on) next.add(columnId);
|
|
111
|
+
else next.delete(columnId);
|
|
112
|
+
return next;
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
const toggleListed = (on: boolean) =>
|
|
116
|
+
setChecked((previous) => {
|
|
117
|
+
const next = new Set(previous);
|
|
118
|
+
for (const column of listed) {
|
|
119
|
+
if (on) next.add(column.id);
|
|
120
|
+
else next.delete(column.id);
|
|
121
|
+
}
|
|
122
|
+
return next;
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
const confirm = async () => {
|
|
126
|
+
// Render order, whatever order the boxes were ticked in.
|
|
127
|
+
const ids = columns
|
|
128
|
+
.filter((column) => checked.has(column.id))
|
|
129
|
+
.map((column) => column.id);
|
|
130
|
+
const run = request.rows === "selected" ? exportSelected : exportAll;
|
|
131
|
+
await run({ columns: ids });
|
|
132
|
+
ui.actions.closeExportPicker();
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
const hint = labels.exportPickerHint(
|
|
136
|
+
request.rows === "selected" ? countSelectedExportRows(table) : null,
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
return (
|
|
140
|
+
<Stack gap="sm" data-dg-part="export-picker">
|
|
141
|
+
<Text size={controlSize} c="dimmed" data-dg-part="export-picker-hint">
|
|
142
|
+
{hint}
|
|
143
|
+
</Text>
|
|
144
|
+
|
|
145
|
+
{searchable && (
|
|
146
|
+
<TextInput
|
|
147
|
+
value={search}
|
|
148
|
+
onChange={(event) => setSearch(event.currentTarget.value)}
|
|
149
|
+
placeholder={labels.columnsSearchPlaceholder}
|
|
150
|
+
leftSection={<SearchIcon size={16} stroke={1.6} />}
|
|
151
|
+
size={controlSize}
|
|
152
|
+
data-dg-part="export-picker-search"
|
|
153
|
+
data-autofocus
|
|
154
|
+
/>
|
|
155
|
+
)}
|
|
156
|
+
|
|
157
|
+
<div className={classes.list}>
|
|
158
|
+
<div className={classes.listHeader}>
|
|
159
|
+
<Checkbox
|
|
160
|
+
size={controlSize}
|
|
161
|
+
label={labels.exportPickerSelectAll}
|
|
162
|
+
checked={allListed}
|
|
163
|
+
indeterminate={someListed}
|
|
164
|
+
onChange={(event) => toggleListed(event.currentTarget.checked)}
|
|
165
|
+
classNames={{ label: classes.headerLabel }}
|
|
166
|
+
data-dg-part="export-column-all"
|
|
167
|
+
/>
|
|
168
|
+
<Text size="xs" c="dimmed" data-dg-part="export-picker-count">
|
|
169
|
+
{labels.exportPickerCount(checked.size, columns.length)}
|
|
170
|
+
</Text>
|
|
171
|
+
</div>
|
|
172
|
+
|
|
173
|
+
<ScrollArea.Autosize mah="50vh" type="auto">
|
|
174
|
+
<div className={classes.rows}>
|
|
175
|
+
{listed.map((column) => (
|
|
176
|
+
<Checkbox
|
|
177
|
+
key={column.id}
|
|
178
|
+
size={controlSize}
|
|
179
|
+
label={
|
|
180
|
+
<>
|
|
181
|
+
<span className={classes.rowText}>
|
|
182
|
+
{getColumnLabel(column)}
|
|
183
|
+
</span>
|
|
184
|
+
{!column.getIsVisible() && (
|
|
185
|
+
<span className={classes.rowHint}>
|
|
186
|
+
{labels.exportPickerHidden}
|
|
187
|
+
</span>
|
|
188
|
+
)}
|
|
189
|
+
</>
|
|
190
|
+
}
|
|
191
|
+
checked={checked.has(column.id)}
|
|
192
|
+
onChange={(event) =>
|
|
193
|
+
toggle(column.id, event.currentTarget.checked)
|
|
194
|
+
}
|
|
195
|
+
classNames={{
|
|
196
|
+
root: classes.row,
|
|
197
|
+
body: classes.rowBody,
|
|
198
|
+
labelWrapper: classes.rowLabelWrapper,
|
|
199
|
+
label: classes.rowLabel,
|
|
200
|
+
}}
|
|
201
|
+
data-dg-part="export-column"
|
|
202
|
+
data-column-id={column.id}
|
|
203
|
+
/>
|
|
204
|
+
))}
|
|
205
|
+
{listed.length === 0 && (
|
|
206
|
+
<Text size={controlSize} c="dimmed" className={classes.empty}>
|
|
207
|
+
{labels.columnsNoMatch(search)}
|
|
208
|
+
</Text>
|
|
209
|
+
)}
|
|
210
|
+
</div>
|
|
211
|
+
</ScrollArea.Autosize>
|
|
212
|
+
</div>
|
|
213
|
+
|
|
214
|
+
<Group justify="flex-end" gap="xs">
|
|
215
|
+
<Button
|
|
216
|
+
variant="default"
|
|
217
|
+
size={controlSize}
|
|
218
|
+
onClick={() => ui.actions.closeExportPicker()}
|
|
219
|
+
data-dg-part="export-picker-cancel"
|
|
220
|
+
>
|
|
221
|
+
{labels.exportPickerCancel}
|
|
222
|
+
</Button>
|
|
223
|
+
<Button
|
|
224
|
+
size={controlSize}
|
|
225
|
+
disabled={checked.size === 0}
|
|
226
|
+
onClick={() => void confirm()}
|
|
227
|
+
data-dg-part="export-picker-confirm"
|
|
228
|
+
>
|
|
229
|
+
{labels.exportPickerConfirm}
|
|
230
|
+
</Button>
|
|
231
|
+
</Group>
|
|
232
|
+
</Stack>
|
|
233
|
+
);
|
|
234
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/* A plain block of controls. Nothing here positions it - the popup and the
|
|
2
|
+
sidebar own their own placement, and a consumer placing the panel by hand
|
|
3
|
+
places it the way any other block. */
|
|
4
|
+
.filterPanel {
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
gap: var(--mantine-spacing-xs);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/* Column, operator and value side by side, bottom-aligned so their fields line
|
|
11
|
+
up under labels of differing heights. */
|
|
12
|
+
.filterRow {
|
|
13
|
+
display: flex;
|
|
14
|
+
align-items: flex-end;
|
|
15
|
+
gap: var(--mantine-spacing-xs);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/* The narrow-host layout: the same three fields one under the other, each
|
|
19
|
+
filling the width, with the ✕ beside the column it removes. A card rather
|
|
20
|
+
than a bare stack, because without the side-by-side alignment there is
|
|
21
|
+
nothing else saying where one filter ends and the next begins. */
|
|
22
|
+
.filterRow[data-layout="stacked"] {
|
|
23
|
+
display: grid;
|
|
24
|
+
grid-template-columns: 1fr auto;
|
|
25
|
+
align-items: end;
|
|
26
|
+
gap: 6px var(--mantine-spacing-xs);
|
|
27
|
+
padding: var(--mantine-spacing-xs);
|
|
28
|
+
border: 1px solid var(--mantine-color-default-border);
|
|
29
|
+
border-radius: var(--mantine-radius-sm);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.filterRow[data-layout="stacked"] .filterRemove {
|
|
33
|
+
grid-column: 2;
|
|
34
|
+
grid-row: 1;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.filterRow[data-layout="stacked"] .filterColumnSlot {
|
|
38
|
+
grid-column: 1;
|
|
39
|
+
grid-row: 1;
|
|
40
|
+
min-width: 0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.filterRow[data-layout="stacked"] .filterOperatorSlot,
|
|
44
|
+
.filterRow[data-layout="stacked"] .filterValueSlot {
|
|
45
|
+
grid-column: 1 / -1;
|
|
46
|
+
min-width: 0;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.filterPanelFooter {
|
|
50
|
+
display: flex;
|
|
51
|
+
align-items: center;
|
|
52
|
+
justify-content: space-between;
|
|
53
|
+
gap: var(--mantine-spacing-md);
|
|
54
|
+
}
|