@exmg/exm-form 1.1.9 → 1.1.10-alpha.26

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.
Files changed (30) hide show
  1. package/.rollup.cache/root/repo/packages/exm-form/dist/exm-form-base.d.ts +56 -0
  2. package/.rollup.cache/root/repo/packages/exm-form/dist/exm-form-base.js +190 -0
  3. package/.rollup.cache/root/repo/packages/exm-form/dist/exm-form-dirty-mixin.d.ts +10 -0
  4. package/.rollup.cache/root/repo/packages/exm-form/dist/exm-form-dirty-mixin.js +92 -0
  5. package/.rollup.cache/root/repo/packages/exm-form/dist/exm-form-validate-mixin.d.ts +10 -0
  6. package/.rollup.cache/root/repo/packages/exm-form/dist/exm-form-validate-mixin.js +66 -0
  7. package/.rollup.cache/root/repo/packages/exm-form/dist/exm-form.d.ts +10 -0
  8. package/.rollup.cache/root/repo/packages/exm-form/dist/exm-form.js +15 -0
  9. package/.rollup.cache/root/repo/packages/exm-form/dist/index.d.ts +6 -0
  10. package/.rollup.cache/root/repo/packages/exm-form/dist/index.js +7 -0
  11. package/.rollup.cache/root/repo/packages/exm-form/dist/styles/exm-form-base-css.d.ts +1 -0
  12. package/.rollup.cache/root/repo/packages/exm-form/dist/styles/exm-form-base-css.js +91 -0
  13. package/.rollup.cache/root/repo/packages/exm-form/dist/styles/exm-form-css.d.ts +1 -0
  14. package/.rollup.cache/root/repo/packages/exm-form/dist/styles/exm-form-css.js +59 -0
  15. package/.rollup.cache/root/repo/packages/exm-form/dist/utils/serializeFormData.d.ts +1 -0
  16. package/.rollup.cache/root/repo/packages/exm-form/dist/utils/serializeFormData.js +64 -0
  17. package/dist/exm-form-base.d.ts +22 -9
  18. package/dist/exm-form-base.js +103 -104
  19. package/dist/exm-form-dirty-mixin.d.ts +10 -0
  20. package/dist/exm-form-dirty-mixin.js +93 -0
  21. package/dist/exm-form-validate-mixin.d.ts +1 -1
  22. package/dist/exm-form-validate-mixin.js +18 -11
  23. package/dist/exm-form.js +4 -2
  24. package/dist/index.d.ts +2 -1
  25. package/dist/index.js +3 -2
  26. package/dist/styles/exm-form-base-css.js +53 -40
  27. package/dist/styles/exm-form-css.js +13 -64
  28. package/dist/utils/serializeFormData.d.ts +1 -0
  29. package/dist/utils/serializeFormData.js +66 -0
  30. package/package.json +6 -8
@@ -0,0 +1,56 @@
1
+ import '@exmg/exm-button/exm-text-button.js';
2
+ import '@material/web/button/outlined-button.js';
3
+ import '@material/web/button/filled-button.js';
4
+ import '@material/web/divider/divider.js';
5
+ import { ExmgElement } from '@exmg/lit-base';
6
+ declare const ExmFormBase_base: import("./exm-form-dirty-mixin.js").Constructor<import("./exm-form-dirty-mixin.js").FormDirtyMixinInterface> & import("./exm-form-validate-mixin.js").Constructor<import("./exm-form-validate-mixin.js").FormValidateMixinInterface> & typeof ExmgElement;
7
+ export declare class ExmFormBase extends ExmFormBase_base {
8
+ /**
9
+ * Submit button copy
10
+ */
11
+ submitBtn: string;
12
+ /**
13
+ * Cancel button copy
14
+ */
15
+ cancelBtn: string;
16
+ /**
17
+ * Hide cancel button
18
+ */
19
+ hideCancelButton: boolean;
20
+ /**
21
+ * Show reset button
22
+ */
23
+ showResetButton: boolean;
24
+ /**
25
+ * Disabled the submit,
26
+ */
27
+ disableSubmitButton?: boolean;
28
+ /**
29
+ * Internall used to show button spinner.
30
+ */
31
+ submitting: boolean;
32
+ boundHandleBlur?: (e: Event) => void;
33
+ boundHandleKeyup?: (e: Event) => void;
34
+ hasDescription: boolean;
35
+ hasHeader: boolean;
36
+ errorMessage?: string | null;
37
+ reset(): void;
38
+ submit(): void;
39
+ /**
40
+ * Action method that needs to be implemented
41
+ * @param {CustomEvent} e
42
+ */
43
+ doAction?(formData: unknown): Promise<void> | void;
44
+ protected handleSubmit(): Promise<void>;
45
+ showError(message: string): void;
46
+ slotHasContent(slot: HTMLSlotElement): boolean;
47
+ handleDescriptionSlotChange(event: CustomEvent): void;
48
+ handleHeaderSlotChange(event: CustomEvent): void;
49
+ protected renderToolbar(): import("lit-html").TemplateResult<1>;
50
+ renderFormContent(): import("lit-html").TemplateResult<1>;
51
+ protected renderDescription(): import("lit-html").TemplateResult<1>;
52
+ protected renderError(): import("lit-html").TemplateResult<1>;
53
+ protected renderActions(): import("lit-html").TemplateResult<1>;
54
+ protected render(): import("lit-html").TemplateResult<1>;
55
+ }
56
+ export {};
@@ -0,0 +1,190 @@
1
+ import { __decorate } from "tslib";
2
+ import { html, nothing } from 'lit';
3
+ import { property, state } from 'lit/decorators.js';
4
+ import '@exmg/exm-button/exm-text-button.js';
5
+ import '@material/web/button/outlined-button.js';
6
+ import '@material/web/button/filled-button.js';
7
+ import '@material/web/divider/divider.js';
8
+ import { ExmgElement } from '@exmg/lit-base';
9
+ import { classMap } from 'lit/directives/class-map.js';
10
+ import { ExmFormValidateMixin } from './exm-form-validate-mixin.js';
11
+ import { serializeFormData } from './utils/serializeFormData.js';
12
+ import { ExmFormDirtyMixin } from './exm-form-dirty-mixin.js';
13
+ export class ExmFormBase extends ExmFormDirtyMixin(ExmFormValidateMixin(ExmgElement)) {
14
+ constructor() {
15
+ super(...arguments);
16
+ /**
17
+ * Submit button copy
18
+ */
19
+ this.submitBtn = 'Save';
20
+ /**
21
+ * Cancel button copy
22
+ */
23
+ this.cancelBtn = 'Cancel';
24
+ /**
25
+ * Hide cancel button
26
+ */
27
+ this.hideCancelButton = false;
28
+ /**
29
+ * Show reset button
30
+ */
31
+ this.showResetButton = false;
32
+ /**
33
+ * Disabled the submit,
34
+ */
35
+ this.disableSubmitButton = false;
36
+ /**
37
+ * Internall used to show button spinner.
38
+ */
39
+ this.submitting = false;
40
+ this.hasDescription = false;
41
+ this.hasHeader = false;
42
+ }
43
+ reset() {
44
+ const form = this.getForm();
45
+ form === null || form === void 0 ? void 0 : form.reset();
46
+ }
47
+ submit() {
48
+ this.handleSubmit();
49
+ }
50
+ async handleSubmit() {
51
+ this.errorMessage = null;
52
+ const form = this.getForm();
53
+ // Check form validity
54
+ this.checkFormValidity();
55
+ // Return when there are invalid fields
56
+ if (!this.formValid) {
57
+ return;
58
+ }
59
+ // Serialize form data
60
+ const data = serializeFormData(form);
61
+ if (this.doAction) {
62
+ try {
63
+ this.submitting = true;
64
+ await this.doAction(data);
65
+ this.fire('form-success', null, true);
66
+ }
67
+ catch (error) {
68
+ this.showError(error instanceof Error ? error.message : 'Unknown error');
69
+ this.fire('form-error', { message: error instanceof Error ? error.message : 'Unknown error' }, true);
70
+ }
71
+ finally {
72
+ this.submitting = false;
73
+ this.fire('form-submit-finished', { success: !this.errorMessage });
74
+ }
75
+ }
76
+ else {
77
+ this.fire('form-submit', data, true);
78
+ }
79
+ }
80
+ showError(message) {
81
+ this.errorMessage = message;
82
+ }
83
+ slotHasContent(slot) {
84
+ const nodes = slot.assignedNodes({ flatten: true });
85
+ return nodes.length > 0;
86
+ }
87
+ handleDescriptionSlotChange(event) {
88
+ this.hasDescription = this.slotHasContent(event.target);
89
+ }
90
+ handleHeaderSlotChange(event) {
91
+ this.hasHeader = this.slotHasContent(event.target);
92
+ }
93
+ renderToolbar() {
94
+ return html `
95
+ <header class="toolbar-container">
96
+ <slot name="toolbar" @slotchange="${this.handleHeaderSlotChange}"></slot>
97
+ </header>
98
+ `;
99
+ }
100
+ renderFormContent() {
101
+ return html `
102
+ <section class="content">
103
+ <slot></slot>
104
+ </section>
105
+ `;
106
+ }
107
+ renderDescription() {
108
+ return html `
109
+ <section class="description">
110
+ <slot name="description" @slotchange="${this.handleDescriptionSlotChange}"></slot>
111
+ </section>
112
+ `;
113
+ }
114
+ renderError() {
115
+ return html `
116
+ <div class="form-error">
117
+ <div>${this.errorMessage}</div>
118
+ </div>
119
+ `;
120
+ }
121
+ renderActions() {
122
+ return html `
123
+ <footer class="actions">
124
+ ${this.showResetButton
125
+ ? html `
126
+ <md-icon-button ?disabled=${!this.dirty} @click=${this.reset}>
127
+ <md-icon>restart_alt</md-icon>
128
+ </md-icon-button>
129
+ `
130
+ : nothing}
131
+ ${this.hideCancelButton
132
+ ? nothing
133
+ : html `
134
+ <md-outlined-button dialogFocus @click=${() => this.fire('form-cancel')}>
135
+ ${this.cancelBtn}
136
+ </md-outlined-button>
137
+ `}
138
+ <md-filled-button
139
+ type="button"
140
+ @click=${this.handleSubmit}
141
+ ?disabled=${this.disableSubmitButton || this.submitting || !this.formValid}
142
+ ?loading=${this.submitting}
143
+ >
144
+ ${this.submitBtn}
145
+ </md-filled-button>
146
+ </footer>
147
+ `;
148
+ }
149
+ render() {
150
+ const classNames = {
151
+ 'has-description': this.hasDescription,
152
+ 'has-header': this.hasHeader,
153
+ 'has-error': !!this.errorMessage,
154
+ };
155
+ return html `
156
+ <article class="form-container ${classMap(classNames)}">
157
+ ${this.renderToolbar()} ${this.renderDescription()} ${this.errorMessage ? this.renderError() : nothing}
158
+ ${this.renderFormContent()} ${this.renderActions()}
159
+ </article>
160
+ `;
161
+ }
162
+ }
163
+ __decorate([
164
+ property({ type: String })
165
+ ], ExmFormBase.prototype, "submitBtn", void 0);
166
+ __decorate([
167
+ property({ type: String })
168
+ ], ExmFormBase.prototype, "cancelBtn", void 0);
169
+ __decorate([
170
+ property({ type: Boolean, attribute: 'hide-cancel-button' })
171
+ ], ExmFormBase.prototype, "hideCancelButton", void 0);
172
+ __decorate([
173
+ property({ type: Boolean, attribute: 'show-reset-button' })
174
+ ], ExmFormBase.prototype, "showResetButton", void 0);
175
+ __decorate([
176
+ property({ type: Boolean, attribute: 'disable-submit-button' })
177
+ ], ExmFormBase.prototype, "disableSubmitButton", void 0);
178
+ __decorate([
179
+ property({ type: Boolean })
180
+ ], ExmFormBase.prototype, "submitting", void 0);
181
+ __decorate([
182
+ state()
183
+ ], ExmFormBase.prototype, "hasDescription", void 0);
184
+ __decorate([
185
+ state()
186
+ ], ExmFormBase.prototype, "hasHeader", void 0);
187
+ __decorate([
188
+ property({ type: String })
189
+ ], ExmFormBase.prototype, "errorMessage", void 0);
190
+ //# sourceMappingURL=exm-form-base.js.map
@@ -0,0 +1,10 @@
1
+ import { LitElement } from 'lit';
2
+ export type Constructor<T> = new (...args: any[]) => T;
3
+ export declare class FormDirtyMixinClass extends LitElement {
4
+ }
5
+ export declare class FormDirtyMixinInterface {
6
+ dirty: boolean;
7
+ getForm(): HTMLFormElement | null;
8
+ takeFormDataSnapshot(): void;
9
+ }
10
+ export declare const ExmFormDirtyMixin: <T extends Constructor<LitElement & FormDirtyMixinClass>>(superClass: T) => Constructor<FormDirtyMixinInterface> & T;
@@ -0,0 +1,92 @@
1
+ import { __decorate } from "tslib";
2
+ import { LitElement } from 'lit';
3
+ import { state } from 'lit/decorators.js';
4
+ export class FormDirtyMixinClass extends LitElement {
5
+ }
6
+ export const ExmFormDirtyMixin = (superClass) => {
7
+ class FormDirtyMixinElement extends superClass {
8
+ constructor(...args) {
9
+ super(...args);
10
+ this.dirty = false;
11
+ this.onFormChanged = this.updateDirtyState.bind(this);
12
+ }
13
+ getForm() {
14
+ var _a, _b;
15
+ return (_b = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('form')) !== null && _b !== void 0 ? _b : null;
16
+ }
17
+ getCurrentFormData() {
18
+ const form = this.getForm();
19
+ if (!form)
20
+ return;
21
+ return new FormData(form);
22
+ }
23
+ // NOTE: We have to compare formdata like this... we can't do a direct comparison unfortunately
24
+ formDataEquals(formData1, formData2) {
25
+ if (!formData1 || !formData2)
26
+ return false;
27
+ return JSON.stringify([...formData1]) === JSON.stringify([...formData2]);
28
+ }
29
+ fireDirtyChanged() {
30
+ this.dispatchEvent(new CustomEvent('form-dirty-changed', {
31
+ detail: this.dirty,
32
+ bubbles: true,
33
+ composed: true,
34
+ }));
35
+ }
36
+ async updateDirtyState() {
37
+ await this.updateComplete;
38
+ const current = this.getCurrentFormData();
39
+ if (!current)
40
+ return;
41
+ if (this.formDataEquals(current, this.formDataSnapshot)) {
42
+ this.resetDirtyState();
43
+ return;
44
+ }
45
+ if (!this.dirty) {
46
+ this.dirty = true;
47
+ this.fireDirtyChanged();
48
+ }
49
+ }
50
+ resetDirtyState() {
51
+ if (this.dirty) {
52
+ this.dirty = false;
53
+ this.fireDirtyChanged();
54
+ }
55
+ }
56
+ // NOTE: Sometimes we want to make a snapshot from a form on for example drawer open instead of on firstUpdated
57
+ takeFormDataSnapshot() {
58
+ const form = this.getForm();
59
+ if (!form)
60
+ return;
61
+ this.formDataSnapshot = new FormData(form);
62
+ }
63
+ async firstUpdated() {
64
+ var _a;
65
+ // @ts-ignore
66
+ (_a = super.firstUpdated) === null || _a === void 0 ? void 0 : _a.call(this);
67
+ await this.updateComplete;
68
+ const form = this.getForm();
69
+ if (!form)
70
+ return;
71
+ this.takeFormDataSnapshot();
72
+ form.addEventListener('input', this.onFormChanged);
73
+ form.addEventListener('change', this.onFormChanged);
74
+ form.addEventListener('reset', this.onFormChanged);
75
+ }
76
+ async disconnectedCallback() {
77
+ var _a;
78
+ const form = this.getForm();
79
+ if (form) {
80
+ form.removeEventListener('input', this.onFormChanged);
81
+ form.removeEventListener('change', this.onFormChanged);
82
+ form.removeEventListener('reset', this.onFormChanged);
83
+ }
84
+ (_a = super.disconnectedCallback) === null || _a === void 0 ? void 0 : _a.call(this);
85
+ }
86
+ }
87
+ __decorate([
88
+ state()
89
+ ], FormDirtyMixinElement.prototype, "dirty", void 0);
90
+ return FormDirtyMixinElement;
91
+ };
92
+ //# sourceMappingURL=exm-form-dirty-mixin.js.map
@@ -0,0 +1,10 @@
1
+ import { LitElement } from 'lit';
2
+ export type Constructor<T> = new (...args: any[]) => T;
3
+ export declare class FormValidateMixinClass extends LitElement {
4
+ }
5
+ export declare class FormValidateMixinInterface {
6
+ formValid: boolean;
7
+ getForm(): HTMLFormElement | null;
8
+ checkFormValidity(): void;
9
+ }
10
+ export declare const ExmFormValidateMixin: <T extends Constructor<LitElement & FormValidateMixinClass>>(superClass: T) => Constructor<FormValidateMixinInterface> & T;
@@ -0,0 +1,66 @@
1
+ import { __decorate } from "tslib";
2
+ import { LitElement } from 'lit';
3
+ import { async, debounce } from '@exmg/lit-base/index.js';
4
+ import { state } from 'lit/decorators.js';
5
+ export class FormValidateMixinClass extends LitElement {
6
+ }
7
+ export const ExmFormValidateMixin = (superClass) => {
8
+ class FormvalidateMixinElement extends superClass {
9
+ constructor() {
10
+ super(...arguments);
11
+ this.formValid = false;
12
+ }
13
+ getForm() {
14
+ return this === null || this === void 0 ? void 0 : this.shadowRoot.querySelector('form');
15
+ }
16
+ checkFormValidity() {
17
+ const form = this.getForm();
18
+ if (!form) {
19
+ return;
20
+ }
21
+ const formElements = form === null || form === void 0 ? void 0 : form.elements;
22
+ let allValid = true;
23
+ for (const el of formElements || []) {
24
+ let isValid = true;
25
+ // @ts-ignore
26
+ if (typeof el.reportValidity === 'function') {
27
+ // @ts-ignore
28
+ isValid = el.checkValidity();
29
+ }
30
+ if (!isValid) {
31
+ allValid = false;
32
+ }
33
+ }
34
+ this.formValid = allValid;
35
+ }
36
+ _handleInputChange(e) {
37
+ const target = e.target;
38
+ // Only check validation every 200ms max
39
+ this.debouncer = debounce.Debouncer.debounce(this.debouncer, async.timeOut.after(200), () => {
40
+ // @ts-ignore
41
+ typeof target.reportValidity === 'function' && target.reportValidity();
42
+ this.checkFormValidity();
43
+ });
44
+ }
45
+ async firstUpdated() {
46
+ const form = this.getForm();
47
+ if (!form) {
48
+ return;
49
+ }
50
+ this.boundHandleChange = this._handleInputChange.bind(this);
51
+ form.addEventListener('keyup', this.boundHandleChange, true);
52
+ form.addEventListener('input', this.boundHandleChange, true);
53
+ }
54
+ async disconnectedCallback() {
55
+ const form = this.getForm();
56
+ this.boundHandleChange && form.addEventListener('keyup', this.boundHandleChange, true);
57
+ this.boundHandleChange && form.addEventListener('input', this.boundHandleChange, true);
58
+ super.disconnectedCallback();
59
+ }
60
+ }
61
+ __decorate([
62
+ state()
63
+ ], FormvalidateMixinElement.prototype, "formValid", void 0);
64
+ return FormvalidateMixinElement;
65
+ };
66
+ //# sourceMappingURL=exm-form-validate-mixin.js.map
@@ -0,0 +1,10 @@
1
+ import { ExmFormBase } from './exm-form-base.js';
2
+ export declare class ExmForm extends ExmFormBase {
3
+ static styles: import("lit").CSSResult[];
4
+ getForm(): HTMLFormElement | null;
5
+ }
6
+ declare global {
7
+ interface HTMLElementTagNameMap {
8
+ 'exm-form': ExmForm;
9
+ }
10
+ }
@@ -0,0 +1,15 @@
1
+ import { __decorate } from "tslib";
2
+ import { customElement } from 'lit/decorators.js';
3
+ import { style } from './styles/exm-form-base-css.js';
4
+ import { ExmFormBase } from './exm-form-base.js';
5
+ let ExmForm = class ExmForm extends ExmFormBase {
6
+ getForm() {
7
+ return this.querySelector('form');
8
+ }
9
+ };
10
+ ExmForm.styles = [style];
11
+ ExmForm = __decorate([
12
+ customElement('exm-form')
13
+ ], ExmForm);
14
+ export { ExmForm };
15
+ //# sourceMappingURL=exm-form.js.map
@@ -0,0 +1,6 @@
1
+ export { ExmForm } from './exm-form.js';
2
+ export { ExmFormValidateMixin, Constructor } from './exm-form-validate-mixin.js';
3
+ export { ExmFormBase } from './exm-form-base.js';
4
+ export { serializeFormData } from './utils/serializeFormData.js';
5
+ export { style as formStyles } from './styles/exm-form-css.js';
6
+ export { style as formBaseStyles } from './styles/exm-form-base-css.js';
@@ -0,0 +1,7 @@
1
+ export { ExmForm } from './exm-form.js';
2
+ export { ExmFormValidateMixin } from './exm-form-validate-mixin.js';
3
+ export { ExmFormBase } from './exm-form-base.js';
4
+ export { serializeFormData } from './utils/serializeFormData.js';
5
+ export { style as formStyles } from './styles/exm-form-css.js';
6
+ export { style as formBaseStyles } from './styles/exm-form-base-css.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ export declare const style: import("lit").CSSResult;
@@ -0,0 +1,91 @@
1
+ import { css } from 'lit';
2
+ export const style = css `
3
+ :host {
4
+ display: block;
5
+ --_exm-form-content-margin-left: var(--exm-form-content-margin-left, 0);
6
+ --_exm-form-container-margin-top: var(--exm-form-container-margin-top, 1rem);
7
+ --_exm-form-container-margin-bottom: var(--exm-form-container-margin-bottom, 1rem);
8
+ --_exm-form-divider-margin-top: var(--exm-form-divider-margin-top, 2rem);
9
+ --_exm-form-aside-font-size: var(--exm-form-aside-font-size, 0.875rem);
10
+ --_exm-form-aside-line-height: var(--exm-form-aside-line-height, 1.25rem);
11
+ --_exm-form-aside-letter-spacing: var(--exm-form-aside-letter-spacing, 0.0142857143em);
12
+ --_exm-form-aside-font-weight: var(--exm-form-aside-font-weight, 400);
13
+ --_exm-form-aside-margin-left: var(--exm-form-aside-margin-left, 1rem);
14
+ --_exm-form-aside-margin-right: var(--exm-form-aside-margin-right, 5rem);
15
+ --_exm-form-aside-min-width: var(--exm-form-aside-min-width, 180px);
16
+ }
17
+
18
+ .form-container {
19
+ display: grid;
20
+ grid-template-rows: auto auto auto 1fr auto;
21
+ height: 100%;
22
+ }
23
+
24
+ ::slotted(.toolbar) {
25
+ grid-area: 1/1/2/2;
26
+ display: none;
27
+ align-items: center;
28
+ padding: 0.5rem 1rem;
29
+ min-height: 3.5rem;
30
+ box-sizing: border-box;
31
+ }
32
+
33
+ ::slotted(.toolbar) .title {
34
+ line-height: 1.5rem;
35
+ font-size: 1rem;
36
+ letter-spacing: 0.00625em;
37
+ font-weight: 500;
38
+ color: var(--md-sys-color-on-surface);
39
+ box-sizing: border-box;
40
+ overflow-wrap: break-word;
41
+ }
42
+
43
+ .has-header ::slotted(.toolbar) {
44
+ display: flex;
45
+ }
46
+
47
+ .description {
48
+ grid-area: 2/1/3/2;
49
+ display: none;
50
+ padding: 0.5rem 1rem;
51
+ line-height: var(--_exm-form-aside-line-height);
52
+ font-size: var(--_exm-form-aside-font-size);
53
+ letter-spacing: var(--_exm-form-aside-letter-spacing);
54
+ font-weight: var(--_exm-form-aside-font-weight);
55
+ color: var(--_exm-form-aside-color, var(--md-sys-color-on-surface));
56
+ height: 100%;
57
+ }
58
+
59
+ .has-description .description {
60
+ display: initial;
61
+ }
62
+
63
+ .content {
64
+ grid-area: 4/1/5/2;
65
+ padding: 0.5rem 1rem;
66
+ overflow: auto;
67
+ }
68
+
69
+ .actions {
70
+ grid-area: 5/1/6/2;
71
+ display: flex;
72
+ padding: 1rem;
73
+ margin-top: 1rem;
74
+ gap: 0.5rem;
75
+ justify-content: flex-end;
76
+ border-top: 1px solid var(--md-sys-color-outline-variant);
77
+ }
78
+
79
+ .form-error {
80
+ grid-area: 3/1/4/2;
81
+ padding: 0.5rem 1rem;
82
+ }
83
+
84
+ .form-error > div {
85
+ padding: 1rem;
86
+ border-radius: 1rem;
87
+ background-color: var(--_exm-form-error-background, var(--md-sys-color-error-container, red));
88
+ color: var(--_exm-form-error-color, var(--md-sys-color-on-error-container, white));
89
+ }
90
+ `;
91
+ //# sourceMappingURL=exm-form-base-css.js.map
@@ -0,0 +1 @@
1
+ export declare const style: import("lit").CSSResult;
@@ -0,0 +1,59 @@
1
+ import { css } from 'lit';
2
+ export const style = css `
3
+ .section-title {
4
+ line-height: 1.5rem;
5
+ font-size: 1rem;
6
+ letter-spacing: 0.00625em;
7
+ font-weight: 500;
8
+ color: var(--_exm-form-title-color, var(--md-sys-color-on-surface));
9
+ padding-bottom: 8px;
10
+ }
11
+
12
+ form {
13
+ display: flex;
14
+ flex-direction: column;
15
+ gap: 0.75rem;
16
+ width: 100%;
17
+ }
18
+
19
+ form > * {
20
+ display: contents;
21
+ }
22
+
23
+ form .row {
24
+ display: flex;
25
+ gap: 0.75rem;
26
+ }
27
+
28
+ form .row > * {
29
+ flex: 1;
30
+ height: fit-content;
31
+ }
32
+
33
+ .no-flex {
34
+ display: block;
35
+ }
36
+
37
+ .extra-margin {
38
+ margin-top: 2rem;
39
+ display: block;
40
+ }
41
+
42
+ label.checkbox {
43
+ display: flex;
44
+ justify-content: flex-start;
45
+ align-items: center;
46
+ font-size: 1rem;
47
+ font-weight: 500;
48
+ margin: 0.5rem 1rem;
49
+ }
50
+
51
+ label.checkbox md-checkbox {
52
+ margin-right: 1rem;
53
+ }
54
+
55
+ a {
56
+ color: var(--md-sys-color-primary);
57
+ }
58
+ `;
59
+ //# sourceMappingURL=exm-form-css.js.map
@@ -0,0 +1 @@
1
+ export declare const serializeFormData: (form: HTMLFormElement) => {};