graphql-docs 5.2.0 → 6.0.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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +9 -0
  3. data/CHANGELOG.md +76 -0
  4. data/README.md +404 -8
  5. data/bin/console +6 -7
  6. data/bin/setup +8 -5
  7. data/exe/graphql-docs +9 -9
  8. data/graphql-docs.gemspec +50 -38
  9. data/lib/graphql-docs/app.rb +488 -0
  10. data/lib/graphql-docs/configuration.rb +28 -11
  11. data/lib/graphql-docs/generator.rb +147 -42
  12. data/lib/graphql-docs/helpers.rb +132 -12
  13. data/lib/graphql-docs/layouts/assets/_sass/_api-box.scss +2 -2
  14. data/lib/graphql-docs/layouts/assets/_sass/_content.scss +20 -19
  15. data/lib/graphql-docs/layouts/assets/_sass/_deprecations.scss +7 -0
  16. data/lib/graphql-docs/layouts/assets/_sass/_fonts.scss +6 -21
  17. data/lib/graphql-docs/layouts/assets/_sass/_header.scss +8 -2
  18. data/lib/graphql-docs/layouts/assets/_sass/_mobile.scss +10 -3
  19. data/lib/graphql-docs/layouts/assets/_sass/_search.scss +32 -10
  20. data/lib/graphql-docs/layouts/assets/_sass/_sidebar.scss +22 -15
  21. data/lib/graphql-docs/layouts/assets/_sass/_syntax.scss +1 -1
  22. data/lib/graphql-docs/layouts/assets/css/screen.scss +54 -5
  23. data/lib/graphql-docs/layouts/default.html +75 -1
  24. data/lib/graphql-docs/layouts/includes/sidebar.html +4 -2
  25. data/lib/graphql-docs/parser.rb +89 -33
  26. data/lib/graphql-docs/renderer.rb +98 -31
  27. data/lib/graphql-docs/version.rb +2 -1
  28. data/lib/graphql-docs.rb +78 -12
  29. data/lib/tasks/graphql-docs.rake +57 -0
  30. metadata +74 -78
  31. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -31
  32. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
  33. data/.github/workflows/tests.yml +0 -21
  34. data/.gitignore +0 -15
  35. data/.rubocop.yml +0 -11
  36. data/CODE_OF_CONDUCT.md +0 -84
  37. data/CONTRIBUTING.md +0 -18
  38. data/Gemfile +0 -6
  39. data/Rakefile +0 -86
  40. data/lib/graphql-docs/layouts/assets/images/graphiql-headers.png +0 -0
  41. data/lib/graphql-docs/layouts/assets/images/graphiql-variables.png +0 -0
  42. data/lib/graphql-docs/layouts/assets/images/graphiql.png +0 -0
  43. data/lib/graphql-docs/layouts/assets/images/search.svg +0 -3
  44. data/lib/graphql-docs/layouts/assets/webfonts/2C4B9D_B_0.eot +0 -0
  45. data/lib/graphql-docs/layouts/assets/webfonts/2C4B9D_B_0.ttf +0 -0
  46. data/lib/graphql-docs/layouts/assets/webfonts/2C4B9D_B_0.woff +0 -0
  47. data/lib/graphql-docs/layouts/assets/webfonts/2C4B9D_B_0.woff2 +0 -0
  48. data/lib/graphql-docs/layouts/assets/webfonts/2C4B9D_C_0.eot +0 -0
  49. data/lib/graphql-docs/layouts/assets/webfonts/2C4B9D_C_0.ttf +0 -0
  50. data/lib/graphql-docs/layouts/assets/webfonts/2C4B9D_C_0.woff +0 -0
  51. data/lib/graphql-docs/layouts/assets/webfonts/2C4B9D_C_0.woff2 +0 -0
  52. data/lib/graphql-docs/layouts/assets/webfonts/2C4B9D_D_0.eot +0 -0
  53. data/lib/graphql-docs/layouts/assets/webfonts/2C4B9D_D_0.ttf +0 -0
  54. data/lib/graphql-docs/layouts/assets/webfonts/2C4B9D_D_0.woff +0 -0
  55. data/lib/graphql-docs/layouts/assets/webfonts/2C4B9D_D_0.woff2 +0 -0
  56. data/lib/graphql-docs/layouts/assets/webfonts/2C4B9D_E_0.eot +0 -0
  57. data/lib/graphql-docs/layouts/assets/webfonts/2C4B9D_E_0.ttf +0 -0
  58. data/lib/graphql-docs/layouts/assets/webfonts/2C4B9D_E_0.woff +0 -0
  59. data/lib/graphql-docs/layouts/assets/webfonts/2C4B9D_E_0.woff2 +0 -0
@@ -7,7 +7,7 @@
7
7
  font-style: italic;
8
8
  }
9
9
  strong {
10
- font-family: 'ProximaNova-Bold';
10
+ font-weight: 700;
11
11
  }
12
12
  h1 {
13
13
  margin: 15px 0;
@@ -22,7 +22,7 @@
22
22
  font-size: 1.5em;
23
23
  margin-top: 30px;
24
24
  padding-bottom: 10px;
25
- border-bottom: 1px solid #eee;
25
+ border-bottom: 1px solid var(--border-color);
26
26
  position: relative;
27
27
  .anchor {
28
28
  opacity: 0;
@@ -95,7 +95,7 @@
95
95
  line-height: 1.4em;
96
96
  }
97
97
  a {
98
- color: #de4f4f;
98
+ color: var(--text-link);
99
99
  }
100
100
  img {
101
101
  max-width: 100%;
@@ -105,12 +105,13 @@
105
105
  font-size: 0.8em;
106
106
  line-height: 1.6em;
107
107
  padding: 1px 4px;
108
- background-color: #eee;
108
+ background-color: var(--bg-code);
109
+ color: var(--text-code);
109
110
  margin: 0 2px;
110
111
  }
111
112
  blockquote {
112
113
  padding-left: 1.3em;
113
- border-left: #eee solid 0.2em;
114
+ border-left: var(--border-color) solid 0.2em;
114
115
  font-style: italic;
115
116
  }
116
117
  blockquote.warning {
@@ -174,7 +175,7 @@
174
175
  margin: 0;
175
176
  }
176
177
  code {
177
- background-color: #272822;
178
+ background-color: var(--bg-code-block);
178
179
  padding: 0;
179
180
  margin: 0;
180
181
  }
@@ -187,7 +188,7 @@
187
188
  .highlight.html {
188
189
  .code {
189
190
  &:after {
190
- font-family: 'ProximaNova-Semibold';
191
+ font-weight: 600;
191
192
  position: absolute;
192
193
  top: 0;
193
194
  right: 0;
@@ -205,7 +206,7 @@
205
206
  .highlight.js {
206
207
  .code {
207
208
  &:after {
208
- font-family: 'ProximaNova-Semibold';
209
+ font-weight: 600;
209
210
  position: absolute;
210
211
  top: 0;
211
212
  right: 0;
@@ -223,7 +224,7 @@
223
224
  .highlight.bash {
224
225
  .code {
225
226
  &:after {
226
- font-family: 'ProximaNova-Semibold';
227
+ font-weight: 600;
227
228
  position: absolute;
228
229
  top: 0;
229
230
  right: 0;
@@ -241,7 +242,7 @@
241
242
  .highlight.css {
242
243
  .code {
243
244
  &:after {
244
- font-family: 'ProximaNova-Semibold';
245
+ font-weight: 600;
245
246
  position: absolute;
246
247
  top: 0;
247
248
  right: 0;
@@ -259,7 +260,7 @@
259
260
  .highlight.jsx {
260
261
  .code {
261
262
  &:after {
262
- font-family: 'ProximaNova-Semibold';
263
+ font-weight: 600;
263
264
  position: absolute;
264
265
  top: 0;
265
266
  right: 0;
@@ -453,20 +454,20 @@
453
454
  width: 100%;
454
455
  margin: 20px 0;
455
456
  tr {
456
- border-top: 1px solid #eee;
457
+ border-top: 1px solid var(--border-color);
457
458
  &:nth-child(2n) {
458
- background-color: #f8f8f8;
459
+ background-color: var(--bg-secondary);
459
460
  }
460
461
  }
461
462
  th {
462
- font-family: 'ProximaNova-Semibold';
463
+ font-weight: 600;
463
464
  padding: 12px 13px;
464
- border: 1px solid #eee;
465
+ border: 1px solid var(--border-color);
465
466
  vertical-align: middle;
466
467
  text-align: left;
467
468
  }
468
469
  td {
469
- border: 1px solid #eee;
470
+ border: 1px solid var(--border-color);
470
471
  vertical-align: middle;
471
472
  padding: 6px 13px;
472
473
  font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
@@ -477,10 +478,10 @@
477
478
  .bottom-nav {
478
479
  height: 44px;
479
480
  margin: 30px 0 25px;
480
- border-bottom: 1px solid #eee;
481
+ border-bottom: 1px solid var(--border-color);
481
482
  padding-bottom: 25px;
482
483
  a {
483
- font-family: 'ProximaNova-Semibold';
484
+ font-weight: 600;
484
485
  margin: 0 5px;
485
486
  }
486
487
  }
@@ -488,7 +489,7 @@
488
489
  text-align: center;
489
490
  a {
490
491
  color: #aaa;
491
- font-family: 'ProximaNova-Semibold';
492
+ font-weight: 600;
492
493
  &:before {
493
494
  content: '';
494
495
  display: inline-block;
@@ -7,3 +7,10 @@
7
7
  font-weight: bold;
8
8
  }
9
9
  }
10
+
11
+ @media (prefers-color-scheme: dark) {
12
+ .deprecation-notice {
13
+ background: #3d1a0f;
14
+ color: #ffb499;
15
+ }
16
+ }
@@ -1,21 +1,6 @@
1
- @import "//hello.myfonts.net/count/2c4b9d";
2
- @font-face {
3
- font-family: 'ProximaNova-Light';
4
- src: url("webfonts/2C4B9D_B_0.eot");
5
- src: url("webfonts/2C4B9D_B_0.eot?#iefix") format('embedded-opentype'), url("webfonts/2C4B9D_B_0.woff2") format('woff2'), url("webfonts/2C4B9D_B_0.woff") format('woff'), url("webfonts/2C4B9D_B_0.ttf") format('truetype');
6
- }
7
- @font-face {
8
- font-family: 'ProximaNova-Semibold';
9
- src: url("webfonts/2C4B9D_C_0.eot");
10
- src: url("webfonts/2C4B9D_C_0.eot?#iefix") format('embedded-opentype'), url("webfonts/2C4B9D_C_0.woff2") format('woff2'), url("webfonts/2C4B9D_C_0.woff") format('woff'), url("webfonts/2C4B9D_C_0.ttf") format('truetype');
11
- }
12
- @font-face {
13
- font-family: 'ProximaNova-Regular';
14
- src: url("webfonts/2C4B9D_D_0.eot");
15
- src: url("webfonts/2C4B9D_D_0.eot?#iefix") format('embedded-opentype'), url("webfonts/2C4B9D_D_0.woff2") format('woff2'), url("webfonts/2C4B9D_D_0.woff") format('woff'), url("webfonts/2C4B9D_D_0.ttf") format('truetype');
16
- }
17
- @font-face {
18
- font-family: 'ProximaNova-Bold';
19
- src: url("webfonts/2C4B9D_E_0.eot");
20
- src: url("webfonts/2C4B9D_E_0.eot?#iefix") format('embedded-opentype'), url("webfonts/2C4B9D_E_0.woff2") format('woff2'), url("webfonts/2C4B9D_E_0.woff") format('woff'), url("webfonts/2C4B9D_E_0.ttf") format('truetype');
21
- }
1
+ // Modern system font stack - no webfonts needed!
2
+ $font-stack: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
3
+ $font-stack-light: $font-stack;
4
+ $font-stack-regular: $font-stack;
5
+ $font-stack-semibold: $font-stack;
6
+ $font-stack-bold: $font-stack;
@@ -6,6 +6,12 @@
6
6
  text-decoration: none;
7
7
  }
8
8
  }
9
+
10
+ @media (prefers-color-scheme: dark) {
11
+ #top-nav {
12
+ background-color: #0a0a0a;
13
+ }
14
+ }
9
15
  #top-nav-links {
10
16
  list-style-type: none;
11
17
  position: absolute;
@@ -28,8 +34,8 @@
28
34
  #site-nav {
29
35
  position: relative;
30
36
  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);
33
39
  padding: 14px 30px;
34
40
  a {
35
41
  vertical-align: bottom;
@@ -5,9 +5,9 @@
5
5
  left: 0;
6
6
  width: 100%;
7
7
  height: 40px;
8
- background-color: #fff;
8
+ background-color: var(--bg-primary);
9
9
  display: none;
10
- box-shadow: 0 0 4px rgba(0,0,0,0.25);
10
+ box-shadow: 0 0 4px var(--shadow-color);
11
11
  .menu-button {
12
12
  position: absolute;
13
13
  width: 24px;
@@ -30,6 +30,13 @@
30
30
  }
31
31
  }
32
32
  }
33
+
34
+ @media (prefers-color-scheme: dark) {
35
+ #mobile-header .menu-button {
36
+ filter: brightness(0) invert(1);
37
+ }
38
+ }
39
+
33
40
  #mobile-shade {
34
41
  z-index: 1;
35
42
  display: none;
@@ -84,7 +91,7 @@
84
91
  left: 0;
85
92
  padding-top: 60px;
86
93
  border-right: none;
87
- box-shadow: 0 0 4px rgba(0,0,0,0.25);
94
+ box-shadow: 0 0 4px var(--shadow-color);
88
95
  transition: transform 0.3s ease;
89
96
  transform: translate3d(-120%, 0, 0);
90
97
  display: block;
@@ -1,34 +1,56 @@
1
1
  .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
+
2
18
  input {
3
19
  width: 200px;
4
- background-color: #fff;
20
+ background-color: var(--bg-primary);
21
+ color: var(--text-primary);
5
22
  outline: none;
6
- font-family: 'ProximaNova-Regular';
23
+ font-family: inherit;
7
24
  font-size: 14px;
8
25
  padding: 7px 12px 6px 32px;
9
26
  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);
13
28
  transition: border-color 0.25s ease;
14
29
  &:focus {
15
- border-color: #de4f4f;
30
+ border-color: var(--text-link);
16
31
  }
17
32
  }
18
33
  }
34
+
35
+ @media (prefers-color-scheme: dark) {
36
+ .search-box::before {
37
+ filter: brightness(0) invert(1);
38
+ }
39
+ }
19
40
  .search-box.st-default-search-input {
20
41
  width: 200px;
21
- background-color: #fff;
42
+ background-color: var(--bg-primary);
43
+ color: var(--text-primary);
22
44
  outline: none;
23
- font-family: 'ProximaNova-Regular';
45
+ font-family: inherit;
24
46
  font-size: 14px;
25
47
  padding: 7px 12px 6px 32px;
26
48
  border-radius: 20px;
27
- border: 1px solid #ddd;
49
+ border: 1px solid var(--border-color-secondary);
28
50
  background: url("../assets/images/search.png") 8px 6px no-repeat;
29
51
  background-size: 20px;
30
52
  transition: border-color 0.25s ease;
31
53
  &:focus {
32
- border-color: #de4f4f;
54
+ border-color: var(--text-link);
33
55
  }
34
56
  }
@@ -1,5 +1,5 @@
1
1
  #sidebar {
2
- background-color: #fff;
2
+ background-color: var(--bg-primary);
3
3
  position: fixed;
4
4
  z-index: 2;
5
5
  top: 30px;
@@ -11,8 +11,8 @@
11
11
  overflow-y: scroll;
12
12
  -webkit-overflow-scrolling: touch;
13
13
  -ms-overflow-style: none;
14
- font-family: 'ProximaNova-Semibold';
15
- border-right: 1px solid #eee;
14
+ font-weight: 600;
15
+ border-right: 1px solid var(--border-color);
16
16
  font-size: 16px;
17
17
  line-height: 1.1em;
18
18
  &::-webkit-scrollbar {
@@ -22,14 +22,14 @@
22
22
  margin-bottom: 0.6em;
23
23
  }
24
24
  a {
25
- color: #444;
25
+ color: var(--text-primary);
26
26
  text-decoration: none;
27
27
  &:hover {
28
- color: #de4f4f;
28
+ color: var(--text-link);
29
29
  }
30
30
  }
31
31
  a.current {
32
- color: #de4f4f;
32
+ color: var(--text-link);
33
33
  }
34
34
  a.H2 {
35
35
  font-weight: bold;
@@ -38,23 +38,23 @@
38
38
  >li {
39
39
  >p {
40
40
  margin-top: 1.5em;
41
- border-top: 1px solid #eee;
41
+ border-top: 1px solid var(--border-color);
42
42
  text-transform: uppercase;
43
43
  padding-top: 1.2em;
44
44
  margin-bottom: 1em;
45
- color: #999;
45
+ color: var(--text-secondary);
46
46
  font-size: 0.8em;
47
47
  }
48
48
  }
49
49
  }
50
50
  .sub-menu {
51
- font-family: 'ProximaNova-Regular';
51
+ font-weight: 400;
52
52
  padding-left: 20px;
53
53
  margin: 0.6em 0;
54
54
  font-size: 14px;
55
55
  .active {
56
56
  position: relative;
57
- color: #de4f4f;
57
+ color: var(--text-link);
58
58
  &:before {
59
59
  content: "";
60
60
  position: absolute;
@@ -65,7 +65,7 @@
65
65
  height: 0;
66
66
  border-top: 4px solid transparent;
67
67
  border-bottom: 4px solid transparent;
68
- border-left: 6px solid #de4f4f;
68
+ border-left: 6px solid var(--text-link);
69
69
  }
70
70
  }
71
71
  }
@@ -73,16 +73,17 @@
73
73
  display: flex;
74
74
  position: relative;
75
75
  align-items: center;
76
- border: 1px solid #ddd;
76
+ border: 1px solid var(--border-color-secondary);
77
77
  border-radius: 5px;
78
78
  padding: 0.01em 16px;
79
79
  margin-bottom: 20px;
80
80
 
81
- img {
81
+ svg {
82
82
  position: absolute;
83
83
  left: 10px;
84
84
  height: 16px;
85
85
  width: 16px;
86
+ fill: currentColor;
86
87
  }
87
88
 
88
89
  input {
@@ -91,10 +92,10 @@
91
92
  width: 100%;
92
93
  padding-left: 15px;
93
94
  background-color: transparent;
94
- color: #444;
95
+ color: var(--text-primary);
95
96
  border: none;
96
97
  font-size: 14px;
97
- font-family: 'ProximaNova-Semibold';
98
+ font-weight: 600;
98
99
  }
99
100
 
100
101
  input:focus {
@@ -103,6 +104,12 @@
103
104
  }
104
105
  }
105
106
 
107
+ @media (prefers-color-scheme: dark) {
108
+ #sidebar #search svg {
109
+ filter: brightness(0) invert(1);
110
+ }
111
+ }
112
+
106
113
  #sidebar-mobile {
107
114
  display: none;
108
115
  margin-bottom: 20px;
@@ -230,7 +230,7 @@ pre {
230
230
  }
231
231
 
232
232
  .highlight .hll { background-color: #49483e }
233
- pre { background: #272822; color: #f8f8f2 }
233
+ pre { background: var(--bg-code-block); color: #f8f8f2 }
234
234
  .highlight .c { color: #75715e } /* Comment */
235
235
  .highlight .err { color: #960050; background-color: #1e0010 } /* Error */
236
236
  .highlight .k { color: #66d9ef } /* Keyword */
@@ -4,13 +4,48 @@
4
4
  @use "../_sass/_normalize.scss";
5
5
  @use "../_sass/_fonts";
6
6
 
7
+ :root {
8
+ // Light mode (default)
9
+ --bg-primary: #fff;
10
+ --bg-secondary: #f8f8f8;
11
+ --bg-tertiary: #fafafa;
12
+ --bg-code: #eee;
13
+ --bg-code-block: #272822;
14
+ --text-primary: #444;
15
+ --text-secondary: #999;
16
+ --text-link: #de4f4f;
17
+ --text-code: #525252;
18
+ --border-color: #eee;
19
+ --border-color-secondary: #ddd;
20
+ --shadow-color: rgba(0, 0, 0, 0.1);
21
+ }
22
+
23
+ @media (prefers-color-scheme: dark) {
24
+ :root {
25
+ // Dark mode
26
+ --bg-primary: #1a1a1a;
27
+ --bg-secondary: #252525;
28
+ --bg-tertiary: #2a2a2a;
29
+ --bg-code: #333;
30
+ --bg-code-block: #1e1e1e;
31
+ --text-primary: #e0e0e0;
32
+ --text-secondary: #888;
33
+ --text-link: #ff6b6b;
34
+ --text-code: #d4d4d4;
35
+ --border-color: #333;
36
+ --border-color-secondary: #444;
37
+ --shadow-color: rgba(255, 255, 255, 0.1);
38
+ }
39
+ }
40
+
7
41
  body {
8
- font-family: 'Source Sans Pro', 'Helvetica Neue', Helvetica, Arial, sans-serif;
42
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
9
43
  -webkit-font-smoothing: antialiased;
10
44
  -moz-osx-font-smoothing: grayscale;
11
45
  font-size: 16px;
12
46
  font-weight: 400;
13
- color: #444;
47
+ color: var(--text-primary);
48
+ background-color: var(--bg-primary);
14
49
  }
15
50
  h1,
16
51
  h2,
@@ -18,8 +53,7 @@ h3,
18
53
  h4,
19
54
  h5,
20
55
  h6 {
21
- font-family: 'ProximaNova-Semibold';
22
- font-weight: 200;
56
+ font-weight: 600;
23
57
  }
24
58
  em {
25
59
  font-style: italic;
@@ -37,7 +71,7 @@ em {
37
71
  left: 0;
38
72
  width: 100%;
39
73
  height: 100px;
40
- font-family: 'ProximaNova-Semibold';
74
+ font-weight: 600;
41
75
  }
42
76
 
43
77
  @include meta.load-css('../_sass/_header');
@@ -48,3 +82,18 @@ em {
48
82
  @include meta.load-css('../_sass/_api-box');
49
83
  @include meta.load-css('../_sass/_syntax');
50
84
  @include meta.load-css('../_sass/_deprecations');
85
+
86
+ // Sidebar resize handle
87
+ .resize-handle {
88
+ position: fixed;
89
+ left: 300px; // Default sidebar width
90
+ top: 30px;
91
+ bottom: 0;
92
+ width: 10px;
93
+ cursor: ew-resize;
94
+ z-index: 3;
95
+ background-color: transparent;
96
+ &:hover {
97
+ background-color: var(--shadow-color);
98
+ }
99
+ }
@@ -33,8 +33,82 @@
33
33
 
34
34
  searchInput.addEventListener('input', listener);
35
35
  }
36
+
37
+ // Resize sidebar functionality
38
+ initializeSidebarResize();
36
39
  });
37
40
 
41
+ function initializeSidebarResize() {
42
+ const sidebar = document.getElementById('sidebar');
43
+ if (!sidebar) {
44
+ return;
45
+ }
46
+
47
+ const minWidth = 200;
48
+ const maxWidth = 350;
49
+
50
+ // Restore saved width from sessionStorage
51
+ const savedWidth = sessionStorage.getItem('sidebarWidth');
52
+ if (savedWidth) {
53
+ sidebar.style.width = savedWidth;
54
+ }
55
+
56
+ // Create resize handle as a sibling to sidebar (not inside it)
57
+ const resizeHandle = document.createElement('div');
58
+ resizeHandle.className = 'resize-handle';
59
+
60
+ // Position handle at current sidebar width
61
+ if (savedWidth) {
62
+ resizeHandle.style.left = savedWidth;
63
+ }
64
+
65
+ // Insert after sidebar
66
+ sidebar.parentNode.insertBefore(resizeHandle, sidebar.nextSibling);
67
+
68
+ // Track resize state
69
+ let isResizing = false;
70
+ let startX = 0;
71
+ let startWidth = 0;
72
+
73
+ // Mouse down on handle
74
+ resizeHandle.addEventListener('mousedown', function(e) {
75
+ isResizing = true;
76
+ startX = e.clientX;
77
+ startWidth = sidebar.offsetWidth;
78
+
79
+ // Prevent text selection while dragging
80
+ e.preventDefault();
81
+ document.body.style.userSelect = 'none';
82
+ document.body.style.cursor = 'ew-resize';
83
+ });
84
+
85
+ // Mouse move
86
+ document.addEventListener('mousemove', function(e) {
87
+ if (!isResizing) return;
88
+
89
+ const dx = e.clientX - startX;
90
+ const newWidth = startWidth + dx;
91
+
92
+ // Apply constraints
93
+ if (newWidth >= minWidth && newWidth <= maxWidth) {
94
+ sidebar.style.width = newWidth + 'px';
95
+ resizeHandle.style.left = newWidth + 'px';
96
+ }
97
+ });
98
+
99
+ // Mouse up
100
+ document.addEventListener('mouseup', function() {
101
+ if (isResizing) {
102
+ isResizing = false;
103
+ document.body.style.userSelect = '';
104
+ document.body.style.cursor = '';
105
+
106
+ // Save the new width to sessionStorage
107
+ sessionStorage.setItem('sidebarWidth', sidebar.style.width);
108
+ }
109
+ });
110
+ }
111
+
38
112
  function debounce(func, wait) {
39
113
  let timeout;
40
114
 
@@ -93,7 +167,7 @@
93
167
  <!-- mobile only -->
94
168
  <div id="mobile-header">
95
169
  <a class="menu-button" onclick="document.body.classList.toggle('sidebar-open')"></a>
96
- <a class="logo" href="<%= base_url.present? ? base_url : '/' %>">
170
+ <a class="logo" href="<%= base_url && !base_url.empty? ? base_url : '/' %>">
97
171
 
98
172
  </a>
99
173
  </div>
@@ -1,12 +1,14 @@
1
1
  <div id="search">
2
- <img src="<%= base_url %>/assets/images/search.svg">
2
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
3
+ <path d="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14" />
4
+ </svg>
3
5
  <input autocomplete="off" placeholder="Search" />
4
6
  </div>
5
7
  <ul class="categories">
6
8
  <li>
7
9
  <ul class="menu-root">
8
10
  <li>
9
- <a href="<%= base_url.present? ? base_url : '/' %>">GraphQL Reference</a>
11
+ <a href="<%= base_url && !base_url.empty? ? base_url : '/' %>">GraphQL Reference</a>
10
12
  </ul>
11
13
  </li>
12
14