Compare commits

...

36 Commits

Author SHA1 Message Date
f07f2bb95e 1.0.244 2024-01-15 19:42:16 +01:00
0b2f6715e0 fix(core): update 2024-01-15 19:42:15 +01:00
e473364d40 1.0.243 2024-01-15 12:57:50 +01:00
554b72b075 fix(core): update 2024-01-15 12:57:49 +01:00
2c34ec8b39 1.0.242 2024-01-11 21:14:31 +01:00
e6b8e2de19 fix(core): update 2024-01-11 21:14:30 +01:00
a99d270ef1 1.0.241 2024-01-10 05:11:56 +01:00
93ee42135c fix(core): update 2024-01-10 05:11:55 +01:00
f3ca4a114a 1.0.240 2024-01-09 13:57:54 +01:00
7515b824eb fix(core): update 2024-01-09 13:57:53 +01:00
18b98b831a 1.0.239 2023-12-26 21:21:19 +01:00
d99fc8bde9 fix(core): update 2023-12-26 21:21:18 +01:00
f8d5f86814 1.0.238 2023-12-20 19:11:16 +01:00
9c1de08b4b fix(core): update 2023-12-20 19:11:16 +01:00
7f26337e1b 1.0.237 2023-12-20 19:09:55 +01:00
49f3fc8feb fix(core): update 2023-12-20 19:09:55 +01:00
5613ad7fa6 1.0.236 2023-12-08 19:16:23 +01:00
5af43900c4 fix(core): update 2023-12-08 19:16:22 +01:00
c5598f95ef 1.0.235 2023-12-08 18:26:40 +01:00
13d0cf729c fix(core): update 2023-12-08 18:26:40 +01:00
032e928dde 1.0.234 2023-12-08 18:22:19 +01:00
14ab3682f2 fix(core): update 2023-12-08 18:22:18 +01:00
c554e730a6 1.0.233 2023-12-08 18:15:40 +01:00
4d5a490e80 fix(core): update 2023-12-08 18:15:40 +01:00
7708c89fe1 1.0.232 2023-11-29 20:39:18 +01:00
0a0be3e357 fix(core): update 2023-11-29 20:39:17 +01:00
7b7c469fab 1.0.231 2023-11-29 17:20:33 +01:00
d852186888 fix(core): update 2023-11-29 17:20:32 +01:00
6cfda1ebf3 1.0.230 2023-10-31 13:44:19 +01:00
8e0062fdd5 fix(core): update 2023-10-31 13:44:18 +01:00
844cc30551 1.0.229 2023-10-24 14:18:04 +02:00
64074e37fc fix(core): update 2023-10-24 14:18:03 +02:00
cd9b028e9b 1.0.228 2023-10-23 21:23:19 +02:00
81da871e38 fix(core): update 2023-10-23 21:23:18 +02:00
90e78a2e31 1.0.227 2023-10-23 17:26:04 +02:00
5cec1fea73 fix(core): update 2023-10-23 17:26:03 +02:00
44 changed files with 2354 additions and 1612 deletions

View File

@ -119,6 +119,6 @@ jobs:
run: | run: |
npmci node install stable npmci node install stable
npmci npm install npmci npm install
pnpm install -g @gitzone/tsdoc pnpm install -g @git.zone/tsdoc
npmci command tsdoc npmci command tsdoc
continue-on-error: true continue-on-error: true

View File

@ -1,6 +1,6 @@
{ {
"name": "@design.estate/dees-catalog", "name": "@design.estate/dees-catalog",
"version": "1.0.226", "version": "1.0.244",
"private": false, "private": false,
"description": "website for lossless.com", "description": "website for lossless.com",
"main": "dist_ts_web/index.js", "main": "dist_ts_web/index.js",
@ -15,29 +15,29 @@
"author": "Lossless GmbH", "author": "Lossless GmbH",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@design.estate/dees-domtools": "^2.0.51", "@design.estate/dees-domtools": "^2.0.55",
"@design.estate/dees-element": "^2.0.29", "@design.estate/dees-element": "^2.0.33",
"@design.estate/dees-wcctools": "^1.0.81", "@design.estate/dees-wcctools": "^1.0.85",
"@fortawesome/fontawesome-svg-core": "^6.4.2", "@fortawesome/fontawesome-svg-core": "^6.5.1",
"@fortawesome/free-brands-svg-icons": "^6.4.2", "@fortawesome/free-brands-svg-icons": "^6.5.1",
"@fortawesome/free-regular-svg-icons": "^6.4.2", "@fortawesome/free-regular-svg-icons": "^6.5.1",
"@fortawesome/free-solid-svg-icons": "^6.4.2", "@fortawesome/free-solid-svg-icons": "^6.5.1",
"@push.rocks/smarti18n": "^1.0.3", "@push.rocks/smarti18n": "^1.0.4",
"@push.rocks/smartpromise": "^4.0.3", "@push.rocks/smartpromise": "^4.0.3",
"@push.rocks/smartstring": "^4.0.9", "@push.rocks/smartstring": "^4.0.13",
"@tsclass/tsclass": "^4.0.43", "@tsclass/tsclass": "^4.0.46",
"highlight.js": "11.8.0", "highlight.js": "11.9.0",
"ibantools": "^4.3.5", "ibantools": "^4.3.8",
"pdfjs-dist": "^3.11.174" "pdfjs-dist": "^4.0.379"
}, },
"devDependencies": { "devDependencies": {
"@gitzone/tsbuild": "^2.1.66", "@git.zone/tsbuild": "^2.1.72",
"@gitzone/tsbundle": "^2.0.8", "@git.zone/tsbundle": "^2.0.14",
"@gitzone/tstest": "^1.0.77", "@git.zone/tstest": "^1.0.77",
"@gitzone/tswatch": "^2.0.7", "@git.zone/tswatch": "^2.0.21",
"@push.rocks/projectinfo": "^5.0.2", "@push.rocks/projectinfo": "^5.0.2",
"@push.rocks/tapbundle": "^5.0.15", "@push.rocks/tapbundle": "^5.0.15",
"@types/node": "^20.8.3" "@types/node": "^20.10.8"
}, },
"files": [ "files": [
"ts/**/*", "ts/**/*",

2473
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@design.estate/dees-catalog', name: '@design.estate/dees-catalog',
version: '1.0.226', version: '1.0.244',
description: 'website for lossless.com' description: 'website for lossless.com'
} }

View File

@ -0,0 +1,11 @@
export const dark = {
blue: '#0050b9',
blueActive: '#0069f2',
text: '#ffffff',
}
export const bright = {
blue: '#0050b9',
blueActive: '#0069f2',
text: '#333333',
}

View File

@ -93,16 +93,15 @@ export class DeesButton extends DeesElement {
} }
.button:hover { .button:hover {
cursor: pointer; background: #0050b9;
background: #039be5;
color: #ffffff; color: #ffffff;
border: 1px solid #039be5; border: 1px solid #0050b9;
border-top: 1px solid #039be5; border-top: 1px solid #0050b9;
} }
.button:active { .button:active {
background: #0277bd; background: #0069f2;
border-top: 1px solid #0277bd; border-top: 1px solid #0069f2;
} }
.button.disabled { .button.disabled {
@ -146,8 +145,8 @@ export class DeesButton extends DeesElement {
} }
.button.pending { .button.pending {
border: 1px dashed ${cssManager.bdTheme('#0277bd', '#0277bd70')}; border: 1px dashed ${cssManager.bdTheme('#0069f2', '#0069f270')};
background: ${cssManager.bdTheme('#0277bd', '#0277bd70')}; background: ${cssManager.bdTheme('#0069f2', '#0069f270')};
color: #fff; color: #fff;
} }

View File

@ -0,0 +1,41 @@
import { html } from '@design.estate/dees-element';
export const demoFunc = () => html`
<style>
.demoContainer {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
background: #222;
}
</style>
<div class="demoContainer">
<dees-chips
selectionMode="none"
.selectableChips=${[
{ key: 'account1', value: 'Payment Account 1' },
{ key: 'account2', value: 'PaymentAccount2' },
{ key: 'account3', value: 'Payment Account 3' },
]}
></dees-chips>
<dees-chips
selectionMode="single"
chipsAreRemovable
.selectableChips=${[
{ key: 'account1', value: 'Payment Account 1' },
{ key: 'account2', value: 'PaymentAccount2' },
{ key: 'account3', value: 'Payment Account 3' },
]}
></dees-chips>
<dees-chips
selectionMode="multiple"
.selectableChips=${[
{ key: 'account1', value: 'Payment Account 1' },
{ key: 'account2', value: 'PaymentAccount2' },
{ key: 'account3', value: 'Payment Account 3' },
]}
></dees-chips>
</div>
`;

View File

@ -11,6 +11,7 @@ import {
} from '@design.estate/dees-element'; } from '@design.estate/dees-element';
import * as domtools from '@design.estate/dees-domtools'; import * as domtools from '@design.estate/dees-domtools';
import { demoFunc } from './dees-chips.demo.js';
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
@ -18,30 +19,32 @@ declare global {
} }
} }
type Tag = { key: string; value: string };
@customElement('dees-chips') @customElement('dees-chips')
export class DeesChips extends DeesElement { export class DeesChips extends DeesElement {
public static demo = () => html` public static demo = demoFunc;
<dees-chips .selectableChips=${['Payment Account 1', 'PaymentAccount2', 'Payment Account 3']}></dees-chips>
<dees-chips selectionMode="multiple" .selectableChips=${['Payment Account 1', 'PaymentAccount2', 'Payment Account 3']}></dees-chips>
`;
@property() @property()
public selectionMode: 'single' | 'multiple' = 'single'; public selectionMode: 'none' | 'single' | 'multiple' = 'single';
@property({ @property({
type: Array type: Boolean,
}) })
public selectableChips: string[] = []; public chipsAreRemovable: boolean = false;
@property({
type: Array,
})
public selectableChips: Tag[] = [];
@property() @property()
public selectedChip: string = null; public selectedChip: Tag = null;
@property({ @property({
type: Array type: Array,
}) })
public selectedChips: string[] = []; public selectedChips: Tag[] = [];
constructor() { constructor() {
super(); super();
@ -50,47 +53,87 @@ export class DeesChips extends DeesElement {
public static styles = [ public static styles = [
cssManager.defaultStyles, cssManager.defaultStyles,
css` css`
:host { :host {
display: block; display: block;
box-sizing: border-box; box-sizing: border-box;
} }
.mainbox { .mainbox {
user-select: none;
} }
.chip { .chip {
background: #494949; border-top: ${cssManager.bdTheme('1px solid #CCC', '1px solid #444')};
display: inline-block; background: #333333;
padding: 8px 12px; display: inline-flex;
font-size: 14px; height: 20px;
line-height: 20px;
padding: 0px 8px;
font-size: 12px;
color: #fff; color: #fff;
border-radius: 40px; border-radius: 40px;
margin-right: 4px; margin-right: 4px;
margin-bottom: 8px; margin-bottom: 4px;
position: relative;
overflow: hidden;
box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.3);
} }
.chip:hover { .chip:hover {
background: #666666; background: #666666;
cursor: pointer;
} }
.chip.selected { .chip.selected {
background: #00A3FF; background: #00a3ff;
} }
.chipKey {
background: rgba(0, 0, 0, 0.3);
height: 100%;
display: inline-block;
margin-left: -8px;
padding-left: 8px;
padding-right: 8px;
margin-right: 8px;
}
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;
}
`, `,
]; ];
public render(): TemplateResult { public render(): TemplateResult {
return html` return html`
<div class="mainbox"> <div class="mainbox">
${this.selectableChips.map(chipArg => html` ${this.selectableChips.map(
<div @click=${() => this.selectChip(chipArg)} class="chip ${this.selectedChip === chipArg || this.selectedChips.includes(chipArg) ? 'selected' : ''}"> (chip) => html`
${chipArg} <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> </div>
`)} `
)}
</div> </div>
`; `;
} }
@ -102,23 +145,51 @@ export class DeesChips extends DeesElement {
} }
} }
public async selectChip(chipArg: string) { private isSelected(chip: Tag): boolean {
if (this.selectionMode === 'single') { if (this.selectionMode === 'single') {
if (this.selectedChip === chipArg) { return this.selectedChip?.key === chip.key;
} else {
return this.selectedChips.some((selected) => selected.key === chip.key);
}
}
public async selectChip(chip: Tag) {
if (this.selectionMode === 'none') {
return;
}
if (this.selectionMode === 'single') {
if (this.isSelected(chip)) {
this.selectedChip = null; this.selectedChip = null;
this.selectedChips = []; this.selectedChips = [];
} else { } else {
this.selectedChip = chipArg; this.selectedChip = chip;
this.selectedChips = [chipArg]; this.selectedChips = [chip];
} }
} else if(this.selectionMode === 'multiple') { } else if (this.selectionMode === 'multiple') {
if (this.selectedChips.includes(chipArg)) { if (this.isSelected(chip)) {
this.selectedChips = this.selectedChips.filter(chipArg2 => chipArg !== chipArg2) this.selectedChips = this.selectedChips.filter((selected) => selected.key !== chip.key);
} else { } else {
this.selectedChips.push(chipArg); this.selectedChips = [...this.selectedChips, chip];
} }
this.requestUpdate(); this.requestUpdate();
} }
console.log(this.selectedChips); console.log(this.selectedChips);
} }
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();
}
} }

View File

@ -1,5 +1,5 @@
import { html } from '@design.estate/dees-element'; import { html } from '@design.estate/dees-element';
import * as plugins from './plugins.js'; import * as plugins from './00plugins.js';
import { DeesContextmenu } from './dees-contextmenu.js'; import { DeesContextmenu } from './dees-contextmenu.js';

View File

@ -1,5 +1,5 @@
import { demoFunc } from './dees-contextmenu.demo.js'; import { demoFunc } from './dees-contextmenu.demo.js';
import * as plugins from './plugins.js'; import * as plugins from './00plugins.js';
import { import {
customElement, customElement,
html, html,
@ -27,7 +27,42 @@ export class DeesContextmenu extends DeesElement {
public static demo = demoFunc public static demo = demoFunc
// STATIC // STATIC
// This will store all the accumulated menu items
public static contextMenuDeactivated = false;
public static accumulatedMenuItems: plugins.tsclass.website.IMenuItem[] = [];
// Add a global event listener for the right-click context menu
public static initializeGlobalListener() {
document.addEventListener('contextmenu', (event: MouseEvent) => {
if (this.contextMenuDeactivated) {
return;
}
event.preventDefault();
// Get the target element of the right-click
let target: EventTarget | null = event.target;
// Clear previously accumulated items
DeesContextmenu.accumulatedMenuItems = [];
// Traverse up the DOM tree to accumulate menu items
while (target) {
if ((target as any).getContextMenuItems) {
DeesContextmenu.accumulatedMenuItems.push(...(target as any).getContextMenuItems());
}
target = (target as Node).parentNode;
}
// Open the context menu with the accumulated items
DeesContextmenu.openContextMenuWithOptions(event, DeesContextmenu.accumulatedMenuItems);
});
}
// allows opening of a contextmenu with options
public static async openContextMenuWithOptions(eventArg: MouseEvent, menuItemsArg: plugins.tsclass.website.IMenuItem[]) { public static async openContextMenuWithOptions(eventArg: MouseEvent, menuItemsArg: plugins.tsclass.website.IMenuItem[]) {
if (this.contextMenuDeactivated) {
return;
}
eventArg.preventDefault(); eventArg.preventDefault();
eventArg.stopPropagation(); eventArg.stopPropagation();
const contextMenu = new DeesContextmenu(); const contextMenu = new DeesContextmenu();
@ -49,6 +84,7 @@ export class DeesContextmenu extends DeesElement {
contextMenu.style.transform = 'scale(1,1)'; contextMenu.style.transform = 'scale(1,1)';
} }
// INSTANCE
@property({ @property({
type: Array, type: Array,
}) })
@ -59,6 +95,9 @@ export class DeesContextmenu extends DeesElement {
super(); super();
} }
/**
* STATIC STYLES
*/
public static styles = [ public static styles = [
cssManager.defaultStyles, cssManager.defaultStyles,
css` css`
@ -91,12 +130,10 @@ export class DeesContextmenu extends DeesElement {
} }
.mainbox .menuitem:hover { .mainbox .menuitem:hover {
cursor: pointer;
background: ${cssManager.bdTheme('#00000010', '#ffffff10')}; background: ${cssManager.bdTheme('#00000010', '#ffffff10')};
} }
.mainbox .menuitem:active { .mainbox .menuitem:active {
cursor: pointer;
background: #ffffff05; background: #ffffff05;
} }
`, `,
@ -115,10 +152,11 @@ export class DeesContextmenu extends DeesElement {
})} })}
${this.menuItems.length === 0 ? html` ${this.menuItems.length === 0 ? html`
<div class="menuitem" @click=${() => { <div class="menuitem" @click=${() => {
alert('No menu items...') DeesContextmenu.contextMenuDeactivated = true;
this.destroy();
}}> }}>
<dees-icon .iconFA=${'xmark'}></dees-icon <dees-icon .iconFA=${'xmark'}></dees-icon
>No menu item present... >Deactivate Contextmenu globally.
</div> </div>
` : html``} ` : html``}
</div> </div>
@ -144,3 +182,5 @@ export class DeesContextmenu extends DeesElement {
this.parentElement.removeChild(this); this.parentElement.removeChild(this);
} }
} }
DeesContextmenu.initializeGlobalListener();

View File

@ -61,51 +61,22 @@ export class DeesDataviewCodebox extends DeesElement {
} }
.appbar { .appbar {
position: relative;
color: ${cssManager.bdTheme('#333', '#ccc')}; color: ${cssManager.bdTheme('#333', '#ccc')};
background: ${cssManager.bdTheme('#ffffff', '#161616')}; background: ${cssManager.bdTheme('#ffffff', '#161616')};
border-bottom: 1px solid ${cssManager.bdTheme('#eeeeeb', '#222222')}; border-bottom: 1px solid ${cssManager.bdTheme('#eeeeeb', '#222222')};
height: 24px; height: 24px;
display: flex;
font-size: 12px; font-size: 12px;
line-height: 24px; line-height: 24px;
} justify-content: center;
align-items: center;
.appbar .macControls {
position: absolute;
top: 6px;
left: 20px;
width: 200px;
display: grid;
grid-template-columns: 24px 24px 24px;
}
.appbar .macControls div {
width: 12px;
height: 12px;
display: inline-block;
border-radius: 50%;
margin: 0px;
padding: 0px;
cursor: pointer;
background: #222222;
}
.appbar .macControls div.close {
background: #ff5f57;
}
.appbar .macControls div.toDock {
background: #ffbd2e;
}
.appbar .macControls div.minMax {
background: #27c93f;
}
.appbar .macControls div:hover {
background: #333333;
} }
.appbar .fileName { .appbar .fileName {
line-height: inherit;
position: relative;
flex: 1;
text-align: center; text-align: center;
} }
@ -209,12 +180,9 @@ export class DeesDataviewCodebox extends DeesElement {
}}" }}"
> >
<div class="appbar"> <div class="appbar">
<div class="macControls"> <dees-windowcontrols type="mac" position="left"></dees-windowcontrols>
<div class="close"></div>
<div class="toDock"></div>
<div class="minMax"></div>
</div>
<div class="fileName">index.ts</div> <div class="fileName">index.ts</div>
<dees-windowcontrols type="mac" position="right"></dees-windowcontrols>
</div> </div>
<div class="codegrid"> <div class="codegrid">
<div class="lineNumbers"> <div class="lineNumbers">

View File

@ -61,7 +61,6 @@ export class DeesDataviewStatusobject extends DeesElement {
} }
.copyMain { .copyMain {
cursor: pointer;
font-size: 10px; font-size: 10px;
font-weight: 600; font-weight: 600;
text-transform: uppercase; text-transform: uppercase;

View File

@ -20,9 +20,30 @@ export const demoFunc = () => html`
form.setStatus('success', 'authenticated!'); form.setStatus('success', 'authenticated!');
}} }}
> >
<dees-input-dropdown
.label=${'title'}
.options=${[
{ option: 'option 1', key: 'option1' },
{ option: 'option 2', key: 'option2' },
{ option: 'option 3', key: 'option3' },
]}
></dees-input-dropdown>
<dees-input-multiselect
.label=${'title'}
.options=${[
{ option: 'option 1', key: 'option1' },
{ option: 'option 2', key: 'option2' },
{ option: 'option 3', key: 'option3' },
]}></dees-input-multiselect>
<dees-input-typelist></dees-input-typelist>
<dees-input-text .required="${true}" key="hello1" label="a text"></dees-input-text> <dees-input-text .required="${true}" key="hello1" label="a text"></dees-input-text>
<dees-input-text .required="${true}" key="hello2" label="also a text"></dees-input-text> <dees-input-text .required="${true}" key="hello2" label="also a text"></dees-input-text>
<dees-input-text .required="${true}" key="hello3" label="a password" isPasswordBool></dees-input-text> <dees-input-text
.required="${true}"
key="hello3"
label="a password"
isPasswordBool
></dees-input-text>
<dees-input-checkbox <dees-input-checkbox
.required="${true}" .required="${true}"
key="hello3" key="hello3"

View File

@ -45,7 +45,7 @@ export class DeesForm extends DeesElement {
public static demo = demoFunc; public static demo = demoFunc;
public name: string = 'myform'; public name: string = 'myform';
public changeSubject = new domtools.rxjs.Subject(); public changeSubject = new domtools.plugins.smartrx.rxjs.Subject();
public readyDeferred = domtools.plugins.smartpromise.defer(); public readyDeferred = domtools.plugins.smartpromise.defer();
public render(): TemplateResult { public render(): TemplateResult {

View File

@ -50,6 +50,7 @@ import {
faEyeSlash as faEyeSlashSolid, faEyeSlash as faEyeSlashSolid,
faFileInvoice as faFileInvoiceSolid, faFileInvoice as faFileInvoiceSolid,
faFileInvoiceDollar as faFileInvoiceDollarSolid, faFileInvoiceDollar as faFileInvoiceDollarSolid,
faGear as faGearSolid,
faGrip as faGripSolid, faGrip as faGripSolid,
faMessage as faMessageSolid, faMessage as faMessageSolid,
faMoneyCheckDollar as faMoneyCheckDollarSolid, faMoneyCheckDollar as faMoneyCheckDollarSolid,
@ -93,6 +94,7 @@ export const faIcons = {
eyeSlash: faEyeSlashSolid, eyeSlash: faEyeSlashSolid,
fileInvoice: faFileInvoiceSolid, fileInvoice: faFileInvoiceSolid,
fileInvoiceDoller: faFileInvoiceDollarSolid, fileInvoiceDoller: faFileInvoiceDollarSolid,
gear: faGearSolid,
grip: faGripSolid, grip: faGripSolid,
message: faMessageRegular, message: faMessageRegular,
messageSolid: faMessageSolid, messageSolid: faMessageSolid,

View File

@ -22,7 +22,7 @@ export class DeesInputCheckbox extends DeesElement {
public static demo = () => html`<dees-input-checkbox></dees-input-checkbox>`; public static demo = () => html`<dees-input-checkbox></dees-input-checkbox>`;
// INSTANCE // INSTANCE
public changeSubject = new domtools.rxjs.Subject(); public changeSubject = new domtools.plugins.smartrx.rxjs.Subject();
@property({ @property({
type: String, type: String,
@ -62,7 +62,10 @@ export class DeesInputCheckbox extends DeesElement {
display: block; display: block;
position: relative; position: relative;
margin: 20px 0px; margin: 20px 0px;
cursor: pointer; cursor: default;
}
:host(:hover) {
filter: ${cssManager.bdTheme('brightness(0.95)', 'brightness(1.1)')};
} }
.maincontainer { .maincontainer {
@ -100,8 +103,8 @@ export class DeesInputCheckbox extends DeesElement {
} }
.checkbox.selected { .checkbox.selected {
background: #039BE5; background: #0050b9;
border: 1px solid #039BE5; border: 1px solid #0050b9;
} }
.checkbox.disabled { .checkbox.disabled {

View File

@ -0,0 +1,27 @@
import { html } from '@design.estate/dees-element';
export const demoFunc = () => html`
<dees-input-dropdown
.options=${[
{option: 'option 1', key: 'option1'},
{option: 'option 2', key: 'option2'},
{option: 'option 3', key: 'option3'}
]}
></dees-input-dropdown>
<dees-input-dropdown
.enableSearch=${false}
.options=${[
{option: 'option 1', key: 'option1'},
{option: 'option 2', key: 'option2'},
{option: 'option 3', key: 'option3'}
]}
></dees-input-dropdown>
<div style="height: 300px"></div>
<dees-input-dropdown
.options=${[
{option: 'option 1', key: 'option1'},
{option: 'option 2', key: 'option2'},
{option: 'option 3', key: 'option3'}
]}
></dees-input-dropdown>
`

View File

@ -1,5 +1,17 @@
import { customElement, DeesElement, type TemplateResult, property, html, css, cssManager, type CSSResult, } from '@design.estate/dees-element'; import {
customElement,
DeesElement,
type TemplateResult,
property,
state,
html,
css,
cssManager,
type CSSResult,
} from '@design.estate/dees-element';
import * as domtools from '@design.estate/dees-domtools'; import * as domtools from '@design.estate/dees-domtools';
import { demoFunc } from './dees-input-dropdown.demo.js';
import { DeesWindowLayer } from './dees-windowlayer.js';
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
@ -9,18 +21,10 @@ declare global {
@customElement('dees-input-dropdown') @customElement('dees-input-dropdown')
export class DeesInputDropdown extends DeesElement { export class DeesInputDropdown extends DeesElement {
public static demo = () => html` public static demo = demoFunc;
<dees-input-dropdown
.options=${[
{option: 'option 1', key: 'option1'},
{option: 'option 2', key: 'option2'},
{option: 'option 3', key: 'option3'}
]}
></dees-input-dropdown>
`
// INSTANCE // INSTANCE
public changeSubject = new domtools.rxjs.Subject(); public changeSubject = new domtools.plugins.smartrx.rxjs.Subject();
@property({ @property({
type: String, type: String,
@ -32,25 +36,38 @@ export class DeesInputDropdown extends DeesElement {
public key: string; public key: string;
@property() @property()
public options: {option: string, key: string, payload?: any}[] = []; public options: { option: string; key: string; payload?: any }[] = [];
@property() @property()
public selectedOption: {option: string, key: string, payload?: any} = { public selectedOption: { option: string; key: string; payload?: any } = null;
key: null,
option: null,
payload: null
};
@property({ @property({
type: Boolean type: Boolean,
}) })
public required: boolean = false; public required: boolean = false;
@property({ @property({
type: Boolean type: Boolean,
})
public enableSearch: boolean = true;
@property({
type: Boolean,
}) })
public disabled: boolean = false; public disabled: boolean = false;
@state()
public opensToTop: boolean = false;
@state()
private filteredOptions: { option: string; key: string; payload?: any }[] = [];
@state()
private highlightedIndex: number = 0;
@state()
public isOpened = false;
public static styles = [ public static styles = [
cssManager.defaultStyles, cssManager.defaultStyles,
css` css`
@ -59,10 +76,11 @@ export class DeesInputDropdown extends DeesElement {
} }
:host { :host {
font-family: Roboto;
position: relative; position: relative;
display: block; display: block;
height: 40px;
color: ${cssManager.bdTheme('#222', '#fff')}; color: ${cssManager.bdTheme('#222', '#fff')};
margin-bottom: 24px;
} }
.maincontainer { .maincontainer {
@ -71,106 +89,283 @@ export class DeesInputDropdown extends DeesElement {
.label { .label {
font-size: 14px; font-size: 14px;
margin-bottom: 15px; margin-bottom: 4px;
} }
.selectedBox { .selectedBox {
cursor: pointer; user-select: none;
position: relative; position: relative;
max-width: 420px; max-width: 420px;
height: 40px; height: 40px;
line-height: 40px; line-height: 40px;
padding: 0px 8px; padding: 0px 8px;
z-index: 0px; background: ${cssManager.bdTheme('#fafafa', '#222222')};
background: ${cssManager.bdTheme('#ffffff', '#333333')};
box-shadow: ${cssManager.bdTheme('0px 1px 4px rgba(0,0,0,0.3)', 'none')}; box-shadow: ${cssManager.bdTheme('0px 1px 4px rgba(0,0,0,0.3)', 'none')};
border-radius: 3px; border-radius: 3px;
border-top: 1px solid #CCCCCC00; border-top: ${cssManager.bdTheme('1px solid #CCC', '1px solid #444')};
border-bottom: 1px solid #66666600; border-bottom: ${cssManager.bdTheme('1px solid #CCC', '1px solid #333')};
transition: all 0.2s ease;
} }
.selectedBox.show { .selectedBox:hover {
border-top: 1px solid ${cssManager.bdTheme('#ffffff', '#666666')}; filter: ${cssManager.bdTheme('brightness(0.95)', 'brightness(1.1)')};
border-bottom: 1px solid ${cssManager.bdTheme('#fafafa', '#222222')}; }
.accentBottom {
filter: none !important;
}
.accentTop {
filter: none !important;
} }
.selectionBox { .selectionBox {
will-change:transform; will-change: transform;
pointer-events: none; pointer-events: none;
cursor: pointer;
transition: all 0.2s ease; transition: all 0.2s ease;
opacity: 0; opacity: 0;
position: relative;
background: ${cssManager.bdTheme('#ffffff', '#222222')}; background: ${cssManager.bdTheme('#ffffff', '#222222')};
max-width: 420px; max-width: 420px;
box-shadow: 0px 0px 5px rgba(0,0,0,0.2); box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2);
min-height: 40px; min-height: 40px;
margin-top: -40px; border-radius: 8px;
z-index: 100; padding: 4px 8px;
border-radius: 3px; position: absolute;
padding: 4px; user-select: none;
transform: scale(0.99,0.99); }
.selectionBox.top {
transform: translate(0px, 4px);
}
.selectionBox.bottom {
transform: translate(0px, -4px);
} }
.selectionBox.show { .selectionBox.show {
pointer-events: all; pointer-events: all;
transform: scale(1, 1) translate(0px, 0px);
opacity: 1; opacity: 1;
transform: scale(1,1); box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.8);
} }
.option { .option {
transition: all 0.1s; transition: all 0.1s;
line-height: 40px; line-height: 32px;
padding: 0px 4px; padding: 0px 4px;
border-radius: 3px; border-radius: 3px;
margin: 4px 0px;
}
.option.highlighted {
border-left: 2px solid #0069f2;
padding-left: 6px;
background: #ffffff20;
} }
.option:hover { .option:hover {
color: #fff; color: #fff;
padding-left: 8px; padding-left: 8px;
background: #0277bd; background: #0069f2;
} }
`
] .search.top {
padding-top: 4px;
}
.search.bottom {
padding-bottom: 4px;
}
.search input {
display: block;
background: none;
border: none;
height: 24px;
color: inherit;
text-align: left;
font-size: 12px;
font-weight: 600;
width: 100%;
margin: auto;
}
.search.top input {
border-bottom: 1px dotted #333;
}
.search.bottom input {
border-top: 1px dotted #333;
}
.search input:focus {
outline: none;
}
`,
];
public render(): TemplateResult { public render(): TemplateResult {
return html` return html`
${domtools.elementBasic.styles} <div class="maincontainer" @keydown="${this.isOpened ? this.handleKeyDown : undefined}">
<style> ${this.label ? html`<div class="label">${this.label}</div>` : html``}
</style>
<div class="maincontainer">
<div class="selectedBox show" @click="${event => {this.toggleSelectionBox();}}">
${this.selectedOption?.option}
</div>
<div class="selectionBox"> <div class="selectionBox">
${this.options.map(option => { ${this.enableSearch && !this.opensToTop
return html` ? html`
<div class="option" @click=${() => {this.updateSelection(option);}}>${option.option}</div> <div class="search top">
<input type="text" placeholder="Search" @input="${this.handleSearch}" />
</div>
` `
: null}
${this.filteredOptions.map((option, index) => {
const isHighlighted = this.highlightedIndex === index;
return html`
<div
class="option ${isHighlighted ? 'highlighted' : ''}"
@click=${() => {
this.updateSelection(option);
}}
>
${option.option}
</div>
`;
})} })}
${this.enableSearch && this.opensToTop
? html`
<div class="search bottom">
<input type="text" placeholder="Search" @input="${this.handleSearch}" />
</div>
`
: null}
</div>
<div
class="selectedBox"
@click="${(event) => {
if (!this.isElevated) {
this.toggleSelectionBox();
} else {
this.updateSelection(this.selectedOption);
}
}}"
>
${this.selectedOption?.option || 'Select...'}
</div> </div>
</div> </div>
`; `;
} }
firstUpdated() { firstUpdated() {
this.selectedOption = this.options[0] || null; this.selectedOption = this.selectedOption || null;
this.filteredOptions = this.options; // Initialize filteredOptions
} }
public async updateSelection(selectedOption) { public async updateSelection(selectedOption) {
this.selectedOption = selectedOption; this.selectedOption = selectedOption;
this.dispatchEvent(new CustomEvent('selectedOption', { this.dispatchEvent(
new CustomEvent('selectedOption', {
detail: selectedOption, detail: selectedOption,
bubbles: true bubbles: true,
})); })
);
if (this.isElevated) {
this.toggleSelectionBox(); this.toggleSelectionBox();
}
this.changeSubject.next(this); this.changeSubject.next(this);
} }
public toggleSelectionBox() { private isElevated: boolean = false;
this.shadowRoot.querySelector('.selectedBox').classList.toggle('show'); private windowOverlay: DeesWindowLayer;
this.shadowRoot.querySelector('.selectionBox').classList.toggle('show'); public async toggleSelectionBox() {
this.isOpened = !this.isOpened;
const domtoolsInstance = await this.domtoolsPromise;
const selectedBox: HTMLElement = this.shadowRoot.querySelector('.selectedBox');
const selectionBox: HTMLElement = this.shadowRoot.querySelector('.selectionBox');
if (!this.isElevated) {
this.windowOverlay = await DeesWindowLayer.createAndShow({
blur: false,
});
const elevatedDropdown = new DeesInputDropdown();
elevatedDropdown.isElevated = true;
elevatedDropdown.label = this.label;
elevatedDropdown.enableSearch = this.enableSearch;
elevatedDropdown.required = this.required;
elevatedDropdown.disabled = this.disabled;
elevatedDropdown.style.position = 'fixed';
elevatedDropdown.style.top = this.getBoundingClientRect().top + 'px';
elevatedDropdown.style.left = this.getBoundingClientRect().left + 'px';
elevatedDropdown.style.width = this.clientWidth + 'px';
elevatedDropdown.options = this.options;
elevatedDropdown.selectedOption = this.selectedOption;
elevatedDropdown.highlightedIndex = elevatedDropdown.selectedOption ? elevatedDropdown.options.indexOf(
elevatedDropdown.options.find((option) => option.key === this.selectedOption.key)
) : -1;
console.log(elevatedDropdown.options);
console.log(elevatedDropdown.selectedOption);
console.log(elevatedDropdown.highlightedIndex);
this.windowOverlay.appendChild(elevatedDropdown);
await domtoolsInstance.convenience.smartdelay.delayFor(0);
elevatedDropdown.toggleSelectionBox();
const destroyOverlay = async () => {
(elevatedDropdown.shadowRoot.querySelector('.selectionBox') as HTMLElement).style.opacity =
'0';
elevatedDropdown.removeEventListener('selectedOption', handleSelection);
this.windowOverlay.removeEventListener('clicked', destroyOverlay);
this.windowOverlay.destroy();
};
const handleSelection = async (event) => {
await this.updateSelection(elevatedDropdown.selectedOption);
destroyOverlay();
};
elevatedDropdown.addEventListener('selectedOption', handleSelection);
this.windowOverlay.addEventListener('clicked', destroyOverlay);
} else {
if (!selectionBox.classList.contains('show')) {
selectionBox.style.width = selectedBox.clientWidth + 'px';
const spaceData = selectedBox.getBoundingClientRect();
if (300 > window.innerHeight - spaceData.bottom) {
this.opensToTop = true;
selectedBox.classList.add('accentTop');
selectionBox.classList.add('top');
selectionBox.style.bottom = selectedBox.clientHeight + 2 + 'px';
} else {
selectedBox.classList.add('accentBottom');
selectionBox.classList.add('bottom');
this.opensToTop = false;
const labelOffset = this.label ? 24 : 0;
selectionBox.style.top = selectedBox.clientHeight + labelOffset + 'px';
}
await domtoolsInstance.convenience.smartdelay.delayFor(0);
const searchInput = selectionBox.querySelector('input');
searchInput?.focus();
selectionBox.classList.add('show');
} else {
selectedBox.style.pointerEvents = 'none';
selectionBox.classList.remove('show');
// selectedBox.style.opacity = '0';
}
}
}
private handleSearch(event: Event): void {
const searchTerm = (event.target as HTMLInputElement).value.toLowerCase();
this.filteredOptions = this.options.filter((option) =>
option.option.toLowerCase().includes(searchTerm)
);
this.highlightedIndex = 0; // Reset highlighted index
}
private handleKeyDown(event: KeyboardEvent): void {
if (!this.isOpened) {
console.log('discarded key event. Check why this function is called.');
return;
}
const key = event.key;
const maxIndex = this.filteredOptions.length - 1;
if (key === 'ArrowDown') {
this.highlightedIndex = this.highlightedIndex + 1 > maxIndex ? 0 : this.highlightedIndex + 1;
event.preventDefault();
} else if (key === 'ArrowUp') {
this.highlightedIndex = this.highlightedIndex - 1 < 0 ? maxIndex : this.highlightedIndex - 1;
event.preventDefault();
} else if (key === 'Enter') {
this.updateSelection(this.filteredOptions[this.highlightedIndex]);
event.preventDefault();
}
} }
} }

View File

@ -22,7 +22,7 @@ export class DeesInputFileupload extends DeesElement {
public static demo = () => html`<dees-input-fileupload .label=${'Attachments'}></dees-input-fileupload>`; public static demo = () => html`<dees-input-fileupload .label=${'Attachments'}></dees-input-fileupload>`;
// INSTANCE // INSTANCE
public changeSubject = new domtools.rxjs.Subject(); public changeSubject = new domtools.plugins.smartrx.rxjs.Subject();
@property({ @property({
type: String, type: String,
@ -88,7 +88,6 @@ export class DeesInputFileupload extends DeesElement {
.uploadButton { .uploadButton {
position: relative; position: relative;
cursor: pointer;
padding: 8px; padding: 8px;
max-width: 600px; max-width: 600px;
background: ${cssManager.bdTheme('#fafafa', '#333333')}; background: ${cssManager.bdTheme('#fafafa', '#333333')};

View File

@ -48,7 +48,7 @@ export class DeesInputIban extends DeesElement {
}) })
public value = ''; public value = '';
public changeSubject = new domtools.rxjs.Subject<DeesInputIban>(); public changeSubject = new domtools.plugins.smartrx.rxjs.Subject<DeesInputIban>();
public render(): TemplateResult { public render(): TemplateResult {
return html` return html`

View File

@ -0,0 +1,14 @@
import { html } from '@design.estate/dees-element';
export const demoFunc = () => html`
<dees-input-multitoggle
.options=${['option 1', 'option 2', 'a longer option with multiple words']}
.selectedOption=${'option 2'}
></dees-input-multitoggle>
<dees-input-multitoggle
.type=${'boolean'}
.booleanTrueName=${'enabled'}
.booleanFalseName=${'disabled'}
.selectedOption=${'true'}
></dees-input-multitoggle>
`;

View File

@ -0,0 +1,121 @@
import {
customElement,
DeesElement,
type TemplateResult,
state,
html,
domtools,
property,
css,
cssManager,
} from '@design.estate/dees-element';
const { demoFunc } = await import('./dees-input-multitoggle.demo.js');
@customElement('dees-input-multitoggle')
export class DeesInputMultitoggle extends DeesElement {
public static demo = demoFunc;
@property()
type: 'boolean' | 'multi' | 'single' = 'multi';
@property()
booleanTrueName: string = 'true';
@property()
booleanFalseName: string = 'false';
@property({
type: Array,
})
options: string[] = [];
@property()
selectedOption: string = '';
@property()
boolValue: boolean = false;
public static styles = [
cssManager.defaultStyles,
css`
:host {
color: ${cssManager.bdTheme('#333', '#fff')};
user-select: none;
}
.selections {
position: relative;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
background: #333;
width: min-content;
border-radius: 20px;
height: 40px;
}
.option {
color: #CCC;
position: relative;
padding: 0px 16px;
line-height: 40px;
cursor: default;
width: min-content; /* Make the width as per the content */
white-space: nowrap; /* Prevent text wrapping */
transition: all 0.1s;
}
.option:hover {
color: #fff;
}
.indicator {
opacity: 0;
position: absolute;
height: 32px;
left: 4px;
top: 4px;
border-radius: 16px;
background: #0050b9;
min-width: 36px;
}
`,
];
public render(): TemplateResult {
return html`
<div class="label">MultiSelect</div>
<div class="mainbox">
<div class="selections">
<div class="indicator"></div>
${this.options.map((option) => html` <div class="option" @click=${() => this.handleSelection(option)}>${option}</div> `)}
</div>
</div>
`;
}
public async firstUpdated() {
if (this.type === 'boolean') {
this.options = [this.booleanTrueName || 'true', this.booleanFalseName || 'false'];
}
this.setIndicator();
}
public async handleSelection(optionArg: string) {
this.selectedOption = optionArg;
this.setIndicator();
}
public async setIndicator() {
const indicator: HTMLDivElement = this.shadowRoot.querySelector('.indicator');
const option: HTMLDivElement = this.shadowRoot.querySelector(`.option:nth-child(${this.options.indexOf(this.selectedOption) + 2})`);
if (indicator && option) {
indicator.style.width = `${option.clientWidth - 8}px`;
indicator.style.left = `${option.offsetLeft + 4}px`;
indicator.style.opacity = '1';
}
setTimeout(() => {
indicator.style.transition = 'all 0.1s';
}, 100);
}
}

View File

@ -12,7 +12,7 @@ export class DeesInputQuantitySelector extends DeesElement {
public static demo = () => html`<dees-input-quantityselector></dees-input-quantityselector>`; public static demo = () => html`<dees-input-quantityselector></dees-input-quantityselector>`;
// INSTANCE // INSTANCE
public changeSubject = new domtools.rxjs.Subject(); public changeSubject = new domtools.plugins.smartrx.rxjs.Subject();
@property() @property()
public label: string = 'Label'; public label: string = 'Label';
@ -85,7 +85,6 @@ export class DeesInputQuantitySelector extends DeesElement {
} }
.selector:hover { .selector:hover {
cursor: pointer;
} }
.quantity { .quantity {

View File

@ -12,7 +12,7 @@ export class DeesInputRadio extends DeesElement {
public static demo = () => html`<dees-input-radio></dees-input-radio>`; public static demo = () => html`<dees-input-radio></dees-input-radio>`;
// INSTANCE // INSTANCE
public changeSubject = new domtools.rxjs.Subject(); public changeSubject = new domtools.plugins.smartrx.rxjs.Subject();
@property({ @property({
type: String, type: String,
@ -51,7 +51,6 @@ export class DeesInputRadio extends DeesElement {
display: block; display: block;
position: relative; position: relative;
margin: 20px 0px; margin: 20px 0px;
cursor: pointer;
} }
.maincontainer { .maincontainer {
@ -91,8 +90,8 @@ export class DeesInputRadio extends DeesElement {
} }
.checkbox.selected { .checkbox.selected {
background: #039BE5; background: #0050b9;
border: 1px solid #039BE5; border: 1px solid #0050b9;
} }
.maincontainer:hover .checkbox.selected { .maincontainer:hover .checkbox.selected {

View File

@ -24,7 +24,7 @@ export class DeesInputText extends DeesElement {
`; `;
// INSTANCE // INSTANCE
public changeSubject = new domtools.rxjs.Subject<DeesInputText>(); public changeSubject = new domtools.plugins.smartrx.rxjs.Subject<DeesInputText>();
@property({ @property({
type: String, type: String,
@ -120,7 +120,7 @@ export class DeesInputText extends DeesElement {
font-size: 16px; font-size: 16px;
position: relative; position: relative;
z-index: 2; z-index: 2;
// see template for more cursor: default;
} }
input:disabled { input:disabled {
@ -133,6 +133,11 @@ export class DeesInputText extends DeesElement {
input:focus { input:focus {
outline: none; outline: none;
border-bottom: 1px solid #e4002b; border-bottom: 1px solid #e4002b;
cursor: text;
}
input:hover {
filter: ${cssManager.bdTheme('brightness(0.95)', 'brightness(1.1)')};
} }
.showPassword { .showPassword {
@ -143,10 +148,10 @@ export class DeesInputText extends DeesElement {
border-radius: 7px; border-radius: 7px;
padding: 4px 0px; padding: 4px 0px;
width: 40px; width: 40px;
z-index: 3;
} }
.showPassword:hover { .showPassword:hover {
cursor: pointer;
background: ${cssManager.bdTheme('#00000010', '#ffffff10')}; background: ${cssManager.bdTheme('#00000010', '#ffffff10')};
} }
@ -169,7 +174,7 @@ export class DeesInputText extends DeesElement {
return html` return html`
<style> <style>
input { input {
font-family: ${this.isPasswordBool ? 'monospace' : 'Inter'}; font-family: ${this.isPasswordBool ? 'monospace' : 'Roboto'};
letter-spacing: ${this.isPasswordBool ? '1px' : 'normal'}; letter-spacing: ${this.isPasswordBool ? '1px' : 'normal'};
color: ${this.goBright ? '#333' : '#ccc'}; color: ${this.goBright ? '#333' : '#ccc'};
} }

View File

@ -0,0 +1,15 @@
import { html } from '@design.estate/dees-element';
export const demoFunc = () => html`
<style>
.demoContainer {
max-width: 600px;
margin: auto;
padding: 40px;
background: #000;
}
</style>
<div class="demoContainer">
<dees-input-typelist></dees-input-typelist>
</div>
`;

View File

@ -0,0 +1,88 @@
import {
customElement,
DeesElement,
type TemplateResult,
state,
html,
domtools,
property,
css,
cssManager,
} from '@design.estate/dees-element';
const { demoFunc } = await import('./dees-input-typelist.demo.js');
@customElement('dees-input-typelist')
export class DeesInputTypelist extends DeesElement {
public static demo = demoFunc;
constructor() {
super();
}
public static styles = [
cssManager.defaultStyles,
css`
:host {
color: ${cssManager.bdTheme('#333', '#fff')}
}
.label {
font-size: 14px;
margin-bottom: 4px;
}
.mainbox {
border-radius: 3px;
background: #222;
overflow: hidden;
border-top: ${cssManager.bdTheme('1px solid #CCC', '1px solid #444')};
border-bottom: ${cssManager.bdTheme('1px solid #CCC', '1px solid #333')};
border-right: ${cssManager.bdTheme('1px solid #CCC', 'none')};
border-left: ${cssManager.bdTheme('1px solid #CCC', 'none')};
}
.tags {
padding: 16px;
cursor: default;
}
.notags {
text-align: center;
opacity: 0.5;
font-size: 12px;
}
input {
display: block;
box-sizing: border-box;
background: #181818;
width: 100%;
outline: none;
border: none;
color: inherit;
padding: 0px 16px;
overflow: hidden;
line-height: 32px;
height: 0px;
transition: height 0.2s;
}
input:focus {
height: 32px;
}
`,
];
public render(): TemplateResult {
return html`
<div class="label">Type List</div>
<div class="mainbox">
<div class="tags" @click=${() => {
this.shadowRoot.querySelector('input').focus();
}}>
<div class="notags">No tags yet</div>
</div>
<input type="text" placeholder="Type, press Enter to add it..." />
</div>
`;
}
}

View File

@ -1,4 +1,4 @@
import * as plugins from './plugins.js'; import * as plugins from './00plugins.js';
import { import {
cssManager, cssManager,
css, css,
@ -105,7 +105,6 @@ export class DeesMobilenavigation extends DeesElement {
padding: 8px; padding: 8px;
margin-left: -8px; margin-left: -8px;
margin-right: -8px; margin-right: -8px;
cursor: pointer;
border-radius: 3px; border-radius: 3px;
} }
.menuItem:hover { .menuItem:hover {

View File

@ -1,4 +1,4 @@
import * as plugins from './plugins.js'; import * as plugins from './00plugins.js';
import { demoFunc } from './dees-modal.demo.js'; import { demoFunc } from './dees-modal.demo.js';
import { import {
customElement, customElement,
@ -71,6 +71,7 @@ export class DeesModal extends DeesElement {
:host { :host {
font-family: 'Roboto', 'Inter', sans-serif; font-family: 'Roboto', 'Inter', sans-serif;
color: ${cssManager.bdTheme('#333', '#fff')}; color: ${cssManager.bdTheme('#333', '#fff')};
will-change: transform;
} }
.modalContainer { .modalContainer {
display: flex; display: flex;
@ -132,7 +133,6 @@ export class DeesModal extends DeesElement {
text-align: center; text-align: center;
font-size: 14px; font-size: 14px;
border-right: 1px solid #222; border-right: 1px solid #222;
cursor: pointer;
} }
.modal .bottomButtons .bottomButton:hover { .modal .bottomButtons .bottomButton:hover {
background: #222; background: #222;

View File

@ -57,18 +57,9 @@ export class DeesPdf extends DeesElement {
if (!DeesPdf.pdfJsReady) { if (!DeesPdf.pdfJsReady) {
const pdfJsReadyDeferred = domtools.plugins.smartpromise.defer(); const pdfJsReadyDeferred = domtools.plugins.smartpromise.defer();
DeesPdf.pdfJsReady = pdfJsReadyDeferred.promise; DeesPdf.pdfJsReady = pdfJsReadyDeferred.promise;
const loadDeferred = domtools.plugins.smartpromise.defer(); // @ts-ignore
const script = document.createElement('script'); DeesPdf.pdfjsLib = await import('https://cdn.jsdelivr.net/npm/pdfjs-dist@4.0.379/+esm');
script.addEventListener('load', () => { DeesPdf.pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdn.jsdelivr.net/npm/pdfjs-dist@4.0.379/build/pdf.worker.mjs';
console.log('pdf.js loaded!');
loadDeferred.resolve();
});
script.src = 'https:////mozilla.github.io/pdf.js/build/pdf.js';
document.getElementsByTagName('head')[0].appendChild(script);
// The workerSrc property shall be specified.
await loadDeferred.promise;
DeesPdf.pdfjsLib = window['pdfjs-dist/build/pdf'];
DeesPdf.pdfjsLib.GlobalWorkerOptions.workerSrc = '//mozilla.github.io/pdf.js/build/pdf.worker.js';
pdfJsReadyDeferred.resolve(); pdfJsReadyDeferred.resolve();
} }
await DeesPdf.pdfJsReady; await DeesPdf.pdfJsReady;

View File

@ -0,0 +1,11 @@
import { html } from '@design.estate/dees-element';
import { DeesProgressbar } from './dees-progressbar.js';
export const demoFunc = () => {
return html`
<dees-progressbar
.percentage=${50}
></dees-progressbar>
`;
}

View File

@ -0,0 +1,95 @@
import * as plugins from './00plugins.js';
import * as colors from './00colors.js';
import { demoFunc } from './dees-progressbar.demo.js';
import {
customElement,
html,
DeesElement,
property,
type TemplateResult,
cssManager,
css,
type CSSResult,
unsafeCSS,
unsafeHTML,
state,
} from '@design.estate/dees-element';
import * as domtools from '@design.estate/dees-domtools';
@customElement('dees-progressbar')
export class DeesProgressbar extends DeesElement {
// STATIC
public static demo = demoFunc;
// INSTANCE
@property({
type: Number,
})
public percentage = 0;
public static styles = [
cssManager.defaultStyles,
css`
:host {
color: ${cssManager.bdTheme(colors.bright.text, colors.dark.text)};
}
.progressBarContainer {
padding: 8px;
min-width: 200px;
}
.progressBar {
background: ${cssManager.bdTheme('#eeeeeb', '#444')};
height: 8px;
width: 100%;
border-radius: 4px;
border-top: 0.5px solid ${cssManager.bdTheme('none', '#555')};
}
.progressBarFill {
background: ${cssManager.bdTheme(colors.dark.blueActive, colors.bright.blueActive)};
height: 8px;
margin-top: -0.5px;
transition: 0.2s width;
border-radius: 4px;
width: 0px;
border-top: 0.5 solid ${cssManager.bdTheme('none', '#398fff')};
}
.progressText {
padding: 8px;
text-align: center;
}
`
];
public render() {
return html`
<div class="progressBarContainer">
<div class="progressBar">
<div class="progressBarFill"></div>
<div class="progressText">
${this.percentage}%
<div>
</div>
</div>
`
}
firstUpdated (_changedProperties: Map<string | number | symbol, unknown>): void {
super.firstUpdated(_changedProperties);
this.updateComplete.then(() => {
this.updatePercentage();
});
}
public async updatePercentage() {
const progressBarFill = this.shadowRoot.querySelector('.progressBarFill') as HTMLElement;
progressBarFill.style.width = `${this.percentage}%`;
}
updated(){
this.updatePercentage();
}
}

View File

@ -48,7 +48,7 @@ export class DeesSimpleLogin extends DeesElement {
min-height: 100px; min-height: 100px;
background: ${cssManager.bdTheme('#eeeeeb', '#111')}; background: ${cssManager.bdTheme('#eeeeeb', '#111')};
box-shadow: ${cssManager.bdTheme('0px 1px 4px rgba(0,0,0,0.3)', 'none')}; box-shadow: ${cssManager.bdTheme('0px 1px 4px rgba(0,0,0,0.3)', 'none')};
border-radius: 3px; border-radius: 8px;
padding: 24px; padding: 24px;
transition: opacity 0.3s, transform 0.3s; transition: opacity 0.3s, transform 0.3s;
} }

View File

@ -52,7 +52,6 @@ export class DeesSpeechbubble extends DeesElement {
display: block; display: block;
box-sizing: border-box; box-sizing: border-box;
color: ${cssManager.bdTheme('#333', '#fff')}; color: ${cssManager.bdTheme('#333', '#fff')};
cursor: pointer;
user-select: none; user-select: none;
} }
:host([hidden]) { :host([hidden]) {

View File

@ -99,7 +99,7 @@ export class DeesStepper extends DeesElement {
transition: all 0.7s ease-in-out; transition: all 0.7s ease-in-out;
max-width: 500px; max-width: 500px;
min-height: 300px; min-height: 300px;
border-radius: 3px; border-radius: 8px;
background: ${cssManager.bdTheme('#ffffff', '#181818')}; background: ${cssManager.bdTheme('#ffffff', '#181818')};
border-top: 1px solid ${cssManager.bdTheme('#ffffff', '#181818')}; border-top: 1px solid ${cssManager.bdTheme('#ffffff', '#181818')};
color: ${cssManager.bdTheme('#333', '#fff')}; color: ${cssManager.bdTheme('#333', '#fff')};
@ -127,6 +127,7 @@ export class DeesStepper extends DeesElement {
} }
.step .stepCounter { .step .stepCounter {
color: #999;
position: absolute; position: absolute;
top: 0px; top: 0px;
right: 0px; right: 0px;
@ -137,6 +138,8 @@ export class DeesStepper extends DeesElement {
} }
.step .goBack { .step .goBack {
color: #999;
cursor: default;
position: absolute; position: absolute;
top: 0px; top: 0px;
left: 0px; left: 0px;
@ -144,7 +147,6 @@ export class DeesStepper extends DeesElement {
font-size: 12px; font-size: 12px;
border-bottom-right-radius: 3px; border-bottom-right-radius: 3px;
background: ${cssManager.bdTheme('#00000008', '#ffffff08')}; background: ${cssManager.bdTheme('#00000008', '#ffffff08')};
cursor: pointer;
} }
.step .goBack:hover { .step .goBack:hover {

View File

@ -1,5 +1,5 @@
import { type ITableAction } from './dees-table.js'; import { type ITableAction } from './dees-table.js';
import * as plugins from './plugins.js'; import * as plugins from './00plugins.js';
import { html } from '@design.estate/dees-element'; import { html } from '@design.estate/dees-element';
interface ITableDemoData { interface ITableDemoData {

View File

@ -1,4 +1,4 @@
import * as plugins from './plugins.js'; import * as plugins from './00plugins.js';
import { demoFunc } from './dees-table.demo.js'; import { demoFunc } from './dees-table.demo.js';
import { import {
customElement, customElement,
@ -61,8 +61,8 @@ export interface ITableAction<T = any> {
} }
export interface ITableActionDataArg<T> { export interface ITableActionDataArg<T> {
item: T, item: T;
table: DeesTable<T>, table: DeesTable<T>;
} }
export type TDisplayFunction<T = any> = (itemArg: T) => object; export type TDisplayFunction<T = any> = (itemArg: T) => object;
@ -113,7 +113,7 @@ export class DeesTable<T> extends DeesElement {
return this.data; return this.data;
} }
set value(valueArg) {} set value(valueArg) {}
public changeSubject = new domtools.rxjs.Subject<DeesTable<T>>(); public changeSubject = new domtools.plugins.smartrx.rxjs.Subject<DeesTable<T>>();
// end dees-form compatibility ----------------------------------------- // end dees-form compatibility -----------------------------------------
@property({ @property({
@ -202,7 +202,6 @@ export class DeesTable<T> extends DeesElement {
.headerActions { .headerActions {
margin-left: auto; margin-left: auto;
cursor: pointer;
} }
.headerAction { .headerAction {
display: flex; display: flex;
@ -236,7 +235,7 @@ export class DeesTable<T> extends DeesElement {
text-align: left; text-align: left;
} }
tr:hover { tr:hover {
cursor: pointer;
} }
tr:hover td { tr:hover td {
background: ${cssManager.bdTheme('#22222210', '#ffffff10')}; background: ${cssManager.bdTheme('#22222210', '#ffffff10')};
@ -343,7 +342,6 @@ export class DeesTable<T> extends DeesElement {
} }
.footerActions .footerAction { .footerActions .footerAction {
cursor: pointer;
padding: 8px 16px; padding: 8px 16px;
display: flex; display: flex;
} }
@ -396,6 +394,8 @@ export class DeesTable<T> extends DeesElement {
</div> </div>
<div class="headingSeparation"></div> <div class="headingSeparation"></div>
<dees-input-text></dees-input-text>
<!-- the actual table --> <!-- the actual table -->
<style></style> <style></style>
${this.data.length > 0 ${this.data.length > 0
@ -524,7 +524,8 @@ export class DeesTable<T> extends DeesElement {
${this.getActionsForType('inRow').map( ${this.getActionsForType('inRow').map(
(actionArg) => html`<div (actionArg) => html`<div
class="action" class="action"
@click=${() => actionArg.actionFunc({ @click=${() =>
actionArg.actionFunc({
item: itemArg, item: itemArg,
table: this, table: this,
})} })}
@ -584,8 +585,7 @@ export class DeesTable<T> extends DeesElement {
`; `;
} }
public async firstUpdated() { public async firstUpdated() {}
}
public async updated(changedProperties: Map<string | number | symbol, unknown>): Promise<void> { public async updated(changedProperties: Map<string | number | symbol, unknown>): Promise<void> {
super.updated(changedProperties); super.updated(changedProperties);
@ -609,7 +609,8 @@ export class DeesTable<T> extends DeesElement {
// Get computed width // Get computed width
const width = window.getComputedStyle(cell).width; const width = window.getComputedStyle(cell).width;
if (cell.textContent.includes('Actions')) { if (cell.textContent.includes('Actions')) {
const neededWidth = this.dataActions.filter(actionArg => actionArg.type.includes('inRow')).length * 35; const neededWidth =
this.dataActions.filter((actionArg) => actionArg.type.includes('inRow')).length * 35;
cell.style.width = `${Math.max(neededWidth, 68)}px`; cell.style.width = `${Math.max(neededWidth, 68)}px`;
} else { } else {
cell.style.width = width; cell.style.width = width;
@ -620,7 +621,7 @@ export class DeesTable<T> extends DeesElement {
}); });
await done.promise; await done.promise;
} }
} };
if (cells[cells.length - 1].textContent.includes('Actions')) { if (cells[cells.length - 1].textContent.includes('Actions')) {
await handleColumnByIndex(cells.length - 1, true); await handleColumnByIndex(cells.length - 1, true);

View File

@ -0,0 +1,10 @@
import { html } from '@design.estate/dees-element';
import { DeesUpdater } from './dees-updater.js';
export const demoFunc = async () => {
const updater = await DeesUpdater.createAndShow();
setTimeout(async () => {
await updater.destroy();
}, 10000);
}

View File

@ -1,7 +1,13 @@
import { customElement, DeesElement, type TemplateResult, html, property, type CSSResult, } from '@design.estate/dees-element'; import {
customElement,
import * as domtools from '@design.estate/dees-domtools'; DeesElement,
type TemplateResult,
html,
property,
type CSSResult,
domtools,
} from '@design.estate/dees-element';
import { demoFunc } from './dees-updater.demo.js';
import './dees-windowlayer'; import './dees-windowlayer';
import { css, cssManager } from '@design.estate/dees-element'; import { css, cssManager } from '@design.estate/dees-element';
@ -14,7 +20,13 @@ declare global {
@customElement('dees-updater') @customElement('dees-updater')
export class DeesUpdater extends DeesElement { export class DeesUpdater extends DeesElement {
public static demo = () => html`<dees-updater></dees-updater>`; public static demo = demoFunc;
public static async createAndShow() {
const updater = new DeesUpdater();
document.body.appendChild(updater);
return updater;
}
@property({ @property({
type: String, type: String,
@ -38,9 +50,8 @@ export class DeesUpdater extends DeesElement {
will-change: transform; will-change: transform;
position: relative; position: relative;
background: ${cssManager.bdTheme('#eeeeeb', '#222')}; background: ${cssManager.bdTheme('#eeeeeb', '#222')};
margin: auto;
max-width: 800px; max-width: 800px;
border-radius: 3px; border-radius: 8px;
border-top: 1px solid ${cssManager.bdTheme('#eeeeeb', '#333')}; border-top: 1px solid ${cssManager.bdTheme('#eeeeeb', '#333')};
} }
@ -63,28 +74,37 @@ export class DeesUpdater extends DeesElement {
display: grid; display: grid;
grid-template-columns: 50% 50%; grid-template-columns: 50% 50%;
} }
` `,
] ];
public render(): TemplateResult { public render(): TemplateResult {
return html` return html`
<dees-windowlayer @clicked="${this.windowLayerClicked}"> <dees-windowlayer
@clicked="${this.windowLayerClicked}"
.options=${{
blur: true,
}}
>
<div class="modalContainer"> <div class="modalContainer">
<div class="headingContainer"> <div class="headingContainer">
<dees-spinner .size=${60}></dees-spinner> <dees-spinner .size=${60}></dees-spinner>
<h1>Updating the application...</h1> <h1>Updating the application...</h1>
</div> </div>
<div class="progress">
<dees-progressbar .progress=${0.5}></dees-progressbar>
</div>
<div class="buttonContainer"> <div class="buttonContainer">
<dees-button>More info</dees-button> <dees-button>More info</dees-button>
<dees-button>Changelog</dees-button> <dees-button>Changelog</dees-button>
</div> </div>
</div> </div> </dees-windowlayer
</dees-windowlayer>> >>
`; `;
} }
private windowLayerClicked() { public async destroy() {
const windowLayer = this.shadowRoot.querySelector('dees-windowlayer'); this.parentElement.removeChild(this);
windowLayer.toggleVisibility();
} }
private windowLayerClicked() {}
} }

View File

@ -0,0 +1,99 @@
import {
customElement,
DeesElement,
domtools,
type TemplateResult,
html,
property,
type CSSResult,
state,
css,
cssManager,
} from '@design.estate/dees-element';
declare global {
interface HTMLElementTagNameMap {
'dees-windowcontrols': DeesWindowControls;
}
}
@customElement('dees-windowcontrols')
export class DeesWindowControls extends DeesElement {
// STATIC
public static demo = () => html`<dees-windowcontrols></dees-windowcontrols>`;
// Instance
@property({
reflect: true,
})
public type: 'mac' | 'linux' | 'windows' = 'mac';
@property({
reflect: true,
})
public position: 'left' | 'right' = 'left';
public static styles = [
cssManager.defaultStyles,
css`
:host {
position: relative;
display: block;
box-sizing: border-box;
padding-left: 16px;
padding-right: 16px;
}
.windowControls {
height: 100%;
position: relative;
display: flex;
justify-content: center;
align-items: center;
}
.windowControls div {
width: 12px;
height: 12px;
display: inline-block;
border-radius: 50%;
margin: 0px;
padding: 0px;
background: #222222;
}
.windowControls div.close {
background: #ff5f57;
margin-right: 12px;
}
.windowControls div.toDock {
background: #ffbd2e;
margin-right: 12px;
}
.windowControls div.minMax {
background: #27c93f;
}
.windowControls div:hover {
background: #333333;
}
`,
];
public render(): TemplateResult {
return html`
${(this.type === 'mac' && this.position === 'left') ||
((this.type === 'linux' || this.type === 'windows') && this.position === 'right')
? html`
<div class="windowControls">
<div class="close"></div>
<div class="toDock"></div>
<div class="minMax"></div>
</div>
`
: html``}
`;
}
}

View File

@ -1,6 +1,4 @@
import { customElement, DeesElement, type TemplateResult, html, property, type CSSResult, state, } from '@design.estate/dees-element'; import { customElement, DeesElement, domtools, type TemplateResult, html, property, type CSSResult, state, } from '@design.estate/dees-element';
import * as domtools from '@design.estate/dees-domtools';
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
@ -66,6 +64,15 @@ export class DeesWindowLayer extends DeesElement {
pointer-events: none; pointer-events: none;
z-index: 200; z-index: 200;
} }
.slotContent {
position: fixed;
height: 100vh;
width: 100vw;
display: flex;
justify-content: center;
align-items: center;
z-index: 201;
}
.visible { .visible {
background: rgba(0, 0, 0, 0.2); background: rgba(0, 0, 0, 0.2);
@ -73,7 +80,9 @@ export class DeesWindowLayer extends DeesElement {
pointer-events: all; pointer-events: all;
} }
</style> </style>
<div @click=${this.dispatchClicked} class="windowOverlay ${this.visible ? 'visible' : null}"> <div class="windowOverlay ${this.visible ? 'visible' : null}">
</div>
<div @click=${this.dispatchClicked} class="slotContent">
<slot></slot> <slot></slot>
</div> </div>
`; `;

View File

@ -12,12 +12,15 @@ export * from './dees-input-checkbox.js';
export * from './dees-input-dropdown.js'; export * from './dees-input-dropdown.js';
export * from './dees-input-fileupload.js'; export * from './dees-input-fileupload.js';
export * from './dees-input-iban.js'; export * from './dees-input-iban.js';
export * from './dees-input-typelist.js';
export * from './dees-input-phone.js'; export * from './dees-input-phone.js';
export * from './dees-progressbar.js';
export * from './dees-input-quantityselector.js'; export * from './dees-input-quantityselector.js';
export * from './dees-input-radio.js'; export * from './dees-input-radio.js';
export * from './dees-input-text.js'; export * from './dees-input-text.js';
export * from './dees-mobilenavigation.js'; export * from './dees-mobilenavigation.js';
export * from './dees-modal.js'; export * from './dees-modal.js';
export * from './dees-input-multitoggle.js';
export * from './dees-pdf.js'; export * from './dees-pdf.js';
export * from './dees-simple-appdash.js'; export * from './dees-simple-appdash.js';
export * from './dees-simple-login.js'; export * from './dees-simple-login.js';
@ -27,4 +30,5 @@ export * from './dees-stepper.js';
export * from './dees-table.js'; export * from './dees-table.js';
export * from './dees-toast.js'; export * from './dees-toast.js';
export * from './dees-updater.js'; export * from './dees-updater.js';
export * from './dees-windowcontrols.js';
export * from './dees-windowlayer.js'; export * from './dees-windowlayer.js';

View File

@ -3,8 +3,8 @@
"experimentalDecorators": true, "experimentalDecorators": true,
"useDefineForClassFields": false, "useDefineForClassFields": false,
"target": "ES2022", "target": "ES2022",
"module": "ES2022", "module": "NodeNext",
"moduleResolution": "nodenext", "moduleResolution": "NodeNext",
"esModuleInterop": true, "esModuleInterop": true,
"verbatimModuleSyntax": true "verbatimModuleSyntax": true
}, },