docyard 0.9.0 → 1.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 (159) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +43 -0
  3. data/README.md +8 -253
  4. data/exe/docyard +6 -0
  5. data/lib/docyard/build/asset_bundler.rb +2 -2
  6. data/lib/docyard/build/file_copier.rb +12 -5
  7. data/lib/docyard/build/llms_txt_generator.rb +103 -0
  8. data/lib/docyard/build/sitemap_generator.rb +1 -1
  9. data/lib/docyard/build/static_generator.rb +115 -79
  10. data/lib/docyard/builder.rb +6 -2
  11. data/lib/docyard/cli.rb +14 -4
  12. data/lib/docyard/components/processors/callout_processor.rb +1 -1
  13. data/lib/docyard/components/processors/code_block_extended_fence_postprocessor.rb +24 -0
  14. data/lib/docyard/components/processors/code_block_extended_fence_preprocessor.rb +44 -0
  15. data/lib/docyard/components/processors/code_block_options_preprocessor.rb +11 -1
  16. data/lib/docyard/components/processors/code_block_processor.rb +5 -24
  17. data/lib/docyard/components/processors/code_group_processor.rb +6 -22
  18. data/lib/docyard/components/processors/code_snippet_import_preprocessor.rb +1 -0
  19. data/lib/docyard/components/processors/file_tree_processor.rb +1 -2
  20. data/lib/docyard/components/processors/icon_processor.rb +8 -2
  21. data/lib/docyard/components/processors/include_processor.rb +10 -10
  22. data/lib/docyard/components/processors/video_embed_processor.rb +14 -3
  23. data/lib/docyard/components/support/code_block/feature_extractor.rb +3 -1
  24. data/lib/docyard/components/support/code_block/icon_detector.rb +5 -12
  25. data/lib/docyard/components/support/code_block/line_number_resolver.rb +30 -0
  26. data/lib/docyard/components/support/code_detector.rb +2 -12
  27. data/lib/docyard/components/support/code_group/html_builder.rb +2 -6
  28. data/lib/docyard/components/support/tabs/icon_detector.rb +6 -2
  29. data/lib/docyard/components/support/tabs/parser.rb +6 -23
  30. data/lib/docyard/config/analytics_resolver.rb +24 -0
  31. data/lib/docyard/config/branding_resolver.rb +58 -27
  32. data/lib/docyard/config/key_validator.rb +30 -0
  33. data/lib/docyard/config/logo_detector.rb +8 -8
  34. data/lib/docyard/config/schema.rb +39 -0
  35. data/lib/docyard/config/section.rb +21 -0
  36. data/lib/docyard/config/validation_helpers.rb +83 -0
  37. data/lib/docyard/config/validator.rb +45 -144
  38. data/lib/docyard/config/validators/navigation.rb +43 -0
  39. data/lib/docyard/config/validators/section.rb +114 -0
  40. data/lib/docyard/config.rb +46 -102
  41. data/lib/docyard/constants.rb +59 -0
  42. data/lib/docyard/{utils/errors.rb → errors.rb} +6 -0
  43. data/lib/docyard/initializer.rb +100 -49
  44. data/lib/docyard/navigation/page_navigation_builder.rb +65 -0
  45. data/lib/docyard/navigation/sidebar/auto_builder.rb +107 -0
  46. data/lib/docyard/navigation/sidebar/cache.rb +96 -0
  47. data/lib/docyard/navigation/sidebar/config_builder.rb +179 -0
  48. data/lib/docyard/navigation/sidebar/distributed_builder.rb +145 -0
  49. data/lib/docyard/navigation/sidebar/local_config_loader.rb +69 -3
  50. data/lib/docyard/navigation/sidebar/renderer.rb +12 -1
  51. data/lib/docyard/navigation/sidebar_builder.rb +43 -81
  52. data/lib/docyard/rendering/branding_variables.rb +65 -0
  53. data/lib/docyard/rendering/icon_helpers.rb +14 -1
  54. data/lib/docyard/rendering/icons/devicons.rb +63 -0
  55. data/lib/docyard/rendering/icons.rb +26 -27
  56. data/lib/docyard/rendering/markdown.rb +5 -23
  57. data/lib/docyard/rendering/og_helpers.rb +36 -0
  58. data/lib/docyard/rendering/renderer.rb +87 -59
  59. data/lib/docyard/rendering/template_resolver.rb +14 -0
  60. data/lib/docyard/routing/fallback_resolver.rb +3 -3
  61. data/lib/docyard/search/build_indexer.rb +2 -2
  62. data/lib/docyard/search/dev_indexer.rb +36 -28
  63. data/lib/docyard/search/pagefind_support.rb +1 -1
  64. data/lib/docyard/server/asset_handler.rb +39 -15
  65. data/lib/docyard/server/dev_server.rb +90 -55
  66. data/lib/docyard/server/file_watcher.rb +68 -18
  67. data/lib/docyard/server/pagefind_handler.rb +1 -1
  68. data/lib/docyard/server/preview_server.rb +29 -33
  69. data/lib/docyard/server/rack_application.rb +38 -70
  70. data/lib/docyard/server/router.rb +11 -7
  71. data/lib/docyard/server/sse_server.rb +157 -0
  72. data/lib/docyard/server/static_file_app.rb +42 -0
  73. data/lib/docyard/templates/assets/css/components/banner.css +31 -0
  74. data/lib/docyard/templates/assets/css/components/breadcrumbs.css +2 -1
  75. data/lib/docyard/templates/assets/css/components/callout.css +26 -6
  76. data/lib/docyard/templates/assets/css/components/code-block.css +4 -2
  77. data/lib/docyard/templates/assets/css/components/code-group.css +20 -7
  78. data/lib/docyard/templates/assets/css/components/feedback.css +126 -0
  79. data/lib/docyard/templates/assets/css/components/file-tree.css +5 -4
  80. data/lib/docyard/templates/assets/css/components/icon.css +5 -0
  81. data/lib/docyard/templates/assets/css/components/nav-menu.css +20 -4
  82. data/lib/docyard/templates/assets/css/components/navigation.css +25 -3
  83. data/lib/docyard/templates/assets/css/components/page-actions.css +131 -0
  84. data/lib/docyard/templates/assets/css/components/prev-next.css +14 -7
  85. data/lib/docyard/templates/assets/css/components/search.css +6 -10
  86. data/lib/docyard/templates/assets/css/components/tab-bar.css +7 -4
  87. data/lib/docyard/templates/assets/css/components/table-of-contents.css +57 -11
  88. data/lib/docyard/templates/assets/css/components/tabs.css +12 -4
  89. data/lib/docyard/templates/assets/css/components/theme-toggle.css +3 -1
  90. data/lib/docyard/templates/assets/css/landing.css +82 -13
  91. data/lib/docyard/templates/assets/css/layout.css +17 -0
  92. data/lib/docyard/templates/assets/css/markdown.css +22 -2
  93. data/lib/docyard/templates/assets/css/variables.css +13 -1
  94. data/lib/docyard/templates/assets/js/components/code-group.js +4 -1
  95. data/lib/docyard/templates/assets/js/components/copy-page.js +115 -0
  96. data/lib/docyard/templates/assets/js/components/feedback.js +66 -0
  97. data/lib/docyard/templates/assets/js/components/file-tree.js +5 -5
  98. data/lib/docyard/templates/assets/js/components/navigation.js +3 -3
  99. data/lib/docyard/templates/assets/js/components/search.js +3 -3
  100. data/lib/docyard/templates/assets/js/components/table-of-contents.js +12 -6
  101. data/lib/docyard/templates/assets/js/components/tabs.js +45 -22
  102. data/lib/docyard/templates/assets/js/components/tooltip.js +4 -4
  103. data/lib/docyard/templates/assets/js/hot-reload.js +44 -0
  104. data/lib/docyard/templates/errors/404.html.erb +114 -5
  105. data/lib/docyard/templates/errors/500.html.erb +173 -10
  106. data/lib/docyard/templates/init/_sidebar.yml +36 -0
  107. data/lib/docyard/templates/init/docyard.yml +36 -0
  108. data/lib/docyard/templates/init/pages/components.md +146 -0
  109. data/lib/docyard/templates/init/pages/getting-started.md +94 -0
  110. data/lib/docyard/templates/init/pages/index.md +22 -0
  111. data/lib/docyard/templates/layouts/default.html.erb +10 -0
  112. data/lib/docyard/templates/layouts/splash.html.erb +14 -1
  113. data/lib/docyard/templates/partials/_analytics.html.erb +24 -0
  114. data/lib/docyard/templates/partials/_banner.html.erb +1 -1
  115. data/lib/docyard/templates/partials/_code_block.html.erb +1 -1
  116. data/lib/docyard/templates/partials/_feedback.html.erb +14 -0
  117. data/lib/docyard/templates/partials/_footer.html.erb +1 -1
  118. data/lib/docyard/templates/partials/_head.html.erb +79 -4
  119. data/lib/docyard/templates/partials/_icon_library.html.erb +8 -0
  120. data/lib/docyard/templates/partials/_page_actions.html.erb +21 -0
  121. data/lib/docyard/templates/partials/_scripts.html.erb +6 -3
  122. data/lib/docyard/templates/partials/_tabs.html.erb +4 -1
  123. data/lib/docyard/utils/git_info.rb +157 -0
  124. data/lib/docyard/utils/hash_utils.rb +31 -0
  125. data/lib/docyard/utils/html_helpers.rb +8 -0
  126. data/lib/docyard/utils/logging.rb +44 -3
  127. data/lib/docyard/utils/path_resolver.rb +0 -10
  128. data/lib/docyard/utils/path_utils.rb +73 -0
  129. data/lib/docyard/version.rb +1 -1
  130. data/lib/docyard.rb +2 -2
  131. metadata +77 -47
  132. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -31
  133. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -19
  134. data/.github/pull_request_template.md +0 -14
  135. data/.github/workflows/ci.yml +0 -49
  136. data/.rubocop.yml +0 -42
  137. data/CODE_OF_CONDUCT.md +0 -132
  138. data/CONTRIBUTING.md +0 -55
  139. data/LICENSE.vscode-icons +0 -42
  140. data/Rakefile +0 -8
  141. data/lib/docyard/config/constants.rb +0 -31
  142. data/lib/docyard/navigation/sidebar/children_discoverer.rb +0 -51
  143. data/lib/docyard/navigation/sidebar/config_parser.rb +0 -208
  144. data/lib/docyard/navigation/sidebar/file_resolver.rb +0 -90
  145. data/lib/docyard/navigation/sidebar/file_system_scanner.rb +0 -78
  146. data/lib/docyard/navigation/sidebar/metadata_extractor.rb +0 -71
  147. data/lib/docyard/navigation/sidebar/metadata_reader.rb +0 -51
  148. data/lib/docyard/navigation/sidebar/path_prefixer.rb +0 -34
  149. data/lib/docyard/navigation/sidebar/sorter.rb +0 -21
  150. data/lib/docyard/navigation/sidebar/title_extractor.rb +0 -25
  151. data/lib/docyard/navigation/sidebar/tree_builder.rb +0 -140
  152. data/lib/docyard/rendering/icons/LICENSE.phosphor +0 -21
  153. data/lib/docyard/rendering/icons/file_types.rb +0 -79
  154. data/lib/docyard/rendering/icons/phosphor.rb +0 -93
  155. data/lib/docyard/rendering/language_mapping.rb +0 -52
  156. data/lib/docyard/templates/assets/js/reload.js +0 -98
  157. data/lib/docyard/templates/partials/_icon.html.erb +0 -1
  158. data/lib/docyard/templates/partials/_icon_file_extension.html.erb +0 -1
  159. data/sig/docyard.rbs +0 -4
@@ -74,7 +74,8 @@
74
74
  flex-shrink: 0;
75
75
  }
76
76
 
77
- .docyard-tabs__icon .docyard-icon {
77
+ .docyard-tabs__icon .docyard-icon,
78
+ .docyard-tabs__icon i[class*="ph-"] {
78
79
  width: 1rem;
79
80
  height: 1rem;
80
81
  display: inline-flex;
@@ -94,13 +95,19 @@
94
95
  border-radius: 1px;
95
96
  pointer-events: none;
96
97
  z-index: 1;
97
-
98
+ opacity: 0;
99
+
98
100
  transition:
99
101
  transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1),
100
- width 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
102
+ width 0.3s cubic-bezier(0.34, 1.56, 0.64, 1),
103
+ opacity 0.15s ease;
101
104
  will-change: transform, width;
102
105
  }
103
106
 
107
+ .docyard-tabs__indicator.is-ready {
108
+ opacity: 1;
109
+ }
110
+
104
111
  .docyard-tabs__scroll-indicator {
105
112
  position: absolute;
106
113
  top: 0;
@@ -230,7 +237,8 @@
230
237
  gap: var(--spacing-1);
231
238
  }
232
239
 
233
- .docyard-tabs__icon .docyard-icon {
240
+ .docyard-tabs__icon .docyard-icon,
241
+ .docyard-tabs__icon i[class*="ph-"] {
234
242
  width: 0.875rem;
235
243
  height: 0.875rem;
236
244
  }
@@ -39,7 +39,9 @@
39
39
  }
40
40
 
41
41
  .theme-toggle-sun .docyard-icon,
42
- .theme-toggle-moon .docyard-icon {
42
+ .theme-toggle-moon .docyard-icon,
43
+ .theme-toggle-sun i[class*="ph-"],
44
+ .theme-toggle-moon i[class*="ph-"] {
43
45
  width: 1.125rem;
44
46
  height: 1.125rem;
45
47
  }
@@ -73,15 +73,15 @@
73
73
 
74
74
  .hero-bg--grid {
75
75
  background-image:
76
- linear-gradient(oklch(0 0 0 / 0.06) 1px, transparent 1px),
77
- linear-gradient(90deg, oklch(0 0 0 / 0.06) 1px, transparent 1px);
78
- background-size: 100px 100px;
76
+ linear-gradient(oklch(0 0 0 / 0.03) 1px, transparent 1px),
77
+ linear-gradient(90deg, oklch(0 0 0 / 0.03) 1px, transparent 1px);
78
+ background-size: 60px 60px;
79
79
  }
80
80
 
81
81
  .dark .hero-bg--grid {
82
82
  background-image:
83
- linear-gradient(oklch(1 0 0 / 0.08) 1px, transparent 1px),
84
- linear-gradient(90deg, oklch(1 0 0 / 0.08) 1px, transparent 1px);
83
+ linear-gradient(oklch(1 0 0 / 0.04) 1px, transparent 1px),
84
+ linear-gradient(90deg, oklch(1 0 0 / 0.04) 1px, transparent 1px);
85
85
  }
86
86
 
87
87
  .hero-bg--grid::after {
@@ -249,7 +249,7 @@
249
249
  background: linear-gradient(135deg,
250
250
  var(--foreground) 0%,
251
251
  var(--foreground) 40%,
252
- oklch(from var(--primary) calc(l + 0.1) c h) 100%);
252
+ oklch(from var(--primary) calc(l - 0.15) c h) 100%);
253
253
  -webkit-background-clip: text;
254
254
  -webkit-text-fill-color: transparent;
255
255
  background-clip: text;
@@ -314,12 +314,12 @@
314
314
 
315
315
  .hero-action--secondary {
316
316
  background: transparent;
317
- color: var(--foreground);
318
- border: 1px solid var(--border);
317
+ color: var(--muted-foreground);
318
+ border: none;
319
319
  }
320
320
 
321
321
  .hero-action--secondary:hover {
322
- background: var(--muted);
322
+ background: transparent;
323
323
  color: var(--foreground);
324
324
  }
325
325
 
@@ -382,6 +382,70 @@
382
382
  display: block;
383
383
  }
384
384
 
385
+ .hero-custom-visual {
386
+ position: relative;
387
+ z-index: 1;
388
+ }
389
+
390
+ .hero-custom-visual--side {
391
+ display: flex;
392
+ align-items: center;
393
+ justify-content: center;
394
+ }
395
+
396
+ .hero-custom-visual--bottom {
397
+ width: 100%;
398
+ max-width: 1100px;
399
+ margin: 0 auto;
400
+ padding: 0 var(--spacing-6);
401
+ margin-bottom: var(--spacing-2);
402
+ }
403
+
404
+ .hero--with-bottom-visual {
405
+ min-height: auto;
406
+ height: auto;
407
+ align-items: flex-start;
408
+ padding-top: 10rem;
409
+ padding-bottom: var(--spacing-4);
410
+ }
411
+
412
+ .hero--with-bottom-visual .hero-content {
413
+ padding-top: 0;
414
+ padding-bottom: var(--spacing-16);
415
+ }
416
+
417
+ @media (max-width: 1024px) {
418
+ .hero-custom-visual--side {
419
+ grid-column: 1 / -1;
420
+ order: 1;
421
+ width: 100%;
422
+ max-width: 1100px;
423
+ margin: 0 auto;
424
+ padding: 0 var(--spacing-4);
425
+ margin-bottom: var(--spacing-2);
426
+ }
427
+
428
+ .hero--with-image:has(.hero-custom-visual--side) {
429
+ min-height: auto;
430
+ height: auto;
431
+ padding-top: 7rem;
432
+ padding-bottom: var(--spacing-4);
433
+ }
434
+
435
+ .hero--with-image:has(.hero-custom-visual--side) .hero-content {
436
+ padding-top: 0;
437
+ padding-bottom: var(--spacing-16);
438
+ }
439
+
440
+ .hero-custom-visual--bottom {
441
+ padding: 0 var(--spacing-4);
442
+ }
443
+
444
+ .hero--with-bottom-visual {
445
+ padding-top: 7rem;
446
+ }
447
+ }
448
+
385
449
  .features-section {
386
450
  padding: var(--spacing-16) var(--spacing-6) var(--spacing-20);
387
451
  background: linear-gradient(180deg, var(--background) 0%, oklch(from var(--background) calc(l + 0.02) c h) 100%);
@@ -394,7 +458,7 @@
394
458
  .features-header {
395
459
  text-align: center;
396
460
  max-width: 600px;
397
- margin: 0 auto var(--spacing-12);
461
+ margin: 0 auto var(--spacing-20);
398
462
  }
399
463
 
400
464
  .features-label {
@@ -407,15 +471,15 @@
407
471
  }
408
472
 
409
473
  .features-title {
410
- font-size: var(--text-2xl);
411
- font-weight: var(--font-semibold);
474
+ font-size: clamp(2rem, 4vw, 3rem);
475
+ font-weight: 700;
412
476
  color: var(--foreground);
413
477
  margin: 0 0 var(--spacing-3) 0;
414
478
  }
415
479
 
416
480
  .features-description {
417
481
  color: var(--muted-foreground);
418
- font-size: var(--text-base);
482
+ font-size: var(--text-lg);
419
483
  margin: 0;
420
484
  line-height: 1.6;
421
485
  }
@@ -478,6 +542,7 @@
478
542
  flex-direction: column;
479
543
  gap: var(--spacing-4);
480
544
  padding: var(--spacing-6);
545
+ height: 100%;
481
546
  background: var(--card);
482
547
  border: 1px solid var(--border);
483
548
  border-radius: var(--radius-xl);
@@ -746,6 +811,10 @@ a.feature-card:active {
746
811
  padding: var(--spacing-10) var(--spacing-4) var(--spacing-12);
747
812
  }
748
813
 
814
+ .hero-custom-visual--bottom + .features-section {
815
+ padding-top: var(--spacing-2);
816
+ }
817
+
749
818
  .features-header {
750
819
  margin-bottom: var(--spacing-8);
751
820
  }
@@ -34,6 +34,7 @@ html:has(.has-tabs) {
34
34
  backdrop-filter: blur(12px);
35
35
  z-index: var(--z-header);
36
36
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
37
+ will-change: transform;
37
38
  }
38
39
 
39
40
  .header.hide-on-scroll {
@@ -200,6 +201,7 @@ html:has(.has-tabs) {
200
201
  z-index: var(--z-secondary-header);
201
202
  transition: top 0.3s cubic-bezier(0.4, 0, 0.2, 1), left 0.3s cubic-bezier(0.4, 0, 0.2, 1);
202
203
  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.02);
204
+ will-change: top, left;
203
205
  }
204
206
 
205
207
  .secondary-header.shift-up {
@@ -232,6 +234,7 @@ html:has(.has-tabs) {
232
234
  z-index: var(--z-secondary-header);
233
235
  transition: top 0.3s cubic-bezier(0.4, 0, 0.2, 1);
234
236
  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.02);
237
+ will-change: top;
235
238
  }
236
239
 
237
240
  .secondary-header.shift-up {
@@ -715,6 +718,13 @@ main.content {
715
718
 
716
719
  @media (max-width: 1280px) and (min-width: 1025px) {
717
720
  .doc-aside {
721
+ position: absolute;
722
+ width: 0;
723
+ height: 0;
724
+ overflow: visible;
725
+ }
726
+
727
+ .doc-aside .doc-footer-desktop {
718
728
  display: none;
719
729
  }
720
730
 
@@ -736,6 +746,13 @@ main.content {
736
746
 
737
747
  @media (max-width: 1024px) {
738
748
  .doc-aside {
749
+ position: absolute;
750
+ width: 0;
751
+ height: 0;
752
+ overflow: visible;
753
+ }
754
+
755
+ .doc-aside .doc-footer-desktop {
739
756
  display: none;
740
757
  }
741
758
 
@@ -21,6 +21,26 @@
21
21
  font-variant-ligatures: none;
22
22
  }
23
23
 
24
+ .content .docyard-callout--note code:not(.highlight code) {
25
+ background-color: oklch(from var(--callout-note-border) l c h / 15%);
26
+ }
27
+
28
+ .content .docyard-callout--tip code:not(.highlight code) {
29
+ background-color: oklch(from var(--callout-tip-border) l c h / 15%);
30
+ }
31
+
32
+ .content .docyard-callout--important code:not(.highlight code) {
33
+ background-color: oklch(from var(--callout-important-border) l c h / 15%);
34
+ }
35
+
36
+ .content .docyard-callout--warning code:not(.highlight code) {
37
+ background-color: oklch(from var(--callout-warning-border) l c h / 15%);
38
+ }
39
+
40
+ .content .docyard-callout--danger code:not(.highlight code) {
41
+ background-color: oklch(from var(--callout-danger-border) l c h / 15%);
42
+ }
43
+
24
44
  .content ul,
25
45
  .content ol {
26
46
  margin: var(--spacing-5) 0;
@@ -154,7 +174,7 @@
154
174
  cursor: zoom-in;
155
175
  }
156
176
 
157
- .content a:not(.heading-anchor):not(.pager-link):not(.breadcrumb-link):not(.site-footer__link):not(.site-footer__attribution):not(.docyard-card):not(.docyard-announcement__link):not(.docyard-announcement__button) {
177
+ .content a:not(.heading-anchor):not(.pager-link):not(.breadcrumb-link):not(.site-footer__link):not(.site-footer__attribution):not(.docyard-card):not(.docyard-announcement__link):not(.docyard-announcement__button):not(.page-actions__edit-link) {
158
178
  color: var(--foreground);
159
179
  font-weight: var(--font-semibold);
160
180
  text-decoration: none;
@@ -162,7 +182,7 @@
162
182
  transition: border-bottom var(--transition-fast);
163
183
  }
164
184
 
165
- .content a:not(.heading-anchor):not(.pager-link):not(.breadcrumb-link):not(.site-footer__link):not(.site-footer__attribution):not(.docyard-card):not(.docyard-announcement__link):not(.docyard-announcement__button):hover {
185
+ .content a:not(.heading-anchor):not(.pager-link):not(.breadcrumb-link):not(.site-footer__link):not(.site-footer__attribution):not(.docyard-card):not(.docyard-announcement__link):not(.docyard-announcement__button):not(.page-actions__edit-link):hover {
166
186
  border-bottom: 2px solid var(--primary);
167
187
  }
168
188
 
@@ -3,7 +3,7 @@
3
3
  src: url('/_docyard/fonts/Inter-Variable.ttf') format('truetype');
4
4
  font-weight: 100 900;
5
5
  font-style: normal;
6
- font-display: optional;
6
+ font-display: swap;
7
7
  }
8
8
 
9
9
  :root {
@@ -308,3 +308,15 @@
308
308
  --text-4xl: 1.875rem;
309
309
  }
310
310
  }
311
+
312
+ .no-transition,
313
+ .no-transition *,
314
+ .no-transition *::before,
315
+ .no-transition *::after {
316
+ transition: none !important;
317
+ animation: none !important;
318
+ }
319
+
320
+ .banner-dismissed .docyard-announcement {
321
+ display: none !important;
322
+ }
@@ -59,9 +59,12 @@ class CodeGroup {
59
59
  this.checkIcon = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" viewBox="0 0 256 256"><path d="M229.66,77.66l-128,128a8,8,0,0,1-11.32,0l-56-56a8,8,0,0,1,11.32-11.32L96,188.69,218.34,66.34a8,8,0,0,1,11.32,11.32Z"/></svg>';
60
60
 
61
61
  this.attachEventListeners();
62
- this.updateIndicator();
62
+ this.updateIndicator(false);
63
63
 
64
64
  requestAnimationFrame(() => {
65
+ if (this.indicator) {
66
+ this.indicator.classList.add('is-ready');
67
+ }
65
68
  this.updateScrollIndicators();
66
69
  });
67
70
  }
@@ -0,0 +1,115 @@
1
+ class CopyPageManager {
2
+ constructor() {
3
+ this.buttons = document.querySelectorAll('[data-copy-page]');
4
+ this.markdownElement = document.getElementById('page-markdown');
5
+
6
+ this.handleCopy = this.handleCopy.bind(this);
7
+ this.init();
8
+ }
9
+
10
+ init() {
11
+ if (!this.markdownElement || this.buttons.length === 0) return;
12
+
13
+ this.buttons.forEach(button => {
14
+ button.addEventListener('click', this.handleCopy);
15
+ });
16
+ }
17
+
18
+ getMarkdownContent() {
19
+ if (!this.markdownElement) return null;
20
+
21
+ try {
22
+ return JSON.parse(this.markdownElement.textContent);
23
+ } catch (error) {
24
+ console.warn('Failed to parse markdown content:', error);
25
+ return null;
26
+ }
27
+ }
28
+
29
+ async handleCopy(event) {
30
+ const button = event.currentTarget;
31
+ const content = this.getMarkdownContent();
32
+
33
+ if (!content) {
34
+ console.warn('No markdown content available to copy');
35
+ return;
36
+ }
37
+
38
+ try {
39
+ await this.copyToClipboard(content);
40
+ this.showSuccess(button);
41
+ } catch (error) {
42
+ console.warn('Failed to copy page:', error);
43
+ }
44
+ }
45
+
46
+ async copyToClipboard(text) {
47
+ if (navigator.clipboard && window.isSecureContext) {
48
+ await navigator.clipboard.writeText(text);
49
+ } else {
50
+ this.fallbackCopy(text);
51
+ }
52
+ }
53
+
54
+ fallbackCopy(text) {
55
+ const textArea = document.createElement('textarea');
56
+ textArea.value = text;
57
+ textArea.style.position = 'fixed';
58
+ textArea.style.left = '-999999px';
59
+ textArea.style.top = '-999999px';
60
+ document.body.appendChild(textArea);
61
+ textArea.focus();
62
+ textArea.select();
63
+
64
+ try {
65
+ document.execCommand('copy');
66
+ textArea.remove();
67
+ } catch (error) {
68
+ textArea.remove();
69
+ throw error;
70
+ }
71
+ }
72
+
73
+ showSuccess(button) {
74
+ const iconElement = button.querySelector('i[class*="ph-"]');
75
+ const textElement = button.querySelector('.page-actions__copy-text');
76
+ const originalClasses = iconElement?.className;
77
+
78
+ button.classList.add('is-copied');
79
+
80
+ if (iconElement) {
81
+ iconElement.className = 'ph ph-check';
82
+ iconElement.classList.add('icon-animate-in');
83
+ }
84
+ if (textElement) {
85
+ textElement.textContent = 'Copied';
86
+ }
87
+
88
+ setTimeout(() => {
89
+ button.classList.remove('is-copied');
90
+ if (iconElement && originalClasses) {
91
+ iconElement.classList.add('icon-animate-out');
92
+ setTimeout(() => {
93
+ iconElement.className = originalClasses;
94
+ }, 150);
95
+ }
96
+ if (textElement) {
97
+ textElement.textContent = 'Copy page';
98
+ }
99
+ }, 2000);
100
+ }
101
+ }
102
+
103
+ function initializeCopyPage() {
104
+ new CopyPageManager();
105
+ }
106
+
107
+ if (document.readyState === 'loading') {
108
+ document.addEventListener('DOMContentLoaded', initializeCopyPage);
109
+ } else {
110
+ initializeCopyPage();
111
+ }
112
+
113
+ if (typeof module !== 'undefined' && module.exports) {
114
+ module.exports = { CopyPageManager };
115
+ }
@@ -0,0 +1,66 @@
1
+ class FeedbackManager {
2
+ constructor() {
3
+ this.container = document.querySelector('.feedback');
4
+ if (!this.container) return;
5
+
6
+ this.buttons = this.container.querySelectorAll('.feedback__btn');
7
+ this.thanks = this.container.querySelector('.feedback__thanks');
8
+ this.pagePath = window.location.pathname;
9
+
10
+ this.init();
11
+ }
12
+
13
+ init() {
14
+ this.buttons.forEach(button => {
15
+ button.addEventListener('click', (e) => this.handleFeedback(e));
16
+ });
17
+ }
18
+
19
+ handleFeedback(event) {
20
+ const button = event.currentTarget;
21
+ const value = button.dataset.feedback;
22
+ const isHelpful = value === 'yes';
23
+
24
+ this.updateUI(button);
25
+ this.sendAnalytics(isHelpful);
26
+ }
27
+
28
+ updateUI(selectedButton) {
29
+ this.buttons.forEach(button => {
30
+ if (button === selectedButton) {
31
+ button.classList.add('is-selected');
32
+ } else {
33
+ button.classList.add('is-not-selected');
34
+ }
35
+ });
36
+
37
+ setTimeout(() => {
38
+ this.container.classList.add('is-submitted');
39
+ this.thanks.hidden = false;
40
+ }, 600);
41
+ }
42
+
43
+ sendAnalytics(isHelpful) {
44
+ const helpful = isHelpful ? 'yes' : 'no';
45
+
46
+ if (typeof gtag === 'function') {
47
+ gtag('event', 'page_feedback', {
48
+ feedback_page: this.pagePath,
49
+ helpful: helpful,
50
+ value: isHelpful ? 1 : 0
51
+ });
52
+ }
53
+
54
+ if (typeof plausible === 'function') {
55
+ plausible('Feedback', { props: { helpful: helpful, page: this.pagePath } });
56
+ }
57
+
58
+ if (typeof fathom === 'object' && typeof fathom.trackEvent === 'function') {
59
+ fathom.trackEvent(`feedback_${helpful}`);
60
+ }
61
+ }
62
+ }
63
+
64
+ document.addEventListener('DOMContentLoaded', () => {
65
+ new FeedbackManager();
66
+ });
@@ -17,14 +17,14 @@ function initializeFileTrees() {
17
17
 
18
18
  folder.classList.toggle('docyard-filetree__item--collapsed');
19
19
 
20
- const icon = entry.querySelector('.docyard-icon');
20
+ const icon = entry.querySelector('i[class*="ph-"]');
21
21
  if (icon) {
22
22
  if (isCollapsed) {
23
- icon.classList.remove('docyard-icon-folder');
24
- icon.classList.add('docyard-icon-folder-open');
23
+ icon.classList.remove('ph-folder');
24
+ icon.classList.add('ph-folder-open');
25
25
  } else {
26
- icon.classList.remove('docyard-icon-folder-open');
27
- icon.classList.add('docyard-icon-folder');
26
+ icon.classList.remove('ph-folder-open');
27
+ icon.classList.add('ph-folder');
28
28
  }
29
29
  }
30
30
  });
@@ -267,7 +267,7 @@
267
267
  scrollTimeout = setTimeout(function() {
268
268
  sessionStorage.setItem(STORAGE_KEY, scrollContainer.scrollTop);
269
269
  }, 150);
270
- });
270
+ }, { passive: true });
271
271
 
272
272
  const logo = document.querySelector('.header-logo');
273
273
  if (logo) {
@@ -304,9 +304,9 @@
304
304
 
305
305
  updateFadeIndicators();
306
306
 
307
- scrollContainer.addEventListener('scroll', updateFadeIndicators);
307
+ scrollContainer.addEventListener('scroll', updateFadeIndicators, { passive: true });
308
308
 
309
- window.addEventListener('resize', updateFadeIndicators);
309
+ window.addEventListener('resize', updateFadeIndicators, { passive: true });
310
310
  }
311
311
 
312
312
  function initScrollBehavior() {
@@ -220,11 +220,11 @@ class SearchManager {
220
220
 
221
221
  async initPagefind() {
222
222
  try {
223
- this.pagefind = await import('/pagefind/pagefind.js');
224
- await this.pagefind.init();
223
+ this.pagefind = await import('/_docyard/pagefind/pagefind.js');
224
+ await this.pagefind.options({ baseUrl: '/' });
225
225
  } catch (error) {
226
226
  console.warn('Pagefind not available:', error);
227
- this.showErrorState('Search is not available. Run "docyard build" to generate the search index.');
227
+ this.showErrorState('Search is not available. Run "docyard serve -s" to enable search.');
228
228
  }
229
229
  }
230
230
 
@@ -308,7 +308,7 @@ class TableOfContentsManager {
308
308
  };
309
309
 
310
310
  checkOverflow();
311
- window.addEventListener('resize', checkOverflow);
311
+ window.addEventListener('resize', checkOverflow, { passive: true });
312
312
  }
313
313
 
314
314
  setupScrollFadeIndicators() {
@@ -343,11 +343,11 @@ class TableOfContentsManager {
343
343
  scrollContainer.addEventListener('scroll', () => {
344
344
  updateFadeIndicators();
345
345
  this.updateIndicator();
346
- });
346
+ }, { passive: true });
347
347
  window.addEventListener('resize', () => {
348
348
  updateFadeIndicators();
349
349
  this.updateIndicator();
350
- });
350
+ }, { passive: true });
351
351
  }
352
352
 
353
353
 
@@ -375,10 +375,16 @@ class TableOfContentsManager {
375
375
  }
376
376
  }
377
377
 
378
+ function initializeTableOfContents() {
379
+ window.tocManager = new TableOfContentsManager();
380
+ }
381
+
378
382
  if (typeof window !== 'undefined') {
379
- document.addEventListener('DOMContentLoaded', () => {
380
- window.tocManager = new TableOfContentsManager();
381
- });
383
+ if (document.readyState === 'loading') {
384
+ document.addEventListener('DOMContentLoaded', initializeTableOfContents);
385
+ } else {
386
+ initializeTableOfContents();
387
+ }
382
388
 
383
389
  window.addEventListener('beforeunload', () => {
384
390
  if (window.tocManager) {