kopia lustrzana https://github.com/shoelace-style/shoelace
improve search
rodzic
c360d471cd
commit
ded05cf079
|
@ -90,9 +90,13 @@ body.site-search-visible {
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-search__results li a:hover,
|
.site-search__results li a:hover,
|
||||||
.site-search__results li a:hover small,
|
.site-search__results li a:hover small {
|
||||||
.site-search__results li a[aria-selected],
|
background-color: rgb(var(--sl-color-neutral-100));
|
||||||
.site-search__results li a[aria-selected] small {
|
}
|
||||||
|
|
||||||
|
.site-search__results li[aria-selected='true'] a,
|
||||||
|
.site-search__results li[aria-selected='true'] a small,
|
||||||
|
.site-search__results li[aria-selected='true'] a sl-icon {
|
||||||
outline: none;
|
outline: none;
|
||||||
color: rgb(var(--sl-color-neutral-0));
|
color: rgb(var(--sl-color-neutral-0));
|
||||||
background-color: rgb(var(--sl-color-primary-600));
|
background-color: rgb(var(--sl-color-primary-600));
|
||||||
|
@ -103,11 +107,28 @@ body.site-search-visible {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-search__results li {
|
.site-search__result {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.site-search__result a {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: var(--sl-spacing-medium);
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-search__result-icon {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
display: flex;
|
||||||
|
color: rgb(var(--sl-color-neutral-300));
|
||||||
|
font-size: var(--sl-font-size-x-large);
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-search__result-description {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
.site-search__results small {
|
.site-search__results small {
|
||||||
display: block;
|
display: block;
|
||||||
color: rgb(var(--sl-color-neutral-600));
|
color: rgb(var(--sl-color-neutral-600));
|
||||||
|
@ -123,3 +144,17 @@ body.site-search-visible {
|
||||||
.site-search--no-results .site-search__empty {
|
.site-search--no-results .site-search__empty {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.site-search__footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: var(--sl-spacing-large);
|
||||||
|
border-top: solid 1px rgb(var(--sl-color-neutral-200));
|
||||||
|
border-bottom-left-radius: inherit;
|
||||||
|
border-bottom-right-radius: inherit;
|
||||||
|
padding: var(--sl-spacing-small);
|
||||||
|
}
|
||||||
|
|
||||||
|
.site-search__footer small {
|
||||||
|
color: rgb(var(--sl-color-neutral-700));
|
||||||
|
}
|
||||||
|
|
|
@ -65,6 +65,11 @@
|
||||||
<ul class="site-search__results"></ul>
|
<ul class="site-search__results"></ul>
|
||||||
<div class="site-search__empty">No results found.</div>
|
<div class="site-search__empty">No results found.</div>
|
||||||
</div>
|
</div>
|
||||||
|
<footer class="site-search__footer">
|
||||||
|
<small><kbd>↑</kbd> <kbd>↓</kbd> navigate</small>
|
||||||
|
<small><kbd>↲</kbd> select</small>
|
||||||
|
<small><kbd>esc</kbd> close</small>
|
||||||
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
document.body.append(siteSearch);
|
document.body.append(siteSearch);
|
||||||
|
@ -75,7 +80,7 @@
|
||||||
const input = siteSearch.querySelector('.site-search__input');
|
const input = siteSearch.querySelector('.site-search__input');
|
||||||
const results = siteSearch.querySelector('.site-search__results');
|
const results = siteSearch.querySelector('.site-search__results');
|
||||||
const animationDuration = 150;
|
const animationDuration = 150;
|
||||||
const searchDebounce = 250;
|
const searchDebounce = 200;
|
||||||
let isShowing = false;
|
let isShowing = false;
|
||||||
let searchTimeout;
|
let searchTimeout;
|
||||||
let searchIndex;
|
let searchIndex;
|
||||||
|
@ -168,18 +173,15 @@
|
||||||
if (['ArrowDown', 'ArrowUp', 'Home', 'End', 'Enter'].includes(event.key)) {
|
if (['ArrowDown', 'ArrowUp', 'Home', 'End', 'Enter'].includes(event.key)) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
const currentEl = results.querySelector('[aria-selected]');
|
const currentEl = results.querySelector('[aria-selected="true"]');
|
||||||
const items = [...results.querySelectorAll('a')];
|
const items = [...results.querySelectorAll('li')];
|
||||||
|
const index = items.indexOf(currentEl);
|
||||||
let nextEl;
|
let nextEl;
|
||||||
|
|
||||||
items.map(item => item.removeAttribute('aria-selected'));
|
|
||||||
|
|
||||||
if (items.length === 0) {
|
if (items.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const index = items.indexOf(currentEl);
|
|
||||||
|
|
||||||
switch (event.key) {
|
switch (event.key) {
|
||||||
case 'ArrowUp':
|
case 'ArrowUp':
|
||||||
nextEl = items[Math.max(0, index - 1)];
|
nextEl = items[Math.max(0, index - 1)];
|
||||||
|
@ -194,14 +196,19 @@
|
||||||
nextEl = items[items.length - 1];
|
nextEl = items[items.length - 1];
|
||||||
break;
|
break;
|
||||||
case 'Enter':
|
case 'Enter':
|
||||||
(currentEl || items[0]).click();
|
currentEl?.querySelector('a')?.click();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextEl) {
|
// Update the selected item
|
||||||
nextEl.setAttribute('aria-selected', 'true');
|
items.map(item => {
|
||||||
nextEl.scrollIntoView({ block: 'nearest' });
|
if (item === nextEl) {
|
||||||
}
|
item.setAttribute('aria-selected', 'true');
|
||||||
|
nextEl.scrollIntoView({ block: 'nearest' });
|
||||||
|
} else {
|
||||||
|
item.setAttribute('aria-selected', 'false');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -213,7 +220,6 @@
|
||||||
|
|
||||||
const hasQuery = query.length > 0;
|
const hasQuery = query.length > 0;
|
||||||
const matches = hasQuery ? searchIndex.search(query) : [];
|
const matches = hasQuery ? searchIndex.search(query) : [];
|
||||||
let id = 0;
|
|
||||||
|
|
||||||
let hasResults = hasQuery && matches.length > 0;
|
let hasResults = hasQuery && matches.length > 0;
|
||||||
siteSearch.classList.toggle('site-search--has-results', hasQuery && hasResults);
|
siteSearch.classList.toggle('site-search--has-results', hasQuery && hasResults);
|
||||||
|
@ -222,18 +228,32 @@
|
||||||
|
|
||||||
results.innerHTML = '';
|
results.innerHTML = '';
|
||||||
|
|
||||||
matches.map(match => {
|
matches.map((match, index) => {
|
||||||
const page = map[match.ref];
|
const page = map[match.ref];
|
||||||
const li = document.createElement('li');
|
const li = document.createElement('li');
|
||||||
const a = document.createElement('a');
|
const a = document.createElement('a');
|
||||||
|
let icon = 'file-text';
|
||||||
|
|
||||||
|
if (page.url.includes('getting-started/')) icon = 'lightbulb';
|
||||||
|
if (page.url.includes('resources/')) icon = 'book';
|
||||||
|
if (page.url.includes('components/')) icon = 'box';
|
||||||
|
if (page.url.includes('tokens/')) icon = 'palette2';
|
||||||
|
if (page.url.includes('utilities/')) icon = 'wrench';
|
||||||
|
if (page.url.includes('tutorials/')) icon = 'joystick';
|
||||||
|
|
||||||
a.href = $docsify.routerMode === 'hash' ? `/#/${page.url}` : `/${page.url}`;
|
a.href = $docsify.routerMode === 'hash' ? `/#/${page.url}` : `/${page.url}`;
|
||||||
a.innerHTML = `
|
a.innerHTML = `
|
||||||
<h3>${page.title}</h3>
|
<div class="site-search__result-icon">
|
||||||
<small>/${page.url}</small>
|
<sl-icon name="${icon}"></sl-icon>
|
||||||
|
</div>
|
||||||
|
<div class="site-search__result__details">
|
||||||
|
<h3>${page.title}</h3>
|
||||||
|
<small>${page.url}</small>
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
li.setAttribute('id', `search-result-${id++}`);
|
li.classList.add('site-search__result');
|
||||||
|
li.setAttribute('aria-selected', index === 0 ? 'true' : 'false');
|
||||||
li.appendChild(a);
|
li.appendChild(a);
|
||||||
results.appendChild(li);
|
results.appendChild(li);
|
||||||
});
|
});
|
||||||
|
|
|
@ -384,9 +384,10 @@ kbd,
|
||||||
.markdown-section kbd {
|
.markdown-section kbd {
|
||||||
font-family: var(--sl-font-mono);
|
font-family: var(--sl-font-mono);
|
||||||
font-size: 87.5%;
|
font-size: 87.5%;
|
||||||
|
background-color: rgb(var(--sl-color-neutral-100));
|
||||||
border-radius: var(--sl-border-radius-small);
|
border-radius: var(--sl-border-radius-small);
|
||||||
border: solid 1px rgb(var(--sl-color-neutral-200));
|
border: solid 1px rgb(var(--sl-color-neutral-200));
|
||||||
box-shadow: var(--sl-shadow-small);
|
box-shadow: inset 0 1px 1px rgb(var(--sl-color-neutral-0));
|
||||||
padding: 2px 5px;
|
padding: 2px 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue