Skip to content

Commit 9747283

Browse files
committed
Improve documentation layout
1 parent 27b477c commit 9747283

File tree

6 files changed

+258
-75
lines changed

6 files changed

+258
-75
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ build
33
.idea
44
docs/_site
55
docs/.jekyll-cache
6+
docs/.jekyll-metadata
67
docs/tailwindcss
78
.phpunit.cache
89
composer.lock

docs/_data/manifest.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
2-
"docs.css": "/styles.0005.css",
3-
"docs.js": "/scripts.0002.js"
2+
"docs.css": "/styles.0006.css",
3+
"docs.js": "/scripts.0004.js"
44
}

docs/input.css

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,3 +541,36 @@ img {
541541
display: none !important;
542542
}
543543
}
544+
545+
546+
#onthispage {
547+
@apply sticky top-[4.5rem] h-[calc(100vh-4.5rem)] w-72 overflow-y-auto pr-8 text-sm xl:pr-16 self-start hidden lg:block;
548+
}
549+
550+
#onthispage nav h3 {
551+
@apply font-semibold tracking-tight text-slate-900
552+
}
553+
554+
#onthispage ul {
555+
@apply pl-3 mt-3 space-y-2
556+
}
557+
558+
#onthispage a {
559+
display:block;
560+
border-left: 2px solid transparent;
561+
padding-left: 0.5rem;
562+
text-decoration: none;
563+
}
564+
565+
#onthispage a:hover {
566+
text-decoration: underline;
567+
}
568+
569+
#onthispage .active {
570+
color: #b78e1d; /* Tailwind blue-600 */
571+
border-left-color: #b78e1d;
572+
}
573+
574+
html {
575+
scroll-behavior: smooth;
576+
}

docs/scripts.0002.js

Lines changed: 0 additions & 51 deletions
This file was deleted.

docs/scripts.0004.js

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
(() => {
2+
let contentHeaders= document.querySelectorAll("main h2[id]");
3+
if (!document.querySelector('html').classList.contains('homepage') && contentHeaders) {
4+
const sections = document.querySelector('article.content').querySelectorAll('h2, h3, h4, h5, h6');
5+
const headings = [...sections];
6+
if (headings.length > 0) {
7+
// on page aside generation
8+
const aside = document.createElement('aside');
9+
aside.setAttribute('id', 'onthispage');
10+
const tocParent = document.createElement('nav');
11+
const tocParentTitle = document.createElement('h3');
12+
tocParentTitle.textContent = 'On This Page';
13+
const toc = document.createElement('ul');
14+
let currentLevel = 1;
15+
let currentList = toc;
16+
headings.forEach(h => {
17+
const level = parseInt(h.tagName.slice(1), 10);
18+
19+
// Going deeper
20+
while (level > currentLevel) {
21+
const newList = document.createElement('ul');
22+
23+
// If there is no lastElementChild, create a dummy parent <li>
24+
if (!currentList.lastElementChild) {
25+
const placeholder = document.createElement('li');
26+
currentList.appendChild(placeholder);
27+
}
28+
29+
currentList.lastElementChild.appendChild(newList);
30+
currentList = newList;
31+
currentLevel++;
32+
}
33+
34+
// Going shallower
35+
while (level < currentLevel) {
36+
currentList = currentList.parentElement.closest('ul');
37+
currentLevel--;
38+
}
39+
40+
// Add list item for current heading
41+
const li = document.createElement('li');
42+
const a = document.createElement('a');
43+
44+
if (!h.id) {
45+
h.id = h.textContent.trim().toLowerCase().replace(/\s+/g, '-');
46+
}
47+
48+
a.href = `#${h.id}`;
49+
a.textContent = h.textContent;
50+
li.appendChild(a);
51+
currentList.appendChild(li);
52+
});
53+
54+
tocParent.append(tocParentTitle, toc);
55+
aside.append(tocParent);
56+
document.querySelector('main').append(aside);
57+
}
58+
59+
const uri = new URL(location.href);
60+
// adding a pointer for headers
61+
contentHeaders.forEach((header) => {
62+
uri.hash = header.id;
63+
let link = document.createElement("a");
64+
link.classList.add("header-permalink");
65+
link.title = "Permalink";
66+
link.href = uri.toString();
67+
link.innerHTML = "&#182;";
68+
header.appendChild(link);
69+
});
70+
71+
const menuLinks = document.querySelectorAll('#onthispage a');
72+
const observer = new IntersectionObserver(entries => {
73+
entries.forEach(entry => {
74+
const id = entry.target.getAttribute("id");
75+
const link = document.querySelector(`#onthispage a[href="#${id}"]`);
76+
77+
if (entry.isIntersecting) {
78+
menuLinks.forEach(a => a.classList.remove("active"));
79+
link.classList.add("active");
80+
}
81+
});
82+
}, {
83+
rootMargin: "-50% 0px -50% 0px", // trigger when the section is centered in viewport
84+
threshold: 0
85+
});
86+
87+
sections.forEach(section => observer.observe(section));
88+
}
89+
90+
// generate code snippet copy/paste
91+
let codeSnippet = document.querySelectorAll('.content .language-php.highlighter-rouge');
92+
codeSnippet.forEach((snippet) => {
93+
let notification = document.createElement("div");
94+
notification.classList.add('copy-snippet-notification', 'hidden', 'rounded', 'p-2');
95+
snippet.appendChild(notification);
96+
97+
let link = document.createElement("span");
98+
link.classList.add("copy-snippet");
99+
link.innerHTML = "copy 📋";
100+
link.addEventListener('click', function (e) {
101+
let snippetParent = e.target.parentNode;
102+
let notification = snippetParent.querySelector('.copy-snippet-notification');
103+
let content = snippetParent.querySelector('pre').textContent;
104+
try {
105+
navigator.clipboard.writeText(content);
106+
notification.innerHTML = 'Copied!';
107+
notification.classList.add('bg-black');
108+
notification.classList.remove('hidden');
109+
setTimeout(() => {
110+
notification.classList.add('hidden');
111+
notification.classList.remove('bg-black');
112+
}, 500);
113+
} catch (err) {
114+
console.error('Failed to copy: ', err);
115+
notification.innerHTML = 'Copy failed!';
116+
notification.classList.add('bg-red-800');
117+
notification.classList.remove('hidden');
118+
setTimeout(() => {
119+
notification.classList.add('hidden');
120+
notification.classList.remove('bg-red-800');
121+
}, 500);
122+
}
123+
}, false);
124+
snippet.appendChild(link);
125+
});
126+
127+
//package menu dropdown
128+
const dropDownList = document.getElementById('packageDropdownList');
129+
const dropDownButton = document.getElementById('packageDropdown');
130+
131+
dropDownButton.addEventListener('click', () => {
132+
dropDownList.classList.toggle('hidden');
133+
});
134+
135+
document.addEventListener('click', (event) => {
136+
if (!dropDownButton.contains(event.target) && !dropDownList.contains(event.target)) {
137+
dropDownList.classList.add('hidden');
138+
}
139+
});
140+
})();
141+
142+
Lines changed: 80 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -679,10 +679,18 @@ video {
679679
margin-bottom: 1rem;
680680
}
681681

682+
.mb-6 {
683+
margin-bottom: 1.5rem;
684+
}
685+
682686
.ml-4 {
683687
margin-left: 1rem;
684688
}
685689

690+
.mt-12 {
691+
margin-top: 3rem;
692+
}
693+
686694
.mt-3 {
687695
margin-top: 0.75rem;
688696
}
@@ -691,18 +699,6 @@ video {
691699
margin-top: 1.5rem;
692700
}
693701

694-
.mb-6 {
695-
margin-bottom: 1.5rem;
696-
}
697-
698-
.mt-16 {
699-
margin-top: 4rem;
700-
}
701-
702-
.mt-12 {
703-
margin-top: 3rem;
704-
}
705-
706702
.block {
707703
display: block;
708704
}
@@ -1139,11 +1135,6 @@ video {
11391135
color: rgb(0 0 0 / var(--tw-text-opacity));
11401136
}
11411137

1142-
.text-csv-base {
1143-
--tw-text-opacity: 1;
1144-
color: rgb(56 193 99 / var(--tw-text-opacity));
1145-
}
1146-
11471138
.text-dark {
11481139
--tw-text-opacity: 1;
11491140
color: rgb(44 44 44 / var(--tw-text-opacity));
@@ -1159,6 +1150,11 @@ video {
11591150
color: rgb(255 198 29 / var(--tw-text-opacity));
11601151
}
11611152

1153+
.text-period-dark {
1154+
--tw-text-opacity: 1;
1155+
color: rgb(178 139 20 / var(--tw-text-opacity));
1156+
}
1157+
11621158
.text-slate-600 {
11631159
--tw-text-opacity: 1;
11641160
color: rgb(71 85 105 / var(--tw-text-opacity));
@@ -1174,11 +1170,6 @@ video {
11741170
color: rgb(255 255 255 / var(--tw-text-opacity));
11751171
}
11761172

1177-
.text-period-dark {
1178-
--tw-text-opacity: 1;
1179-
color: rgb(178 139 20 / var(--tw-text-opacity));
1180-
}
1181-
11821173
.underline {
11831174
text-decoration-line: underline;
11841175
}
@@ -1882,6 +1873,73 @@ img {
18821873
}
18831874
}
18841875

1876+
#onthispage {
1877+
position: sticky;
1878+
top: 4.5rem;
1879+
display: none;
1880+
height: calc(100vh - 4.5rem);
1881+
width: 18rem;
1882+
align-self: flex-start;
1883+
overflow-y: auto;
1884+
padding-right: 2rem;
1885+
font-size: 0.875rem;
1886+
line-height: 1.25rem;
1887+
}
1888+
1889+
@media (min-width: 1024px) {
1890+
#onthispage {
1891+
display: block;
1892+
}
1893+
}
1894+
1895+
@media (min-width: 1280px) {
1896+
#onthispage {
1897+
padding-right: 4rem;
1898+
}
1899+
}
1900+
1901+
#onthispage nav h3 {
1902+
font-weight: 600;
1903+
letter-spacing: -0.025em;
1904+
--tw-text-opacity: 1;
1905+
color: rgb(15 23 42 / var(--tw-text-opacity));
1906+
}
1907+
1908+
#onthispage ul {
1909+
margin-top: 0.75rem;
1910+
}
1911+
1912+
#onthispage ul > :not([hidden]) ~ :not([hidden]) {
1913+
--tw-space-y-reverse: 0;
1914+
margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
1915+
margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
1916+
}
1917+
1918+
#onthispage ul {
1919+
padding-left: 0.75rem;
1920+
}
1921+
1922+
#onthispage a {
1923+
display:block;
1924+
border-left: 2px solid transparent;
1925+
padding-left: 0.5rem;
1926+
text-decoration: none;
1927+
}
1928+
1929+
#onthispage a:hover {
1930+
text-decoration: underline;
1931+
}
1932+
1933+
#onthispage .active {
1934+
color: #b78e1d;
1935+
/* Tailwind blue-600 */
1936+
border-left-color: #b78e1d;
1937+
}
1938+
1939+
html {
1940+
scroll-behavior: smooth;
1941+
}
1942+
18851943
.hover\:bg-period-base:hover {
18861944
--tw-bg-opacity: 1;
18871945
background-color: rgb(255 198 29 / var(--tw-bg-opacity));

0 commit comments

Comments
 (0)