mirror of
https://github.com/modernweb-dev/rocket.git
synced 2026-03-21 15:54:57 +00:00
Compare commits
6 Commits
@rocket/bu
...
@rocket/na
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e9090d64b9 | ||
|
|
728a205b7b | ||
|
|
67ba29d45a | ||
|
|
758caffdf9 | ||
|
|
302227e8a9 | ||
|
|
04a31220fb |
@@ -47,3 +47,9 @@ export const headlineConverter = () => html`
|
||||
```
|
||||
|
||||
How it then works is very similar to https://www.11ty.dev/docs/plugins/navigation/
|
||||
|
||||
## Sidebar redirects
|
||||
|
||||
By default, the sidebar nav redirects clicks on category headings to the first child page in that category.
|
||||
|
||||
To disable those redirects, override `_includes/_joiningBlocks/_layoutSidebar/sidebar/20-navigation.njk` and add the `no-redirects` attribute to the `<rocket-navigation>` element.
|
||||
|
||||
@@ -38,6 +38,6 @@
|
||||
"testing"
|
||||
],
|
||||
"dependencies": {
|
||||
"plugins-manager": "^0.2.0"
|
||||
"plugins-manager": "^0.2.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,12 +43,12 @@
|
||||
"remark"
|
||||
],
|
||||
"dependencies": {
|
||||
"@mdjs/mdjs-preview": "^0.3.1",
|
||||
"@mdjs/mdjs-story": "^0.1.1",
|
||||
"@mdjs/mdjs-preview": "^0.3.2",
|
||||
"@mdjs/mdjs-story": "^0.1.2",
|
||||
"@types/unist": "^2.0.3",
|
||||
"es-module-lexer": "^0.3.26",
|
||||
"github-markdown-css": "^4.0.0",
|
||||
"plugins-manager": "^0.2.0",
|
||||
"plugins-manager": "^0.2.1",
|
||||
"rehype-autolink-headings": "^5.0.1",
|
||||
"rehype-prism-template": "^0.4.1",
|
||||
"rehype-raw": "^5.0.0",
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
# @rocket/navigation
|
||||
|
||||
## 0.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 728a205: feat(navigation): add no-redirects attribute
|
||||
|
||||
By default, the sidebar nav redirects clicks on category headings to
|
||||
their first child.
|
||||
|
||||
To disable those redirects, override
|
||||
\_includes/\_joiningBlocks/\_layoutSidebar/sidebar/20-navigation.njk
|
||||
and add the no-redirects attribute to the <rocket-navigation>
|
||||
element.
|
||||
|
||||
## 0.2.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@rocket/navigation",
|
||||
"version": "0.2.0",
|
||||
"version": "0.2.1",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
||||
@@ -1,3 +1,27 @@
|
||||
/**
|
||||
* Debounce a function
|
||||
* @template {(this: any, ...args: any[]) => void} T
|
||||
* @param {T} func function
|
||||
* @param {number} wait time in milliseconds to debounce
|
||||
* @param {boolean} immediate when true, run immediately and on the leading edge
|
||||
* @return {T} debounced function
|
||||
*/
|
||||
function debounce(func, wait, immediate) {
|
||||
/** @type {number|undefined} */
|
||||
let timeout;
|
||||
return /** @type {typeof func}*/ (function () {
|
||||
let args = /** @type {Parameters<typeof func>} */ (/** @type {unknown}*/ (arguments));
|
||||
const later = () => {
|
||||
timeout = undefined;
|
||||
if (!immediate) func.apply(this, args);
|
||||
};
|
||||
const callNow = immediate && !timeout;
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(later, wait);
|
||||
if (callNow) func.apply(this, args);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {object} NavigationListItem
|
||||
* @property {HTMLElement} headline
|
||||
@@ -5,12 +29,17 @@
|
||||
* @property {number} top
|
||||
*/
|
||||
|
||||
/**
|
||||
* @element rocket-navigation
|
||||
* @attr {Boolean} no-redirects - if set, will not redirect to first child of nav category when clicking on category header.
|
||||
*/
|
||||
export class RocketNavigation extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
/** @type NavigationListItem[] */
|
||||
this.list = [];
|
||||
this.__scrollHandler = this.__scrollHandler.bind(this);
|
||||
this.__clickHandler = this.__clickHandler.bind(this);
|
||||
this.__scrollHandler = debounce(this.__scrollHandler.bind(this), 25, true);
|
||||
this.__isSetup = false;
|
||||
}
|
||||
|
||||
@@ -20,27 +49,7 @@ export class RocketNavigation extends HTMLElement {
|
||||
}
|
||||
this.__isSetup = true;
|
||||
|
||||
this.addEventListener('click', ev => {
|
||||
const el = /** @type {HTMLElement} */ (ev.target);
|
||||
if (el.classList.contains('anchor')) {
|
||||
const anchor = /** @type {HTMLAnchorElement} */ (el);
|
||||
ev.preventDefault();
|
||||
this.dispatchEvent(new Event('close-overlay', { bubbles: true }));
|
||||
// wait for closing animation to finish before start scrolling
|
||||
setTimeout(() => {
|
||||
const parsedUrl = new URL(anchor.href);
|
||||
document.location.hash = parsedUrl.hash;
|
||||
}, 250);
|
||||
}
|
||||
const links = el.parentElement?.querySelectorAll('ul a');
|
||||
if (links && links.length > 1) {
|
||||
const subLink = /** @type {HTMLAnchorElement} */ (links[1]);
|
||||
if (!subLink.classList.contains('anchor')) {
|
||||
ev.preventDefault();
|
||||
subLink.click();
|
||||
}
|
||||
}
|
||||
});
|
||||
this.addEventListener('click', this.__clickHandler);
|
||||
|
||||
const anchors = /** @type {NodeListOf<HTMLAnchorElement>} */ (this.querySelectorAll(
|
||||
'li.current a.anchor',
|
||||
@@ -57,12 +66,41 @@ export class RocketNavigation extends HTMLElement {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: debounce
|
||||
window.addEventListener('scroll', this.__scrollHandler);
|
||||
window.addEventListener('scroll', this.__scrollHandler, { passive: true });
|
||||
|
||||
this.__scrollHandler();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Event} ev
|
||||
*/
|
||||
__clickHandler(ev) {
|
||||
const el = /** @type {HTMLElement} */ (ev.target);
|
||||
if (el.classList.contains('anchor')) {
|
||||
const anchor =
|
||||
el instanceof HTMLAnchorElement
|
||||
? el
|
||||
: /** @type{HTMLAnchorElement} */ (el.querySelector('a.anchor'));
|
||||
ev.preventDefault();
|
||||
this.dispatchEvent(new Event('close-overlay', { bubbles: true }));
|
||||
// wait for closing animation to finish before start scrolling
|
||||
setTimeout(() => {
|
||||
const parsedUrl = new URL(anchor.href);
|
||||
document.location.hash = parsedUrl.hash;
|
||||
}, 250);
|
||||
}
|
||||
if (!this.hasAttribute('no-redirects')) {
|
||||
const links = el.parentElement?.querySelectorAll('ul a');
|
||||
if (links && links.length > 1) {
|
||||
const subLink = /** @type {HTMLAnchorElement} */ (links[1]);
|
||||
if (!subLink.classList.contains('anchor')) {
|
||||
ev.preventDefault();
|
||||
subLink.click();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__scrollHandler() {
|
||||
for (const listObj of this.list) {
|
||||
listObj.top = listObj.headline.getBoundingClientRect().top;
|
||||
|
||||
@@ -58,7 +58,8 @@ describe('rocket-navigation', () => {
|
||||
expect(anchorSpy).to.not.be.called;
|
||||
});
|
||||
|
||||
it('will mark the currently "active" headline in the menu', async () => {
|
||||
it('will mark the currently "active" headline in the menu', async function () {
|
||||
this.timeout(5000);
|
||||
function addBlock(headline, length = 5) {
|
||||
return html`
|
||||
<h2 id="${headline}">${headline}</h2>
|
||||
@@ -96,20 +97,20 @@ describe('rocket-navigation', () => {
|
||||
}
|
||||
</style>
|
||||
`);
|
||||
await aTimeout(0);
|
||||
await aTimeout(50);
|
||||
const anchorLis = wrapper.querySelectorAll('.menu-item.anchor');
|
||||
expect(anchorLis[0]).to.have.class('current');
|
||||
expect(anchorLis[1]).to.not.have.class('current');
|
||||
expect(anchorLis[2]).to.not.have.class('current');
|
||||
|
||||
document.querySelector('#middle').scrollIntoView();
|
||||
await aTimeout(20);
|
||||
await aTimeout(100);
|
||||
expect(anchorLis[0]).to.not.have.class('current');
|
||||
expect(anchorLis[1]).to.have.class('current');
|
||||
expect(anchorLis[2]).to.not.have.class('current');
|
||||
|
||||
document.querySelector('#bottom').scrollIntoView();
|
||||
await aTimeout(20);
|
||||
await aTimeout(100);
|
||||
expect(anchorLis[0]).to.not.have.class('current');
|
||||
expect(anchorLis[1]).to.not.have.class('current');
|
||||
expect(anchorLis[2]).to.have.class('current');
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @rocket/search
|
||||
|
||||
## 0.3.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- 302227e: Add variable for border-radius of SearchCombobox
|
||||
|
||||
## 0.3.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@rocket/search",
|
||||
"version": "0.3.1",
|
||||
"version": "0.3.2",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
|
||||
@@ -138,7 +138,7 @@ export class RocketSearchCombobox extends LionCombobox {
|
||||
display: flex;
|
||||
border: 1px solid var(--rocket-search-input-border-color, #dfe1e5);
|
||||
box-shadow: none;
|
||||
border-radius: 24px;
|
||||
border-radius: var(--rocket-search-input-border-radius, 24px);
|
||||
padding: 5px 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user