@exmg/exm-chip-input 1.1.36 → 1.2.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/.rollup.cache/root/repo/packages/exm-chip-input/dist/dropdown/dropdown-container.d.ts +6 -0
- package/.rollup.cache/root/repo/packages/exm-chip-input/dist/dropdown/dropdown-container.js +39 -0
- package/.rollup.cache/root/repo/packages/exm-chip-input/dist/exm-chip-input-dropdown.d.ts +35 -0
- package/.rollup.cache/root/repo/packages/exm-chip-input/dist/exm-chip-input-dropdown.js +153 -0
- package/.rollup.cache/root/repo/packages/exm-chip-input/dist/exm-chip-input.d.ts +19 -0
- package/.rollup.cache/root/repo/packages/exm-chip-input/dist/exm-chip-input.js +76 -0
- package/.rollup.cache/root/repo/packages/exm-chip-input/dist/exm-chip.d.ts +51 -0
- package/.rollup.cache/root/repo/packages/exm-chip-input/dist/exm-chip.js +149 -0
- package/.rollup.cache/root/repo/packages/exm-chip-input/dist/index.d.ts +4 -0
- package/.rollup.cache/root/repo/packages/exm-chip-input/dist/index.js +5 -0
- package/.rollup.cache/root/repo/packages/exm-chip-input/dist/selection-controller.d.ts +68 -0
- package/.rollup.cache/root/repo/packages/exm-chip-input/dist/selection-controller.js +74 -0
- package/.rollup.cache/root/repo/packages/exm-chip-input/dist/styles/exm-chip-input-css.d.ts +1 -0
- package/.rollup.cache/root/repo/packages/exm-chip-input/dist/styles/exm-chip-input-css.js +19 -0
- package/.rollup.cache/root/repo/packages/exm-chip-input/dist/styles/exm-chip-input-dropdown-css.d.ts +1 -0
- package/.rollup.cache/root/repo/packages/exm-chip-input/dist/styles/exm-chip-input-dropdown-css.js +20 -0
- package/.rollup.cache/root/repo/packages/exm-chip-input/dist/styles/exm-chips-shared-css.d.ts +1 -0
- package/.rollup.cache/root/repo/packages/exm-chip-input/dist/styles/exm-chips-shared-css.js +77 -0
- package/.rollup.cache/root/repo/packages/exm-chip-input/dist/validator/chip-validator.d.ts +38 -0
- package/.rollup.cache/root/repo/packages/exm-chip-input/dist/validator/chip-validator.js +65 -0
- package/dist/dropdown/dropdown-container.js +6 -4
- package/dist/exm-chip-input-dropdown.js +5 -3
- package/dist/exm-chip-input.js +5 -3
- package/dist/exm-chip.js +16 -14
- package/dist/index.js +1 -1
- package/dist/selection-controller.js +4 -2
- package/dist/styles/exm-chip-input-css.js +5 -2
- package/dist/styles/exm-chip-input-dropdown-css.js +5 -2
- package/dist/styles/exm-chips-shared-css.js +5 -2
- package/dist/validator/chip-validator.js +6 -3
- package/package.json +2 -2
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { LitElement, html, css } from 'lit';
|
|
3
|
+
import { customElement, property } from 'lit/decorators.js';
|
|
4
|
+
let DropdownContainer = class DropdownContainer extends LitElement {
|
|
5
|
+
constructor() {
|
|
6
|
+
super(...arguments);
|
|
7
|
+
this.dropdownTitle = 'Select items';
|
|
8
|
+
}
|
|
9
|
+
render() {
|
|
10
|
+
return html `<div class="container">
|
|
11
|
+
<div class="label">${this.dropdownTitle}</div>
|
|
12
|
+
<div class="items"><slot></slot></div>
|
|
13
|
+
</div>`;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
DropdownContainer.styles = [
|
|
17
|
+
css `
|
|
18
|
+
:host {
|
|
19
|
+
display: block;
|
|
20
|
+
padding: 0 1rem 0.5rem;
|
|
21
|
+
}
|
|
22
|
+
.label {
|
|
23
|
+
margin-bottom: 0.5rem;
|
|
24
|
+
}
|
|
25
|
+
.items {
|
|
26
|
+
display: flex;
|
|
27
|
+
flex-wrap: wrap;
|
|
28
|
+
gap: 0.3rem;
|
|
29
|
+
}
|
|
30
|
+
`,
|
|
31
|
+
];
|
|
32
|
+
__decorate([
|
|
33
|
+
property({ type: String })
|
|
34
|
+
], DropdownContainer.prototype, "dropdownTitle", void 0);
|
|
35
|
+
DropdownContainer = __decorate([
|
|
36
|
+
customElement('dropdown-container')
|
|
37
|
+
], DropdownContainer);
|
|
38
|
+
export { DropdownContainer };
|
|
39
|
+
//# sourceMappingURL=dropdown-container.js.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import '@material/web/iconbutton/icon-button.js';
|
|
2
|
+
import '@material/web/button/text-button.js';
|
|
3
|
+
import '@material/web/chips/input-chip.js';
|
|
4
|
+
import '@material/web/icon/icon.js';
|
|
5
|
+
import '@material/web/menu/menu.js';
|
|
6
|
+
import './dropdown/dropdown-container.js';
|
|
7
|
+
import { ChipSet } from '@material/web/chips/internal/chip-set.js';
|
|
8
|
+
import { ExmChip } from './exm-chip.js';
|
|
9
|
+
declare global {
|
|
10
|
+
interface HTMLElementTagNameMap {
|
|
11
|
+
'exm-chip-input-dropdown': ExmChipInputDropdown;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
*
|
|
16
|
+
* @final
|
|
17
|
+
* @suppress {visibility}
|
|
18
|
+
*/
|
|
19
|
+
export declare class ExmChipInputDropdown extends ChipSet {
|
|
20
|
+
label: string;
|
|
21
|
+
dropdownTitle: string;
|
|
22
|
+
btnAddText: string;
|
|
23
|
+
selectedChips?: ExmChip[];
|
|
24
|
+
supportingText: string;
|
|
25
|
+
private menuOpen;
|
|
26
|
+
static styles: import("lit").CSSResult[];
|
|
27
|
+
constructor();
|
|
28
|
+
private _onSelect;
|
|
29
|
+
private onOpenClick;
|
|
30
|
+
private onMenuClosed;
|
|
31
|
+
private _removeSelected;
|
|
32
|
+
private onKeydown;
|
|
33
|
+
protected render(): import("lit-html").TemplateResult<1>;
|
|
34
|
+
private updateTabIndicesOverride;
|
|
35
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { customElement } from 'lit/decorators/custom-element.js';
|
|
3
|
+
import '@material/web/iconbutton/icon-button.js';
|
|
4
|
+
import '@material/web/button/text-button.js';
|
|
5
|
+
import '@material/web/chips/input-chip.js';
|
|
6
|
+
import '@material/web/icon/icon.js';
|
|
7
|
+
import '@material/web/menu/menu.js';
|
|
8
|
+
import './dropdown/dropdown-container.js';
|
|
9
|
+
import { ChipSet } from '@material/web/chips/internal/chip-set.js';
|
|
10
|
+
import { html, nothing } from 'lit';
|
|
11
|
+
import { property, state } from 'lit/decorators.js';
|
|
12
|
+
import { repeat } from 'lit/directives/repeat.js';
|
|
13
|
+
import { style } from './styles/exm-chip-input-dropdown-css.js';
|
|
14
|
+
import { sharedChipStyle } from './styles/exm-chips-shared-css.js';
|
|
15
|
+
import { classMap } from 'lit/directives/class-map.js';
|
|
16
|
+
/**
|
|
17
|
+
*
|
|
18
|
+
* @final
|
|
19
|
+
* @suppress {visibility}
|
|
20
|
+
*/
|
|
21
|
+
let ExmChipInputDropdown = class ExmChipInputDropdown extends ChipSet {
|
|
22
|
+
constructor() {
|
|
23
|
+
super();
|
|
24
|
+
this.label = '';
|
|
25
|
+
this.dropdownTitle = 'Select items';
|
|
26
|
+
this.btnAddText = 'Add items';
|
|
27
|
+
this.supportingText = '';
|
|
28
|
+
this.menuOpen = false;
|
|
29
|
+
// Add event listeners in the constructor
|
|
30
|
+
this.addEventListener('click', this._onSelect);
|
|
31
|
+
}
|
|
32
|
+
_onSelect(e) {
|
|
33
|
+
const clickedElement = e.target;
|
|
34
|
+
const elementType = clickedElement.tagName;
|
|
35
|
+
if (elementType === 'EXM-CHIP') {
|
|
36
|
+
// @ts-ignore
|
|
37
|
+
this.selectedChips = this.chips.filter((chip) => chip.selected);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
onOpenClick() {
|
|
41
|
+
this.menuOpen = true;
|
|
42
|
+
}
|
|
43
|
+
onMenuClosed() {
|
|
44
|
+
this.menuOpen = false;
|
|
45
|
+
}
|
|
46
|
+
_removeSelected(val) {
|
|
47
|
+
const index = (this.selectedChips || []).findIndex((el) => el.value === val);
|
|
48
|
+
if (index > -1) {
|
|
49
|
+
(this.selectedChips || []).splice(index, 1); // 2nd parameter means remove one item only
|
|
50
|
+
// @ts-ignore
|
|
51
|
+
const chip = this.chips.find((el) => el.value === val);
|
|
52
|
+
if (chip) {
|
|
53
|
+
// @ts-ignore
|
|
54
|
+
chip.selected = false;
|
|
55
|
+
setTimeout(() => chip.dispatchEvent(new CustomEvent('blur', { bubbles: true, composed: true })), 0);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
onKeydown(e) {
|
|
60
|
+
if (!e.defaultPrevented && e.key === 'Escape') {
|
|
61
|
+
e.preventDefault();
|
|
62
|
+
this.menuOpen = false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
render() {
|
|
66
|
+
const containerClasses = { 'has-label': !!this.label };
|
|
67
|
+
const labelClasses = { 'not-empty': (this.selectedChips || []).length > 0, 'has-focus': this.menuOpen };
|
|
68
|
+
return html `
|
|
69
|
+
<div class="container ${classMap(containerClasses)}">
|
|
70
|
+
<div class="background"></div>
|
|
71
|
+
<div class="label ${classMap(labelClasses)}">${this.label}</div>
|
|
72
|
+
<div class="input-container" id="input-container" @click="${this.onOpenClick}">
|
|
73
|
+
<div class="selected-chips">
|
|
74
|
+
${repeat(this.selectedChips || [], (chip) => chip.value, (chip) => html `<md-input-chip
|
|
75
|
+
label="${chip.label}"
|
|
76
|
+
data-value=${chip.value}
|
|
77
|
+
selected
|
|
78
|
+
@remove=${() => this._removeSelected(chip.value)}
|
|
79
|
+
></md-input-chip>`)}
|
|
80
|
+
</div>
|
|
81
|
+
<md-menu
|
|
82
|
+
anchor="input-container"
|
|
83
|
+
menu-corner="start-start"
|
|
84
|
+
anchor-corner="end-start"
|
|
85
|
+
default-focus="none"
|
|
86
|
+
role="dialog"
|
|
87
|
+
aria-label="${this.dropdownTitle} controls"
|
|
88
|
+
.open=${this.menuOpen}
|
|
89
|
+
@closed=${this.onMenuClosed}
|
|
90
|
+
@keydown=${this.onKeydown}
|
|
91
|
+
>
|
|
92
|
+
<dropdown-container .dropdownTitle=${this.dropdownTitle}
|
|
93
|
+
><slot @slotchange=${this.updateTabIndicesOverride}></slot
|
|
94
|
+
></dropdown-container>
|
|
95
|
+
</md-menu>
|
|
96
|
+
</div>
|
|
97
|
+
${this.supportingText ? html `<div class="supporting-text">${this.supportingText}</div>` : nothing}
|
|
98
|
+
</div>
|
|
99
|
+
`;
|
|
100
|
+
}
|
|
101
|
+
updateTabIndicesOverride() {
|
|
102
|
+
// The chip that should be focusable is either the chip that currently has
|
|
103
|
+
// focus or the first chip that can be focused.
|
|
104
|
+
const { chips } = this;
|
|
105
|
+
// update selected array after dom change
|
|
106
|
+
// @ts-ignore
|
|
107
|
+
this.selectedChips = this.chips.filter((chip) => chip.selected);
|
|
108
|
+
let chipToFocus;
|
|
109
|
+
for (const chip of chips) {
|
|
110
|
+
const isChipFocusable = chip.alwaysFocusable || !chip.disabled;
|
|
111
|
+
const chipIsFocused = chip.matches(':focus-within');
|
|
112
|
+
if (chipIsFocused && isChipFocusable) {
|
|
113
|
+
// Found the first chip that is actively focused. This overrides the
|
|
114
|
+
// first focusable chip found.
|
|
115
|
+
chipToFocus = chip;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (isChipFocusable && !chipToFocus) {
|
|
119
|
+
chipToFocus = chip;
|
|
120
|
+
}
|
|
121
|
+
// Disable non-focused chips. If we disable all of them, we'll grant focus
|
|
122
|
+
// to the first focusable child that was found.
|
|
123
|
+
chip.tabIndex = -1;
|
|
124
|
+
}
|
|
125
|
+
if (chipToFocus) {
|
|
126
|
+
chipToFocus.tabIndex = 0;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
ExmChipInputDropdown.styles = [sharedChipStyle, style];
|
|
131
|
+
__decorate([
|
|
132
|
+
property({ type: String })
|
|
133
|
+
], ExmChipInputDropdown.prototype, "label", void 0);
|
|
134
|
+
__decorate([
|
|
135
|
+
property({ type: String })
|
|
136
|
+
], ExmChipInputDropdown.prototype, "dropdownTitle", void 0);
|
|
137
|
+
__decorate([
|
|
138
|
+
property({ type: String })
|
|
139
|
+
], ExmChipInputDropdown.prototype, "btnAddText", void 0);
|
|
140
|
+
__decorate([
|
|
141
|
+
property({ type: Array })
|
|
142
|
+
], ExmChipInputDropdown.prototype, "selectedChips", void 0);
|
|
143
|
+
__decorate([
|
|
144
|
+
property({ type: String, attribute: 'supporting-text' })
|
|
145
|
+
], ExmChipInputDropdown.prototype, "supportingText", void 0);
|
|
146
|
+
__decorate([
|
|
147
|
+
state()
|
|
148
|
+
], ExmChipInputDropdown.prototype, "menuOpen", void 0);
|
|
149
|
+
ExmChipInputDropdown = __decorate([
|
|
150
|
+
customElement('exm-chip-input-dropdown')
|
|
151
|
+
], ExmChipInputDropdown);
|
|
152
|
+
export { ExmChipInputDropdown };
|
|
153
|
+
//# sourceMappingURL=exm-chip-input-dropdown.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ChipSet } from '@material/web/chips/internal/chip-set.js';
|
|
2
|
+
declare global {
|
|
3
|
+
interface HTMLElementTagNameMap {
|
|
4
|
+
'exm-chip-input': ExmChipInput;
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* @final
|
|
10
|
+
* @suppress {visibility}
|
|
11
|
+
*/
|
|
12
|
+
export declare class ExmChipInput extends ChipSet {
|
|
13
|
+
label: string;
|
|
14
|
+
supportingText: string;
|
|
15
|
+
chipCount: number;
|
|
16
|
+
static styles: import("lit").CSSResult[];
|
|
17
|
+
protected render(): import("lit-html").TemplateResult<1>;
|
|
18
|
+
private updateTabIndicesOverride;
|
|
19
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { customElement } from 'lit/decorators/custom-element.js';
|
|
3
|
+
import { style } from './styles/exm-chip-input-css.js';
|
|
4
|
+
import { ChipSet } from '@material/web/chips/internal/chip-set.js';
|
|
5
|
+
import { styles } from '@material/web/chips/internal/chip-set-styles.js';
|
|
6
|
+
import { html, nothing } from 'lit';
|
|
7
|
+
import { property, state } from 'lit/decorators.js';
|
|
8
|
+
import { sharedChipStyle } from './styles/exm-chips-shared-css.js';
|
|
9
|
+
import { classMap } from 'lit/directives/class-map.js';
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @final
|
|
13
|
+
* @suppress {visibility}
|
|
14
|
+
*/
|
|
15
|
+
let ExmChipInput = class ExmChipInput extends ChipSet {
|
|
16
|
+
constructor() {
|
|
17
|
+
super(...arguments);
|
|
18
|
+
this.label = '';
|
|
19
|
+
this.supportingText = '';
|
|
20
|
+
this.chipCount = 0;
|
|
21
|
+
}
|
|
22
|
+
render() {
|
|
23
|
+
const containerClasses = { 'has-label': !!this.label };
|
|
24
|
+
const labelClasses = { 'not-empty': this.chipCount > 0 };
|
|
25
|
+
return html `
|
|
26
|
+
<div class="container ${classMap(containerClasses)}">
|
|
27
|
+
<div class="background"></div>
|
|
28
|
+
<div class="state-layer"></div>
|
|
29
|
+
<div class="label ${classMap(labelClasses)}">${this.label}</div>
|
|
30
|
+
<div class="items"><slot @slotchange=${this.updateTabIndicesOverride}></slot></div>
|
|
31
|
+
${this.supportingText ? html `<div class="supporting-text">${this.supportingText}</div>` : nothing}
|
|
32
|
+
</div>
|
|
33
|
+
`;
|
|
34
|
+
}
|
|
35
|
+
updateTabIndicesOverride() {
|
|
36
|
+
// The chip that should be focusable is either the chip that currently has
|
|
37
|
+
// focus or the first chip that can be focused.
|
|
38
|
+
const { chips } = this;
|
|
39
|
+
this.chipCount = chips.length;
|
|
40
|
+
let chipToFocus;
|
|
41
|
+
for (const chip of chips) {
|
|
42
|
+
const isChipFocusable = chip.alwaysFocusable || !chip.disabled;
|
|
43
|
+
const chipIsFocused = chip.matches(':focus-within');
|
|
44
|
+
if (chipIsFocused && isChipFocusable) {
|
|
45
|
+
// Found the first chip that is actively focused. This overrides the
|
|
46
|
+
// first focusable chip found.
|
|
47
|
+
chipToFocus = chip;
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (isChipFocusable && !chipToFocus) {
|
|
51
|
+
chipToFocus = chip;
|
|
52
|
+
}
|
|
53
|
+
// Disable non-focused chips. If we disable all of them, we'll grant focus
|
|
54
|
+
// to the first focusable child that was found.
|
|
55
|
+
chip.tabIndex = -1;
|
|
56
|
+
}
|
|
57
|
+
if (chipToFocus) {
|
|
58
|
+
chipToFocus.tabIndex = 0;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
ExmChipInput.styles = [styles, sharedChipStyle, style];
|
|
63
|
+
__decorate([
|
|
64
|
+
property({ type: String })
|
|
65
|
+
], ExmChipInput.prototype, "label", void 0);
|
|
66
|
+
__decorate([
|
|
67
|
+
property({ type: String, attribute: 'supporting-text' })
|
|
68
|
+
], ExmChipInput.prototype, "supportingText", void 0);
|
|
69
|
+
__decorate([
|
|
70
|
+
state()
|
|
71
|
+
], ExmChipInput.prototype, "chipCount", void 0);
|
|
72
|
+
ExmChipInput = __decorate([
|
|
73
|
+
customElement('exm-chip-input')
|
|
74
|
+
], ExmChipInput);
|
|
75
|
+
export { ExmChipInput };
|
|
76
|
+
//# sourceMappingURL=exm-chip-input.js.map
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { FilterChip } from '@material/web/chips/internal/filter-chip.js';
|
|
2
|
+
import { createValidator, getValidityAnchor } from '@material/web/labs/behaviors/constraint-validation.js';
|
|
3
|
+
import { getFormState, getFormValue } from '@material/web/labs/behaviors/form-associated.js';
|
|
4
|
+
import { ChipValidator } from './validator/chip-validator.js';
|
|
5
|
+
declare global {
|
|
6
|
+
interface HTMLElementTagNameMap {
|
|
7
|
+
'exm-chip': ExmChip;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
declare const CHECKED: unique symbol;
|
|
11
|
+
declare const FilterChipBaseClass: import("@material/web/labs/behaviors/mixin.js").MixinReturn<import("@material/web/labs/behaviors/mixin.js").MixinReturn<(abstract new (...args: any[]) => import("@material/web/labs/behaviors/element-internals.js").WithElementInternals) & (abstract new (...args: any[]) => import("@material/web/labs/behaviors/focusable.js").Focusable) & typeof FilterChip & import("@material/web/labs/behaviors/form-associated.js").FormAssociatedConstructor, import("@material/web/labs/behaviors/form-associated.js").FormAssociated>, import("@material/web/labs/behaviors/constraint-validation.js").ConstraintValidation>;
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
* @final
|
|
15
|
+
* @suppress {visibility}
|
|
16
|
+
*/
|
|
17
|
+
export declare class ExmChip extends FilterChipBaseClass {
|
|
18
|
+
static styles: import("lit").CSSResult[];
|
|
19
|
+
removable: boolean;
|
|
20
|
+
selected: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Whether or not the radio is selected.
|
|
23
|
+
*/
|
|
24
|
+
get checked(): boolean;
|
|
25
|
+
set checked(checked: boolean);
|
|
26
|
+
[CHECKED]: boolean;
|
|
27
|
+
private selectionController;
|
|
28
|
+
/**
|
|
29
|
+
* Whether or not the radio is required. If any radio is required in a group,
|
|
30
|
+
* all radios are implicitly required.
|
|
31
|
+
*/
|
|
32
|
+
required: boolean;
|
|
33
|
+
/**
|
|
34
|
+
* The element value to use in form submission when checked.
|
|
35
|
+
*/
|
|
36
|
+
value: string;
|
|
37
|
+
private readonly container;
|
|
38
|
+
disabled: boolean;
|
|
39
|
+
name: string;
|
|
40
|
+
[getFormValue](): string | null;
|
|
41
|
+
[getFormState](): string;
|
|
42
|
+
constructor();
|
|
43
|
+
formResetCallback(): void;
|
|
44
|
+
formStateRestoreCallback(state: string): void;
|
|
45
|
+
protected updated(): void;
|
|
46
|
+
protected renderPrimaryAction(content: unknown): import("lit-html").TemplateResult<1>;
|
|
47
|
+
private _handleClick;
|
|
48
|
+
[createValidator](): ChipValidator;
|
|
49
|
+
[getValidityAnchor](): HTMLElement;
|
|
50
|
+
}
|
|
51
|
+
export {};
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
var _a;
|
|
2
|
+
import { __decorate } from "tslib";
|
|
3
|
+
import { customElement, property, query } from 'lit/decorators.js';
|
|
4
|
+
import { styles as elevatedStyles } from '@material/web/chips/internal/elevated-styles.js';
|
|
5
|
+
import { FilterChip } from '@material/web/chips/internal/filter-chip.js';
|
|
6
|
+
import { styles } from '@material/web/chips/internal/filter-styles.js';
|
|
7
|
+
import { styles as selectableStyles } from '@material/web/chips/internal/selectable-styles.js';
|
|
8
|
+
import { styles as sharedStyles } from '@material/web/chips/internal/shared-styles.js';
|
|
9
|
+
import { styles as trailingIconStyles } from '@material/web/chips/internal/trailing-icon-styles.js';
|
|
10
|
+
import { redispatchEvent } from '@material/web/internal/events/redispatch-event.js';
|
|
11
|
+
import { createValidator, getValidityAnchor, mixinConstraintValidation, } from '@material/web/labs/behaviors/constraint-validation.js';
|
|
12
|
+
import { getFormState, getFormValue, mixinFormAssociated } from '@material/web/labs/behaviors/form-associated.js';
|
|
13
|
+
import { internals, mixinElementInternals } from '@material/web/labs/behaviors/element-internals.js';
|
|
14
|
+
import { mixinFocusable } from '@material/web/labs/behaviors/focusable.js';
|
|
15
|
+
import { ChipValidator } from './validator/chip-validator.js';
|
|
16
|
+
import { observer } from '@exmg/lit-base';
|
|
17
|
+
import { SelectionController } from './selection-controller.js';
|
|
18
|
+
import { html, nothing } from 'lit';
|
|
19
|
+
const CHECKED = Symbol('checked');
|
|
20
|
+
// Separate variable needed for closure.
|
|
21
|
+
const FilterChipBaseClass = mixinConstraintValidation(mixinFormAssociated(mixinElementInternals(mixinFocusable(FilterChip))));
|
|
22
|
+
/**
|
|
23
|
+
*
|
|
24
|
+
* @final
|
|
25
|
+
* @suppress {visibility}
|
|
26
|
+
*/
|
|
27
|
+
let ExmChip = class ExmChip extends FilterChipBaseClass {
|
|
28
|
+
/**
|
|
29
|
+
* Whether or not the radio is selected.
|
|
30
|
+
*/
|
|
31
|
+
get checked() {
|
|
32
|
+
return this[CHECKED];
|
|
33
|
+
}
|
|
34
|
+
set checked(checked) {
|
|
35
|
+
const wasChecked = this.checked;
|
|
36
|
+
if (wasChecked === checked) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
this[CHECKED] = checked;
|
|
40
|
+
this.requestUpdate('checked', wasChecked);
|
|
41
|
+
}
|
|
42
|
+
[(_a = CHECKED, getFormValue)]() {
|
|
43
|
+
return this.checked ? this.value : null;
|
|
44
|
+
}
|
|
45
|
+
[getFormState]() {
|
|
46
|
+
return String(this.checked);
|
|
47
|
+
}
|
|
48
|
+
constructor() {
|
|
49
|
+
super();
|
|
50
|
+
this.removable = false;
|
|
51
|
+
this.selected = false;
|
|
52
|
+
this[_a] = false;
|
|
53
|
+
this.selectionController = new SelectionController(this);
|
|
54
|
+
/**
|
|
55
|
+
* Whether or not the radio is required. If any radio is required in a group,
|
|
56
|
+
* all radios are implicitly required.
|
|
57
|
+
*/
|
|
58
|
+
this.required = false;
|
|
59
|
+
/**
|
|
60
|
+
* The element value to use in form submission when checked.
|
|
61
|
+
*/
|
|
62
|
+
this.value = 'on';
|
|
63
|
+
this.addController(this.selectionController);
|
|
64
|
+
this[internals].role = 'radio';
|
|
65
|
+
}
|
|
66
|
+
formResetCallback() {
|
|
67
|
+
// The checked property does not reflect, so the original attribute set by
|
|
68
|
+
// the user is used to determine the default value.
|
|
69
|
+
this.checked = this.hasAttribute('checked');
|
|
70
|
+
}
|
|
71
|
+
formStateRestoreCallback(state) {
|
|
72
|
+
this.checked = state === 'true';
|
|
73
|
+
}
|
|
74
|
+
updated() {
|
|
75
|
+
this[internals].ariaChecked = String(this.checked);
|
|
76
|
+
}
|
|
77
|
+
renderPrimaryAction(content) {
|
|
78
|
+
const { ariaLabel } = this;
|
|
79
|
+
return html `
|
|
80
|
+
<button
|
|
81
|
+
class="primary action"
|
|
82
|
+
id="button"
|
|
83
|
+
aria-label=${ariaLabel || nothing}
|
|
84
|
+
aria-pressed=${this.selected}
|
|
85
|
+
?disabled=${this.disabled && !this.alwaysFocusable}
|
|
86
|
+
@click=${this._handleClick}
|
|
87
|
+
>
|
|
88
|
+
${content}
|
|
89
|
+
</button>
|
|
90
|
+
`;
|
|
91
|
+
}
|
|
92
|
+
_handleClick(event) {
|
|
93
|
+
if (this.disabled) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
// Store prevValue to revert in case `chip.selected` is changed during an
|
|
97
|
+
// event listener.
|
|
98
|
+
const prevValue = this.selected;
|
|
99
|
+
this.selected = !this.selected;
|
|
100
|
+
const preventDefault = !redispatchEvent(this, event);
|
|
101
|
+
if (preventDefault) {
|
|
102
|
+
// We should not do `this.selected = !this.selected`, since a client
|
|
103
|
+
// click listener could change its value. Instead, always revert to the
|
|
104
|
+
// original value.
|
|
105
|
+
this.selected = prevValue;
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
[createValidator]() {
|
|
110
|
+
return new ChipValidator(() => {
|
|
111
|
+
if (!this.selectionController) {
|
|
112
|
+
// Validation runs on superclass construction, so selection controller
|
|
113
|
+
// might not actually be ready until this class constructs.
|
|
114
|
+
return [this];
|
|
115
|
+
}
|
|
116
|
+
return this.selectionController.controls;
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
[getValidityAnchor]() {
|
|
120
|
+
return this.container;
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
ExmChip.styles = [sharedStyles, elevatedStyles, trailingIconStyles, selectableStyles, styles];
|
|
124
|
+
__decorate([
|
|
125
|
+
property({ type: Boolean })
|
|
126
|
+
], ExmChip.prototype, "removable", void 0);
|
|
127
|
+
__decorate([
|
|
128
|
+
property({ type: Boolean, reflect: true }),
|
|
129
|
+
observer(function (selected) {
|
|
130
|
+
this.checked = selected;
|
|
131
|
+
})
|
|
132
|
+
], ExmChip.prototype, "selected", void 0);
|
|
133
|
+
__decorate([
|
|
134
|
+
property({ type: Boolean })
|
|
135
|
+
], ExmChip.prototype, "checked", null);
|
|
136
|
+
__decorate([
|
|
137
|
+
property({ type: Boolean })
|
|
138
|
+
], ExmChip.prototype, "required", void 0);
|
|
139
|
+
__decorate([
|
|
140
|
+
property()
|
|
141
|
+
], ExmChip.prototype, "value", void 0);
|
|
142
|
+
__decorate([
|
|
143
|
+
query('.container')
|
|
144
|
+
], ExmChip.prototype, "container", void 0);
|
|
145
|
+
ExmChip = __decorate([
|
|
146
|
+
customElement('exm-chip')
|
|
147
|
+
], ExmChip);
|
|
148
|
+
export { ExmChip };
|
|
149
|
+
//# sourceMappingURL=exm-chip.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { ExmChipInput } from './exm-chip-input.js';
|
|
2
|
+
export { ExmChip } from './exm-chip.js';
|
|
3
|
+
export { ExmChipInputDropdown } from './exm-chip-input-dropdown.js';
|
|
4
|
+
export { style as chipInputStyles } from './styles/exm-chip-input-css.js';
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { ReactiveController } from 'lit';
|
|
7
|
+
/**
|
|
8
|
+
* An element that supports single-selection with `SelectionController`.
|
|
9
|
+
*/
|
|
10
|
+
export interface SelectionElement extends HTMLElement {
|
|
11
|
+
/**
|
|
12
|
+
* Whether or not the element is selected.
|
|
13
|
+
*/
|
|
14
|
+
checked: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* A `ReactiveController` that provides root node-scoped selection for
|
|
18
|
+
* elements, similar to native `<input type="radio">` selection.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* const CHECKED = Symbol('checked');
|
|
22
|
+
*
|
|
23
|
+
* class MyChip extends LitElement {
|
|
24
|
+
* @property({ type: Boolean }) removable = false;
|
|
25
|
+
*
|
|
26
|
+
* @property({ type: Boolean, reflect: true })
|
|
27
|
+
* @observer(function (this: ExmChip, selected: boolean) {
|
|
28
|
+
* this.checked = selected;
|
|
29
|
+
* })
|
|
30
|
+
* selected = false;
|
|
31
|
+
*
|
|
32
|
+
* @property({ type: Boolean })
|
|
33
|
+
* get checked() {
|
|
34
|
+
* return this[CHECKED];
|
|
35
|
+
* }
|
|
36
|
+
* set checked(checked: boolean) {
|
|
37
|
+
* const wasChecked = this.checked;
|
|
38
|
+
* if (wasChecked === checked) {
|
|
39
|
+
* return;
|
|
40
|
+
* }
|
|
41
|
+
* console.log('checked', checked);
|
|
42
|
+
*
|
|
43
|
+
* this[CHECKED] = checked;
|
|
44
|
+
* this.requestUpdate('checked', wasChecked);
|
|
45
|
+
* }
|
|
46
|
+
*
|
|
47
|
+
* [CHECKED] = false;
|
|
48
|
+
*
|
|
49
|
+
* private selectionController = new SelectionController(this);
|
|
50
|
+
*
|
|
51
|
+
* constructor() {
|
|
52
|
+
* super();
|
|
53
|
+
* this.addController(this.selectionController);
|
|
54
|
+
* }
|
|
55
|
+
* }
|
|
56
|
+
*/
|
|
57
|
+
export declare class SelectionController implements ReactiveController {
|
|
58
|
+
private readonly host;
|
|
59
|
+
/**
|
|
60
|
+
* All selection elements in the host element's root with the same
|
|
61
|
+
* `name` attribute, including the host element.
|
|
62
|
+
*/
|
|
63
|
+
get controls(): [SelectionElement, ...SelectionElement[]];
|
|
64
|
+
private root;
|
|
65
|
+
constructor(host: SelectionElement);
|
|
66
|
+
hostConnected(): void;
|
|
67
|
+
hostDisconnected(): void;
|
|
68
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2022 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* A `ReactiveController` that provides root node-scoped selection for
|
|
8
|
+
* elements, similar to native `<input type="radio">` selection.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* const CHECKED = Symbol('checked');
|
|
12
|
+
*
|
|
13
|
+
* class MyChip extends LitElement {
|
|
14
|
+
* @property({ type: Boolean }) removable = false;
|
|
15
|
+
*
|
|
16
|
+
* @property({ type: Boolean, reflect: true })
|
|
17
|
+
* @observer(function (this: ExmChip, selected: boolean) {
|
|
18
|
+
* this.checked = selected;
|
|
19
|
+
* })
|
|
20
|
+
* selected = false;
|
|
21
|
+
*
|
|
22
|
+
* @property({ type: Boolean })
|
|
23
|
+
* get checked() {
|
|
24
|
+
* return this[CHECKED];
|
|
25
|
+
* }
|
|
26
|
+
* set checked(checked: boolean) {
|
|
27
|
+
* const wasChecked = this.checked;
|
|
28
|
+
* if (wasChecked === checked) {
|
|
29
|
+
* return;
|
|
30
|
+
* }
|
|
31
|
+
* console.log('checked', checked);
|
|
32
|
+
*
|
|
33
|
+
* this[CHECKED] = checked;
|
|
34
|
+
* this.requestUpdate('checked', wasChecked);
|
|
35
|
+
* }
|
|
36
|
+
*
|
|
37
|
+
* [CHECKED] = false;
|
|
38
|
+
*
|
|
39
|
+
* private selectionController = new SelectionController(this);
|
|
40
|
+
*
|
|
41
|
+
* constructor() {
|
|
42
|
+
* super();
|
|
43
|
+
* this.addController(this.selectionController);
|
|
44
|
+
* }
|
|
45
|
+
* }
|
|
46
|
+
*/
|
|
47
|
+
export class SelectionController {
|
|
48
|
+
/**
|
|
49
|
+
* All selection elements in the host element's root with the same
|
|
50
|
+
* `name` attribute, including the host element.
|
|
51
|
+
*/
|
|
52
|
+
get controls() {
|
|
53
|
+
const name = this.host.getAttribute('name');
|
|
54
|
+
if (!name || !this.root || !this.host.isConnected) {
|
|
55
|
+
return [this.host];
|
|
56
|
+
}
|
|
57
|
+
// Cast as unknown since there is not enough information for typescript to
|
|
58
|
+
// know that there is always at least one element (the host).
|
|
59
|
+
return Array.from(this.root.querySelectorAll(`[name="${name}"]`));
|
|
60
|
+
}
|
|
61
|
+
constructor(host) {
|
|
62
|
+
this.host = host;
|
|
63
|
+
// eslint-disable-next-line no-undef
|
|
64
|
+
this.root = null;
|
|
65
|
+
}
|
|
66
|
+
hostConnected() {
|
|
67
|
+
// eslint-disable-next-line no-undef
|
|
68
|
+
this.root = this.host.getRootNode();
|
|
69
|
+
}
|
|
70
|
+
hostDisconnected() {
|
|
71
|
+
this.root = null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=selection-controller.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const style: import("lit").CSSResult;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const style = css `
|
|
3
|
+
:host {
|
|
4
|
+
display: block;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.container {
|
|
8
|
+
overflow: hidden;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.items {
|
|
12
|
+
grid-area: 2/1/3/2;
|
|
13
|
+
padding: 16px;
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-wrap: wrap;
|
|
16
|
+
gap: 0.3rem;
|
|
17
|
+
}
|
|
18
|
+
`;
|
|
19
|
+
//# sourceMappingURL=exm-chip-input-css.js.map
|
package/.rollup.cache/root/repo/packages/exm-chip-input/dist/styles/exm-chip-input-dropdown-css.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const style: import("lit").CSSResult;
|
package/.rollup.cache/root/repo/packages/exm-chip-input/dist/styles/exm-chip-input-dropdown-css.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const style = css `
|
|
3
|
+
:host {
|
|
4
|
+
display: block;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.input-container {
|
|
8
|
+
grid-area: 2/1/3/2;
|
|
9
|
+
position: relative;
|
|
10
|
+
min-height: 32px;
|
|
11
|
+
padding: 16px;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.selected-chips {
|
|
15
|
+
display: flex;
|
|
16
|
+
flex-wrap: wrap;
|
|
17
|
+
gap: 0.3rem;
|
|
18
|
+
}
|
|
19
|
+
`;
|
|
20
|
+
//# sourceMappingURL=exm-chip-input-dropdown-css.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const sharedChipStyle: import("lit").CSSResult;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const sharedChipStyle = css `
|
|
3
|
+
.container {
|
|
4
|
+
display: grid;
|
|
5
|
+
grid-template-rows: 0px auto auto;
|
|
6
|
+
border-top-right-radius: 4px;
|
|
7
|
+
border-top-left-radius: 4px;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.container.has-label {
|
|
11
|
+
grid-template-rows: 2rem auto auto;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.background {
|
|
15
|
+
grid-area: 1/1/3/2;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.background {
|
|
19
|
+
background-color: var(--editor-code-background-color, var(--md-sys-color-surface-container-highest));
|
|
20
|
+
border-bottom: 1px solid var(--editor-border-color-focus, var(--md-sys-color-primary));
|
|
21
|
+
border-top-right-radius: inherit;
|
|
22
|
+
border-top-left-radius: inherit;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.container:hover .state-layer {
|
|
26
|
+
background-color: var(--editor-code-background-focus-color, var(--md-sys-color-on-surface-variant));
|
|
27
|
+
border-top-right-radius: inherit;
|
|
28
|
+
border-top-left-radius: inherit;
|
|
29
|
+
opacity: 0.08;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.label {
|
|
33
|
+
grid-area: 1/1/2/2;
|
|
34
|
+
font-size: 1rem;
|
|
35
|
+
padding: 0.5rem 0 0 1rem;
|
|
36
|
+
transition: all 200ms ease;
|
|
37
|
+
transform: scale(1) translateY(0px);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.label.has-focus {
|
|
41
|
+
color: var(--editor-label-focus-color, var(--md-sys-color-primary));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.label.has-focus,
|
|
45
|
+
.label.not-empty {
|
|
46
|
+
padding: 0.5rem 0 0 1rem;
|
|
47
|
+
font-size: 0.7rem;
|
|
48
|
+
transition: all 200ms ease;
|
|
49
|
+
transform: scale(1) translateY(0px);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.supporting-text {
|
|
53
|
+
grid-area: 3/1/4/2;
|
|
54
|
+
|
|
55
|
+
color: var(--md-filled-field-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));
|
|
56
|
+
display: flex;
|
|
57
|
+
font-family: var(
|
|
58
|
+
--md-filled-field-supporting-text-font,
|
|
59
|
+
var(--md-sys-typescale-body-small-font, var(--md-ref-typeface-plain, Roboto))
|
|
60
|
+
);
|
|
61
|
+
font-size: var(--md-filled-field-supporting-text-size, var(--md-sys-typescale-body-small-size, 0.75rem));
|
|
62
|
+
line-height: var(
|
|
63
|
+
--md-filled-field-supporting-text-line-height,
|
|
64
|
+
var(--md-sys-typescale-body-small-line-height, 1rem)
|
|
65
|
+
);
|
|
66
|
+
font-weight: var(
|
|
67
|
+
--md-filled-field-supporting-text-weight,
|
|
68
|
+
var(--md-sys-typescale-body-small-weight, var(--md-ref-typeface-weight-regular, 400))
|
|
69
|
+
);
|
|
70
|
+
gap: 16px;
|
|
71
|
+
justify-content: space-between;
|
|
72
|
+
padding-inline-start: var(--md-filled-field-supporting-text-leading-space, 16px);
|
|
73
|
+
padding-inline-end: var(--md-filled-field-supporting-text-trailing-space, 16px);
|
|
74
|
+
padding-top: var(--md-filled-field-supporting-text-top-space, 4px);
|
|
75
|
+
}
|
|
76
|
+
`;
|
|
77
|
+
//# sourceMappingURL=exm-chips-shared-css.js.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2023 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { Validator } from '@material/web/labs/behaviors/validators/validator.js';
|
|
7
|
+
/**
|
|
8
|
+
* Constraint validation properties for a checkbox.
|
|
9
|
+
*/
|
|
10
|
+
export interface ChipState {
|
|
11
|
+
/**
|
|
12
|
+
* Whether the checkbox is checked.
|
|
13
|
+
*/
|
|
14
|
+
readonly checked: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Whether the checkbox is required.
|
|
17
|
+
*/
|
|
18
|
+
readonly required: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Radio constraint validation properties for a single radio and its siblings.
|
|
22
|
+
*/
|
|
23
|
+
export type ChipGroupState = readonly [ChipState, ...ChipState[]];
|
|
24
|
+
/**
|
|
25
|
+
* A validator that provides constraint validation that emulates
|
|
26
|
+
* `<input type="checkbox">` validation.
|
|
27
|
+
*/
|
|
28
|
+
export declare class ChipValidator extends Validator<ChipGroupState> {
|
|
29
|
+
private radioElement?;
|
|
30
|
+
protected computeValidity(states: ChipGroupState): {
|
|
31
|
+
validity: {
|
|
32
|
+
valueMissing: boolean;
|
|
33
|
+
};
|
|
34
|
+
validationMessage: string;
|
|
35
|
+
};
|
|
36
|
+
protected equals(prevGroup: ChipGroupState, nextGroup: ChipGroupState): boolean;
|
|
37
|
+
protected copy(states: ChipGroupState): ChipGroupState;
|
|
38
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2023 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { Validator } from '@material/web/labs/behaviors/validators/validator.js';
|
|
7
|
+
/**
|
|
8
|
+
* A validator that provides constraint validation that emulates
|
|
9
|
+
* `<input type="checkbox">` validation.
|
|
10
|
+
*/
|
|
11
|
+
export class ChipValidator extends Validator {
|
|
12
|
+
computeValidity(states) {
|
|
13
|
+
if (!this.radioElement) {
|
|
14
|
+
// Lazily create the radio element
|
|
15
|
+
this.radioElement = document.createElement('input');
|
|
16
|
+
this.radioElement.type = 'radio';
|
|
17
|
+
// A name is required for validation to run
|
|
18
|
+
this.radioElement.name = 'group';
|
|
19
|
+
}
|
|
20
|
+
let isRequired = false;
|
|
21
|
+
let isChecked = false;
|
|
22
|
+
for (const { checked, required } of states) {
|
|
23
|
+
if (required) {
|
|
24
|
+
isRequired = true;
|
|
25
|
+
}
|
|
26
|
+
if (checked) {
|
|
27
|
+
isChecked = true;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
// Firefox v119 doesn't compute grouped radio validation correctly while
|
|
31
|
+
// they are detached from the DOM, which is why we don't render multiple
|
|
32
|
+
// virtual <input>s. Instead, we can check the required/checked states and
|
|
33
|
+
// grab the i18n'd validation message if the value is missing.
|
|
34
|
+
this.radioElement.checked = isChecked;
|
|
35
|
+
this.radioElement.required = isRequired;
|
|
36
|
+
return {
|
|
37
|
+
validity: {
|
|
38
|
+
valueMissing: isRequired && !isChecked,
|
|
39
|
+
},
|
|
40
|
+
validationMessage: this.radioElement.validationMessage,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
equals(prevGroup, nextGroup) {
|
|
44
|
+
if (prevGroup.length !== nextGroup.length) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
for (let i = 0; i < prevGroup.length; i++) {
|
|
48
|
+
const prev = prevGroup[i];
|
|
49
|
+
const next = nextGroup[i];
|
|
50
|
+
if (prev.checked !== next.checked || prev.required !== next.required) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
copy(states) {
|
|
57
|
+
// Cast as unknown since typescript does not have enough information to
|
|
58
|
+
// infer that the array always has at least one element.
|
|
59
|
+
return states.map(({ checked, required }) => ({
|
|
60
|
+
checked,
|
|
61
|
+
required,
|
|
62
|
+
}));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=chip-validator.js.map
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { __decorate } from
|
|
2
|
-
import { LitElement, html
|
|
3
|
-
import {
|
|
1
|
+
import { __decorate } from 'tslib';
|
|
2
|
+
import { css, LitElement, html } from 'lit';
|
|
3
|
+
import { property, customElement } from 'lit/decorators.js';
|
|
4
|
+
|
|
4
5
|
let DropdownContainer = class DropdownContainer extends LitElement {
|
|
5
6
|
constructor() {
|
|
6
7
|
super(...arguments);
|
|
@@ -35,5 +36,6 @@ __decorate([
|
|
|
35
36
|
DropdownContainer = __decorate([
|
|
36
37
|
customElement('dropdown-container')
|
|
37
38
|
], DropdownContainer);
|
|
39
|
+
|
|
38
40
|
export { DropdownContainer };
|
|
39
|
-
//# sourceMappingURL=dropdown-container.js.map
|
|
41
|
+
//# sourceMappingURL=dropdown-container.js.map
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { __decorate } from
|
|
1
|
+
import { __decorate } from 'tslib';
|
|
2
2
|
import { customElement } from 'lit/decorators/custom-element.js';
|
|
3
3
|
import '@material/web/iconbutton/icon-button.js';
|
|
4
4
|
import '@material/web/button/text-button.js';
|
|
@@ -7,12 +7,13 @@ import '@material/web/icon/icon.js';
|
|
|
7
7
|
import '@material/web/menu/menu.js';
|
|
8
8
|
import './dropdown/dropdown-container.js';
|
|
9
9
|
import { ChipSet } from '@material/web/chips/internal/chip-set.js';
|
|
10
|
-
import {
|
|
10
|
+
import { nothing, html } from 'lit';
|
|
11
11
|
import { property, state } from 'lit/decorators.js';
|
|
12
12
|
import { repeat } from 'lit/directives/repeat.js';
|
|
13
13
|
import { style } from './styles/exm-chip-input-dropdown-css.js';
|
|
14
14
|
import { sharedChipStyle } from './styles/exm-chips-shared-css.js';
|
|
15
15
|
import { classMap } from 'lit/directives/class-map.js';
|
|
16
|
+
|
|
16
17
|
/**
|
|
17
18
|
*
|
|
18
19
|
* @final
|
|
@@ -149,5 +150,6 @@ __decorate([
|
|
|
149
150
|
ExmChipInputDropdown = __decorate([
|
|
150
151
|
customElement('exm-chip-input-dropdown')
|
|
151
152
|
], ExmChipInputDropdown);
|
|
153
|
+
|
|
152
154
|
export { ExmChipInputDropdown };
|
|
153
|
-
//# sourceMappingURL=exm-chip-input-dropdown.js.map
|
|
155
|
+
//# sourceMappingURL=exm-chip-input-dropdown.js.map
|
package/dist/exm-chip-input.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import { __decorate } from
|
|
1
|
+
import { __decorate } from 'tslib';
|
|
2
2
|
import { customElement } from 'lit/decorators/custom-element.js';
|
|
3
3
|
import { style } from './styles/exm-chip-input-css.js';
|
|
4
4
|
import { ChipSet } from '@material/web/chips/internal/chip-set.js';
|
|
5
5
|
import { styles } from '@material/web/chips/internal/chip-set-styles.js';
|
|
6
|
-
import {
|
|
6
|
+
import { nothing, html } from 'lit';
|
|
7
7
|
import { property, state } from 'lit/decorators.js';
|
|
8
8
|
import { sharedChipStyle } from './styles/exm-chips-shared-css.js';
|
|
9
9
|
import { classMap } from 'lit/directives/class-map.js';
|
|
10
|
+
|
|
10
11
|
/**
|
|
11
12
|
*
|
|
12
13
|
* @final
|
|
@@ -72,5 +73,6 @@ __decorate([
|
|
|
72
73
|
ExmChipInput = __decorate([
|
|
73
74
|
customElement('exm-chip-input')
|
|
74
75
|
], ExmChipInput);
|
|
76
|
+
|
|
75
77
|
export { ExmChipInput };
|
|
76
|
-
//# sourceMappingURL=exm-chip-input.js.map
|
|
78
|
+
//# sourceMappingURL=exm-chip-input.js.map
|
package/dist/exm-chip.js
CHANGED
|
@@ -1,21 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { styles as elevatedStyles } from '@material/web/chips/internal/elevated-styles.js';
|
|
1
|
+
import { __decorate } from 'tslib';
|
|
2
|
+
import { property, query, customElement } from 'lit/decorators.js';
|
|
3
|
+
import { styles as styles$1 } from '@material/web/chips/internal/elevated-styles.js';
|
|
5
4
|
import { FilterChip } from '@material/web/chips/internal/filter-chip.js';
|
|
6
|
-
import { styles } from '@material/web/chips/internal/filter-styles.js';
|
|
7
|
-
import { styles as
|
|
8
|
-
import { styles
|
|
9
|
-
import { styles as
|
|
5
|
+
import { styles as styles$4 } from '@material/web/chips/internal/filter-styles.js';
|
|
6
|
+
import { styles as styles$3 } from '@material/web/chips/internal/selectable-styles.js';
|
|
7
|
+
import { styles } from '@material/web/chips/internal/shared-styles.js';
|
|
8
|
+
import { styles as styles$2 } from '@material/web/chips/internal/trailing-icon-styles.js';
|
|
10
9
|
import { redispatchEvent } from '@material/web/internal/events/redispatch-event.js';
|
|
11
|
-
import { createValidator, getValidityAnchor
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
10
|
+
import { mixinConstraintValidation, createValidator, getValidityAnchor } from '@material/web/labs/behaviors/constraint-validation.js';
|
|
11
|
+
import { mixinFormAssociated, getFormValue, getFormState } from '@material/web/labs/behaviors/form-associated.js';
|
|
12
|
+
import { mixinElementInternals, internals } from '@material/web/labs/behaviors/element-internals.js';
|
|
14
13
|
import { mixinFocusable } from '@material/web/labs/behaviors/focusable.js';
|
|
15
14
|
import { ChipValidator } from './validator/chip-validator.js';
|
|
16
15
|
import { observer } from '@exmg/lit-base';
|
|
17
16
|
import { SelectionController } from './selection-controller.js';
|
|
18
|
-
import {
|
|
17
|
+
import { nothing, html } from 'lit';
|
|
18
|
+
|
|
19
|
+
var _a;
|
|
19
20
|
const CHECKED = Symbol('checked');
|
|
20
21
|
// Separate variable needed for closure.
|
|
21
22
|
const FilterChipBaseClass = mixinConstraintValidation(mixinFormAssociated(mixinElementInternals(mixinFocusable(FilterChip))));
|
|
@@ -120,7 +121,7 @@ let ExmChip = class ExmChip extends FilterChipBaseClass {
|
|
|
120
121
|
return this.container;
|
|
121
122
|
}
|
|
122
123
|
};
|
|
123
|
-
ExmChip.styles = [
|
|
124
|
+
ExmChip.styles = [styles, styles$1, styles$2, styles$3, styles$4];
|
|
124
125
|
__decorate([
|
|
125
126
|
property({ type: Boolean })
|
|
126
127
|
], ExmChip.prototype, "removable", void 0);
|
|
@@ -145,5 +146,6 @@ __decorate([
|
|
|
145
146
|
ExmChip = __decorate([
|
|
146
147
|
customElement('exm-chip')
|
|
147
148
|
], ExmChip);
|
|
149
|
+
|
|
148
150
|
export { ExmChip };
|
|
149
|
-
//# sourceMappingURL=exm-chip.js.map
|
|
151
|
+
//# sourceMappingURL=exm-chip.js.map
|
package/dist/index.js
CHANGED
|
@@ -2,4 +2,4 @@ export { ExmChipInput } from './exm-chip-input.js';
|
|
|
2
2
|
export { ExmChip } from './exm-chip.js';
|
|
3
3
|
export { ExmChipInputDropdown } from './exm-chip-input-dropdown.js';
|
|
4
4
|
export { style as chipInputStyles } from './styles/exm-chip-input-css.js';
|
|
5
|
-
//# sourceMappingURL=index.js.map
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
* }
|
|
45
45
|
* }
|
|
46
46
|
*/
|
|
47
|
-
|
|
47
|
+
class SelectionController {
|
|
48
48
|
/**
|
|
49
49
|
* All selection elements in the host element's root with the same
|
|
50
50
|
* `name` attribute, including the host element.
|
|
@@ -71,4 +71,6 @@ export class SelectionController {
|
|
|
71
71
|
this.root = null;
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
|
-
|
|
74
|
+
|
|
75
|
+
export { SelectionController };
|
|
76
|
+
//# sourceMappingURL=selection-controller.js.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { css } from 'lit';
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
const style = css `
|
|
3
4
|
:host {
|
|
4
5
|
display: block;
|
|
5
6
|
}
|
|
@@ -16,4 +17,6 @@ export const style = css `
|
|
|
16
17
|
gap: 0.3rem;
|
|
17
18
|
}
|
|
18
19
|
`;
|
|
19
|
-
|
|
20
|
+
|
|
21
|
+
export { style };
|
|
22
|
+
//# sourceMappingURL=exm-chip-input-css.js.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { css } from 'lit';
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
const style = css `
|
|
3
4
|
:host {
|
|
4
5
|
display: block;
|
|
5
6
|
}
|
|
@@ -17,4 +18,6 @@ export const style = css `
|
|
|
17
18
|
gap: 0.3rem;
|
|
18
19
|
}
|
|
19
20
|
`;
|
|
20
|
-
|
|
21
|
+
|
|
22
|
+
export { style };
|
|
23
|
+
//# sourceMappingURL=exm-chip-input-dropdown-css.js.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { css } from 'lit';
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
const sharedChipStyle = css `
|
|
3
4
|
.container {
|
|
4
5
|
display: grid;
|
|
5
6
|
grid-template-rows: 0px auto auto;
|
|
@@ -74,4 +75,6 @@ export const sharedChipStyle = css `
|
|
|
74
75
|
padding-top: var(--md-filled-field-supporting-text-top-space, 4px);
|
|
75
76
|
}
|
|
76
77
|
`;
|
|
77
|
-
|
|
78
|
+
|
|
79
|
+
export { sharedChipStyle };
|
|
80
|
+
//# sourceMappingURL=exm-chips-shared-css.js.map
|
|
@@ -1,14 +1,15 @@
|
|
|
1
|
+
import { Validator } from '@material/web/labs/behaviors/validators/validator.js';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* @license
|
|
3
5
|
* Copyright 2023 Google LLC
|
|
4
6
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
7
|
*/
|
|
6
|
-
import { Validator } from '@material/web/labs/behaviors/validators/validator.js';
|
|
7
8
|
/**
|
|
8
9
|
* A validator that provides constraint validation that emulates
|
|
9
10
|
* `<input type="checkbox">` validation.
|
|
10
11
|
*/
|
|
11
|
-
|
|
12
|
+
class ChipValidator extends Validator {
|
|
12
13
|
computeValidity(states) {
|
|
13
14
|
if (!this.radioElement) {
|
|
14
15
|
// Lazily create the radio element
|
|
@@ -62,4 +63,6 @@ export class ChipValidator extends Validator {
|
|
|
62
63
|
}));
|
|
63
64
|
}
|
|
64
65
|
}
|
|
65
|
-
|
|
66
|
+
|
|
67
|
+
export { ChipValidator };
|
|
68
|
+
//# sourceMappingURL=chip-validator.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exmg/exm-chip-input",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -39,5 +39,5 @@
|
|
|
39
39
|
"publishConfig": {
|
|
40
40
|
"access": "public"
|
|
41
41
|
},
|
|
42
|
-
"gitHead": "
|
|
42
|
+
"gitHead": "b5f4ed4f41d79e3cce85dc0c44181ef4413d7458"
|
|
43
43
|
}
|