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
@@ -0,0 +1,283 @@
1
+ class CodeGroupManager {
2
+ constructor() {
3
+ this.groups = [];
4
+ this.init();
5
+ }
6
+
7
+ init() {
8
+ const containers = document.querySelectorAll('.docyard-code-group');
9
+ if (containers.length === 0) return;
10
+
11
+ containers.forEach(container => {
12
+ this.groups.push(new CodeGroup(container, this));
13
+ });
14
+
15
+ this.loadPreference();
16
+ }
17
+
18
+ syncTabs(label) {
19
+ this.groups.forEach(group => {
20
+ group.activateTabByLabel(label, true);
21
+ });
22
+ this.savePreference(label);
23
+ }
24
+
25
+ loadPreference() {
26
+ try {
27
+ const preferredTab = localStorage.getItem('docyard-code-group-tab');
28
+ if (!preferredTab) return;
29
+
30
+ this.groups.forEach(group => {
31
+ group.activateTabByLabel(preferredTab, false);
32
+ });
33
+ } catch (error) {
34
+ // localStorage not available
35
+ }
36
+ }
37
+
38
+ savePreference(label) {
39
+ try {
40
+ localStorage.setItem('docyard-code-group-tab', label.toLowerCase());
41
+ } catch (error) {
42
+ // localStorage not available
43
+ }
44
+ }
45
+ }
46
+
47
+ class CodeGroup {
48
+ constructor(container, manager) {
49
+ this.container = container;
50
+ this.manager = manager;
51
+ this.scrollContainer = container.querySelector('.docyard-code-group__tabs-scroll-container');
52
+ this.tabList = container.querySelector('[role="tablist"]');
53
+ this.tabs = Array.from(container.querySelectorAll('[role="tab"]'));
54
+ this.panels = Array.from(container.querySelectorAll('[role="tabpanel"]'));
55
+ this.indicator = container.querySelector('.docyard-code-group__indicator');
56
+ this.copyButton = container.querySelector('.docyard-code-group__copy');
57
+ this.activeIndex = 0;
58
+
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
+
61
+ this.attachEventListeners();
62
+ this.updateIndicator();
63
+
64
+ requestAnimationFrame(() => {
65
+ this.updateScrollIndicators();
66
+ });
67
+ }
68
+
69
+ attachEventListeners() {
70
+ this.tabs.forEach((tab, index) => {
71
+ tab.addEventListener('click', () => this.handleTabClick(index));
72
+ });
73
+
74
+ this.tabList.addEventListener('keydown', (e) => this.handleKeyDown(e));
75
+ this.tabList.addEventListener('scroll', () => this.handleScroll());
76
+ window.addEventListener('resize', () => this.handleResize());
77
+
78
+ if (this.copyButton) {
79
+ this.copyButton.addEventListener('click', () => this.handleCopy());
80
+ }
81
+ }
82
+
83
+ handleScroll() {
84
+ if (this.scrollTimeout) {
85
+ cancelAnimationFrame(this.scrollTimeout);
86
+ }
87
+
88
+ this.scrollTimeout = requestAnimationFrame(() => {
89
+ this.updateScrollIndicators();
90
+ });
91
+ }
92
+
93
+ handleTabClick(index) {
94
+ if (index === this.activeIndex) return;
95
+
96
+ const label = this.tabs[index].dataset.label;
97
+ this.manager.syncTabs(label);
98
+ }
99
+
100
+ handleKeyDown(event) {
101
+ const { key } = event;
102
+
103
+ if (key === 'ArrowLeft' || key === 'ArrowRight') {
104
+ event.preventDefault();
105
+
106
+ if (key === 'ArrowLeft') {
107
+ this.activatePreviousTab();
108
+ } else {
109
+ this.activateNextTab();
110
+ }
111
+
112
+ this.tabs[this.activeIndex].focus();
113
+ const label = this.tabs[this.activeIndex].dataset.label;
114
+ this.manager.syncTabs(label);
115
+ }
116
+
117
+ if (key === 'Home') {
118
+ event.preventDefault();
119
+ this.activateTab(0, true);
120
+ this.tabs[0].focus();
121
+ const label = this.tabs[0].dataset.label;
122
+ this.manager.syncTabs(label);
123
+ }
124
+
125
+ if (key === 'End') {
126
+ event.preventDefault();
127
+ const lastIndex = this.tabs.length - 1;
128
+ this.activateTab(lastIndex, true);
129
+ this.tabs[lastIndex].focus();
130
+ const label = this.tabs[lastIndex].dataset.label;
131
+ this.manager.syncTabs(label);
132
+ }
133
+ }
134
+
135
+ handleResize() {
136
+ if (this.resizeTimeout) {
137
+ cancelAnimationFrame(this.resizeTimeout);
138
+ }
139
+
140
+ this.resizeTimeout = requestAnimationFrame(() => {
141
+ this.updateIndicator(false);
142
+ this.updateScrollIndicators();
143
+ });
144
+ }
145
+
146
+ activateTab(index, animate = true) {
147
+ if (index < 0 || index >= this.tabs.length) return;
148
+
149
+ this.activeIndex = index;
150
+
151
+ this.tabs.forEach((tab, i) => {
152
+ const isActive = i === index;
153
+ tab.setAttribute('aria-selected', isActive ? 'true' : 'false');
154
+ tab.setAttribute('tabindex', isActive ? '0' : '-1');
155
+ });
156
+
157
+ this.panels.forEach((panel, i) => {
158
+ const isActive = i === index;
159
+ panel.setAttribute('aria-hidden', isActive ? 'false' : 'true');
160
+ });
161
+
162
+ this.updateIndicator(animate);
163
+ }
164
+
165
+ activateTabByLabel(label, animate = true) {
166
+ const index = this.tabs.findIndex(tab =>
167
+ tab.dataset.label.toLowerCase() === label.toLowerCase()
168
+ );
169
+
170
+ if (index !== -1 && index !== this.activeIndex) {
171
+ this.activateTab(index, animate);
172
+ }
173
+ }
174
+
175
+ activateNextTab() {
176
+ const nextIndex = (this.activeIndex + 1) % this.tabs.length;
177
+ this.activateTab(nextIndex, true);
178
+ }
179
+
180
+ activatePreviousTab() {
181
+ const prevIndex = (this.activeIndex - 1 + this.tabs.length) % this.tabs.length;
182
+ this.activateTab(prevIndex, true);
183
+ }
184
+
185
+ updateIndicator(animate = true) {
186
+ if (!this.indicator || !this.tabs[this.activeIndex]) return;
187
+
188
+ const activeTab = this.tabs[this.activeIndex];
189
+ const tabListRect = this.tabList.getBoundingClientRect();
190
+ const activeTabRect = activeTab.getBoundingClientRect();
191
+
192
+ const left = activeTabRect.left - tabListRect.left + this.tabList.scrollLeft;
193
+ const width = activeTabRect.width;
194
+
195
+ this.indicator.style.width = `${width}px`;
196
+ this.indicator.style.transform = `translateX(${left}px)`;
197
+
198
+ if (!animate) {
199
+ this.indicator.style.transition = 'none';
200
+ void this.indicator.offsetWidth;
201
+ this.indicator.style.transition = '';
202
+ }
203
+ }
204
+
205
+ updateScrollIndicators() {
206
+ if (!this.tabList || !this.scrollContainer) return;
207
+
208
+ const { scrollLeft, scrollWidth, clientWidth } = this.tabList;
209
+ const hasOverflow = scrollWidth > clientWidth;
210
+
211
+ if (!hasOverflow) {
212
+ this.scrollContainer.classList.remove('can-scroll-left', 'can-scroll-right');
213
+ return;
214
+ }
215
+
216
+ const canScrollLeft = scrollLeft > 5;
217
+ this.scrollContainer.classList.toggle('can-scroll-left', canScrollLeft);
218
+
219
+ const canScrollRight = scrollLeft < scrollWidth - clientWidth - 5;
220
+ this.scrollContainer.classList.toggle('can-scroll-right', canScrollRight);
221
+ }
222
+
223
+ async handleCopy() {
224
+ const activePanel = this.panels[this.activeIndex];
225
+ if (!activePanel) return;
226
+
227
+ const codeText = activePanel.dataset.code || '';
228
+
229
+ try {
230
+ await this.copyToClipboard(codeText);
231
+ this.showCopySuccess();
232
+ } catch (error) {
233
+ console.warn('Failed to copy code:', error);
234
+ }
235
+ }
236
+
237
+ async copyToClipboard(text) {
238
+ if (navigator.clipboard && window.isSecureContext) {
239
+ await navigator.clipboard.writeText(text);
240
+ } else {
241
+ const textArea = document.createElement('textarea');
242
+ textArea.value = text;
243
+ textArea.style.position = 'fixed';
244
+ textArea.style.left = '-999999px';
245
+ document.body.appendChild(textArea);
246
+ textArea.select();
247
+ document.execCommand('copy');
248
+ document.body.removeChild(textArea);
249
+ }
250
+ }
251
+
252
+ showCopySuccess() {
253
+ if (!this.copyButton) return;
254
+
255
+ const iconEl = this.copyButton.querySelector('.docyard-code-group__copy-icon');
256
+ const textEl = this.copyButton.querySelector('.docyard-code-group__copy-text');
257
+
258
+ if (!iconEl || !textEl) return;
259
+
260
+ const originalIcon = iconEl.innerHTML;
261
+ const originalText = textEl.textContent;
262
+
263
+ iconEl.innerHTML = this.checkIcon;
264
+ textEl.textContent = 'Copied';
265
+ this.copyButton.classList.add('is-success');
266
+
267
+ setTimeout(() => {
268
+ iconEl.innerHTML = originalIcon;
269
+ textEl.textContent = originalText;
270
+ this.copyButton.classList.remove('is-success');
271
+ }, 2000);
272
+ }
273
+ }
274
+
275
+ function initializeCodeGroups() {
276
+ new CodeGroupManager();
277
+ }
278
+
279
+ if (document.readyState === 'loading') {
280
+ document.addEventListener('DOMContentLoaded', initializeCodeGroups);
281
+ } else {
282
+ initializeCodeGroups();
283
+ }
@@ -0,0 +1,39 @@
1
+ function initializeFileTrees() {
2
+ const fileTrees = document.querySelectorAll('.docyard-filetree');
3
+
4
+ fileTrees.forEach(tree => {
5
+ const folders = tree.querySelectorAll('.docyard-filetree__item--folder');
6
+
7
+ folders.forEach(folder => {
8
+ const entry = folder.querySelector(':scope > .docyard-filetree__entry');
9
+ const childList = folder.querySelector(':scope > .docyard-filetree__list');
10
+
11
+ if (!entry || !childList || childList.children.length === 0) return;
12
+
13
+ folder.classList.add('docyard-filetree__item--has-children');
14
+
15
+ entry.addEventListener('click', () => {
16
+ const isCollapsed = folder.classList.contains('docyard-filetree__item--collapsed');
17
+
18
+ folder.classList.toggle('docyard-filetree__item--collapsed');
19
+
20
+ const icon = entry.querySelector('.docyard-icon');
21
+ if (icon) {
22
+ if (isCollapsed) {
23
+ icon.classList.remove('docyard-icon-folder');
24
+ icon.classList.add('docyard-icon-folder-open');
25
+ } else {
26
+ icon.classList.remove('docyard-icon-folder-open');
27
+ icon.classList.add('docyard-icon-folder');
28
+ }
29
+ }
30
+ });
31
+ });
32
+ });
33
+ }
34
+
35
+ if (document.readyState === 'loading') {
36
+ document.addEventListener('DOMContentLoaded', initializeFileTrees);
37
+ } else {
38
+ initializeFileTrees();
39
+ }
@@ -0,0 +1,72 @@
1
+ (function() {
2
+ 'use strict';
3
+
4
+ let lightbox = null;
5
+ let lightboxImg = null;
6
+
7
+ function createLightbox() {
8
+ if (lightbox) return;
9
+
10
+ lightbox = document.createElement('div');
11
+ lightbox.className = 'docyard-lightbox';
12
+ lightbox.innerHTML = `
13
+ <button class="docyard-lightbox-close" aria-label="Close">
14
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256" fill="currentColor">
15
+ <path d="M205.66,194.34a8,8,0,0,1-11.32,11.32L128,139.31,61.66,205.66a8,8,0,0,1-11.32-11.32L116.69,128,50.34,61.66A8,8,0,0,1,61.66,50.34L128,116.69l66.34-66.35a8,8,0,0,1,11.32,11.32L139.31,128Z"/>
16
+ </svg>
17
+ </button>
18
+ <img src="" alt="">
19
+ `;
20
+
21
+ document.body.appendChild(lightbox);
22
+ lightboxImg = lightbox.querySelector('img');
23
+
24
+ lightbox.addEventListener('click', closeLightbox);
25
+ lightbox.querySelector('.docyard-lightbox-close').addEventListener('click', closeLightbox);
26
+
27
+ document.addEventListener('keydown', function(e) {
28
+ if (e.key === 'Escape' && lightbox.classList.contains('active')) {
29
+ closeLightbox();
30
+ }
31
+ });
32
+ }
33
+
34
+ function openLightbox(src, alt) {
35
+ createLightbox();
36
+ lightboxImg.src = src;
37
+ lightboxImg.alt = alt || '';
38
+ requestAnimationFrame(function() {
39
+ lightbox.classList.add('active');
40
+ document.body.style.overflow = 'hidden';
41
+ });
42
+ }
43
+
44
+ function closeLightbox(e) {
45
+ if (e && e.target === lightboxImg) return;
46
+ if (lightbox) {
47
+ lightbox.classList.remove('active');
48
+ document.body.style.overflow = '';
49
+ }
50
+ }
51
+
52
+ function initLightbox() {
53
+ var contentImages = document.querySelectorAll('.content img');
54
+
55
+ contentImages.forEach(function(img) {
56
+ if (img.hasAttribute('data-no-zoom')) {
57
+ img.style.cursor = 'default';
58
+ return;
59
+ }
60
+
61
+ img.addEventListener('click', function() {
62
+ openLightbox(this.src, this.alt);
63
+ });
64
+ });
65
+ }
66
+
67
+ if (document.readyState === 'loading') {
68
+ document.addEventListener('DOMContentLoaded', initLightbox);
69
+ } else {
70
+ initLightbox();
71
+ }
72
+ })();
@@ -0,0 +1,118 @@
1
+ function initializeTooltips() {
2
+ const tooltips = document.querySelectorAll('.docyard-tooltip');
3
+ if (tooltips.length === 0) return;
4
+
5
+ const popover = createTooltipPopover();
6
+ document.body.appendChild(popover);
7
+
8
+ let hideTimeout;
9
+ let isHoveringPopover = false;
10
+
11
+ popover.addEventListener('mouseenter', () => {
12
+ isHoveringPopover = true;
13
+ clearTimeout(hideTimeout);
14
+ });
15
+
16
+ popover.addEventListener('mouseleave', () => {
17
+ isHoveringPopover = false;
18
+ hideTimeout = setTimeout(() => {
19
+ hideTooltipPopover(popover);
20
+ }, 100);
21
+ });
22
+
23
+ tooltips.forEach(tooltip => {
24
+ tooltip.addEventListener('mouseenter', () => {
25
+ clearTimeout(hideTimeout);
26
+ showTooltipPopover(popover, tooltip);
27
+ });
28
+
29
+ tooltip.addEventListener('mouseleave', () => {
30
+ hideTimeout = setTimeout(() => {
31
+ if (!isHoveringPopover) {
32
+ hideTooltipPopover(popover);
33
+ }
34
+ }, 100);
35
+ });
36
+ });
37
+ }
38
+
39
+ function createTooltipPopover() {
40
+ const popover = document.createElement('div');
41
+ popover.className = 'docyard-tooltip-popover';
42
+ popover.innerHTML = `
43
+ <span class="docyard-tooltip-popover__term"></span>
44
+ <span class="docyard-tooltip-popover__description"></span>
45
+ <a class="docyard-tooltip-popover__link" style="display: none;">
46
+ <span class="docyard-tooltip-popover__link-text"></span>
47
+ <svg class="docyard-tooltip-popover__link-icon" viewBox="0 0 256 256" fill="currentColor">
48
+ <path d="M221.66,133.66l-72,72a8,8,0,0,1-11.32-11.32L196.69,136H40a8,8,0,0,1,0-16H196.69l-58.35-58.34a8,8,0,0,1,11.32-11.32l72,72A8,8,0,0,1,221.66,133.66Z"></path>
49
+ </svg>
50
+ </a>
51
+ `;
52
+ return popover;
53
+ }
54
+
55
+ function showTooltipPopover(popover, tooltip) {
56
+ const term = tooltip.textContent;
57
+ const description = tooltip.dataset.description;
58
+ const link = tooltip.dataset.link;
59
+ const linkText = tooltip.dataset.linkText;
60
+
61
+ popover.querySelector('.docyard-tooltip-popover__term').textContent = term;
62
+ popover.querySelector('.docyard-tooltip-popover__description').textContent = description;
63
+
64
+ const linkEl = popover.querySelector('.docyard-tooltip-popover__link');
65
+ if (link) {
66
+ linkEl.href = link;
67
+ linkEl.querySelector('.docyard-tooltip-popover__link-text').textContent = linkText;
68
+ linkEl.style.display = 'inline-flex';
69
+ } else {
70
+ linkEl.style.display = 'none';
71
+ }
72
+
73
+ const rect = tooltip.getBoundingClientRect();
74
+ const scrollX = window.scrollX;
75
+ const scrollY = window.scrollY;
76
+
77
+ popover.style.visibility = 'hidden';
78
+ popover.classList.add('is-visible');
79
+
80
+ requestAnimationFrame(() => {
81
+ const popoverRect = popover.getBoundingClientRect();
82
+ let left = rect.left + scrollX + (rect.width / 2) - (popoverRect.width / 2);
83
+ let top = rect.top + scrollY - popoverRect.height - 8;
84
+
85
+ const viewportWidth = window.innerWidth;
86
+ const padding = 16;
87
+
88
+ if (left < padding) {
89
+ left = padding;
90
+ } else if (left + popoverRect.width > viewportWidth - padding) {
91
+ left = viewportWidth - popoverRect.width - padding;
92
+ }
93
+
94
+ if (top < scrollY + padding) {
95
+ top = rect.bottom + scrollY + 8;
96
+ popover.classList.add('is-below');
97
+ } else {
98
+ popover.classList.remove('is-below');
99
+ }
100
+
101
+ const arrowLeft = rect.left + scrollX + (rect.width / 2) - left;
102
+ popover.style.setProperty('--arrow-left', `${Math.max(12, Math.min(arrowLeft, popoverRect.width - 12))}px`);
103
+
104
+ popover.style.left = `${left}px`;
105
+ popover.style.top = `${top}px`;
106
+ popover.style.visibility = 'visible';
107
+ });
108
+ }
109
+
110
+ function hideTooltipPopover(popover) {
111
+ popover.classList.remove('is-visible');
112
+ }
113
+
114
+ if (document.readyState === 'loading') {
115
+ document.addEventListener('DOMContentLoaded', initializeTooltips);
116
+ } else {
117
+ initializeTooltips();
118
+ }
@@ -4,6 +4,7 @@
4
4
  <%= render_partial('_head') %>
5
5
  </head>
6
6
  <body<%= ' class="has-tabs"' if @has_tabs %>>
7
+ <%= render_partial('_banner') %>
7
8
  <a href="#main-content" class="skip-link">Skip to main content</a>
8
9
 
9
10
  <%= render_partial('_header') %>
@@ -4,6 +4,7 @@
4
4
  <%= render_partial('_head') %>
5
5
  </head>
6
6
  <body class="splash-page<%= ' has-sidebar' if @show_sidebar %><%= ' has-tabs' if @has_tabs %>">
7
+ <%= render_partial('_banner') %>
7
8
  <a href="#main-content" class="skip-link">Skip to main content</a>
8
9
 
9
10
  <%= render_partial('_header') %>
@@ -0,0 +1,9 @@
1
+ <details class="docyard-accordion"<%= ' open' if @open %>>
2
+ <summary class="docyard-accordion__summary">
3
+ <span class="docyard-accordion__icon" aria-hidden="true"><%= @icon_svg %></span>
4
+ <span class="docyard-accordion__title"><%= @title %></span>
5
+ </summary>
6
+ <div class="docyard-accordion__content">
7
+ <%= @content_html %>
8
+ </div>
9
+ </details>
@@ -0,0 +1,27 @@
1
+ <% if @announcement %>
2
+ <div class="docyard-announcement" data-dismissible="<%= @announcement[:dismissible] %>"<%= @announcement[:button] ? ' data-has-button="true"' : '' %>>
3
+ <div class="docyard-announcement__content">
4
+ <% if @announcement[:link] %>
5
+ <a href="<%= @announcement[:link] %>" class="docyard-announcement__link">
6
+ <span class="docyard-announcement__text"><%= @announcement[:text] %></span>
7
+ <%= icon("arrow-right") %>
8
+ </a>
9
+ <% else %>
10
+ <span class="docyard-announcement__text"><%= @announcement[:text] %></span>
11
+ <% end %>
12
+
13
+ <% if @announcement[:button] %>
14
+ <a href="<%= @announcement[:button][:link] %>" class="docyard-announcement__button">
15
+ <%= @announcement[:button][:text] %>
16
+ </a>
17
+ <% end %>
18
+ </div>
19
+
20
+ <% if @announcement[:dismissible] %>
21
+ <button class="docyard-announcement__dismiss" aria-label="Dismiss announcement">
22
+ <%= icon("x") %>
23
+ </button>
24
+ <% end %>
25
+ </div>
26
+ <script>document.body.classList.add('has-announcement');</script>
27
+ <% end %>
@@ -0,0 +1,23 @@
1
+ <% if @href %>
2
+ <a href="<%= @href %>" class="docyard-card">
3
+ <% else %>
4
+ <div class="docyard-card">
5
+ <% end %>
6
+ <% if @icon_svg %>
7
+ <div class="docyard-card__icon">
8
+ <%= @icon_svg %>
9
+ </div>
10
+ <% end %>
11
+ <div class="docyard-card__content">
12
+ <h3 class="docyard-card__title"><%= @title %></h3>
13
+ <% unless @content_html.empty? %>
14
+ <div class="docyard-card__body">
15
+ <%= @content_html %>
16
+ </div>
17
+ <% end %>
18
+ </div>
19
+ <% if @href %>
20
+ </a>
21
+ <% else %>
22
+ </div>
23
+ <% end %>
@@ -7,6 +7,9 @@
7
7
  <span class="nav-item-icon"><%= icon(@icon) %></span>
8
8
  <% end %>
9
9
  <span class="nav-item-text"><%= @title %></span>
10
+ <% if @badge %>
11
+ <span class="docyard-badge docyard-badge--<%= @badge_type || 'default' %>"><%= @badge %></span>
12
+ <% end %>
10
13
  </span>
11
14
  <span class="nav-group-icon"><%= icon(:caret_right) %></span>
12
15
  </a>
@@ -17,6 +20,9 @@
17
20
  <span class="nav-item-icon"><%= icon(@icon) %></span>
18
21
  <% end %>
19
22
  <span class="nav-item-text"><%= @title %></span>
23
+ <% if @badge %>
24
+ <span class="docyard-badge docyard-badge--<%= @badge_type || 'default' %>"><%= @badge %></span>
25
+ <% end %>
20
26
  </span>
21
27
  <span class="nav-group-icon"><%= icon(:caret_right) %></span>
22
28
  </button>
@@ -3,6 +3,9 @@
3
3
  <span class="nav-item-icon"><%= icon(@icon) %></span>
4
4
  <% end %>
5
5
  <span class="nav-item-text"><%= @title %></span>
6
+ <% if @badge %>
7
+ <span class="docyard-badge docyard-badge--<%= @badge_type || 'default' %>"><%= @badge %></span>
8
+ <% end %>
6
9
  <% if @target == "_blank" %>
7
10
  <span class="nav-item-external"><%= icon(:link_external) %></span>
8
11
  <% end %>
@@ -0,0 +1,14 @@
1
+ <div class="docyard-step<%= ' docyard-step--last' if @is_last %>">
2
+ <div class="docyard-step__indicator">
3
+ <span class="docyard-step__number"><%= @number %></span>
4
+ <% unless @is_last %><div class="docyard-step__connector"></div><% end %>
5
+ </div>
6
+ <div class="docyard-step__content">
7
+ <h3 class="docyard-step__title"><%= @title %></h3>
8
+ <% unless @content_html.empty? %>
9
+ <div class="docyard-step__body">
10
+ <%= @content_html %>
11
+ </div>
12
+ <% end %>
13
+ </div>
14
+ </div>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Docyard
4
- VERSION = "0.8.0"
4
+ VERSION = "0.9.0"
5
5
  end