Skip to content

Commit 5889ad5

Browse files
committed
feat: add Dark Mode support and fix white frame issue in TableWidget
- Update TableWidget CSS with variables and media queries for dark mode. - Pass CSS content via a new 'css_styles' traitlet to ensure reliable loading. - Implement robust JavaScript logic to detect VS Code dark themes and recursively clear ancestor backgrounds, eliminating the 'white frame' issue. - Reformat CSS and JS files to comply with project style guides. - Add unit test for CSS traitlet population.
1 parent 31fbdf5 commit 5889ad5

File tree

5 files changed

+148
-92
lines changed

5 files changed

+148
-92
lines changed

bigframes/display/anywidget.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class TableWidget(_WIDGET_BASE):
6868
page_size = traitlets.Int(0).tag(sync=True)
6969
row_count = traitlets.Int(allow_none=True, default_value=None).tag(sync=True)
7070
table_html = traitlets.Unicode("").tag(sync=True)
71+
css_styles = traitlets.Unicode("").tag(sync=True)
7172
sort_column = traitlets.Unicode("").tag(sync=True)
7273
sort_ascending = traitlets.Bool(True).tag(sync=True)
7374
orderable_columns = traitlets.List(traitlets.Unicode(), []).tag(sync=True)
@@ -119,6 +120,9 @@ def __init__(self, dataframe: bigframes.dataframe.DataFrame):
119120
else:
120121
self.orderable_columns = []
121122

123+
# Load CSS manually to ensure it's available for JS injection if needed
124+
self.css_styles = self._css
125+
122126
self._initial_load()
123127

124128
# Signals to the frontend that the initial data load is complete.

bigframes/display/html.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ def render_html(
4949
) -> str:
5050
"""Render a pandas DataFrame to HTML with specific styling."""
5151
orderable_columns = orderable_columns or []
52-
classes = "dataframe table"
52+
classes = "dataframe table table-striped table-hover"
5353
table_html_parts = [f'<table border="1" class="{classes}" id="{table_id}">']
5454
table_html_parts.append(_render_table_header(dataframe, orderable_columns))
5555
table_html_parts.append(_render_table_body(dataframe))

bigframes/display/table_widget.css

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,25 @@
1717
.bigframes-widget {
1818
/* Default Light Mode Variables */
1919
--bf-bg: white;
20-
--bf-fg: black;
21-
--bf-header-bg: #f5f5f5;
22-
--bf-row-odd-bg: white;
23-
--bf-row-even-bg: #f5f5f5;
2420
--bf-border-color: #ccc;
25-
--bf-null-fg: gray;
2621
--bf-error-bg: #fbe;
2722
--bf-error-border: red;
2823
--bf-error-fg: black;
24+
--bf-fg: black;
25+
--bf-header-bg: #f5f5f5;
26+
--bf-null-fg: gray;
27+
--bf-row-even-bg: #f5f5f5;
28+
--bf-row-odd-bg: white;
2929

30-
display: flex;
31-
flex-direction: column;
32-
/* Double class to increase specificity + !important to override framework styles */
3330
background-color: var(--bf-bg) !important;
31+
box-sizing: border-box;
3432
color: var(--bf-fg) !important;
33+
display: flex;
34+
flex-direction: column;
3535
font-family:
3636
"-apple-system", "BlinkMacSystemFont", "Segoe UI", "Roboto", sans-serif;
37-
padding: 0 !important;
3837
margin: 0 !important;
39-
box-sizing: border-box;
38+
padding: 0 !important;
4039
}
4140

4241
.bigframes-widget * {
@@ -47,48 +46,48 @@
4746
@media (prefers-color-scheme: dark) {
4847
.bigframes-widget {
4948
--bf-bg: var(--vscode-editor-background, #202124);
50-
--bf-fg: white;
51-
--bf-header-bg: var(--vscode-editor-background, black);
52-
--bf-row-odd-bg: #383838;
53-
--bf-row-even-bg: #202124;
5449
--bf-border-color: #444;
55-
--bf-null-fg: #aaa;
5650
--bf-error-bg: #511;
5751
--bf-error-border: #f88;
5852
--bf-error-fg: #fcc;
53+
--bf-fg: white;
54+
--bf-header-bg: var(--vscode-editor-background, black);
55+
--bf-null-fg: #aaa;
56+
--bf-row-even-bg: #202124;
57+
--bf-row-odd-bg: #383838;
5958
}
6059
}
6160

6261
/* Dark Mode Overrides via Explicit Class */
6362
.bigframes-widget.bigframes-dark-mode.bigframes-dark-mode {
6463
--bf-bg: var(--vscode-editor-background, #202124);
65-
--bf-fg: white;
66-
--bf-header-bg: var(--vscode-editor-background, black);
67-
--bf-row-odd-bg: #383838;
68-
--bf-row-even-bg: #202124;
6964
--bf-border-color: #444;
70-
--bf-null-fg: #aaa;
7165
--bf-error-bg: #511;
7266
--bf-error-border: #f88;
7367
--bf-error-fg: #fcc;
68+
--bf-fg: white;
69+
--bf-header-bg: var(--vscode-editor-background, black);
70+
--bf-null-fg: #aaa;
71+
--bf-row-even-bg: #202124;
72+
--bf-row-odd-bg: #383838;
7473
}
7574

7675
.bigframes-widget .table-container {
76+
background-color: var(--bf-bg);
77+
margin: 0;
7778
max-height: 620px;
7879
overflow: auto;
79-
background-color: var(--bf-bg);
8080
padding: 0;
81-
margin: 0;
8281
}
8382

8483
.bigframes-widget .footer {
8584
align-items: center;
85+
background-color: var(--bf-bg);
86+
color: var(--bf-fg);
8687
display: flex;
8788
font-size: 0.8rem;
8889
justify-content: space-between;
8990
padding: 8px;
90-
background-color: var(--bf-bg);
91-
color: var(--bf-fg);
9291
}
9392

9493
.bigframes-widget .footer > * {
@@ -126,17 +125,17 @@
126125

127126
.bigframes-widget table,
128127
.bigframes-widget table.dataframe {
129-
border-collapse: collapse !important;
130-
border-spacing: 0 !important;
131-
text-align: left;
132-
width: auto !important; /* Fix stretching */
133128
background-color: var(--bf-bg) !important;
134-
color: var(--bf-fg) !important;
135129
/* Explicitly override border="1" defaults */
136130
border: 1px solid var(--bf-border-color) !important;
131+
border-collapse: collapse !important;
132+
border-spacing: 0 !important;
137133
box-shadow: none !important;
138-
outline: none !important;
134+
color: var(--bf-fg) !important;
139135
margin: 0 !important;
136+
outline: none !important;
137+
text-align: left;
138+
width: auto !important; /* Fix stretching */
140139
}
141140

142141
.bigframes-widget tr {
@@ -145,19 +144,19 @@
145144

146145
.bigframes-widget th {
147146
background-color: var(--bf-header-bg) !important;
147+
border: 1px solid var(--bf-border-color) !important;
148148
color: var(--bf-fg) !important;
149149
padding: 0;
150150
position: sticky;
151151
text-align: left;
152152
top: 0;
153153
z-index: 1;
154-
border: 1px solid var(--bf-border-color) !important;
155154
}
156155

157156
.bigframes-widget td {
158-
padding: 0.5em;
159157
border: 1px solid var(--bf-border-color) !important;
160158
color: var(--bf-fg) !important;
159+
padding: 0.5em;
161160
}
162161

163162
.bigframes-widget table tbody tr:nth-child(odd),
@@ -189,17 +188,17 @@
189188
}
190189

191190
.bigframes-widget button {
191+
background-color: transparent;
192+
border: 1px solid currentColor;
193+
border-radius: 4px;
194+
color: inherit;
192195
cursor: pointer;
193196
display: inline-block;
197+
padding: 2px 8px;
194198
text-align: center;
195199
text-decoration: none;
196200
user-select: none;
197201
vertical-align: middle;
198-
color: inherit;
199-
background-color: transparent;
200-
border: 1px solid currentColor;
201-
border-radius: 4px;
202-
padding: 2px 8px;
203202
}
204203

205204
.bigframes-widget button:disabled {
@@ -210,8 +209,8 @@
210209
.bigframes-widget .bigframes-error-message {
211210
background-color: var(--bf-error-bg);
212211
border: 1px solid var(--bf-error-border);
213-
color: var(--bf-error-fg);
214212
border-radius: 4px;
213+
color: var(--bf-error-fg);
215214
font-size: 14px;
216215
margin-bottom: 8px;
217216
padding: 8px;

0 commit comments

Comments
 (0)