Compare commits
67 Commits
Author | SHA1 | Date | |
---|---|---|---|
aabda883cd | |||
5890977009 | |||
f4aebcf4e6 | |||
66bf117bfc | |||
f7ee4d77fd | |||
ab19e97c31 | |||
631502b480 | |||
ea519cf543 | |||
91c97cad1d | |||
de958303e3 | |||
95192ea3ce | |||
0b1e50bbc6 | |||
888f07db79 | |||
e14d83b3a7 | |||
f4055fb8c1 | |||
d0d4638264 | |||
7d63f16fc1 | |||
00cb552f44 | |||
2f52f14cf9 | |||
54ce305cf1 | |||
9d5f0b5ff8 | |||
c1594736ec | |||
4eb1abaa39 | |||
b8c231fc61 | |||
260c4a269a | |||
c1e7629f1f | |||
b84e2c4774 | |||
e9374900a0 | |||
486b8cb6a6 | |||
0adb319616 | |||
a6e7adc983 | |||
59dfbb34bb | |||
cf34cea94d | |||
7f5e72c27f | |||
4311c0fff6 | |||
e028f37493 | |||
c6967156d6 | |||
efaf2a78df | |||
e6adbf9b6d | |||
e88605a4aa | |||
6a161982b7 | |||
22d7883c04 | |||
2a613c96a0 | |||
bdd766e4bc | |||
b1ce8f093f | |||
056090856e | |||
fef0705acc | |||
6eced2321f | |||
05a9042de8 | |||
d369805ee8 | |||
3a2f3500fd | |||
2f9711a094 | |||
cf80efd1ec | |||
cf5cd37ebc | |||
88554396a4 | |||
2f13311098 | |||
5407b158d0 | |||
b171eaf3fc | |||
5585d7e304 | |||
02119a1ce4 | |||
222f06bda7 | |||
8ee99136cc | |||
faf35c3144 | |||
ae53459d56 | |||
5e1a32633a | |||
4b1b3ac615 | |||
9f8a5fedfa |
@ -19,23 +19,35 @@ mirror:
|
|||||||
stage: security
|
stage: security
|
||||||
script:
|
script:
|
||||||
- npmci git mirror
|
- npmci git mirror
|
||||||
|
only:
|
||||||
|
- tags
|
||||||
tags:
|
tags:
|
||||||
- lossless
|
- lossless
|
||||||
- docker
|
- docker
|
||||||
- notpriv
|
- notpriv
|
||||||
|
|
||||||
audit:
|
auditProductionDependencies:
|
||||||
|
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
|
||||||
|
stage: security
|
||||||
|
script:
|
||||||
|
- npmci npm prepare
|
||||||
|
- npmci command npm install --production --ignore-scripts
|
||||||
|
- npmci command npm config set registry https://registry.npmjs.org
|
||||||
|
- npmci command npm audit --audit-level=high --only=prod --production
|
||||||
|
tags:
|
||||||
|
- docker
|
||||||
|
|
||||||
|
auditDevDependencies:
|
||||||
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
|
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
|
||||||
stage: security
|
stage: security
|
||||||
script:
|
script:
|
||||||
- npmci npm prepare
|
- npmci npm prepare
|
||||||
- npmci command npm install --ignore-scripts
|
- npmci command npm install --ignore-scripts
|
||||||
- npmci command npm config set registry https://registry.npmjs.org
|
- npmci command npm config set registry https://registry.npmjs.org
|
||||||
- npmci command npm audit --audit-level=high
|
- npmci command npm audit --audit-level=high --only=dev
|
||||||
tags:
|
tags:
|
||||||
- lossless
|
|
||||||
- docker
|
- docker
|
||||||
- notpriv
|
allow_failure: true
|
||||||
|
|
||||||
# ====================
|
# ====================
|
||||||
# test stage
|
# test stage
|
||||||
@ -50,9 +62,7 @@ testStable:
|
|||||||
- npmci npm test
|
- npmci npm test
|
||||||
coverage: /\d+.?\d+?\%\s*coverage/
|
coverage: /\d+.?\d+?\%\s*coverage/
|
||||||
tags:
|
tags:
|
||||||
- lossless
|
|
||||||
- docker
|
- docker
|
||||||
- priv
|
|
||||||
|
|
||||||
testBuild:
|
testBuild:
|
||||||
stage: test
|
stage: test
|
||||||
@ -63,9 +73,7 @@ testBuild:
|
|||||||
- npmci command npm run build
|
- npmci command npm run build
|
||||||
coverage: /\d+.?\d+?\%\s*coverage/
|
coverage: /\d+.?\d+?\%\s*coverage/
|
||||||
tags:
|
tags:
|
||||||
- lossless
|
|
||||||
- docker
|
- docker
|
||||||
- notpriv
|
|
||||||
|
|
||||||
release:
|
release:
|
||||||
stage: release
|
stage: release
|
||||||
@ -85,6 +93,8 @@ release:
|
|||||||
codequality:
|
codequality:
|
||||||
stage: metadata
|
stage: metadata
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
only:
|
||||||
|
- tags
|
||||||
script:
|
script:
|
||||||
- npmci command npm install -g tslint typescript
|
- npmci command npm install -g tslint typescript
|
||||||
- npmci npm prepare
|
- npmci npm prepare
|
||||||
|
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -15,7 +15,7 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"projectType": {
|
"projectType": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": ["website", "element", "service", "npm"]
|
"enum": ["website", "element", "service", "npm", "wcc"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height"
|
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height"
|
||||||
/>
|
/>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
|
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
@ -18,9 +17,8 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script src="../ts_web/index.ts"></script>
|
<script src="./index.ts"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<></>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
10
html/index.ts
Normal file
10
html/index.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// dees tools
|
||||||
|
import * as deesWccTools from '@designestate/dees-wcctools';
|
||||||
|
import * as deesDomTools from '@designestate/dees-domtools';
|
||||||
|
|
||||||
|
// elements and pages
|
||||||
|
import * as elements from '../ts_web/elements';
|
||||||
|
import * as pages from '../ts_web/pages';
|
||||||
|
|
||||||
|
deesWccTools.setupWccTools(elements as any, pages);
|
||||||
|
deesDomTools.elementBasic.setup();
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"gitzone": {
|
"gitzone": {
|
||||||
"projectType": "element",
|
"projectType": "wcc",
|
||||||
"module": {
|
"module": {
|
||||||
"githost": "gitlab.com",
|
"githost": "gitlab.com",
|
||||||
"gitscope": "designestate",
|
"gitscope": "designestate",
|
||||||
|
24406
package-lock.json
generated
24406
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
38
package.json
38
package.json
@ -1,30 +1,35 @@
|
|||||||
{
|
{
|
||||||
"name": "@losslessone_private/dees-catalog",
|
"name": "@designestate/dees-catalog",
|
||||||
"version": "1.0.18",
|
"version": "1.0.52",
|
||||||
"private": false,
|
"private": false,
|
||||||
"description": "website for lossless.com",
|
"description": "website for lossless.com",
|
||||||
"main": "dist_ts_web/index.js",
|
"main": "dist_ts_web/index.js",
|
||||||
"typings": "dist_ts_web/index.d.ts",
|
"typings": "dist_ts_web/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "npm run build",
|
"test": "tstest test/ --web",
|
||||||
"build": "tsbuild custom ts_web --web",
|
"build": "tsbuild element && tsbundle element --production",
|
||||||
"watch": "tswatch element"
|
"watch": "tswatch element"
|
||||||
},
|
},
|
||||||
"author": "Lossless GmbH",
|
"author": "Lossless GmbH",
|
||||||
"license": "UNLICENSED",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@gitzone/tsrun": "^1.1.17",
|
"@designestate/dees-domtools": "^1.0.90",
|
||||||
"@pushrocks/smartexpress": "^3.0.10",
|
"@designestate/dees-element": "^1.0.19",
|
||||||
"lit-element": "^2.0.0-rc.5",
|
"@designestate/dees-wcctools": "^1.0.57",
|
||||||
"lit-html": "^1.0.0-rc.2",
|
"@fortawesome/fontawesome-svg-core": "^1.2.36",
|
||||||
"typescript": "^3.2.2"
|
"@fortawesome/free-brands-svg-icons": "^5.15.4",
|
||||||
|
"@fortawesome/free-regular-svg-icons": "^5.15.4",
|
||||||
|
"@fortawesome/free-solid-svg-icons": "^5.15.4",
|
||||||
|
"typescript": "^4.4.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@gitzone/tsbuild": "^2.1.8",
|
"@gitzone/tsbuild": "^2.1.26",
|
||||||
"@gitzone/tswatch": "^1.0.30",
|
"@gitzone/tsbundle": "^1.0.87",
|
||||||
"@pushrocks/parcel-plugin-wrapper": "^1.0.5",
|
"@gitzone/tstest": "^1.0.57",
|
||||||
"@pushrocks/projectinfo": "^4.0.2",
|
"@gitzone/tswatch": "^1.0.56",
|
||||||
"tslint": "^5.11.0",
|
"@pushrocks/projectinfo": "^4.0.5",
|
||||||
|
"@pushrocks/tapbundle": "^3.2.14",
|
||||||
|
"tslint": "^6.1.3",
|
||||||
"tslint-config-prettier": "^1.17.0"
|
"tslint-config-prettier": "^1.17.0"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
@ -38,5 +43,8 @@
|
|||||||
"cli.js",
|
"cli.js",
|
||||||
"npmextra.json",
|
"npmextra.json",
|
||||||
"readme.md"
|
"readme.md"
|
||||||
|
],
|
||||||
|
"browserslist": [
|
||||||
|
"last 1 chrome versions"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
24
readme.md
24
readme.md
@ -8,16 +8,26 @@ a webcomponents catalog for handling daily stuff on the web
|
|||||||
* [docs (typedoc)](https://designestate.gitlab.io/dees-catalog/)
|
* [docs (typedoc)](https://designestate.gitlab.io/dees-catalog/)
|
||||||
|
|
||||||
## Status for master
|
## Status for master
|
||||||
[](https://gitlab.com/designestate/dees-catalog/commits/master)
|
|
||||||
[](https://gitlab.com/designestate/dees-catalog/commits/master)
|
Status Category | Status Badge
|
||||||
[](https://www.npmjs.com/package/@designestate/dees-catalog)
|
-- | --
|
||||||
[](https://snyk.io/test/npm/@designestate/dees-catalog)
|
GitLab Pipelines | [](https://lossless.cloud)
|
||||||
[](https://nodejs.org/dist/latest-v10.x/docs/api/)
|
GitLab Pipline Test Coverage | [](https://lossless.cloud)
|
||||||
[](https://nodejs.org/dist/latest-v10.x/docs/api/)
|
npm | [](https://lossless.cloud)
|
||||||
[](https://prettier.io/)
|
Snyk | [](https://lossless.cloud)
|
||||||
|
TypeScript Support | [](https://lossless.cloud)
|
||||||
|
node Support | [](https://nodejs.org/dist/latest-v10.x/docs/api/)
|
||||||
|
Code Style | [](https://lossless.cloud)
|
||||||
|
PackagePhobia (total standalone install weight) | [](https://lossless.cloud)
|
||||||
|
PackagePhobia (package size on registry) | [](https://lossless.cloud)
|
||||||
|
BundlePhobia (total size when bundled) | [](https://lossless.cloud)
|
||||||
|
Platform support | [](https://lossless.cloud) [](https://lossless.cloud)
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
## Contribution
|
||||||
|
|
||||||
|
We are always happy for code contributions. If you are not the code contributing type that is ok. Still, maintaining Open Source repositories takes considerable time and thought. If you like the quality of what we do and our modules are useful to you we would appreciate a little monthly contribution: You can [contribute one time](https://lossless.link/contribute-onetime) or [contribute monthly](https://lossless.link/contribute). :)
|
||||||
|
|
||||||
## Contribution
|
## Contribution
|
||||||
|
|
||||||
|
12
test/test.browser.ts
Normal file
12
test/test.browser.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { tap, expect, webhelpers } from '@pushrocks/tapbundle';
|
||||||
|
|
||||||
|
import * as deesCatalog from '../ts_web';
|
||||||
|
|
||||||
|
tap.test('should create a working button', async () => {
|
||||||
|
const button: deesCatalog.DeesButton = await webhelpers.fixture(
|
||||||
|
webhelpers.html`<dees-button></dees-button>`
|
||||||
|
);
|
||||||
|
expect(button).to.be.instanceOf(deesCatalog.DeesButton);
|
||||||
|
});
|
||||||
|
|
||||||
|
tap.start();
|
211
ts_web/elements/dees-button.ts
Normal file
211
ts_web/elements/dees-button.ts
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
import {
|
||||||
|
customElement,
|
||||||
|
html,
|
||||||
|
DeesElement,
|
||||||
|
property,
|
||||||
|
TemplateResult,
|
||||||
|
cssManager,
|
||||||
|
css,
|
||||||
|
unsafeCSS,
|
||||||
|
} from '@designestate/dees-element';
|
||||||
|
|
||||||
|
import * as domtools from '@designestate/dees-domtools';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
'dees-button': DeesButton;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@customElement('dees-button')
|
||||||
|
export class DeesButton extends DeesElement {
|
||||||
|
public static demo = () => html`
|
||||||
|
<dees-button>This is a slotted Text</dees-button>
|
||||||
|
<p><dees-button text="Highlighted: This text shows" type="highlighted">Highlighted</dees-button></p>
|
||||||
|
<p><dees-button type="discreet">This is discreete button</dees-button></p>
|
||||||
|
<p><dees-button disabled>This is a disabled button</dees-button></p>
|
||||||
|
<p><dees-button type="big">This is a slotted Text</dees-button></p>
|
||||||
|
<p><dees-button status="normal">Normal Status</dees-button></p>
|
||||||
|
<p><dees-button disabled status="pending">Pending Status</dees-button></p>
|
||||||
|
<p><dees-button disabled status="success">Success Status</dees-button></p>
|
||||||
|
<p><dees-button disabled status="error">Error Status</dees-button></p>
|
||||||
|
`;
|
||||||
|
|
||||||
|
@property()
|
||||||
|
public text: string;
|
||||||
|
|
||||||
|
@property()
|
||||||
|
public eventDetailData: string;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Boolean
|
||||||
|
})
|
||||||
|
public disabled = false;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Boolean
|
||||||
|
})
|
||||||
|
public isHidden = false;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: String
|
||||||
|
})
|
||||||
|
public type: 'normal' | 'highlighted' | 'discreet' | 'big' = 'normal';
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: String
|
||||||
|
})
|
||||||
|
public status: 'normal' | 'pending' | 'success' | 'error' = 'normal';
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static styles = [
|
||||||
|
cssManager.defaultStyles,
|
||||||
|
css`
|
||||||
|
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
:host([hidden]) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
transition: all 0.1s ease;
|
||||||
|
position: relative;
|
||||||
|
font-size: 14px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: ${cssManager.bdTheme('#eee', '#333')};
|
||||||
|
box-shadow: ${cssManager.bdTheme('0px 0px 5px rgba(0,0,0,0.1)', 'none')};
|
||||||
|
border: 1px solid ${cssManager.bdTheme('#eee', '#333')};
|
||||||
|
border-top: ${cssManager.bdTheme('1px solid #eee', '1px solid #444')};
|
||||||
|
border-radius: 2px;
|
||||||
|
line-height: 40px;
|
||||||
|
padding: 0px 10px;
|
||||||
|
min-width: 100px;
|
||||||
|
user-select: none;
|
||||||
|
color: ${cssManager.bdTheme('#333', ' #ccc')};
|
||||||
|
max-width: 500px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
background: #039be5;
|
||||||
|
border: 1px solid #039be5;
|
||||||
|
border-top: 1px solid #039be5;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:active {
|
||||||
|
background: #0277bd;
|
||||||
|
border-top: 1px solid #0277bd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.disabled {
|
||||||
|
background: ${cssManager.bdTheme('#ffffff00', '#11111100')};
|
||||||
|
border: 1px dashed ${cssManager.bdTheme('#666666', '#666666')};
|
||||||
|
color: #9b9b9e;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.highlighted {
|
||||||
|
background: #e4002b;
|
||||||
|
border: none;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.highlighted:hover {
|
||||||
|
background: #b50021;
|
||||||
|
border: none;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.discreet {
|
||||||
|
background: none;
|
||||||
|
border: 1px solid #9b9b9e;
|
||||||
|
color: ${cssManager.bdTheme('#000', '#fff')};
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.discreet:hover {
|
||||||
|
background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.1)', 'rgba(255, 255, 255, 0.1)')};
|
||||||
|
}
|
||||||
|
.button.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.big {
|
||||||
|
width: 300px;
|
||||||
|
line-height: 48px;
|
||||||
|
font-size: 16px;
|
||||||
|
padding: 0px 48px;
|
||||||
|
margin-top: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.pending {
|
||||||
|
border: 1px dashed ${cssManager.bdTheme('#0277bd', '#0277bd70')};
|
||||||
|
background: ${cssManager.bdTheme('#0277bd', '#0277bd70')};
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.success {
|
||||||
|
border: 1px dashed ${cssManager.bdTheme('#689F38', '#8BC34A70')};
|
||||||
|
background: ${cssManager.bdTheme('#689F38', '#8BC34A70')};
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.error {
|
||||||
|
border: 1px dashed ${cssManager.bdTheme('#B71C1C', '#E64A1970')};
|
||||||
|
background: ${cssManager.bdTheme('#B71C1C', '#E64A1970')};
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
dees-spinner {
|
||||||
|
position: absolute;
|
||||||
|
left: 10px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
|
||||||
|
public render(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
<div
|
||||||
|
class="button ${this.isHidden ? 'hidden' : 'block'} ${this.type} ${this.status} ${this.disabled
|
||||||
|
? 'disabled'
|
||||||
|
: null}"
|
||||||
|
@click="${this.dispatchClick}"
|
||||||
|
>
|
||||||
|
${this.status === 'normal' ? html``: html`
|
||||||
|
<dees-spinner status="${this.status}"></dees-spinner>
|
||||||
|
`}
|
||||||
|
<div class="textbox">${this.text ? this.text : html`<slot></slot>`}</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async dispatchClick() {
|
||||||
|
if (this.disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dispatchEvent(
|
||||||
|
new CustomEvent('clicked', {
|
||||||
|
detail: {
|
||||||
|
data: this.eventDetailData,
|
||||||
|
},
|
||||||
|
bubbles: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async firstUpdated() {
|
||||||
|
if (!this.textContent) {
|
||||||
|
this.textContent = 'Button';
|
||||||
|
this.performUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
57
ts_web/elements/dees-form-submit.ts
Normal file
57
ts_web/elements/dees-form-submit.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import {
|
||||||
|
customElement,
|
||||||
|
html,
|
||||||
|
DeesElement,
|
||||||
|
css,
|
||||||
|
cssManager,
|
||||||
|
property,
|
||||||
|
} from '@designestate/dees-element';
|
||||||
|
import { DeesForm } from './dees-form';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
'dees-form-submit': DeesFormSubmit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@customElement('dees-form-submit')
|
||||||
|
export class DeesFormSubmit extends DeesElement {
|
||||||
|
public static demo = () => html`<dees-form-submit>This is a sloted text</dees-form-submit>`;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Boolean,
|
||||||
|
})
|
||||||
|
public disabled = false;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: String,
|
||||||
|
})
|
||||||
|
public text: string;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: String
|
||||||
|
})
|
||||||
|
public status: 'normal' | 'pending' | 'success' | 'error' = 'normal';
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static styles = [cssManager.defaultStyles, css``];
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
return html`
|
||||||
|
<dees-button status=${this.status} @click=${this.submit} .disabled=${this.disabled}>
|
||||||
|
${this.text ? this.text : html`<slot></slot>`}
|
||||||
|
</dees-button>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async submit() {
|
||||||
|
if (this.disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const parentElement: DeesForm = this.parentElement as DeesForm;
|
||||||
|
parentElement.gatherAndDispatch();
|
||||||
|
}
|
||||||
|
}
|
164
ts_web/elements/dees-form.ts
Normal file
164
ts_web/elements/dees-form.ts
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
import { customElement, html, TemplateResult, DeesElement } from '@designestate/dees-element';
|
||||||
|
|
||||||
|
import { DeesInputCheckbox } from './dees-input-checkbox';
|
||||||
|
import { DeesInputText } from './dees-input-text';
|
||||||
|
import { DeesInputQuantitySelector } from './dees-input-quantityselector';
|
||||||
|
import { DeesInputRadio } from './dees-input-radio';
|
||||||
|
import * as domtools from '@designestate/dees-domtools';
|
||||||
|
import { DeesFormSubmit } from './dees-form-submit';
|
||||||
|
|
||||||
|
export type TFormElement = Array<
|
||||||
|
DeesInputCheckbox | DeesInputText | DeesInputQuantitySelector | DeesInputRadio
|
||||||
|
>;
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
'dees-form': DeesForm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@customElement('dees-form')
|
||||||
|
export class DeesForm extends DeesElement {
|
||||||
|
public static demo = () => html`
|
||||||
|
<dees-form
|
||||||
|
style="display: block; margin:auto; max-width: 500px; padding: 20px"
|
||||||
|
@formData=${async (eventArg) => {
|
||||||
|
const form: DeesForm = eventArg.currentTarget;
|
||||||
|
form.setStatus('pending', 'authenticating...');
|
||||||
|
await domtools.plugins.smartdelay.delayFor(1000);
|
||||||
|
form.setStatus('success', 'authenticated!');
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<dees-input-text .required="${true}" key="hello1" label="a text"></dees-input-text>
|
||||||
|
<dees-input-text .required="${true}" key="hello2" label="also a text"></dees-input-text>
|
||||||
|
<dees-input-checkbox
|
||||||
|
.required="${true}"
|
||||||
|
key="hello3"
|
||||||
|
label="another text"
|
||||||
|
></dees-input-checkbox>
|
||||||
|
<dees-form-submit>Submit</dees-form-submit>
|
||||||
|
</dees-form>
|
||||||
|
`;
|
||||||
|
|
||||||
|
public name: string = 'myform';
|
||||||
|
public changeSubject = new domtools.rxjs.Subject();
|
||||||
|
|
||||||
|
public render(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
display: contents;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<slot></slot>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
public firstUpdated() {
|
||||||
|
const formChildren = this.getFormChildren();
|
||||||
|
this.checkRequiredStatus();
|
||||||
|
for (const child of formChildren) {
|
||||||
|
child.changeSubject.subscribe(async (elementArg: TFormElement) => {
|
||||||
|
const valueObject = await this.gatherData();
|
||||||
|
this.changeSubject.next(valueObject);
|
||||||
|
console.log(valueObject);
|
||||||
|
this.checkRequiredStatus();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getFormChildren() {
|
||||||
|
const children: Array<DeesElement> = this.children as any;
|
||||||
|
const formChildren: TFormElement = [];
|
||||||
|
|
||||||
|
for (const child of children) {
|
||||||
|
if (
|
||||||
|
child instanceof DeesInputCheckbox ||
|
||||||
|
child instanceof DeesInputText ||
|
||||||
|
child instanceof DeesInputQuantitySelector
|
||||||
|
) {
|
||||||
|
formChildren.push(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return formChildren;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getSubmitButton() {
|
||||||
|
const children: Array<DeesElement> = this.children as any;
|
||||||
|
let submitButton: DeesFormSubmit;
|
||||||
|
for (const childArg of children) {
|
||||||
|
if (childArg instanceof DeesFormSubmit) {
|
||||||
|
submitButton = childArg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return submitButton;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async checkRequiredStatus() {
|
||||||
|
console.log('checking the required status.');
|
||||||
|
|
||||||
|
let requiredOK = true;
|
||||||
|
for (const childArg of this.getFormChildren()) {
|
||||||
|
if (childArg.required && !childArg.value) {
|
||||||
|
requiredOK = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.getSubmitButton().disabled = !requiredOK;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async gatherData() {
|
||||||
|
const children = this.getFormChildren();
|
||||||
|
const valueObject: { [key: string]: string | number | boolean } = {};
|
||||||
|
for (const child of children) {
|
||||||
|
valueObject[child.key] = child.value;
|
||||||
|
}
|
||||||
|
return valueObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async gatherAndDispatch() {
|
||||||
|
const valueObject = await this.gatherData();
|
||||||
|
const formDataEvent = new CustomEvent('formData', {
|
||||||
|
detail: {
|
||||||
|
data: valueObject,
|
||||||
|
},
|
||||||
|
bubbles: true,
|
||||||
|
});
|
||||||
|
this.dispatchEvent(formDataEvent);
|
||||||
|
console.log('dispatched data:');
|
||||||
|
console.log(valueObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
public setStatus(
|
||||||
|
visualStateArg: 'normal' | 'pending' | 'error' | 'success',
|
||||||
|
textStateArg: string
|
||||||
|
) {
|
||||||
|
const inputChildren = this.getFormChildren();
|
||||||
|
const submitButton = this.getSubmitButton();
|
||||||
|
|
||||||
|
switch (visualStateArg) {
|
||||||
|
case 'pending':
|
||||||
|
submitButton.disabled = true;
|
||||||
|
submitButton.status = 'pending';
|
||||||
|
for (const inputChild of inputChildren) {
|
||||||
|
inputChild.disabled = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'success':
|
||||||
|
submitButton.disabled = true;
|
||||||
|
submitButton.status = 'success';
|
||||||
|
for (const inputChild of inputChildren) {
|
||||||
|
inputChild.disabled = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'error':
|
||||||
|
submitButton.disabled = true;
|
||||||
|
submitButton.status = 'error';
|
||||||
|
for (const inputChild of inputChildren) {
|
||||||
|
inputChild.disabled = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
submitButton.text = textStateArg;
|
||||||
|
}
|
||||||
|
}
|
124
ts_web/elements/dees-icon.ts
Normal file
124
ts_web/elements/dees-icon.ts
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
import { LitElement, html, property, customElement } from 'lit-element';
|
||||||
|
|
||||||
|
import * as domtools from '@designestate/dees-domtools';
|
||||||
|
|
||||||
|
import { icon, IconDefinition } from '@fortawesome/fontawesome-svg-core';
|
||||||
|
import {
|
||||||
|
faFacebook,
|
||||||
|
faGoogle,
|
||||||
|
faLinkedin,
|
||||||
|
faMedium,
|
||||||
|
faSlackHash,
|
||||||
|
faTwitter,
|
||||||
|
} from '@fortawesome/free-brands-svg-icons';
|
||||||
|
|
||||||
|
import {} from '@fortawesome/free-regular-svg-icons';
|
||||||
|
import { faDesktop, faRss, faUsers } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
|
||||||
|
type TFontAwesomeIcon =
|
||||||
|
// normal
|
||||||
|
| 'desktop'
|
||||||
|
| 'rss'
|
||||||
|
// brands
|
||||||
|
| 'facebook'
|
||||||
|
| 'google'
|
||||||
|
| 'twitter'
|
||||||
|
| 'linkedin'
|
||||||
|
| 'medium'
|
||||||
|
| 'slack'
|
||||||
|
| 'users';
|
||||||
|
const faIcons: { [key: string]: IconDefinition } = {
|
||||||
|
// normal
|
||||||
|
desktop: faDesktop,
|
||||||
|
rss: faRss,
|
||||||
|
// brands
|
||||||
|
facebook: faFacebook,
|
||||||
|
google: faGoogle,
|
||||||
|
linkedin: faLinkedin,
|
||||||
|
medium: faMedium,
|
||||||
|
slack: faSlackHash,
|
||||||
|
twitter: faTwitter,
|
||||||
|
users: faUsers,
|
||||||
|
};
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
'dees-icon': DeesIcon;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@customElement('dees-icon')
|
||||||
|
export class DeesIcon extends LitElement {
|
||||||
|
public static demo = () => html`
|
||||||
|
<div style="background: #fff; padding: 10px;">
|
||||||
|
<dees-icon iconName="visibility"></dees-icon>
|
||||||
|
<dees-icon brandName="facebook"></dees-icon>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
@property()
|
||||||
|
public iconName: string;
|
||||||
|
|
||||||
|
@property()
|
||||||
|
public brandName: TFontAwesomeIcon;
|
||||||
|
|
||||||
|
@property()
|
||||||
|
public svgSize: number = 20;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
domtools.elementBasic.setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
return html`
|
||||||
|
${domtools.elementBasic.styles}
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
line-height: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
}
|
||||||
|
#iconContainer svg {
|
||||||
|
display: inline-block;
|
||||||
|
height: ${this.svgSize}px;
|
||||||
|
}
|
||||||
|
.material-icons {
|
||||||
|
font-family: 'Material Icons';
|
||||||
|
font-weight: normal;
|
||||||
|
font-style: normal;
|
||||||
|
line-height: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
display: inline-block;
|
||||||
|
line-height: inherit;
|
||||||
|
text-transform: none;
|
||||||
|
letter-spacing: normal;
|
||||||
|
word-wrap: normal;
|
||||||
|
white-space: nowrap;
|
||||||
|
direction: ltr;
|
||||||
|
|
||||||
|
/* Support for all WebKit browsers. */
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
/* Support for Safari and Chrome. */
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
|
||||||
|
/* Support for Firefox. */
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
|
||||||
|
/* Support for IE. */
|
||||||
|
font-feature-settings: 'liga';
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
${this.iconName ? html`<i class="material-icons">${this.iconName}</i>` : html``}
|
||||||
|
${this.brandName ? html`<div id="iconContainer"></div>` : html``}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
firstUpdated() {
|
||||||
|
if (this.brandName && !this.iconName) {
|
||||||
|
this.shadowRoot.querySelector('#iconContainer').innerHTML = icon(
|
||||||
|
faIcons[this.brandName]
|
||||||
|
).html[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
174
ts_web/elements/dees-input-checkbox.ts
Normal file
174
ts_web/elements/dees-input-checkbox.ts
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
import {
|
||||||
|
customElement,
|
||||||
|
DeesElement,
|
||||||
|
TemplateResult,
|
||||||
|
property,
|
||||||
|
html,
|
||||||
|
css,
|
||||||
|
cssManager
|
||||||
|
} from '@designestate/dees-element';
|
||||||
|
import * as domtools from '@designestate/dees-domtools';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
'dees-input-checkbox': DeesInputCheckbox;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@customElement('dees-input-checkbox')
|
||||||
|
export class DeesInputCheckbox extends DeesElement {
|
||||||
|
// STATIC
|
||||||
|
public static demo = () => html`<dees-input-checkbox></dees-input-checkbox>`;
|
||||||
|
|
||||||
|
// INSTANCE
|
||||||
|
public changeSubject = new domtools.rxjs.Subject();
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: String,
|
||||||
|
})
|
||||||
|
public key: string;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: String,
|
||||||
|
})
|
||||||
|
public label: string = 'Label';
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Boolean,
|
||||||
|
})
|
||||||
|
public value: boolean = false;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Boolean,
|
||||||
|
})
|
||||||
|
public required: boolean = false;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Boolean
|
||||||
|
})
|
||||||
|
public disabled: boolean = false;
|
||||||
|
|
||||||
|
public render(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
${domtools.elementBasic.styles}
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
margin: 20px 0px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.maincontainer {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 25px auto;
|
||||||
|
padding: 5px 0px;
|
||||||
|
color: ${this.goBright ? '#333' : '#ccc'};
|
||||||
|
}
|
||||||
|
|
||||||
|
.maincontainer:hover {
|
||||||
|
${this.goBright ? '#000' : '#ccc'};
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
margin-left: 15px;
|
||||||
|
line-height: 25px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-bottom: 1px solid #e4002b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox {
|
||||||
|
transition: all 0.1s;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border: 1px solid ${this.goBright ? '#CCC' : '#999'};
|
||||||
|
border-radius: 2px;
|
||||||
|
height: 24px;
|
||||||
|
width: 24px;
|
||||||
|
display: inline-block;
|
||||||
|
background: ${this.goBright ? '#fafafa' : '#222'};
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox.selected {
|
||||||
|
background: #039BE5;
|
||||||
|
border: 1px solid #039BE5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox.disabled {
|
||||||
|
background: none;
|
||||||
|
border: 1px dashed ${cssManager.bdTheme('#666666', '#666666')};
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox .checkmark {
|
||||||
|
display: inline-block;
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
-ms-transform: rotate(45deg); /* IE 9 */
|
||||||
|
-webkit-transform: rotate(45deg); /* Chrome, Safari, Opera */
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox .checkmark_stem {
|
||||||
|
position: absolute;
|
||||||
|
width: 3px;
|
||||||
|
height: 9px;
|
||||||
|
background-color: #fff;
|
||||||
|
left: 11px;
|
||||||
|
top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox .checkmark_kick {
|
||||||
|
position: absolute;
|
||||||
|
width: 3px;
|
||||||
|
height: 3px;
|
||||||
|
background-color: #fff;
|
||||||
|
left: 8px;
|
||||||
|
top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox.disabled .checkmark_stem, .checkbox.disabled .checkmark_kick {
|
||||||
|
background-color: ${cssManager.bdTheme('#333', '#fff')};
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="maincontainer" @click="${this.toggleSelected}">
|
||||||
|
<div class="checkbox ${this.value ? 'selected' : ''} ${this.disabled ? 'disabled' : ''}">
|
||||||
|
${this.value
|
||||||
|
? html`
|
||||||
|
<span class="checkmark">
|
||||||
|
<div class="checkmark_stem"></div>
|
||||||
|
<div class="checkmark_kick"></div>
|
||||||
|
</span>
|
||||||
|
`
|
||||||
|
: html``}
|
||||||
|
</div>
|
||||||
|
<div class="label">${this.label}</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async toggleSelected() {
|
||||||
|
if (this.disabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.value = !this.value;
|
||||||
|
this.dispatchEvent(
|
||||||
|
new CustomEvent('newValue', {
|
||||||
|
detail: this.value,
|
||||||
|
bubbles: true,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
this.changeSubject.next(this);
|
||||||
|
}
|
||||||
|
}
|
137
ts_web/elements/dees-input-dropdown.ts
Normal file
137
ts_web/elements/dees-input-dropdown.ts
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
import { customElement, LitElement, TemplateResult, property, html } from 'lit-element';
|
||||||
|
import * as domtools from '@designestate/dees-domtools';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
'dees-input-dropdown': DeesInputDropdown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@customElement('dees-input-dropdown')
|
||||||
|
export class DeesInputDropdown extends LitElement {
|
||||||
|
public static demo = () => html`<dees-input-dropdown></dees-input-dropdown>`
|
||||||
|
|
||||||
|
// INSTANCE
|
||||||
|
public changeSubject = new domtools.rxjs.Subject();
|
||||||
|
|
||||||
|
@property()
|
||||||
|
public label: string = 'Label';
|
||||||
|
|
||||||
|
@property()
|
||||||
|
public key: string;
|
||||||
|
|
||||||
|
@property()
|
||||||
|
public options: {option: string, key: string, payload?: any}[] = [];
|
||||||
|
|
||||||
|
@property()
|
||||||
|
public selectedOption: {option: string, key: string, payload?: any} = {
|
||||||
|
key: null,
|
||||||
|
option: null,
|
||||||
|
payload: null
|
||||||
|
};
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Boolean
|
||||||
|
})
|
||||||
|
public required: boolean = false;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Boolean
|
||||||
|
})
|
||||||
|
public disabled: boolean = false;
|
||||||
|
|
||||||
|
public render(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
${domtools.elementBasic.styles}
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host {
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.maincontainer {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selectedBox {
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
max-width: 420px;
|
||||||
|
height: 40px;
|
||||||
|
border: 1px solid #CCC;
|
||||||
|
padding: 12px;
|
||||||
|
z-index: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selectionBox {
|
||||||
|
pointer-events: none;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
opacity: 0;
|
||||||
|
position: relative;
|
||||||
|
background: #ffffff;
|
||||||
|
max-width: 420px;
|
||||||
|
box-shadow: 0px 0px 5px rgba(0,0,0,0.2);
|
||||||
|
height: 40px;
|
||||||
|
margin-top: -40px;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selectionBox.show {
|
||||||
|
pointer-events: all;
|
||||||
|
opacity: 1;
|
||||||
|
min-height: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option {
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option:hover {
|
||||||
|
background: #fafafa;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="maincontainer">
|
||||||
|
<div class="selectedBox" @click="${event => {this.toggleSelectionBox();}}">
|
||||||
|
${this.selectedOption?.option}
|
||||||
|
</div>
|
||||||
|
<div class="selectionBox">
|
||||||
|
${this.options.map(option => {
|
||||||
|
return html`
|
||||||
|
<div class="option" @click=${() => {this.updateSelection(option);}}>${option.option}</div>
|
||||||
|
`
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
firstUpdated() {
|
||||||
|
this.selectedOption = this.options[0] || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async updateSelection(selectedOption) {
|
||||||
|
this.selectedOption = selectedOption;
|
||||||
|
|
||||||
|
this.dispatchEvent(new CustomEvent('selectedOption', {
|
||||||
|
detail: selectedOption,
|
||||||
|
bubbles: true
|
||||||
|
}));
|
||||||
|
this.toggleSelectionBox();
|
||||||
|
this.changeSubject.next(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public toggleSelectionBox() {
|
||||||
|
this.shadowRoot.querySelector('.selectionBox').classList.toggle('show');
|
||||||
|
}
|
||||||
|
}
|
144
ts_web/elements/dees-input-fileupload.ts
Normal file
144
ts_web/elements/dees-input-fileupload.ts
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
import {
|
||||||
|
customElement,
|
||||||
|
DeesElement,
|
||||||
|
TemplateResult,
|
||||||
|
property,
|
||||||
|
html,
|
||||||
|
css,
|
||||||
|
unsafeCSS,
|
||||||
|
cssManager,
|
||||||
|
} from '@designestate/dees-element';
|
||||||
|
|
||||||
|
import * as domtools from '@designestate/dees-domtools';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
'dees-input-fileupload': DeesInputFileupload;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@customElement('dees-input-fileupload')
|
||||||
|
export class DeesInputFileupload extends DeesElement {
|
||||||
|
public static demo = () => html`<dees-input-fileupload></dees-input-fileupload>`;
|
||||||
|
|
||||||
|
// INSTANCE
|
||||||
|
public changeSubject = new domtools.rxjs.Subject();
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: String,
|
||||||
|
})
|
||||||
|
public label: string = null;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: String,
|
||||||
|
})
|
||||||
|
public key: string;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
attribute: false,
|
||||||
|
})
|
||||||
|
public value: File[] = [];
|
||||||
|
|
||||||
|
@property()
|
||||||
|
public state: 'idle' | 'dragOver' | 'dropped' | 'uploading' | 'completed' = 'idle';
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Boolean,
|
||||||
|
})
|
||||||
|
public required: boolean = false;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Boolean
|
||||||
|
})
|
||||||
|
public disabled: boolean = false;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
}
|
||||||
|
|
||||||
|
public static styles = [
|
||||||
|
cssManager.defaultStyles,
|
||||||
|
css`
|
||||||
|
:host {
|
||||||
|
position: relative;
|
||||||
|
display: grid;
|
||||||
|
margin: 10px 0px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.maincontainer {
|
||||||
|
color: ${cssManager.bdTheme('#333', '#ccc')};
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uploadButton {
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 20px 20px;
|
||||||
|
max-width: 200px;
|
||||||
|
background: ${cssManager.bdTheme('#fafafa', '#333333')};
|
||||||
|
border-radius: 3px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.uploadButton::after {
|
||||||
|
top: 7px;
|
||||||
|
right: 7px;
|
||||||
|
left: 7px;
|
||||||
|
bottom: 7px;
|
||||||
|
transform: scale3d(0.9, 0.9, 1);
|
||||||
|
position: absolute;
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
border: 4px dashed rgba(255, 255, 255, 0);
|
||||||
|
transition: all 0.2s;
|
||||||
|
}
|
||||||
|
.uploadButton.dragOver::after {
|
||||||
|
transform: scale3d(1, 1, 1);
|
||||||
|
border: 4px dashed rgba(255, 255, 255, 0.3);
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
|
||||||
|
public render(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
<div class="maincontainer">
|
||||||
|
${this.label ? html`<div class="label">${this.label}</div>` : null}
|
||||||
|
<div class="uploadButton ${this.state === 'dragOver' ? 'dragOver' : ''}">Upload File! (Drag/Drop enabled)</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async updateValue(eventArg: Event) {
|
||||||
|
const target: any = eventArg.target;
|
||||||
|
this.value = target.value;
|
||||||
|
this.changeSubject.next(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public firstUpdated() {
|
||||||
|
const dropArea = this.shadowRoot.querySelector('.uploadButton');
|
||||||
|
const handlerFunction = (eventArg: DragEvent) => {
|
||||||
|
eventArg.preventDefault();
|
||||||
|
switch(eventArg.type) {
|
||||||
|
case 'dragover':
|
||||||
|
this.state = 'dragOver';
|
||||||
|
break;
|
||||||
|
case 'dragleave':
|
||||||
|
this.state = 'idle';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
console.log(eventArg);
|
||||||
|
for (const file of Array.from(eventArg.dataTransfer.files)) {
|
||||||
|
this.value.push(file);
|
||||||
|
};
|
||||||
|
console.log(`Got ${this.value.length} files!`);
|
||||||
|
};
|
||||||
|
dropArea.addEventListener('dragenter', handlerFunction, false);
|
||||||
|
dropArea.addEventListener('dragleave', handlerFunction, false);
|
||||||
|
dropArea.addEventListener('dragover', handlerFunction, false);
|
||||||
|
dropArea.addEventListener('drop', handlerFunction, false);
|
||||||
|
}
|
||||||
|
}
|
112
ts_web/elements/dees-input-quantityselector.ts
Normal file
112
ts_web/elements/dees-input-quantityselector.ts
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
import { customElement, property, html, TemplateResult, DeesElement } from '@designestate/dees-element';
|
||||||
|
import * as domtools from '@designestate/dees-domtools';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
'dees-input-quantityselector': DeesInputQuantitySelector;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@customElement('dees-input-quantityselector')
|
||||||
|
export class DeesInputQuantitySelector extends DeesElement {
|
||||||
|
public static demo = () => html`<dees-input-quantityselector></dees-input-quantityselector>`;
|
||||||
|
|
||||||
|
// INSTANCE
|
||||||
|
public changeSubject = new domtools.rxjs.Subject();
|
||||||
|
|
||||||
|
@property()
|
||||||
|
public key: string;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Number
|
||||||
|
})
|
||||||
|
public value: number = 1;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Boolean,
|
||||||
|
})
|
||||||
|
public required: boolean = false;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Boolean
|
||||||
|
})
|
||||||
|
public disabled: boolean = false;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
${domtools.elementBasic.styles}
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
width: 110px;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
.maincontainer {
|
||||||
|
transition: all 0.1s;
|
||||||
|
font-size: 14px;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 33% 34% 33%;
|
||||||
|
text-align: center;
|
||||||
|
background:none;
|
||||||
|
line-height: 40px;
|
||||||
|
padding: 0px;
|
||||||
|
min-width: 100px;
|
||||||
|
color: ${this.goBright ? '#666' : '#CCC'};
|
||||||
|
border: ${this.goBright ? '1px solid #333' : '1px solid #CCC'};
|
||||||
|
}
|
||||||
|
|
||||||
|
.mainContainer:hover {
|
||||||
|
color: ${this.goBright ? '#333' : '#fff'};
|
||||||
|
border: ${this.goBright ? '1px solid #333' : '1px solid #fff'};
|
||||||
|
}
|
||||||
|
|
||||||
|
.minus {
|
||||||
|
padding-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.plus {
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selector {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selector:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quantity {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<div class="maincontainer">
|
||||||
|
<div class="selector minus" @click="${() => {this.decrease();}}">-</div>
|
||||||
|
<div class="quantity">${this.value}</div>
|
||||||
|
<div class="selector plus" @click="${() => {this.increase();}}">+</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
public increase () {
|
||||||
|
this.value++;
|
||||||
|
this.changeSubject.next(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public decrease () {
|
||||||
|
if (this.value > 0) {
|
||||||
|
this.value--;
|
||||||
|
} else {
|
||||||
|
// nothing to do here
|
||||||
|
}
|
||||||
|
this.changeSubject.next(this);
|
||||||
|
}
|
||||||
|
}
|
125
ts_web/elements/dees-input-radio.ts
Normal file
125
ts_web/elements/dees-input-radio.ts
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
import {customElement, LitElement, TemplateResult, property, html} from 'lit-element';
|
||||||
|
import * as domtools from '@designestate/dees-domtools';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
'dees-input-radio': DeesInputRadio;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@customElement('dees-input-radio')
|
||||||
|
export class DeesInputRadio extends LitElement {
|
||||||
|
public static demo = () => html`<dees-input-radio></dees-input-radio>`;
|
||||||
|
|
||||||
|
// INSTANCE
|
||||||
|
public changeSubject = new domtools.rxjs.Subject();
|
||||||
|
|
||||||
|
@property()
|
||||||
|
public key: string;
|
||||||
|
|
||||||
|
@property()
|
||||||
|
public label: string = 'Label';
|
||||||
|
|
||||||
|
@property()
|
||||||
|
public value: boolean = false;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Boolean,
|
||||||
|
})
|
||||||
|
public required: boolean = false;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Boolean
|
||||||
|
})
|
||||||
|
public disabled: boolean = false;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): TemplateResult {
|
||||||
|
return html `
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
margin: 20px 0px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.maincontainer {
|
||||||
|
transition: all 0.3s;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 25px auto;
|
||||||
|
padding: 5px 0px;
|
||||||
|
color: #ccc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.maincontainer:hover {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
margin-left: 15px;
|
||||||
|
line-height: 25px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: normal;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-bottom: 1px solid #e4002b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox {
|
||||||
|
transition: all 0.3s;
|
||||||
|
box-sizing: border-box;
|
||||||
|
border-radius: 20px;
|
||||||
|
border: 1px solid #999;
|
||||||
|
height: 24px;
|
||||||
|
width: 24px;
|
||||||
|
display: inline-block;
|
||||||
|
background: #222;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox.selected {
|
||||||
|
background: #039BE5;
|
||||||
|
border: 1px solid #039BE5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.maincontainer:hover .checkbox.selected {
|
||||||
|
background: #03A9F4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.innercircle {
|
||||||
|
transition: all 0.3s;
|
||||||
|
margin: 6px 0px 0px 6px;
|
||||||
|
background: #222;
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="maincontainer" @click="${this.toggleSelected}">
|
||||||
|
<div class="checkbox ${this.value ? 'selected' : ''}">
|
||||||
|
${this.value ? html`<div class="innercircle"></div>`: html``}
|
||||||
|
</div>
|
||||||
|
<div class="label">${this.label}</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async toggleSelected () {
|
||||||
|
this.value = !this.value;
|
||||||
|
this.dispatchEvent(new CustomEvent('newValue', {
|
||||||
|
detail: this.value,
|
||||||
|
bubbles: true
|
||||||
|
}));
|
||||||
|
this.changeSubject.next(this);
|
||||||
|
}
|
||||||
|
}
|
115
ts_web/elements/dees-input-text.ts
Normal file
115
ts_web/elements/dees-input-text.ts
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
import {customElement, DeesElement, TemplateResult, property, html, cssManager} from '@designestate/dees-element';
|
||||||
|
import * as domtools from '@designestate/dees-domtools';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
'dees-input-text': DeesInputText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@customElement('dees-input-text')
|
||||||
|
export class DeesInputText extends DeesElement {
|
||||||
|
public static demo = () => html`<dees-input-text></dees-input-text>`;
|
||||||
|
|
||||||
|
// INSTANCE
|
||||||
|
public changeSubject = new domtools.rxjs.Subject();
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: String
|
||||||
|
})
|
||||||
|
public label: string = 'Label';
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: String
|
||||||
|
})
|
||||||
|
public key: string;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: String
|
||||||
|
})
|
||||||
|
public value: string = '';
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Boolean
|
||||||
|
})
|
||||||
|
public required: boolean = false;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Boolean
|
||||||
|
})
|
||||||
|
public disabled: boolean = false;
|
||||||
|
|
||||||
|
public render(): TemplateResult {
|
||||||
|
return html `
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host {
|
||||||
|
position: relative;
|
||||||
|
display: grid;
|
||||||
|
margin: 10px 0px;
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.maincontainer {
|
||||||
|
color: ${this.goBright ? '#333' : '#ccc'};
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
margin-top: 5px;
|
||||||
|
background: ${this.goBright ? '#fafafa' : '#222'};
|
||||||
|
border-top: ${this.goBright ? '1px solid #CCC' : '1px solid #444'};
|
||||||
|
border-bottom: ${this.goBright ? '1px solid #CCC' : '1px solid #333'};
|
||||||
|
border-right: ${this.goBright ? '1px solid #CCC' : 'none'};
|
||||||
|
border-left: ${this.goBright ? '1px solid #CCC' : 'none'};
|
||||||
|
padding-left:10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
border-radius: 2px;
|
||||||
|
width: 100%;
|
||||||
|
line-height: 48px;
|
||||||
|
transition: all 0.2s;
|
||||||
|
outline: none;
|
||||||
|
font-size: 16px;
|
||||||
|
color: ${this.goBright ? '#333' : '#ccc'};
|
||||||
|
}
|
||||||
|
|
||||||
|
input:disabled {
|
||||||
|
background: ${cssManager.bdTheme('#ffffff00', '#11111100')};
|
||||||
|
border: 1px dashed ${cssManager.bdTheme('#666666', '#666666')};
|
||||||
|
color: #9b9b9e;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-bottom: 1px solid #e4002b;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="maincontainer">
|
||||||
|
<div class="label">${this.label}</div>
|
||||||
|
<input type="text" value=${this.value} @input="${this.updateValue}" .disabled=${this.disabled} />
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async updateValue(eventArg: Event) {
|
||||||
|
const target: any = eventArg.target;
|
||||||
|
this.value = target.value;
|
||||||
|
this.changeSubject.next(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async freeze() {
|
||||||
|
this.disabled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async unfreeze() {
|
||||||
|
this.disabled = false;
|
||||||
|
}
|
||||||
|
}
|
141
ts_web/elements/dees-spinner.ts
Normal file
141
ts_web/elements/dees-spinner.ts
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
import {
|
||||||
|
customElement,
|
||||||
|
html,
|
||||||
|
DeesElement,
|
||||||
|
property,
|
||||||
|
TemplateResult,
|
||||||
|
cssManager,
|
||||||
|
css,
|
||||||
|
unsafeCSS,
|
||||||
|
} from '@designestate/dees-element';
|
||||||
|
|
||||||
|
import * as domtools from '@designestate/dees-domtools';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
'dees-spinner': DeesSpinner;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@customElement('dees-spinner')
|
||||||
|
export class DeesSpinner extends DeesElement {
|
||||||
|
public static demo = () => html`
|
||||||
|
<dees-spinner></dees-spinner>
|
||||||
|
<dees-spinner status="success"></dees-spinner>
|
||||||
|
<dees-spinner status="error"></dees-spinner>
|
||||||
|
`;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Number,
|
||||||
|
})
|
||||||
|
public size = 20;
|
||||||
|
|
||||||
|
@property()
|
||||||
|
public status: 'normal' | 'pending' | 'success' | 'error' = 'normal';
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static styles = [
|
||||||
|
cssManager.defaultStyles,
|
||||||
|
css`
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#loading {
|
||||||
|
transition: none;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-content: center;
|
||||||
|
background: #8bc34a00;
|
||||||
|
border: 3px solid ${cssManager.bdTheme('rgba(0, 0, 0, 0.1)', 'rgba(255, 255, 255, 0.3)')};
|
||||||
|
border-radius: 50%;
|
||||||
|
border-top-color: ${cssManager.bdTheme('#333', '#fff')};
|
||||||
|
animation: spin 1s ease-in-out infinite;
|
||||||
|
-webkit-animation: spin 1s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
#loading.success {
|
||||||
|
border: 0px solid rgba(255, 255, 255, 0);
|
||||||
|
background: #8bc34a;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: none;
|
||||||
|
-webkit-animation: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#loading.error {
|
||||||
|
border: 0px solid rgba(255, 255, 255, 0);
|
||||||
|
background: #e64a19;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: none;
|
||||||
|
-webkit-animation: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
to {
|
||||||
|
-webkit-transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@-webkit-keyframes spin {
|
||||||
|
to {
|
||||||
|
-webkit-transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#loading .checkmark {
|
||||||
|
display: inline-block;
|
||||||
|
width: 22px;
|
||||||
|
height: 22px;
|
||||||
|
-ms-transform: rotate(45deg); /* IE 9 */
|
||||||
|
-webkit-transform: rotate(45deg); /* Chrome, Safari, Opera */
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
#loading .checkmark_stem {
|
||||||
|
position: absolute;
|
||||||
|
width: 3px;
|
||||||
|
height: 9px;
|
||||||
|
background-color: #fff;
|
||||||
|
left: 9px;
|
||||||
|
top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#loading .checkmark_kick {
|
||||||
|
position: absolute;
|
||||||
|
width: 3px;
|
||||||
|
height: 3px;
|
||||||
|
background-color: #fff;
|
||||||
|
left: 6px;
|
||||||
|
top: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#loading.disabled .checkmark_stem,
|
||||||
|
#loading.disabled .checkmark_kick {
|
||||||
|
background-color: ${cssManager.bdTheme('#333', '#fff')};
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
#loading {
|
||||||
|
width: ${this.size}px;
|
||||||
|
height: ${this.size}px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="${this.status}" id="loading">
|
||||||
|
${this.status === 'success' || this.status === 'error'
|
||||||
|
? html`
|
||||||
|
<span class="checkmark">
|
||||||
|
<div class="checkmark_stem"></div>
|
||||||
|
<div class="checkmark_kick"></div>
|
||||||
|
</span>
|
||||||
|
`
|
||||||
|
: null}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
212
ts_web/elements/dees-stepper.ts
Normal file
212
ts_web/elements/dees-stepper.ts
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
import {
|
||||||
|
DeesElement,
|
||||||
|
customElement,
|
||||||
|
html,
|
||||||
|
css,
|
||||||
|
unsafeCSS,
|
||||||
|
cssManager,
|
||||||
|
property,
|
||||||
|
TemplateResult,
|
||||||
|
} from '@designestate/dees-element';
|
||||||
|
|
||||||
|
import * as domtools from '@designestate/dees-domtools';
|
||||||
|
|
||||||
|
export interface IStep {
|
||||||
|
title: string;
|
||||||
|
content: TemplateResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
@customElement('dees-stepper')
|
||||||
|
export class DeesStepper extends DeesElement {
|
||||||
|
public static demo = () => html` <dees-stepper></dees-stepper> `;
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Array,
|
||||||
|
})
|
||||||
|
public steps: IStep[] = [
|
||||||
|
{
|
||||||
|
title: 'Whats your name?',
|
||||||
|
content: html`
|
||||||
|
<dees-form>
|
||||||
|
<dees-input-text key="email" label="Your Email" value="hello@something.com" disabled></dees-input-text>
|
||||||
|
<dees-input-text key="firstName" required label="Vorname"></dees-input-text>
|
||||||
|
<dees-input-text key="lastName" required label="Nachname"></dees-input-text>
|
||||||
|
<dees-form-submit>Next</dees-form-submit>
|
||||||
|
</dees-form>
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Whats your mobile number?',
|
||||||
|
content: html``,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Whats the verification code?',
|
||||||
|
content: html``,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Whats your new password?',
|
||||||
|
content: html``,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Verification:',
|
||||||
|
content: html``,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
@property({
|
||||||
|
type: Object,
|
||||||
|
})
|
||||||
|
public selectedStep: IStep;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static styles = [
|
||||||
|
cssManager.defaultStyles,
|
||||||
|
css`
|
||||||
|
:host {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.stepperContainer {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: ${cssManager.bdTheme('#eeeeeb', '#000')};
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step {
|
||||||
|
position: relative;
|
||||||
|
pointer-events: none;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: all 0.7s ease-in-out;
|
||||||
|
max-width: 500px;
|
||||||
|
min-height: 300px;
|
||||||
|
border-radius: 3px;
|
||||||
|
background: ${cssManager.bdTheme('#ffffff', '#181818')};
|
||||||
|
color: ${cssManager.bdTheme('#333', '#fff')};
|
||||||
|
margin: auto;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
filter: opacity(0.5);
|
||||||
|
box-shadow: 0px 0px 3px #00000010;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step.selected {
|
||||||
|
pointer-events: all;
|
||||||
|
filter: opacity(1);
|
||||||
|
box-shadow: 0px 0px 5px #00000010;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step.hiddenStep {
|
||||||
|
filter: opacity(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.step .stepCounter {
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
right: 0px;
|
||||||
|
padding: 10px 15px;
|
||||||
|
font-size: 12px;
|
||||||
|
border-bottom-left-radius: 3px;
|
||||||
|
background: ${cssManager.bdTheme('#00000008', '#ffffff08')};
|
||||||
|
}
|
||||||
|
|
||||||
|
.step .goBack {
|
||||||
|
position: absolute;
|
||||||
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
|
padding: 10px 15px;
|
||||||
|
font-size: 12px;
|
||||||
|
border-bottom-right-radius: 3px;
|
||||||
|
background: ${cssManager.bdTheme('#00000008', '#ffffff08')};
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step .goBack:hover {
|
||||||
|
background: ${cssManager.bdTheme('#00000012', '#ffffff12')};
|
||||||
|
}
|
||||||
|
|
||||||
|
.step .title {
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 50px;
|
||||||
|
font-family: Roboto;
|
||||||
|
font-size: 25px;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.step .content {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
|
||||||
|
public render() {
|
||||||
|
return html`
|
||||||
|
<div class="stepperContainer">
|
||||||
|
${this.steps.map(
|
||||||
|
(stepArg) =>
|
||||||
|
html`<div class="step ${stepArg === this.selectedStep ? 'selected' : null} ${this.getIndexOfStep(stepArg) > this.getIndexOfStep(this.selectedStep) ? 'hiddenStep' : ''}">
|
||||||
|
${this.getIndexOfStep(stepArg) > 0 ? html`<div class="goBack" @click=${this.goBack}><- go to previous step</div>` : ``}
|
||||||
|
<div class="stepCounter">Step ${this.steps.findIndex(elementArg => elementArg === stepArg) + 1} of ${this.steps.length} </div>
|
||||||
|
<div class="title">${stepArg.title}</div>
|
||||||
|
<div class="content">${stepArg.content}</div>
|
||||||
|
</div> `
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getIndexOfStep = (stepArg: IStep): number => {
|
||||||
|
return this.steps.findIndex(stepArg2 => stepArg === stepArg2 )
|
||||||
|
}
|
||||||
|
|
||||||
|
public firstUpdated() {
|
||||||
|
this.selectedStep = this.steps[0];
|
||||||
|
this.setScrollStatus();
|
||||||
|
domtools.plugins.smartdelay.delayFor(2000).then(() => {
|
||||||
|
this.goNext();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
public updated() {
|
||||||
|
this.setScrollStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
public scroller: typeof domtools.plugins.sweetScroll.prototype;
|
||||||
|
|
||||||
|
public async setScrollStatus() {
|
||||||
|
await domtools.plugins.smartdelay.delayFor(50);
|
||||||
|
const stepperContainer: HTMLElement = this.shadowRoot.querySelector('.stepperContainer');
|
||||||
|
const firstStepElement: HTMLElement = this.shadowRoot.querySelector('.step');
|
||||||
|
const selectedStepElement: HTMLElement = this.shadowRoot.querySelector('.selected');
|
||||||
|
if (!stepperContainer.style.paddingTop) {
|
||||||
|
stepperContainer.style.paddingTop = `${(stepperContainer.offsetHeight / 2) - (selectedStepElement.offsetHeight / 2)}px`;
|
||||||
|
}
|
||||||
|
console.log('Setting scroll status');
|
||||||
|
console.log(selectedStepElement);
|
||||||
|
const scrollPosition = selectedStepElement.offsetTop - (stepperContainer.offsetHeight / 2) + (selectedStepElement.offsetHeight / 2) ;
|
||||||
|
console.log(scrollPosition);
|
||||||
|
const domtoolsInstance = await domtools.DomTools.setupDomTools()
|
||||||
|
if (!this.scroller) {
|
||||||
|
this.scroller = new domtools.plugins.sweetScroll({
|
||||||
|
vertical: true,
|
||||||
|
horizontal: false,
|
||||||
|
easing: 'easeInOutQuint'
|
||||||
|
}, stepperContainer);
|
||||||
|
}
|
||||||
|
this.scroller.to(scrollPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
public goBack() {
|
||||||
|
const currentIndex = this.steps.findIndex(stepArg => stepArg === this.selectedStep);
|
||||||
|
this.selectedStep = this.steps[currentIndex - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
public goNext() {
|
||||||
|
const currentIndex = this.steps.findIndex(stepArg => stepArg === this.selectedStep);
|
||||||
|
this.selectedStep = this.steps[currentIndex + 1];
|
||||||
|
}
|
||||||
|
}
|
26
ts_web/elements/dees-toast.ts
Normal file
26
ts_web/elements/dees-toast.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { customElement, LitElement, TemplateResult, html } from 'lit-element';
|
||||||
|
|
||||||
|
import * as domtools from '@designestate/dees-domtools';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
'dees-toast': DeesToast;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@customElement('dees-toast')
|
||||||
|
export class DeesToast extends LitElement {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
domtools.elementBasic.setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
${domtools.elementBasic.styles}
|
||||||
|
<style></style>
|
||||||
|
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
86
ts_web/elements/dees-updater.ts
Normal file
86
ts_web/elements/dees-updater.ts
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
import { customElement, LitElement, TemplateResult, html, property } from 'lit-element';
|
||||||
|
|
||||||
|
import * as domtools from '@designestate/dees-domtools';
|
||||||
|
|
||||||
|
|
||||||
|
import './dees-windowlayer';
|
||||||
|
import { css, cssManager } from '@designestate/dees-element';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
'dees-updater': DeesUpdater;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@customElement('dees-updater')
|
||||||
|
export class DeesUpdater extends LitElement {
|
||||||
|
public static demo = () => html`<dees-updater ></dees-updater>`;
|
||||||
|
|
||||||
|
@property()
|
||||||
|
currentVersion: string;
|
||||||
|
|
||||||
|
@property()
|
||||||
|
updatedVersion: string;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
domtools.elementBasic.setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static styles = [
|
||||||
|
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')};
|
||||||
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttonContainer {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 50% 50%;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
]
|
||||||
|
|
||||||
|
public render(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
<dees-windowlayer @clicked="${this.windowLayerClicked}">
|
||||||
|
<div class="modalContainer">
|
||||||
|
<div class="headingContainer">
|
||||||
|
<dees-spinner .size=${60}></dees-spinner>
|
||||||
|
<h1>Updating the application...</h1>
|
||||||
|
</div>
|
||||||
|
<div class="buttonContainer">
|
||||||
|
<dees-button>More info</dees-button>
|
||||||
|
<dees-button>Changelog</dees-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</dees-windowlayer>>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private windowLayerClicked() {
|
||||||
|
const windowLayer = this.shadowRoot.querySelector('dees-windowlayer');
|
||||||
|
windowLayer.toggleVisibility();
|
||||||
|
}
|
||||||
|
}
|
72
ts_web/elements/dees-windowlayer.ts
Normal file
72
ts_web/elements/dees-windowlayer.ts
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import { customElement, LitElement, TemplateResult, html, property } from 'lit-element';
|
||||||
|
|
||||||
|
import * as domtools from '@designestate/dees-domtools';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
'dees-windowlayer': DeesWindowLayer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@customElement('dees-windowlayer')
|
||||||
|
export class DeesWindowLayer extends LitElement {
|
||||||
|
// STATIC
|
||||||
|
public static demo = () => html`<dees-windowlayer></dees-windowlayer>`;
|
||||||
|
|
||||||
|
// INSTANCE
|
||||||
|
@property({
|
||||||
|
type: Boolean
|
||||||
|
})
|
||||||
|
public visible = false;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
domtools.elementBasic.setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
public render(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
${domtools.elementBasic.styles}
|
||||||
|
<style>
|
||||||
|
.windowOverlay {
|
||||||
|
transition: all 0.3s;
|
||||||
|
will-change: transform;
|
||||||
|
position: fixed;
|
||||||
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
|
height: 100vh;
|
||||||
|
width: 100vw;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: rgba(0, 0, 0, 0.0);
|
||||||
|
backdrop-filter: brightness(1);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.visible {
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
backdrop-filter: brightness(0.3);
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div @click=${this.dispatchClicked} class="windowOverlay ${this.visible ? 'visible' : null}">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
firstUpdated() {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.visible = true;
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatchClicked() {
|
||||||
|
this.dispatchEvent(new CustomEvent('clicked'))
|
||||||
|
}
|
||||||
|
|
||||||
|
public toggleVisibility () {
|
||||||
|
this.visible = !this.visible;
|
||||||
|
}
|
||||||
|
}
|
15
ts_web/elements/index.ts
Normal file
15
ts_web/elements/index.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
export * from './dees-button';
|
||||||
|
export * from './dees-form';
|
||||||
|
export * from './dees-form-submit';
|
||||||
|
export * from './dees-icon';
|
||||||
|
export * from './dees-input-checkbox';
|
||||||
|
export * from './dees-input-dropdown';
|
||||||
|
export * from './dees-input-fileupload';
|
||||||
|
export * from './dees-input-quantityselector';
|
||||||
|
export * from './dees-input-radio';
|
||||||
|
export * from './dees-input-text';
|
||||||
|
export * from './dees-spinner';
|
||||||
|
export * from './dees-stepper';
|
||||||
|
export * from './dees-toast';
|
||||||
|
export * from './dees-updater';
|
||||||
|
export * from './dees-windowlayer';
|
@ -1,35 +0,0 @@
|
|||||||
import { LitElement, property, html, customElement } from 'lit-element';
|
|
||||||
import { TemplateResult } from 'lit-html';
|
|
||||||
|
|
||||||
@customElement('lele-element')
|
|
||||||
export class LeleElement extends LitElement {
|
|
||||||
@property()
|
|
||||||
public footerText = `Lossless GmbH - 2018`;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
// you have access to all kinds of things through this.
|
|
||||||
// this.setAttribute('gotIt','true');
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public render(): TemplateResult {
|
|
||||||
return html`
|
|
||||||
<style>
|
|
||||||
@import url('https://fonts.googleapis.com/css?family=Roboto');
|
|
||||||
:host {
|
|
||||||
font-family: 'Roboto', sans-serif;
|
|
||||||
background: #FCFCFC;
|
|
||||||
box-shadow: 0px 0px 5px rgba(0,0,0,0.6);
|
|
||||||
display: block;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
:host([hidden]) {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<slot></slot>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1 @@
|
|||||||
import { LeleElement } from './elements/lele-element';
|
export * from './elements/index';
|
||||||
|
|
||||||
export {
|
|
||||||
LeleElement
|
|
||||||
};
|
|
||||||
|
Reference in New Issue
Block a user