dees-catalog/ts_web/elements/dees-chips.ts

196 lines
4.6 KiB
TypeScript
Raw Normal View History

2021-10-08 14:07:40 +00:00
import {
customElement,
html,
DeesElement,
property,
2023-08-07 18:02:18 +00:00
type TemplateResult,
2021-10-08 14:07:40 +00:00
cssManager,
css,
2023-08-07 23:10:02 +00:00
type CSSResult,
2021-10-08 14:07:40 +00:00
unsafeCSS,
2023-08-07 17:13:29 +00:00
} from '@design.estate/dees-element';
2021-10-08 14:07:40 +00:00
2023-08-07 17:13:29 +00:00
import * as domtools from '@design.estate/dees-domtools';
2023-10-23 19:23:18 +00:00
import { demoFunc } from './dees-chips.demo.js';
2021-10-08 14:07:40 +00:00
declare global {
interface HTMLElementTagNameMap {
'dees-chips': DeesChips;
}
}
2023-10-31 12:44:18 +00:00
type Tag = { key: string; value: string };
2023-10-23 19:23:18 +00:00
2021-10-08 14:07:40 +00:00
@customElement('dees-chips')
export class DeesChips extends DeesElement {
2023-10-23 19:23:18 +00:00
public static demo = demoFunc;
2021-10-08 14:07:40 +00:00
@property()
2023-10-23 19:23:18 +00:00
public selectionMode: 'none' | 'single' | 'multiple' = 'single';
2021-10-08 14:07:40 +00:00
@property({
2023-10-31 12:44:18 +00:00
type: Boolean,
})
public chipsAreRemovable: boolean = false;
@property({
type: Array,
2021-10-08 14:07:40 +00:00
})
2023-10-23 19:23:18 +00:00
public selectableChips: Tag[] = [];
2021-10-08 14:07:40 +00:00
@property()
2023-10-23 19:23:18 +00:00
public selectedChip: Tag = null;
2021-10-08 14:07:40 +00:00
@property({
2023-10-31 12:44:18 +00:00
type: Array,
2021-10-08 14:07:40 +00:00
})
2023-10-23 19:23:18 +00:00
public selectedChips: Tag[] = [];
2021-10-08 14:07:40 +00:00
constructor() {
super();
}
public static styles = [
cssManager.defaultStyles,
css`
:host {
display: block;
box-sizing: border-box;
}
.mainbox {
2023-10-23 19:23:18 +00:00
user-select: none;
2021-10-08 14:07:40 +00:00
}
.chip {
2023-10-23 19:23:18 +00:00
border-top: ${cssManager.bdTheme('1px solid #CCC', '1px solid #444')};
background: #333333;
display: inline-flex;
height: 20px;
line-height: 20px;
padding: 0px 8px;
font-size: 12px;
2021-10-08 14:07:40 +00:00
color: #fff;
2022-05-30 21:15:32 +00:00
border-radius: 40px;
margin-right: 4px;
2023-10-24 12:18:03 +00:00
margin-bottom: 4px;
2023-10-23 19:23:18 +00:00
position: relative;
overflow: hidden;
2023-10-31 12:44:18 +00:00
box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.3);
2021-10-08 14:07:40 +00:00
}
.chip:hover {
background: #666666;
}
.chip.selected {
2023-10-31 12:44:18 +00:00
background: #00a3ff;
2021-10-08 14:07:40 +00:00
}
2023-10-23 19:23:18 +00:00
.chipKey {
2023-10-31 12:44:18 +00:00
background: rgba(0, 0, 0, 0.3);
2023-10-23 19:23:18 +00:00
height: 100%;
display: inline-block;
margin-left: -8px;
padding-left: 8px;
padding-right: 8px;
margin-right: 8px;
}
2023-10-31 12:44:18 +00:00
dees-icon {
padding: 0px 6px 0px 4px;
margin-left: 4px;
margin-right: -8px;
background: rgba(0, 0, 0, 0.3);
}
dees-icon:hover {
background: #e4002b;
}
2021-10-08 14:07:40 +00:00
`,
];
public render(): TemplateResult {
return html`
<div class="mainbox">
2023-10-31 12:44:18 +00:00
${this.selectableChips.map(
(chip) => html`
<div
@click=${() => this.selectChip(chip)}
class="chip ${this.isSelected(chip) ? 'selected' : ''}"
>
${chip.key ? html`<div class="chipKey">${chip.key}</div>` : html``} ${chip.value}
${this.chipsAreRemovable
? html`
<dees-icon
@click=${(event: Event) => {
event.stopPropagation(); // prevent the selectChip event from being triggered
this.removeChip(chip);
}}
.iconFA=${'xmark'}
></dees-icon>
`
: html``}
</div>
`
)}
2021-10-08 14:07:40 +00:00
</div>
`;
}
public async firstUpdated() {
if (!this.textContent) {
this.textContent = 'Button';
this.performUpdate();
}
}
2023-10-23 19:23:18 +00:00
private isSelected(chip: Tag): boolean {
if (this.selectionMode === 'single') {
return this.selectedChip?.key === chip.key;
} else {
2023-10-31 12:44:18 +00:00
return this.selectedChips.some((selected) => selected.key === chip.key);
2023-10-23 19:23:18 +00:00
}
}
public async selectChip(chip: Tag) {
if (this.selectionMode === 'none') {
return;
}
2021-10-08 14:07:40 +00:00
if (this.selectionMode === 'single') {
2023-10-23 19:23:18 +00:00
if (this.isSelected(chip)) {
2021-10-08 14:07:40 +00:00
this.selectedChip = null;
this.selectedChips = [];
} else {
2023-10-23 19:23:18 +00:00
this.selectedChip = chip;
this.selectedChips = [chip];
2021-10-08 14:07:40 +00:00
}
2023-10-31 12:44:18 +00:00
} else if (this.selectionMode === 'multiple') {
2023-10-23 19:23:18 +00:00
if (this.isSelected(chip)) {
2023-10-31 12:44:18 +00:00
this.selectedChips = this.selectedChips.filter((selected) => selected.key !== chip.key);
2021-10-08 14:07:40 +00:00
} else {
2023-10-23 19:23:18 +00:00
this.selectedChips = [...this.selectedChips, chip];
2021-10-08 14:07:40 +00:00
}
this.requestUpdate();
}
console.log(this.selectedChips);
}
2023-10-31 12:44:18 +00:00
public removeChip(chipToRemove: Tag): void {
// Remove the chip from selectableChips
this.selectableChips = this.selectableChips.filter((chip) => chip.key !== chipToRemove.key);
// Remove the chip from selectedChips if present
this.selectedChips = this.selectedChips.filter((chip) => chip.key !== chipToRemove.key);
// If the removed chip was the selectedChip, set selectedChip to null
if (this.selectedChip && this.selectedChip.key === chipToRemove.key) {
this.selectedChip = null;
}
// Trigger an update to re-render the component
this.requestUpdate();
}
2021-10-08 14:07:40 +00:00
}