Compare commits

...

44 Commits

Author SHA1 Message Date
7d4e5f2ca7 1.0.258 2024-01-22 00:59:26 +01:00
c0ad0f4570 fix(core): update 2024-01-22 00:59:25 +01:00
d56eb602a9 1.0.257 2024-01-21 22:37:39 +01:00
f1c791eb12 fix(core): update 2024-01-21 22:37:39 +01:00
e872188be7 1.0.256 2024-01-21 17:14:16 +01:00
2d712e78b0 fix(core): update 2024-01-21 17:14:15 +01:00
ebeecd0686 1.0.255 2024-01-21 14:25:03 +01:00
1d09f994c6 fix(core): update 2024-01-21 14:25:02 +01:00
686c3714fc 1.0.254 2024-01-21 14:14:57 +01:00
e29086036c fix(core): update 2024-01-21 14:14:57 +01:00
78e24aa720 1.0.253 2024-01-21 13:57:46 +01:00
7c8876c835 fix(core): update 2024-01-21 13:57:46 +01:00
2222fb1e01 1.0.252 2024-01-21 13:57:27 +01:00
46b30a1ef0 fix(core): update 2024-01-21 13:57:26 +01:00
d49d5f70ef 1.0.251 2024-01-21 13:36:48 +01:00
76a950e2ba fix(core): update 2024-01-21 13:36:47 +01:00
077aba5e58 1.0.250 2024-01-21 13:27:29 +01:00
857362423f fix(core): update 2024-01-21 13:27:29 +01:00
e7232b6a53 1.0.249 2024-01-21 01:45:36 +01:00
2eb26544b3 fix(core): update 2024-01-21 01:45:35 +01:00
a40834d1cf 1.0.248 2024-01-21 01:42:07 +01:00
0c1159d4c7 fix(core): update 2024-01-21 01:42:06 +01:00
4584765046 1.0.247 2024-01-21 01:12:57 +01:00
5817068cb5 fix(core): update 2024-01-21 01:12:57 +01:00
8fa01fbaad 1.0.246 2024-01-18 02:08:20 +01:00
9cdae8ccdb fix(core): update 2024-01-18 02:08:19 +01:00
7e1c5f3dbb 1.0.245 2024-01-15 19:42:34 +01:00
1f3f17247c fix(core): update 2024-01-15 19:42:33 +01:00
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
42 changed files with 2427 additions and 660 deletions

View File

@ -1,6 +1,6 @@
{
"name": "@design.estate/dees-catalog",
"version": "1.0.236",
"version": "1.0.258",
"private": false,
"description": "website for lossless.com",
"main": "dist_ts_web/index.js",
@ -15,29 +15,29 @@
"author": "Lossless GmbH",
"license": "MIT",
"dependencies": {
"@design.estate/dees-domtools": "^2.0.55",
"@design.estate/dees-domtools": "^2.0.57",
"@design.estate/dees-element": "^2.0.33",
"@design.estate/dees-wcctools": "^1.0.81",
"@fortawesome/fontawesome-svg-core": "^6.5.0",
"@fortawesome/free-brands-svg-icons": "^6.5.0",
"@fortawesome/free-regular-svg-icons": "^6.5.0",
"@fortawesome/free-solid-svg-icons": "^6.5.0",
"@design.estate/dees-wcctools": "^1.0.87",
"@fortawesome/fontawesome-svg-core": "^6.5.1",
"@fortawesome/free-brands-svg-icons": "^6.5.1",
"@fortawesome/free-regular-svg-icons": "^6.5.1",
"@fortawesome/free-solid-svg-icons": "^6.5.1",
"@push.rocks/smarti18n": "^1.0.4",
"@push.rocks/smartpromise": "^4.0.3",
"@push.rocks/smartstring": "^4.0.9",
"@push.rocks/smartstring": "^4.0.13",
"@tsclass/tsclass": "^4.0.46",
"highlight.js": "11.9.0",
"ibantools": "^4.3.6",
"pdfjs-dist": "^3.11.174"
"ibantools": "^4.3.9",
"pdfjs-dist": "^4.0.379"
},
"devDependencies": {
"@git.zone/tsbuild": "^2.1.66",
"@git.zone/tsbundle": "^2.0.8",
"@git.zone/tstest": "^1.0.77",
"@git.zone/tswatch": "^2.0.7",
"@git.zone/tsbuild": "^2.1.72",
"@git.zone/tsbundle": "^2.0.15",
"@git.zone/tstest": "^1.0.86",
"@git.zone/tswatch": "^2.0.21",
"@push.rocks/projectinfo": "^5.0.2",
"@push.rocks/tapbundle": "^5.0.15",
"@types/node": "^20.10.0"
"@types/node": "^20.11.5"
},
"files": [
"ts/**/*",

1478
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@design.estate/dees-catalog',
version: '1.0.236',
version: '1.0.258',
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 {
cursor: pointer;
background: #039be5;
background: #0050b9;
color: #ffffff;
border: 1px solid #039be5;
border-top: 1px solid #039be5;
border: 1px solid #0050b9;
border-top: 1px solid #0050b9;
}
.button:active {
background: #0277bd;
border-top: 1px solid #0277bd;
background: #0069f2;
border-top: 1px solid #0069f2;
}
.button.disabled {
@ -146,8 +145,8 @@ export class DeesButton extends DeesElement {
}
.button.pending {
border: 1px dashed ${cssManager.bdTheme('#0277bd', '#0277bd70')};
background: ${cssManager.bdTheme('#0277bd', '#0277bd70')};
border: 1px dashed ${cssManager.bdTheme('#0069f2', '#0069f270')};
background: ${cssManager.bdTheme('#0069f2', '#0069f270')};
color: #fff;
}

View File

@ -81,7 +81,6 @@ export class DeesChips extends DeesElement {
.chip:hover {
background: #666666;
cursor: pointer;
}
.chip.selected {

View File

@ -1,5 +1,5 @@
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';

View File

@ -1,5 +1,6 @@
import * as colors from './00colors.js';
import * as plugins from './00plugins.js';
import { demoFunc } from './dees-contextmenu.demo.js';
import * as plugins from './plugins.js';
import {
customElement,
html,
@ -110,16 +111,18 @@ export class DeesContextmenu extends DeesElement {
color: ${cssManager.bdTheme('#222', '#ccc')};
font-size: 14px;
width: 200px;
border: 1px solid ${cssManager.bdTheme('#fff', '#444')};
border: 1px solid ${cssManager.bdTheme('#fff', '#ffffff10')};
min-height: 34px;
border-radius: 3px;
background: ${cssManager.bdTheme('#fff', '#222')};
box-shadow: 0px 1px 4px ${cssManager.bdTheme('#00000020', '#000000')};
user-select: none;
padding: 4px;
}
.mainbox .menuitem {
padding: 8px;
padding: 4px 8px;
border-radius: 3px;
}
.mainbox .menuitem dees-icon {
@ -130,12 +133,10 @@ export class DeesContextmenu extends DeesElement {
}
.mainbox .menuitem:hover {
cursor: pointer;
background: ${cssManager.bdTheme('#00000010', '#ffffff10')};
background: ${cssManager.bdTheme(colors.bright.blue, colors.dark.blue)};
}
.mainbox .menuitem:active {
cursor: pointer;
background: #ffffff05;
}
`,
@ -158,7 +159,7 @@ export class DeesContextmenu extends DeesElement {
this.destroy();
}}>
<dees-icon .iconFA=${'xmark'}></dees-icon
>Deactivate Contextmenu globally.
>allow native context
</div>
` : html``}
</div>

View File

@ -61,17 +61,22 @@ export class DeesDataviewCodebox extends DeesElement {
}
.appbar {
position: relative;
color: ${cssManager.bdTheme('#333', '#ccc')};
background: ${cssManager.bdTheme('#ffffff', '#161616')};
border-bottom: 1px solid ${cssManager.bdTheme('#eeeeeb', '#222222')};
height: 24px;
display: flex;
font-size: 12px;
line-height: 24px;
justify-content: center;
align-items: center;
}
.appbar .fileName {
line-height: inherit;
position: relative;
flex: 1;
text-align: center;
}
@ -175,8 +180,9 @@ export class DeesDataviewCodebox extends DeesElement {
}}"
>
<div class="appbar">
<dees-windowcontrols></dees-windowcontrols>
<dees-windowcontrols type="mac" position="left"></dees-windowcontrols>
<div class="fileName">index.ts</div>
<dees-windowcontrols type="mac" position="right"></dees-windowcontrols>
</div>
<div class="codegrid">
<div class="lineNumbers">

View File

@ -1,39 +1,49 @@
import { html } from '@design.estate/dees-element';
import { html, cssManager } 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>`;
export const demoFunc = () => html` <style>
.demo {
background: ${cssManager.bdTheme('#eeeeeb', '#000000')};
display: block;
content: '';
padding: 40px;
}
</style>
<div class="demo">
<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>
</div>`;

View File

@ -1,3 +1,6 @@
import * as colors from './00colors.js';
import * as plugins from './00plugins.js';
import { demoFunc } from './dees-dataview-statusobject.demo.js';
import {
DeesElement,
@ -34,6 +37,8 @@ export class DeesDataviewStatusobject extends DeesElement {
box-shadow: 0px 1px 3px #00000030;
min-height: 48px;
color: ${cssManager.bdTheme('#000', '#fff')};
border-top: ${cssManager.bdTheme('none', '1px solid #ffffff10')};
cursor: default;
}
.heading {
@ -61,16 +66,28 @@ export class DeesDataviewStatusobject extends DeesElement {
}
.copyMain {
cursor: pointer;
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
border: 1px solid ${cssManager.bdTheme('#999', '#444')};
border: 1px solid ${cssManager.bdTheme('#e0e0e0', '#444')};
text-align: center;
padding: 4px;
border-radius: 3px;
margin-right: 16px;
color: #ffffff80
color: ${cssManager.bdTheme('#333', '#ffffff80')};
user-select: none;
}
.copyMain:hover {
background: ${cssManager.bdTheme(colors.bright.blue, colors.dark.blue)};
border: 1px solid ${cssManager.bdTheme(colors.bright.blue, colors.dark.blue)};
color: #fff;
}
.copyMain:active {
background: ${cssManager.bdTheme(colors.bright.blueActive, colors.dark.blueActive)};
border: 1px solid ${cssManager.bdTheme(colors.bright.blueActive, colors.dark.blueActive)};
color: #fff;
}
.statusdot.ok {
@ -86,11 +103,20 @@ export class DeesDataviewStatusobject extends DeesElement {
}
.detail {
minheight: 60px;
min-height: 60px;
align-items: center;
display: grid;
grid-template-columns: 40px auto;
border-top: 1px dotted ${cssManager.bdTheme('#999', '#282828')};
border-top: 1px dotted ${cssManager.bdTheme('#e0e0e0', '#282828')};
transition: all 0.2s;
}
.detail:hover {
background: #ffffff05;
}
.detail:active {
background: #ffffff10;
}
.detail .detailsText {

View File

@ -1,13 +1,14 @@
import { html, domtools } from '@design.estate/dees-element';
import { html, domtools, cssManager } from '@design.estate/dees-element';
import type { DeesForm } from './dees-form.js';
export const demoFunc = () => html`
<style>
.demoContainer {
max-width: 400px;
margin: auto;
margin: 24px auto;
padding: 16px;
background: #111;
background: ${cssManager.bdTheme('#eeeeeb', '#111')};
box-shadow: 0px 1px 3px #00000030;
}
</style>
<div class="demoContainer">
@ -28,7 +29,19 @@ export const demoFunc = () => html`
{ option: 'option 3', key: 'option3' },
]}
></dees-input-dropdown>
<dees-input-text .required="${true}" key="hello1" label="a text"></dees-input-text>
<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
.label=${'a type list'}
></dees-input-typelist>
<dees-input-text .required="${true}" key="hello1" label="a text" .description=${`
This is an awesome description.
`}></dees-input-text>
<dees-input-text .required="${true}" key="hello2" label="also a text"></dees-input-text>
<dees-input-text
.required="${true}"
@ -42,6 +55,14 @@ export const demoFunc = () => html`
label="another text"
></dees-input-checkbox>
<dees-input-iban></dees-input-iban>
<dees-input-multitoggle
.label=${'multi select'}
.options=${['option 1', 'option 2', 'option 3']}
.selectedOption=${'option 1'}
></dees-input-multitoggle>
<dees-input-fileupload
.label=${'attachments'}
></dees-input-fileupload>
<dees-form-submit>Submit</dees-form-submit>
</dees-form>
</div>

View File

@ -50,11 +50,14 @@ import {
faEyeSlash as faEyeSlashSolid,
faFileInvoice as faFileInvoiceSolid,
faFileInvoiceDollar as faFileInvoiceDollarSolid,
faGear as faGearSolid,
faGrip as faGripSolid,
faMagnifyingGlass as faMagnifyingGlassSolid,
faMessage as faMessageSolid,
faMoneyCheckDollar as faMoneyCheckDollarSolid,
faMugHot as faMugHotSolid,
faMinus as faMinusSolid,
faPaperclip as faPaperclipSolid,
faPaste as faPasteSolid,
faPenToSquare as faPenToSquareSolid,
faPlus as faPlusSolid,
@ -93,12 +96,15 @@ export const faIcons = {
eyeSlash: faEyeSlashSolid,
fileInvoice: faFileInvoiceSolid,
fileInvoiceDoller: faFileInvoiceDollarSolid,
gear: faGearSolid,
grip: faGripSolid,
magnifyingGlass: faMagnifyingGlassSolid,
message: faMessageRegular,
messageSolid: faMessageSolid,
moneyCheckDollar: faMoneyCheckDollarSolid,
mugHot: faMugHotSolid,
minus: faMinusSolid,
paperclip: faPaperclipSolid,
paste: faPasteRegular,
pasteSolid: faPasteSolid,
penToSquare: faPenToSquareSolid,

View File

@ -62,7 +62,10 @@ export class DeesInputCheckbox extends DeesElement {
display: block;
position: relative;
margin: 20px 0px;
cursor: pointer;
cursor: default;
}
:host(:hover) {
filter: ${cssManager.bdTheme('brightness(0.95)', 'brightness(1.1)')};
}
.maincontainer {
@ -100,8 +103,8 @@ export class DeesInputCheckbox extends DeesElement {
}
.checkbox.selected {
background: #039BE5;
border: 1px solid #039BE5;
background: #0050b9;
border: 1px solid #0050b9;
}
.checkbox.disabled {

View File

@ -59,6 +59,15 @@ export class DeesInputDropdown extends DeesElement {
@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 = [
cssManager.defaultStyles,
css`
@ -80,88 +89,115 @@ export class DeesInputDropdown extends DeesElement {
.label {
font-size: 14px;
margin-bottom: 4px;
margin-bottom: 8px;
}
.selectedBox {
user-select: none;
cursor: pointer;
position: relative;
max-width: 420px;
height: 40px;
line-height: 40px;
padding: 0px 8px;
background: ${cssManager.bdTheme('#fafafa', '#222')};
background: ${cssManager.bdTheme('#fafafa', '#222222')};
box-shadow: ${cssManager.bdTheme('0px 1px 4px rgba(0,0,0,0.3)', 'none')};
border-radius: 3px;
border-top: ${cssManager.bdTheme('1px solid #CCC', '1px solid #444')};
border-bottom: ${cssManager.bdTheme('1px solid #CCC', '1px solid #333')};
border-top: ${cssManager.bdTheme('1px solid #CCC', '1px solid #ffffff10')};
border-bottom: ${cssManager.bdTheme('1px solid #CCC', '1px solid #222')};
transition: all 0.2s ease;
font-size: 16px;
color: ${cssManager.bdTheme('#222', '#ccc')};
}
.accentTop {
border-top: 1px solid #e4002b;
.selectedBox:hover {
filter: ${cssManager.bdTheme('brightness(0.95)', 'brightness(1.1)')};
}
.accentBottom {
border-bottom: 1px solid #e4002b;
filter: none !important;
}
.accentTop {
filter: none !important;
}
.selectionBox {
will-change: transform;
pointer-events: none;
cursor: pointer;
transition: all 0.2s ease;
opacity: 0;
background: ${cssManager.bdTheme('#ffffff', '#222222')};
max-width: 420px;
box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2);
min-height: 40px;
border-radius: 3px;
padding: 4px;
transform: scale(0.99, 0.99);
border-radius: 8px;
padding: 4px 8px;
position: absolute;
user-select: none;
margin: 3px 0px 0px 0px;
border-top: ${cssManager.bdTheme('1px solid #CCC', '1px solid #ffffff10')};
}
.selectionBox.top {
transform: translate(0px, 4px);
}
.selectionBox.bottom {
transform: translate(0px, -4px);
}
.selectionBox.show {
pointer-events: all;
transform: scale(1, 1) translate(0px, 0px);
opacity: 1;
transform: scale(1, 1);
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.8);
}
.option {
transition: all 0.1s;
line-height: 40px;
line-height: 32px;
padding: 0px 4px;
border-radius: 3px;
margin: 4px 0px;
}
.option.highlighted {
border-left: 2px solid #0069f2;
padding-left: 6px;
background: #ffffff20;
}
.option:hover {
color: #fff;
padding-left: 8px;
background: #0277bd;
background: #0069f2;
}
.search {
padding: 8px;
.search.top {
padding-top: 4px;
}
.search.bottom {
padding-bottom: 4px;
}
.search input {
display: block;
width: 80%;
background: none;
border: none;
height: 24px;
color: inherit;
text-align: center;
text-align: left;
font-size: 12px;
font-weight: 600;
background: ${cssManager.bdTheme('#00000010', '#ffffff08')};
border-radius: 16px;
width: 100%;
margin: auto;
}
.search.top input {
border-bottom: 1px dotted #333;
}
.search.bottom input {
border-top: 1px dotted #333;
}
.search input:focus {
border: none;
outline: none;
}
`,
@ -169,20 +205,21 @@ export class DeesInputDropdown extends DeesElement {
public render(): TemplateResult {
return html`
<div class="maincontainer">
<div class="maincontainer" @keydown="${this.isOpened ? this.handleKeyDown : undefined}">
${this.label ? html`<div class="label">${this.label}</div>` : html``}
<div class="selectionBox">
${this.enableSearch && !this.opensToTop
? html`
<div class="search">
<input type="text" placeholder="Search" />
<div class="search top">
<input type="text" placeholder="Search" @input="${this.handleSearch}" />
</div>
`
: null}
${this.options.map((option) => {
${this.filteredOptions.map((option, index) => {
const isHighlighted = this.highlightedIndex === index;
return html`
<div
class="option"
class="option ${isHighlighted ? 'highlighted' : ''}"
@click=${() => {
this.updateSelection(option);
}}
@ -193,8 +230,8 @@ export class DeesInputDropdown extends DeesElement {
})}
${this.enableSearch && this.opensToTop
? html`
<div class="search">
<input type="text" placeholder="Search" />
<div class="search bottom">
<input type="text" placeholder="Search" @input="${this.handleSearch}" />
</div>
`
: null}
@ -209,14 +246,15 @@ export class DeesInputDropdown extends DeesElement {
}
}}"
>
${this.selectedOption?.option}
${this.selectedOption?.option || 'Select...'}
</div>
</div>
`;
}
firstUpdated() {
this.selectedOption = this.selectedOption || this.options[0] || null;
this.selectedOption = this.selectedOption || null;
this.filteredOptions = this.options; // Initialize filteredOptions
}
public async updateSelection(selectedOption) {
@ -237,6 +275,7 @@ export class DeesInputDropdown extends DeesElement {
private isElevated: boolean = false;
private windowOverlay: DeesWindowLayer;
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');
@ -256,7 +295,12 @@ export class DeesInputDropdown extends DeesElement {
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();
@ -276,26 +320,56 @@ export class DeesInputDropdown extends DeesElement {
} else {
if (!selectionBox.classList.contains('show')) {
selectionBox.style.width = selectedBox.clientWidth + 'px';
selectionBox.classList.add('show');
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();
searchInput?.focus();
selectionBox.classList.add('show');
} else {
selectedBox.style.pointerEvents = 'none';
selectionBox.classList.remove('show');
selectedBox.style.opacity = '0';
// 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

@ -1,3 +1,8 @@
import * as colors from './00colors.js';
import * as plugins from './00plugins.js';
import { DeesContextmenu } from './dees-contextmenu.js';
import {
customElement,
DeesElement,
@ -19,7 +24,8 @@ declare global {
@customElement('dees-input-fileupload')
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
public changeSubject = new domtools.plugins.smartrx.rxjs.Subject();
@ -70,6 +76,7 @@ export class DeesInputFileupload extends DeesElement {
display: grid;
margin: 10px 0px;
margin-bottom: 24px;
color: ${cssManager.bdTheme('#333', '#ccc')};
}
.hidden {
@ -77,31 +84,15 @@ export class DeesInputFileupload extends DeesElement {
}
.maincontainer {
color: ${cssManager.bdTheme('#333', '#ccc')};
}
.label {
font-size: 14px;
margin-bottom: 5px;
}
.uploadButton {
position: relative;
cursor: pointer;
padding: 8px;
max-width: 600px;
background: ${cssManager.bdTheme('#fafafa', '#333333')};
border-radius: 3px;
text-align: center;
padding: 8px;
background: ${cssManager.bdTheme('#fafafa', '#222222')};
color: ${cssManager.bdTheme('#333', '#ccc')};
border-top: 1px solid #ffffff10;
}
.uploadButton:hover {
color: #fff;
background: rgb(3, 155, 229);
}
.uploadButton::after {
.maincontainer::after {
top: 2px;
right: 2px;
left: 2px;
@ -112,28 +103,71 @@ export class DeesInputFileupload extends DeesElement {
display: block;
border: 2px dashed rgba(255, 255, 255, 0);
transition: all 0.2s;
pointer-events: none;
background: #00000000;
}
.uploadButton.dragOver::after {
.maincontainer.dragOver::after {
transform: scale3d(1, 1, 1);
border: 2px dashed rgba(255, 255, 255, 0.3);
background: #00000080;
}
.label {
font-size: 14px;
margin-bottom: 8px;
}
.uploadButton {
position: relative;
padding: 8px;
max-width: 600px;
background: ${cssManager.bdTheme('#fafafa', '#333333')};
border-radius: 3px;
text-align: center;
font-size: 14px;
cursor: default;
}
.uploadButton:hover {
color: #fff;
background: ${unsafeCSS(colors.dark.blue)};
}
.uploadCandidate {
display: grid;
grid-template-columns: 48px auto;
background: #333;
padding: 8px 8px 8px 0px;
margin-bottom: 8px;
text-align: left;
border-bottom: 1px dashed #444;
border-radius: 3px;
color: ${cssManager.bdTheme('#666', '#ccc')};
padding: 8px;
font-family: 'Roboto', 'Inter', sans-serif;
}
.uploadButton:hover .uploadCandidate {
color: ${cssManager.bdTheme('#fff', '#fff')};
border-bottom: 1px dashed #fff;
cursor: default;
transition: all 0.2s;
border-top: 1px solid #ffffff10;
}
.uploadCandidate:last-child {
margin-bottom: 8px;
}
.uploadCandidate .icon {
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
}
.uploadCandidate:hover {
background: #393939;
}
.uploadCandidate .description {
font-size: 14px;
border-left: 1px solid #ffffff10;
padding-left: 8px;
}
`,
];
@ -142,10 +176,32 @@ export class DeesInputFileupload extends DeesElement {
<div class="hidden">
<input type="file"></div>
</div>
<div class="maincontainer">
${this.label ? html`<div class="label">${this.label}</div>` : null}
${this.value.map((fileArg) => html` <div class="uploadCandidate">${fileArg.name} | ${fileArg.size}</div> `)}
<div class="uploadButton ${this.state === 'dragOver' ? 'dragOver' : ''}" @click=${this.openFileSelector}>
${this.label ? html`<div class="label">${this.label}</div>` : null}
<div class="maincontainer ${this.state === 'dragOver' ? 'dragOver' : ''}">
${this.value.map(
(fileArg) => html`
<div class="uploadCandidate" @contextmenu=${eventArg => {
DeesContextmenu.openContextMenuWithOptions(eventArg, [{
iconName: 'trash',
name: 'Remove',
action: async () => {
this.value.splice(this.value.indexOf(fileArg), 1);
this.requestUpdate();
}
}]);
}}>
<div class="icon">
<dees-icon .iconFA=${'paperclip'}></dees-icon>
</div>
<div class="description">
<span style="font-weight: 600">${fileArg.name}</span><br />
<span style="font-weight: 400">${fileArg.size}</span>
</div>
</div> `
)}
<div class="uploadButton" @click=${
this.openFileSelector
}>
${this.buttonText}
</div>
</div>
@ -158,7 +214,6 @@ export class DeesInputFileupload extends DeesElement {
this.state = 'idle';
this.buttonText = 'Upload more files...';
}
public async updateValue(eventArg: Event) {
const target: any = eventArg.target;
@ -179,9 +234,8 @@ export class DeesInputFileupload extends DeesElement {
target.value = '';
});
// lets handle drag and drop
const dropArea = this.shadowRoot.querySelector('.uploadButton');
const dropArea = this.shadowRoot.querySelector('.maincontainer');
const handlerFunction = (eventArg: DragEvent) => {
eventArg.preventDefault();
switch (eventArg.type) {

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,153 @@
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: String,
})
public label: string;
@property({
type: String,
})
public description: string;
@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 {
display: block;
color: ${cssManager.bdTheme('#333', '#ccc')};
user-select: none;
margin: 8px 0px 24px 0px;
}
.label {
font-size: 14px;
margin-bottom: 8px;
}
.selections {
position: relative;
display: flex;
flex-direction: row;
flex-wrap: nowrap;
background: ${cssManager.bdTheme('#fff', '#222')};
width: min-content;
border-radius: 20px;
height: 32px;
border-top: 1px solid #ffffff10;
}
.option {
color: #ccc;
position: relative;
padding: 0px 16px;
line-height: 32px;
cursor: default;
width: min-content; /* Make the width as per the content */
white-space: nowrap; /* Prevent text wrapping */
transition: all 0.1s;
font-size: 14px;
transform: translateY(-1px);
}
.option:hover {
color: #fff;
}
.option.selected {
color: #fff;
}
.indicator {
opacity: 0;
position: absolute;
height: 24px;
left: 4px;
top: 3px;
border-radius: 16px;
background: #0050b9;
min-width: 36px;
}
`,
];
public render(): TemplateResult {
return html`
<dees-label .label=${this.label} .description=${this.description}></dees-label>
<div class="mainbox">
<div class="selections">
<div class="indicator"></div>
${this.options.map(
(option) =>
html`<div class="option ${option === this.selectedOption ? 'selected': ''}" @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

@ -85,7 +85,6 @@ export class DeesInputQuantitySelector extends DeesElement {
}
.selector:hover {
cursor: pointer;
}
.quantity {

View File

@ -51,7 +51,6 @@ export class DeesInputRadio extends DeesElement {
display: block;
position: relative;
margin: 20px 0px;
cursor: pointer;
}
.maincontainer {
@ -91,8 +90,8 @@ export class DeesInputRadio extends DeesElement {
}
.checkbox.selected {
background: #039BE5;
border: 1px solid #039BE5;
background: #0050b9;
border: 1px solid #0050b9;
}
.maincontainer:hover .checkbox.selected {

View File

@ -1,3 +1,5 @@
import * as colors from './00colors.js';
import {
customElement,
DeesElement,
@ -31,6 +33,11 @@ export class DeesInputText extends DeesElement {
})
public label: string;
@property({
type: String,
})
public description: string;
@property({
type: String,
reflect: true,
@ -98,16 +105,11 @@ export class DeesInputText extends DeesElement {
color: ${cssManager.bdTheme('#333', '#ccc')};
}
.label {
font-size: 14px;
margin-bottom: 4px;
}
input {
margin-top: 5px;
margin-top: 0px;
background: ${cssManager.bdTheme('#fafafa', '#222')};
border-top: ${cssManager.bdTheme('1px solid #CCC', '1px solid #444')};
border-bottom: ${cssManager.bdTheme('1px solid #CCC', '1px solid #333')};
border-top: ${cssManager.bdTheme('1px solid #CCC', '1px solid #ffffff10')};
border-bottom: ${cssManager.bdTheme('1px solid #CCC', '1px solid #222')};
border-right: ${cssManager.bdTheme('1px solid #CCC', 'none')};
border-left: ${cssManager.bdTheme('1px solid #CCC', 'none')};
padding-left: 10px;
@ -120,7 +122,7 @@ export class DeesInputText extends DeesElement {
font-size: 16px;
position: relative;
z-index: 2;
// see template for more
cursor: default;
}
input:disabled {
@ -132,7 +134,12 @@ export class DeesInputText extends DeesElement {
input:focus {
outline: none;
border-bottom: 1px solid #e4002b;
border-bottom: 1px solid ${cssManager.bdTheme( colors.bright.blueActive, colors.dark.blueActive)};
cursor: text;
}
input:hover {
filter: ${cssManager.bdTheme('brightness(0.95)', 'brightness(1.1)')};
}
.showPassword {
@ -147,7 +154,6 @@ export class DeesInputText extends DeesElement {
}
.showPassword:hover {
cursor: pointer;
background: ${cssManager.bdTheme('#00000010', '#ffffff10')};
}
@ -188,7 +194,7 @@ export class DeesInputText extends DeesElement {
`}
</style>
<div class="maincontainer">
${this.label ? html`<div class="label">${this.label}</div>` : html``}
<dees-label .label=${this.label} .description=${this.description}></dees-label>
<input
type="${this.isPasswordBool && !this.showPasswordBool ? 'password' : 'text'}"
.value=${this.value}

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,98 @@
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;
// INSTANCE
@property({
type: String,
})
public label: string;
constructor() {
super();
}
public static styles = [
cssManager.defaultStyles,
css`
:host {
display: block;
color: ${cssManager.bdTheme('#333', '#fff')};
margin: 8px 0px 24px 0px;
}
.label {
font-size: 14px;
margin-bottom: 8px;
}
.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">${this.label}</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

@ -0,0 +1,7 @@
import { html, cssManager } from '@design.estate/dees-element';
export const demoFunc = () => {
return html`
<dees-label .label=${'a label'}></dees-label>
`;
}

View File

@ -0,0 +1,70 @@
import * as plugins from './00plugins.js';
import * as colors from './00colors.js';
import {
customElement,
html,
css,
cssManager,
DeesElement,
property,
unsafeCSS,
query,
} from '@design.estate/dees-element';
import { demoFunc } from './dees-label.demo.js';
@customElement('dees-label')
export class DeesLabel extends DeesElement {
public static demo = demoFunc;
// INSTANCE
@property({
type: String,
reflect: true,
})
public label = '';
@property({
type: String,
reflect: true,
})
public description: string;
public static styles = [
cssManager.defaultStyles,
css`
.label {
color: ${cssManager.bdTheme('#333', '#ccc')};
font-size: 14px;
margin-bottom: 8px;
cursor: default;
user-select: none;
}
dees-icon {
display: inline-block;
font-size: 14px;
transform: translateY(1.5px);
}
`,
];
public render() {
return html`
${this.label
? html`
<div class="label">
${this.label}
${this.description
? html`
<dees-icon .iconFA=${'circleInfo'}></dees-icon>
<dees-speechbubble .text=${this.description}></dees-speechbubble>
`
: html``}
</div>
`
: html``}
`;
}
}

View File

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

View File

@ -1,4 +1,6 @@
import * as plugins from './plugins.js';
import * as colors from './00colors.js';
import * as plugins from './00plugins.js';
import { demoFunc } from './dees-modal.demo.js';
import {
customElement,
@ -123,20 +125,35 @@ export class DeesModal extends DeesElement {
padding: 16px;
}
.modal .bottomButtons {
display: grid;
display: flex;
flex-direction: row;
border-top: 1px solid #222;
justify-content: flex-end;
}
.modal .bottomButtons .bottomButton {
height: 40px;
line-height: 40px;
margin: 8px 0px;
padding: 8px 12px;
border-radius: 4px;
line-height: 16px;
text-align: center;
font-size: 14px;
border-right: 1px solid #222;
cursor: pointer;
cursor: default;
user-select: none;
}
.modal .bottomButtons .bottomButton:first-child {
margin-left: 8px;
}
.modal .bottomButtons .bottomButton:last-child {
margin-right: 8px;
}
.modal .bottomButtons .bottomButton:hover {
background: #222;
background: ${cssManager.bdTheme(colors.bright.blue, colors.dark.blue)};
}
.modal .bottomButtons .bottomButton:active {
background: ${cssManager.bdTheme(colors.bright.blueActive, colors.dark.blueActive)};
}
.modal .bottomButtons .bottomButton:last-child {
border-right: none;

View File

@ -57,18 +57,9 @@ export class DeesPdf extends DeesElement {
if (!DeesPdf.pdfJsReady) {
const pdfJsReadyDeferred = domtools.plugins.smartpromise.defer();
DeesPdf.pdfJsReady = pdfJsReadyDeferred.promise;
const loadDeferred = domtools.plugins.smartpromise.defer();
const script = document.createElement('script');
script.addEventListener('load', () => {
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';
// @ts-ignore
DeesPdf.pdfjsLib = await import('https://cdn.jsdelivr.net/npm/pdfjs-dist@4.0.379/+esm');
DeesPdf.pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdn.jsdelivr.net/npm/pdfjs-dist@4.0.379/build/pdf.worker.mjs';
pdfJsReadyDeferred.resolve();
}
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

@ -35,7 +35,7 @@ export class DeesSimpleAppDash extends DeesElement {
user-select: none;
}
.appbar {
position: absolute;
position: fixed;
top: 0;
height: 40px;
width: 100%;
@ -47,10 +47,12 @@ export class DeesSimpleAppDash extends DeesElement {
padding: 0px 16px;
}
.appcontent {
position: absolute;
position: fixed;
top: 40px;
bottom: 0;
height: calc(100% - 40px);
bottom: 0px;
width: 100%;
overflow: auto;
background: ${cssManager.bdTheme('#eeeeeb', '#000')};
}
`,

View File

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

View File

@ -0,0 +1,23 @@
import { html, cssManager } from '@design.estate/dees-element';
export const demoFunc = () => {
return html`
<style>
.ref1 {
margin: 20px;
width: 10px;
height: 10px;
background-color: red;
}
</style>
<div class="ref1"></div>
<dees-speechbubble .text=${`
**This is a longer markdown text that can be used the write**
a longer description about whats going on the app
**This is a subheader**
and another text
`}></dees-speechbubble>
`;
};

View File

@ -1,3 +1,7 @@
import * as colors from './00colors.js';
import * as plugins from './00plugins.js';
import { demoFunc } from './dees-speechbubble.demo.js';
import {
customElement,
html,
@ -8,9 +12,11 @@ import {
css,
type CSSResult,
unsafeCSS,
domtools,
directives,
unsafeHTML,
} from '@design.estate/dees-element';
import * as domtools from '@design.estate/dees-domtools';
import { DeesWindowLayer } from './dees-windowlayer.js';
declare global {
interface HTMLElementTagNameMap {
@ -20,26 +26,53 @@ declare global {
@customElement('dees-speechbubble')
export class DeesSpeechbubble extends DeesElement {
public static demo = () => html` <dees-speechbubble></dees-speechbubble> `;
public static demo = demoFunc;
@property()
// STATIC
public static async createAndShow(refElement: HTMLElement, textArg: string) {
const windowLayer = await DeesWindowLayer.createAndShow({
blur: false,
});
const speechbubble = document.createElement('dees-speechbubble');
speechbubble.windowLayer = windowLayer;
speechbubble.reffedElement = refElement;
speechbubble.text = textArg;
speechbubble.manifested = true;
windowLayer.appendChild(speechbubble);
windowLayer.style.pointerEvents = 'none';
(windowLayer.shadowRoot.querySelector('.windowOverlay') as HTMLElement).style.pointerEvents = 'none';
return speechbubble;
}
// INSTANCE
@property({
type: Object,
})
reffedElement: HTMLElement;
@property({
type: String,
reflect: true,
})
public text: string;
@property({
type: Boolean,
})
public disabled = false;
public wave: boolean = false;
@property({
type: Boolean,
})
public isHidden = false;
public manifested = false;
@property({
type: String,
})
public status: 'normal' | 'pending' | 'success' | 'error' = 'normal';
public windowLayer: DeesWindowLayer;
constructor() {
super();
}
@ -48,28 +81,22 @@ export class DeesSpeechbubble extends DeesElement {
cssManager.defaultStyles,
css`
:host {
position: relative;
display: block;
box-sizing: border-box;
color: ${cssManager.bdTheme('#333', '#fff')};
cursor: pointer;
user-select: none;
}
:host([hidden]) {
display: none;
}
.maincontainer {
position: relative;
will-change: transform;
transition: transform 0.2s;
transform: translateX(0px);
position: relative;
transition: all 0.2s;
margin-left: 0px;
}
.maincontainer:hover {
transform: translateX(3px);
filter: drop-shadow(0px 0px 2px rgba(0, 0, 0, 0.2));
pointer-events: none;
opacity: 0;
transition: all 0.2s;
}
.arrow {
@ -78,17 +105,17 @@ export class DeesSpeechbubble extends DeesElement {
background: ${cssManager.bdTheme('#fff', '#333')};
height: 15px;
width: 15px;
left: 4px;
top: 5px;
border-radius: 2px;
left: 2px;
top: 12px;
border-radius: 3px;
}
.speechbubble {
background: ${cssManager.bdTheme('#fff', '#333')};
padding: 0px 10px;
padding: 0px 16px;
border-radius: 3px;
position: absolute;
line-height: 25px;
min-width: 240px;
font-size: 12px;
top: 0px;
left: 8px;
@ -133,25 +160,70 @@ export class DeesSpeechbubble extends DeesElement {
public render(): TemplateResult {
return html`
<div class="maincontainer" @click=${this.handleClick}>
<div class="arrow"></div>
<div class="speechbubble"><span class="wave">👋</span> We build with launch.sh, and you can too.</div>
</div>
${this.manifested
? html`
<div class="maincontainer" @click=${this.handleClick}>
<div class="arrow"></div>
<div class="speechbubble">
${this.wave ? html`<span class="wave">👋</span>` : html``}
${directives.resolve(this.getHtml())}
</div>
</div>
`
: html``}
`;
}
public async handleClick() {
if (this.disabled) {
return;
}
globalThis.location.href = "https://launch.sh"
console.log('speechbubble got clicked.');
}
public async firstUpdated() {
if (!this.textContent) {
this.textContent = 'Button';
this.performUpdate();
// lets make sure we have a ref
if (!this.reffedElement) {
this.reffedElement = this.previousElementSibling as HTMLElement;
}
if (this.manifested) {
await this.updatePosition();
(this.shadowRoot.querySelector('.maincontainer') as HTMLElement).style.opacity = '1';
} else {
// lets make sure we instrument it
let speechbubble: DeesSpeechbubble;
this.reffedElement.addEventListener('mouseenter', async () => {
speechbubble = await DeesSpeechbubble.createAndShow(this.reffedElement, this.text);
});
this.reffedElement.addEventListener('mouseleave', () => {
speechbubble.destroy();
});
}
}
public async updatePosition() {
const refElement = this.reffedElement;
const boundingClientRect = refElement.getBoundingClientRect();
this.style.position = 'fixed';
this.style.top = `${boundingClientRect.top - 13}px`;
this.style.left = `${boundingClientRect.left + refElement.clientWidth + 4}px`;
if (boundingClientRect.right > 250) {
this.style.width = `250px`;
}
}
public async getHtml(): Promise<any> {
if (!this.text) {
return '';
}
const normalized = domtools.plugins.smartstring.normalize.standard(this.text);
const result = await domtools.plugins.smartmarkdown.SmartMarkdown.easyMarkdownToHtml(
normalized
);
return unsafeHTML(result);
}
public async show() {}
public async destroy() {
(this.shadowRoot.querySelector('.maincontainer') as HTMLElement).style.opacity = '0';
this.windowLayer.destroy();
}
}

View File

@ -1,3 +1,6 @@
import * as plugins from './00plugins.js';
import * as colors from './00colors.js';
import {
DeesElement,
customElement,
@ -99,7 +102,7 @@ export class DeesStepper extends DeesElement {
transition: all 0.7s ease-in-out;
max-width: 500px;
min-height: 300px;
border-radius: 3px;
border-radius: 8px;
background: ${cssManager.bdTheme('#ffffff', '#181818')};
border-top: 1px solid ${cssManager.bdTheme('#ffffff', '#181818')};
color: ${cssManager.bdTheme('#333', '#fff')};
@ -127,6 +130,7 @@ export class DeesStepper extends DeesElement {
}
.step .stepCounter {
color: #999;
position: absolute;
top: 0px;
right: 0px;
@ -137,6 +141,8 @@ export class DeesStepper extends DeesElement {
}
.step .goBack {
color: #999;
cursor: default;
position: absolute;
top: 0px;
left: 0px;
@ -144,11 +150,25 @@ export class DeesStepper extends DeesElement {
font-size: 12px;
border-bottom-right-radius: 3px;
background: ${cssManager.bdTheme('#00000008', '#ffffff08')};
cursor: pointer;
}
.step .goBack:hover {
background: ${cssManager.bdTheme('#00000012', '#ffffff12')};
color: ${cssManager.bdTheme('#333', '#fff')};
background: ${cssManager.bdTheme('#00000012', colors.dark.blue)};
}
.step .goBack:active {
color: ${cssManager.bdTheme('#333', '#fff')};
background: ${cssManager.bdTheme('#00000012', colors.dark.blueActive)};
}
.step .goBack span {
transition: all 0.2s;
display: inline-block;
}
.step .goBack:hover span {
transform: translateX(-2px);
}
.step .title {
@ -178,7 +198,7 @@ export class DeesStepper extends DeesElement {
: ''}"
>
${this.getIndexOfStep(stepArg) > 0
? html`<div class="goBack" @click=${this.goBack}><- go to previous step</div>`
? html`<div class="goBack" @click=${this.goBack}><span style="font-family: Inter"><-</span> go to previous step</div>`
: ``}
<div class="stepCounter">
Step ${this.steps.findIndex((elementArg) => elementArg === stepArg) + 1} of

View File

@ -1,5 +1,5 @@
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';
interface ITableDemoData {

View File

@ -1,4 +1,5 @@
import * as plugins from './plugins.js';
import * as colors from './00colors.js';
import * as plugins from './00plugins.js';
import { demoFunc } from './dees-table.demo.js';
import {
customElement,
@ -116,12 +117,21 @@ export class DeesTable<T> extends DeesElement {
public changeSubject = new domtools.plugins.smartrx.rxjs.Subject<DeesTable<T>>();
// end dees-form compatibility -----------------------------------------
/**
* What does a row of data represent?
*/
@property({
type: String,
reflect: true,
})
public dataName: string;
@property({
type: Boolean,
})
searchable: boolean = true;
@property({
type: Array,
})
@ -168,11 +178,12 @@ export class DeesTable<T> extends DeesElement {
display: block;
width: 100%;
min-height: 50px;
background: ${cssManager.bdTheme('#ffffff', '#333333')};
background: ${cssManager.bdTheme('#ffffff', '#222222')};
border-radius: 3px;
border-top: 1px solid ${cssManager.bdTheme('#fff', '#444')};
border-top: 1px solid ${cssManager.bdTheme('#fff', '#ffffff10')};
box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.3);
overflow-x: auto;
cursor: default;
}
.header {
@ -197,16 +208,20 @@ export class DeesTable<T> extends DeesElement {
.headingSeparation {
margin-top: 7px;
border-bottom: 1px solid ${cssManager.bdTheme('#bcbcbc', '#bcbcbc')};
border-bottom: 1px solid ${cssManager.bdTheme('#bcbcbc', '#444444')};
}
.headerActions {
user-select: none;
display: flex;
flex-direction: row;
margin-left: auto;
cursor: pointer;
}
.headerAction {
display: flex;
flex-direction: row;
color: ${cssManager.bdTheme('#333', '#ccc')};
margin-left: 16px;
}
.headerAction:hover {
@ -217,6 +232,24 @@ export class DeesTable<T> extends DeesElement {
margin-right: 8px;
}
.searchGrid {
background: ${cssManager.bdTheme('#fff', '#111111')};
display: grid;
grid-gap: 16px;
grid-template-columns: 1fr 200px;
margin-top: 16px;
padding: 0px 16px;
border-top: 1px solid ${cssManager.bdTheme('#fff', '#ffffff20')};
border-radius: 8px;
}
.searchGrid.hidden {
height: 0px;
opacity: 0;
overflow: hidden;
margin-top: 0px;
}
table,
.noDataSet {
margin-top: 16px;
@ -236,7 +269,6 @@ export class DeesTable<T> extends DeesElement {
text-align: left;
}
tr:hover {
cursor: pointer;
}
tr:hover td {
background: ${cssManager.bdTheme('#22222210', '#ffffff10')};
@ -305,22 +337,32 @@ export class DeesTable<T> extends DeesElement {
font-weight: inherit;
padding: 0px 6px;
}
.action {
margin: -6px 0px;
padding: 10px;
line-height: 36px;
height: 36px;
display: inline-block;
.actionsContainer {
display: flex;
flex-direction: row;
height: 24px;
transform: translateY(-4px);
margin-left: -6px;
}
.action:first-child {
margin-left: -8px;
width: min-content;
.action {
position: relative;
padding: 8px 10px;
line-height: 24px;
height: 32px;
size: 16px;
border-radius: 8px;
}
.action:hover {
background: ${cssManager.bdTheme('#CCC', '#00000030')};
background: ${cssManager.bdTheme(colors.bright.blue, colors.dark.blue)};
}
.action:active {
background: ${cssManager.bdTheme(colors.bright.blue, colors.dark.blueActive)};
}
.action:hover dees-icon {
filter: ${cssManager.bdTheme('invert(1) brightness(3)', '')};
}
.footer {
@ -343,19 +385,23 @@ export class DeesTable<T> extends DeesElement {
}
.footerActions .footerAction {
cursor: pointer;
padding: 8px 16px;
display: flex;
user-select: none;
}
.footerActions .footerAction:hover {
background: ${cssManager.bdTheme('#CCC', '#111')};
background: ${cssManager.bdTheme(colors.bright.blue, colors.dark.blue)};
color: #fff;
}
.footerActions dees-icon {
.footerActions .footerAction dees-icon {
display: flex;
margin-right: 8px;
}
.footerActions .footerAction:hover dees-icon {
}
`,
];
@ -395,8 +441,32 @@ export class DeesTable<T> extends DeesElement {
</div>
</div>
<div class="headingSeparation"></div>
<dees-input-text></dees-input-text>
<div class="searchGrid hidden">
<dees-input-text
.label=${'lucene syntax search'}
.description=${`
You can use the lucene syntax to search for data, e.g.:
\`\`\`
name: "john" AND age: 18
\`\`\`
`}
></dees-input-text>
<dees-input-multitoggle
.label=${'search mode'}
.options=${['table', 'data', 'server']}
.selectedOption=${'table'}
.description=${`
There are three basic modes:
* table: only searches data already in the table
* data: searches original data, ignoring table transforms
* server: searches data on the server
`}
></dees-input-multitoggle>
</div>
<!-- the actual table -->
<style></style>
@ -523,22 +593,28 @@ export class DeesTable<T> extends DeesElement {
return html`
<td>
<div class="innerCellContainer">
${this.getActionsForType('inRow').map(
(actionArg) => html`<div
class="action"
@click=${() =>
actionArg.actionFunc({
item: itemArg,
table: this,
})}
>
${actionArg.iconName
? html`
<dees-icon .iconFA=${actionArg.iconName}></dees-icon>
`
: actionArg.name}
</div>`
)}
<div class="actionsContainer">
${this.getActionsForType('inRow').map(
(actionArg) => html`
<div
class="action"
@click=${() =>
actionArg.actionFunc({
item: itemArg,
table: this,
})}
>
${actionArg.iconName
? html`
<dees-icon
.iconFA=${actionArg.iconName}
></dees-icon>
`
: actionArg.name}
</div>
`
)}
</div>
</div>
</td>
`;
@ -587,11 +663,30 @@ export class DeesTable<T> extends DeesElement {
`;
}
public async firstUpdated() {}
public async firstUpdated() {
}
public async updated(changedProperties: Map<string | number | symbol, unknown>): Promise<void> {
super.updated(changedProperties);
this.determineColumnWidths();
if (this.searchable) {
const existing = this.dataActions.find((actionArg) => actionArg.type.includes('header') && actionArg.name === 'Search');
if (!existing) {
this.dataActions.unshift({
name: 'Search',
iconName: 'magnifyingGlass',
type: ['header'],
actionFunc: async () => {
console.log('open search');
const searchGrid = this.shadowRoot.querySelector('.searchGrid');
searchGrid.classList.toggle('hidden');
}
});
console.log(this.dataActions);
this.requestUpdate();
};
}
}
public async determineColumnWidths() {
@ -612,7 +707,7 @@ export class DeesTable<T> extends DeesElement {
const width = window.getComputedStyle(cell).width;
if (cell.textContent.includes('Actions')) {
const neededWidth =
this.dataActions.filter((actionArg) => actionArg.type.includes('inRow')).length * 35;
this.dataActions.filter((actionArg) => actionArg.type.includes('inRow')).length * 36;
cell.style.width = `${Math.max(neededWidth, 68)}px`;
} else {
cell.style.width = width;

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 * as domtools from '@design.estate/dees-domtools';
import {
customElement,
DeesElement,
type TemplateResult,
html,
property,
type CSSResult,
domtools,
} from '@design.estate/dees-element';
import { demoFunc } from './dees-updater.demo.js';
import './dees-windowlayer';
import { css, cssManager } from '@design.estate/dees-element';
@ -14,7 +20,13 @@ declare global {
@customElement('dees-updater')
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({
type: String,
@ -35,56 +47,64 @@ export class DeesUpdater extends DeesElement {
cssManager.defaultStyles,
css`
.modalContainer {
will-change: transform;
position: relative;
background: ${cssManager.bdTheme('#eeeeeb', '#222')};
margin: auto;
max-width: 800px;
border-radius: 3px;
border-top: 1px solid ${cssManager.bdTheme('#eeeeeb', '#333')};
}
will-change: transform;
position: relative;
background: ${cssManager.bdTheme('#eeeeeb', '#222')};
max-width: 800px;
border-radius: 8px;
border-top: 1px solid ${cssManager.bdTheme('#eeeeeb', '#333')};
}
.headingContainer {
display: flex;
justify-content: center;
align-items: center;
padding: 40px 40px;
}
.headingContainer {
display: flex;
justify-content: center;
align-items: center;
padding: 40px 40px;
}
h1 {
margin: none;
font-size: 20px;
color: ${cssManager.bdTheme('#333', '#fff')};
margin-left: 20px;
font-weight: normal;
}
h1 {
margin: none;
font-size: 20px;
color: ${cssManager.bdTheme('#333', '#fff')};
margin-left: 20px;
font-weight: normal;
}
.buttonContainer {
display: grid;
grid-template-columns: 50% 50%;
}
`
]
.buttonContainer {
display: grid;
grid-template-columns: 50% 50%;
}
`,
];
public render(): TemplateResult {
return html`
<dees-windowlayer @clicked="${this.windowLayerClicked}">
<dees-windowlayer
@clicked="${this.windowLayerClicked}"
.options=${{
blur: true,
}}
>
<div class="modalContainer">
<div class="headingContainer">
<dees-spinner .size=${60}></dees-spinner>
<h1>Updating the application...</h1>
</div>
<div class="progress">
<dees-progressbar .progress=${0.5}></dees-progressbar>
</div>
<div class="buttonContainer">
<dees-button>More info</dees-button>
<dees-button>Changelog</dees-button>
</div>
</div>
</dees-windowlayer>>
</div> </dees-windowlayer
>>
`;
}
private windowLayerClicked() {
const windowLayer = this.shadowRoot.querySelector('dees-windowlayer');
windowLayer.toggleVisibility();
public async destroy() {
this.parentElement.removeChild(this);
}
private windowLayerClicked() {}
}

View File

@ -19,18 +19,37 @@ declare global {
@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 {
position: absolute;
top: 6px;
left: 20px;
width: 200px;
display: grid;
grid-template-columns: 24px 24px 24px;
height: 100%;
position: relative;
display: flex;
justify-content: center;
align-items: center;
}
.windowControls div {
@ -40,16 +59,17 @@ export class DeesWindowControls extends DeesElement {
border-radius: 50%;
margin: 0px;
padding: 0px;
cursor: pointer;
background: #222222;
}
.windowControls div.close {
background: #ff5f57;
margin-right: 12px;
}
.windowControls div.toDock {
background: #ffbd2e;
margin-right: 12px;
}
.windowControls div.minMax {
@ -64,11 +84,16 @@ export class DeesWindowControls extends DeesElement {
public render(): TemplateResult {
return html`
<div class="windowControls">
<div class="close"></div>
<div class="toDock"></div>
<div class="minMax"></div>
</div>
${(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

@ -12,12 +12,16 @@ export * from './dees-input-checkbox.js';
export * from './dees-input-dropdown.js';
export * from './dees-input-fileupload.js';
export * from './dees-input-iban.js';
export * from './dees-input-typelist.js';
export * from './dees-input-phone.js';
export * from './dees-progressbar.js';
export * from './dees-input-quantityselector.js';
export * from './dees-input-radio.js';
export * from './dees-input-text.js';
export * from './dees-label.js';
export * from './dees-mobilenavigation.js';
export * from './dees-modal.js';
export * from './dees-input-multitoggle.js';
export * from './dees-pdf.js';
export * from './dees-simple-appdash.js';
export * from './dees-simple-login.js';