Skip to content

Commit 281de0c

Browse files
committed
Add support for Dark Mode styles
Makes use of the user's prefers-color-scheme value. A nice side effect is that by using CSS vars, it's possible to customize the themes of the gem as well. Fixes #104
1 parent c2dc178 commit 281de0c

File tree

10 files changed

+198
-39
lines changed

10 files changed

+198
-39
lines changed

README.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,81 @@ In your ERB layouts, there are several helper methods you can use. The helper me
127127

128128
To call these methods within templates, you must use the dot notation, such as `<%= slugify.(text) %>`.
129129

130+
## Dark Mode Support
131+
132+
GraphQLDocs includes built-in dark mode support that automatically adapts to the user's system preferences using the `prefers-color-scheme` media query. When a user has dark mode enabled on their operating system, the documentation will automatically display with a dark theme.
133+
134+
### Customizing Colors
135+
136+
The default styles use CSS custom properties (variables) for all colors, making it easy to customize the color scheme to match your brand. You can override these variables by providing a custom stylesheet.
137+
138+
The available CSS variables are:
139+
140+
**Light Mode (default):**
141+
```css
142+
:root {
143+
--bg-primary: #fff; /* Main background color */
144+
--bg-secondary: #f8f8f8; /* Secondary background (tables, etc.) */
145+
--bg-tertiary: #fafafa; /* Tertiary background (API boxes) */
146+
--bg-code: #eee; /* Inline code background */
147+
--bg-code-block: #272822; /* Code block background */
148+
--text-primary: #444; /* Primary text color */
149+
--text-secondary: #999; /* Secondary text (categories, etc.) */
150+
--text-link: #de4f4f; /* Link color */
151+
--text-code: #525252; /* Inline code text color */
152+
--border-color: #eee; /* Primary border color */
153+
--border-color-secondary: #ddd; /* Secondary border color */
154+
--shadow-color: rgba(0, 0, 0, 0.1); /* Shadow/hover effects */
155+
}
156+
```
157+
158+
**Dark Mode:**
159+
```css
160+
@media (prefers-color-scheme: dark) {
161+
:root {
162+
--bg-primary: #1a1a1a;
163+
--bg-secondary: #252525;
164+
--bg-tertiary: #2a2a2a;
165+
--bg-code: #333;
166+
--bg-code-block: #1e1e1e;
167+
--text-primary: #e0e0e0;
168+
--text-secondary: #888;
169+
--text-link: #ff6b6b;
170+
--text-code: #d4d4d4;
171+
--border-color: #333;
172+
--border-color-secondary: #444;
173+
--shadow-color: rgba(255, 255, 255, 0.1);
174+
}
175+
}
176+
```
177+
178+
### Example: Custom Color Scheme
179+
180+
To customize the colors, create a custom CSS file and load it after the default styles. You can override specific variables while keeping the rest of the defaults:
181+
182+
```css
183+
/* custom-theme.css */
184+
:root {
185+
--text-link: #0066cc; /* Change link color to blue */
186+
--bg-tertiary: #f0f0f0; /* Lighter API boxes */
187+
}
188+
189+
@media (prefers-color-scheme: dark) {
190+
:root {
191+
--text-link: #66b3ff; /* Lighter blue for dark mode */
192+
--bg-primary: #0d1117; /* GitHub-like dark background */
193+
--bg-secondary: #161b22;
194+
}
195+
}
196+
```
197+
198+
Then reference it in your custom template by overriding the `default` template and adding a link to your stylesheet:
199+
200+
```html
201+
<link rel="stylesheet" href="<%= base_url %>/assets/style.css">
202+
<link rel="stylesheet" href="<%= base_url %>/assets/custom-theme.css">
203+
```
204+
130205
## Configuration
131206

132207
The following options are available:

lib/graphql-docs/layouts/assets/_sass/_api-box.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
.api {
2-
background: #fafafa;
2+
background: var(--bg-tertiary);
33
h3 {
44
padding: 5px 10px;
55
}
@@ -32,7 +32,7 @@
3232
margin-left: 15px;
3333
font-size: 0.9em;
3434
font-weight: 200;
35-
color: #000;
35+
color: var(--text-primary);
3636
}
3737
}
3838
dd {

lib/graphql-docs/layouts/assets/_sass/_content.scss

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
font-size: 1.5em;
2323
margin-top: 30px;
2424
padding-bottom: 10px;
25-
border-bottom: 1px solid #eee;
25+
border-bottom: 1px solid var(--border-color);
2626
position: relative;
2727
.anchor {
2828
opacity: 0;
@@ -95,7 +95,7 @@
9595
line-height: 1.4em;
9696
}
9797
a {
98-
color: #de4f4f;
98+
color: var(--text-link);
9999
}
100100
img {
101101
max-width: 100%;
@@ -105,12 +105,13 @@
105105
font-size: 0.8em;
106106
line-height: 1.6em;
107107
padding: 1px 4px;
108-
background-color: #eee;
108+
background-color: var(--bg-code);
109+
color: var(--text-code);
109110
margin: 0 2px;
110111
}
111112
blockquote {
112113
padding-left: 1.3em;
113-
border-left: #eee solid 0.2em;
114+
border-left: var(--border-color) solid 0.2em;
114115
font-style: italic;
115116
}
116117
blockquote.warning {
@@ -174,7 +175,7 @@
174175
margin: 0;
175176
}
176177
code {
177-
background-color: #272822;
178+
background-color: var(--bg-code-block);
178179
padding: 0;
179180
margin: 0;
180181
}
@@ -453,20 +454,20 @@
453454
width: 100%;
454455
margin: 20px 0;
455456
tr {
456-
border-top: 1px solid #eee;
457+
border-top: 1px solid var(--border-color);
457458
&:nth-child(2n) {
458-
background-color: #f8f8f8;
459+
background-color: var(--bg-secondary);
459460
}
460461
}
461462
th {
462463
font-family: 'ProximaNova-Semibold';
463464
padding: 12px 13px;
464-
border: 1px solid #eee;
465+
border: 1px solid var(--border-color);
465466
vertical-align: middle;
466467
text-align: left;
467468
}
468469
td {
469-
border: 1px solid #eee;
470+
border: 1px solid var(--border-color);
470471
vertical-align: middle;
471472
padding: 6px 13px;
472473
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
@@ -477,7 +478,7 @@
477478
.bottom-nav {
478479
height: 44px;
479480
margin: 30px 0 25px;
480-
border-bottom: 1px solid #eee;
481+
border-bottom: 1px solid var(--border-color);
481482
padding-bottom: 25px;
482483
a {
483484
font-family: 'ProximaNova-Semibold';

lib/graphql-docs/layouts/assets/_sass/_deprecations.scss

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,10 @@
77
font-weight: bold;
88
}
99
}
10+
11+
@media (prefers-color-scheme: dark) {
12+
.deprecation-notice {
13+
background: #3d1a0f;
14+
color: #ffb499;
15+
}
16+
}

lib/graphql-docs/layouts/assets/_sass/_header.scss

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
text-decoration: none;
77
}
88
}
9+
10+
@media (prefers-color-scheme: dark) {
11+
#top-nav {
12+
background-color: #0a0a0a;
13+
}
14+
}
915
#top-nav-links {
1016
list-style-type: none;
1117
position: absolute;
@@ -28,8 +34,8 @@
2834
#site-nav {
2935
position: relative;
3036
height: 70px;
31-
background-color: #fff;
32-
border-bottom: 1px solid #eee;
37+
background-color: var(--bg-primary);
38+
border-bottom: 1px solid var(--border-color);
3339
padding: 14px 30px;
3440
a {
3541
vertical-align: bottom;

lib/graphql-docs/layouts/assets/_sass/_mobile.scss

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
left: 0;
66
width: 100%;
77
height: 40px;
8-
background-color: #fff;
8+
background-color: var(--bg-primary);
99
display: none;
10-
box-shadow: 0 0 4px rgba(0,0,0,0.25);
10+
box-shadow: 0 0 4px var(--shadow-color);
1111
.menu-button {
1212
position: absolute;
1313
width: 24px;
@@ -30,6 +30,13 @@
3030
}
3131
}
3232
}
33+
34+
@media (prefers-color-scheme: dark) {
35+
#mobile-header .menu-button {
36+
filter: brightness(0) invert(1);
37+
}
38+
}
39+
3340
#mobile-shade {
3441
z-index: 1;
3542
display: none;
@@ -84,7 +91,7 @@
8491
left: 0;
8592
padding-top: 60px;
8693
border-right: none;
87-
box-shadow: 0 0 4px rgba(0,0,0,0.25);
94+
box-shadow: 0 0 4px var(--shadow-color);
8895
transition: transform 0.3s ease;
8996
transform: translate3d(-120%, 0, 0);
9097
display: block;
Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,56 @@
11
.search-box {
2+
position: relative;
3+
4+
&::before {
5+
content: "";
6+
position: absolute;
7+
left: 18px;
8+
top: 50%;
9+
transform: translateY(-50%);
10+
width: 20px;
11+
height: 20px;
12+
background: url("../assets/images/search.png") center no-repeat;
13+
background-size: 20px;
14+
pointer-events: none;
15+
z-index: 1;
16+
}
17+
218
input {
319
width: 200px;
4-
background-color: #fff;
20+
background-color: var(--bg-primary);
21+
color: var(--text-primary);
522
outline: none;
623
font-family: 'ProximaNova-Regular';
724
font-size: 14px;
825
padding: 7px 12px 6px 32px;
926
border-radius: 20px;
10-
border: 1px solid #ddd;
11-
background: url("../assets/images/search.png") 8px 6px no-repeat;
12-
background-size: 20px;
27+
border: 1px solid var(--border-color-secondary);
1328
transition: border-color 0.25s ease;
1429
&:focus {
15-
border-color: #de4f4f;
30+
border-color: var(--text-link);
1631
}
1732
}
1833
}
34+
35+
@media (prefers-color-scheme: dark) {
36+
.search-box::before {
37+
filter: brightness(0) invert(1);
38+
}
39+
}
1940
.search-box.st-default-search-input {
2041
width: 200px;
21-
background-color: #fff;
42+
background-color: var(--bg-primary);
43+
color: var(--text-primary);
2244
outline: none;
2345
font-family: 'ProximaNova-Regular';
2446
font-size: 14px;
2547
padding: 7px 12px 6px 32px;
2648
border-radius: 20px;
27-
border: 1px solid #ddd;
49+
border: 1px solid var(--border-color-secondary);
2850
background: url("../assets/images/search.png") 8px 6px no-repeat;
2951
background-size: 20px;
3052
transition: border-color 0.25s ease;
3153
&:focus {
32-
border-color: #de4f4f;
54+
border-color: var(--text-link);
3355
}
3456
}

0 commit comments

Comments
 (0)