@einfach-excel/spreadsheet-ui-styles 0.0.0-stage → 0.2.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/LICENSE +21 -0
- package/README.md +37 -2
- package/features/comment-thread.css +169 -0
- package/features/comment-thread.css.d.ts +2 -0
- package/features/conditional-format-dialog.css +254 -0
- package/features/conditional-format-dialog.css.d.ts +7 -0
- package/features/conditional-format-fields.css +10 -0
- package/features/conditional-format-fields.css.d.ts +2 -0
- package/features/data-validation-dialog.css +197 -0
- package/features/data-validation-dialog.css.d.ts +7 -0
- package/features/filter-dropdown.css +177 -0
- package/features/filter-dropdown.css.d.ts +2 -0
- package/features/find-replace-actions.css +13 -0
- package/features/find-replace-actions.css.d.ts +2 -0
- package/features/find-replace-dialog.css +147 -0
- package/features/find-replace-dialog.css.d.ts +2 -0
- package/features/find-replace-status-messages.css +19 -0
- package/features/find-replace-status-messages.css.d.ts +2 -0
- package/features/format-cells-dialog.css +296 -0
- package/features/format-cells-dialog.css.d.ts +2 -0
- package/features/format-cells-panels.css +154 -0
- package/features/format-cells-panels.css.d.ts +2 -0
- package/features/go-to-dialog.css +205 -0
- package/features/go-to-dialog.css.d.ts +2 -0
- package/features/menu-help-dialog.css +82 -0
- package/features/name-manager-dialog.css +276 -0
- package/features/number-format-dialog.css +147 -0
- package/features/number-format-dialog.css.d.ts +2 -0
- package/features/page-setup-dialog.css +167 -0
- package/features/page-setup-dialog.css.d.ts +3 -0
- package/features/paste-special-dialog.css +126 -0
- package/features/paste-special-dialog.css.d.ts +7 -0
- package/features/print-preview-dialog.css +197 -0
- package/features/print-preview-dialog.css.d.ts +3 -0
- package/features/protection-unlock-dialog.css +127 -0
- package/features/remove-duplicates-dialog.css +165 -0
- package/features/remove-duplicates-dialog.css.d.ts +7 -0
- package/features/sheet-tab-delete-dialog.css +64 -0
- package/features/sheet-tab-delete-dialog.css.d.ts +3 -0
- package/features/sort-confirmation-dialog.css +157 -0
- package/features/sort-confirmation-dialog.css.d.ts +2 -0
- package/features/text-to-columns-dialog.css +246 -0
- package/features/text-to-columns-dialog.css.d.ts +2 -0
- package/features/toolbar-shell.css +46 -0
- package/features/toolbar-shell.css.d.ts +2 -0
- package/package.json +40 -3
- package/styles/button-states.css +45 -0
- package/styles/chrome-tokens.css +124 -0
- package/styles/demo-header.css +23 -0
- package/styles/demo-two-column.css +115 -0
- package/styles/diagnostics.css +127 -0
- package/styles/dialog-skin.css +143 -0
- package/styles/formula-autocomplete.css +87 -0
- package/styles/formula-bar-row.css +51 -0
- package/styles/grid-cells.css +254 -0
- package/styles/grid-frame.css +268 -0
- package/styles/grid-headers.css +99 -0
- package/styles/grid-overlays.css +160 -0
- package/styles/help-overlay.css +67 -0
- package/styles/history-panel.css +127 -0
- package/styles/index.css +26 -0
- package/styles/locked-edit-feedback.css +45 -0
- package/styles/marching-ants.css +18 -0
- package/styles/menu-bar.css +97 -0
- package/styles/name-box.css +89 -0
- package/styles/presence-overlay.css +36 -0
- package/styles/shared-context-menu.css +50 -0
- package/styles/shared-format-toolbar.css +82 -0
- package/styles/shared-sheet-tabs.css +138 -0
- package/styles/sheet-tabs.css +98 -0
- package/styles/status-bar.css +161 -0
- package/styles/toolbar-popovers.css +278 -0
- package/styles/toolbar.css +213 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/* === vNext Grid === */
|
|
2
|
+
|
|
3
|
+
.vnext-demo {
|
|
4
|
+
overflow: auto;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.spreadsheet-grid {
|
|
8
|
+
overflow: hidden;
|
|
9
|
+
max-height: 70vh;
|
|
10
|
+
max-width: 100%;
|
|
11
|
+
border: 1px solid var(--border);
|
|
12
|
+
font-size: 13px;
|
|
13
|
+
outline: none;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.spreadsheet-grid-scroll-viewport {
|
|
17
|
+
overflow: auto;
|
|
18
|
+
max-height: 70vh;
|
|
19
|
+
max-width: 100%;
|
|
20
|
+
/* `none` disables BOTH the scroll-chain to the parent page AND the
|
|
21
|
+
* rubber-band overscroll on this element itself. `contain` would only
|
|
22
|
+
* stop the chain — the inner viewport would still bounce at the edge. */
|
|
23
|
+
overscroll-behavior: none;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.spreadsheet-grid-overlay-layer {
|
|
27
|
+
position: absolute;
|
|
28
|
+
inset: 0;
|
|
29
|
+
overflow: hidden;
|
|
30
|
+
pointer-events: none;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/* 刻意不给网格根画焦点光晕:焦点位置由活动单元格边框表达(Excel 口径),
|
|
34
|
+
键盘可见性由 overlay 的选区框保证。 */
|
|
35
|
+
|
|
36
|
+
/*
|
|
37
|
+
* Format-painter cursor feedback. SpreadsheetFormatPainter mirrors the
|
|
38
|
+
* painter state onto the grid root via data-format-painter-active="armed"
|
|
39
|
+
* or "sticky". Without this rule, the only signal the painter is armed is
|
|
40
|
+
* the toolbar button — easy to miss when the user's eyes are on the grid.
|
|
41
|
+
*/
|
|
42
|
+
.spreadsheet-grid[data-format-painter-active] .cell,
|
|
43
|
+
.spreadsheet-grid[data-format-painter-active] .spreadsheet-grid-cell {
|
|
44
|
+
cursor: copy;
|
|
45
|
+
}
|
|
46
|
+
.spreadsheet-grid[data-format-painter-active='sticky'] {
|
|
47
|
+
outline: 2px dashed var(--office-blue);
|
|
48
|
+
outline-offset: -2px;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.spreadsheet-grid-table {
|
|
52
|
+
border-collapse: collapse;
|
|
53
|
+
table-layout: fixed;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.spreadsheet-grid-virtual-spacer {
|
|
57
|
+
border: 0;
|
|
58
|
+
padding: 0;
|
|
59
|
+
background: transparent;
|
|
60
|
+
pointer-events: none;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.spreadsheet-grid-corner,
|
|
64
|
+
.spreadsheet-grid-col-header,
|
|
65
|
+
.spreadsheet-grid-row-header,
|
|
66
|
+
.spreadsheet-grid-cell {
|
|
67
|
+
border: 1px solid var(--gridline);
|
|
68
|
+
padding: 0;
|
|
69
|
+
height: 24px;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.spreadsheet-grid-cell {
|
|
73
|
+
position: relative;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.spreadsheet-grid-cell.cell-merge-anchor {
|
|
77
|
+
overflow: hidden;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.spreadsheet-grid-cell[data-validation-severity]::after {
|
|
81
|
+
content: '';
|
|
82
|
+
position: absolute;
|
|
83
|
+
top: 1px;
|
|
84
|
+
right: 1px;
|
|
85
|
+
width: 0;
|
|
86
|
+
height: 0;
|
|
87
|
+
border-top: 7px solid #d97706;
|
|
88
|
+
border-left: 7px solid transparent;
|
|
89
|
+
pointer-events: none;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
.spreadsheet-grid-cell[data-validation-severity='error']::after {
|
|
93
|
+
border-top-color: #dc2626;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.spreadsheet-grid-col-header,
|
|
97
|
+
.spreadsheet-grid-cell {
|
|
98
|
+
width: 96px;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.spreadsheet-grid-corner,
|
|
102
|
+
.spreadsheet-grid-row-header {
|
|
103
|
+
width: 44px;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.spreadsheet-grid-col-header,
|
|
107
|
+
.spreadsheet-grid-row-header,
|
|
108
|
+
.spreadsheet-grid-corner {
|
|
109
|
+
background: var(--bg-chrome);
|
|
110
|
+
color: var(--text-muted);
|
|
111
|
+
font-weight: 400;
|
|
112
|
+
text-align: center;
|
|
113
|
+
user-select: none;
|
|
114
|
+
font-size: 12px;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.spreadsheet-grid-col-header,
|
|
118
|
+
.spreadsheet-grid-row-header,
|
|
119
|
+
.spreadsheet-grid-corner {
|
|
120
|
+
cursor: pointer;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* Make column headers / row headers / corner stick to the edges of the scroll
|
|
124
|
+
* viewport. This unlocks freeze rows/cols because the frozen cells then layer
|
|
125
|
+
* underneath the always-visible headers, and also fixes a long-standing UX
|
|
126
|
+
* gap (headers used to scroll out of view). */
|
|
127
|
+
.spreadsheet-grid-col-header {
|
|
128
|
+
position: sticky;
|
|
129
|
+
top: 0;
|
|
130
|
+
z-index: 2;
|
|
131
|
+
}
|
|
132
|
+
.spreadsheet-grid-row-header {
|
|
133
|
+
position: sticky;
|
|
134
|
+
left: 0;
|
|
135
|
+
z-index: 2;
|
|
136
|
+
}
|
|
137
|
+
.spreadsheet-grid-corner {
|
|
138
|
+
position: sticky;
|
|
139
|
+
top: 0;
|
|
140
|
+
left: 0;
|
|
141
|
+
z-index: 3;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/* Frozen rows / cols / corner — set by SpreadsheetGrid via data attribute.
|
|
145
|
+
* `top` and `left` offsets are supplied inline because they depend on
|
|
146
|
+
* cumulative row heights / column widths. Z-index layers above plain cells
|
|
147
|
+
* (1) and below headers (2/3). */
|
|
148
|
+
.spreadsheet-grid-cell[data-frozen-row] {
|
|
149
|
+
position: sticky;
|
|
150
|
+
z-index: 1;
|
|
151
|
+
background: var(--bg-cell);
|
|
152
|
+
}
|
|
153
|
+
.spreadsheet-grid-cell[data-frozen-col] {
|
|
154
|
+
position: sticky;
|
|
155
|
+
z-index: 1;
|
|
156
|
+
background: var(--bg-cell);
|
|
157
|
+
}
|
|
158
|
+
.spreadsheet-grid-cell[data-frozen-row][data-frozen-col] {
|
|
159
|
+
z-index: 2;
|
|
160
|
+
}
|
|
161
|
+
/* Frozen headers must outrank both their non-frozen siblings (which already
|
|
162
|
+
* sit at z 2/3 thanks to the .spreadsheet-grid scoped sticky rules below)
|
|
163
|
+
* AND the corner (z 4). Otherwise non-frozen headers scrolling past land on
|
|
164
|
+
* top in source-order ties. */
|
|
165
|
+
.spreadsheet-grid .spreadsheet-grid-col-header[data-frozen-col='true'],
|
|
166
|
+
.spreadsheet-grid .spreadsheet-grid-row-header[data-frozen-row='true'] {
|
|
167
|
+
z-index: 5;
|
|
168
|
+
}
|
|
169
|
+
.spreadsheet-grid-row-header[data-frozen-row] {
|
|
170
|
+
position: sticky;
|
|
171
|
+
z-index: 5;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/* Outline (grouping) gutter — renders only when the sheet has row/column
|
|
175
|
+
* groups. Row gutter cells stick to the left edge like row headers; the
|
|
176
|
+
* column band sticks to the top like column headers. Slot layout lives in
|
|
177
|
+
* an inner flex wrapper because flex on a th breaks table column sizing. */
|
|
178
|
+
.spreadsheet-grid-outline-row-cell,
|
|
179
|
+
.spreadsheet-grid-outline-header,
|
|
180
|
+
.spreadsheet-grid-outline-col-cell,
|
|
181
|
+
.spreadsheet-grid-outline-corner {
|
|
182
|
+
border: 1px solid var(--gridline);
|
|
183
|
+
padding: 0;
|
|
184
|
+
background: var(--bg-chrome);
|
|
185
|
+
user-select: none;
|
|
186
|
+
}
|
|
187
|
+
.spreadsheet-grid-outline-row-cell {
|
|
188
|
+
position: sticky;
|
|
189
|
+
left: 0;
|
|
190
|
+
z-index: 2;
|
|
191
|
+
}
|
|
192
|
+
.spreadsheet-grid-outline-col-cell {
|
|
193
|
+
position: sticky;
|
|
194
|
+
top: 0;
|
|
195
|
+
z-index: 2;
|
|
196
|
+
}
|
|
197
|
+
.spreadsheet-grid-outline-header {
|
|
198
|
+
position: sticky;
|
|
199
|
+
left: 0;
|
|
200
|
+
top: 0;
|
|
201
|
+
z-index: 4;
|
|
202
|
+
}
|
|
203
|
+
.spreadsheet-grid-outline-corner {
|
|
204
|
+
position: sticky;
|
|
205
|
+
left: 0;
|
|
206
|
+
top: 0;
|
|
207
|
+
z-index: 4;
|
|
208
|
+
}
|
|
209
|
+
.spreadsheet-outline-slots {
|
|
210
|
+
display: flex;
|
|
211
|
+
width: 100%;
|
|
212
|
+
height: 100%;
|
|
213
|
+
align-items: stretch;
|
|
214
|
+
justify-content: center;
|
|
215
|
+
}
|
|
216
|
+
.spreadsheet-outline-slots[data-axis='column'] {
|
|
217
|
+
flex-direction: column;
|
|
218
|
+
}
|
|
219
|
+
.spreadsheet-outline-slot {
|
|
220
|
+
display: flex;
|
|
221
|
+
align-items: center;
|
|
222
|
+
justify-content: center;
|
|
223
|
+
flex: 0 0 14px;
|
|
224
|
+
min-width: 0;
|
|
225
|
+
min-height: 0;
|
|
226
|
+
}
|
|
227
|
+
.spreadsheet-outline-line {
|
|
228
|
+
display: block;
|
|
229
|
+
background: var(--border-strong);
|
|
230
|
+
}
|
|
231
|
+
.spreadsheet-outline-slots[data-axis='row'] .spreadsheet-outline-line {
|
|
232
|
+
width: 2px;
|
|
233
|
+
height: 100%;
|
|
234
|
+
}
|
|
235
|
+
.spreadsheet-outline-slots[data-axis='column'] .spreadsheet-outline-line {
|
|
236
|
+
height: 2px;
|
|
237
|
+
width: 100%;
|
|
238
|
+
}
|
|
239
|
+
.spreadsheet-outline-toggle,
|
|
240
|
+
.spreadsheet-outline-level-button {
|
|
241
|
+
display: inline-flex;
|
|
242
|
+
align-items: center;
|
|
243
|
+
justify-content: center;
|
|
244
|
+
width: 12px;
|
|
245
|
+
height: 12px;
|
|
246
|
+
padding: 0;
|
|
247
|
+
border: 1px solid var(--border-strong);
|
|
248
|
+
border-radius: 2px;
|
|
249
|
+
background: var(--bg-surface);
|
|
250
|
+
color: var(--text-default);
|
|
251
|
+
font-size: 9px;
|
|
252
|
+
line-height: 1;
|
|
253
|
+
cursor: pointer;
|
|
254
|
+
}
|
|
255
|
+
.spreadsheet-outline-toggle:hover,
|
|
256
|
+
.spreadsheet-outline-level-button:hover {
|
|
257
|
+
background: var(--hover);
|
|
258
|
+
}
|
|
259
|
+
.spreadsheet-grid-outline-header,
|
|
260
|
+
.spreadsheet-grid-outline-corner {
|
|
261
|
+
text-align: center;
|
|
262
|
+
vertical-align: middle;
|
|
263
|
+
}
|
|
264
|
+
.spreadsheet-grid-outline-header .spreadsheet-outline-level-button,
|
|
265
|
+
.spreadsheet-grid-outline-corner .spreadsheet-outline-level-button {
|
|
266
|
+
margin: 1px;
|
|
267
|
+
}
|
|
268
|
+
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/* === B. Grid headers + selection chrome ============================== */
|
|
2
|
+
|
|
3
|
+
.spreadsheet-grid {
|
|
4
|
+
font-family: var(--excel-font);
|
|
5
|
+
font-size: 13px;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.spreadsheet-grid .spreadsheet-grid-table {
|
|
9
|
+
border-collapse: separate;
|
|
10
|
+
border-spacing: 0;
|
|
11
|
+
background: var(--bg-cell);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* Top-left empty corner — pinned, slightly darker chrome */
|
|
15
|
+
.spreadsheet-grid .spreadsheet-grid-corner {
|
|
16
|
+
background: var(--bg-chrome);
|
|
17
|
+
border-right: 1px solid var(--border);
|
|
18
|
+
border-bottom: 1px solid var(--border);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/* Column letters */
|
|
22
|
+
.spreadsheet-grid .spreadsheet-grid-col-header {
|
|
23
|
+
position: relative;
|
|
24
|
+
height: 24px;
|
|
25
|
+
padding: 0 4px;
|
|
26
|
+
background: var(--bg-chrome);
|
|
27
|
+
border-right: 1px solid var(--border);
|
|
28
|
+
border-bottom: 1px solid var(--border);
|
|
29
|
+
color: var(--text-muted);
|
|
30
|
+
font-weight: 400;
|
|
31
|
+
text-align: center;
|
|
32
|
+
user-select: none;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.spreadsheet-grid .spreadsheet-grid-col-header.is-in-selection {
|
|
36
|
+
background: var(--header-selected-bg);
|
|
37
|
+
color: var(--header-selected-text);
|
|
38
|
+
font-weight: 600;
|
|
39
|
+
border-bottom: 2px solid var(--excel-green);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* 整列选中(点击列字母):实心品牌绿,Excel 口径。 */
|
|
43
|
+
.spreadsheet-grid .spreadsheet-grid-col-header.is-selected {
|
|
44
|
+
background: var(--header-full-selected-bg);
|
|
45
|
+
color: var(--text-on-accent);
|
|
46
|
+
font-weight: 600;
|
|
47
|
+
border-bottom: 2px solid var(--excel-green);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.spreadsheet-grid .spreadsheet-grid-col-header .spreadsheet-grid-header-label {
|
|
51
|
+
display: inline-block;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* Row numbers */
|
|
55
|
+
.spreadsheet-grid .spreadsheet-grid-row-header {
|
|
56
|
+
width: 36px;
|
|
57
|
+
padding: 0 6px;
|
|
58
|
+
background: var(--bg-chrome);
|
|
59
|
+
border-right: 1px solid var(--border);
|
|
60
|
+
border-bottom: 1px solid var(--border);
|
|
61
|
+
color: var(--text-muted);
|
|
62
|
+
font-weight: 400;
|
|
63
|
+
text-align: right;
|
|
64
|
+
user-select: none;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.spreadsheet-grid .spreadsheet-grid-corner,
|
|
68
|
+
.spreadsheet-grid .spreadsheet-grid-col-header {
|
|
69
|
+
position: sticky;
|
|
70
|
+
top: 0;
|
|
71
|
+
z-index: 3;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.spreadsheet-grid .spreadsheet-grid-corner,
|
|
75
|
+
.spreadsheet-grid .spreadsheet-grid-row-header {
|
|
76
|
+
position: sticky;
|
|
77
|
+
left: 0;
|
|
78
|
+
z-index: 2;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.spreadsheet-grid .spreadsheet-grid-corner {
|
|
82
|
+
z-index: 4;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.spreadsheet-grid .spreadsheet-grid-row-header.is-in-selection {
|
|
86
|
+
background: var(--header-selected-bg);
|
|
87
|
+
color: var(--header-selected-text);
|
|
88
|
+
font-weight: 600;
|
|
89
|
+
border-right: 2px solid var(--excel-green);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* 整行选中(点击行号):实心品牌绿。 */
|
|
93
|
+
.spreadsheet-grid .spreadsheet-grid-row-header.is-selected {
|
|
94
|
+
background: var(--header-full-selected-bg);
|
|
95
|
+
color: var(--text-on-accent);
|
|
96
|
+
font-weight: 600;
|
|
97
|
+
border-right: 2px solid var(--excel-green);
|
|
98
|
+
}
|
|
99
|
+
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/* Freeze boundary divider — single SVG overlay drawn once per grid root
|
|
2
|
+
* (NOT inside the scroll viewport), so it sits at the seam between pinned
|
|
3
|
+
* and scrollable regions without participating in scroll. The line positions
|
|
4
|
+
* recompute when freezeRowCount / freezeColCount / row heights / column
|
|
5
|
+
* widths change, but not on scroll — the boundary is anchored to the grid
|
|
6
|
+
* chrome, not the table content.
|
|
7
|
+
*
|
|
8
|
+
* z-index sits below the selection canvas overlay (which has no explicit
|
|
9
|
+
* z-index; rendered after in DOM order) so marching ants / fill handle
|
|
10
|
+
* always paint on top of the divider. */
|
|
11
|
+
.spreadsheet-grid-freeze-boundary {
|
|
12
|
+
position: absolute;
|
|
13
|
+
inset: 0;
|
|
14
|
+
width: 100%;
|
|
15
|
+
height: 100%;
|
|
16
|
+
pointer-events: none;
|
|
17
|
+
overflow: visible;
|
|
18
|
+
/* Above corner (4) and frozen headers (5) so the seam line is visible
|
|
19
|
+
* across the entire grid including the frozen header bands. */
|
|
20
|
+
z-index: 6;
|
|
21
|
+
}
|
|
22
|
+
.spreadsheet-grid-freeze-boundary line {
|
|
23
|
+
stroke: var(--border-strong);
|
|
24
|
+
stroke-width: 2;
|
|
25
|
+
shape-rendering: crispEdges;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.spreadsheet-grid-header-label {
|
|
29
|
+
display: inline-flex;
|
|
30
|
+
align-items: center;
|
|
31
|
+
justify-content: center;
|
|
32
|
+
width: 100%;
|
|
33
|
+
height: 100%;
|
|
34
|
+
pointer-events: none;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.spreadsheet-grid-col-resize-handle,
|
|
38
|
+
.spreadsheet-grid-row-resize-handle {
|
|
39
|
+
position: absolute;
|
|
40
|
+
z-index: 2;
|
|
41
|
+
border: 0;
|
|
42
|
+
padding: 0;
|
|
43
|
+
background: transparent;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.spreadsheet-grid-col-resize-handle {
|
|
47
|
+
top: 0;
|
|
48
|
+
right: -3px;
|
|
49
|
+
bottom: 0;
|
|
50
|
+
width: 6px;
|
|
51
|
+
cursor: col-resize;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.spreadsheet-grid-row-resize-handle {
|
|
55
|
+
right: 0;
|
|
56
|
+
bottom: -3px;
|
|
57
|
+
left: 0;
|
|
58
|
+
height: 6px;
|
|
59
|
+
cursor: row-resize;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.spreadsheet-grid-col-resize-handle:hover,
|
|
63
|
+
.spreadsheet-grid-row-resize-handle:hover {
|
|
64
|
+
background: var(--resize-hint);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/* 选中态表头的取色统一在 grid-headers.css(绿色系),这里不再另立蓝色系。 */
|
|
68
|
+
.spreadsheet-grid-corner[data-selected='true'] {
|
|
69
|
+
background: var(--header-selected-bg);
|
|
70
|
+
color: var(--header-selected-text);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
.spreadsheet-grid-cell-button {
|
|
74
|
+
/*
|
|
75
|
+
* Flex column so the inner `.cell-display` can pick its vertical position
|
|
76
|
+
* via `margin-top: auto` / `margin-bottom: auto`, driven from
|
|
77
|
+
* SpreadsheetCellFormat.verticalAlign in the cell renderer.
|
|
78
|
+
*/
|
|
79
|
+
display: flex;
|
|
80
|
+
flex-direction: column;
|
|
81
|
+
width: 100%;
|
|
82
|
+
height: 100%;
|
|
83
|
+
border: 0;
|
|
84
|
+
padding: 0;
|
|
85
|
+
/* `inherit` (not `transparent`) so the parent TD's inline fill propagates
|
|
86
|
+
* down to the .cell-display child via `background-color: inherit`. The
|
|
87
|
+
* fill renderer paints bgColor onto the TD inline; intermediate elements
|
|
88
|
+
* must hand the value through or the span ends up transparent. */
|
|
89
|
+
background-color: inherit;
|
|
90
|
+
color: inherit;
|
|
91
|
+
font: inherit;
|
|
92
|
+
text-align: left;
|
|
93
|
+
position: relative;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.spreadsheet-grid-data-bar {
|
|
97
|
+
position: absolute;
|
|
98
|
+
top: 20%;
|
|
99
|
+
left: 2px;
|
|
100
|
+
z-index: 0;
|
|
101
|
+
height: 60%;
|
|
102
|
+
max-width: calc(100% - 4px);
|
|
103
|
+
border-radius: 2px;
|
|
104
|
+
pointer-events: none;
|
|
105
|
+
background: linear-gradient(90deg, var(--data-bar-min-color), var(--data-bar-max-color));
|
|
106
|
+
opacity: 0.58;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.spreadsheet-grid-cell-button > .cell-display {
|
|
110
|
+
position: relative;
|
|
111
|
+
z-index: 1;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.cell-rich-link {
|
|
115
|
+
color: var(--office-blue-text);
|
|
116
|
+
text-decoration: underline;
|
|
117
|
+
text-underline-offset: 2px;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.cell-rich-text {
|
|
121
|
+
display: inline;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
.spreadsheet-grid-fill-handle {
|
|
125
|
+
position: absolute;
|
|
126
|
+
right: -3px;
|
|
127
|
+
bottom: -3px;
|
|
128
|
+
z-index: 3;
|
|
129
|
+
width: 7px;
|
|
130
|
+
height: 7px;
|
|
131
|
+
border: 1px solid var(--bg-cell);
|
|
132
|
+
padding: 0;
|
|
133
|
+
background: var(--excel-green);
|
|
134
|
+
cursor: crosshair;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.cell-fill-preview {
|
|
138
|
+
box-shadow: inset 0 0 0 1px var(--excel-green);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/* Range cell highlight (every cell in the rectangle EXCEPT the focus cell).
|
|
142
|
+
* Lighter blue so the focus cell's outline + tint still pop. */
|
|
143
|
+
.cell-in-range {
|
|
144
|
+
background: var(--select-bg);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/* Hover override inside a range — keep the range tint visible instead of
|
|
148
|
+
* the generic hover blue, which would otherwise wipe the visual. */
|
|
149
|
+
.cell-in-range:hover {
|
|
150
|
+
background: var(--select-bg);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/* 动态数组溢出区(ADR 0006 阶段 3)。外圈的细蓝框由 overlay 画;这里只给区内每格
|
|
154
|
+
* 一层极淡的蓝,让「这一片是一个数组」在框之外也读得出来。
|
|
155
|
+
*
|
|
156
|
+
* 刻意用低特异性的单类选择器:`.spreadsheet-grid .spreadsheet-grid-cell.cell-active`
|
|
157
|
+
* 一类的选区底色特异性更高,所以选中态永远压得住这层。 */
|
|
158
|
+
.cell-spill {
|
|
159
|
+
background: var(--spill-tint);
|
|
160
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/* Help overlay (Keyboard Shortcuts / About) — centered card. */
|
|
2
|
+
.spreadsheet-help-overlay {
|
|
3
|
+
position: fixed;
|
|
4
|
+
top: 50%;
|
|
5
|
+
left: 50%;
|
|
6
|
+
transform: translate(-50%, -50%);
|
|
7
|
+
z-index: 1000;
|
|
8
|
+
min-width: 320px;
|
|
9
|
+
max-width: 480px;
|
|
10
|
+
background: var(--bg, #fff);
|
|
11
|
+
border: 1px solid var(--border, #d0d0d0);
|
|
12
|
+
border-radius: 6px;
|
|
13
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
|
|
14
|
+
padding: 16px 20px;
|
|
15
|
+
font-size: 13px;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.spreadsheet-help-overlay-title {
|
|
19
|
+
margin: 0 0 12px 0;
|
|
20
|
+
font-size: 15px;
|
|
21
|
+
font-weight: 600;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.spreadsheet-help-overlay-body {
|
|
25
|
+
margin: 0 0 12px 0;
|
|
26
|
+
line-height: 1.5;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.spreadsheet-help-overlay-shortcut-list {
|
|
30
|
+
list-style: none;
|
|
31
|
+
margin: 0 0 12px 0;
|
|
32
|
+
padding: 0;
|
|
33
|
+
display: grid;
|
|
34
|
+
grid-template-columns: max-content 1fr;
|
|
35
|
+
gap: 6px 16px;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.spreadsheet-help-overlay-shortcut-item {
|
|
39
|
+
display: contents;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
.spreadsheet-help-overlay-keys {
|
|
43
|
+
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
44
|
+
background: var(--bg-muted, #f1f1f1);
|
|
45
|
+
border: 1px solid var(--border, #d0d0d0);
|
|
46
|
+
border-radius: 3px;
|
|
47
|
+
padding: 1px 6px;
|
|
48
|
+
font-size: 12px;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.spreadsheet-help-overlay-actions {
|
|
52
|
+
display: flex;
|
|
53
|
+
justify-content: flex-end;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.spreadsheet-help-overlay-close {
|
|
57
|
+
padding: 4px 12px;
|
|
58
|
+
border: 1px solid var(--border, #d0d0d0);
|
|
59
|
+
background: var(--bg-muted, #f7f7f7);
|
|
60
|
+
border-radius: 3px;
|
|
61
|
+
cursor: pointer;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.spreadsheet-help-overlay-close:hover {
|
|
65
|
+
background: var(--bg-hover, #ececec);
|
|
66
|
+
}
|
|
67
|
+
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/* === History timeline panel (demo right-rail) ====================================== */
|
|
2
|
+
|
|
3
|
+
.spreadsheet-history-timeline {
|
|
4
|
+
display: flex;
|
|
5
|
+
flex-direction: column;
|
|
6
|
+
gap: 6px;
|
|
7
|
+
padding: 8px 10px;
|
|
8
|
+
border-top: 1px solid var(--border);
|
|
9
|
+
background: var(--bg-chrome);
|
|
10
|
+
font-family: var(--excel-font);
|
|
11
|
+
font-size: 12px;
|
|
12
|
+
color: var(--text-default);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.history-timeline-controls {
|
|
16
|
+
display: inline-flex;
|
|
17
|
+
align-items: center;
|
|
18
|
+
gap: 6px;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.history-timeline-btn {
|
|
22
|
+
display: inline-flex;
|
|
23
|
+
align-items: center;
|
|
24
|
+
height: 22px;
|
|
25
|
+
padding: 0 10px;
|
|
26
|
+
border: 1px solid var(--border);
|
|
27
|
+
border-radius: 2px;
|
|
28
|
+
background: var(--bg-surface);
|
|
29
|
+
color: var(--text-default);
|
|
30
|
+
font: inherit;
|
|
31
|
+
cursor: pointer;
|
|
32
|
+
transition: background 100ms ease-out, border-color 100ms ease-out;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.history-timeline-btn:not(:disabled):hover {
|
|
36
|
+
background: var(--hover);
|
|
37
|
+
border-color: var(--border-strong);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.history-timeline-btn:disabled {
|
|
41
|
+
color: var(--text-muted);
|
|
42
|
+
background: transparent;
|
|
43
|
+
cursor: default;
|
|
44
|
+
opacity: 0.6;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.history-timeline-cursor {
|
|
48
|
+
margin-left: 4px;
|
|
49
|
+
color: var(--text-muted);
|
|
50
|
+
font-variant-numeric: tabular-nums;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.history-timeline-list {
|
|
54
|
+
margin: 0;
|
|
55
|
+
padding: 0;
|
|
56
|
+
list-style: none;
|
|
57
|
+
display: flex;
|
|
58
|
+
flex-direction: column;
|
|
59
|
+
gap: 2px;
|
|
60
|
+
max-height: 180px;
|
|
61
|
+
overflow-y: auto;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.history-timeline-entry {
|
|
65
|
+
display: flex;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.history-timeline-entry-btn {
|
|
69
|
+
flex: 1 1 auto;
|
|
70
|
+
display: inline-flex;
|
|
71
|
+
align-items: center;
|
|
72
|
+
justify-content: space-between;
|
|
73
|
+
gap: 8px;
|
|
74
|
+
padding: 4px 8px;
|
|
75
|
+
border: 1px solid transparent;
|
|
76
|
+
border-radius: 2px;
|
|
77
|
+
background: transparent;
|
|
78
|
+
color: var(--text-default);
|
|
79
|
+
font: inherit;
|
|
80
|
+
text-align: left;
|
|
81
|
+
cursor: pointer;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.history-timeline-entry-btn:hover {
|
|
85
|
+
background: var(--hover);
|
|
86
|
+
border-color: var(--border);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.history-timeline-entry-current .history-timeline-entry-btn {
|
|
90
|
+
background: var(--select-bg);
|
|
91
|
+
border-color: var(--excel-green);
|
|
92
|
+
/*
|
|
93
|
+
a11y: --excel-green (#217346) on --select-bg (#dae3dc) is 4.43:1, just
|
|
94
|
+
under the 4.5:1 WCAG AA floor for the 11-12px text inside this button
|
|
95
|
+
(axe `color-contrast`, serious). --excel-green-text is the same hue
|
|
96
|
+
darkened to 5.68:1. The brand green is kept for the border, which is a
|
|
97
|
+
non-text element held to the 3:1 rule instead.
|
|
98
|
+
*/
|
|
99
|
+
color: var(--excel-green-text);
|
|
100
|
+
font-weight: 600;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.history-timeline-entry-kind {
|
|
104
|
+
font-variant-numeric: tabular-nums;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.history-timeline-entry-time {
|
|
108
|
+
color: var(--text-muted);
|
|
109
|
+
font-size: 11px;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/*
|
|
113
|
+
a11y: --text-muted (#6a6a6a) clears 4.5:1 on the default chrome, but the
|
|
114
|
+
current entry swaps the background to --select-bg (#dae3dc) where it drops
|
|
115
|
+
to 4.12:1 (axe `color-contrast`, serious). Darken it only in that context —
|
|
116
|
+
#595959 on --select-bg is 5.34:1.
|
|
117
|
+
*/
|
|
118
|
+
.history-timeline-entry-current .history-timeline-entry-time {
|
|
119
|
+
color: #595959;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.history-timeline-empty {
|
|
123
|
+
padding: 6px 0;
|
|
124
|
+
color: var(--text-muted);
|
|
125
|
+
font-style: italic;
|
|
126
|
+
}
|
|
127
|
+
|