@olenbetong/appframe-ds 1.6.1 → 1.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 +15 -0
- package/package.json +2 -2
- package/src/AfLookup/Lookup.css +147 -147
- package/src/AfLookup/Lookup.tsx +186 -186
- package/src/AfLookup/LookupCombobox.css +69 -69
- package/src/AfLookup/LookupCombobox.tsx +273 -273
- package/src/AfLookup/LookupEdit.tsx +130 -130
- package/src/AfLookup/LookupGrid.css +145 -145
- package/src/AfLookup/LookupGrid.test.tsx +142 -142
- package/src/AfLookup/LookupGrid.tsx +324 -324
- package/src/AfLookup/index.ts +5 -5
- package/src/grid/index.css +8 -2
- package/src/grid/index.tsx +73 -3
- package/src/grid/useAfGridApi.ts +3 -0
- package/src/layout/AppMenuItem.css +6 -2
- package/src/mdi/Mdi.css +138 -138
package/src/grid/index.css
CHANGED
|
@@ -140,8 +140,8 @@
|
|
|
140
140
|
|
|
141
141
|
/* The funnel is highlighted while the column has criteria, as in the toolbar */
|
|
142
142
|
.AfGrid-headerFilterButton[data-active] {
|
|
143
|
-
--dsc-button-color: var(--ds-color-
|
|
144
|
-
--dsc-button-color--hover: var(--ds-color-
|
|
143
|
+
--dsc-button-color: var(--ds-color-brand-base-default);
|
|
144
|
+
--dsc-button-color--hover: var(--ds-color-brand-base-hover);
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
.AfGrid-headerFilterEmpty {
|
|
@@ -243,3 +243,9 @@
|
|
|
243
243
|
.AfGrid-root .MuiDataGrid-cell a.ds-button {
|
|
244
244
|
text-decoration: none;
|
|
245
245
|
}
|
|
246
|
+
|
|
247
|
+
/* Group rows (row grouping): tinted and bold, so the subtotals read apart from the data rows */
|
|
248
|
+
.AfGrid-root .MuiDataGrid-row.AfGrid-groupRow {
|
|
249
|
+
background-color: var(--ds-color-neutral-background-tinted);
|
|
250
|
+
font-weight: 600;
|
|
251
|
+
}
|
package/src/grid/index.tsx
CHANGED
|
@@ -9,6 +9,9 @@ import {
|
|
|
9
9
|
type GridAggregationFunction,
|
|
10
10
|
type GridApi,
|
|
11
11
|
type GridFilterModel,
|
|
12
|
+
type GridColSpanFn,
|
|
13
|
+
type GridGroupingColDefOverride,
|
|
14
|
+
type GridGroupingColDefOverrideParams,
|
|
12
15
|
type GridGroupNode,
|
|
13
16
|
type GridRowParams,
|
|
14
17
|
useGridApiRef,
|
|
@@ -17,9 +20,10 @@ import { type DataObject, uid } from "@olenbetong/appframe-data";
|
|
|
17
20
|
import { DataObjectProvider, useLoading } from "@olenbetong/appframe-react";
|
|
18
21
|
|
|
19
22
|
import clsx from "clsx";
|
|
20
|
-
import { useEffect, useMemo, useState } from "react";
|
|
23
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
21
24
|
import { FilterBuilder } from "../filter/index.js";
|
|
22
25
|
import { AfGridColumnsPanel } from "./AfGridColumnsPanel.js";
|
|
26
|
+
import { AfHeaderFilterCell } from "./AfHeaderFilterCell.js";
|
|
23
27
|
import { type AfGridContextValue, AfGridContextProvider } from "./AfGridContext.js";
|
|
24
28
|
import { AfGridError } from "./AfGridError.js";
|
|
25
29
|
import { registerLicense } from "./license.js";
|
|
@@ -141,6 +145,58 @@ export {
|
|
|
141
145
|
};
|
|
142
146
|
|
|
143
147
|
/** MUI's own default: the grand total in the footer, group subtotals inline. */
|
|
148
|
+
/**
|
|
149
|
+
* On a group row the grouping cell spans the following visible columns up to the first one that
|
|
150
|
+
* shows an aggregate, since those cells are empty there. Data rows span nothing.
|
|
151
|
+
*/
|
|
152
|
+
const spanGroupLabel: GridColSpanFn = (_value, row, column, apiRef) => {
|
|
153
|
+
// The callback is typed with the community API; this grid is premium, which has aggregation.
|
|
154
|
+
let api = apiRef.current as GridApi | null;
|
|
155
|
+
if (!api || api.getRowNode(api.getRowId(row))?.type !== "group") return 1;
|
|
156
|
+
|
|
157
|
+
let aggregated = api.state.aggregation?.model ?? {};
|
|
158
|
+
let columns = api.getVisibleColumns();
|
|
159
|
+
let index = columns.findIndex((c) => c.field === column.field);
|
|
160
|
+
let span = 1;
|
|
161
|
+
|
|
162
|
+
while (index + span < columns.length && !aggregated[columns[index + span].field]) {
|
|
163
|
+
span++;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return span;
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* MUI generates the grouping column itself, so it never passes through `useAfColumns` and got
|
|
171
|
+
* MUI's own header filter. It gets ours instead, filtering on the grouped field when the rows are
|
|
172
|
+
* grouped by a single field, and an empty cell like any unfilterable column otherwise.
|
|
173
|
+
*
|
|
174
|
+
* On group rows the column spans the empty cells after it, so the group label is readable in a
|
|
175
|
+
* column no wider than its expand toggle. A grid can still set its own `colSpan`.
|
|
176
|
+
*/
|
|
177
|
+
function getGroupingColDef(
|
|
178
|
+
params: GridGroupingColDefOverrideParams,
|
|
179
|
+
groupingColDef: DataGridProps["groupingColDef"],
|
|
180
|
+
dataObject: DataObject<any>,
|
|
181
|
+
): GridGroupingColDefOverride {
|
|
182
|
+
let base = typeof groupingColDef === "function" ? groupingColDef(params) : groupingColDef;
|
|
183
|
+
let filterColumn = params.fields.length === 1 ? params.fields[0] : undefined;
|
|
184
|
+
|
|
185
|
+
return {
|
|
186
|
+
...base,
|
|
187
|
+
colSpan: base?.colSpan ?? spanGroupLabel,
|
|
188
|
+
renderHeaderFilter:
|
|
189
|
+
base?.renderHeaderFilter ??
|
|
190
|
+
((props) => (
|
|
191
|
+
<AfHeaderFilterCell
|
|
192
|
+
{...props}
|
|
193
|
+
colDef={{ ...props.colDef, filterColumn } as AfGridColDef}
|
|
194
|
+
dataObject={dataObject}
|
|
195
|
+
/>
|
|
196
|
+
)),
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
144
200
|
function getDefaultAggregationPosition(groupNode: GridGroupNode) {
|
|
145
201
|
return groupNode.depth === -1 ? "footer" : "inline";
|
|
146
202
|
}
|
|
@@ -241,6 +297,12 @@ export type AfGridProps = {
|
|
|
241
297
|
* where the client total is wrong.
|
|
242
298
|
*/
|
|
243
299
|
serverAggregation?: boolean;
|
|
300
|
+
/**
|
|
301
|
+
* Leave out MUI's loading overlay while the data object loads. For a grid that refreshes on a
|
|
302
|
+
* timer: the overlay covers the rows and blocks selecting text in them. The toolbar's refresh
|
|
303
|
+
* button still shows that the grid is loading.
|
|
304
|
+
*/
|
|
305
|
+
disableLoadingOverlay?: boolean;
|
|
244
306
|
} & Omit<
|
|
245
307
|
DataGridProps,
|
|
246
308
|
| "apiRef"
|
|
@@ -312,18 +374,25 @@ function AfGrid_(props: AfGridProps) {
|
|
|
312
374
|
pinnedRows,
|
|
313
375
|
getRowClassName,
|
|
314
376
|
serverAggregation = dataObject.options?.dynamicLoading === true,
|
|
377
|
+
disableLoadingOverlay = false,
|
|
315
378
|
...other
|
|
316
379
|
} = props;
|
|
317
380
|
let apiRefPriv = useGridApiRef();
|
|
318
381
|
let apiRef = apiRefProp ?? apiRefPriv;
|
|
319
382
|
useAfGridApi(props, apiRef);
|
|
383
|
+
// Group rows (row grouping) are marked so AfGrid's stylesheet can set them apart from the data rows.
|
|
384
|
+
let getRowClassNameWithGroups = useCallback<NonNullable<DataGridProps["getRowClassName"]>>(
|
|
385
|
+
(params) =>
|
|
386
|
+
clsx(getRowClassName?.(params), apiRef.current?.getRowNode(params.id)?.type === "group" && "AfGrid-groupRow"),
|
|
387
|
+
[getRowClassName, apiRef],
|
|
388
|
+
);
|
|
320
389
|
let newItemRow = useAfNewItemRow({
|
|
321
390
|
apiRef,
|
|
322
391
|
dataObject,
|
|
323
392
|
position: newItemRowPosition,
|
|
324
393
|
disableInsert,
|
|
325
394
|
pinnedRows,
|
|
326
|
-
getRowClassName,
|
|
395
|
+
getRowClassName: getRowClassNameWithGroups,
|
|
327
396
|
});
|
|
328
397
|
let initialState_ = useAfPersistedState({
|
|
329
398
|
apiRef,
|
|
@@ -431,7 +500,7 @@ function AfGrid_(props: AfGridProps) {
|
|
|
431
500
|
apiRef={apiRef}
|
|
432
501
|
rows={data}
|
|
433
502
|
columns={columns}
|
|
434
|
-
loading={loading}
|
|
503
|
+
loading={!disableLoadingOverlay && loading}
|
|
435
504
|
getRowId={(row) => row[uid] ?? row[idField]}
|
|
436
505
|
{...editProps}
|
|
437
506
|
{...newItemRow.gridProps}
|
|
@@ -463,6 +532,7 @@ function AfGrid_(props: AfGridProps) {
|
|
|
463
532
|
* so the default position is passed explicitly.
|
|
464
533
|
*/
|
|
465
534
|
getAggregationPosition={other.getAggregationPosition ?? getDefaultAggregationPosition}
|
|
535
|
+
groupingColDef={(params) => getGroupingColDef(params, other.groupingColDef, dataObject)}
|
|
466
536
|
localeText={{ ...other.localeText, ...AF_GRID_LOCALE_TEXT }}
|
|
467
537
|
slots={{
|
|
468
538
|
...dsBaseSlots,
|
package/src/grid/useAfGridApi.ts
CHANGED
|
@@ -62,6 +62,9 @@ export function useAfGridApi(props: Partial<AfGridProps>, apiRef: React.RefObjec
|
|
|
62
62
|
);
|
|
63
63
|
}
|
|
64
64
|
apiRef.current?.setPinnedColumns(propsRef.current.initialState?.pinnedColumns ?? {});
|
|
65
|
+
// Grouping and aggregation are part of the layout too: back to what the grid declares.
|
|
66
|
+
apiRef.current?.setRowGroupingModel(propsRef.current.initialState?.rowGrouping?.model ?? []);
|
|
67
|
+
apiRef.current?.setAggregationModel(propsRef.current.initialState?.aggregation?.model ?? {});
|
|
65
68
|
}, [apiRef]);
|
|
66
69
|
|
|
67
70
|
if (apiRef.current) {
|
|
@@ -47,8 +47,12 @@
|
|
|
47
47
|
flex-shrink: 0;
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
/*
|
|
51
|
+
* Hover and press tint the item with the text colour, so it darkens the item in light mode and
|
|
52
|
+
* lightens it in dark mode; a black overlay disappeared on the dark menu.
|
|
53
|
+
*/
|
|
50
54
|
.AppMenuItem-root::before {
|
|
51
|
-
background-color: #000;
|
|
55
|
+
background-color: var(--ds-color-neutral-text-default, #000);
|
|
52
56
|
opacity: 0;
|
|
53
57
|
transition:
|
|
54
58
|
opacity 30ms linear,
|
|
@@ -70,7 +74,7 @@
|
|
|
70
74
|
}
|
|
71
75
|
|
|
72
76
|
.AppMenuItem-root:hover::before {
|
|
73
|
-
opacity: 0.
|
|
77
|
+
opacity: 0.08;
|
|
74
78
|
}
|
|
75
79
|
|
|
76
80
|
.AppMenuItem-root:active::before {
|
package/src/mdi/Mdi.css
CHANGED
|
@@ -1,138 +1,138 @@
|
|
|
1
|
-
.ObMdi-root {
|
|
2
|
-
position: relative;
|
|
3
|
-
width: 100%;
|
|
4
|
-
height: 100%;
|
|
5
|
-
min-width: 0;
|
|
6
|
-
min-height: 0;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
.ObMdi-root > .dv-dockview {
|
|
10
|
-
width: 100%;
|
|
11
|
-
height: 100%;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/*
|
|
15
|
-
* The dockview variables mapped to Designsystemet tokens. The theme class is also
|
|
16
|
-
* applied to the container in popout windows, so the mapping travels with them.
|
|
17
|
-
*/
|
|
18
|
-
.ObMdi-theme {
|
|
19
|
-
--dv-paneview-active-outline-color: var(--ds-color-focus-outer, #1e2b3c);
|
|
20
|
-
--dv-tabs-and-actions-container-font-size: var(--ds-font-size-3, 0.875rem);
|
|
21
|
-
--dv-tabs-and-actions-container-height: 2.25rem;
|
|
22
|
-
--dv-tab-font-size: inherit;
|
|
23
|
-
--dv-tabs-and-actions-container-background-color: var(--ds-color-neutral-surface-default, #f3f4f5);
|
|
24
|
-
--dv-group-view-background-color: var(--ds-color-neutral-background-default, #fff);
|
|
25
|
-
--dv-activegroup-visiblepanel-tab-background-color: var(--ds-color-neutral-background-default, #fff);
|
|
26
|
-
--dv-activegroup-hiddenpanel-tab-background-color: var(--ds-color-neutral-surface-default, #f3f4f5);
|
|
27
|
-
--dv-inactivegroup-visiblepanel-tab-background-color: var(--ds-color-neutral-background-tinted, #f8f9fa);
|
|
28
|
-
--dv-inactivegroup-hiddenpanel-tab-background-color: var(--ds-color-neutral-surface-default, #f3f4f5);
|
|
29
|
-
--dv-activegroup-visiblepanel-tab-color: var(--ds-color-neutral-text-default, #292c30);
|
|
30
|
-
--dv-activegroup-hiddenpanel-tab-color: var(--ds-color-neutral-text-subtle, #5b5f64);
|
|
31
|
-
--dv-inactivegroup-visiblepanel-tab-color: var(--ds-color-neutral-text-subtle, #5b5f64);
|
|
32
|
-
--dv-inactivegroup-hiddenpanel-tab-color: var(--ds-color-neutral-text-subtle, #5b5f64);
|
|
33
|
-
--dv-tab-divider-color: var(--ds-color-neutral-border-subtle, #d5d7d9);
|
|
34
|
-
--dv-separator-border: var(--ds-color-neutral-border-subtle, #d5d7d9);
|
|
35
|
-
--dv-paneview-header-border-color: var(--ds-color-neutral-border-default, #a6a9ad);
|
|
36
|
-
--dv-sash-color: transparent;
|
|
37
|
-
--dv-active-sash-color: var(--ds-color-
|
|
38
|
-
--dv-active-sash-transition-duration: 0.1s;
|
|
39
|
-
--dv-active-sash-transition-delay: 0.3s;
|
|
40
|
-
--dv-drag-over-background-color: color-mix(in srgb, var(--ds-color-
|
|
41
|
-
--dv-drag-over-border-color: var(--ds-color-
|
|
42
|
-
--dv-drag-over-border: none;
|
|
43
|
-
--dv-edge-dock-indicator-color: var(--ds-color-
|
|
44
|
-
--dv-dnd-compass-color: var(--ds-color-neutral-border-default, #a6a9ad);
|
|
45
|
-
--dv-dnd-compass-cell-color: var(--ds-color-neutral-surface-default, #f3f4f5);
|
|
46
|
-
--dv-dnd-compass-edge-cell-color: var(--ds-color-neutral-surface-hover, #e6e8ea);
|
|
47
|
-
--dv-dnd-compass-active-cell-color: var(--ds-color-
|
|
48
|
-
--dv-tabs-container-scrollbar-color: var(--ds-color-neutral-border-default, #a6a9ad);
|
|
49
|
-
--dv-scrollbar-background-color: var(--ds-color-neutral-border-default, #a6a9ad);
|
|
50
|
-
--dv-icon-hover-background-color: var(--ds-color-neutral-surface-hover, #e6e8ea);
|
|
51
|
-
--dv-context-menu-background-color: var(--ds-color-neutral-background-default, #fff);
|
|
52
|
-
--dv-context-menu-color: var(--ds-color-neutral-text-default, #292c30);
|
|
53
|
-
--dv-floating-box-shadow: var(--ds-shadow-lg, 0 8px 32px rgba(0, 0, 0, 0.12));
|
|
54
|
-
--dv-floating-border: 1px solid var(--ds-color-neutral-border-default, #a6a9ad);
|
|
55
|
-
--dv-floating-group-border: none;
|
|
56
|
-
--dv-floating-group-dragging-opacity: 0.5;
|
|
57
|
-
--dv-floating-titlebar-height: 22px;
|
|
58
|
-
--dv-floating-titlebar-background-color: var(--dv-tabs-and-actions-container-background-color);
|
|
59
|
-
--dv-floating-titlebar-border-bottom: var(--dv-floating-border);
|
|
60
|
-
--dv-overlay-z-index: 999;
|
|
61
|
-
--dv-border-radius: 0px;
|
|
62
|
-
--dv-tab-margin: 0;
|
|
63
|
-
--dv-spacing-padding: 0px;
|
|
64
|
-
--dv-tab-border-radius: 0px;
|
|
65
|
-
--dv-sash-border-radius: 0px;
|
|
66
|
-
--dv-dropdown-border-radius: var(--ds-border-radius-md, 0.25rem);
|
|
67
|
-
--dv-tab-close-icon-size: inherit;
|
|
68
|
-
--dv-smart-guides-color: var(--ds-color-
|
|
69
|
-
--dv-smart-guides-preview-color: color-mix(in srgb, var(--ds-color-
|
|
70
|
-
--dv-tab-group-color-grey: #5f6368;
|
|
71
|
-
--dv-tab-group-color-blue: #1a73e8;
|
|
72
|
-
--dv-tab-group-color-red: #d93025;
|
|
73
|
-
--dv-tab-group-color-yellow: #f9ab00;
|
|
74
|
-
--dv-tab-group-color-green: #188038;
|
|
75
|
-
--dv-tab-group-color-pink: #d01884;
|
|
76
|
-
--dv-tab-group-color-purple: #a142f4;
|
|
77
|
-
--dv-tab-group-color-cyan: #007b83;
|
|
78
|
-
--dv-tab-group-color-orange: #e8710a;
|
|
79
|
-
--dv-tab-group-chip-padding: 4px 8px;
|
|
80
|
-
--dv-tab-group-chip-border-radius: 6px;
|
|
81
|
-
--dv-tab-group-chip-font-size: 11px;
|
|
82
|
-
--dv-tab-group-line-height: 2px;
|
|
83
|
-
--dv-tab-group-line-opacity: 0.6;
|
|
84
|
-
|
|
85
|
-
font-family: var(--ds-font-family, inherit);
|
|
86
|
-
color: var(--ds-color-neutral-text-default, #292c30);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/* The active tab gets an accent line so it reads as selected without relying on background alone. */
|
|
90
|
-
.ObMdi-theme .dv-tab.dv-active-tab {
|
|
91
|
-
box-shadow: inset 0 -2px 0 var(--ds-color-
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
.ObMdi-theme .dv-tab:focus-visible {
|
|
95
|
-
outline: 2px solid var(--ds-color-focus-outer, #1e2b3c);
|
|
96
|
-
outline-offset: -2px;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/* Dirty marker: a dot after the title */
|
|
100
|
-
.ObMdi-tab--dirty .dv-default-tab-content::after {
|
|
101
|
-
content: " \2022";
|
|
102
|
-
color: var(--ds-color-warning-base-default, #b8860b);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
.ObMdi-error {
|
|
106
|
-
display: flex;
|
|
107
|
-
flex-direction: column;
|
|
108
|
-
gap: var(--ds-size-2, 0.5rem);
|
|
109
|
-
padding: var(--ds-size-4, 1rem);
|
|
110
|
-
color: var(--ds-color-danger-text-default, #b3221a);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
.ObMdi-error-title {
|
|
114
|
-
margin: 0;
|
|
115
|
-
font-weight: 600;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
.ObMdi-error-message {
|
|
119
|
-
margin: 0;
|
|
120
|
-
white-space: pre-wrap;
|
|
121
|
-
font-size: var(--ds-font-size-2, 0.8125rem);
|
|
122
|
-
color: var(--ds-color-neutral-text-subtle, #5b5f64);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
.ObMdi-watermark {
|
|
126
|
-
display: flex;
|
|
127
|
-
align-items: center;
|
|
128
|
-
justify-content: center;
|
|
129
|
-
width: 100%;
|
|
130
|
-
height: 100%;
|
|
131
|
-
color: var(--ds-color-neutral-text-subtle, #5b5f64);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
.ObMdi-confirmClose-actions {
|
|
135
|
-
display: flex;
|
|
136
|
-
gap: var(--ds-size-2, 0.5rem);
|
|
137
|
-
justify-content: flex-end;
|
|
138
|
-
}
|
|
1
|
+
.ObMdi-root {
|
|
2
|
+
position: relative;
|
|
3
|
+
width: 100%;
|
|
4
|
+
height: 100%;
|
|
5
|
+
min-width: 0;
|
|
6
|
+
min-height: 0;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.ObMdi-root > .dv-dockview {
|
|
10
|
+
width: 100%;
|
|
11
|
+
height: 100%;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/*
|
|
15
|
+
* The dockview variables mapped to Designsystemet tokens. The theme class is also
|
|
16
|
+
* applied to the container in popout windows, so the mapping travels with them.
|
|
17
|
+
*/
|
|
18
|
+
.ObMdi-theme {
|
|
19
|
+
--dv-paneview-active-outline-color: var(--ds-color-focus-outer, #1e2b3c);
|
|
20
|
+
--dv-tabs-and-actions-container-font-size: var(--ds-font-size-3, 0.875rem);
|
|
21
|
+
--dv-tabs-and-actions-container-height: 2.25rem;
|
|
22
|
+
--dv-tab-font-size: inherit;
|
|
23
|
+
--dv-tabs-and-actions-container-background-color: var(--ds-color-neutral-surface-default, #f3f4f5);
|
|
24
|
+
--dv-group-view-background-color: var(--ds-color-neutral-background-default, #fff);
|
|
25
|
+
--dv-activegroup-visiblepanel-tab-background-color: var(--ds-color-neutral-background-default, #fff);
|
|
26
|
+
--dv-activegroup-hiddenpanel-tab-background-color: var(--ds-color-neutral-surface-default, #f3f4f5);
|
|
27
|
+
--dv-inactivegroup-visiblepanel-tab-background-color: var(--ds-color-neutral-background-tinted, #f8f9fa);
|
|
28
|
+
--dv-inactivegroup-hiddenpanel-tab-background-color: var(--ds-color-neutral-surface-default, #f3f4f5);
|
|
29
|
+
--dv-activegroup-visiblepanel-tab-color: var(--ds-color-neutral-text-default, #292c30);
|
|
30
|
+
--dv-activegroup-hiddenpanel-tab-color: var(--ds-color-neutral-text-subtle, #5b5f64);
|
|
31
|
+
--dv-inactivegroup-visiblepanel-tab-color: var(--ds-color-neutral-text-subtle, #5b5f64);
|
|
32
|
+
--dv-inactivegroup-hiddenpanel-tab-color: var(--ds-color-neutral-text-subtle, #5b5f64);
|
|
33
|
+
--dv-tab-divider-color: var(--ds-color-neutral-border-subtle, #d5d7d9);
|
|
34
|
+
--dv-separator-border: var(--ds-color-neutral-border-subtle, #d5d7d9);
|
|
35
|
+
--dv-paneview-header-border-color: var(--ds-color-neutral-border-default, #a6a9ad);
|
|
36
|
+
--dv-sash-color: transparent;
|
|
37
|
+
--dv-active-sash-color: var(--ds-color-brand-base-default, #116069);
|
|
38
|
+
--dv-active-sash-transition-duration: 0.1s;
|
|
39
|
+
--dv-active-sash-transition-delay: 0.3s;
|
|
40
|
+
--dv-drag-over-background-color: color-mix(in srgb, var(--ds-color-brand-base-default, #116069) 20%, transparent);
|
|
41
|
+
--dv-drag-over-border-color: var(--ds-color-brand-base-default, #116069);
|
|
42
|
+
--dv-drag-over-border: none;
|
|
43
|
+
--dv-edge-dock-indicator-color: var(--ds-color-brand-base-default, #116069);
|
|
44
|
+
--dv-dnd-compass-color: var(--ds-color-neutral-border-default, #a6a9ad);
|
|
45
|
+
--dv-dnd-compass-cell-color: var(--ds-color-neutral-surface-default, #f3f4f5);
|
|
46
|
+
--dv-dnd-compass-edge-cell-color: var(--ds-color-neutral-surface-hover, #e6e8ea);
|
|
47
|
+
--dv-dnd-compass-active-cell-color: var(--ds-color-brand-surface-hover, #d1e5e7);
|
|
48
|
+
--dv-tabs-container-scrollbar-color: var(--ds-color-neutral-border-default, #a6a9ad);
|
|
49
|
+
--dv-scrollbar-background-color: var(--ds-color-neutral-border-default, #a6a9ad);
|
|
50
|
+
--dv-icon-hover-background-color: var(--ds-color-neutral-surface-hover, #e6e8ea);
|
|
51
|
+
--dv-context-menu-background-color: var(--ds-color-neutral-background-default, #fff);
|
|
52
|
+
--dv-context-menu-color: var(--ds-color-neutral-text-default, #292c30);
|
|
53
|
+
--dv-floating-box-shadow: var(--ds-shadow-lg, 0 8px 32px rgba(0, 0, 0, 0.12));
|
|
54
|
+
--dv-floating-border: 1px solid var(--ds-color-neutral-border-default, #a6a9ad);
|
|
55
|
+
--dv-floating-group-border: none;
|
|
56
|
+
--dv-floating-group-dragging-opacity: 0.5;
|
|
57
|
+
--dv-floating-titlebar-height: 22px;
|
|
58
|
+
--dv-floating-titlebar-background-color: var(--dv-tabs-and-actions-container-background-color);
|
|
59
|
+
--dv-floating-titlebar-border-bottom: var(--dv-floating-border);
|
|
60
|
+
--dv-overlay-z-index: 999;
|
|
61
|
+
--dv-border-radius: 0px;
|
|
62
|
+
--dv-tab-margin: 0;
|
|
63
|
+
--dv-spacing-padding: 0px;
|
|
64
|
+
--dv-tab-border-radius: 0px;
|
|
65
|
+
--dv-sash-border-radius: 0px;
|
|
66
|
+
--dv-dropdown-border-radius: var(--ds-border-radius-md, 0.25rem);
|
|
67
|
+
--dv-tab-close-icon-size: inherit;
|
|
68
|
+
--dv-smart-guides-color: var(--ds-color-brand-base-default, #116069);
|
|
69
|
+
--dv-smart-guides-preview-color: color-mix(in srgb, var(--ds-color-brand-base-default, #116069) 20%, transparent);
|
|
70
|
+
--dv-tab-group-color-grey: #5f6368;
|
|
71
|
+
--dv-tab-group-color-blue: #1a73e8;
|
|
72
|
+
--dv-tab-group-color-red: #d93025;
|
|
73
|
+
--dv-tab-group-color-yellow: #f9ab00;
|
|
74
|
+
--dv-tab-group-color-green: #188038;
|
|
75
|
+
--dv-tab-group-color-pink: #d01884;
|
|
76
|
+
--dv-tab-group-color-purple: #a142f4;
|
|
77
|
+
--dv-tab-group-color-cyan: #007b83;
|
|
78
|
+
--dv-tab-group-color-orange: #e8710a;
|
|
79
|
+
--dv-tab-group-chip-padding: 4px 8px;
|
|
80
|
+
--dv-tab-group-chip-border-radius: 6px;
|
|
81
|
+
--dv-tab-group-chip-font-size: 11px;
|
|
82
|
+
--dv-tab-group-line-height: 2px;
|
|
83
|
+
--dv-tab-group-line-opacity: 0.6;
|
|
84
|
+
|
|
85
|
+
font-family: var(--ds-font-family, inherit);
|
|
86
|
+
color: var(--ds-color-neutral-text-default, #292c30);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/* The active tab gets an accent line so it reads as selected without relying on background alone. */
|
|
90
|
+
.ObMdi-theme .dv-tab.dv-active-tab {
|
|
91
|
+
box-shadow: inset 0 -2px 0 var(--ds-color-brand-base-default, #116069);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.ObMdi-theme .dv-tab:focus-visible {
|
|
95
|
+
outline: 2px solid var(--ds-color-focus-outer, #1e2b3c);
|
|
96
|
+
outline-offset: -2px;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* Dirty marker: a dot after the title */
|
|
100
|
+
.ObMdi-tab--dirty .dv-default-tab-content::after {
|
|
101
|
+
content: " \2022";
|
|
102
|
+
color: var(--ds-color-warning-base-default, #b8860b);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.ObMdi-error {
|
|
106
|
+
display: flex;
|
|
107
|
+
flex-direction: column;
|
|
108
|
+
gap: var(--ds-size-2, 0.5rem);
|
|
109
|
+
padding: var(--ds-size-4, 1rem);
|
|
110
|
+
color: var(--ds-color-danger-text-default, #b3221a);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.ObMdi-error-title {
|
|
114
|
+
margin: 0;
|
|
115
|
+
font-weight: 600;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.ObMdi-error-message {
|
|
119
|
+
margin: 0;
|
|
120
|
+
white-space: pre-wrap;
|
|
121
|
+
font-size: var(--ds-font-size-2, 0.8125rem);
|
|
122
|
+
color: var(--ds-color-neutral-text-subtle, #5b5f64);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.ObMdi-watermark {
|
|
126
|
+
display: flex;
|
|
127
|
+
align-items: center;
|
|
128
|
+
justify-content: center;
|
|
129
|
+
width: 100%;
|
|
130
|
+
height: 100%;
|
|
131
|
+
color: var(--ds-color-neutral-text-subtle, #5b5f64);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.ObMdi-confirmClose-actions {
|
|
135
|
+
display: flex;
|
|
136
|
+
gap: var(--ds-size-2, 0.5rem);
|
|
137
|
+
justify-content: flex-end;
|
|
138
|
+
}
|