@exmg/exm-form-drawer 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +131 -0
- package/index.d.ts +5 -0
- package/index.js +6 -0
- package/package.json +51 -0
- package/src/exm-drawer.d.ts +30 -0
- package/src/exm-drawer.js +71 -0
- package/src/exm-form-drawer-base.d.ts +85 -0
- package/src/exm-form-drawer-base.js +223 -0
- package/src/exm-form-drawer.d.ts +10 -0
- package/src/exm-form-drawer.js +16 -0
- package/src/styles/exm-drawer-styles-css.d.ts +2 -0
- package/src/styles/exm-drawer-styles-css.js +4 -0
- package/src/styles/exm-drawer-styles.scss +15 -0
- package/src/styles/exm-form-drawer-styles-css.d.ts +2 -0
- package/src/styles/exm-form-drawer-styles-css.js +4 -0
- package/src/styles/exm-form-drawer-styles.scss +46 -0
package/README.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# `<exm-form-drawer>` [](https://www.npmjs.com/package/@exmg/exm-form-drawer)
|
|
2
|
+
|
|
3
|
+
This package provides dialog drawer functionality.
|
|
4
|
+
|
|
5
|
+
Components included:
|
|
6
|
+
|
|
7
|
+
1. **exm-drawer** - basic component
|
|
8
|
+
2. **exm-form-drawer** - form drawer
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install @exmg/exm-form-drawer
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Before start ensure that you have installed `web-animation-js`. It is required by `@polymer/paper-dialog`.
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install web-animation-js
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Load this script in index.html
|
|
23
|
+
|
|
24
|
+
```html
|
|
25
|
+
<!-- Ensure Web Animations polyfill is loaded -->
|
|
26
|
+
<script src="../node_modules/web-animations-js/web-animations-next-lite.min.js"></script>
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Some dependencies `@exmg/exm-paper-combobox` use `@apply` to apply css mixins.
|
|
30
|
+
This require to load script in index.html
|
|
31
|
+
|
|
32
|
+
```html
|
|
33
|
+
<script src="../node_modules/@webcomponents/shadycss/apply-shim.min.js"></script>
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Components
|
|
37
|
+
|
|
38
|
+
### \<exm-drawer>
|
|
39
|
+
|
|
40
|
+
It is basic component that probably should not be used directly.
|
|
41
|
+
It serves only as drawer without form functionality, so it is content agnostic.
|
|
42
|
+
You can pass any dom markup as children of this component.
|
|
43
|
+
|
|
44
|
+
### \<exm-form-drawer>
|
|
45
|
+
|
|
46
|
+
Wraps around **exm-drawer**.
|
|
47
|
+
|
|
48
|
+
Provides form functionality to drawer:
|
|
49
|
+
|
|
50
|
+
- submit and cancel buttons
|
|
51
|
+
- title
|
|
52
|
+
- material styling
|
|
53
|
+
|
|
54
|
+
## API
|
|
55
|
+
|
|
56
|
+
### Slots
|
|
57
|
+
|
|
58
|
+
| Name | Description |
|
|
59
|
+
| --------- | --------------------------- |
|
|
60
|
+
| _default_ | Form elements within drawer |
|
|
61
|
+
|
|
62
|
+
### Properties/Attributes
|
|
63
|
+
|
|
64
|
+
| Name | Type | Default | Description |
|
|
65
|
+
| ------------------------------- | --------- | ------- | --------------------------------------------------------------------------- |
|
|
66
|
+
| `opened` | `boolean` | _None_ | whether or not drawer is visible |
|
|
67
|
+
| `no-cancel-on-outside-click` | `boolean` | _None_ | whether or not clicking outside drawer should close drawer |
|
|
68
|
+
| `submit-btn-title` | `string` | _None_ | title of submit button. Default "Submit" |
|
|
69
|
+
| `cancel-btn-title` | `string` | _None_ | title of cancel button. Default "Cancel" |
|
|
70
|
+
| `keep-opened-on-submit-success` | `boolean` | _None_ | whether or not drawer should be hidden after successful form submission |
|
|
71
|
+
| `reset-form-on-submit-success` | `boolean` | _None_ | whether or not drawer form should be reset after successful form submission |
|
|
72
|
+
|
|
73
|
+
### Events
|
|
74
|
+
|
|
75
|
+
| Name | Description |
|
|
76
|
+
| --------------------------- | ------------------------ |
|
|
77
|
+
| `exm-drawer-opened-changed` | when drawer shown/hidden |
|
|
78
|
+
|
|
79
|
+
### CSS Custom Properties
|
|
80
|
+
|
|
81
|
+
| Name | Description |
|
|
82
|
+
| ------------------------------------------ | ------------------------------------------------------------------------------------ |
|
|
83
|
+
| `--exm-drawer-color` | set the height of slot container - handy when wanting to control max-height of form. |
|
|
84
|
+
| `--exm-drawer-bg-color` | set the padding right for the form internal element. |
|
|
85
|
+
| `--mdc-theme-primary` | _None_ |
|
|
86
|
+
| `--mdc-theme-on-surface` | _None_ |
|
|
87
|
+
| `--mdc-theme-surface` | _None_ |
|
|
88
|
+
| `--exm-form-drawer-header-separator-color` | Color of header seperator of form |
|
|
89
|
+
| `--exm-drawer-max-width` | Max width of drawer |
|
|
90
|
+
|
|
91
|
+
#### Notes about drawer form
|
|
92
|
+
|
|
93
|
+
All dom markup passed as children into **exm-form-drawer** will be wrapped into **exm-form** underhood.
|
|
94
|
+
|
|
95
|
+
To properly handle form submission, you should call done() or error() on form instance after receiving **submit**
|
|
96
|
+
event from **exm-form-drawer**. Please read https://github.com/ExmgElements/exm-form docs for more info.
|
|
97
|
+
|
|
98
|
+
## Usage
|
|
99
|
+
|
|
100
|
+
### Form drawer
|
|
101
|
+
|
|
102
|
+
```html
|
|
103
|
+
<exm-form-drawer
|
|
104
|
+
?opened="${this.opened}"
|
|
105
|
+
?keep-opened-on-submit-success="${this.keepOpenedOnSubmitSuccess}"
|
|
106
|
+
?reset-form-on-submit-success="${this.resetFormOnSubmitSuccess}"
|
|
107
|
+
?no-cancel-on-outside-click="${this.noCancelOnOutsideClick}"
|
|
108
|
+
@exm-drawer-opened-changed="${this.handleOpenedChanged}"
|
|
109
|
+
submit-btn-title="Create"
|
|
110
|
+
@submit="${this.onSubmit}"
|
|
111
|
+
@cancel="${this.onCancel}"
|
|
112
|
+
>
|
|
113
|
+
<span slot="title">New event</span>
|
|
114
|
+
<exm-paper-combobox label="Type" name="type" selected="0" always-float-label>
|
|
115
|
+
<paper-item>Trivia</paper-item>
|
|
116
|
+
<paper-item>Other</paper-item>
|
|
117
|
+
</exm-paper-combobox>
|
|
118
|
+
<paper-input name="question" label="Question" value="Who's Dylan Hartigan's favorite artist?" required></paper-input>
|
|
119
|
+
<paper-input name="answer_a" label="Answer A" value="Beyoncé"></paper-input>
|
|
120
|
+
<paper-input name="answer_b" label="Answer B" value="Eminem"></paper-input>
|
|
121
|
+
<paper-input name="answer_c" label="Answer C" value="Ariana Grande"></paper-input>
|
|
122
|
+
<br />
|
|
123
|
+
<exm-button unelevated> + Add answer </exm-button>
|
|
124
|
+
</exm-form-drawer>
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Additional references
|
|
128
|
+
|
|
129
|
+
- [Additional Documentation](https://exmg.github.io/exmachina-web-components/ExmgFormDrawer.html)
|
|
130
|
+
|
|
131
|
+
- [Demo](https://exmg.github.io/exmachina-web-components/demo/?el=exm-form-drawer)
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { ExmgDrawer } from './src/exm-drawer.js';
|
|
2
|
+
export { ExmgFormDrawer } from './src/exm-form-drawer.js';
|
|
3
|
+
export { ExmgFormDrawerBase } from './src/exm-form-drawer-base.js';
|
|
4
|
+
export { style as drawerStyles } from './src/styles/exm-drawer-styles-css.js';
|
|
5
|
+
export { style as formDrawerStyles } from './src/styles/exm-form-drawer-styles-css.js';
|
package/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { ExmgDrawer } from './src/exm-drawer.js';
|
|
2
|
+
export { ExmgFormDrawer } from './src/exm-form-drawer.js';
|
|
3
|
+
export { ExmgFormDrawerBase } from './src/exm-form-drawer-base.js';
|
|
4
|
+
export { style as drawerStyles } from './src/styles/exm-drawer-styles-css.js';
|
|
5
|
+
export { style as formDrawerStyles } from './src/styles/exm-form-drawer-styles-css.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@exmg/exm-form-drawer",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"module": "index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./index.js",
|
|
9
|
+
"./exm-form-drawer.js": "./src/exm-form-drawer.js",
|
|
10
|
+
"./exm-drawer.js": "./src/exm-drawer.js"
|
|
11
|
+
},
|
|
12
|
+
"description": "Form side drawer element",
|
|
13
|
+
"contributors": [
|
|
14
|
+
"Ex Machina"
|
|
15
|
+
],
|
|
16
|
+
"keywords": [
|
|
17
|
+
"web-components",
|
|
18
|
+
"lit",
|
|
19
|
+
"form"
|
|
20
|
+
],
|
|
21
|
+
"files": [
|
|
22
|
+
"**/*.scss",
|
|
23
|
+
"**/*.js",
|
|
24
|
+
"**/*.d.ts"
|
|
25
|
+
],
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git@github.com:exmg/exm-web-components.git",
|
|
29
|
+
"directory": "packages/exm-form-drawer"
|
|
30
|
+
},
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@exmg/exm-button": "^1.0.0",
|
|
34
|
+
"@exmg/exm-form": "^1.0.0",
|
|
35
|
+
"@material/typography": "^14.0.0",
|
|
36
|
+
"@polymer/neon-animation": "^3.0.1",
|
|
37
|
+
"@polymer/paper-dialog": "^3.0.1",
|
|
38
|
+
"lit": "^3.0.0",
|
|
39
|
+
"tslib": "^2.6.2"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@exmg/lit-cli": "1.1.13"
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build:styles": "exmg-lit-cli sass -f \"./**/*.scss\""
|
|
46
|
+
},
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
},
|
|
50
|
+
"gitHead": "0907b55c89325d59902b98a64c352bf6e1fc81ff"
|
|
51
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
import '@polymer/neon-animation/animations/slide-from-right-animation.js';
|
|
3
|
+
import '@polymer/neon-animation/animations/slide-right-animation.js';
|
|
4
|
+
import '@polymer/paper-dialog/paper-dialog.js';
|
|
5
|
+
export declare class ExmgDrawer extends LitElement {
|
|
6
|
+
/**
|
|
7
|
+
* The opened state of the drawer
|
|
8
|
+
* @type {Boolean}
|
|
9
|
+
*/
|
|
10
|
+
opened: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Prevent cancel on outside click or not
|
|
13
|
+
* @type {Boolean}
|
|
14
|
+
*/
|
|
15
|
+
noCancelOnOutsideClick: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Scroll action of the drawer
|
|
18
|
+
* @type {'lock' | 'refit' | 'cancel' | undefined}
|
|
19
|
+
*/
|
|
20
|
+
scrollAction?: 'lock' | 'refit' | 'cancel' | undefined;
|
|
21
|
+
handleOpenedChanged(e: CustomEvent): void;
|
|
22
|
+
openDialog(): void;
|
|
23
|
+
static styles: import("lit").CSSResult[];
|
|
24
|
+
render(): import("lit-html").TemplateResult<1>;
|
|
25
|
+
}
|
|
26
|
+
declare global {
|
|
27
|
+
interface HTMLElementTagNameMap {
|
|
28
|
+
'exm-drawer': ExmgDrawer;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { LitElement, html } from 'lit';
|
|
3
|
+
import { customElement, property } from 'lit/decorators.js';
|
|
4
|
+
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
5
|
+
import '@polymer/neon-animation/animations/slide-from-right-animation.js';
|
|
6
|
+
import '@polymer/neon-animation/animations/slide-right-animation.js';
|
|
7
|
+
import '@polymer/paper-dialog/paper-dialog.js';
|
|
8
|
+
import { style } from './styles/exm-drawer-styles-css.js';
|
|
9
|
+
let ExmgDrawer = class ExmgDrawer extends LitElement {
|
|
10
|
+
constructor() {
|
|
11
|
+
super(...arguments);
|
|
12
|
+
/**
|
|
13
|
+
* The opened state of the drawer
|
|
14
|
+
* @type {Boolean}
|
|
15
|
+
*/
|
|
16
|
+
this.opened = false;
|
|
17
|
+
/**
|
|
18
|
+
* Prevent cancel on outside click or not
|
|
19
|
+
* @type {Boolean}
|
|
20
|
+
*/
|
|
21
|
+
this.noCancelOnOutsideClick = false;
|
|
22
|
+
}
|
|
23
|
+
handleOpenedChanged(e) {
|
|
24
|
+
this.opened = e.detail.value;
|
|
25
|
+
this.dispatchEvent(new CustomEvent('exm-drawer-opened-changed', {
|
|
26
|
+
bubbles: true,
|
|
27
|
+
composed: true,
|
|
28
|
+
detail: {
|
|
29
|
+
value: e.detail.value,
|
|
30
|
+
},
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
openDialog() {
|
|
34
|
+
this.opened = true;
|
|
35
|
+
}
|
|
36
|
+
render() {
|
|
37
|
+
return html `
|
|
38
|
+
<style>
|
|
39
|
+
paper-dialog {
|
|
40
|
+
max-width: var(--exm-drawer-max-width, ${this.style.maxWidth || '547px'});
|
|
41
|
+
}
|
|
42
|
+
</style>
|
|
43
|
+
<paper-dialog
|
|
44
|
+
scroll-action=${ifDefined(this.scrollAction)}
|
|
45
|
+
?opened="${this.opened}"
|
|
46
|
+
?no-cancel-on-outside-click="${this.noCancelOnOutsideClick}"
|
|
47
|
+
@opened-changed="${this.handleOpenedChanged}"
|
|
48
|
+
entry-animation="slide-from-right-animation"
|
|
49
|
+
exit-animation="slide-right-animation"
|
|
50
|
+
with-backdrop
|
|
51
|
+
>
|
|
52
|
+
<slot></slot>
|
|
53
|
+
</paper-dialog>
|
|
54
|
+
`;
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
ExmgDrawer.styles = [style];
|
|
58
|
+
__decorate([
|
|
59
|
+
property({ type: Boolean })
|
|
60
|
+
], ExmgDrawer.prototype, "opened", void 0);
|
|
61
|
+
__decorate([
|
|
62
|
+
property({ type: Boolean, attribute: 'no-cancel-on-outside-click' })
|
|
63
|
+
], ExmgDrawer.prototype, "noCancelOnOutsideClick", void 0);
|
|
64
|
+
__decorate([
|
|
65
|
+
property({ type: String, attribute: 'scroll-action' })
|
|
66
|
+
], ExmgDrawer.prototype, "scrollAction", void 0);
|
|
67
|
+
ExmgDrawer = __decorate([
|
|
68
|
+
customElement('exm-drawer')
|
|
69
|
+
], ExmgDrawer);
|
|
70
|
+
export { ExmgDrawer };
|
|
71
|
+
//# sourceMappingURL=exm-drawer.js.map
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import './exm-drawer.js';
|
|
2
|
+
import '@exmg/exm-button/exm-filled-button.js';
|
|
3
|
+
import '@material/web/button/text-button.js';
|
|
4
|
+
import { ExmgElement } from '@exmg/lit-base';
|
|
5
|
+
export declare class ExmgFormDrawerBase extends ExmgElement {
|
|
6
|
+
/**
|
|
7
|
+
* Opened state of the form-drawer
|
|
8
|
+
* @type {Boolean}
|
|
9
|
+
*/
|
|
10
|
+
opened: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* The title of the 'submit' button
|
|
13
|
+
* @type {String}
|
|
14
|
+
*/
|
|
15
|
+
submitBtnTitle: string;
|
|
16
|
+
/**
|
|
17
|
+
* Whether or not to hide the submit button
|
|
18
|
+
* @type {Boolean}
|
|
19
|
+
*/
|
|
20
|
+
submitBtnHidden: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Title of the cancel button
|
|
23
|
+
* @type {String}
|
|
24
|
+
*/
|
|
25
|
+
cancelBtnTitle: string;
|
|
26
|
+
/**
|
|
27
|
+
* Whether or not to keep the form drawer opened on submit success
|
|
28
|
+
* @type {Boolean}
|
|
29
|
+
*/
|
|
30
|
+
keepOpenedOnSubmitSuccess: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* No cancel on outside click
|
|
33
|
+
* @type {Boolean}
|
|
34
|
+
*/
|
|
35
|
+
noCancelOnOutsideClick: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Disable sticky header in drawer
|
|
38
|
+
* @type {Boolean}
|
|
39
|
+
*/
|
|
40
|
+
disableStickyHeader: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Internall used to show button spinner.
|
|
43
|
+
*/
|
|
44
|
+
submitting: boolean;
|
|
45
|
+
private formValid;
|
|
46
|
+
boundHandleBlur?: (e: Event) => void;
|
|
47
|
+
/**
|
|
48
|
+
* Scroll action of the drawer
|
|
49
|
+
* @type {'lock' | 'refit' | 'cancel' | undefined}
|
|
50
|
+
*/
|
|
51
|
+
scrollAction?: 'lock' | 'refit' | 'cancel' | undefined;
|
|
52
|
+
errorMessage?: string | null;
|
|
53
|
+
protected getForm(): HTMLFormElement | null;
|
|
54
|
+
protected _handleBlur(e: Event): void;
|
|
55
|
+
protected firstUpdated(): void;
|
|
56
|
+
disconnectedCallback(): void;
|
|
57
|
+
/**
|
|
58
|
+
* Opens and shows the drawer.
|
|
59
|
+
*/
|
|
60
|
+
show(): void;
|
|
61
|
+
/**
|
|
62
|
+
* Closes the drawer.
|
|
63
|
+
*/
|
|
64
|
+
close(): void;
|
|
65
|
+
/**
|
|
66
|
+
* Opens and shows the dialog if it is closed; otherwise closes it.
|
|
67
|
+
*/
|
|
68
|
+
toggleShow(): void;
|
|
69
|
+
protected _checkFormValidity(): Promise<void>;
|
|
70
|
+
reset(): void;
|
|
71
|
+
/**
|
|
72
|
+
* Action method that needs to be implemented
|
|
73
|
+
* @param {CustomEvent} e
|
|
74
|
+
*/
|
|
75
|
+
doAction?(formData: unknown): Promise<void> | void;
|
|
76
|
+
protected handleSubmit(): Promise<void>;
|
|
77
|
+
private handleCancelBtnClick;
|
|
78
|
+
showError(message: string): void;
|
|
79
|
+
/**
|
|
80
|
+
* Method should be overriden to render form content
|
|
81
|
+
*/
|
|
82
|
+
protected renderFormContent(): import("lit-html").TemplateResult<1>;
|
|
83
|
+
protected renderError(): import("lit-html").TemplateResult<1>;
|
|
84
|
+
protected render(): import("lit-html").TemplateResult<1>;
|
|
85
|
+
}
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { html, nothing } from 'lit';
|
|
3
|
+
import { property, state } from 'lit/decorators.js';
|
|
4
|
+
import { ifDefined } from 'lit/directives/if-defined.js';
|
|
5
|
+
import './exm-drawer.js';
|
|
6
|
+
import '@exmg/exm-button/exm-filled-button.js';
|
|
7
|
+
import '@material/web/button/text-button.js';
|
|
8
|
+
import { ExmgElement } from '@exmg/lit-base';
|
|
9
|
+
import { serializeForm } from '@exmg/exm-form';
|
|
10
|
+
export class ExmgFormDrawerBase extends ExmgElement {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
13
|
+
/**
|
|
14
|
+
* Opened state of the form-drawer
|
|
15
|
+
* @type {Boolean}
|
|
16
|
+
*/
|
|
17
|
+
this.opened = false;
|
|
18
|
+
/**
|
|
19
|
+
* The title of the 'submit' button
|
|
20
|
+
* @type {String}
|
|
21
|
+
*/
|
|
22
|
+
this.submitBtnTitle = 'Submit';
|
|
23
|
+
/**
|
|
24
|
+
* Whether or not to hide the submit button
|
|
25
|
+
* @type {Boolean}
|
|
26
|
+
*/
|
|
27
|
+
this.submitBtnHidden = false;
|
|
28
|
+
/**
|
|
29
|
+
* Title of the cancel button
|
|
30
|
+
* @type {String}
|
|
31
|
+
*/
|
|
32
|
+
this.cancelBtnTitle = 'Cancel';
|
|
33
|
+
/**
|
|
34
|
+
* Whether or not to keep the form drawer opened on submit success
|
|
35
|
+
* @type {Boolean}
|
|
36
|
+
*/
|
|
37
|
+
this.keepOpenedOnSubmitSuccess = false;
|
|
38
|
+
/**
|
|
39
|
+
* No cancel on outside click
|
|
40
|
+
* @type {Boolean}
|
|
41
|
+
*/
|
|
42
|
+
this.noCancelOnOutsideClick = false;
|
|
43
|
+
/**
|
|
44
|
+
* Disable sticky header in drawer
|
|
45
|
+
* @type {Boolean}
|
|
46
|
+
*/
|
|
47
|
+
this.disableStickyHeader = false;
|
|
48
|
+
/**
|
|
49
|
+
* Internall used to show button spinner.
|
|
50
|
+
*/
|
|
51
|
+
this.submitting = false;
|
|
52
|
+
this.formValid = false;
|
|
53
|
+
}
|
|
54
|
+
getForm() {
|
|
55
|
+
return this.shadowRoot.querySelector('form');
|
|
56
|
+
}
|
|
57
|
+
_handleBlur(e) {
|
|
58
|
+
// @ts-ignore
|
|
59
|
+
typeof e.target.reportValidity === 'function' && e.target.reportValidity();
|
|
60
|
+
this._checkFormValidity();
|
|
61
|
+
}
|
|
62
|
+
firstUpdated() {
|
|
63
|
+
const form = this.getForm();
|
|
64
|
+
this.boundHandleBlur = this._handleBlur.bind(this);
|
|
65
|
+
form.addEventListener('blur', this.boundHandleBlur, true);
|
|
66
|
+
}
|
|
67
|
+
disconnectedCallback() {
|
|
68
|
+
const form = this.getForm();
|
|
69
|
+
this.boundHandleBlur && form.addEventListener('blur', this.boundHandleBlur, true);
|
|
70
|
+
super.disconnectedCallback();
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Opens and shows the drawer.
|
|
74
|
+
*/
|
|
75
|
+
show() {
|
|
76
|
+
this.opened = true;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Closes the drawer.
|
|
80
|
+
*/
|
|
81
|
+
close() {
|
|
82
|
+
this.opened = false;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Opens and shows the dialog if it is closed; otherwise closes it.
|
|
86
|
+
*/
|
|
87
|
+
toggleShow() {
|
|
88
|
+
if (this.opened) {
|
|
89
|
+
this.close();
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
this.show();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async _checkFormValidity() {
|
|
96
|
+
await this.updateComplete;
|
|
97
|
+
const form = this.getForm();
|
|
98
|
+
const formElements = form === null || form === void 0 ? void 0 : form.elements;
|
|
99
|
+
let allValid = true;
|
|
100
|
+
for (const el of formElements || []) {
|
|
101
|
+
// @ts-ignore
|
|
102
|
+
const isValid = typeof el.reportValidity === 'function' && el.checkValidity();
|
|
103
|
+
if (!isValid) {
|
|
104
|
+
allValid = false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
this.formValid = allValid;
|
|
108
|
+
}
|
|
109
|
+
reset() {
|
|
110
|
+
this.errorMessage = null;
|
|
111
|
+
const form = this.getForm();
|
|
112
|
+
form.reset();
|
|
113
|
+
}
|
|
114
|
+
async handleSubmit() {
|
|
115
|
+
const form = this.getForm();
|
|
116
|
+
// Return when there are invalid fields
|
|
117
|
+
if (!this.formValid) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
// Serialize form data
|
|
121
|
+
const data = serializeForm(form);
|
|
122
|
+
if (this.doAction) {
|
|
123
|
+
try {
|
|
124
|
+
this.submitting = true;
|
|
125
|
+
await this.doAction(data);
|
|
126
|
+
this.fire('action-success');
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
this.errorMessage = error instanceof Error ? error.message : 'Unkbnown error';
|
|
130
|
+
this.fire('action-error', { message: this.errorMessage }, true);
|
|
131
|
+
}
|
|
132
|
+
finally {
|
|
133
|
+
this.submitting = false;
|
|
134
|
+
if (!this.keepOpenedOnSubmitSuccess) {
|
|
135
|
+
this.opened = false;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
this.fire('action-submit', data, true);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
handleCancelBtnClick() {
|
|
144
|
+
this.reset();
|
|
145
|
+
this.close();
|
|
146
|
+
}
|
|
147
|
+
showError(message) {
|
|
148
|
+
this.errorMessage = message;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Method should be overriden to render form content
|
|
152
|
+
*/
|
|
153
|
+
renderFormContent() {
|
|
154
|
+
return html `<slot></slot>`;
|
|
155
|
+
}
|
|
156
|
+
renderError() {
|
|
157
|
+
return html `<div class="error"><div>${this.errorMessage}</div></div>`;
|
|
158
|
+
}
|
|
159
|
+
render() {
|
|
160
|
+
return html `
|
|
161
|
+
<exm-drawer
|
|
162
|
+
?opened="${this.opened}"
|
|
163
|
+
?no-cancel-on-outside-click="${this.noCancelOnOutsideClick}"
|
|
164
|
+
scroll-action=${ifDefined(this.scrollAction)}
|
|
165
|
+
style="max-width: ${this.style.maxWidth || '547px'}"
|
|
166
|
+
>
|
|
167
|
+
<div class="header">
|
|
168
|
+
<slot name="title" class="title">${this.title}</slot>
|
|
169
|
+
<div class="header-buttons">
|
|
170
|
+
<md-text-button slot="footer" dialogFocus @click=${() => this.handleCancelBtnClick()}
|
|
171
|
+
>${this.cancelBtnTitle}</md-text-button
|
|
172
|
+
>
|
|
173
|
+
${this.submitBtnHidden
|
|
174
|
+
? ''
|
|
175
|
+
: html ` <exm-filled-button
|
|
176
|
+
slot="footer"
|
|
177
|
+
@click=${this.handleSubmit}
|
|
178
|
+
?disabled=${this.submitting || !this.formValid}
|
|
179
|
+
?loading=${this.submitting}
|
|
180
|
+
>${this.submitBtnTitle}</exm-filled-button
|
|
181
|
+
>`}
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
${this.errorMessage ? this.renderError() : nothing}
|
|
185
|
+
<div class="form-elements">${this.renderFormContent()}</div>
|
|
186
|
+
</exm-drawer>
|
|
187
|
+
`;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
__decorate([
|
|
191
|
+
property({ type: Boolean })
|
|
192
|
+
], ExmgFormDrawerBase.prototype, "opened", void 0);
|
|
193
|
+
__decorate([
|
|
194
|
+
property({ type: String, attribute: 'submit-btn-title' })
|
|
195
|
+
], ExmgFormDrawerBase.prototype, "submitBtnTitle", void 0);
|
|
196
|
+
__decorate([
|
|
197
|
+
property({ type: Boolean, attribute: 'submit-btn-hidden' })
|
|
198
|
+
], ExmgFormDrawerBase.prototype, "submitBtnHidden", void 0);
|
|
199
|
+
__decorate([
|
|
200
|
+
property({ type: String, attribute: 'cancel-btn-title' })
|
|
201
|
+
], ExmgFormDrawerBase.prototype, "cancelBtnTitle", void 0);
|
|
202
|
+
__decorate([
|
|
203
|
+
property({ type: Boolean, attribute: 'keep-opened-on-submit-success' })
|
|
204
|
+
], ExmgFormDrawerBase.prototype, "keepOpenedOnSubmitSuccess", void 0);
|
|
205
|
+
__decorate([
|
|
206
|
+
property({ type: Boolean, attribute: 'no-cancel-on-outside-click' })
|
|
207
|
+
], ExmgFormDrawerBase.prototype, "noCancelOnOutsideClick", void 0);
|
|
208
|
+
__decorate([
|
|
209
|
+
property({ type: Boolean, attribute: 'disable-sticky-header' })
|
|
210
|
+
], ExmgFormDrawerBase.prototype, "disableStickyHeader", void 0);
|
|
211
|
+
__decorate([
|
|
212
|
+
property({ type: Boolean })
|
|
213
|
+
], ExmgFormDrawerBase.prototype, "submitting", void 0);
|
|
214
|
+
__decorate([
|
|
215
|
+
state()
|
|
216
|
+
], ExmgFormDrawerBase.prototype, "formValid", void 0);
|
|
217
|
+
__decorate([
|
|
218
|
+
property({ type: String, attribute: 'scroll-action' })
|
|
219
|
+
], ExmgFormDrawerBase.prototype, "scrollAction", void 0);
|
|
220
|
+
__decorate([
|
|
221
|
+
property({ type: String })
|
|
222
|
+
], ExmgFormDrawerBase.prototype, "errorMessage", void 0);
|
|
223
|
+
//# sourceMappingURL=exm-form-drawer-base.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { ExmgFormDrawerBase } from './exm-form-drawer-base.js';
|
|
2
|
+
export declare class ExmgFormDrawer extends ExmgFormDrawerBase {
|
|
3
|
+
static styles: import("lit").CSSResult[];
|
|
4
|
+
getForm(): HTMLFormElement | null;
|
|
5
|
+
}
|
|
6
|
+
declare global {
|
|
7
|
+
interface HTMLElementTagNameMap {
|
|
8
|
+
'exm-form-drawer': ExmgFormDrawer;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { customElement } from 'lit/decorators.js';
|
|
3
|
+
import { style } from './styles/exm-form-drawer-styles-css.js';
|
|
4
|
+
import { ExmgFormDrawerBase } from './exm-form-drawer-base.js';
|
|
5
|
+
import { exmgFormStyles } from '@exmg/exm-form';
|
|
6
|
+
let ExmgFormDrawer = class ExmgFormDrawer extends ExmgFormDrawerBase {
|
|
7
|
+
getForm() {
|
|
8
|
+
return this.querySelector('form');
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
ExmgFormDrawer.styles = [style, exmgFormStyles];
|
|
12
|
+
ExmgFormDrawer = __decorate([
|
|
13
|
+
customElement('exm-form-drawer')
|
|
14
|
+
], ExmgFormDrawer);
|
|
15
|
+
export { ExmgFormDrawer };
|
|
16
|
+
//# sourceMappingURL=exm-form-drawer.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const style = css `paper-dialog{margin:0;padding:0;position:fixed;top:0;right:0;bottom:0;width:100%;box-shadow:none;overflow:scroll;color:var(--exm-drawer-color, var(--md-sys-color-on-surface, black));background-color:var(--exm-drawer-bg-color, var(--md-sys-color-surface-variant, white))}`;
|
|
3
|
+
export default style;
|
|
4
|
+
//# sourceMappingURL=exm-drawer-styles-css.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
paper-dialog {
|
|
2
|
+
margin: 0;
|
|
3
|
+
padding: 0;
|
|
4
|
+
position: fixed;
|
|
5
|
+
top: 0;
|
|
6
|
+
right: 0;
|
|
7
|
+
bottom: 0;
|
|
8
|
+
width: 100%;
|
|
9
|
+
box-shadow: none;
|
|
10
|
+
overflow: scroll;
|
|
11
|
+
|
|
12
|
+
color: var(--exm-drawer-color, var(--md-sys-color-on-surface, black));
|
|
13
|
+
// background-color: var(--exm-drawer-bg-color, var(--mdc-theme-surface, $exm-drawer-bg-color));
|
|
14
|
+
background-color: var(--exm-drawer-bg-color, var(--md-sys-color-surface-variant, white));
|
|
15
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const style = css `:host{display:flex}:host .header{display:flex;flex-direction:row;align-items:center;margin:0;padding:20px;border-bottom:1px solid var(--exm-form-drawer-header-separator-color, var(--mdc-theme-on-surface, rgba(2, 24, 43, 0.1)))}:host .header .title{font-size:1.4rem}:host .form-elements{padding:0 0px}.header-buttons{display:flex;flex-direction:row;flex:1;justify-content:flex-end}.header-buttons>*{margin-left:20px}:host(:not([disable-sticky-header])) .header{position:sticky;top:0;background-color:var(--exm-drawer-bg-color, var(--md-sys-color-surface-variant, white));z-index:2}form{margin:0 !important;padding:.5rem 1rem;box-sizing:border-box}`;
|
|
3
|
+
export default style;
|
|
4
|
+
//# sourceMappingURL=exm-form-drawer-styles-css.js.map
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
:host {
|
|
2
|
+
display: flex;
|
|
3
|
+
|
|
4
|
+
.header {
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: row;
|
|
7
|
+
align-items: center;
|
|
8
|
+
|
|
9
|
+
margin: 0;
|
|
10
|
+
padding: 20px;
|
|
11
|
+
border-bottom: 1px solid
|
|
12
|
+
var(--exm-form-drawer-header-separator-color, var(--mdc-theme-on-surface, rgba(#02182b, 0.1)));
|
|
13
|
+
|
|
14
|
+
.title {
|
|
15
|
+
font-size: 1.4rem;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.form-elements {
|
|
20
|
+
padding: 0 0px;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.header-buttons {
|
|
25
|
+
display: flex;
|
|
26
|
+
flex-direction: row;
|
|
27
|
+
flex: 1;
|
|
28
|
+
justify-content: flex-end;
|
|
29
|
+
|
|
30
|
+
> * {
|
|
31
|
+
margin-left: 20px;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
:host(:not([disable-sticky-header])) .header {
|
|
36
|
+
position: sticky;
|
|
37
|
+
top: 0;
|
|
38
|
+
background-color: var(--exm-drawer-bg-color, var(--md-sys-color-surface-variant, white));
|
|
39
|
+
z-index: 2;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
form {
|
|
43
|
+
margin: 0 !important;
|
|
44
|
+
padding: 0.5rem 1rem;
|
|
45
|
+
box-sizing: border-box;
|
|
46
|
+
}
|