Compare commits
42 Commits
Author | SHA1 | Date | |
---|---|---|---|
64f5bee801 | |||
9d57f983dd | |||
8ccd21df36 | |||
c22c994d12 | |||
01369444b7 | |||
4beb15f70c | |||
30170bcd2e | |||
f29a8de504 | |||
965ab02315 | |||
991784eae6 | |||
b474b7986c | |||
98542252cb | |||
0d78deadf2 | |||
5108f47e56 | |||
7d4e5f2ca7 | |||
c0ad0f4570 | |||
d56eb602a9 | |||
f1c791eb12 | |||
e872188be7 | |||
2d712e78b0 | |||
ebeecd0686 | |||
1d09f994c6 | |||
686c3714fc | |||
e29086036c | |||
78e24aa720 | |||
7c8876c835 | |||
2222fb1e01 | |||
46b30a1ef0 | |||
d49d5f70ef | |||
76a950e2ba | |||
077aba5e58 | |||
857362423f | |||
e7232b6a53 | |||
2eb26544b3 | |||
a40834d1cf | |||
0c1159d4c7 | |||
4584765046 | |||
5817068cb5 | |||
8fa01fbaad | |||
9cdae8ccdb | |||
7e1c5f3dbb | |||
1f3f17247c |
20
package.json
20
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@design.estate/dees-catalog",
|
||||
"version": "1.0.244",
|
||||
"version": "1.0.265",
|
||||
"private": false,
|
||||
"description": "website for lossless.com",
|
||||
"main": "dist_ts_web/index.js",
|
||||
@ -15,9 +15,9 @@
|
||||
"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.85",
|
||||
"@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",
|
||||
@ -26,18 +26,22 @@
|
||||
"@push.rocks/smartpromise": "^4.0.3",
|
||||
"@push.rocks/smartstring": "^4.0.13",
|
||||
"@tsclass/tsclass": "^4.0.46",
|
||||
"@webcontainer/api": "^1.1.8",
|
||||
"highlight.js": "11.9.0",
|
||||
"ibantools": "^4.3.8",
|
||||
"pdfjs-dist": "^4.0.379"
|
||||
"ibantools": "^4.3.9",
|
||||
"monaco-editor": "^0.45.0",
|
||||
"pdfjs-dist": "^4.0.379",
|
||||
"xterm": "^5.3.0",
|
||||
"xterm-addon-fit": "^0.8.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@git.zone/tsbuild": "^2.1.72",
|
||||
"@git.zone/tsbundle": "^2.0.14",
|
||||
"@git.zone/tstest": "^1.0.77",
|
||||
"@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.8"
|
||||
"@types/node": "^20.11.5"
|
||||
},
|
||||
"files": [
|
||||
"ts/**/*",
|
||||
|
1172
pnpm-lock.yaml
generated
1172
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@design.estate/dees-catalog',
|
||||
version: '1.0.244',
|
||||
version: '1.0.265',
|
||||
description: 'website for lossless.com'
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
export const dark = {
|
||||
blue: '#0050b9',
|
||||
blueActive: '#0069f2',
|
||||
blueMuted: '#012452',
|
||||
text: '#ffffff',
|
||||
}
|
||||
|
||||
export const bright = {
|
||||
blue: '#0050b9',
|
||||
blueActive: '#0069f2',
|
||||
blueMuted: '#0069f2',
|
||||
text: '#333333',
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
import { demoFunc } from './dees-contextmenu.demo.js';
|
||||
import * as colors from './00colors.js';
|
||||
import * as plugins from './00plugins.js';
|
||||
import { demoFunc } from './dees-contextmenu.demo.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,7 +133,7 @@ export class DeesContextmenu extends DeesElement {
|
||||
}
|
||||
|
||||
.mainbox .menuitem:hover {
|
||||
background: ${cssManager.bdTheme('#00000010', '#ffffff10')};
|
||||
background: ${cssManager.bdTheme(colors.bright.blue, colors.dark.blue)};
|
||||
}
|
||||
|
||||
.mainbox .menuitem:active {
|
||||
@ -156,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>
|
||||
|
@ -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>`;
|
||||
|
@ -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 {
|
||||
@ -64,12 +69,25 @@ export class DeesDataviewStatusobject extends DeesElement {
|
||||
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 {
|
||||
@ -85,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 {
|
||||
|
98
ts_web/elements/dees-editor-markdown.ts
Normal file
98
ts_web/elements/dees-editor-markdown.ts
Normal file
@ -0,0 +1,98 @@
|
||||
import {
|
||||
DeesElement,
|
||||
property,
|
||||
html,
|
||||
customElement,
|
||||
type TemplateResult,
|
||||
css,
|
||||
cssManager,
|
||||
domtools
|
||||
} from '@design.estate/dees-element';
|
||||
|
||||
const deferred = domtools.plugins.smartpromise.defer();
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'dees-editormarkdown': DeesEditorMarkdown;
|
||||
}
|
||||
}
|
||||
|
||||
@customElement('dees-editormarkdown')
|
||||
export class DeesEditorMarkdown extends DeesElement {
|
||||
public static demo = () => html`<dees-editormarkdown></dees-editormarkdown>`;
|
||||
|
||||
public static styles = [
|
||||
cssManager.defaultStyles,
|
||||
css`
|
||||
.gridcontainer {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: 60% 40%;
|
||||
}
|
||||
.editorContainer {
|
||||
position: relative;
|
||||
}
|
||||
.outletContainer {
|
||||
background: #111;
|
||||
color: #fff;
|
||||
font-family: 'Roboto Slab';
|
||||
padding: 20px;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
public render() {
|
||||
return html`
|
||||
<div class="gridcontainer">
|
||||
<div class="editorContainer">
|
||||
<dees-editor
|
||||
.language=${'markdown'}
|
||||
.content=${`# a test content
|
||||
|
||||
This is test content that is of longer form an hopefully starts to wrap when I need it. And yes, it does perfectly. nice.
|
||||
|
||||
Test | Hello
|
||||
--- | ---
|
||||
Yeah | So good
|
||||
|
||||
This is real asset I think. Why would we want to leave that on the table? Can you tell my that?
|
||||
|
||||
Why are we here?
|
||||
|
||||
Do you know?
|
||||
|
||||
> note:
|
||||
There is something going on.
|
||||
|
||||
\`\`\`typescript
|
||||
const hello = 'yes'
|
||||
\`\`\`
|
||||
`}
|
||||
wordWrap="bounded"
|
||||
></dees-editor>
|
||||
</div>
|
||||
<div class="outletContainer">
|
||||
<dees-editormarkdownoutlet></dees-editormarkdownoutlet>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
public async firstUpdated(_changedPropertiesArg) {
|
||||
await super.firstUpdated(_changedPropertiesArg);
|
||||
const editor = this.shadowRoot.querySelector('dees-editor');
|
||||
|
||||
// lets care about wiring the markdown stuff.
|
||||
const markdownOutlet = this.shadowRoot.querySelector('dees-editormarkdownoutlet');
|
||||
const smartmarkdownInstance = new domtools.plugins.smartmarkdown.SmartMarkdown();
|
||||
const mdParsedResult = await smartmarkdownInstance.getMdParsedResultFromMarkdown('loading...')
|
||||
editor.contentSubject.subscribe(async contentArg => {
|
||||
await mdParsedResult.updateFromMarkdownString(contentArg)
|
||||
const html = mdParsedResult.html;
|
||||
markdownOutlet.updateHtmlText(html);
|
||||
})
|
||||
}
|
||||
}
|
42
ts_web/elements/dees-editor-markdownoutlet.ts
Normal file
42
ts_web/elements/dees-editor-markdownoutlet.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { customElement, DeesElement, html, type TemplateResult } from '@design.estate/dees-element';
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'dees-editormarkdownoutlet': DeesEditorMarkdownOutlet;
|
||||
}
|
||||
}
|
||||
|
||||
@customElement('dees-editormarkdownoutlet')
|
||||
export class DeesEditorMarkdownOutlet extends DeesElement {
|
||||
// DEMO
|
||||
public static demo = () => html`<dees-editormarkdownoutlet></dees-editormarkdownoutlet>`;
|
||||
|
||||
// INSTANCE
|
||||
private outlet: HTMLElement;
|
||||
|
||||
public render(): TemplateResult {
|
||||
return html`
|
||||
<div class="outlet markdown-body">
|
||||
<h1>Hi there</h1>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
public async firstUpdated(_changedProperties: Map<string | number | symbol, unknown>) {
|
||||
await super.firstUpdated(_changedProperties);
|
||||
const styleElement = document.createElement('style');
|
||||
const cssText = await (
|
||||
await fetch('https://unpkg.com/github-markdown-css@5.1.0/github-markdown-dark.css')
|
||||
).text();
|
||||
styleElement.textContent = cssText;
|
||||
this.shadowRoot.append(styleElement);
|
||||
}
|
||||
|
||||
public async updateHtmlText(htmlTextArg: string) {
|
||||
await this.updateComplete;
|
||||
if (!this.outlet) {
|
||||
this.outlet = this.shadowRoot.querySelector('.outlet');
|
||||
}
|
||||
this.outlet.innerHTML = htmlTextArg;
|
||||
}
|
||||
}
|
126
ts_web/elements/dees-editor.ts
Normal file
126
ts_web/elements/dees-editor.ts
Normal file
@ -0,0 +1,126 @@
|
||||
import {
|
||||
DeesElement,
|
||||
property,
|
||||
html,
|
||||
customElement,
|
||||
type TemplateResult,
|
||||
css,
|
||||
cssManager,
|
||||
} from '@design.estate/dees-element';
|
||||
import * as domtools from '@design.estate/dees-domtools';
|
||||
|
||||
import type * as monaco from 'monaco-editor';
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'dees-editor': DeesEditor;
|
||||
}
|
||||
}
|
||||
|
||||
@customElement('dees-editor')
|
||||
export class DeesEditor extends DeesElement {
|
||||
// DEMO
|
||||
public static demo = () => html` <dees-editor></dees-editor> `;
|
||||
|
||||
// STATIC
|
||||
public static monacoDeferred: ReturnType<typeof domtools.plugins.smartpromise.defer>;
|
||||
|
||||
// INSTANCE
|
||||
public editorDeferred = domtools.plugins.smartpromise.defer<monaco.editor.IStandaloneCodeEditor>();
|
||||
public language = 'typescript';
|
||||
|
||||
@property({
|
||||
type: String
|
||||
})
|
||||
public content = "function hello() {\n\talert('Hello world!');\n}";
|
||||
|
||||
@property({
|
||||
type: Object
|
||||
})
|
||||
public contentSubject = new domtools.plugins.smartrx.rxjs.Subject<string>();
|
||||
|
||||
@property({
|
||||
type: Boolean
|
||||
})
|
||||
public wordWrap: monaco.editor.IStandaloneEditorConstructionOptions['wordWrap'] = 'off';
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
domtools.DomTools.setupDomTools();
|
||||
}
|
||||
|
||||
public static styles = [
|
||||
domtools.elementBasic.staticStyles,
|
||||
css`
|
||||
:host {
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#container {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
public render(): TemplateResult {
|
||||
return html`
|
||||
<div class="mainbox">
|
||||
<div id="container"></div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
public async firstUpdated(
|
||||
_changedProperties: Map<string | number | symbol, unknown>
|
||||
): Promise<void> {
|
||||
super.firstUpdated(_changedProperties);
|
||||
const container = this.shadowRoot.getElementById('container');
|
||||
|
||||
if (!DeesEditor.monacoDeferred) {
|
||||
DeesEditor.monacoDeferred = domtools.plugins.smartpromise.defer();
|
||||
const scriptUrl = `https://cdn.jsdelivr.net/npm/monaco-editor/min/vs/loader.js`;
|
||||
const script = document.createElement('script');
|
||||
script.src = scriptUrl;
|
||||
script.onload = () => {
|
||||
DeesEditor.monacoDeferred.resolve();
|
||||
};
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
await DeesEditor.monacoDeferred.promise;
|
||||
|
||||
(window as any).require.config({
|
||||
paths: { vs: 'https://cdn.jsdelivr.net/npm/monaco-editor/min/vs' },
|
||||
});
|
||||
(window as any).require(['vs/editor/editor.main'], async () => {
|
||||
const editor = ((window as any).monaco.editor as typeof monaco.editor).create(container, {
|
||||
value: this.content,
|
||||
language: this.language,
|
||||
theme: 'vs-dark',
|
||||
useShadowDOM: true,
|
||||
fontSize: 16,
|
||||
automaticLayout: true,
|
||||
wordWrap: this.wordWrap
|
||||
});
|
||||
this.editorDeferred.resolve(editor);
|
||||
});
|
||||
const css = await (
|
||||
await fetch('https://cdn.jsdelivr.net/npm/monaco-editor/min/vs/editor/editor.main.css')
|
||||
).text();
|
||||
const styleElement = document.createElement('style');
|
||||
styleElement.textContent = css;
|
||||
this.shadowRoot.append(styleElement);
|
||||
|
||||
|
||||
// editor is setup let do the rest
|
||||
const editor = await this.editorDeferred.promise;
|
||||
editor.onDidChangeModelContent(async eventArg => {
|
||||
this.contentSubject.next(editor.getValue());
|
||||
});
|
||||
this.contentSubject.next(editor.getValue());
|
||||
}
|
||||
}
|
@ -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">
|
||||
@ -35,8 +36,12 @@ export const demoFunc = () => html`
|
||||
{ option: 'option 2', key: 'option2' },
|
||||
{ option: 'option 3', key: 'option3' },
|
||||
]}></dees-input-multiselect>
|
||||
<dees-input-typelist></dees-input-typelist>
|
||||
<dees-input-text .required="${true}" key="hello1" label="a text"></dees-input-text>
|
||||
<dees-input-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}"
|
||||
@ -50,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>
|
||||
|
@ -52,10 +52,13 @@ import {
|
||||
faFileInvoiceDollar as faFileInvoiceDollarSolid,
|
||||
faGear as faGearSolid,
|
||||
faGrip as faGripSolid,
|
||||
faMagnifyingGlass as faMagnifyingGlassSolid,
|
||||
faMessage as faMessageSolid,
|
||||
faMoneyCheckDollar as faMoneyCheckDollarSolid,
|
||||
faMugHot as faMugHotSolid,
|
||||
faMinus as faMinusSolid,
|
||||
faNetworkWired as faNetworkWiredSolid,
|
||||
faPaperclip as faPaperclipSolid,
|
||||
faPaste as faPasteSolid,
|
||||
faPenToSquare as faPenToSquareSolid,
|
||||
faPlus as faPlusSolid,
|
||||
@ -64,6 +67,7 @@ import {
|
||||
faUsers as faUsersSolid,
|
||||
faShare as faShareSolid,
|
||||
faSun as faSunSolid,
|
||||
faTerminal as faTerminalSolid,
|
||||
faTrash as faTrashSolid,
|
||||
faTrashCan as faTrashCanSolid,
|
||||
faWallet as faWalletSolid,
|
||||
@ -96,11 +100,14 @@ export const faIcons = {
|
||||
fileInvoiceDoller: faFileInvoiceDollarSolid,
|
||||
gear: faGearSolid,
|
||||
grip: faGripSolid,
|
||||
magnifyingGlass: faMagnifyingGlassSolid,
|
||||
message: faMessageRegular,
|
||||
messageSolid: faMessageSolid,
|
||||
moneyCheckDollar: faMoneyCheckDollarSolid,
|
||||
mugHot: faMugHotSolid,
|
||||
minus: faMinusSolid,
|
||||
networkWired: faNetworkWiredSolid,
|
||||
paperclip: faPaperclipSolid,
|
||||
paste: faPasteRegular,
|
||||
pasteSolid: faPasteSolid,
|
||||
penToSquare: faPenToSquareSolid,
|
||||
@ -110,6 +117,7 @@ export const faIcons = {
|
||||
share: faShareSolid,
|
||||
sun: faSunRegular,
|
||||
sunSolid: faSunSolid,
|
||||
terminal: faTerminalSolid,
|
||||
trash: faTrashSolid,
|
||||
trashSolid: faTrashSolid,
|
||||
trashCan: faTrashCanRegular,
|
||||
|
@ -89,7 +89,7 @@ export class DeesInputDropdown extends DeesElement {
|
||||
|
||||
.label {
|
||||
font-size: 14px;
|
||||
margin-bottom: 4px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.selectedBox {
|
||||
@ -102,9 +102,11 @@ export class DeesInputDropdown extends DeesElement {
|
||||
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')};
|
||||
}
|
||||
|
||||
.selectedBox:hover {
|
||||
@ -132,6 +134,8 @@ export class DeesInputDropdown extends DeesElement {
|
||||
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);
|
||||
|
@ -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,30 +84,15 @@ export class DeesInputFileupload extends DeesElement {
|
||||
}
|
||||
|
||||
.maincontainer {
|
||||
color: ${cssManager.bdTheme('#333', '#ccc')};
|
||||
|
||||
}
|
||||
|
||||
.label {
|
||||
font-size: 14px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.uploadButton {
|
||||
position: relative;
|
||||
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;
|
||||
@ -111,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;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
@ -141,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>
|
||||
@ -157,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;
|
||||
@ -178,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) {
|
||||
|
@ -16,6 +16,16 @@ const { demoFunc } = await import('./dees-input-multitoggle.demo.js');
|
||||
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';
|
||||
|
||||
@ -40,41 +50,56 @@ export class DeesInputMultitoggle extends DeesElement {
|
||||
cssManager.defaultStyles,
|
||||
css`
|
||||
:host {
|
||||
color: ${cssManager.bdTheme('#333', '#fff')};
|
||||
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: #333;
|
||||
background: ${cssManager.bdTheme('#fff', '#222')};
|
||||
width: min-content;
|
||||
border-radius: 20px;
|
||||
height: 40px;
|
||||
height: 32px;
|
||||
border-top: 1px solid #ffffff10;
|
||||
}
|
||||
|
||||
.option {
|
||||
color: #CCC;
|
||||
color: #ccc;
|
||||
position: relative;
|
||||
padding: 0px 16px;
|
||||
line-height: 40px;
|
||||
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: 32px;
|
||||
height: 24px;
|
||||
left: 4px;
|
||||
top: 4px;
|
||||
top: 3px;
|
||||
border-radius: 16px;
|
||||
background: #0050b9;
|
||||
min-width: 36px;
|
||||
@ -84,11 +109,16 @@ export class DeesInputMultitoggle extends DeesElement {
|
||||
|
||||
public render(): TemplateResult {
|
||||
return html`
|
||||
<div class="label">MultiSelect</div>
|
||||
<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" @click=${() => this.handleSelection(option)}>${option}</div> `)}
|
||||
${this.options.map(
|
||||
(option) =>
|
||||
html`<div class="option ${option === this.selectedOption ? 'selected': ''}" @click=${() => this.handleSelection(option)}>
|
||||
${option}
|
||||
</div> `
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
@ -108,7 +138,9 @@ export class DeesInputMultitoggle extends DeesElement {
|
||||
|
||||
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})`);
|
||||
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`;
|
||||
|
@ -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;
|
||||
@ -132,7 +134,7 @@ 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;
|
||||
}
|
||||
|
||||
@ -192,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}
|
||||
|
@ -16,6 +16,14 @@ const { demoFunc } = await import('./dees-input-typelist.demo.js');
|
||||
export class DeesInputTypelist extends DeesElement {
|
||||
public static demo = demoFunc;
|
||||
|
||||
|
||||
// INSTANCE
|
||||
|
||||
@property({
|
||||
type: String,
|
||||
})
|
||||
public label: string;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
@ -24,11 +32,13 @@ export class DeesInputTypelist extends DeesElement {
|
||||
cssManager.defaultStyles,
|
||||
css`
|
||||
:host {
|
||||
color: ${cssManager.bdTheme('#333', '#fff')}
|
||||
display: block;
|
||||
color: ${cssManager.bdTheme('#333', '#fff')};
|
||||
margin: 8px 0px 24px 0px;
|
||||
}
|
||||
.label {
|
||||
font-size: 14px;
|
||||
margin-bottom: 4px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.mainbox {
|
||||
border-radius: 3px;
|
||||
@ -74,7 +84,7 @@ export class DeesInputTypelist extends DeesElement {
|
||||
|
||||
public render(): TemplateResult {
|
||||
return html`
|
||||
<div class="label">Type List</div>
|
||||
<div class="label">${this.label}</div>
|
||||
<div class="mainbox">
|
||||
<div class="tags" @click=${() => {
|
||||
this.shadowRoot.querySelector('input').focus();
|
||||
|
7
ts_web/elements/dees-label.demo.ts
Normal file
7
ts_web/elements/dees-label.demo.ts
Normal 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>
|
||||
`;
|
||||
}
|
70
ts_web/elements/dees-label.ts
Normal file
70
ts_web/elements/dees-label.ts
Normal 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``}
|
||||
`;
|
||||
}
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
import * as colors from './00colors.js';
|
||||
import * as plugins from './00plugins.js';
|
||||
|
||||
import { demoFunc } from './dees-modal.demo.js';
|
||||
import {
|
||||
customElement,
|
||||
@ -123,19 +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: 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;
|
||||
|
@ -1,4 +1,6 @@
|
||||
import { demoFunc } from './dees-simple-appdash.demo.js';
|
||||
import * as colors from './00colors.js';
|
||||
|
||||
import {
|
||||
customElement,
|
||||
html,
|
||||
@ -10,7 +12,9 @@ import {
|
||||
unsafeCSS,
|
||||
type CSSResult,
|
||||
state,
|
||||
domtools,
|
||||
} from '@design.estate/dees-element';
|
||||
import { DeesTerminal } from './dees-terminal.js';
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
@ -27,43 +31,106 @@ export class DeesSimpleAppDash extends DeesElement {
|
||||
@property()
|
||||
public name = 'Dees Simple Login';
|
||||
|
||||
@property()
|
||||
public views: Array<{ name: string; icon: string; viewFunction: () => Promise<TemplateResult> }> =
|
||||
[];
|
||||
|
||||
public static styles = [
|
||||
cssManager.defaultStyles,
|
||||
css`
|
||||
:host {
|
||||
color: ${cssManager.bdTheme('#333', '#fff')};
|
||||
color: ${cssManager.bdTheme('#333', '#ccc')};
|
||||
user-select: none;
|
||||
display: block;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
}
|
||||
.appbar {
|
||||
position: absolute;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
height: 40px;
|
||||
height: 32px;
|
||||
width: 100%;
|
||||
background: ${cssManager.bdTheme('#eeeeeb', '#000')};
|
||||
border-bottom: 1px solid ${cssManager.bdTheme('#ccc', '#333')};
|
||||
background: ${cssManager.bdTheme('#eeeeeb', '#222')};
|
||||
border-bottom: 1px solid ${cssManager.bdTheme('#ccc', '#ffffff10')};
|
||||
font-size: 14px;
|
||||
line-height: 40px;
|
||||
line-height: 32px;
|
||||
font-family: 'Roboto', 'Inter', sans-serif;
|
||||
padding: 0px 16px;
|
||||
z-index: 2;
|
||||
box-shadow: 0px 4px 10px 0px rgba(0, 0, 0, 0.8);
|
||||
display: grid;
|
||||
grid-template-columns: min-content 1fr auto;
|
||||
}
|
||||
|
||||
.appName {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.appActions {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.appActions .action {
|
||||
}
|
||||
.appActions .action:hover {
|
||||
color: ${cssManager.bdTheme('#000', '#fff')};
|
||||
}
|
||||
|
||||
.appcontent {
|
||||
position: absolute;
|
||||
top: 40px;
|
||||
bottom: 0;
|
||||
z-index: 1;
|
||||
position: fixed;
|
||||
top: 32px;
|
||||
height: calc(100vh - 32px - 24px);
|
||||
bottom: 24px;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
background: ${cssManager.bdTheme('#eeeeeb', '#000')};
|
||||
}
|
||||
|
||||
.controlbar {
|
||||
color: #fff;
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
width: 100%;
|
||||
height: 24px;
|
||||
background: ${cssManager.bdTheme(colors.bright.blueMuted, colors.dark.blueMuted)};
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
.control {
|
||||
width: min-content;
|
||||
margin-right: 16px;
|
||||
font-size: 12px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
public render(): TemplateResult {
|
||||
return html`
|
||||
<div class="appbar">
|
||||
configvault v1.2.3
|
||||
<div class="appName">${this.name}</div>
|
||||
<div class="viewTabs"></div>
|
||||
<div class="appActions">
|
||||
<div class="action">Logout</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="appcontent">
|
||||
<slot></slot>
|
||||
</div>
|
||||
<div class="controlbar">
|
||||
<div class="control">
|
||||
<dees-icon .iconFA=${'networkWired'}></dees-icon>
|
||||
</div>
|
||||
<div class="control" @click=${this.launchTerminal}>
|
||||
<dees-icon .iconFA=${'terminal'}></dees-icon>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
@ -71,4 +138,19 @@ export class DeesSimpleAppDash extends DeesElement {
|
||||
const domtools = await this.domtoolsPromise;
|
||||
super.firstUpdated(_changedProperties);
|
||||
}
|
||||
|
||||
public async launchTerminal() {
|
||||
const appcontent = this.shadowRoot.querySelector('.appcontent');
|
||||
const terminal = new DeesTerminal();
|
||||
terminal.style.position = 'absolute';
|
||||
terminal.style.top = '0px';
|
||||
terminal.style.left = '0px';
|
||||
terminal.style.opacity = '0';
|
||||
terminal.style.transform = 'translateY(20px)';
|
||||
terminal.style.transition = 'all 0.2s';
|
||||
appcontent.appendChild(terminal);
|
||||
await domtools.plugins.smartdelay.delayFor(0);
|
||||
terminal.style.opacity = '1';
|
||||
terminal.style.transform = 'translateY(0px)';
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ export class DeesSimpleLogin extends DeesElement {
|
||||
color: ${cssManager.bdTheme('#333', '#fff')};
|
||||
user-select: none;
|
||||
}
|
||||
.loginContainer {
|
||||
.loginContainer, .slotContainer {
|
||||
position: absolute;
|
||||
display: flex;
|
||||
justify-content: center; /* aligns horizontally */
|
||||
|
23
ts_web/elements/dees-speechbubble.demo.ts
Normal file
23
ts_web/elements/dees-speechbubble.demo.ts
Normal 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>
|
||||
`;
|
||||
};
|
@ -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,27 +81,22 @@ export class DeesSpeechbubble extends DeesElement {
|
||||
cssManager.defaultStyles,
|
||||
css`
|
||||
:host {
|
||||
position: relative;
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
color: ${cssManager.bdTheme('#333', '#fff')};
|
||||
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 {
|
||||
@ -77,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;
|
||||
@ -132,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();
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,6 @@
|
||||
import * as plugins from './00plugins.js';
|
||||
import * as colors from './00colors.js';
|
||||
|
||||
import {
|
||||
DeesElement,
|
||||
customElement,
|
||||
@ -150,7 +153,22 @@ export class DeesStepper extends DeesElement {
|
||||
}
|
||||
|
||||
.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 {
|
||||
@ -180,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
|
||||
|
@ -1,3 +1,4 @@
|
||||
import * as colors from './00colors.js';
|
||||
import * as plugins from './00plugins.js';
|
||||
import { demoFunc } from './dees-table.demo.js';
|
||||
import {
|
||||
@ -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,15 +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;
|
||||
}
|
||||
.headerAction {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
color: ${cssManager.bdTheme('#333', '#ccc')};
|
||||
margin-left: 16px;
|
||||
}
|
||||
|
||||
.headerAction:hover {
|
||||
@ -216,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;
|
||||
@ -235,7 +269,6 @@ export class DeesTable<T> extends DeesElement {
|
||||
text-align: left;
|
||||
}
|
||||
tr:hover {
|
||||
|
||||
}
|
||||
tr:hover td {
|
||||
background: ${cssManager.bdTheme('#22222210', '#ffffff10')};
|
||||
@ -304,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 {
|
||||
@ -344,16 +387,21 @@ export class DeesTable<T> extends DeesElement {
|
||||
.footerActions .footerAction {
|
||||
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 {
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
@ -393,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>
|
||||
@ -521,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>
|
||||
`;
|
||||
@ -585,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() {
|
||||
@ -610,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;
|
||||
|
274
ts_web/elements/dees-terminal.ts
Normal file
274
ts_web/elements/dees-terminal.ts
Normal file
@ -0,0 +1,274 @@
|
||||
import {
|
||||
DeesElement,
|
||||
property,
|
||||
html,
|
||||
customElement,
|
||||
type TemplateResult,
|
||||
css,
|
||||
cssManager,
|
||||
} from '@design.estate/dees-element';
|
||||
import * as domtools from '@design.estate/dees-domtools';
|
||||
|
||||
import * as webcontainer from '@webcontainer/api';
|
||||
|
||||
import { Terminal } from 'xterm';
|
||||
import { FitAddon } from 'xterm-addon-fit';
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'dees-terminal': DeesTerminal;
|
||||
}
|
||||
}
|
||||
|
||||
@customElement('dees-terminal')
|
||||
export class DeesTerminal extends DeesElement {
|
||||
public static demo = () => html` <dees-terminal></dees-terminal> `;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
domtools.DomTools.setupDomTools();
|
||||
}
|
||||
|
||||
public static styles = [
|
||||
domtools.elementBasic.staticStyles,
|
||||
css`
|
||||
:host {
|
||||
padding: 20px;
|
||||
background: #000;
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
#container {
|
||||
position: absolute;
|
||||
height: calc(100% - 40px);
|
||||
width: calc(100% - 40px);
|
||||
}
|
||||
/**
|
||||
* Copyright (c) 2014 The xterm.js authors. All rights reserved.
|
||||
* Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
|
||||
* https://github.com/chjj/term.js
|
||||
* @license MIT
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* Originally forked from (with the author's permission):
|
||||
* Fabrice Bellard's javascript vt100 for jslinux:
|
||||
* http://bellard.org/jslinux/
|
||||
* Copyright (c) 2011 Fabrice Bellard
|
||||
* The original design remains. The terminal itself
|
||||
* has been extended to include xterm CSI codes, among
|
||||
* other features.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Default styles for xterm.js
|
||||
*/
|
||||
|
||||
.xterm {
|
||||
font-feature-settings: 'liga' 0;
|
||||
position: relative;
|
||||
user-select: none;
|
||||
-ms-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
}
|
||||
|
||||
.xterm.focus,
|
||||
.xterm:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.xterm .xterm-helpers {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
/**
|
||||
* The z-index of the helpers must be higher than the canvases in order for
|
||||
* IMEs to appear on top.
|
||||
*/
|
||||
z-index: 5;
|
||||
}
|
||||
|
||||
.xterm .xterm-helper-textarea {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
/* Move textarea out of the screen to the far left, so that the cursor is not visible */
|
||||
position: absolute;
|
||||
opacity: 0;
|
||||
left: -9999em;
|
||||
top: 0;
|
||||
width: 0;
|
||||
height: 0;
|
||||
z-index: -5;
|
||||
/** Prevent wrapping so the IME appears against the textarea at the correct position */
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
.xterm .composition-view {
|
||||
/* TODO: Composition position got messed up somewhere */
|
||||
background: #000;
|
||||
color: #fff;
|
||||
display: none;
|
||||
position: absolute;
|
||||
white-space: nowrap;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.xterm .composition-view.active {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.xterm .xterm-viewport {
|
||||
/* On OS X this is required in order for the scroll bar to appear fully opaque */
|
||||
background-color: #000;
|
||||
overflow-y: scroll;
|
||||
cursor: default;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.xterm .xterm-screen {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.xterm .xterm-screen canvas {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.xterm .xterm-scroll-area {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.xterm-char-measure-element {
|
||||
display: inline-block;
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -9999em;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
.xterm {
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.xterm.enable-mouse-events {
|
||||
/* When mouse events are enabled (eg. tmux), revert to the standard pointer cursor */
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.xterm.xterm-cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.xterm.column-select.focus {
|
||||
/* Column selection mode */
|
||||
cursor: crosshair;
|
||||
}
|
||||
|
||||
.xterm .xterm-accessibility,
|
||||
.xterm .xterm-message {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.xterm .live-region {
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.xterm-dim {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.xterm-underline {
|
||||
text-decoration: underline;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
public render(): TemplateResult {
|
||||
return html`
|
||||
<div class="mainbox">
|
||||
<div id="container"></div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
public async firstUpdated(
|
||||
_changedProperties: Map<string | number | symbol, unknown>
|
||||
): Promise<void> {
|
||||
const domtools = await this.domtoolsPromise;
|
||||
super.firstUpdated(_changedProperties);
|
||||
const container = this.shadowRoot.getElementById('container');
|
||||
|
||||
const term = new Terminal({
|
||||
convertEol: true,
|
||||
cursorBlink: true,
|
||||
});
|
||||
const fitAddon = new FitAddon();
|
||||
term.loadAddon(fitAddon);
|
||||
|
||||
// Open the terminal in #terminal-container
|
||||
term.open(container);
|
||||
|
||||
// Make the terminal's size and geometry fit the size of #terminal-container
|
||||
fitAddon.fit();
|
||||
|
||||
term.write(`dees-terminal custom terminal. \r\n$ `);
|
||||
|
||||
// lets start the webcontainer
|
||||
// Call only once
|
||||
const webcontainerInstance = await webcontainer.WebContainer.boot();
|
||||
const shellProcess = await webcontainerInstance.spawn('jsh');
|
||||
shellProcess.output.pipeTo(
|
||||
new WritableStream({
|
||||
write(data) {
|
||||
term.write(data);
|
||||
},
|
||||
})
|
||||
);
|
||||
const input = shellProcess.input.getWriter();
|
||||
term.onData((data) => {
|
||||
input.write(data);
|
||||
});
|
||||
await domtools.convenience.smartdelay.delayFor(5000);
|
||||
input.write(`pnpm add isomorphic-git @git.zone/tsbuild\n`);
|
||||
}
|
||||
}
|
@ -4,6 +4,9 @@ export * from './dees-chips.js';
|
||||
export * from './dees-contextmenu.js';
|
||||
export * from './dees-dataview-codebox.js';
|
||||
export * from './dees-dataview-statusobject.js';
|
||||
export * from './dees-editor.js';
|
||||
export * from './dees-editor-markdown.js';
|
||||
export * from './dees-editor-markdownoutlet.js';
|
||||
export * from './dees-form-submit.js';
|
||||
export * from './dees-form.js';
|
||||
export * from './dees-hint.js';
|
||||
@ -18,6 +21,7 @@ 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';
|
||||
@ -28,6 +32,7 @@ export * from './dees-speechbubble.js';
|
||||
export * from './dees-spinner.js';
|
||||
export * from './dees-stepper.js';
|
||||
export * from './dees-table.js';
|
||||
export * from './dees-terminal.js';
|
||||
export * from './dees-toast.js';
|
||||
export * from './dees-updater.js';
|
||||
export * from './dees-windowcontrols.js';
|
||||
|
Reference in New Issue
Block a user