Compare commits

...

40 Commits

Author SHA1 Message Date
c30736870d 1.0.203 2023-09-15 19:03:19 +02:00
cfd48de885 fix(core): update 2023-09-15 19:03:18 +02:00
462df2b648 1.0.202 2023-09-15 17:27:36 +02:00
f64da93cf9 fix(core): update 2023-09-15 17:27:35 +02:00
a55db621ef 1.0.201 2023-09-14 19:46:10 +02:00
c033bdfc3b fix(core): update 2023-09-14 19:46:09 +02:00
2610e56ec1 1.0.200 2023-09-14 19:43:27 +02:00
08aa9e3fe4 fix(core): update 2023-09-14 19:43:26 +02:00
411ae7ee07 1.0.199 2023-09-13 21:14:06 +02:00
41700c1eb1 fix(core): update 2023-09-13 21:14:05 +02:00
8d7bac9793 1.0.198 2023-09-13 21:13:48 +02:00
0229eefa4d fix(core): update 2023-09-13 21:13:47 +02:00
61f646743a 1.0.197 2023-09-13 19:15:54 +02:00
e3babde7e8 fix(core): update 2023-09-13 19:15:53 +02:00
c389e43e93 1.0.196 2023-09-13 18:12:02 +02:00
1511db4eea fix(core): update 2023-09-13 18:12:01 +02:00
d713756034 1.0.195 2023-09-13 16:46:01 +02:00
17d224332d fix(core): update 2023-09-13 16:46:00 +02:00
32dd5e769b 1.0.194 2023-09-13 16:25:55 +02:00
12ace00a90 fix(core): update 2023-09-13 16:25:54 +02:00
bbc09330c9 1.0.193 2023-09-13 13:41:57 +02:00
82ead7bd1a fix(core): update 2023-09-13 13:41:56 +02:00
f8f9b150b8 1.0.192 2023-09-13 01:37:03 +02:00
494e8b7e26 fix(core): update 2023-09-13 01:37:02 +02:00
c76d364071 1.0.191 2023-09-12 13:44:07 +02:00
760e0085f7 fix(core): update 2023-09-12 13:44:07 +02:00
6890ca1f1f 1.0.190 2023-09-12 13:42:56 +02:00
9ca000cf06 fix(core): update 2023-09-12 13:42:55 +02:00
1c0f5129a9 1.0.189 2023-09-09 13:34:46 +02:00
69e17949f4 fix(core): update 2023-09-09 13:34:46 +02:00
bcfd3495dd 1.0.188 2023-09-08 11:44:04 +02:00
03a46a72c5 fix(core): update 2023-09-08 11:44:03 +02:00
2465ce5f9b 1.0.187 2023-09-07 18:34:39 +02:00
00ac83f205 fix(core): update 2023-09-07 18:34:38 +02:00
67065b1ffb 1.0.186 2023-09-07 02:57:31 +02:00
783c10479f fix(core): update 2023-09-07 02:57:30 +02:00
d4eae1cd9e 1.0.185 2023-09-04 19:29:39 +02:00
4e674f67c5 fix(core): update 2023-09-04 19:29:39 +02:00
889a543780 1.0.184 2023-09-04 19:28:50 +02:00
fc5f3a9576 fix(core): update 2023-09-04 19:28:50 +02:00
25 changed files with 1585 additions and 423 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "@design.estate/dees-catalog", "name": "@design.estate/dees-catalog",
"version": "1.0.183", "version": "1.0.203",
"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,18 +15,18 @@
"author": "Lossless GmbH", "author": "Lossless GmbH",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@design.estate/dees-domtools": "^2.0.38", "@design.estate/dees-domtools": "^2.0.40",
"@design.estate/dees-element": "^2.0.25", "@design.estate/dees-element": "^2.0.27",
"@design.estate/dees-wcctools": "^1.0.78", "@design.estate/dees-wcctools": "^1.0.78",
"@fortawesome/fontawesome-svg-core": "^6.4.2", "@fortawesome/fontawesome-svg-core": "^6.4.2",
"@fortawesome/free-brands-svg-icons": "^6.4.2", "@fortawesome/free-brands-svg-icons": "^6.4.2",
"@fortawesome/free-regular-svg-icons": "^6.4.2", "@fortawesome/free-regular-svg-icons": "^6.4.2",
"@fortawesome/free-solid-svg-icons": "^6.4.2", "@fortawesome/free-solid-svg-icons": "^6.4.2",
"@push.rocks/smartpromise": "^4.0.3", "@push.rocks/smartpromise": "^4.0.3",
"@push.rocks/smartstring": "^4.0.8", "@push.rocks/smartstring": "^4.0.9",
"@tsclass/tsclass": "^4.0.42", "@tsclass/tsclass": "^4.0.43",
"highlight.js": "11.8.0", "highlight.js": "11.8.0",
"pdfjs-dist": "^2.16.105" "pdfjs-dist": "^3.10.111"
}, },
"devDependencies": { "devDependencies": {
"@gitzone/tsbuild": "^2.1.66", "@gitzone/tsbuild": "^2.1.66",
@ -35,7 +35,7 @@
"@gitzone/tswatch": "^2.0.7", "@gitzone/tswatch": "^2.0.7",
"@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.5.1" "@types/node": "^20.6.0"
}, },
"files": [ "files": [
"ts/**/*", "ts/**/*",

695
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.183', version: '1.0.203',
description: 'website for lossless.com' description: 'website for lossless.com'
} }

View File

@ -0,0 +1,15 @@
import { html } from '@design.estate/dees-element';
export const demoFunc = () => html`
<dees-button>This is a slotted Text</dees-button>
<p>
<dees-button text="Highlighted: This text shows" type="highlighted">Highlighted</dees-button>
</p>
<p><dees-button type="discreet">This is discreete button</dees-button></p>
<p><dees-button disabled>This is a disabled button</dees-button></p>
<p><dees-button type="big">This is a slotted Text</dees-button></p>
<p><dees-button status="normal">Normal Status</dees-button></p>
<p><dees-button disabled status="pending">Pending Status</dees-button></p>
<p><dees-button disabled status="success">Success Status</dees-button></p>
<p><dees-button disabled status="error">Error Status</dees-button></p>
`;

View File

@ -1,3 +1,4 @@
import { demoFunc } from './dees-button.demo.js';
import { import {
customElement, customElement,
html, html,
@ -20,17 +21,7 @@ declare global {
@customElement('dees-button') @customElement('dees-button')
export class DeesButton extends DeesElement { export class DeesButton extends DeesElement {
public static demo = () => html` public static demo = demoFunc;
<dees-button>This is a slotted Text</dees-button>
<p><dees-button text="Highlighted: This text shows" type="highlighted">Highlighted</dees-button></p>
<p><dees-button type="discreet">This is discreete button</dees-button></p>
<p><dees-button disabled>This is a disabled button</dees-button></p>
<p><dees-button type="big">This is a slotted Text</dees-button></p>
<p><dees-button status="normal">Normal Status</dees-button></p>
<p><dees-button disabled status="pending">Pending Status</dees-button></p>
<p><dees-button disabled status="success">Success Status</dees-button></p>
<p><dees-button disabled status="error">Error Status</dees-button></p>
`;
@property({ @property({
reflect: true, reflect: true,

View File

@ -0,0 +1,57 @@
import { html } from '@design.estate/dees-element';
import * as plugins from './plugins.js';
import { DeesContextmenu } from './dees-contextmenu.js';
export const demoFunc = () => html`
<style>
.withMargin {
display: block;
margin: 20px;
}
</style>
<dees-button @contextmenu=${(eventArg) => {
DeesContextmenu.openContextMenuWithOptions(eventArg, [
{
name: 'copy',
iconName: 'copySolid',
action: async () => {
return null;
},
},
{
name: 'edit',
iconName: 'penToSquare',
action: async () => {
return null;
},
},{
name: 'paste',
iconName: 'pasteSolid',
action: async () => {
return null;
},
},
]);
}}>Right-Click for contextmenu</dees-button>
<dees-contextmenu class="withMargin"></dees-contextmenu>
<dees-contextmenu
class="withMargin"
.menuItems=${[
{
name: 'copy',
iconName: 'copySolid',
action: async () => {},
},
{
name: 'edit',
iconName: 'penToSquare',
action: async () => {},
},{
name: 'paste',
iconName: 'pasteSolid',
action: async () => {},
},
] as plugins.tsclass.website.IMenuItem[]}
></dees-contextmenu>
`;

View File

@ -1,3 +1,4 @@
import { demoFunc } from './dees-contextmenu.demo.js';
import * as plugins from './plugins.js'; import * as plugins from './plugins.js';
import { import {
customElement, customElement,
@ -23,70 +24,25 @@ declare global {
@customElement('dees-contextmenu') @customElement('dees-contextmenu')
export class DeesContextmenu extends DeesElement { export class DeesContextmenu extends DeesElement {
// DEMO // DEMO
public static demo = () => html` public static demo = demoFunc
<style>
.withMargin {
display: block;
margin: 20px;
}
</style>
<dees-button @contextmenu=${(eventArg) => {
DeesContextmenu.openContextMenuWithOptions(eventArg, [
{
name: 'copy',
iconName: 'copySolid',
action: async () => {
return null;
},
},
{
name: 'edit',
iconName: 'penToSquare',
action: async () => {
return null;
},
},{
name: 'paste',
iconName: 'pasteSolid',
action: async () => {
return null;
},
},
]);
}}>Hello</dees-button>
<dees-contextmenu class="withMargin"></dees-contextmenu>
<dees-contextmenu
class="withMargin"
.menuItems=${[
{
name: 'copy',
iconName: 'copySolid',
action: async () => {},
},
{
name: 'edit',
iconName: 'penToSquare',
action: async () => {},
},{
name: 'paste',
iconName: 'pasteSolid',
action: async () => {},
},
] as plugins.tsclass.website.IMenuItem[]}
></dees-contextmenu>
`;
// STATIC // STATIC
public static async openContextMenuWithOptions(eventArg: MouseEvent, menuItemsArg: plugins.tsclass.website.IMenuItem[]) { public static async openContextMenuWithOptions(eventArg: MouseEvent, menuItemsArg: plugins.tsclass.website.IMenuItem[]) {
eventArg.preventDefault(); eventArg.preventDefault();
eventArg.stopPropagation();
const contextMenu = new DeesContextmenu(); const contextMenu = new DeesContextmenu();
contextMenu.style.position = 'absolute'; contextMenu.style.position = 'fixed';
contextMenu.style.zIndex = '2000';
contextMenu.style.top = `${eventArg.clientY.toString()}px`; contextMenu.style.top = `${eventArg.clientY.toString()}px`;
contextMenu.style.left = `${eventArg.clientX.toString()}px`; contextMenu.style.left = `${eventArg.clientX.toString()}px`;
contextMenu.style.opacity = '0'; contextMenu.style.opacity = '0';
contextMenu.style.transform = 'scale(0.95,0.95)'; contextMenu.style.transform = 'scale(0.95,0.95)';
contextMenu.style.transformOrigin = 'top left'; contextMenu.style.transformOrigin = 'top left';
contextMenu.menuItems = menuItemsArg; contextMenu.menuItems = menuItemsArg;
contextMenu.windowLayer = await DeesWindowLayer.createAndShow();
contextMenu.windowLayer.addEventListener('click', async () => {
await contextMenu.destroy();
})
document.body.append(contextMenu); document.body.append(contextMenu);
await domtools.plugins.smartdelay.delayFor(0); await domtools.plugins.smartdelay.delayFor(0);
contextMenu.style.opacity = '1'; contextMenu.style.opacity = '1';
@ -97,6 +53,7 @@ export class DeesContextmenu extends DeesElement {
type: Array, type: Array,
}) })
public menuItems: plugins.tsclass.website.IMenuItem[] = []; public menuItems: plugins.tsclass.website.IMenuItem[] = [];
windowLayer: DeesWindowLayer;
constructor() { constructor() {
super(); super();
@ -115,7 +72,7 @@ export class DeesContextmenu extends DeesElement {
font-size: 14px; font-size: 14px;
width: 200px; width: 200px;
border: 1px solid #444; border: 1px solid #444;
min-height: 40px; min-height: 34px;
border-radius: 3px; border-radius: 3px;
background: #222; background: #222;
box-shadow: 0px 1px 4px #000; box-shadow: 0px 1px 4px #000;
@ -156,15 +113,20 @@ export class DeesContextmenu extends DeesElement {
</div> </div>
`; `;
})} })}
${this.menuItems.length === 0 ? html`
<div class="menuitem" @click=${() => {
alert('No menu items...')
}}>
<dees-icon .iconFA=${'xmark'}></dees-icon
>No menu item present...
</div>
` : html``}
</div> </div>
`; `;
} }
public async firstUpdated() { public async firstUpdated() {
if (!this.menuItems || this.menuItems.length === 0) {
const mainbox = this.shadowRoot.querySelector('.mainbox');
mainbox.textContent = 'no menu items present';
}
} }
public async handleClick(menuItem: plugins.tsclass.website.IMenuItem) { public async handleClick(menuItem: plugins.tsclass.website.IMenuItem) {
@ -173,6 +135,9 @@ export class DeesContextmenu extends DeesElement {
} }
public async destroy() { public async destroy() {
if (this.windowLayer) {
this.windowLayer.destroy();
}
this.style.opacity = '0'; this.style.opacity = '0';
this.style.transform = 'scale(0.95,0,95)'; this.style.transform = 'scale(0.95,0,95)';
await domtools.plugins.smartdelay.delayFor(100); await domtools.plugins.smartdelay.delayFor(100);

View File

@ -0,0 +1,18 @@
import { html } from '@design.estate/dees-element';
export const demoFunc = () => html` <style>
.demoWrapper {
box-sizing: border-box;
position: absolute;
width: 100%;
height: 100%;
padding: 20px;
background: none;
}
</style>
<div class="demoWrapper">
<dees-dataview-codebox proglang="typescript">
import * as text from './hello'; const hiThere = 'nice'; const myFunction = async () => {
console.log('nice one'); }
</dees-dataview-codebox>
</div>`

View File

@ -1,3 +1,4 @@
import { demoFunc } from './dees-dataview-codebox.demo.js';
import { import {
DeesElement, DeesElement,
html, html,
@ -21,10 +22,7 @@ declare global {
@customElement('dees-dataview-codebox') @customElement('dees-dataview-codebox')
export class DeesDataviewCodebox extends DeesElement { export class DeesDataviewCodebox extends DeesElement {
public static demo = () => html`<dees-dataview-codebox proglang="typescript"> public static demo = demoFunc;
import * as text from './hello'; const hiThere = 'nice'; const myFunction = async () => {
console.log('nice one'); }
</dees-dataview-codebox>`;
@property() @property()
public progLang: string = 'typescript'; public progLang: string = 'typescript';
@ -52,19 +50,48 @@ export class DeesDataviewCodebox extends DeesElement {
.mainbox { .mainbox {
position: relative; position: relative;
color: ${this.goBright ? '#333333' : '#ffffff'}; color: ${this.goBright ? '#333333' : '#ffffff'};
border-top: 1px solid ${this.goBright ? '#ffffff' : '#333333'};
box-shadow: 0px 0px 5px ${this.goBright ? 'rgba(0,0,0,0.1)' : 'rgba(0,0,0,0.5)'};
background: ${this.goBright ? '#ffffff' : '#191919'};
border-radius: 16px;
overflow: hidden;
}
.appbar {
height: 24px;
background: #161616;
border-bottom: 1px solid #222222;
font-size: 12px;
color: #CCC;
font-family: 'Hubot Sans', 'monospace';
line-height: 24px;
}
.appbar .fileName {
text-align: center;
}
.bottomBar {
height: 24px;
background: #161616;
border-top: 1px solid #222222;
font-size: 12px;
color: #CCC;
font-family: 'Hubot Sans', 'monospace';
line-height: 24px;
} }
.languageLabel { .languageLabel {
color: #fff; color: #fff;
font-size: 12px; font-size: 12px;
line-height: 24px;
z-index: 10; z-index: 10;
background: #6596ff; background: #6596ff20;
display: inline-block; display: inline-block;
position: absolute; position: absolute;
right: 32px; bottom: 0px;
padding: 4px; right: 0px;
border-bottom-left-radius: 3px; padding: 0px 16px 0px 8px;
border-bottom-right-radius: 3px;
} }
.hljs-keyword { .hljs-keyword {
@ -74,18 +101,15 @@ export class DeesDataviewCodebox extends DeesElement {
.codegrid { .codegrid {
display: grid; display: grid;
grid-template-columns: 50px auto; grid-template-columns: 50px auto;
background: ${this.goBright ? '#ffffff' : '#191919'};
border-top: 1px solid ${this.goBright ? '#ffffff' : '#333333'};
box-shadow: 0px 0px 5px ${this.goBright ? 'rgba(0,0,0,0.1)' : 'rgba(0,0,0,0.5)'};
border-radius: 3px;
overflow: hidden; overflow: hidden;
} }
.lineNumbers { .lineNumbers {
background: ${this.goBright ? '#fafafa' : '#151515'};
color: ${this.goBright ? '#acacac' : '#666666'}; color: ${this.goBright ? '#acacac' : '#666666'};
padding: 30px 16px 0px 0px; padding: 30px 16px 0px 0px;
text-align: right; text-align: right;
border-right: 1px solid ${this.goBright ? '#eaeaea' : '#222222'};
} }
.lineCounter:last-child { .lineCounter:last-child {
@ -121,31 +145,37 @@ export class DeesDataviewCodebox extends DeesElement {
} }
.hljs-function { .hljs-function {
color: ${this.goBright ? '#2765DF': '#6596ff' }; color: ${this.goBright ? '#2765DF' : '#6596ff'};
} }
.hljs-params { .hljs-params {
color: ${this.goBright ? '#3DB420' : '#65d5ff' }; color: ${this.goBright ? '#3DB420' : '#65d5ff'};
} }
.hljs-comment { .hljs-comment {
color: ${this.goBright ? '#EF9300' : '#ffd765' }; color: ${this.goBright ? '#EF9300' : '#ffd765'};
} }
</style> </style>
<div class="mainbox"> <div class="mainbox">
<div class="languageLabel">${this.progLang}</div> <div class="appbar">
<div class="fileName">index.ts</div>
</div>
<div class="codegrid"> <div class="codegrid">
<div class="lineNumbers"> <div class="lineNumbers">
${(() => { ${(() => {
let lineCounter = 0; let lineCounter = 0;
return this.codeToDisplay.split('\n').map(lineArg => { return this.codeToDisplay.split('\n').map((lineArg) => {
lineCounter++; lineCounter++;
return html`<div class="lineCounter">${lineCounter}</div>`; return html`<div class="lineCounter">${lineCounter}</div>`;
}) });
})()} })()}
</div> </div>
<pre><code></code></pre> <pre><code></code></pre>
</div> </div>
<div class="bottomBar">
Spaces: 2
<div class="languageLabel">${this.progLang}</div>
</div>
</div> </div>
`; `;
} }
@ -167,12 +197,17 @@ export class DeesDataviewCodebox extends DeesElement {
this.codeToDisplayStore = smartstring.indent.normalize(this.codeToDisplay).trimStart(); this.codeToDisplayStore = smartstring.indent.normalize(this.codeToDisplay).trimStart();
} }
if (slottedCodeNodes[0] && slottedCodeNodes[0].wholeText && !this.codeToDisplay) { if (slottedCodeNodes[0] && slottedCodeNodes[0].wholeText && !this.codeToDisplay) {
this.codeToDisplayStore = smartstring.indent.normalize(slottedCodeNodes[0].wholeText).trimStart(); this.codeToDisplayStore = smartstring.indent
.normalize(slottedCodeNodes[0].wholeText)
.trimStart();
this.codeToDisplay = this.codeToDisplayStore; this.codeToDisplay = this.codeToDisplayStore;
} }
await domtools.plugins.smartdelay.delayFor(0); await domtools.plugins.smartdelay.delayFor(0);
const localCodeNode = this.shadowRoot.querySelector('code'); const localCodeNode = this.shadowRoot.querySelector('code');
const html = hlight.highlight(this.codeToDisplayStore, {language: this.progLang, ignoreIllegals: true}); const html = hlight.highlight(this.codeToDisplayStore, {
language: this.progLang,
ignoreIllegals: true,
});
localCodeNode.innerHTML = html.value; localCodeNode.innerHTML = html.value;
} }
} }

View File

@ -0,0 +1,39 @@
import { html } from '@design.estate/dees-element';
import * as tsclass from '@tsclass/tsclass';
export const demoFunc = () => html`<dees-dataview-statusobject
.statusObject=${{
id: '1',
name: 'Demo Item',
combinedStatus: 'partly_ok',
combinedStatusText: 'partly_ok',
details: [
{
name: 'Detail 1',
value: 'Value 1',
status: 'ok',
statusText: 'OK',
},
{
name: 'Detail 2',
value: 'Value 2',
status: 'partly_ok',
statusText: 'partly_ok',
},
{
name: 'Detail 3',
value: 'Value 3',
status: 'not_ok',
statusText: 'not_ok',
},
{
name: 'Detail 4',
value:
'Value 4 jhdkfjhalskdfjhfdjskalsdkfjhfdjskalskdjfhjdkslaksjdhfjdkslaskdfjhfjdkslaskdjfhjdskalskdjhfdjskalskdjfhdjskl',
status: 'ok',
statusText: 'OK',
},
],
} as tsclass.code.IStatusObject}
>
</dees-dataview-statusobject>`;

View File

@ -1,3 +1,4 @@
import { demoFunc } from './dees-dataview-statusobject.demo.js';
import { import {
DeesElement, DeesElement,
html, html,
@ -20,41 +21,7 @@ declare global {
@customElement('dees-dataview-statusobject') @customElement('dees-dataview-statusobject')
export class DeesDataviewStatusobject extends DeesElement { export class DeesDataviewStatusobject extends DeesElement {
public static demo = () => html`<dees-dataview-statusobject public static demo = demoFunc;
.statusObject=${{
id: '1',
name: 'Demo Item',
combinedStatus: 'partly_ok',
combinedStatusText: 'partly_ok',
details: [
{
name: 'Detail 1',
value: 'Value 1',
status: 'ok',
statusText: 'OK',
},
{
name: 'Detail 2',
value: 'Value 2',
status: 'partly_ok',
statusText: 'partly_ok',
},
{
name: 'Detail 3',
value: 'Value 3',
status: 'not_ok',
statusText: 'not_ok',
},
{
name: 'Detail 4',
value: 'Value 4 jhdkfjhalskdfjhfdjskalsdkfjhfdjskalskdjfhjdkslaksjdhfjdkslaskdfjhfjdkslaskdjfhjdskalskdjhfdjskalskdjfhdjskl',
status: 'ok',
statusText: 'OK',
},
],
}}
>
</dees-dataview-statusobject>`;
@property({ type: Object }) statusObject: tsclass.code.IStatusObject; @property({ type: Object }) statusObject: tsclass.code.IStatusObject;
@ -95,7 +62,7 @@ export class DeesDataviewStatusobject extends DeesElement {
.copyMain { .copyMain {
cursor: pointer; cursor: pointer;
font-size: 8px; font-size: 10px;
font-weight: 600; font-weight: 600;
text-transform: uppercase; text-transform: uppercase;
border: 1px solid ${cssManager.bdTheme('#999', '#444')}; border: 1px solid ${cssManager.bdTheme('#999', '#444')};
@ -103,6 +70,7 @@ export class DeesDataviewStatusobject extends DeesElement {
padding: 4px; padding: 4px;
border-radius: 3px; border-radius: 3px;
margin-right: 16px; margin-right: 16px;
color: #ffffff80
} }
.statusdot.ok { .statusdot.ok {
@ -122,7 +90,7 @@ export class DeesDataviewStatusobject extends DeesElement {
align-items: center; align-items: center;
display: grid; display: grid;
grid-template-columns: 40px auto; grid-template-columns: 40px auto;
border-top: 1px dotted ${cssManager.bdTheme('#999', '#444')}; border-top: 1px dotted ${cssManager.bdTheme('#999', '#282828')};
} }
.detail .detailsText { .detail .detailsText {
@ -134,10 +102,11 @@ export class DeesDataviewStatusobject extends DeesElement {
.detail .detailsText .label { .detail .detailsText .label {
font-size: 12px; font-size: 12px;
color: #ffffff80
} }
.detail .detailsText .value { .detail .detailsText .value {
font-size: 16px; font-size: 14px;
font-family: 'Intel One Mono'; font-family: 'Intel One Mono';
} }
`, `,

View File

@ -42,6 +42,7 @@ import {
faCircleInfo as faCircleInfoSolid, faCircleInfo as faCircleInfoSolid,
faCircleCheck as faCircleCheckSolid, faCircleCheck as faCircleCheckSolid,
faCircleXmark as faCircleXmarkSolid, faCircleXmark as faCircleXmarkSolid,
faClockRotateLeft as faClockRotateLeftSolid,
faCopy as faCopySolid, faCopy as faCopySolid,
faDesktop as faDesktopSolid, faDesktop as faDesktopSolid,
faEye as faEyeSolid, faEye as faEyeSolid,
@ -82,6 +83,8 @@ export const faIcons = {
circleCheckSolid: faCircleCheckSolid, circleCheckSolid: faCircleCheckSolid,
circleXmark: faCircleXmarkRegular, circleXmark: faCircleXmarkRegular,
circleXmarkSolid: faCircleXmarkSolid, circleXmarkSolid: faCircleXmarkSolid,
clockRotateLeft: faClockRotateLeftSolid,
clockRotateLeftSolid: faClockRotateLeftSolid,
copy: faCopyRegular, copy: faCopyRegular,
copySolid: faCopySolid, copySolid: faCopySolid,
desktop: faDesktopSolid, desktop: faDesktopSolid,
@ -95,7 +98,7 @@ export const faIcons = {
message: faMessageRegular, message: faMessageRegular,
messageSolid: faMessageSolid, messageSolid: faMessageSolid,
mugHot: faMugHotSolid, mugHot: faMugHotSolid,
faMugHotSolid: faMugHotSolid, mugHotSolid: faMugHotSolid,
minus: faMinusSolid, minus: faMinusSolid,
minusSolid: faMinusSolid, minusSolid: faMinusSolid,
paste: faPasteRegular, paste: faPasteRegular,
@ -122,6 +125,8 @@ export const faIcons = {
users: faUsersSolid, users: faUsersSolid,
}; };
export type TIconKey = keyof typeof faIcons;
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
'dees-icon': DeesIcon; 'dees-icon': DeesIcon;

View File

@ -15,26 +15,21 @@ import { DeesWindowLayer } from './dees-windowlayer.js';
export class DeesMobilenavigation extends DeesElement { export class DeesMobilenavigation extends DeesElement {
// STATIC // STATIC
public static demo = () => html` public static demo = () => html`
<dees-mobilenavigation <dees-button @click=${() => {
.menuItems="${[ DeesMobilenavigation.createAndShow([
{ {
name: 'hello1', name: 'Test',
action: async () => {}, action: async (deesMobileNav) => {
alert('test');
return null;
},
}, },
{ ]);
name: 'hello2', }}></dees-button>
action: async () => {},
},
{
name: 'hello3',
action: async () => {},
},
]}"
></dees-mobilenavigation>
`; `;
private static singletonRef: DeesMobilenavigation; private static singletonRef: DeesMobilenavigation;
public static async createAndInit(menuItemsArg: plugins.tsclass.website.IMenuItem[]) { public static async createAndShow(menuItemsArg: plugins.tsclass.website.IMenuItem<DeesMobilenavigation>[]) {
if (!this.singletonRef) { if (!this.singletonRef) {
this.singletonRef = new DeesMobilenavigation(); this.singletonRef = new DeesMobilenavigation();
document.body.append(this.singletonRef); document.body.append(this.singletonRef);
@ -140,7 +135,7 @@ export class DeesMobilenavigation extends DeesElement {
class="menuItem" class="menuItem"
@click="${() => { @click="${() => {
this.hide(); this.hide();
menuItem.action(); menuItem.action(this);
}}" }}"
> >
${menuItem.name} ${menuItem.name}

View File

@ -0,0 +1,37 @@
import { html } from '@design.estate/dees-element';
import { DeesModal } from './dees-modal.js';
export const demoFunc = () => html`
<dees-button @click=${() => {
DeesModal.createAndShow({
heading: 'This is a heading',
content: html`
<dees-form>
<dees-input-text
.label=${'Username'}
>
</dees-input-text>
<dees-input-text
.label=${'Password'}
>
</dees-input-text>
</dees-form>
`,
menuOptions: [{
name: 'Cancel',
iconName: null,
action: async (deesModalArg) => {
deesModalArg.destroy();
return null;
}
}, {
name: 'Ok',
iconName: null,
action: async (deesModalArg) => {
deesModalArg.destroy();
return null;
}
}],
});
}}>open modal</dees-button>
`

View File

@ -0,0 +1,196 @@
import * as plugins from './plugins.js';
import { demoFunc } from './dees-modal.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';
import { DeesWindowLayer } from './dees-windowlayer.js';
declare global {
interface HTMLElementTagNameMap {
'dees-modal': DeesModal;
}
}
@customElement('dees-modal')
export class DeesModal extends DeesElement {
// STATIC
public static demo = demoFunc;
public static async createAndShow(optionsArg: {
heading: string;
content: TemplateResult;
menuOptions: plugins.tsclass.website.IMenuItem<DeesModal>[];
}) {
const body = document.body;
const modal = new DeesModal();
modal.heading = optionsArg.heading;
modal.content = optionsArg.content;
modal.menuOptions = optionsArg.menuOptions;
modal.windowLayer = await DeesWindowLayer.createAndShow({
blur: true,
});
modal.windowLayer.addEventListener('click', async () => {
await modal.destroy();
});
body.append(modal.windowLayer);
body.append(modal);
}
// INSTANCE
@property({
type: String,
})
public heading = '';
@state({})
public content: TemplateResult;
@state({})
public menuOptions: plugins.tsclass.website.IMenuItem<DeesModal>[] = [];
constructor() {
super();
}
public static styles = [
cssManager.defaultStyles,
css`
:host {
font-family: 'Mona Sans', 'Inter', sans-serif;
color: ${cssManager.bdTheme('#333', '#fff')};
}
.modalContainer {
display: flex;
position: fixed;
top: 0px;
left: 0px;
width: 100vw;
height: 100vh;
box-sizing: border-box;
align-items: center;
justify-content: center;
z-index: 2000;
}
.modal {
will-change: transform;
transform: translateY(0px) scale(0.95);
opacity: 0;
width: 480px;
min-height: 120px;
background: #111;
border-radius: 8px;
border: 1px solid #222;
transition: all 0.2s;
overflow: hidden;
box-shadow: 0px 2px 5px #00000080;
}
.modal.show {
opacity: 1;
transform: translateY(0px) scale(1);
}
.modal.show.predestroy {
opacity: 0;
transform: translateY(10px) scale(1);
}
.modal .heading {
height: 32px;
font-family: 'Hubot Sans', 'Inter', sans-serif;
line-height: 32px;
text-align: center;
font-weight: 600;
font-size: 12px;
border-bottom: 1px solid #222;
}
.modal .content {
padding: 16px;
}
.modal .bottomButtons {
display: grid;
border-top: 1px solid #222;
}
.modal .bottomButtons .bottomButton {
height: 40px;
line-height: 40px;
text-align: center;
font-size: 14px;
border-right: 1px solid #222;
cursor: pointer;
}
.modal .bottomButtons .bottomButton:hover {
background: #222;
}
.modal .bottomButtons .bottomButton:last-child {
border-right: none;
}
`,
];
public render(): TemplateResult {
return html`
<style>
.modal .bottomButtons {
grid-template-columns: ${cssManager.cssGridColumns(this.menuOptions.length, 0)};
}
</style>
<div class="modalContainer" @click=${this.handleOutsideClick}>
<div class="modal">
<div class="heading">${this.heading}</div>
<div class="content">${this.content}</div>
<div class="bottomButtons">
${this.menuOptions.map(
(actionArg) => html`
<div class="bottomButton" @click=${() => {
actionArg.action(this);
}}>${actionArg.name}</div>
`
)}
</div>
</div>
</div>
`;
}
private windowLayer: DeesWindowLayer;
public async firstUpdated(_changedProperties: Map<string | number | symbol, unknown>) {
super.firstUpdated(_changedProperties);
const domtools = await this.domtoolsPromise;
await domtools.convenience.smartdelay.delayFor(30);
const modal = this.shadowRoot.querySelector('.modal');
modal.classList.add('show');
}
public async handleOutsideClick(eventArg: MouseEvent) {
eventArg.stopPropagation();
const modalContainer = this.shadowRoot.querySelector('.modalContainer');
if (eventArg.target === modalContainer) {
await this.destroy();
}
}
public async destroy() {
const domtools = await this.domtoolsPromise;
const modal = this.shadowRoot.querySelector('.modal');
modal.classList.add('predestroy');
await domtools.convenience.smartdelay.delayFor(200);
document.body.removeChild(this);
await this.windowLayer.destroy();
}
}

View File

@ -2,7 +2,7 @@ import { DeesElement, property, html, customElement, domtools, type TemplateResu
import { Deferred } from '@push.rocks/smartpromise'; import { Deferred } from '@push.rocks/smartpromise';
import type pdfjsTypes from 'pdfjs-dist'; // import type pdfjsTypes from 'pdfjs-dist';
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
@ -51,7 +51,7 @@ export class DeesPdf extends DeesElement {
} }
public static pdfJsReady: Promise<any>; public static pdfJsReady: Promise<any>;
public static pdfjsLib: typeof pdfjsTypes; public static pdfjsLib: any // typeof pdfjsTypes;
public async connectedCallback() { public async connectedCallback() {
super.connectedCallback(); super.connectedCallback();
if (!DeesPdf.pdfJsReady) { if (!DeesPdf.pdfJsReady) {

View File

@ -0,0 +1,5 @@
import { html } from '@design.estate/dees-element';
export const demoFunc = () => html`
<dees-simple-appdash>Hello there</dees-simple-appdash>
`;

View File

@ -0,0 +1,74 @@
import { demoFunc } from './dees-simple-appdash.demo.js';
import {
customElement,
html,
DeesElement,
property,
type TemplateResult,
cssManager,
css,
unsafeCSS,
type CSSResult,
state,
} from '@design.estate/dees-element';
declare global {
interface HTMLElementTagNameMap {
'dees-simple-appdash': DeesSimpleAppDash;
}
}
@customElement('dees-simple-appdash')
export class DeesSimpleAppDash extends DeesElement {
// STATIC
public static demo = demoFunc;
// INSTANCE
@property()
public name = 'Dees Simple Login';
public static styles = [
cssManager.defaultStyles,
css`
:host {
color: ${cssManager.bdTheme('#333', '#fff')};
user-select: none;
}
.appbar {
position: absolute;
top: 0;
height: 40px;
width: 100%;
background: ${cssManager.bdTheme('#eeeeeb', '#000')};
border-bottom: 1px solid ${cssManager.bdTheme('#ccc', '#333')};
font-size: 14px;
line-height: 40px;
font-family: 'Hubot Sans', 'Inter', sans-serif;
padding: 0px 16px;
}
.appcontent {
position: absolute;
top: 40px;
bottom: 0;
width: 100%;
background: ${cssManager.bdTheme('#eeeeeb', '#000')};
}
`,
];
public render(): TemplateResult {
return html`
<div class="appbar">
configvault v1.2.3
</div>
<div class="appcontent">
<slot></slot>
</div>
`;
}
public async firstUpdated(_changedProperties): Promise<void> {
const domtools = await this.domtoolsPromise;
super.firstUpdated(_changedProperties);
}
}

View File

@ -0,0 +1,3 @@
import { html } from '@design.estate/dees-element';
export const demoFunc = () => html` <dees-simple-login name="someapp"> Hello there </dees-simple-login> `;

View File

@ -1,3 +1,5 @@
import { demoFunc } from './dees-simple-login.demo.js';
import { import {
customElement, customElement,
html, html,
@ -20,15 +22,11 @@ declare global {
@customElement('dees-simple-login') @customElement('dees-simple-login')
export class DeesSimpleLogin extends DeesElement { export class DeesSimpleLogin extends DeesElement {
// STATIC // STATIC
public static demo = () => html` public static demo = demoFunc
<dees-simple-login>
Hello there
</dees-simple-login>
`;
// INSTANCE // INSTANCE
@property() @property()
public title = 'Dees Simple Login'; public name = 'Dees Simple Login';
public static styles = [ public static styles = [
cssManager.defaultStyles, cssManager.defaultStyles,
@ -71,7 +69,7 @@ export class DeesSimpleLogin extends DeesElement {
<div class="loginContainer"> <div class="loginContainer">
<div class="login"> <div class="login">
<dees-form> <dees-form>
<div class="header">Login to ${this.title}</div> <div class="header">Login to ${this.name}</div>
<dees-input-text key="username" label="username" required></dees-input-text> <dees-input-text key="username" label="username" required></dees-input-text>
<dees-input-text key="password" label="password" isPasswordBool required></dees-input-text> <dees-input-text key="password" label="password" isPasswordBool required></dees-input-text>
<dees-form-submit disabled>login</dees-form-submit> <dees-form-submit disabled>login</dees-form-submit>

View File

@ -0,0 +1,129 @@
import { type ITableAction } from './dees-table.js';
import * as plugins from './plugins.js';
import { html } from '@design.estate/dees-element';
interface ITableDemoData {
date: string;
amount: string;
description: string;
}
export const demoFunc = () => html`
<style>
.demoWrapper {
box-sizing: border-box;
position: absolute;
width: 100%;
height: 100%;
padding: 20px;
background: #000000;
}
</style>
<div class="demoWrapper">
<dees-table
heading1="Current Account Statement"
heading2="Bunq - Payment Account 2 - April 2021"
.editableFields="${['description']}"
.data=${[
{
date: '2021-04-01',
amount: '2464.65 €',
description: 'Printing Paper (Office Supplies) - STAPLES BREMEN',
},
{
date: '2021-04-02',
amount: '165.65 €',
description: 'Logitech Mouse (Hardware) - logi.com OnlineShop',
},
{
date: '2021-04-03',
amount: '2999,00 €',
description: 'Macbook Pro 16inch (Hardware) - Apple.de OnlineShop',
},
{
date: '2021-04-01',
amount: '2464.65 €',
description: 'Office-Supplies - STAPLES BREMEN',
},
{
date: '2021-04-01',
amount: '2464.65 €',
description: 'Office-Supplies - STAPLES BREMEN',
},
]}
dataName="transactions"
.dataActions="${[
{
name: 'upload',
iconName: 'bell',
useTableBehaviour: 'upload',
type: ['inRow'],
actionFunc: async (itemArg) => {
alert(itemArg.amount);
},
},
{
name: 'visibility',
iconName: 'copy',
type: ['inRow'],
useTableBehaviour: 'preview',
actionFunc: async (itemArg: any) => {},
},
{
name: 'create new',
iconName: 'instagram',
type: ['header'],
useTableBehaviour: 'preview',
actionFunc: async (itemArg: any) => {},
},
{
name: 'to gallery',
iconName: 'message',
type: ['footer'],
useTableBehaviour: 'preview',
actionFunc: async (itemArg: any) => {},
},
{
name: 'copy',
iconName: 'copySolid',
type: ['contextmenu', 'inRow'],
action: async () => {
return null;
},
},
{
name: 'edit (from demo)',
iconName: 'penToSquare',
type: ['contextmenu'],
action: async () => {
return null;
},
},
{
name: 'paste',
iconName: 'pasteSolid',
type: ['contextmenu'],
action: async () => {
return null;
},
},
{
name: 'preview',
type: ['doubleClick', 'contextmenu'],
iconName: 'eye',
actionFunc: async (itemArg) => {
alert(itemArg.amount);
return null;
},
}
] as (ITableAction<ITableDemoData>)[] as any}"
.displayFunction=${(itemArg) => {
return {
...itemArg,
onlyDisplayProp: 'onlyDisplay',
};
}}
>This is a slotted Text</dees-table
>
</div>
`;

View File

@ -1,3 +1,5 @@
import * as plugins from './plugins.js';
import { demoFunc } from './dees-table.demo.js';
import { import {
customElement, customElement,
html, html,
@ -9,9 +11,13 @@ import {
unsafeCSS, unsafeCSS,
type CSSResult, type CSSResult,
state, state,
resolveExec,
} from '@design.estate/dees-element'; } from '@design.estate/dees-element';
import { DeesContextmenu } from './dees-contextmenu.js';
import * as domtools from '@design.estate/dees-domtools'; import * as domtools from '@design.estate/dees-domtools';
import { type TIconKey } from './dees-icon.js';
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
@ -19,75 +25,47 @@ declare global {
} }
} }
export interface IDataAction<T = any> { // interfaces
export interface ITableAction<T = any> {
name: string; name: string;
iconName: string; iconName: TIconKey;
/**
* the table behaviour to use for this action
* e.g. upload: allows to upload files to the table
*/
useTableBehaviour?: 'upload' | 'cancelUpload' | 'none'; useTableBehaviour?: 'upload' | 'cancelUpload' | 'none';
/**
* the type of the action
*/
type: (
| 'inRow'
| 'contextmenu'
| 'doubleClick'
| 'footer'
| 'header'
| 'preview'
| 'keyCombination'
)[];
/**
* allows to check if the action is relevant for the given item
* @param itemArg
* @returns
*/
actionRelevancyCheckFunc?: (itemArg: T) => boolean;
/**
* the actual action function implementation
* @param itemArg
* @returns
*/
actionFunc: (itemArg: T) => Promise<any>; actionFunc: (itemArg: T) => Promise<any>;
} }
export type TDisplayFunction<T = any> = (itemArg: T) => object;
// the table implementation
@customElement('dees-table') @customElement('dees-table')
export class DeesTable<T> extends DeesElement { export class DeesTable<T> extends DeesElement {
public static demo = () => html` public static demo = demoFunc;
<style>
.demoWrapper {
box-sizing: border-box;
position: absolute;
width: 100%;
height: 100%;
padding: 60px;
background: #000000;
}
</style>
<div class="demoWrapper">
<dees-table
heading1="Current Account Statement"
heading2="Bunq - Payment Account 2 - April 2021"
.data=${[
{
date: '2021-04-01',
amount: '2464.65 €',
description: 'Printing Paper (Office Supplies) - STAPLES BREMEN',
},
{
date: '2021-04-02',
amount: '165.65 €',
description: 'Logitech Mouse (Hardware) - logi.com OnlineShop',
},
{
date: '2021-04-03',
amount: '2999,00 €',
description: 'Macbook Pro 16inch (Hardware) - Apple.de OnlineShop',
},
{
date: '2021-04-01',
amount: '2464.65 €',
description: 'Office-Supplies - STAPLES BREMEN',
},
{
date: '2021-04-01',
amount: '2464.65 €',
description: 'Office-Supplies - STAPLES BREMEN',
},
]}
.dataActions="${[{
name: 'upload',
iconName: 'upload',
useTableBehaviour: 'upload',
actionFunc: async (itemArg: any) => {
},
},{
name: 'visibility',
iconName: 'visibility',
useTableBehaviour: 'preview',
actionFunc: async (itemArg: any) => {
},
}] as IDataAction[]}"
>This is a slotted Text</dees-table>
</div>
`;
// INSTANCE // INSTANCE
@property({ @property({
@ -105,10 +83,21 @@ export class DeesTable<T> extends DeesElement {
}) })
public data: T[] = []; public data: T[] = [];
@property({
type: String,
reflect: true,
})
public dataName: string;
@property({ @property({
type: Array, type: Array,
}) })
public dataActions: IDataAction[] = []; public dataActions: ITableAction<T>[] = [];
@property({
attribute: false,
})
public displayFunction: TDisplayFunction = (itemArg: T) => itemArg as any;
@property({ @property({
type: Object, type: Object,
@ -116,14 +105,9 @@ export class DeesTable<T> extends DeesElement {
public selectedDataRow: T; public selectedDataRow: T;
@property({ @property({
type: String, type: Array,
}) })
public type: 'normal' | 'highlighted' | 'discreet' | 'big' = 'normal'; public editableFields: string[] = [];
@property({
type: String,
})
public status: 'normal' | 'pending' | 'success' | 'error' = 'normal';
public files: File[] = []; public files: File[] = [];
public fileWeakMap = new WeakMap(); public fileWeakMap = new WeakMap();
@ -139,7 +123,7 @@ export class DeesTable<T> extends DeesElement {
color: ${cssManager.bdTheme('#333', '#fff')}; color: ${cssManager.bdTheme('#333', '#fff')};
font-family: 'Mona Sans', 'Inter', sans-serif; font-family: 'Mona Sans', 'Inter', sans-serif;
font-weight: 400; font-weight: 400;
font-size: 16px; font-size: 14px;
padding: 16px; padding: 16px;
display: block; display: block;
width: 100%; width: 100%;
@ -150,11 +134,49 @@ export class DeesTable<T> extends DeesElement {
box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.3); box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.3);
overflow-x: auto; overflow-x: auto;
} }
.header {
display: flex;
justify-content: flex-end;
align-items: center;
}
.headingContainer {
}
.heading {
font-family: 'Hubot Sans', 'Inter', sans-serif;
}
.heading1 {
font-weight: 600;
}
.heading2 {
opacity: 0.6;
}
.headingSeparation { .headingSeparation {
margin-top: 7px; margin-top: 7px;
border-bottom: 1px solid ${cssManager.bdTheme('#bcbcbc', '#bcbcbc')}; border-bottom: 1px solid ${cssManager.bdTheme('#bcbcbc', '#bcbcbc')};
} }
.headerActions {
margin-left: auto;
cursor: pointer;
}
.headerAction {
display: flex;
color: ${cssManager.bdTheme('#333', '#ccc')};
}
.headerAction:hover {
color: ${cssManager.bdTheme('#555', '#fff')};
}
.headerAction dees-icon {
margin-right: 8px;
}
table, table,
.noDataSet { .noDataSet {
margin-top: 16px; margin-top: 16px;
@ -176,7 +198,7 @@ export class DeesTable<T> extends DeesElement {
tr:hover { tr:hover {
cursor: pointer; cursor: pointer;
} }
tr:hover .innerCellContainer { tr:hover td {
background: ${cssManager.bdTheme('#22222210', '#ffffff20')}; background: ${cssManager.bdTheme('#22222210', '#ffffff20')};
} }
tr:first-child:hover { tr:first-child:hover {
@ -185,19 +207,25 @@ export class DeesTable<T> extends DeesElement {
tr:first-child:hover .innerCellContainer { tr:first-child:hover .innerCellContainer {
background: none; background: none;
} }
tr.selected .innerCellContainer { tr.selected td {
background: ${cssManager.bdTheme('#22222220', '#ffffff20')}; background: ${cssManager.bdTheme('#22222220', '#ffffff40')};
} }
th { th {
text-transform: uppercase; text-transform: uppercase;
} }
th, th,
td { td {
padding: 3px 0px; position: relative;
padding: 0px;
border-right: 1px dashed ${cssManager.bdTheme('#999', '#808080')}; border-right: 1px dashed ${cssManager.bdTheme('#999', '#808080')};
} }
.innerCellContainer { .innerCellContainer {
min-height: 36px;
position: relative;
height: 100%;
width: 100%;
padding: 6px 8px; padding: 6px 8px;
line-height: 24px;
} }
th:first-child .innerCellContainer, th:first-child .innerCellContainer,
td:first-child .innerCellContainer { td:first-child .innerCellContainer {
@ -211,6 +239,23 @@ export class DeesTable<T> extends DeesElement {
td:last-child { td:last-child {
border-right: none; border-right: none;
} }
td input {
width: 100%;
height: 100%;
outline: none;
border: 2px solid #fa6101;
top: 0px;
bottom: 0px;
right: 0px;
left: 0px;
position: absolute;
background: #00000060;
color: inherit;
font-family: inherit;
font-size: inherit;
font-weight: inherit;
padding: 0px 6px
}
.action { .action {
margin: -8px 0px; margin: -8px 0px;
@ -228,14 +273,37 @@ export class DeesTable<T> extends DeesElement {
background: ${cssManager.bdTheme('#CCC', '#111')}; background: ${cssManager.bdTheme('#CCC', '#111')};
} }
.tableStatistics { .footer {
padding: 4px 16px; font-size: 14px;
font-size: 12px;
color: ${cssManager.bdTheme('#111', '#ffffff90')}; color: ${cssManager.bdTheme('#111', '#ffffff90')};
background: ${cssManager.bdTheme('#eeeeeb', '#00000050')}; background: ${cssManager.bdTheme('#eeeeeb', '#00000050')};
margin: 16px -16px -16px -16px; margin: 16px -16px -16px -16px;
border-bottom-left-radius: 3px; border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px; border-bottom-right-radius: 3px;
display: flex;
}
.tableStatistics {
padding: 8px 16px;
}
.footerActions {
margin-left: auto;
}
.footerActions .footerAction {
cursor: pointer;
padding: 8px 16px;
display: flex;
}
.footerActions .footerAction:hover {
background: ${cssManager.bdTheme('#CCC', '#111')};
}
.footerActions dees-icon {
display: flex;
margin-right: 8px;
} }
`, `,
]; ];
@ -244,15 +312,44 @@ export class DeesTable<T> extends DeesElement {
return html` return html`
<div class="mainbox"> <div class="mainbox">
<!-- the heading part --> <!-- the heading part -->
<div>${this.heading1}</div> <div class="header">
<div>${this.heading2}</div> <div class="headingContainer">
<div class="heading heading1">${this.heading1}</div>
<div class="heading heading2">${this.heading2}</div>
</div>
<div class="headerActions">
${resolveExec(async () => {
const resultArray: TemplateResult[] = [];
for (const action of this.dataActions) {
if (!action.type.includes('header')) continue;
resultArray.push(
html`<div
class="headerAction"
@click=${() => {
action.actionFunc(this.selectedDataRow);
}}
>
${action.iconName
? html`<dees-icon .iconSize=${14} .iconFA=${action.iconName}></dees-icon>
${action.name}`
: action.name}
</div>`
);
}
return resultArray;
})}
</div>
</div>
<div class="headingSeparation"></div> <div class="headingSeparation"></div>
<!-- the actual table --> <!-- the actual table -->
<style></style> <style></style>
${this.data.length > 0 ${this.data.length > 0
? (() => { ? (() => {
const headings: string[] = Object.keys(this.data[0]); // Only pick up the keys from the first transformed data object
// as all data objects are assumed to have the same structure
const firstTransformedItem = this.displayFunction(this.data[0]);
const headings: string[] = Object.keys(firstTransformedItem);
return html` return html`
<table> <table>
<tr> <tr>
@ -273,32 +370,42 @@ export class DeesTable<T> extends DeesElement {
} }
})()} })()}
</tr> </tr>
${this.data.map( ${this.data.map((itemArg) => {
(itemArg) => html` const transformedItem = this.displayFunction(itemArg);
const getTr = (elementArg: HTMLElement): HTMLElement => {
if (elementArg.tagName === 'TR') {
return elementArg;
} else {
return getTr(elementArg.parentElement);
}
};
return html`
<tr <tr
@click=${() => { @click=${() => {
this.selectedDataRow = itemArg; this.selectedDataRow = itemArg;
}} }}
@dragenter=${async (eventArg: DragEvent) => { @dragenter=${async (eventArg: DragEvent) => {
console.log((eventArg.target as HTMLElement).tagName)
console.log('dragenter');
eventArg.preventDefault(); eventArg.preventDefault();
eventArg.stopPropagation(); eventArg.stopPropagation();
(eventArg.target as HTMLElement).parentElement.style.background = '#800000'; const realTarget = getTr(eventArg.target as HTMLElement);
console.log('dragenter');
console.log(realTarget);
setTimeout(() => {
realTarget.style.background = 'green';
}, 0);
}} }}
@dragleave=${async (eventArg: DragEvent) => { @dragleave=${async (eventArg: DragEvent) => {
console.log((eventArg.target as HTMLElement).tagName)
console.log('dragleave');
eventArg.preventDefault(); eventArg.preventDefault();
eventArg.stopPropagation(); eventArg.stopPropagation();
(eventArg.target as HTMLElement).parentElement.style.background = 'none'; const realTarget = getTr(eventArg.target as HTMLElement);
realTarget.style.background = 'none';
}} }}
@dragover=${async (eventArg: DragEvent) => { @dragover=${async (eventArg: DragEvent) => {
eventArg.preventDefault(); eventArg.preventDefault();
}} }}
@drop=${async (eventArg: DragEvent) => { @drop=${async (eventArg: DragEvent) => {
eventArg.preventDefault(); eventArg.preventDefault();
const newFiles = [] const newFiles = [];
for (const file of Array.from(eventArg.dataTransfer.files)) { for (const file of Array.from(eventArg.dataTransfer.files)) {
this.files.push(file); this.files.push(file);
newFiles.push(file); newFiles.push(file);
@ -306,17 +413,46 @@ export class DeesTable<T> extends DeesElement {
} }
const result: File[] = this.fileWeakMap.get(itemArg as object); const result: File[] = this.fileWeakMap.get(itemArg as object);
if (!result) { if (!result) {
this.fileWeakMap.set(itemArg as object, newFiles) this.fileWeakMap.set(itemArg as object, newFiles);
} else { } else {
result.push(...newFiles); result.push(...newFiles);
} }
}} }}
@contextmenu=${async (eventArg: MouseEvent) => {
DeesContextmenu.openContextMenuWithOptions(
eventArg,
this.getActionsForType('contextmenu').map((action) => {
const menuItem: plugins.tsclass.website.IMenuItem = {
name: action.name,
iconName: action.iconName as any,
action: async () => {
await action.actionFunc(itemArg);
return null;
},
};
return menuItem;
})
);
}}
class="${itemArg === this.selectedDataRow ? 'selected' : ''}" class="${itemArg === this.selectedDataRow ? 'selected' : ''}"
> >
${headings.map( ${headings.map(
(headingArg) => html` (headingArg) => html`
<td> <td
<div class="innerCellContainer">${itemArg[headingArg]}</div> @dblclick=${(e: Event) => {
if (this.editableFields.includes(headingArg)) {
this.handleCellEditing(e, itemArg, headingArg);
} else {
const wantedAction = this.dataActions.find((actionArg) =>
actionArg.type.includes('doubleClick')
);
if (wantedAction) {
wantedAction.actionFunc(itemArg);
}
}
}}
>
<div class="innerCellContainer">${transformedItem[headingArg]}</div>
</td> </td>
` `
)} )}
@ -325,36 +461,96 @@ export class DeesTable<T> extends DeesElement {
return html` return html`
<td> <td>
<div class="innerCellContainer"> <div class="innerCellContainer">
${(() => { ${this.getActionsForType('inRow').map(
const actions: TemplateResult[] = []; (actionArg) => html`<div
for (const action of this.dataActions) { class="action"
actions.push(html`<div class="action">${action.iconName ? html` @click=${() => actionArg.actionFunc(itemArg)}
<dees-icon .iconName=${'upload_file'}></dees-icon> >
` : action.name}</div>`) ${actionArg.iconName
} ? html`
return actions; <dees-icon .iconFA=${actionArg.iconName}></dees-icon>
})()} `
: actionArg.name}
</div>`
)}
</div> </div>
</td> </td>
`; `;
} }
})()} })()}
</tr> </tr>
` `;
)} })}
</table> </table>
`; `;
})() })()
: html` <div class="noDataSet">No data set!</div> `} : html` <div class="noDataSet">No data set!</div> `}
<div class="tableStatistics"> <div class="footer">
${this.data.length} data rows (total) | <div class="tableStatistics">
${this.selectedDataRow ${this.data.length} ${this.dataName || 'data rows'} (total) |
? html`Row ${this.data.indexOf(this.selectedDataRow) + 1} selected` ${this.selectedDataRow ? '# ' + `${this.data.indexOf(this.selectedDataRow) + 1}` : `No`}
: html`No row selected`} selected
</div>
<div class="footerActions">
${resolveExec(async () => {
const resultArray: TemplateResult[] = [];
for (const action of this.dataActions) {
if (!action.type.includes('footer')) continue;
resultArray.push(
html`<div
class="footerAction"
@click=${() => {
action.actionFunc(this.selectedDataRow);
}}
>
${action.iconName
? html`<dees-icon .iconSize=${14} .iconFA=${action.iconName}></dees-icon>
${action.name}`
: action.name}
</div>`
);
}
return resultArray;
})}
</div>
</div> </div>
</div> </div>
`; `;
} }
public async firstUpdated() {} public async firstUpdated() {}
getActionsForType(typeArg: ITableAction['type'][0]) {
const actions: ITableAction[] = [];
for (const action of this.dataActions) {
if (!action.type.includes(typeArg)) continue;
actions.push(action);
}
return actions;
}
handleCellEditing(event: Event, item: T, key: string) {
const target = event.target as HTMLElement;
// Create an input element
const input = document.createElement('input');
input.type = 'text';
input.value = (item[key] as unknown as string) || '';
// When the input loses focus or the Enter key is pressed, update the data
input.addEventListener('blur', () => {
item[key] = input.value as any; // Convert string to T (you might need better type casting depending on your data structure)
target.innerHTML = input.value; // Update the cell's display
});
input.addEventListener('keydown', (e: KeyboardEvent) => {
if (e.key === 'Enter') {
input.blur(); // This will trigger the blur event handler above
}
});
// Replace the cell's content with the input
target.innerHTML = '';
target.appendChild(input);
input.focus();
}
} }

View File

@ -1,4 +1,4 @@
import { customElement, DeesElement, type TemplateResult, html, property, type CSSResult, } from '@design.estate/dees-element'; import { customElement, DeesElement, type TemplateResult, html, property, type CSSResult, state, } from '@design.estate/dees-element';
import * as domtools from '@design.estate/dees-domtools'; import * as domtools from '@design.estate/dees-domtools';
@ -8,11 +8,33 @@ declare global {
} }
} }
export interface IOptions_DeesWindowLayer {
blur: boolean;
}
@customElement('dees-windowlayer') @customElement('dees-windowlayer')
export class DeesWindowLayer extends DeesElement { export class DeesWindowLayer extends DeesElement {
// STATIC // STATIC
public static demo = () => html`<dees-windowlayer></dees-windowlayer>`; public static demo = () => html`<dees-windowlayer></dees-windowlayer>`;
public static async createAndShow(optionsArg?: IOptions_DeesWindowLayer) {
const domtoolsInstance = domtools.DomTools.getGlobalDomToolsSync();
const windowLayer = new DeesWindowLayer();
windowLayer.options = {
...windowLayer.options,
...optionsArg,
}
document.body.append(windowLayer);
await domtoolsInstance.convenience.smartdelay.delayFor(0);
windowLayer.show();
return windowLayer;
}
@state()
public options: IOptions_DeesWindowLayer = {
blur: false
};
// INSTANCE // INSTANCE
@property({ @property({
type: Boolean type: Boolean
@ -29,7 +51,7 @@ export class DeesWindowLayer extends DeesElement {
${domtools.elementBasic.styles} ${domtools.elementBasic.styles}
<style> <style>
.windowOverlay { .windowOverlay {
transition: all 0.3s; transition: all 0.2s;
will-change: transform; will-change: transform;
position: fixed; position: fixed;
top: 0px; top: 0px;
@ -40,14 +62,14 @@ export class DeesWindowLayer extends DeesElement {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
background: rgba(0, 0, 0, 0.0); background: rgba(0, 0, 0, 0.0);
backdrop-filter: brightness(1); backdrop-filter: brightness(1) ${this.options.blur ? 'blur(0px)' : ''};
pointer-events: none; pointer-events: none;
z-index: 200; z-index: 200;
} }
.visible { .visible {
background: rgba(0, 0, 0, 0.2); background: rgba(0, 0, 0, 0.2);
backdrop-filter: brightness(0.3); backdrop-filter: brightness(0.9) ${this.options.blur ? 'blur(2px)' : ''};
pointer-events: all; pointer-events: all;
} }
</style> </style>
@ -82,4 +104,11 @@ export class DeesWindowLayer extends DeesElement {
await domtools.convenience.smartdelay.delayFor(0); await domtools.convenience.smartdelay.delayFor(0);
this.visible = false; this.visible = false;
} }
public async destroy() {
const domtools = await this.domtoolsPromise;
await this.hide();
await domtools.convenience.smartdelay.delayFor(300);
this.remove();
}
} }

View File

@ -14,7 +14,9 @@ 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-pdf.js'; export * from './dees-pdf.js';
export * from './dees-simple-appdash.js';
export * from './dees-simple-login.js'; export * from './dees-simple-login.js';
export * from './dees-speechbubble.js'; export * from './dees-speechbubble.js';
export * from './dees-spinner.js'; export * from './dees-spinner.js';

View File

@ -5,7 +5,8 @@
"target": "ES2022", "target": "ES2022",
"module": "ES2022", "module": "ES2022",
"moduleResolution": "nodenext", "moduleResolution": "nodenext",
"esModuleInterop": true "esModuleInterop": true,
"verbatimModuleSyntax": true
}, },
"exclude": [ "exclude": [
"dist_*/**/*.d.ts" "dist_*/**/*.d.ts"