@exmg/exm-form-drawer 0.0.2-alpha.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 ADDED
@@ -0,0 +1,131 @@
1
+ # `<exm-form-drawer>` [![Published on npm](https://img.shields.io/npm/v/@exmg/exm-form-drawer.svg)](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/ExmFormDrawer.html)
130
+
131
+ - [Demo](https://exmg.github.io/exmachina-web-components/demo/?el=exm-form-drawer)
@@ -0,0 +1,80 @@
1
+ import '@exmg/exm-drawer/exm-drawer.js';
2
+ import '@material/web/button/text-button.js';
3
+ import { ExmgElement } from '@exmg/lit-base';
4
+ declare const ExmFormDrawerBase_base: import("@exmg/exm-form").Constructor<import("@exmg/exm-form/dist/exm-form-validate-mixin.js").FormValidateMixinInterface> & typeof ExmgElement;
5
+ export declare class ExmFormDrawerBase extends ExmFormDrawerBase_base {
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
+ /**
46
+ * Scroll action of the drawer
47
+ * @type {'lock' | 'refit' | 'cancel' | undefined}
48
+ */
49
+ scrollAction?: 'lock' | 'refit' | 'cancel' | undefined;
50
+ errorMessage?: string | null;
51
+ /**
52
+ * Opens and shows the drawer.
53
+ */
54
+ show(): void;
55
+ /**
56
+ * Closes the drawer.
57
+ */
58
+ close(): void;
59
+ /**
60
+ * Opens and shows the dialog if it is closed; otherwise closes it.
61
+ */
62
+ toggleShow(): void;
63
+ reset(): void;
64
+ /**
65
+ * Action method that needs to be implemented
66
+ * @param {CustomEvent} e
67
+ */
68
+ doAction?(formData: unknown): Promise<void> | void;
69
+ protected handleSubmit(): Promise<void>;
70
+ private handleCancelBtnClick;
71
+ showError(message: string): void;
72
+ /**
73
+ * Method should be overriden to render form content
74
+ */
75
+ protected renderFormContent(): import("lit-html").TemplateResult<1>;
76
+ protected renderError(): import("lit-html").TemplateResult<1>;
77
+ protected handleDrawerOpenedChanged(e: CustomEvent): void;
78
+ protected render(): import("lit-html").TemplateResult<1>;
79
+ }
80
+ export {};
@@ -0,0 +1,197 @@
1
+ import { __decorate } from "tslib";
2
+ import { html, nothing } from 'lit';
3
+ import { property } from 'lit/decorators.js';
4
+ import { ifDefined } from 'lit/directives/if-defined.js';
5
+ import '@exmg/exm-drawer/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, ExmFormValidateMixin } from '@exmg/exm-form';
10
+ export class ExmFormDrawerBase extends ExmFormValidateMixin(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
+ }
53
+ /**
54
+ * Opens and shows the drawer.
55
+ */
56
+ show() {
57
+ this.opened = true;
58
+ }
59
+ /**
60
+ * Closes the drawer.
61
+ */
62
+ close() {
63
+ this.opened = false;
64
+ }
65
+ /**
66
+ * Opens and shows the dialog if it is closed; otherwise closes it.
67
+ */
68
+ toggleShow() {
69
+ if (this.opened) {
70
+ this.close();
71
+ }
72
+ else {
73
+ this.show();
74
+ }
75
+ }
76
+ reset() {
77
+ this.errorMessage = null;
78
+ const form = this.getForm();
79
+ form.reset();
80
+ }
81
+ async handleSubmit() {
82
+ const form = this.getForm();
83
+ this.errorMessage = null;
84
+ // Check form validity
85
+ this.checkFormValidity();
86
+ // Return when there are invalid fields
87
+ if (!this.formValid) {
88
+ return;
89
+ }
90
+ // Serialize form data
91
+ const data = serializeForm(form);
92
+ if (this.doAction) {
93
+ try {
94
+ this.submitting = true;
95
+ await this.doAction(data);
96
+ this.fire('action-success');
97
+ }
98
+ catch (error) {
99
+ this.errorMessage = error instanceof Error ? error.message : 'Unkbnown error';
100
+ this.fire('action-error', { message: this.errorMessage }, true);
101
+ }
102
+ finally {
103
+ this.submitting = false;
104
+ if (this.errorMessage === null && !this.keepOpenedOnSubmitSuccess) {
105
+ this.opened = false;
106
+ }
107
+ }
108
+ }
109
+ else {
110
+ this.fire('action-submit', data, true);
111
+ }
112
+ }
113
+ handleCancelBtnClick() {
114
+ this.reset();
115
+ this.close();
116
+ }
117
+ showError(message) {
118
+ this.errorMessage = message;
119
+ }
120
+ /**
121
+ * Method should be overriden to render form content
122
+ */
123
+ renderFormContent() {
124
+ return html `<slot></slot>`;
125
+ }
126
+ renderError() {
127
+ return html `<div class="error"><div>${this.errorMessage}</div></div>`;
128
+ }
129
+ handleDrawerOpenedChanged(e) {
130
+ this.opened = e.detail.value;
131
+ if (this.opened) {
132
+ this.checkFormValidity();
133
+ }
134
+ }
135
+ render() {
136
+ return html `
137
+ <exm-drawer
138
+ ?opened="${this.opened}"
139
+ ?no-cancel-on-outside-click="${this.noCancelOnOutsideClick}"
140
+ @exm-drawer-opened-changed=${this.handleDrawerOpenedChanged}
141
+ scroll-action=${ifDefined(this.scrollAction)}
142
+ maxWidth="${this.style.maxWidth || '547px'}"
143
+ >
144
+ <div class="header">
145
+ <slot name="title" class="title">${this.title}</slot>
146
+ <div class="header-buttons">
147
+ <md-text-button slot="footer" dialogFocus @click=${() => this.handleCancelBtnClick()}
148
+ >${this.cancelBtnTitle}</md-text-button
149
+ >
150
+ ${this.submitBtnHidden
151
+ ? ''
152
+ : html ` <exm-filled-button
153
+ slot="footer"
154
+ @click=${this.handleSubmit}
155
+ ?disabled=${this.submitting || !this.formValid}
156
+ ?loading=${this.submitting}
157
+ >${this.submitBtnTitle}</exm-filled-button
158
+ >`}
159
+ </div>
160
+ </div>
161
+ ${this.errorMessage ? this.renderError() : nothing}
162
+ <div class="form-elements">${this.renderFormContent()}</div>
163
+ </exm-drawer>
164
+ `;
165
+ }
166
+ }
167
+ __decorate([
168
+ property({ type: Boolean })
169
+ ], ExmFormDrawerBase.prototype, "opened", void 0);
170
+ __decorate([
171
+ property({ type: String, attribute: 'submit-btn-title' })
172
+ ], ExmFormDrawerBase.prototype, "submitBtnTitle", void 0);
173
+ __decorate([
174
+ property({ type: Boolean, attribute: 'submit-btn-hidden' })
175
+ ], ExmFormDrawerBase.prototype, "submitBtnHidden", void 0);
176
+ __decorate([
177
+ property({ type: String, attribute: 'cancel-btn-title' })
178
+ ], ExmFormDrawerBase.prototype, "cancelBtnTitle", void 0);
179
+ __decorate([
180
+ property({ type: Boolean, attribute: 'keep-opened-on-submit-success' })
181
+ ], ExmFormDrawerBase.prototype, "keepOpenedOnSubmitSuccess", void 0);
182
+ __decorate([
183
+ property({ type: Boolean, attribute: 'no-cancel-on-outside-click' })
184
+ ], ExmFormDrawerBase.prototype, "noCancelOnOutsideClick", void 0);
185
+ __decorate([
186
+ property({ type: Boolean, attribute: 'disable-sticky-header' })
187
+ ], ExmFormDrawerBase.prototype, "disableStickyHeader", void 0);
188
+ __decorate([
189
+ property({ type: Boolean })
190
+ ], ExmFormDrawerBase.prototype, "submitting", void 0);
191
+ __decorate([
192
+ property({ type: String, attribute: 'scroll-action' })
193
+ ], ExmFormDrawerBase.prototype, "scrollAction", void 0);
194
+ __decorate([
195
+ property({ type: String })
196
+ ], ExmFormDrawerBase.prototype, "errorMessage", void 0);
197
+ //# sourceMappingURL=exm-form-drawer-base.js.map
@@ -0,0 +1,10 @@
1
+ import { ExmFormDrawerBase } from './exm-form-drawer-base.js';
2
+ export declare class ExmFormDrawer extends ExmFormDrawerBase {
3
+ static styles: import("lit").CSSResult[];
4
+ getForm(): HTMLFormElement | null;
5
+ }
6
+ declare global {
7
+ interface HTMLElementTagNameMap {
8
+ 'exm-form-drawer': ExmFormDrawer;
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 { ExmFormDrawerBase } from './exm-form-drawer-base.js';
5
+ import { formStyles } from '@exmg/exm-form';
6
+ let ExmFormDrawer = class ExmFormDrawer extends ExmFormDrawerBase {
7
+ getForm() {
8
+ return this.querySelector('form');
9
+ }
10
+ };
11
+ ExmFormDrawer.styles = [style, formStyles];
12
+ ExmFormDrawer = __decorate([
13
+ customElement('exm-form-drawer')
14
+ ], ExmFormDrawer);
15
+ export { ExmFormDrawer };
16
+ //# sourceMappingURL=exm-form-drawer.js.map
@@ -0,0 +1,3 @@
1
+ export { ExmFormDrawer } from './exm-form-drawer.js';
2
+ export { ExmFormDrawerBase } from './exm-form-drawer-base.js';
3
+ export { style as formDrawerStyles } from './styles/exm-form-drawer-styles-css.js';
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export { ExmFormDrawer } from './exm-form-drawer.js';
2
+ export { ExmFormDrawerBase } from './exm-form-drawer-base.js';
3
+ export { style as formDrawerStyles } from './styles/exm-form-drawer-styles-css.js';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ export declare const style: import("lit").CSSResult;
@@ -0,0 +1,60 @@
1
+ import { css } from 'lit';
2
+ export const style = css `
3
+ :host {
4
+ display: flex;
5
+ }
6
+
7
+ :host .header {
8
+ display: flex;
9
+ flex-direction: row;
10
+ align-items: center;
11
+ margin: 0;
12
+ padding: 20px;
13
+ border-bottom: 1px solid
14
+ var(--exm-form-drawer-header-separator-color, var(--mdc-theme-on-surface, rgba(2, 24, 43, 0.1)));
15
+ }
16
+
17
+ :host .header .title {
18
+ font-size: 1.4rem;
19
+ }
20
+
21
+ :host .form-elements {
22
+ padding: 0 0px;
23
+ }
24
+
25
+ .header-buttons {
26
+ display: flex;
27
+ flex-direction: row;
28
+ flex: 1;
29
+ justify-content: flex-end;
30
+ }
31
+
32
+ .header-buttons > * {
33
+ margin-left: 20px;
34
+ }
35
+
36
+ :host(:not([disable-sticky-header])) .header {
37
+ position: sticky;
38
+ top: 0;
39
+ color: var(--exm-drawer-color, var(--md-sys-color-on-surface-variant, black));
40
+ background-color: var(--exm-drawer-bg-color, var(--md-sys-color-surface-variant, white));
41
+ z-index: 2;
42
+ }
43
+
44
+ form {
45
+ margin: 1rem 0 !important;
46
+ padding: 0.5rem 1rem;
47
+ box-sizing: border-box;
48
+ }
49
+
50
+ .error {
51
+ background-color: var(--md-sys-color-error-container);
52
+ color: var(--md-sys-color-on-error-container);
53
+ padding: 0.5rem;
54
+ }
55
+
56
+ .error > * {
57
+ margin: 1rem;
58
+ }
59
+ `;
60
+ //# sourceMappingURL=exm-form-drawer-styles-css.js.map
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@exmg/exm-form-drawer",
3
+ "version": "0.0.2-alpha.0+df24e0c",
4
+ "type": "module",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "module": "dist/index.js",
8
+ "exports": {
9
+ ".": "./dist/index.js",
10
+ "./exm-form-drawer.js": "./dist/exm-form-drawer.js",
11
+ "./exm-drawer.js": "./dist/exm-drawer.js"
12
+ },
13
+ "description": "Form side drawer element",
14
+ "contributors": [
15
+ "Ex Machina"
16
+ ],
17
+ "keywords": [
18
+ "web-components",
19
+ "lit",
20
+ "form"
21
+ ],
22
+ "files": [
23
+ "**/*.scss",
24
+ "**/*.js",
25
+ "**/*.d.ts"
26
+ ],
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "git@bitbucket.org:exmachina/exm-web-components.git",
30
+ "directory": "packages/exm-form-drawer"
31
+ },
32
+ "license": "MIT",
33
+ "dependencies": {
34
+ "@exmg/exm-drawer": "^0.0.2-alpha.0+df24e0c",
35
+ "@exmg/exm-form": "^0.0.2-alpha.0+df24e0c"
36
+ },
37
+ "peerDependencies": {
38
+ "lit": "^3.2.1",
39
+ "tslib": "^2.6.2"
40
+ },
41
+ "scripts": {},
42
+ "publishConfig": {
43
+ "access": "public"
44
+ },
45
+ "gitHead": "df24e0c74a76a7e1c258f69386036e24e7860256"
46
+ }