Merge pull request #12872 from lunarway/feature/techdocs-scroll

Add navigation scroll to techdocs
This commit is contained in:
Ben Lambert
2022-08-02 16:11:42 +02:00
committed by GitHub
7 changed files with 1709 additions and 0 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-techdocs': patch
---
Scroll techdocs navigation into focus and expand any nested navigation items.
@@ -41,6 +41,7 @@ import {
rewriteDocLinks,
simplifyMkdocsFooter,
scrollIntoAnchor,
scrollIntoNavigation,
transform as transformer,
copyToClipboard,
useSanitizerTransformer,
@@ -166,6 +167,7 @@ export const useTechDocsReaderDom = (
async (transformedElement: Element) =>
transformer(transformedElement, [
scrollIntoAnchor(),
scrollIntoNavigation(),
copyToClipboard(theme),
addLinkClickListener({
baseUrl: window.location.origin,
@@ -26,4 +26,5 @@ export * from './removeMkdocsHeader';
export * from './simplifyMkdocsFooter';
export * from './onCssReady';
export * from './scrollIntoAnchor';
export * from './scrollIntoNavigation';
export * from './transformer';
@@ -0,0 +1,84 @@
/*
* Copyright 2021 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { scrollIntoNavigation } from '.';
import { createTestShadowDom, FIXTURES } from '../../test-utils';
jest.useFakeTimers();
describe('scrollIntoNavigation', () => {
afterEach(() => {
jest.clearAllMocks();
});
it('scroll to active navigation item', async () => {
await createTestShadowDom(FIXTURES.FIXTURE_STANDARD_PAGE, {
preTransformers: [],
postTransformers: [scrollIntoNavigation()],
});
// jsdom does not implement scrollIntoView so we attach a function to the
// prototype to be able to test the expected behaviour.
const scrollNavIntoView = jest.fn();
window.HTMLElement.prototype.scrollIntoView = scrollNavIntoView;
jest.advanceTimersByTime(200);
expect(scrollNavIntoView).toHaveBeenCalledWith();
});
it('expand active navigation items', async () => {
const shadowDom = await createTestShadowDom(
FIXTURES.FIXTURE_STANDARD_PAGE,
{
preTransformers: [],
postTransformers: [scrollIntoNavigation()],
},
);
// jsdom does not implement scrollIntoView so we attach an empty function to
// support the behaviour.
window.HTMLElement.prototype.scrollIntoView = () => {};
const click = jest.fn();
shadowDom.addEventListener('click', click);
jest.advanceTimersByTime(200);
expect(click).toHaveBeenCalled();
});
it('does not expand already expanded active navigation items', async () => {
const shadowDom = await createTestShadowDom(
FIXTURES.FIXTURE_STANDARD_PAGE_EXPANDED_NAVIGATION,
{
preTransformers: [],
postTransformers: [scrollIntoNavigation()],
},
);
// jsdom does not implement scrollIntoView so we attach an empty function to
// support the behaviour.
window.HTMLElement.prototype.scrollIntoView = () => {};
const click = jest.fn();
shadowDom.addEventListener('click', click);
jest.advanceTimersByTime(200);
expect(click).not.toHaveBeenCalled();
});
});
@@ -0,0 +1,38 @@
/*
* Copyright 2021 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { Transformer } from './transformer';
export const scrollIntoNavigation = (): Transformer => {
return dom => {
setTimeout(() => {
const activeNavItems = dom?.querySelectorAll(`li.md-nav__item--active`);
if (activeNavItems.length !== 0) {
// expand all navigation items that are active
activeNavItems.forEach(activeNavItem => {
const checkbox = activeNavItem?.querySelector('input');
if (!checkbox?.checked) {
checkbox?.click();
}
});
const lastItem = activeNavItems[activeNavItems.length - 1];
lastItem.scrollIntoView();
}
}, 200);
return dom;
};
};
File diff suppressed because it is too large Load Diff
+2
View File
@@ -15,9 +15,11 @@
*/
import FIXTURE_STANDARD_PAGE from './fixtures/mkdocs-index';
import FIXTURE_STANDARD_PAGE_EXPANDED_NAVIGATION from './fixtures/mkdocs-expanded-index';
export const FIXTURES = {
FIXTURE_STANDARD_PAGE,
FIXTURE_STANDARD_PAGE_EXPANDED_NAVIGATION,
};
export * from './shadowDom';