@aurelia-mdc-web/all 9.3.0-au2 → 9.3.1-au2
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/dist/chips/mdc-chip/mdc-chip.js.map +1 -1
- package/dist/data-table/mdc-data-table.js.map +1 -1
- package/dist/dialog/mdc-dialog-service.js.map +1 -1
- package/dist/expandable/mdc-expandable.js.map +1 -1
- package/dist/form-field/mdc-form-field.js.map +1 -1
- package/dist/list/mdc-deprecated-list/mdc-deprecated-list-item/mdc-deprecated-list-item.js.map +1 -1
- package/dist/list/mdc-list-item/mdc-list-item.js.map +1 -1
- package/dist/menu/mdc-menu.js.map +1 -1
- package/dist/segmented-button/mdc-segmented-button-segment/mdc-segmented-button-segment.js.map +1 -1
- package/dist/select/mdc-select-value-observer.js.map +1 -1
- package/dist/select/mdc-select.js.map +1 -1
- package/dist/text-field/mdc-text-field.js.map +1 -1
- package/dist/tree-view/mdc-tree-view.js.map +1 -1
- package/package.json +2 -2
- package/src/chips/mdc-chip/mdc-chip.ts +290 -290
- package/src/data-table/mdc-data-table.ts +432 -432
- package/src/dialog/mdc-dialog-service.ts +80 -80
- package/src/expandable/mdc-expandable.ts +104 -104
- package/src/form-field/mdc-form-field.ts +60 -60
- package/src/list/mdc-deprecated-list/mdc-deprecated-list-item/mdc-deprecated-list-item.ts +108 -108
- package/src/list/mdc-list-item/mdc-list-item.ts +136 -136
- package/src/menu/mdc-menu.ts +340 -340
- package/src/segmented-button/mdc-segmented-button-segment/mdc-segmented-button-segment.ts +170 -170
- package/src/select/mdc-select-value-observer.ts +346 -346
- package/src/select/mdc-select.ts +480 -480
- package/src/text-field/mdc-text-field.ts +535 -535
- package/src/tree-view/mdc-tree-view.ts +147 -147
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
import { MdcDialog } from './mdc-dialog';
|
|
2
|
-
import Aurelia, { CustomAttribute, IAurelia, resolve } from 'aurelia';
|
|
3
|
-
import { MDCDialogCloseEvent, strings } from '@material/dialog';
|
|
4
|
-
import { CustomElement } from '@aurelia/runtime-html';
|
|
5
|
-
import { Constructable } from '@aurelia/kernel';
|
|
6
|
-
import { IMdcRippleElement, MdcRipple } from '../ripple/mdc-ripple';
|
|
7
|
-
|
|
8
|
-
/** Dialog service open method options */
|
|
9
|
-
export interface IMdcDialogOptions<T extends { loading: (params: any) => any }> {
|
|
10
|
-
/** A class represeting the dialog content view model */
|
|
11
|
-
viewModel: Constructable<T>;
|
|
12
|
-
|
|
13
|
-
/** Data to pass to the view model's loading method */
|
|
14
|
-
model?: unknown;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
interface IMdcDialogBindingContext {
|
|
18
|
-
handleClosed(evt: MDCDialogCloseEvent): void;
|
|
19
|
-
handleOpened(): void;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/** Service to open MDC dialogs */
|
|
23
|
-
export class MdcDialogService {
|
|
24
|
-
constructor(private readonly au: Aurelia = resolve(IAurelia)) { }
|
|
25
|
-
|
|
26
|
-
/** Opens the dialog specified in the options */
|
|
27
|
-
async open<T extends { loading: (params: any) => any }>(options: IMdcDialogOptions<T>) {
|
|
28
|
-
let closedResolver: (action?: string | PromiseLike<string> | undefined) => void;
|
|
29
|
-
const closedPromise = new Promise<string>(r => closedResolver = r);
|
|
30
|
-
let openedResolver: (value?: unknown) => void;
|
|
31
|
-
const openedPromise = new Promise(r => openedResolver = r);
|
|
32
|
-
let opened = false;
|
|
33
|
-
const bindingContext: IMdcDialogBindingContext = {
|
|
34
|
-
handleOpened: () => {
|
|
35
|
-
opened = true;
|
|
36
|
-
openedResolver();
|
|
37
|
-
},
|
|
38
|
-
handleClosed: (evt: MDCDialogCloseEvent) => {
|
|
39
|
-
if (!opened) {
|
|
40
|
-
// The dialog was closed before it was opened, need to prevent an unresolved open promise.
|
|
41
|
-
openedResolver();
|
|
42
|
-
}
|
|
43
|
-
closedResolver(evt.detail.action);
|
|
44
|
-
controller.deactivate();
|
|
45
|
-
dialogVm.root.removeEventListener(strings.CLOSED_EVENT, bindingContext.handleClosed);
|
|
46
|
-
dialogVm.root.removeEventListener(strings.OPENED_EVENT, bindingContext.handleOpened);
|
|
47
|
-
dialogContainer.remove();
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const dialogContainer = document.createElement('div');
|
|
52
|
-
const def = CustomElement.getDefinition(options.viewModel);
|
|
53
|
-
dialogContainer.innerHTML = `<${def.name}></${def.name}>`;
|
|
54
|
-
document.body.appendChild(dialogContainer);
|
|
55
|
-
|
|
56
|
-
const controller = await this.au.enhance({ host: dialogContainer, component: {} });
|
|
57
|
-
const dialogVm = CustomElement.for<MdcDialog>(dialogContainer.querySelector('mdc-dialog') as HTMLElement).viewModel;
|
|
58
|
-
dialogVm.root.addEventListener(strings.CLOSED_EVENT, bindingContext.handleClosed);
|
|
59
|
-
dialogVm.root.addEventListener(strings.OPENED_EVENT, bindingContext.handleOpened);
|
|
60
|
-
const vm = CustomElement.for<T>(dialogContainer.firstChild as HTMLElement).viewModel;
|
|
61
|
-
if (vm.loading) {
|
|
62
|
-
const loadingResult = vm.loading(options.model);
|
|
63
|
-
if (loadingResult instanceof Promise) {
|
|
64
|
-
await loadingResult;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
await dialogVm.initialised;
|
|
68
|
-
dialogVm.open();
|
|
69
|
-
|
|
70
|
-
await openedPromise;
|
|
71
|
-
// re-layout ripple elements because dialogs use `transform: scale(.8)` and initial layout is incorrect
|
|
72
|
-
const ripples = Array.from(dialogVm.root.querySelectorAll<IMdcRippleElement>('.mdc-ripple-upgraded'));
|
|
73
|
-
await Promise.all(ripples.map(async x => {
|
|
74
|
-
const ripple = CustomAttribute.for<MdcRipple>(x, 'mdc-ripple');
|
|
75
|
-
await ripple?.viewModel.initialised;
|
|
76
|
-
ripple?.viewModel.foundation?.layout();
|
|
77
|
-
}));
|
|
78
|
-
return await closedPromise;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
1
|
+
import { MdcDialog } from './mdc-dialog';
|
|
2
|
+
import Aurelia, { CustomAttribute, IAurelia, resolve } from 'aurelia';
|
|
3
|
+
import { MDCDialogCloseEvent, strings } from '@material/dialog';
|
|
4
|
+
import { CustomElement } from '@aurelia/runtime-html';
|
|
5
|
+
import { Constructable } from '@aurelia/kernel';
|
|
6
|
+
import { IMdcRippleElement, MdcRipple } from '../ripple/mdc-ripple';
|
|
7
|
+
|
|
8
|
+
/** Dialog service open method options */
|
|
9
|
+
export interface IMdcDialogOptions<T extends { loading: (params: any) => any }> {
|
|
10
|
+
/** A class represeting the dialog content view model */
|
|
11
|
+
viewModel: Constructable<T>;
|
|
12
|
+
|
|
13
|
+
/** Data to pass to the view model's loading method */
|
|
14
|
+
model?: unknown;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface IMdcDialogBindingContext {
|
|
18
|
+
handleClosed(evt: MDCDialogCloseEvent): void;
|
|
19
|
+
handleOpened(): void;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Service to open MDC dialogs */
|
|
23
|
+
export class MdcDialogService {
|
|
24
|
+
constructor(private readonly au: Aurelia = resolve(IAurelia)) { }
|
|
25
|
+
|
|
26
|
+
/** Opens the dialog specified in the options */
|
|
27
|
+
async open<T extends { loading: (params: any) => any }>(options: IMdcDialogOptions<T>) {
|
|
28
|
+
let closedResolver: (action?: string | PromiseLike<string> | undefined) => void;
|
|
29
|
+
const closedPromise = new Promise<string>(r => closedResolver = r);
|
|
30
|
+
let openedResolver: (value?: unknown) => void;
|
|
31
|
+
const openedPromise = new Promise(r => openedResolver = r);
|
|
32
|
+
let opened = false;
|
|
33
|
+
const bindingContext: IMdcDialogBindingContext = {
|
|
34
|
+
handleOpened: () => {
|
|
35
|
+
opened = true;
|
|
36
|
+
openedResolver();
|
|
37
|
+
},
|
|
38
|
+
handleClosed: (evt: MDCDialogCloseEvent) => {
|
|
39
|
+
if (!opened) {
|
|
40
|
+
// The dialog was closed before it was opened, need to prevent an unresolved open promise.
|
|
41
|
+
openedResolver();
|
|
42
|
+
}
|
|
43
|
+
closedResolver(evt.detail.action);
|
|
44
|
+
controller.deactivate();
|
|
45
|
+
dialogVm.root.removeEventListener(strings.CLOSED_EVENT, bindingContext.handleClosed);
|
|
46
|
+
dialogVm.root.removeEventListener(strings.OPENED_EVENT, bindingContext.handleOpened);
|
|
47
|
+
dialogContainer.remove();
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const dialogContainer = document.createElement('div');
|
|
52
|
+
const def = CustomElement.getDefinition(options.viewModel);
|
|
53
|
+
dialogContainer.innerHTML = `<${def.name}></${def.name}>`;
|
|
54
|
+
document.body.appendChild(dialogContainer);
|
|
55
|
+
|
|
56
|
+
const controller = await this.au.enhance({ host: dialogContainer, component: {} });
|
|
57
|
+
const dialogVm = CustomElement.for<MdcDialog>(dialogContainer.querySelector('mdc-dialog') as HTMLElement).viewModel;
|
|
58
|
+
dialogVm.root.addEventListener(strings.CLOSED_EVENT, bindingContext.handleClosed);
|
|
59
|
+
dialogVm.root.addEventListener(strings.OPENED_EVENT, bindingContext.handleOpened);
|
|
60
|
+
const vm = CustomElement.for<T>(dialogContainer.firstChild as HTMLElement).viewModel;
|
|
61
|
+
if (vm.loading) {
|
|
62
|
+
const loadingResult = vm.loading(options.model);
|
|
63
|
+
if (loadingResult instanceof Promise) {
|
|
64
|
+
await loadingResult;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
await dialogVm.initialised;
|
|
68
|
+
dialogVm.open();
|
|
69
|
+
|
|
70
|
+
await openedPromise;
|
|
71
|
+
// re-layout ripple elements because dialogs use `transform: scale(.8)` and initial layout is incorrect
|
|
72
|
+
const ripples = Array.from(dialogVm.root.querySelectorAll<IMdcRippleElement>('.mdc-ripple-upgraded'));
|
|
73
|
+
await Promise.all(ripples.map(async x => {
|
|
74
|
+
const ripple = CustomAttribute.for<MdcRipple>(x, 'mdc-ripple');
|
|
75
|
+
await ripple?.viewModel.initialised;
|
|
76
|
+
ripple?.viewModel.foundation?.layout();
|
|
77
|
+
}));
|
|
78
|
+
return await closedPromise;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -1,104 +1,104 @@
|
|
|
1
|
-
import { customElement, inject, bindable, IPlatform } from 'aurelia';
|
|
2
|
-
import { booleanAttr } from '../base';
|
|
3
|
-
import { CustomElement } from '@aurelia/runtime-html';
|
|
4
|
-
import template from './mdc-expandable.html?raw';
|
|
5
|
-
|
|
6
|
-
const OPEN_CHANGED_EVENT = 'mdcexpandable:open-changed';
|
|
7
|
-
const ENTER = 13;
|
|
8
|
-
const SPACE = 32;
|
|
9
|
-
|
|
10
|
-
/** @selector mdc-expandable */
|
|
11
|
-
@inject(Element, IPlatform)
|
|
12
|
-
@customElement({ name: 'mdc-expandable', template })
|
|
13
|
-
export class MdcExpandable {
|
|
14
|
-
constructor(public element: HTMLElement, private platform: IPlatform) { }
|
|
15
|
-
|
|
16
|
-
header?: HTMLElement = undefined;
|
|
17
|
-
content?: HTMLElement = undefined;
|
|
18
|
-
contentContainer?: HTMLElement = undefined;
|
|
19
|
-
focused: boolean;
|
|
20
|
-
|
|
21
|
-
/** Toggles the expandable open and closed */
|
|
22
|
-
@bindable({ set: booleanAttr })
|
|
23
|
-
open: boolean;
|
|
24
|
-
openChanged() {
|
|
25
|
-
this.updateContainerHeight();
|
|
26
|
-
this.element.dispatchEvent(new CustomEvent(
|
|
27
|
-
OPEN_CHANGED_EVENT,
|
|
28
|
-
{ detail: { component: this, open: this.open } }
|
|
29
|
-
));
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
/** Set the expandable to be in an accordion group */
|
|
33
|
-
@bindable()
|
|
34
|
-
accordion?: string;
|
|
35
|
-
|
|
36
|
-
handleEvent(e: Event) {
|
|
37
|
-
switch (e.type) {
|
|
38
|
-
case 'transitionend':
|
|
39
|
-
this.setContentContainerHeightToAuto();
|
|
40
|
-
break;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
setContentContainerHeightToAuto() {
|
|
45
|
-
this.contentContainer!.style.overflow = 'visible';
|
|
46
|
-
this.contentContainer!.style.height = 'auto';
|
|
47
|
-
this.contentContainer!.removeEventListener('transitionend', this);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
attached() {
|
|
51
|
-
this.openChanged();
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
updateContainerHeight() {
|
|
55
|
-
if (this.open) {
|
|
56
|
-
// after transition set body height to auto so that expandable children are visible
|
|
57
|
-
this.contentContainer!.addEventListener('transitionend', this);
|
|
58
|
-
this.contentContainer!.style.height = `${this.content!.clientHeight}px`;
|
|
59
|
-
} else {
|
|
60
|
-
// the following line is needed because height has been restored to auto'
|
|
61
|
-
this.contentContainer!.style.height = `${this.content!.clientHeight}px`;
|
|
62
|
-
this.platform.taskQueue.queueTask(() => {
|
|
63
|
-
this.contentContainer!.style.overflow = 'hidden';
|
|
64
|
-
this.contentContainer!.style.height = '0';
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/** Toggles the expandable open and closed */
|
|
70
|
-
toggle() {
|
|
71
|
-
if (!this.open && this.accordion !== undefined) {
|
|
72
|
-
const otherAccordions = Array.from(this.element.parentElement!.querySelectorAll(`.mdc-expandable--accordion__${this.accordion}.mdc-expandable--open`));
|
|
73
|
-
otherAccordions.filter(x => x !== this.element)
|
|
74
|
-
.map(x => CustomElement.for<MdcExpandable>(x).viewModel)
|
|
75
|
-
.forEach(x => x.toggle());
|
|
76
|
-
}
|
|
77
|
-
this.open = !this.open;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
handleFocus() {
|
|
81
|
-
this.focused = true;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
handleBlur() {
|
|
85
|
-
this.focused = false;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
handleKeydown(evt: KeyboardEvent) {
|
|
89
|
-
if ((evt.keyCode === ENTER || evt.keyCode === SPACE)) {
|
|
90
|
-
this.toggle();
|
|
91
|
-
}
|
|
92
|
-
return true;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/** @hidden */
|
|
97
|
-
export interface IMdcExpandableElement extends HTMLElement {
|
|
98
|
-
$au: {
|
|
99
|
-
'au:resource:custom-element': {
|
|
100
|
-
viewModel: MdcExpandable;
|
|
101
|
-
};
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
|
|
1
|
+
import { customElement, inject, bindable, IPlatform } from 'aurelia';
|
|
2
|
+
import { booleanAttr } from '../base';
|
|
3
|
+
import { CustomElement } from '@aurelia/runtime-html';
|
|
4
|
+
import template from './mdc-expandable.html?raw';
|
|
5
|
+
|
|
6
|
+
const OPEN_CHANGED_EVENT = 'mdcexpandable:open-changed';
|
|
7
|
+
const ENTER = 13;
|
|
8
|
+
const SPACE = 32;
|
|
9
|
+
|
|
10
|
+
/** @selector mdc-expandable */
|
|
11
|
+
@inject(Element, IPlatform)
|
|
12
|
+
@customElement({ name: 'mdc-expandable', template })
|
|
13
|
+
export class MdcExpandable {
|
|
14
|
+
constructor(public element: HTMLElement, private platform: IPlatform) { }
|
|
15
|
+
|
|
16
|
+
header?: HTMLElement = undefined;
|
|
17
|
+
content?: HTMLElement = undefined;
|
|
18
|
+
contentContainer?: HTMLElement = undefined;
|
|
19
|
+
focused: boolean;
|
|
20
|
+
|
|
21
|
+
/** Toggles the expandable open and closed */
|
|
22
|
+
@bindable({ set: booleanAttr })
|
|
23
|
+
open: boolean;
|
|
24
|
+
openChanged() {
|
|
25
|
+
this.updateContainerHeight();
|
|
26
|
+
this.element.dispatchEvent(new CustomEvent(
|
|
27
|
+
OPEN_CHANGED_EVENT,
|
|
28
|
+
{ detail: { component: this, open: this.open } }
|
|
29
|
+
));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Set the expandable to be in an accordion group */
|
|
33
|
+
@bindable()
|
|
34
|
+
accordion?: string;
|
|
35
|
+
|
|
36
|
+
handleEvent(e: Event) {
|
|
37
|
+
switch (e.type) {
|
|
38
|
+
case 'transitionend':
|
|
39
|
+
this.setContentContainerHeightToAuto();
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
setContentContainerHeightToAuto() {
|
|
45
|
+
this.contentContainer!.style.overflow = 'visible';
|
|
46
|
+
this.contentContainer!.style.height = 'auto';
|
|
47
|
+
this.contentContainer!.removeEventListener('transitionend', this);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
attached() {
|
|
51
|
+
this.openChanged();
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
updateContainerHeight() {
|
|
55
|
+
if (this.open) {
|
|
56
|
+
// after transition set body height to auto so that expandable children are visible
|
|
57
|
+
this.contentContainer!.addEventListener('transitionend', this);
|
|
58
|
+
this.contentContainer!.style.height = `${this.content!.clientHeight}px`;
|
|
59
|
+
} else {
|
|
60
|
+
// the following line is needed because height has been restored to auto'
|
|
61
|
+
this.contentContainer!.style.height = `${this.content!.clientHeight}px`;
|
|
62
|
+
this.platform.taskQueue.queueTask(() => {
|
|
63
|
+
this.contentContainer!.style.overflow = 'hidden';
|
|
64
|
+
this.contentContainer!.style.height = '0';
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Toggles the expandable open and closed */
|
|
70
|
+
toggle() {
|
|
71
|
+
if (!this.open && this.accordion !== undefined) {
|
|
72
|
+
const otherAccordions = Array.from(this.element.parentElement!.querySelectorAll(`.mdc-expandable--accordion__${this.accordion}.mdc-expandable--open`));
|
|
73
|
+
otherAccordions.filter(x => x !== this.element)
|
|
74
|
+
.map(x => CustomElement.for<MdcExpandable>(x).viewModel)
|
|
75
|
+
.forEach(x => x.toggle());
|
|
76
|
+
}
|
|
77
|
+
this.open = !this.open;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
handleFocus() {
|
|
81
|
+
this.focused = true;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
handleBlur() {
|
|
85
|
+
this.focused = false;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
handleKeydown(evt: KeyboardEvent) {
|
|
89
|
+
if ((evt.keyCode === ENTER || evt.keyCode === SPACE)) {
|
|
90
|
+
this.toggle();
|
|
91
|
+
}
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** @hidden */
|
|
97
|
+
export interface IMdcExpandableElement extends HTMLElement {
|
|
98
|
+
$au: {
|
|
99
|
+
'au:resource:custom-element': {
|
|
100
|
+
viewModel: MdcExpandable;
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
@@ -1,60 +1,60 @@
|
|
|
1
|
-
import { cssClasses, MDCFormFieldFoundation, MDCFormFieldAdapter } from '@material/form-field';
|
|
2
|
-
import { MdcComponent, booleanAttr } from '../base';
|
|
3
|
-
import { customElement, inject, bindable } from 'aurelia';
|
|
4
|
-
import { CustomAttribute } from '@aurelia/runtime-html';
|
|
5
|
-
import template from './mdc-form-field.html?raw';
|
|
6
|
-
import { MdcRipple, IMdcRippleElement } from '../ripple/mdc-ripple';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* @selector mdc-form-field
|
|
10
|
-
*/
|
|
11
|
-
@inject(Element)
|
|
12
|
-
@customElement({ name: 'mdc-form-field', template })
|
|
13
|
-
export class MdcFormField extends MdcComponent<MDCFormFieldFoundation> {
|
|
14
|
-
cssClasses = cssClasses;
|
|
15
|
-
|
|
16
|
-
ripple?: MdcRipple;
|
|
17
|
-
|
|
18
|
-
label?: HTMLLabelElement | null;
|
|
19
|
-
|
|
20
|
-
/** Force label text to stay on a single line and ellipse the overflow text */
|
|
21
|
-
@bindable({ set: booleanAttr })
|
|
22
|
-
nowrap: boolean;
|
|
23
|
-
|
|
24
|
-
/** Position the input after the label */
|
|
25
|
-
@bindable({ set: booleanAttr })
|
|
26
|
-
alignEnd: boolean;
|
|
27
|
-
|
|
28
|
-
/** Distributes space between label text and control */
|
|
29
|
-
@bindable({ set: booleanAttr })
|
|
30
|
-
spaceBetween: boolean;
|
|
31
|
-
|
|
32
|
-
initialSyncWithDOM() {
|
|
33
|
-
let rippleUpgraded = this.root.querySelector<IMdcRippleElement>('mdc-checkbox');
|
|
34
|
-
if (!rippleUpgraded) {
|
|
35
|
-
rippleUpgraded = this.root.querySelector<IMdcRippleElement>('mdc-radio');
|
|
36
|
-
}
|
|
37
|
-
this.ripple = rippleUpgraded ? CustomAttribute.for<MdcRipple>(rippleUpgraded, 'mdc-ripple')?.viewModel : undefined;
|
|
38
|
-
|
|
39
|
-
const input = this.root.querySelector('input, button');
|
|
40
|
-
if (input?.hasAttribute('id')) {
|
|
41
|
-
this.label = this.root.querySelector('label');
|
|
42
|
-
if (this.label) {
|
|
43
|
-
this.label.setAttribute('for', input.getAttribute('id')!);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
getDefaultFoundation() {
|
|
49
|
-
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
|
|
50
|
-
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
|
|
51
|
-
const adapter: MDCFormFieldAdapter = {
|
|
52
|
-
activateInputRipple: () => this.ripple?.activate(),
|
|
53
|
-
deactivateInputRipple: () => this.ripple?.deactivate(),
|
|
54
|
-
deregisterInteractionHandler: (evtType, handler) => this.label?.removeEventListener(evtType, handler),
|
|
55
|
-
registerInteractionHandler: (evtType, handler) => this.label?.addEventListener(evtType, handler),
|
|
56
|
-
};
|
|
57
|
-
return new MDCFormFieldFoundation(adapter);
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
}
|
|
1
|
+
import { cssClasses, MDCFormFieldFoundation, MDCFormFieldAdapter } from '@material/form-field';
|
|
2
|
+
import { MdcComponent, booleanAttr } from '../base';
|
|
3
|
+
import { customElement, inject, bindable } from 'aurelia';
|
|
4
|
+
import { CustomAttribute } from '@aurelia/runtime-html';
|
|
5
|
+
import template from './mdc-form-field.html?raw';
|
|
6
|
+
import { MdcRipple, IMdcRippleElement } from '../ripple/mdc-ripple';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @selector mdc-form-field
|
|
10
|
+
*/
|
|
11
|
+
@inject(Element)
|
|
12
|
+
@customElement({ name: 'mdc-form-field', template })
|
|
13
|
+
export class MdcFormField extends MdcComponent<MDCFormFieldFoundation> {
|
|
14
|
+
cssClasses = cssClasses;
|
|
15
|
+
|
|
16
|
+
ripple?: MdcRipple;
|
|
17
|
+
|
|
18
|
+
label?: HTMLLabelElement | null;
|
|
19
|
+
|
|
20
|
+
/** Force label text to stay on a single line and ellipse the overflow text */
|
|
21
|
+
@bindable({ set: booleanAttr })
|
|
22
|
+
nowrap: boolean;
|
|
23
|
+
|
|
24
|
+
/** Position the input after the label */
|
|
25
|
+
@bindable({ set: booleanAttr })
|
|
26
|
+
alignEnd: boolean;
|
|
27
|
+
|
|
28
|
+
/** Distributes space between label text and control */
|
|
29
|
+
@bindable({ set: booleanAttr })
|
|
30
|
+
spaceBetween: boolean;
|
|
31
|
+
|
|
32
|
+
initialSyncWithDOM() {
|
|
33
|
+
let rippleUpgraded = this.root.querySelector<IMdcRippleElement>('mdc-checkbox');
|
|
34
|
+
if (!rippleUpgraded) {
|
|
35
|
+
rippleUpgraded = this.root.querySelector<IMdcRippleElement>('mdc-radio');
|
|
36
|
+
}
|
|
37
|
+
this.ripple = rippleUpgraded ? CustomAttribute.for<MdcRipple>(rippleUpgraded, 'mdc-ripple')?.viewModel : undefined;
|
|
38
|
+
|
|
39
|
+
const input = this.root.querySelector('input, button');
|
|
40
|
+
if (input?.hasAttribute('id')) {
|
|
41
|
+
this.label = this.root.querySelector('label');
|
|
42
|
+
if (this.label) {
|
|
43
|
+
this.label.setAttribute('for', input.getAttribute('id')!);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
getDefaultFoundation() {
|
|
49
|
+
// DO NOT INLINE this variable. For backward compatibility, foundations take a Partial<MDCFooAdapter>.
|
|
50
|
+
// To ensure we don't accidentally omit any methods, we need a separate, strongly typed adapter variable.
|
|
51
|
+
const adapter: MDCFormFieldAdapter = {
|
|
52
|
+
activateInputRipple: () => this.ripple?.activate(),
|
|
53
|
+
deactivateInputRipple: () => this.ripple?.deactivate(),
|
|
54
|
+
deregisterInteractionHandler: (evtType, handler) => this.label?.removeEventListener(evtType, handler),
|
|
55
|
+
registerInteractionHandler: (evtType, handler) => this.label?.addEventListener(evtType, handler),
|
|
56
|
+
};
|
|
57
|
+
return new MDCFormFieldFoundation(adapter);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
}
|