mirror of
https://github.com/qdrant/landing_page.git
synced 2026-10-01 17:08:30 +02:00
Created Dev-portal pages (#1219)
* Created Dev-portal pages * changed structure of documents for dev-portal section, renamed dev-portal to docs, related template changes * keeping learn section for future usage * update dev-portal and documents * added feedback and breadcrumbs components * used the docs-side menu partial on documentation pages, and added active state to the docs-header links * search console on docs * small fixes * assigned partitions, css fix * fix links on the core page * update links for cloud * update links for build * Reference -> API Reference * [WIP] Dev portal light theme (#1250) * light theme - docs side menu * background fix * wip: updating layout * layout update * light theme * card titles with a link * upd page-search package * simplified header * fixes * TOC scroll spy (#1259) * scroll spy on table of contents * packages versions fix * custom scroll spy for toc * make spy work again --------- Co-authored-by: generall <andrey@vasnetsov.com> * limit toc depth to 3 * thin scrollbar * No dev template (#1266) * divided the docs template into smaller partials, increased reusability * removed docs section, moved all to the documentation * review fixes * review fixes --------- Co-authored-by: generall <andrey@vasnetsov.com> * side panel more compact * toc margin bottom fix * Refactoring and renaming (#1277) * renamed and moved partials, fixed link * refactoring: docs-card * fix * fix urls * disable scrollbar on table of content * added scrollbar colors for light theme (#1280) * fix language * Dev portal fixes (#1285) * cards fixes * moved files, fixed paddings * fix for my fix * external header links * fix --------- Co-authored-by: trean <trean.mi@gmail.com> Co-authored-by: Andrey Vasnetsov <andrey@vasnetsov.com> Co-authored-by: davidmyriel <davidmyriel@gmail.com>
This commit is contained in:
co-authored by
generall
trean
davidmyriel
parent
9704ddb36b
commit
aa1acf0acb
@@ -1,3 +1,6 @@
|
||||
export const LG_BREAKPOINT = 992;
|
||||
export const XL_BREAKPOINT = 1200;
|
||||
export const XXL_BREAKPOINT = 1400;
|
||||
|
||||
// Offset for content navigation from the top of the page
|
||||
export const DOCS_HEADER_OFFSET = 100;
|
||||
@@ -1,5 +1,6 @@
|
||||
import ThemeSwitch from './theme-switch.js';
|
||||
import { XL_BREAKPOINT } from './constants';
|
||||
import TableOfContents from './table-of-content';
|
||||
|
||||
const themeSwitch = new ThemeSwitch();
|
||||
|
||||
@@ -15,10 +16,10 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
sidebar.classList.toggle('active');
|
||||
});
|
||||
|
||||
const moveSearchButton = function() {
|
||||
const moveSearchButton = function () {
|
||||
const checkIfFirstChildIsSearch = (element) => {
|
||||
return element.children.length > 0 && element.children[0].classList.contains('docs-menu__input');
|
||||
}
|
||||
};
|
||||
|
||||
const isMobile = window.innerWidth <= XL_BREAKPOINT;
|
||||
if (isMobile && !checkIfFirstChildIsSearch(docsMenu)) {
|
||||
@@ -26,9 +27,14 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
} else if (!isMobile && !checkIfFirstChildIsSearch(sidebar)) {
|
||||
sidebar.before(searchbar);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
moveSearchButton();
|
||||
|
||||
window.addEventListener('resize', moveSearchButton);
|
||||
|
||||
// if #TableOfContents and .documentation-article exists on the page, initialize TableOfContents class
|
||||
if (document.getElementById('TableOfContents') && document.querySelector('.documentation-article')) {
|
||||
new TableOfContents('#TableOfContents', '.documentation-article');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -31,11 +31,17 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
let menuOffset = window.innerWidth >= 1400 ? PADDING_PART_TO_HIDE : 0; // 24px is a PART of padding-top which we want to scroll over
|
||||
|
||||
function addScrollStateToPage() {
|
||||
if (!header) {
|
||||
return;
|
||||
}
|
||||
header.style.minHeight = `${header.offsetHeight}px`;
|
||||
body.classList.add('scrolled');
|
||||
}
|
||||
|
||||
function removeScrollStateFromPage() {
|
||||
if (!header) {
|
||||
return;
|
||||
}
|
||||
header.style.minHeight = '';
|
||||
body.classList.remove('scrolled');
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'qdrant-page-search/dist/js/search.min.js';
|
||||
|
||||
(function () {
|
||||
if (/documentation/.test(window.location?.pathname)) {
|
||||
if (/documentation|docs/.test(window.location?.pathname)) {
|
||||
window.initQdrantSearch({ searchApiUrl: 'https://search.qdrant.tech/api/search', section: 'documentation' });
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
import { DOCS_HEADER_OFFSET } from './constants';
|
||||
|
||||
class TableOfContents {
|
||||
constructor(tocSelector, contentSelector) {
|
||||
this.tocLinks = Array.from(document.querySelectorAll(`${tocSelector} a`));
|
||||
this.headings = Array.from(
|
||||
document.querySelectorAll(
|
||||
`${contentSelector} h1, ${contentSelector} h2, ${contentSelector} h3`,
|
||||
),
|
||||
);
|
||||
this.currentActiveIndex = -1; // Track the current active heading index
|
||||
this.currentActive = null; // Track the current active heading element
|
||||
|
||||
|
||||
this.debounceTimeout = null;
|
||||
|
||||
this.currentlyVisibleHeaderIds = new Set();
|
||||
|
||||
this.headerOffset = DOCS_HEADER_OFFSET + 10;
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
// Initialize the Table of Contents functionality
|
||||
init() {
|
||||
this.setupObserver();
|
||||
}
|
||||
|
||||
// Clear 'active' class from all links
|
||||
clearActiveClasses() {
|
||||
this.tocLinks.forEach((link) => link.classList.remove('active'));
|
||||
}
|
||||
|
||||
// Set active link with debounce
|
||||
setActiveLink(index) {
|
||||
if (index !== this.currentActiveIndex) {
|
||||
this.clearActiveClasses();
|
||||
if (this.tocLinks[index]) {
|
||||
this.tocLinks[index].classList.add('active');
|
||||
this.currentActiveIndex = index;
|
||||
this.currentActive = this.headings[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Setup Intersection Observer
|
||||
setupObserver() {
|
||||
const observerCallback = (entries) => {
|
||||
|
||||
entries.forEach((entry) => {
|
||||
const entryIndex = this.headings.indexOf(entry.target);
|
||||
const isIntersecting = entry.isIntersecting;
|
||||
|
||||
if (isIntersecting) {
|
||||
this.currentlyVisibleHeaderIds.add(entryIndex);
|
||||
} else {
|
||||
this.currentlyVisibleHeaderIds.delete(entryIndex);
|
||||
}
|
||||
});
|
||||
|
||||
if (this.currentlyVisibleHeaderIds.size !== 0) {
|
||||
let minimalVisibleHeaderId = Math.min(...Array.from(this.currentlyVisibleHeaderIds));
|
||||
this.setActiveLink(minimalVisibleHeaderId);
|
||||
} else {
|
||||
// No intersection found
|
||||
// If current active heading is below the viewport, then set current active to one above it
|
||||
if (this.currentActive && this.currentActive.getBoundingClientRect().top > this.headerOffset) {
|
||||
this.setActiveLink(this.currentActiveIndex - 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Observer options
|
||||
const observerOptions = {
|
||||
root: null,
|
||||
rootMargin: `-${this.headerOffset}px 0px -25% 0px`,
|
||||
threshold: 0.0, // Lower threshold for better visibility
|
||||
};
|
||||
|
||||
const observer = new IntersectionObserver(observerCallback, observerOptions);
|
||||
this.headings.forEach((heading) => observer.observe(heading));
|
||||
}
|
||||
}
|
||||
|
||||
export default TableOfContents;
|
||||
@@ -1,5 +1,6 @@
|
||||
import AnchorJS from 'anchor-js';
|
||||
import { scrollIntoViewWithOffset } from '../helpers';
|
||||
import { DOCS_HEADER_OFFSET } from '../constants';
|
||||
|
||||
const anchors = new AnchorJS();
|
||||
anchors.options.placement = 'left';
|
||||
@@ -8,19 +9,19 @@ anchors.options.class = 'text-decoration-none';
|
||||
document.addEventListener('DOMContentLoaded', function (event) {
|
||||
anchors.add('.qdrant-post__body :is(h1, h2, h3, h4, h5, h6)');
|
||||
if (/documentation/.test(window.location?.pathname)) {
|
||||
anchors.add('.documentation-article :is(h1, h2, h3, h4, h5, h6)');
|
||||
anchors.add('.documentation-article > :is(h1, h2, h3, h4, h5, h6)');
|
||||
}
|
||||
|
||||
// scroll to anchors:
|
||||
let offset = 100;
|
||||
let offset = DOCS_HEADER_OFFSET;
|
||||
|
||||
if (window.location.hash) {
|
||||
scrollIntoViewWithOffset(window.location.hash.replace('#', ''), offset).catch((e) => {
|
||||
console.error(e);
|
||||
});
|
||||
scrollIntoViewWithOffset(window.location.hash.replace('#', ''), offset);
|
||||
}
|
||||
|
||||
document.querySelectorAll('a[href^="#"]').forEach((anchor) => {
|
||||
let allLinks = document.querySelectorAll('a[href^="#"]');
|
||||
|
||||
allLinks.forEach((anchor) => {
|
||||
const target = anchor.getAttribute('href');
|
||||
anchor.addEventListener('click', function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
Reference in New Issue
Block a user