docyard 0.8.0 → 0.9.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 (69) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -1
  3. data/lib/docyard/components/aliases.rb +12 -0
  4. data/lib/docyard/components/processors/abbreviation_processor.rb +72 -0
  5. data/lib/docyard/components/processors/accordion_processor.rb +81 -0
  6. data/lib/docyard/components/processors/badge_processor.rb +72 -0
  7. data/lib/docyard/components/processors/callout_processor.rb +8 -2
  8. data/lib/docyard/components/processors/cards_processor.rb +100 -0
  9. data/lib/docyard/components/processors/code_block_options_preprocessor.rb +23 -2
  10. data/lib/docyard/components/processors/code_block_processor.rb +6 -0
  11. data/lib/docyard/components/processors/code_group_processor.rb +198 -0
  12. data/lib/docyard/components/processors/code_snippet_import_preprocessor.rb +6 -1
  13. data/lib/docyard/components/processors/custom_anchor_processor.rb +42 -0
  14. data/lib/docyard/components/processors/file_tree_processor.rb +151 -0
  15. data/lib/docyard/components/processors/image_caption_processor.rb +96 -0
  16. data/lib/docyard/components/processors/include_processor.rb +86 -0
  17. data/lib/docyard/components/processors/steps_processor.rb +89 -0
  18. data/lib/docyard/components/processors/tabs_processor.rb +9 -1
  19. data/lib/docyard/components/processors/tooltip_processor.rb +57 -0
  20. data/lib/docyard/components/processors/video_embed_processor.rb +196 -0
  21. data/lib/docyard/components/support/code_group/html_builder.rb +122 -0
  22. data/lib/docyard/components/support/markdown_code_block_helper.rb +56 -0
  23. data/lib/docyard/config/branding_resolver.rb +30 -35
  24. data/lib/docyard/config/logo_detector.rb +39 -0
  25. data/lib/docyard/config.rb +6 -1
  26. data/lib/docyard/navigation/sidebar/file_resolver.rb +16 -4
  27. data/lib/docyard/navigation/sidebar/item.rb +6 -1
  28. data/lib/docyard/navigation/sidebar/metadata_extractor.rb +4 -2
  29. data/lib/docyard/navigation/sidebar/metadata_reader.rb +8 -4
  30. data/lib/docyard/navigation/sidebar/renderer.rb +6 -2
  31. data/lib/docyard/navigation/sidebar/tree_builder.rb +2 -1
  32. data/lib/docyard/rendering/icons/phosphor.rb +3 -0
  33. data/lib/docyard/rendering/markdown.rb +24 -1
  34. data/lib/docyard/rendering/renderer.rb +2 -1
  35. data/lib/docyard/server/asset_handler.rb +1 -0
  36. data/lib/docyard/templates/assets/css/components/abbreviation.css +86 -0
  37. data/lib/docyard/templates/assets/css/components/accordion.css +138 -0
  38. data/lib/docyard/templates/assets/css/components/badges.css +47 -0
  39. data/lib/docyard/templates/assets/css/components/banner.css +202 -0
  40. data/lib/docyard/templates/assets/css/components/cards.css +100 -0
  41. data/lib/docyard/templates/assets/css/components/code-block.css +10 -0
  42. data/lib/docyard/templates/assets/css/components/code-group.css +281 -0
  43. data/lib/docyard/templates/assets/css/components/figure.css +22 -0
  44. data/lib/docyard/templates/assets/css/components/file-tree.css +124 -0
  45. data/lib/docyard/templates/assets/css/components/heading-anchor.css +21 -13
  46. data/lib/docyard/templates/assets/css/components/lightbox.css +65 -0
  47. data/lib/docyard/templates/assets/css/components/navigation.css +7 -0
  48. data/lib/docyard/templates/assets/css/components/prev-next.css +9 -18
  49. data/lib/docyard/templates/assets/css/components/steps.css +122 -0
  50. data/lib/docyard/templates/assets/css/components/tabs.css +1 -1
  51. data/lib/docyard/templates/assets/css/components/tooltip.css +113 -0
  52. data/lib/docyard/templates/assets/css/components/video.css +41 -0
  53. data/lib/docyard/templates/assets/css/markdown.css +5 -3
  54. data/lib/docyard/templates/assets/js/components/abbreviation.js +85 -0
  55. data/lib/docyard/templates/assets/js/components/banner.js +81 -0
  56. data/lib/docyard/templates/assets/js/components/code-group.js +283 -0
  57. data/lib/docyard/templates/assets/js/components/file-tree.js +39 -0
  58. data/lib/docyard/templates/assets/js/components/lightbox.js +72 -0
  59. data/lib/docyard/templates/assets/js/components/tooltip.js +118 -0
  60. data/lib/docyard/templates/layouts/default.html.erb +1 -0
  61. data/lib/docyard/templates/layouts/splash.html.erb +1 -0
  62. data/lib/docyard/templates/partials/_accordion.html.erb +9 -0
  63. data/lib/docyard/templates/partials/_banner.html.erb +27 -0
  64. data/lib/docyard/templates/partials/_card.html.erb +23 -0
  65. data/lib/docyard/templates/partials/_nav_group.html.erb +6 -0
  66. data/lib/docyard/templates/partials/_nav_leaf.html.erb +3 -0
  67. data/lib/docyard/templates/partials/_step.html.erb +14 -0
  68. data/lib/docyard/version.rb +1 -1
  69. metadata +38 -1
@@ -58,10 +58,8 @@
58
58
 
59
59
  .pager-label .docyard-icon {
60
60
  display: inline-flex;
61
- opacity: 0;
62
- transition:
63
- opacity 0.2s ease,
64
- transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
61
+ opacity: 0.5;
62
+ transition: transform 0.4s cubic-bezier(0.34, 1.56, 0.64, 1);
65
63
  }
66
64
 
67
65
  .pager-label .docyard-icon svg {
@@ -69,17 +67,16 @@
69
67
  height: 1rem;
70
68
  }
71
69
 
72
- .pager-link.prev .pager-label .docyard-icon {
73
- transform: translateX(6px);
70
+ .pager-link:hover .pager-label .docyard-icon {
71
+ opacity: 1;
74
72
  }
75
73
 
76
- .pager-link.next .pager-label .docyard-icon {
77
- transform: translateX(-6px);
74
+ .pager-link.prev:hover .pager-label .docyard-icon {
75
+ transform: translateX(-4px);
78
76
  }
79
77
 
80
- .pager-link:hover .pager-label .docyard-icon {
81
- opacity: 1;
82
- transform: translateX(0);
78
+ .pager-link.next:hover .pager-label .docyard-icon {
79
+ transform: translateX(4px);
83
80
  }
84
81
 
85
82
  .pager-title {
@@ -101,14 +98,8 @@
101
98
  padding: var(--spacing-3) var(--spacing-4);
102
99
  }
103
100
 
104
-
105
101
  .pager-label .docyard-icon {
106
- opacity: 0.6;
107
- transform: translateX(0);
108
- }
109
-
110
- .pager-link:hover .pager-label .docyard-icon {
111
- opacity: 1;
102
+ opacity: 0.5;
112
103
  }
113
104
 
114
105
  .pager-title {
@@ -0,0 +1,122 @@
1
+ .docyard-steps {
2
+ margin: var(--spacing-6) 0;
3
+ }
4
+
5
+ .docyard-step {
6
+ display: flex;
7
+ gap: var(--spacing-4);
8
+ position: relative;
9
+ }
10
+
11
+ .docyard-step:not(.docyard-step--last) {
12
+ padding-bottom: var(--spacing-6);
13
+ }
14
+
15
+ .docyard-step__indicator {
16
+ display: flex;
17
+ flex-direction: column;
18
+ align-items: center;
19
+ flex-shrink: 0;
20
+ }
21
+
22
+ .docyard-step__number {
23
+ display: flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ width: 2rem;
27
+ height: 2rem;
28
+ border-radius: 50%;
29
+ background-color: var(--primary);
30
+ color: var(--primary-foreground);
31
+ font-size: var(--text-sm);
32
+ font-weight: var(--font-semibold);
33
+ flex-shrink: 0;
34
+ }
35
+
36
+ .docyard-step__connector {
37
+ width: 2px;
38
+ flex: 1;
39
+ background-color: var(--border);
40
+ margin-top: var(--spacing-2);
41
+ }
42
+
43
+ .docyard-step__content {
44
+ flex: 1;
45
+ min-width: 0;
46
+ padding-top: var(--spacing-1);
47
+ }
48
+
49
+ .docyard-step__title {
50
+ margin: 0;
51
+ font-size: var(--text-base);
52
+ font-weight: var(--font-semibold);
53
+ color: var(--foreground);
54
+ line-height: var(--leading-tight);
55
+ }
56
+
57
+ .docyard-step__body {
58
+ margin-top: var(--spacing-3);
59
+ font-size: var(--text-sm);
60
+ color: var(--muted-foreground);
61
+ line-height: var(--leading-relaxed);
62
+ }
63
+
64
+ .docyard-step__body > *:first-child {
65
+ margin-top: 0;
66
+ }
67
+
68
+ .docyard-step__body > *:last-child {
69
+ margin-bottom: 0;
70
+ }
71
+
72
+ .docyard-step__body p {
73
+ margin: var(--spacing-2) 0;
74
+ }
75
+
76
+ .docyard-step__body a {
77
+ color: var(--primary);
78
+ text-decoration: underline;
79
+ text-underline-offset: 3px;
80
+ }
81
+
82
+ .docyard-step__body a:hover {
83
+ color: var(--foreground);
84
+ }
85
+
86
+ .docyard-step__body pre {
87
+ margin: var(--spacing-4) 0;
88
+ border-radius: var(--radius-lg);
89
+ }
90
+
91
+ .docyard-step__body :not(pre) > code {
92
+ background-color: var(--muted);
93
+ padding: 0.125rem 0.375rem;
94
+ border-radius: var(--radius-sm);
95
+ font-size: 0.875em;
96
+ }
97
+
98
+ .docyard-step__body ul,
99
+ .docyard-step__body ol {
100
+ margin: var(--spacing-2) 0;
101
+ padding-left: var(--spacing-4);
102
+ }
103
+
104
+ .docyard-step__body li {
105
+ margin: var(--spacing-1) 0;
106
+ }
107
+
108
+ @media (max-width: 640px) {
109
+ .docyard-step {
110
+ gap: var(--spacing-3);
111
+ }
112
+
113
+ .docyard-step__number {
114
+ width: 1.75rem;
115
+ height: 1.75rem;
116
+ font-size: var(--text-xs);
117
+ }
118
+
119
+ .docyard-step__title {
120
+ font-size: var(--text-sm);
121
+ }
122
+ }
@@ -90,7 +90,7 @@
90
90
  bottom: 0;
91
91
  left: 0;
92
92
  height: 2px;
93
- background: var(--foreground);
93
+ background: var(--primary);
94
94
  border-radius: 1px;
95
95
  pointer-events: none;
96
96
  z-index: 1;
@@ -0,0 +1,113 @@
1
+ .docyard-tooltip {
2
+ text-decoration: underline;
3
+ text-decoration-style: dotted;
4
+ text-decoration-color: var(--muted-foreground);
5
+ text-underline-offset: 3px;
6
+ cursor: help;
7
+ position: relative;
8
+ }
9
+
10
+ .docyard-tooltip:hover {
11
+ text-decoration-color: var(--primary);
12
+ }
13
+
14
+ .docyard-tooltip-popover {
15
+ position: absolute;
16
+ z-index: 1000;
17
+ width: max-content;
18
+ max-width: 300px;
19
+ padding: var(--spacing-3) var(--spacing-4);
20
+ background: var(--background);
21
+ border: 1px solid var(--border);
22
+ border-radius: var(--radius-lg);
23
+ box-shadow:
24
+ 0 4px 6px -1px oklch(from var(--foreground) l c h / 8%),
25
+ 0 2px 4px -2px oklch(from var(--foreground) l c h / 6%);
26
+ pointer-events: none;
27
+ opacity: 0;
28
+ transform: translateY(-4px) scale(0.96);
29
+ transition:
30
+ opacity 0.15s ease,
31
+ transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
32
+ }
33
+
34
+ .docyard-tooltip-popover.is-visible {
35
+ opacity: 1;
36
+ transform: translateY(0) scale(1);
37
+ pointer-events: auto;
38
+ }
39
+
40
+ .docyard-tooltip-popover::after {
41
+ content: "";
42
+ position: absolute;
43
+ bottom: -6px;
44
+ left: var(--arrow-left, 16px);
45
+ width: 10px;
46
+ height: 10px;
47
+ background: var(--background);
48
+ border-bottom: 1px solid var(--border);
49
+ border-right: 1px solid var(--border);
50
+ transform: rotate(45deg);
51
+ }
52
+
53
+ .docyard-tooltip-popover__term {
54
+ display: block;
55
+ font-weight: var(--font-semibold);
56
+ font-size: var(--text-sm);
57
+ color: var(--foreground);
58
+ margin-bottom: var(--spacing-1);
59
+ }
60
+
61
+ .docyard-tooltip-popover__description {
62
+ display: block;
63
+ font-size: var(--text-sm);
64
+ color: var(--muted-foreground);
65
+ line-height: var(--leading-relaxed);
66
+ }
67
+
68
+ .docyard-tooltip-popover__link {
69
+ display: inline-flex;
70
+ align-items: center;
71
+ gap: var(--spacing-1);
72
+ margin-top: var(--spacing-2);
73
+ font-size: var(--text-sm);
74
+ font-weight: var(--font-medium);
75
+ color: var(--foreground);
76
+ text-decoration: none;
77
+ }
78
+
79
+ .docyard-tooltip-popover__link:hover {
80
+ color: var(--primary);
81
+ }
82
+
83
+ .docyard-tooltip-popover__link-icon {
84
+ width: 14px;
85
+ height: 14px;
86
+ transition: transform 0.15s ease;
87
+ }
88
+
89
+ .docyard-tooltip-popover__link:hover .docyard-tooltip-popover__link-icon {
90
+ transform: translateX(2px);
91
+ }
92
+
93
+ .docyard-tooltip-popover.is-below::after {
94
+ top: -6px;
95
+ bottom: auto;
96
+ border-bottom: none;
97
+ border-right: none;
98
+ border-top: 1px solid var(--border);
99
+ border-left: 1px solid var(--border);
100
+ }
101
+
102
+ @media (max-width: 640px) {
103
+ .docyard-tooltip-popover {
104
+ max-width: 260px;
105
+ padding: var(--spacing-2) var(--spacing-3);
106
+ }
107
+
108
+ .docyard-tooltip-popover__term,
109
+ .docyard-tooltip-popover__description,
110
+ .docyard-tooltip-popover__link {
111
+ font-size: var(--text-xs);
112
+ }
113
+ }
@@ -0,0 +1,41 @@
1
+ .docyard-video {
2
+ position: relative;
3
+ width: 100%;
4
+ margin: var(--spacing-6) 0;
5
+ border-radius: var(--radius-xl);
6
+ overflow: hidden;
7
+ background-color: var(--muted);
8
+ aspect-ratio: 16 / 9;
9
+ }
10
+
11
+ .docyard-video iframe {
12
+ position: absolute;
13
+ top: 0;
14
+ left: 0;
15
+ width: 100%;
16
+ height: 100%;
17
+ border: none;
18
+ }
19
+
20
+ .docyard-video[style*="height"] {
21
+ aspect-ratio: unset;
22
+ }
23
+
24
+ .docyard-callout__body .docyard-video {
25
+ margin: var(--spacing-4) 0;
26
+ }
27
+
28
+ .docyard-callout__body .docyard-video:first-child {
29
+ margin-top: 0;
30
+ }
31
+
32
+ .docyard-callout__body .docyard-video:last-child {
33
+ margin-bottom: 0;
34
+ }
35
+
36
+ @media (max-width: 640px) {
37
+ .docyard-video {
38
+ margin: var(--spacing-4) 0;
39
+ border-radius: var(--radius-lg);
40
+ }
41
+ }
@@ -145,14 +145,16 @@
145
145
  }
146
146
 
147
147
  .content img {
148
+ display: block;
148
149
  max-width: 100%;
149
150
  height: auto;
150
151
  border-radius: var(--radius-xl);
151
- margin: var(--spacing-4) 0;
152
+ margin: var(--spacing-4) auto;
152
153
  border: 1px solid var(--border);
154
+ cursor: zoom-in;
153
155
  }
154
156
 
155
- .content a:not(.heading-anchor):not(.pager-link):not(.breadcrumb-link):not(.site-footer__link):not(.site-footer__attribution) {
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) {
156
158
  color: var(--foreground);
157
159
  font-weight: var(--font-semibold);
158
160
  text-decoration: none;
@@ -160,7 +162,7 @@
160
162
  transition: border-bottom var(--transition-fast);
161
163
  }
162
164
 
163
- .content a:not(.heading-anchor):not(.pager-link):not(.breadcrumb-link):not(.site-footer__link):not(.site-footer__attribution):hover {
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 {
164
166
  border-bottom: 2px solid var(--primary);
165
167
  }
166
168
 
@@ -0,0 +1,85 @@
1
+ function initializeAbbreviations() {
2
+ const abbreviations = document.querySelectorAll('.docyard-abbr');
3
+ if (abbreviations.length === 0) return;
4
+
5
+ const popover = createPopover();
6
+ document.body.appendChild(popover);
7
+
8
+ let hideTimeout;
9
+
10
+ abbreviations.forEach(abbr => {
11
+ abbr.addEventListener('mouseenter', () => {
12
+ clearTimeout(hideTimeout);
13
+ showPopover(popover, abbr);
14
+ });
15
+
16
+ abbr.addEventListener('mouseleave', () => {
17
+ hideTimeout = setTimeout(() => {
18
+ hidePopover(popover);
19
+ }, 100);
20
+ });
21
+ });
22
+ }
23
+
24
+ function createPopover() {
25
+ const popover = document.createElement('div');
26
+ popover.className = 'docyard-abbr-popover';
27
+ popover.innerHTML = `
28
+ <span class="docyard-abbr-popover__term"></span>
29
+ <span class="docyard-abbr-popover__definition"></span>
30
+ `;
31
+ return popover;
32
+ }
33
+
34
+ function showPopover(popover, abbr) {
35
+ const term = abbr.textContent;
36
+ const definition = abbr.dataset.definition;
37
+
38
+ popover.querySelector('.docyard-abbr-popover__term').textContent = term;
39
+ popover.querySelector('.docyard-abbr-popover__definition').textContent = definition;
40
+
41
+ const rect = abbr.getBoundingClientRect();
42
+ const scrollX = window.scrollX;
43
+ const scrollY = window.scrollY;
44
+
45
+ popover.style.visibility = 'hidden';
46
+ popover.classList.add('is-visible');
47
+ popover.classList.remove('is-below');
48
+
49
+ requestAnimationFrame(() => {
50
+ const popoverRect = popover.getBoundingClientRect();
51
+ let left = rect.left + scrollX + (rect.width / 2) - (popoverRect.width / 2);
52
+ let top = rect.top + scrollY - popoverRect.height - 8;
53
+
54
+ const viewportWidth = window.innerWidth;
55
+ const padding = 16;
56
+
57
+ if (left < padding) {
58
+ left = padding;
59
+ } else if (left + popoverRect.width > viewportWidth - padding) {
60
+ left = viewportWidth - popoverRect.width - padding;
61
+ }
62
+
63
+ if (top < scrollY + padding) {
64
+ top = rect.bottom + scrollY + 8;
65
+ popover.classList.add('is-below');
66
+ }
67
+
68
+ const arrowLeft = rect.left + scrollX + (rect.width / 2) - left;
69
+ popover.style.setProperty('--arrow-left', `${Math.max(12, Math.min(arrowLeft, popoverRect.width - 12))}px`);
70
+
71
+ popover.style.left = `${left}px`;
72
+ popover.style.top = `${top}px`;
73
+ popover.style.visibility = 'visible';
74
+ });
75
+ }
76
+
77
+ function hidePopover(popover) {
78
+ popover.classList.remove('is-visible');
79
+ }
80
+
81
+ if (document.readyState === 'loading') {
82
+ document.addEventListener('DOMContentLoaded', initializeAbbreviations);
83
+ } else {
84
+ initializeAbbreviations();
85
+ }
@@ -0,0 +1,81 @@
1
+ (function () {
2
+ var STORAGE_KEY = 'docyard-announcement-dismissed';
3
+
4
+ function initAnnouncement() {
5
+ var banner = document.querySelector('.docyard-announcement');
6
+ if (!banner) return;
7
+
8
+ var isDismissible = banner.dataset.dismissible === 'true';
9
+
10
+ if (isDismissible && isDismissed()) {
11
+ banner.style.display = 'none';
12
+ document.body.classList.remove('has-announcement');
13
+ return;
14
+ }
15
+
16
+ if (isDismissible) {
17
+ var dismissButton = banner.querySelector('.docyard-announcement__dismiss');
18
+ if (dismissButton) {
19
+ dismissButton.addEventListener('click', function () {
20
+ dismissAnnouncement(banner);
21
+ });
22
+ }
23
+ }
24
+
25
+ var actionLink = banner.querySelector('.docyard-announcement__link');
26
+ var actionButton = banner.querySelector('.docyard-announcement__button');
27
+
28
+ if (actionLink) {
29
+ actionLink.addEventListener('click', function () {
30
+ saveDismissed();
31
+ });
32
+ }
33
+
34
+ if (actionButton) {
35
+ actionButton.addEventListener('click', function () {
36
+ saveDismissed();
37
+ });
38
+ }
39
+ }
40
+
41
+ function saveDismissed() {
42
+ try {
43
+ localStorage.setItem(STORAGE_KEY, Date.now().toString());
44
+ } catch (e) {
45
+ }
46
+ }
47
+
48
+ function isDismissed() {
49
+ try {
50
+ var dismissed = localStorage.getItem(STORAGE_KEY);
51
+ if (!dismissed) return false;
52
+
53
+ var dismissedAt = parseInt(dismissed, 10);
54
+ var sevenDaysAgo = Date.now() - (7 * 24 * 60 * 60 * 1000);
55
+
56
+ return dismissedAt > sevenDaysAgo;
57
+ } catch (e) {
58
+ return false;
59
+ }
60
+ }
61
+
62
+ function dismissAnnouncement(banner) {
63
+ banner.classList.add('is-dismissed');
64
+
65
+ try {
66
+ localStorage.setItem(STORAGE_KEY, Date.now().toString());
67
+ } catch (e) {
68
+ }
69
+
70
+ banner.addEventListener('animationend', function () {
71
+ banner.style.display = 'none';
72
+ document.body.classList.remove('has-announcement');
73
+ });
74
+ }
75
+
76
+ if (document.readyState === 'loading') {
77
+ document.addEventListener('DOMContentLoaded', initAnnouncement);
78
+ } else {
79
+ initAnnouncement();
80
+ }
81
+ })();