-
-
Notifications
You must be signed in to change notification settings - Fork 561
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Style search components to match designs (#23)
- Loading branch information
Showing
9 changed files
with
322 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,286 @@ | ||
--- | ||
import '@pagefind/default-ui/css/ui.css'; | ||
import Icon from './Icon.astro'; | ||
--- | ||
|
||
<div class="search-container"> | ||
<div id="starbook__search"></div> | ||
</div> | ||
<site-search> | ||
<button data-open-modal disabled> | ||
<Icon name="magnifier" label="Search" /> | ||
<span class="hidden md:block" aria-hidden="true">Search</span> | ||
<Icon | ||
name="forward-slash" | ||
class="hidden md:block" | ||
label="(Press / to search)" | ||
/> | ||
</button> | ||
|
||
<dialog style="padding:0" aria-label="Search the documentation"> | ||
<div class="dialog-frame"> | ||
<button data-close-modal class="flex md:hidden">Cancel</button> | ||
<div class="search-container"> | ||
<div id="starbook__search"></div> | ||
</div> | ||
</div> | ||
</dialog> | ||
</site-search> | ||
|
||
<script> | ||
class SiteSearch extends HTMLElement { | ||
constructor() { | ||
super(); | ||
const openBtn = this.querySelector<HTMLButtonElement>( | ||
'button[data-open-modal]' | ||
)!; | ||
const closeBtn = this.querySelector<HTMLButtonElement>( | ||
'button[data-close-modal]' | ||
)!; | ||
const dialog = this.querySelector('dialog')!; | ||
const dialogFrame = this.querySelector('.dialog-frame')!; | ||
|
||
/** Close the modal if a user clicks outside of the modal. */ | ||
const onWindowClick = (event: MouseEvent) => { | ||
if (!dialogFrame.contains(event.target as Node)) closeModal(); | ||
}; | ||
|
||
const openModal = (event?: MouseEvent) => { | ||
dialog.showModal(); | ||
this.querySelector('input')?.focus(); | ||
event?.stopPropagation(); | ||
window.addEventListener('click', onWindowClick); | ||
}; | ||
|
||
const closeModal = () => { | ||
dialog.close(); | ||
window.removeEventListener('click', onWindowClick); | ||
}; | ||
|
||
openBtn.addEventListener('click', openModal); | ||
openBtn.disabled = false; | ||
closeBtn.addEventListener('click', closeModal); | ||
|
||
// Listen for `/` and `cmd + k` keyboard shortcuts. | ||
window.addEventListener('keydown', (e) => { | ||
if (e.metaKey === true && e.key === 'k') { | ||
dialog.open ? closeModal() : openModal(); | ||
e.preventDefault(); | ||
} else if (e.key === '/' && !dialog.open) { | ||
openModal(); | ||
e.preventDefault(); | ||
} | ||
}); | ||
} | ||
} | ||
customElements.define('site-search', SiteSearch); | ||
|
||
window.addEventListener('DOMContentLoaded', () => { | ||
const onIdle = window.requestIdleCallback || ((cb) => setTimeout(cb, 1)); | ||
onIdle(async () => { | ||
const { PagefindUI } = await import('@pagefind/default-ui'); | ||
new PagefindUI({ | ||
element: '#starbook__search', | ||
baseUrl: import.meta.env.BASE_URL, | ||
showImages: false, | ||
}); | ||
}); | ||
}); | ||
</script> | ||
|
||
<style> | ||
.search-container { | ||
--pagefind-ui-scale: 0.65; | ||
button[data-open-modal] { | ||
display: flex; | ||
align-items: center; | ||
gap: 0.5rem; | ||
border: 0; | ||
background-color: transparent; | ||
color: var(--sb-color-gray-1); | ||
cursor: pointer; | ||
height: 2.5rem; | ||
font-size: var(--sb-text-xl); | ||
} | ||
|
||
@media (min-width: 50rem) { | ||
button[data-open-modal] { | ||
border: 1px solid var(--sb-color-gray-5); | ||
border-radius: 0.5rem; | ||
padding-inline-start: 0.75rem; | ||
padding-inline-end: 1rem; | ||
background-color: var(--sb-color-black); | ||
color: var(--sb-color-gray-2); | ||
font-size: var(--sb-text-sm); | ||
width: 100%; | ||
max-width: 22rem; | ||
} | ||
button[data-open-modal]:hover { | ||
border-color: var(--sb-color-gray-2); | ||
color: var(--sb-color-white); | ||
} | ||
|
||
button[data-open-modal] > :last-child { | ||
margin-inline-start: auto; | ||
} | ||
} | ||
|
||
dialog { | ||
margin: 0; | ||
background-color: var(--sb-color-gray-6); | ||
border: 1px solid var(--sb-color-gray-5); | ||
width: 100%; | ||
max-width: 100%; | ||
height: 100%; | ||
max-height: 100%; | ||
box-shadow: var(--sb-shadow-lg); | ||
} | ||
dialog[open] { | ||
display: grid; | ||
} | ||
|
||
dialog::backdrop { | ||
background-color: var(--sb-color-backdrop-overlay); | ||
-webkit-backdrop-filter: blur(0.25rem); | ||
backdrop-filter: blur(0.25rem); | ||
} | ||
|
||
.dialog-frame { | ||
display: flex; | ||
flex-direction: column; | ||
gap: 1rem; | ||
padding: 1.5rem; | ||
} | ||
|
||
button[data-close-modal] { | ||
position: absolute; | ||
z-index: 1; | ||
display: flex; | ||
align-items: center; | ||
align-self: flex-end; | ||
height: calc(64px * var(--pagefind-ui-scale)); | ||
padding: 0.25rem; | ||
border: 0; | ||
background: transparent; | ||
cursor: pointer; | ||
color: var(--sb-color-text-accent); | ||
} | ||
|
||
#starbook__search { | ||
--pagefind-ui-primary: var(--sb-color-accent-light); | ||
--pagefind-ui-text: var(--sb-color-gray-2); | ||
--pagefind-ui-background: var(--sb-color-gray-6); | ||
--pagefind-ui-background: var(--sb-color-black); | ||
--pagefind-ui-border: var(--sb-color-gray-5); | ||
--pagefind-ui-border-width: 1px; | ||
--sb-search-cancel-space: 5rem; | ||
} | ||
|
||
position: relative; | ||
width: 50%; | ||
@media (min-width: 50rem) { | ||
#starbook__search { | ||
--sb-search-cancel-space: 0px; | ||
} | ||
|
||
dialog { | ||
margin: 4rem auto auto; | ||
border-radius: 0.5rem; | ||
width: 90%; | ||
max-width: 40rem; | ||
height: max-content; | ||
min-height: 15rem; | ||
max-height: calc(100% - 8rem); | ||
} | ||
|
||
button[data-close-modal] { | ||
display: none; | ||
} | ||
} | ||
</style> | ||
|
||
<style is:global> | ||
#starbook__search .pagefind-ui__form::before { | ||
--pagefind-ui-text: var(--sb-color-gray-1); | ||
opacity: 1; | ||
} | ||
|
||
#starbook__search .pagefind-ui__search-input { | ||
color: var(--sb-color-white); | ||
font-weight: 400; | ||
width: calc(100% - var(--sb-search-cancel-space)); | ||
} | ||
|
||
#starbook__search input:focus { | ||
--pagefind-ui-border: var(--sb-color-accent); | ||
} | ||
|
||
#starbook__search .pagefind-ui__search-clear { | ||
inset-inline-end: var(--sb-search-cancel-space); | ||
width: calc(60px * var(--pagefind-ui-scale)); | ||
padding: 0; | ||
background-color: transparent; | ||
overflow: hidden; | ||
} | ||
#starbook__search .pagefind-ui__search-clear:focus { | ||
outline: 1px solid var(--sb-color-accent); | ||
} | ||
#starbook__search .pagefind-ui__search-clear::before { | ||
content: ''; | ||
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m13.41 12 6.3-6.29a1 1 0 1 0-1.42-1.42L12 10.59l-6.29-6.3a1 1 0 0 0-1.42 1.42l6.3 6.29-6.3 6.29a1 1 0 0 0 .33 1.64 1 1 0 0 0 1.09-.22l6.29-6.3 6.29 6.3a1 1 0 0 0 1.64-.33 1 1 0 0 0-.22-1.09L13.41 12Z'/%3E%3C/svg%3E") | ||
center / 50% no-repeat; | ||
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='m13.41 12 6.3-6.29a1 1 0 1 0-1.42-1.42L12 10.59l-6.29-6.3a1 1 0 0 0-1.42 1.42l6.3 6.29-6.3 6.29a1 1 0 0 0 .33 1.64 1 1 0 0 0 1.09-.22l6.29-6.3 6.29 6.3a1 1 0 0 0 1.64-.33 1 1 0 0 0-.22-1.09L13.41 12Z'/%3E%3C/svg%3E") | ||
center / 50% no-repeat; | ||
background-color: var(--sb-color-text-accent); | ||
display: block; | ||
width: 100%; | ||
height: 100%; | ||
} | ||
#search { | ||
|
||
#starbook__search .pagefind-ui__results > * + * { | ||
margin-top: 0.5rem; | ||
} | ||
#starbook__search .pagefind-ui__result { | ||
position: relative; | ||
border: 0; | ||
border-radius: 0.25rem; | ||
padding: 1rem; | ||
background-color: var(--sb-color-black); | ||
} | ||
|
||
#starbook__search .pagefind-ui__result:hover, | ||
#starbook__search .pagefind-ui__result:focus-within { | ||
outline: 1px solid var(--sb-color-accent-high); | ||
} | ||
|
||
#starbook__search .pagefind-ui__result:focus-within { | ||
background-color: var(--sb-color-accent-low); | ||
} | ||
|
||
#starbook__search .pagefind-ui__result-thumb, | ||
#starbook__search .pagefind-ui__result-inner { | ||
margin-top: 0; | ||
} | ||
|
||
#starbook__search .pagefind-ui__result-link { | ||
--pagefind-ui-text: var(--sb-color-white); | ||
font-weight: 600; | ||
} | ||
|
||
#starbook__search .pagefind-ui__result-link:hover { | ||
text-decoration: none; | ||
} | ||
|
||
#starbook__search .pagefind-ui__result-link::after { | ||
content: ''; | ||
position: absolute; | ||
top: 0; | ||
width: calc(100% - 1rem); | ||
max-width: 22rem; | ||
background: var(--sb-color-gray-6); | ||
padding: 0 0.5rem 0.5rem; | ||
inset: 0; | ||
} | ||
|
||
#starbook__search .pagefind-ui__result-excerpt { | ||
font-size: var(--sb-text-body-sm); | ||
} | ||
|
||
#starbook__search mark { | ||
color: var(--sb-color-white); | ||
background-color: var(--sb-color-accent-low); | ||
font-weight: 500; | ||
padding: 0.1em 0.2em; | ||
} | ||
|
||
#starbook__search .pagefind-ui__result:focus-within mark { | ||
text-decoration: underline; | ||
} | ||
</style> |
Oops, something went wrong.