@casualoffice/sheets 0.17.0 → 0.19.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/dist/chrome.cjs +3339 -244
- package/dist/chrome.cjs.map +1 -1
- package/dist/chrome.js +3298 -203
- package/dist/chrome.js.map +1 -1
- package/dist/embed/embed-runtime.js +203 -157
- package/dist/index.cjs +5971 -1572
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5961 -1548
- package/dist/index.js.map +1 -1
- package/dist/sheets.cjs +4937 -538
- package/dist/sheets.cjs.map +1 -1
- package/dist/sheets.js +4945 -532
- package/dist/sheets.js.map +1 -1
- package/package.json +8 -7
- package/src/charts/ChartContextMenu.tsx +264 -0
- package/src/charts/ChartLayer.tsx +333 -0
- package/src/charts/ChartOverlay.tsx +293 -0
- package/src/charts/ChartsPanel.tsx +211 -0
- package/src/charts/FormatChartDialog.tsx +419 -0
- package/src/charts/InsertChartDialog.tsx +478 -0
- package/src/charts/build-option.ts +476 -0
- package/src/charts/charts-context.tsx +205 -0
- package/src/charts/echarts-init.ts +58 -0
- package/src/charts/hit-test.ts +130 -0
- package/src/charts/insert-chart.ts +106 -0
- package/src/charts/naming.ts +38 -0
- package/src/charts/render-to-png.ts +117 -0
- package/src/charts/resources.ts +108 -0
- package/src/charts/types.ts +239 -0
- package/src/charts/univer-dom.ts +102 -0
- package/src/chrome/CommentsPanel.tsx +427 -0
- package/src/chrome/ConditionalFormattingDialog.tsx +534 -0
- package/src/chrome/CustomSortDialog.tsx +357 -0
- package/src/chrome/DataValidationDialog.tsx +536 -0
- package/src/chrome/DeleteCellsDialog.tsx +183 -0
- package/src/chrome/GoalSeekDialog.tsx +370 -0
- package/src/chrome/HistoryPanel.tsx +319 -0
- package/src/chrome/InsertCellsDialog.tsx +185 -0
- package/src/chrome/InsertChartDialog.tsx +490 -0
- package/src/chrome/InsertFunctionDialog.tsx +493 -0
- package/src/chrome/InsertPivotDialog.tsx +488 -0
- package/src/chrome/InsertSparklineDialog.tsx +344 -0
- package/src/chrome/NameManagerDialog.tsx +378 -0
- package/src/chrome/PanelHost.tsx +55 -0
- package/src/chrome/PanelRail.tsx +90 -0
- package/src/chrome/PasteSpecialDialog.tsx +286 -0
- package/src/chrome/PivotFieldsPanel.tsx +1052 -0
- package/src/chrome/TablesPanel.tsx +301 -0
- package/src/chrome/dialog-context.tsx +24 -0
- package/src/chrome/panel-context.tsx +55 -0
- package/src/chrome/panel-registry.ts +48 -0
- package/src/sheets/CasualSheets.tsx +60 -34
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2026 Casual Office
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Chart model the in-memory store (`charts-context`) carries per
|
|
19
|
+
* inserted chart. P0 is minimal — just enough to render a column
|
|
20
|
+
* chart bound to a cell range. P1 adds the resource persistence
|
|
21
|
+
* round-trip; P2 wires Univer's drawing model for move/resize; P3
|
|
22
|
+
* expands `type` into the catalog of supported chart types.
|
|
23
|
+
*
|
|
24
|
+
* Position lives in cell coordinates rather than pixels — that's
|
|
25
|
+
* how Excel anchors charts (top-left anchored to cell A, bottom-
|
|
26
|
+
* right to cell B). We can compute pixels on the fly via
|
|
27
|
+
* `range.getCellRect()` so the chart moves with the rows/columns
|
|
28
|
+
* when they shift.
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Chart subtypes, grouped by family. Matches the most-used subset of
|
|
32
|
+
* Excel's "Insert Chart" catalog:
|
|
33
|
+
*
|
|
34
|
+
* - Column (vertical bars): clustered / stacked / 100 %-stacked.
|
|
35
|
+
* - Bar (horizontal bars): clustered / stacked / 100 %-stacked.
|
|
36
|
+
* - Line: line / stacked line.
|
|
37
|
+
* - Area: area / stacked area.
|
|
38
|
+
* - Pie: pie / doughnut.
|
|
39
|
+
* - Scatter.
|
|
40
|
+
*
|
|
41
|
+
* The legacy `'bar'` literal that P0/P1 used for "vertical column
|
|
42
|
+
* chart" is migrated to `'column'` on read (see `resources.ts`).
|
|
43
|
+
*/
|
|
44
|
+
export type ChartType =
|
|
45
|
+
| 'column'
|
|
46
|
+
| 'column-stacked'
|
|
47
|
+
| 'column-stacked-100'
|
|
48
|
+
| 'bar'
|
|
49
|
+
| 'bar-stacked'
|
|
50
|
+
| 'bar-stacked-100'
|
|
51
|
+
| 'line'
|
|
52
|
+
| 'line-stacked'
|
|
53
|
+
| 'area'
|
|
54
|
+
| 'area-stacked'
|
|
55
|
+
| 'pie'
|
|
56
|
+
| 'doughnut'
|
|
57
|
+
| 'scatter';
|
|
58
|
+
|
|
59
|
+
/** Top-level family — what shows in the left column of the Insert dialog. */
|
|
60
|
+
export type ChartFamily = 'column' | 'bar' | 'line' | 'area' | 'pie' | 'scatter';
|
|
61
|
+
|
|
62
|
+
export const CHART_FAMILY_OF: Record<ChartType, ChartFamily> = {
|
|
63
|
+
column: 'column',
|
|
64
|
+
'column-stacked': 'column',
|
|
65
|
+
'column-stacked-100': 'column',
|
|
66
|
+
bar: 'bar',
|
|
67
|
+
'bar-stacked': 'bar',
|
|
68
|
+
'bar-stacked-100': 'bar',
|
|
69
|
+
line: 'line',
|
|
70
|
+
'line-stacked': 'line',
|
|
71
|
+
area: 'area',
|
|
72
|
+
'area-stacked': 'area',
|
|
73
|
+
pie: 'pie',
|
|
74
|
+
doughnut: 'pie',
|
|
75
|
+
scatter: 'scatter',
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/** Human-readable label shown in the panel + dialog. */
|
|
79
|
+
export const CHART_TYPE_LABEL: Record<ChartType, string> = {
|
|
80
|
+
column: 'Clustered Column',
|
|
81
|
+
'column-stacked': 'Stacked Column',
|
|
82
|
+
'column-stacked-100': '100% Stacked Column',
|
|
83
|
+
bar: 'Clustered Bar',
|
|
84
|
+
'bar-stacked': 'Stacked Bar',
|
|
85
|
+
'bar-stacked-100': '100% Stacked Bar',
|
|
86
|
+
line: 'Line',
|
|
87
|
+
'line-stacked': 'Stacked Line',
|
|
88
|
+
area: 'Area',
|
|
89
|
+
'area-stacked': 'Stacked Area',
|
|
90
|
+
pie: 'Pie',
|
|
91
|
+
doughnut: 'Doughnut',
|
|
92
|
+
scatter: 'Scatter',
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export type ChartModel = {
|
|
96
|
+
id: string;
|
|
97
|
+
/** Sheet the chart lives on. Matches `FWorksheet.getSheetId()`. */
|
|
98
|
+
sheetId: string;
|
|
99
|
+
/** Source data range — first row treated as header (column names),
|
|
100
|
+
* first column as category axis labels. */
|
|
101
|
+
source: { startRow: number; endRow: number; startColumn: number; endColumn: number };
|
|
102
|
+
/** Chart position, in 0-indexed cell coordinates. */
|
|
103
|
+
pos: { startRow: number; endRow: number; startColumn: number; endColumn: number };
|
|
104
|
+
type: ChartType;
|
|
105
|
+
/** Auto-generated "Chart N" name; the user can rename via the panel
|
|
106
|
+
* or the right-click menu. Doubles as the chart title shown above
|
|
107
|
+
* the plot when `format.showTitle` is true. */
|
|
108
|
+
title?: string;
|
|
109
|
+
/** Excel's "Format Chart Area" options — none required; absent
|
|
110
|
+
* values fall back to the defaults documented in `defaultFormat`. */
|
|
111
|
+
format?: ChartFormat;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/** Equivalent of Excel's "Format Chart Area" pane in scope. */
|
|
115
|
+
export type ChartFormat = {
|
|
116
|
+
/** Render the chart title above the plot. Defaults to `true` when
|
|
117
|
+
* the chart has a `title`, `false` otherwise. */
|
|
118
|
+
showTitle?: boolean;
|
|
119
|
+
/** Legend placement. `'none'` hides the legend entirely. */
|
|
120
|
+
legend?: 'top' | 'right' | 'bottom' | 'left' | 'none';
|
|
121
|
+
/** Optional axis titles. Ignored for pie / doughnut. */
|
|
122
|
+
xAxisTitle?: string;
|
|
123
|
+
yAxisTitle?: string;
|
|
124
|
+
/** Show major gridlines on the value axis. */
|
|
125
|
+
gridlines?: boolean;
|
|
126
|
+
/** Show numeric labels on bars / lines / slices. */
|
|
127
|
+
dataLabels?: boolean;
|
|
128
|
+
/** Color palette applied to the series. Mirrors Excel's "Change
|
|
129
|
+
* Colors" picker — pick the first N from the chosen palette. */
|
|
130
|
+
palette?: ChartPalette;
|
|
131
|
+
/** Overlay a linear-regression trendline on every numeric series.
|
|
132
|
+
* Only meaningful for line / scatter / area / bar / column charts;
|
|
133
|
+
* ignored for pie. ECharts renders this via `markLine` from the
|
|
134
|
+
* computed regression endpoints. */
|
|
135
|
+
trendline?: boolean;
|
|
136
|
+
/** Per-series colour overrides, keyed by series name (the header
|
|
137
|
+
* row in the source range). Missing entries fall back to the
|
|
138
|
+
* active `palette`. Stored on the resource so the override
|
|
139
|
+
* survives reload + xlsx round-trip via the chart's `format`
|
|
140
|
+
* payload. */
|
|
141
|
+
seriesColors?: Record<string, string>;
|
|
142
|
+
/** Combo charts: per-series render-kind override, keyed by series
|
|
143
|
+
* name. Lets a column/bar/line/area chart mix bar + line series
|
|
144
|
+
* (Excel's "Combo" chart type). Missing entries fall back to the
|
|
145
|
+
* chart's base `type`. Only `'bar'` and `'line'` are offered; pie /
|
|
146
|
+
* doughnut / scatter / 100%-stacked ignore this. */
|
|
147
|
+
seriesTypes?: Record<string, 'bar' | 'line'>;
|
|
148
|
+
/** Dual axis: when a series name maps to `true`, that series is
|
|
149
|
+
* plotted against a secondary value axis (Excel's "Secondary Axis"
|
|
150
|
+
* checkbox in the Format Data Series pane). The chart then renders
|
|
151
|
+
* with two value axes — primary on the left, secondary on the
|
|
152
|
+
* right. Only meaningful for the bar / column / line / area
|
|
153
|
+
* families; ignored by pie / doughnut / scatter / 100%-stacked
|
|
154
|
+
* (a shared 0–100% scale defeats the purpose). */
|
|
155
|
+
secondaryAxis?: Record<string, boolean>;
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
export type ChartPalette = 'office' | 'mono' | 'vivid' | 'pastel';
|
|
159
|
+
|
|
160
|
+
/** Resolved (filled-in) format used by build-option. Apply over the
|
|
161
|
+
* user's partial via `mergeFormat`. */
|
|
162
|
+
export type ResolvedChartFormat = Required<Omit<ChartFormat, 'xAxisTitle' | 'yAxisTitle'>> & {
|
|
163
|
+
xAxisTitle?: string;
|
|
164
|
+
yAxisTitle?: string;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
export function defaultFormat(model: Pick<ChartModel, 'title'>): ResolvedChartFormat {
|
|
168
|
+
return {
|
|
169
|
+
showTitle: Boolean(model.title),
|
|
170
|
+
legend: 'bottom',
|
|
171
|
+
gridlines: true,
|
|
172
|
+
dataLabels: false,
|
|
173
|
+
palette: 'office',
|
|
174
|
+
trendline: false,
|
|
175
|
+
seriesColors: {},
|
|
176
|
+
seriesTypes: {},
|
|
177
|
+
secondaryAxis: {},
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export function mergeFormat(model: Pick<ChartModel, 'title' | 'format'>): ResolvedChartFormat {
|
|
182
|
+
const base = defaultFormat(model);
|
|
183
|
+
const f = model.format ?? {};
|
|
184
|
+
return {
|
|
185
|
+
showTitle: f.showTitle ?? base.showTitle,
|
|
186
|
+
legend: f.legend ?? base.legend,
|
|
187
|
+
gridlines: f.gridlines ?? base.gridlines,
|
|
188
|
+
dataLabels: f.dataLabels ?? base.dataLabels,
|
|
189
|
+
palette: f.palette ?? base.palette,
|
|
190
|
+
trendline: f.trendline ?? base.trendline,
|
|
191
|
+
seriesColors: f.seriesColors ?? base.seriesColors,
|
|
192
|
+
seriesTypes: f.seriesTypes ?? base.seriesTypes,
|
|
193
|
+
secondaryAxis: f.secondaryAxis ?? base.secondaryAxis,
|
|
194
|
+
xAxisTitle: f.xAxisTitle,
|
|
195
|
+
yAxisTitle: f.yAxisTitle,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/** Palette colours, applied in order to the series. Picked to match
|
|
200
|
+
* Excel's default colour sets so the look stays familiar. */
|
|
201
|
+
export const PALETTES: Record<ChartPalette, string[]> = {
|
|
202
|
+
office: ['#5B9BD5', '#ED7D31', '#A5A5A5', '#FFC000', '#4472C4', '#70AD47', '#264478', '#9E480E'],
|
|
203
|
+
mono: ['#1F77B4', '#3F8FBC', '#5FA7C5', '#7FBFCD', '#9FD7D6', '#BFEFDE', '#5A8DAA', '#3D6E89'],
|
|
204
|
+
vivid: ['#E63946', '#F1A208', '#06A77D', '#005F73', '#9B5DE5', '#F15BB5', '#00BBF9', '#00F5D4'],
|
|
205
|
+
pastel: ['#A3CEF1', '#FFD6A5', '#CAFFBF', '#FFADAD', '#BDB2FF', '#FDFFB6', '#FFC6FF', '#9BF6FF'],
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
export const PALETTE_LABELS: Record<ChartPalette, string> = {
|
|
209
|
+
office: 'Office',
|
|
210
|
+
mono: 'Monochromatic',
|
|
211
|
+
vivid: 'Vivid',
|
|
212
|
+
pastel: 'Pastel',
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
export const LEGEND_POSITIONS: { id: NonNullable<ChartFormat['legend']>; label: string }[] = [
|
|
216
|
+
{ id: 'bottom', label: 'Bottom' },
|
|
217
|
+
{ id: 'top', label: 'Top' },
|
|
218
|
+
{ id: 'right', label: 'Right' },
|
|
219
|
+
{ id: 'left', label: 'Left' },
|
|
220
|
+
{ id: 'none', label: 'None' },
|
|
221
|
+
];
|
|
222
|
+
|
|
223
|
+
export function newChartId(): string {
|
|
224
|
+
return `ch-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Plugin-resource name we use when stashing chart models in
|
|
229
|
+
* `IWorkbookData.resources`. Mirrors `OUTLINE_RESOURCE_NAME` — survives
|
|
230
|
+
* xlsx via the hidden `__casual_sheets_resources__` sheet and survives
|
|
231
|
+
* collab via Univer's snapshot-load path.
|
|
232
|
+
*/
|
|
233
|
+
export const CHARTS_RESOURCE_NAME = '__casual_sheets_charts__';
|
|
234
|
+
|
|
235
|
+
/** Versioned envelope so a future schema change can be detected. */
|
|
236
|
+
export type ChartsResourceV1 = {
|
|
237
|
+
v: 1;
|
|
238
|
+
charts: ChartModel[];
|
|
239
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2026 Casual Office
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Helpers for reaching into Univer's mounted DOM. Internal Univer DOM
|
|
19
|
+
* identifiers are not part of the public API and have shifted between
|
|
20
|
+
* minor versions — centralise the selectors here so a Univer upgrade
|
|
21
|
+
* needs one fix instead of touching every overlay that anchors to the
|
|
22
|
+
* canvas (PresenceLayer, ChartLayer, future drawing/comment overlays).
|
|
23
|
+
*
|
|
24
|
+
* Every helper falls back to a structural query and warns once if it
|
|
25
|
+
* had to use the fallback, so a silent overlay-disappears regression
|
|
26
|
+
* surfaces in the console instead of looking like a sync bug.
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import type { FUniver } from '@univerjs/core/facade';
|
|
30
|
+
|
|
31
|
+
const PRIMARY_CANVAS_SELECTOR = 'canvas[id^="univer-sheet-main-canvas_"]';
|
|
32
|
+
/** Univer mounts a hidden formula-editor canvas BEFORE the main grid
|
|
33
|
+
* canvas. That one has no id, sits with width/height = 0, and is
|
|
34
|
+
* useless to anchor overlays to. The fallback path must explicitly
|
|
35
|
+
* skip it — picking it caused PresenceLayer / ChartLayer to render
|
|
36
|
+
* cursors at the wrong position whenever the primary selector raced
|
|
37
|
+
* the main-canvas mount. */
|
|
38
|
+
let fallbackWarned = false;
|
|
39
|
+
|
|
40
|
+
export function getUniverHost(): HTMLElement | null {
|
|
41
|
+
return document.querySelector('[data-testid="univer-host"]') as HTMLElement | null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function getUniverMainCanvas(host: HTMLElement): HTMLCanvasElement | null {
|
|
45
|
+
const primary = host.querySelector(PRIMARY_CANVAS_SELECTOR) as HTMLCanvasElement | null;
|
|
46
|
+
if (primary) return primary;
|
|
47
|
+
// Walk all canvases and pick the first one that LOOKS like the main
|
|
48
|
+
// grid: has a non-empty id AND a non-zero rendered size. Editor
|
|
49
|
+
// canvases have empty ids and 0x0 boxes until focused. We refuse to
|
|
50
|
+
// return any of those — better to render no overlay than to anchor
|
|
51
|
+
// it to a hidden offscreen canvas.
|
|
52
|
+
const all = Array.from(host.querySelectorAll('canvas')) as HTMLCanvasElement[];
|
|
53
|
+
for (const c of all) {
|
|
54
|
+
if (!c.id) continue;
|
|
55
|
+
const r = c.getBoundingClientRect();
|
|
56
|
+
if (r.width < 50 || r.height < 50) continue;
|
|
57
|
+
if (!fallbackWarned) {
|
|
58
|
+
fallbackWarned = true;
|
|
59
|
+
console.warn(
|
|
60
|
+
'[univer-dom] primary canvas selector "%s" matched nothing — using fallback id "%s". Update PRIMARY_CANVAS_SELECTOR after a Univer upgrade.',
|
|
61
|
+
PRIMARY_CANVAS_SELECTOR,
|
|
62
|
+
c.id,
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
return c;
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Pixel offset between the canvas top-left and the cell-content area's
|
|
72
|
+
* top-left — i.e. the row-header gutter width and the column-header
|
|
73
|
+
* gutter height. Every overlay that anchors to `getCellRect()`
|
|
74
|
+
* coordinates must add these to land on the actual cells instead of
|
|
75
|
+
* ~40 px up-and-left of them.
|
|
76
|
+
*
|
|
77
|
+
* We use Univer 0.22.x's documented defaults (row header = 46 px,
|
|
78
|
+
* column header = 20 px) rather than reaching into the render
|
|
79
|
+
* skeleton at runtime — the dynamic lookup via
|
|
80
|
+
* `RenderUnit.with(SheetSkeletonManagerService)` instantiates the
|
|
81
|
+
* service through redi, which transitively requires
|
|
82
|
+
* `SheetScrollManagerService` that may not yet be registered on the
|
|
83
|
+
* unit's injector when our rAF tick fires (race with Univer's
|
|
84
|
+
* render-unit init). The crash surfaces as
|
|
85
|
+
* "QuantityCheckError: Expect 1 dependency item(s) for id
|
|
86
|
+
* 'SheetScrollManagerService' but get 0".
|
|
87
|
+
*
|
|
88
|
+
* Hardcoding the defaults trades ~40 px accuracy for any user who
|
|
89
|
+
* customises header sizes (rare, undocumented in our app) for
|
|
90
|
+
* zero-risk init. If you change Univer's default theme, update
|
|
91
|
+
* these constants and the cursor/chart layers stay aligned.
|
|
92
|
+
*/
|
|
93
|
+
export type HeaderGutter = { rowHeaderWidth: number; columnHeaderHeight: number };
|
|
94
|
+
|
|
95
|
+
const DEFAULT_HEADER_GUTTER: HeaderGutter = {
|
|
96
|
+
rowHeaderWidth: 46,
|
|
97
|
+
columnHeaderHeight: 20,
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export function getHeaderGutter(_api: FUniver | null): HeaderGutter {
|
|
101
|
+
return DEFAULT_HEADER_GUTTER;
|
|
102
|
+
}
|