2023-11-09 12:23:41 +01:00
|
|
|
<script>
|
|
|
|
import { tick } from "svelte"
|
|
|
|
import { Icon, Body } from "@budibase/bbui"
|
|
|
|
|
|
|
|
export let title
|
|
|
|
export let placeholder
|
2023-11-09 15:12:17 +01:00
|
|
|
export let value
|
2023-11-09 12:23:41 +01:00
|
|
|
|
|
|
|
let searchInput
|
|
|
|
let search = false
|
|
|
|
|
|
|
|
const openSearch = async () => {
|
|
|
|
search = true
|
|
|
|
await tick()
|
|
|
|
searchInput.focus()
|
|
|
|
}
|
|
|
|
|
|
|
|
const closeSearch = async () => {
|
|
|
|
search = false
|
2023-11-09 15:14:58 +01:00
|
|
|
value = ""
|
2023-11-09 12:23:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
const onKeyDown = e => {
|
|
|
|
if (e.key === "Escape") {
|
|
|
|
closeSearch()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<svelte:window on:keydown={onKeyDown} />
|
|
|
|
|
|
|
|
<div class="header" class:search>
|
|
|
|
<input
|
|
|
|
readonly={!search}
|
2023-11-09 15:12:17 +01:00
|
|
|
bind:value
|
2023-11-09 12:23:41 +01:00
|
|
|
bind:this={searchInput}
|
2023-11-09 13:11:29 +01:00
|
|
|
class="searchBox"
|
|
|
|
class:hide={!search}
|
2023-11-09 12:23:41 +01:00
|
|
|
{placeholder}
|
|
|
|
/>
|
2023-11-09 12:53:47 +01:00
|
|
|
|
2023-11-09 13:11:29 +01:00
|
|
|
<div
|
|
|
|
on:click={closeSearch}
|
|
|
|
on:keydown={closeSearch}
|
|
|
|
class="closeButton"
|
|
|
|
class:hide={!search}
|
|
|
|
>
|
2023-11-09 12:53:47 +01:00
|
|
|
<Icon name="Add" />
|
|
|
|
</div>
|
2023-11-09 12:23:41 +01:00
|
|
|
<div class="title" class:hide={search}>
|
|
|
|
<Body size="S">{title}</Body>
|
|
|
|
</div>
|
|
|
|
<div
|
|
|
|
on:click={openSearch}
|
|
|
|
on:keydown={openSearch}
|
|
|
|
class="searchButton"
|
|
|
|
class:hide={search}
|
|
|
|
>
|
|
|
|
<Icon size="S" name="Search" />
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<style>
|
|
|
|
.search {
|
|
|
|
transition: height 300ms ease-out;
|
|
|
|
max-height: none;
|
|
|
|
}
|
|
|
|
|
|
|
|
.header {
|
|
|
|
flex-shrink: 0;
|
|
|
|
flex-direction: row;
|
|
|
|
position: relative;
|
|
|
|
height: 50px;
|
|
|
|
width: 100%;
|
|
|
|
box-sizing: border-box;
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
justify-content: space-between;
|
|
|
|
border-bottom: 2px solid transparent;
|
|
|
|
transition: border-bottom 130ms ease-out;
|
|
|
|
}
|
|
|
|
|
2023-11-09 13:11:29 +01:00
|
|
|
.searchBox {
|
2023-11-09 12:23:41 +01:00
|
|
|
font-family: var(--font-sans);
|
|
|
|
color: var(--ink);
|
|
|
|
background-color: transparent;
|
|
|
|
border: none;
|
|
|
|
font-size: var(--spectrum-alias-font-size-default);
|
2023-11-09 13:11:29 +01:00
|
|
|
display: flex;
|
2023-11-09 12:23:41 +01:00
|
|
|
}
|
2023-11-09 13:11:29 +01:00
|
|
|
.searchBox:focus {
|
2023-11-09 12:23:41 +01:00
|
|
|
outline: none;
|
|
|
|
}
|
2023-11-09 13:11:29 +01:00
|
|
|
.searchBox::placeholder {
|
2023-11-09 12:23:41 +01:00
|
|
|
color: var(--spectrum-global-color-gray-600);
|
|
|
|
}
|
|
|
|
|
|
|
|
.title {
|
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
|
|
|
height: 100%;
|
|
|
|
box-sizing: border-box;
|
|
|
|
flex: 1;
|
|
|
|
opacity: 1;
|
|
|
|
z-index: 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
.searchButton {
|
|
|
|
color: var(--grey-7);
|
|
|
|
cursor: pointer;
|
|
|
|
opacity: 1;
|
|
|
|
}
|
|
|
|
.searchButton:hover {
|
|
|
|
color: var(--ink);
|
|
|
|
}
|
|
|
|
|
|
|
|
.hide {
|
|
|
|
opacity: 0;
|
|
|
|
pointer-events: none;
|
2023-11-09 13:11:29 +01:00
|
|
|
display: none !important;
|
2023-11-09 12:23:41 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
.closeButton {
|
2023-11-09 13:11:29 +01:00
|
|
|
display: flex;
|
2023-11-09 12:23:41 +01:00
|
|
|
transform: rotate(45deg);
|
2023-11-09 12:53:47 +01:00
|
|
|
color: var(--grey-7);
|
|
|
|
cursor: pointer;
|
|
|
|
transition: transform 300ms ease-out;
|
|
|
|
}
|
|
|
|
|
|
|
|
.closeButton:hover {
|
|
|
|
color: var(--ink);
|
2023-11-09 12:23:41 +01:00
|
|
|
}
|
|
|
|
</style>
|