161 lines
4.0 KiB
TypeScript
161 lines
4.0 KiB
TypeScript
|
import {
|
||
|
customElement,
|
||
|
DeesElement,
|
||
|
property,
|
||
|
html,
|
||
|
cssManager,
|
||
|
unsafeCSS,
|
||
|
css,
|
||
|
type TemplateResult,
|
||
|
domtools,
|
||
|
query,
|
||
|
} from '@design.estate/dees-element';
|
||
|
|
||
|
import * as colors from './00colors.js';
|
||
|
import { demoFunc } from './dees-searchbar.demo.js';
|
||
|
|
||
|
declare global {
|
||
|
interface HTMLElementTagNameMap {
|
||
|
'dees-searchbar': DeesSearchbar;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@customElement('dees-searchbar')
|
||
|
export class DeesSearchbar extends DeesElement {
|
||
|
// DEMO
|
||
|
public static demo = demoFunc;
|
||
|
|
||
|
// STATIC
|
||
|
public static styles = [
|
||
|
cssManager.defaultStyles,
|
||
|
css`
|
||
|
:host {
|
||
|
padding: 40px;
|
||
|
font-family: Dees Sans;
|
||
|
display: block;
|
||
|
background: ${cssManager.bdTheme('#eeeeeb', '#000000')};
|
||
|
}
|
||
|
|
||
|
.searchboxContainer {
|
||
|
position: relative;
|
||
|
margin: auto;
|
||
|
max-width: 800px;
|
||
|
background: ${cssManager.bdTheme('#00000015', '#ffffff15')};
|
||
|
--boxHeight: 60px;
|
||
|
height: var(--boxHeight);
|
||
|
border-radius: var(--boxHeight);
|
||
|
display: grid;
|
||
|
grid-template-columns: 1fr 140px;
|
||
|
justify-content: center;
|
||
|
align-items: center;
|
||
|
border-top: 1px solid ${cssManager.bdTheme('#00000015', '#ffffff20')};
|
||
|
}
|
||
|
|
||
|
input {
|
||
|
height: 100%;
|
||
|
width: 100%;
|
||
|
border: none;
|
||
|
background: none;
|
||
|
color: ${cssManager.bdTheme('#000000', '#eeeeeb')};
|
||
|
padding-left: 25px;
|
||
|
margin-right: -8px;
|
||
|
outline: none;
|
||
|
font-size: 16px;
|
||
|
}
|
||
|
|
||
|
.searchButton {
|
||
|
--buttonPadding: 8px;
|
||
|
background: ${cssManager.bdTheme('#eeeeeb', '#000000')};
|
||
|
color: ${cssManager.bdTheme('#000000', '#eeeeeb')};
|
||
|
line-height: calc(var(--boxHeight) - (var(--buttonPadding) * 2));
|
||
|
border-radius: var(--boxHeight);
|
||
|
transform: scale(1) ;
|
||
|
transform-origin: 50% 50%;
|
||
|
text-align: center;
|
||
|
|
||
|
transition: transform 0.1s, background 0.1s;
|
||
|
margin-right: var(--buttonPadding);
|
||
|
user-select: none;
|
||
|
}
|
||
|
|
||
|
.searchButton:hover {
|
||
|
color: #fff;
|
||
|
background: ${cssManager.bdTheme(colors.bright.blue, colors.dark.blue)};
|
||
|
}
|
||
|
|
||
|
.searchButton:active {
|
||
|
color: #fff;
|
||
|
background: ${cssManager.bdTheme(colors.bright.blueActive, colors.dark.blueActive)};
|
||
|
transform: scale(0.98);
|
||
|
}
|
||
|
|
||
|
.filters {
|
||
|
margin: auto;
|
||
|
max-width: 800px;
|
||
|
}
|
||
|
`,
|
||
|
];
|
||
|
|
||
|
// INSTANCE
|
||
|
|
||
|
@property()
|
||
|
public filters = [];
|
||
|
|
||
|
|
||
|
@query('input')
|
||
|
public searchInput!: HTMLInputElement;
|
||
|
@query('.searchButton')
|
||
|
public searchButton!: HTMLElement;
|
||
|
|
||
|
constructor() {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
public render(): TemplateResult {
|
||
|
return html`
|
||
|
<div class="searchboxContainer">
|
||
|
<input type="text" placeholder="Your Skills (e.g. TypeScript, Rust, Projectmanagement)" />
|
||
|
<div class="searchButton">Search -></div>
|
||
|
</div>
|
||
|
${this.filters.length > 0 ? html`
|
||
|
<div class="filters">
|
||
|
<dees-heading level="hr-small">Filters</dees-heading>
|
||
|
<dees-input-dropdown .label=${'location'}></dees-input-dropdown>
|
||
|
</div>
|
||
|
` : html``}
|
||
|
`;
|
||
|
}
|
||
|
/**
|
||
|
* Lifecycle: after first render, wire up events for input and submit actions
|
||
|
*/
|
||
|
public firstUpdated(): void {
|
||
|
// dispatch change on each input
|
||
|
this.searchInput.addEventListener('input', () => {
|
||
|
this.dispatchEvent(new CustomEvent('search-changed', {
|
||
|
bubbles: true,
|
||
|
composed: true,
|
||
|
detail: { value: this.searchInput.value }
|
||
|
}));
|
||
|
});
|
||
|
// submit on Enter key
|
||
|
this.searchInput.addEventListener('keydown', (e: KeyboardEvent) => {
|
||
|
if (e.key === 'Enter') {
|
||
|
this._dispatchSubmit();
|
||
|
}
|
||
|
});
|
||
|
// submit on button click
|
||
|
this.searchButton.addEventListener('click', () => this._dispatchSubmit());
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Dispatch a submit event with the current search value
|
||
|
*/
|
||
|
private _dispatchSubmit(): void {
|
||
|
this.dispatchEvent(new CustomEvent('search-submit', {
|
||
|
bubbles: true,
|
||
|
composed: true,
|
||
|
detail: { value: this.searchInput.value }
|
||
|
}));
|
||
|
}
|
||
|
}
|