feat(dees-searchbar): Add dees-searchbar component with live search and filter demo
This commit is contained in:
parent
fcb44dfd24
commit
b7f672e0f2
@ -1,5 +1,12 @@
|
||||
# Changelog
|
||||
|
||||
## 2025-04-22 - 1.7.0 - feat(dees-searchbar)
|
||||
Add dees-searchbar component with live search and filter demo
|
||||
|
||||
- Introduces a new dees-searchbar element with an input field, a search button, and filters
|
||||
- Wires up events for 'search-changed' and 'search-submit' to provide real‐time feedback
|
||||
- Adds a demo file to showcase usage and logging of search events
|
||||
|
||||
## 2025-04-22 - 1.6.0 - feat(documentation/dees-heading)
|
||||
Add codex documentation overview and dees-heading component demo
|
||||
|
||||
|
@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@design.estate/dees-catalog',
|
||||
version: '1.6.0',
|
||||
version: '1.7.0',
|
||||
description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.'
|
||||
}
|
||||
|
46
ts_web/elements/dees-searchbar.demo.ts
Normal file
46
ts_web/elements/dees-searchbar.demo.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import { html } from '@design.estate/dees-element';
|
||||
|
||||
export const demoFunc = () => {
|
||||
const onChanged = (e: CustomEvent) => {
|
||||
// find the demo wrapper and update the 'changed' log inside it
|
||||
const wrapper = (e.target as HTMLElement).closest('.demoWrapper');
|
||||
const el = wrapper?.querySelector('#changed');
|
||||
if (el) el.textContent = `search-changed: ${e.detail.value}`;
|
||||
};
|
||||
const onSubmit = (e: CustomEvent) => {
|
||||
// find the demo wrapper and update the 'submitted' log inside it
|
||||
const wrapper = (e.target as HTMLElement).closest('.demoWrapper');
|
||||
const el = wrapper?.querySelector('#submitted');
|
||||
if (el) el.textContent = `search-submit: ${e.detail.value}`;
|
||||
};
|
||||
return html`
|
||||
<style>
|
||||
.demoWrapper {
|
||||
display: block;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
background: #888888;
|
||||
}
|
||||
.logs {
|
||||
padding: 16px;
|
||||
width: 600px;
|
||||
color: #fff;
|
||||
font-family: monospace;
|
||||
}
|
||||
.logs div {
|
||||
margin: 4px 0;
|
||||
}
|
||||
</style>
|
||||
<div class="demoWrapper">
|
||||
<dees-searchbar
|
||||
@search-changed=${onChanged}
|
||||
@search-submit=${onSubmit}
|
||||
></dees-searchbar>
|
||||
<div class="logs">
|
||||
<div id="changed">search-changed:</div>
|
||||
<div id="submitted">search-submit:</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
};
|
160
ts_web/elements/dees-searchbar.ts
Normal file
160
ts_web/elements/dees-searchbar.ts
Normal file
@ -0,0 +1,160 @@
|
||||
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 }
|
||||
}));
|
||||
}
|
||||
}
|
@ -36,6 +36,7 @@ export * from './dees-mobilenavigation.js';
|
||||
export * from './dees-modal.js';
|
||||
export * from './dees-input-multitoggle.js';
|
||||
export * from './dees-pdf.js';
|
||||
export * from './dees-searchbar.js';
|
||||
export * from './dees-simple-appdash.js';
|
||||
export * from './dees-simple-login.js';
|
||||
export * from './dees-speechbubble.js';
|
||||
|
Loading…
x
Reference in New Issue
Block a user