@vaadin/field-base 22.0.0-alpha5 → 22.0.0-alpha9
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/index.d.ts +7 -15
- package/index.js +7 -15
- package/package.json +24 -18
- package/src/aria-label-controller.d.ts +11 -0
- package/src/aria-label-controller.js +53 -0
- package/src/checked-mixin.d.ts +21 -0
- package/src/checked-mixin.js +54 -0
- package/src/delegate-focus-mixin.d.ts +2 -2
- package/src/delegate-focus-mixin.js +150 -133
- package/src/delegate-state-mixin.d.ts +1 -1
- package/src/delegate-state-mixin.js +100 -88
- package/src/field-mixin.d.ts +39 -0
- package/src/field-mixin.js +317 -0
- package/src/input-constraints-mixin.d.ts +4 -2
- package/src/input-constraints-mixin.js +107 -64
- package/src/input-control-mixin.d.ts +52 -0
- package/src/input-control-mixin.js +170 -0
- package/src/input-controller.d.ts +11 -0
- package/src/input-controller.js +35 -0
- package/src/input-field-mixin.d.ts +2 -16
- package/src/input-field-mixin.js +125 -80
- package/src/input-mixin.d.ts +1 -1
- package/src/input-mixin.js +156 -145
- package/src/label-mixin.d.ts +2 -2
- package/src/label-mixin.js +73 -60
- package/src/pattern-mixin.js +9 -9
- package/src/shadow-focus-mixin.d.ts +21 -0
- package/src/shadow-focus-mixin.js +87 -0
- package/src/slot-controller.d.ts +8 -0
- package/src/slot-controller.js +36 -0
- package/src/slot-label-mixin.d.ts +20 -0
- package/src/slot-label-mixin.js +38 -0
- package/src/slot-styles-mixin.js +38 -31
- package/src/slot-target-mixin.d.ts +32 -0
- package/src/slot-target-mixin.js +110 -0
- package/src/styles/clear-button-styles.d.ts +8 -0
- package/src/styles/clear-button-styles.js +21 -0
- package/src/styles/field-shared-styles.d.ts +8 -0
- package/src/styles/field-shared-styles.js +29 -0
- package/src/styles/input-field-container-styles.d.ts +8 -0
- package/src/styles/input-field-container-styles.js +16 -0
- package/src/styles/input-field-shared-styles.d.ts +8 -0
- package/src/styles/input-field-shared-styles.js +10 -0
- package/src/text-area-controller.d.ts +11 -0
- package/src/text-area-controller.js +38 -0
- package/src/validate-mixin.d.ts +1 -9
- package/src/validate-mixin.js +43 -118
- package/src/active-mixin.d.ts +0 -26
- package/src/active-mixin.js +0 -106
- package/src/aria-label-mixin.d.ts +0 -20
- package/src/aria-label-mixin.js +0 -71
- package/src/char-length-mixin.d.ts +0 -30
- package/src/char-length-mixin.js +0 -42
- package/src/clear-button-mixin.d.ts +0 -28
- package/src/clear-button-mixin.js +0 -82
- package/src/delegate-input-state-mixin.d.ts +0 -43
- package/src/delegate-input-state-mixin.js +0 -63
- package/src/disabled-mixin.d.ts +0 -23
- package/src/disabled-mixin.js +0 -60
- package/src/field-aria-mixin.d.ts +0 -24
- package/src/field-aria-mixin.js +0 -61
- package/src/focus-mixin.d.ts +0 -33
- package/src/focus-mixin.js +0 -104
- package/src/helper-text-mixin.d.ts +0 -24
- package/src/helper-text-mixin.js +0 -144
- package/src/input-slot-mixin.d.ts +0 -26
- package/src/input-slot-mixin.js +0 -71
- package/src/keyboard-mixin.d.ts +0 -32
- package/src/keyboard-mixin.js +0 -51
- package/src/slot-mixin.d.ts +0 -23
- package/src/slot-mixin.js +0 -49
- package/src/tabindex-mixin.d.ts +0 -29
- package/src/tabindex-mixin.js +0 -78
- package/src/text-area-slot-mixin.d.ts +0 -21
- package/src/text-area-slot-mixin.js +0 -56
- package/src/text-field-mixin.d.ts +0 -21
- package/src/text-field-mixin.js +0 -17
package/src/label-mixin.js
CHANGED
|
@@ -4,77 +4,90 @@
|
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
|
|
7
|
-
import { SlotMixin } from '
|
|
7
|
+
import { SlotMixin } from '@vaadin/component-base/src/slot-mixin.js';
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
9
|
+
/**
|
|
10
|
+
* A mixin to provide label via corresponding property or named slot.
|
|
11
|
+
*
|
|
12
|
+
* @polymerMixin
|
|
13
|
+
* @mixes SlotMixin
|
|
14
|
+
*/
|
|
15
|
+
export const LabelMixin = dedupingMixin(
|
|
16
|
+
(superclass) =>
|
|
17
|
+
class LabelMixinClass extends SlotMixin(superclass) {
|
|
18
|
+
static get properties() {
|
|
19
|
+
return {
|
|
20
|
+
/**
|
|
21
|
+
* The label text for the input node.
|
|
22
|
+
* When no light dom defined via [slot=label], this value will be used.
|
|
23
|
+
*/
|
|
24
|
+
label: {
|
|
25
|
+
type: String,
|
|
26
|
+
observer: '_labelChanged'
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
23
30
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
/** @protected */
|
|
32
|
+
get slots() {
|
|
33
|
+
return {
|
|
34
|
+
...super.slots,
|
|
35
|
+
label: () => {
|
|
36
|
+
const label = document.createElement('label');
|
|
37
|
+
label.textContent = this.label;
|
|
38
|
+
return label;
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
34
42
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
43
|
+
/** @protected */
|
|
44
|
+
get _labelNode() {
|
|
45
|
+
return this._getDirectSlotChild('label');
|
|
46
|
+
}
|
|
39
47
|
|
|
40
|
-
|
|
41
|
-
|
|
48
|
+
constructor() {
|
|
49
|
+
super();
|
|
42
50
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
51
|
+
// Ensure every instance has unique ID
|
|
52
|
+
const uniqueId = (LabelMixinClass._uniqueLabelId = 1 + LabelMixinClass._uniqueLabelId || 0);
|
|
53
|
+
this._labelId = `label-${this.localName}-${uniqueId}`;
|
|
47
54
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
55
|
+
/**
|
|
56
|
+
* @type {MutationObserver}
|
|
57
|
+
* @private
|
|
58
|
+
*/
|
|
59
|
+
this.__labelNodeObserver = new MutationObserver(() => {
|
|
60
|
+
this._toggleHasLabelAttribute();
|
|
61
|
+
});
|
|
62
|
+
}
|
|
51
63
|
|
|
52
|
-
|
|
53
|
-
|
|
64
|
+
/** @protected */
|
|
65
|
+
ready() {
|
|
66
|
+
super.ready();
|
|
54
67
|
|
|
55
|
-
this.
|
|
56
|
-
|
|
57
|
-
|
|
68
|
+
if (this._labelNode) {
|
|
69
|
+
this._labelNode.id = this._labelId;
|
|
70
|
+
this._toggleHasLabelAttribute();
|
|
58
71
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
const label = this._labelNode.textContent;
|
|
62
|
-
if (label !== this.label) {
|
|
63
|
-
this.label = label;
|
|
72
|
+
this.__labelNodeObserver.observe(this._labelNode, { childList: true });
|
|
73
|
+
}
|
|
64
74
|
}
|
|
65
|
-
}
|
|
66
75
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
76
|
+
/** @protected */
|
|
77
|
+
_labelChanged(label) {
|
|
78
|
+
if (this._labelNode) {
|
|
79
|
+
this._labelNode.textContent = label;
|
|
80
|
+
this._toggleHasLabelAttribute();
|
|
81
|
+
}
|
|
71
82
|
}
|
|
72
83
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
84
|
+
/** @protected */
|
|
85
|
+
_toggleHasLabelAttribute() {
|
|
86
|
+
if (this._labelNode) {
|
|
87
|
+
const hasLabel = this._labelNode.children.length > 0 || this._labelNode.textContent.trim() !== '';
|
|
76
88
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
89
|
+
this.toggleAttribute('has-label', hasLabel);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
);
|
package/src/pattern-mixin.js
CHANGED
|
@@ -3,12 +3,17 @@
|
|
|
3
3
|
* Copyright (c) 2021 Vaadin Ltd.
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
|
-
import { Debouncer } from '@
|
|
7
|
-
import { timeOut } from '@
|
|
8
|
-
import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
|
|
6
|
+
import { Debouncer } from '@vaadin/component-base/src/debounce.js';
|
|
7
|
+
import { timeOut } from '@vaadin/component-base/src/async.js';
|
|
9
8
|
import { InputConstraintsMixin } from './input-constraints-mixin.js';
|
|
10
9
|
|
|
11
|
-
|
|
10
|
+
/**
|
|
11
|
+
* A mixin to provide `pattern` and `preventInvalidInput` properties.
|
|
12
|
+
*
|
|
13
|
+
* @polymerMixin
|
|
14
|
+
* @mixes InputConstraintsMixin
|
|
15
|
+
*/
|
|
16
|
+
export const PatternMixin = (superclass) =>
|
|
12
17
|
class PatternMixinClass extends InputConstraintsMixin(superclass) {
|
|
13
18
|
static get properties() {
|
|
14
19
|
return {
|
|
@@ -65,8 +70,3 @@ const PatternMixinImplementation = (superclass) =>
|
|
|
65
70
|
super._onInput(event);
|
|
66
71
|
}
|
|
67
72
|
};
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* A mixin to provide `pattern` and `preventInvalidInput` properties.
|
|
71
|
-
*/
|
|
72
|
-
export const PatternMixin = dedupingMixin(PatternMixinImplementation);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2021 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { KeyboardMixin } from '@vaadin/component-base/src/keyboard-mixin.js';
|
|
7
|
+
import { TabindexMixin } from '@vaadin/component-base/src/tabindex-mixin.js';
|
|
8
|
+
import { DelegateFocusMixin } from './delegate-focus-mixin.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A mixin to forward focus to an element in the shadow DOM.
|
|
12
|
+
*/
|
|
13
|
+
declare function ShadowFocusMixin<T extends new (...args: any[]) => {}>(base: T): T & ShadowFocusMixinConstructor;
|
|
14
|
+
|
|
15
|
+
interface ShadowFocusMixinConstructor {
|
|
16
|
+
new (...args: any[]): ShadowFocusMixin;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface ShadowFocusMixin extends KeyboardMixin, TabindexMixin, DelegateFocusMixin {}
|
|
20
|
+
|
|
21
|
+
export { ShadowFocusMixinConstructor, ShadowFocusMixin };
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2021 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { KeyboardMixin } from '@vaadin/component-base/src/keyboard-mixin.js';
|
|
7
|
+
import { TabindexMixin } from '@vaadin/component-base/src/tabindex-mixin.js';
|
|
8
|
+
import { DelegateFocusMixin } from './delegate-focus-mixin.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A mixin to forward focus to an element in the shadow DOM.
|
|
12
|
+
*
|
|
13
|
+
* @polymerMixin
|
|
14
|
+
* @mixes DelegateFocusMixin
|
|
15
|
+
* @mixes KeyboardMixin
|
|
16
|
+
* @mixes TabindexMixin
|
|
17
|
+
*/
|
|
18
|
+
export const ShadowFocusMixin = (superClass) =>
|
|
19
|
+
class ShadowFocusMixinClass extends TabindexMixin(DelegateFocusMixin(KeyboardMixin(superClass))) {
|
|
20
|
+
/**
|
|
21
|
+
* Override an event listener from `KeyboardMixin`
|
|
22
|
+
* to prevent setting `focused` on Shift Tab.
|
|
23
|
+
* @param {KeyboardEvent} event
|
|
24
|
+
* @protected
|
|
25
|
+
* @override
|
|
26
|
+
*/
|
|
27
|
+
_onKeyDown(event) {
|
|
28
|
+
super._onKeyDown(event);
|
|
29
|
+
|
|
30
|
+
// When focus moves with Shift + Tab, do not mark host as focused.
|
|
31
|
+
// The flag set here will be later used in focusin event listener.
|
|
32
|
+
if (!event.defaultPrevented && event.keyCode === 9 && event.shiftKey) {
|
|
33
|
+
this._isShiftTabbing = true;
|
|
34
|
+
HTMLElement.prototype.focus.apply(this);
|
|
35
|
+
this._setFocused(false);
|
|
36
|
+
setTimeout(() => (this._isShiftTabbing = false), 0);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Override method inherited from `FocusMixin`
|
|
42
|
+
* to support focusElement in Shadow DOM.
|
|
43
|
+
* @param {Event} event
|
|
44
|
+
* @return {boolean}
|
|
45
|
+
* @protected
|
|
46
|
+
* @override
|
|
47
|
+
*/
|
|
48
|
+
_shouldSetFocus(event) {
|
|
49
|
+
if (!this.disabled && this.focusElement) {
|
|
50
|
+
const path = event.composedPath();
|
|
51
|
+
|
|
52
|
+
// When focus moves from outside and not with Shift + Tab, delegate it to focusElement.
|
|
53
|
+
if (path[0] === this && !this.contains(event.relatedTarget) && !this._isShiftTabbing) {
|
|
54
|
+
this.focusElement.focus();
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (path.includes(this.focusElement)) {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Override an observer from `TabindexMixin`.
|
|
68
|
+
* Do not call super to remove tabindex attribute
|
|
69
|
+
* from host when disabled by setting undefined.
|
|
70
|
+
* @param {string} tabindex
|
|
71
|
+
* @protected
|
|
72
|
+
* @override
|
|
73
|
+
*/
|
|
74
|
+
_tabindexChanged(tabindex) {
|
|
75
|
+
if (tabindex !== undefined) {
|
|
76
|
+
this.focusElement.tabIndex = tabindex;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (this.disabled && tabindex) {
|
|
80
|
+
// If tabindex attribute was changed while component was disabled
|
|
81
|
+
if (tabindex !== -1) {
|
|
82
|
+
this.__lastTabIndex = tabindex;
|
|
83
|
+
}
|
|
84
|
+
this.tabindex = undefined;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2021 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { ReactiveController } from 'lit';
|
|
7
|
+
|
|
8
|
+
export class SlotController implements ReactiveController {}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2021 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
export class SlotController {
|
|
7
|
+
constructor(host, [slotName, slotFactory, slotInitializer]) {
|
|
8
|
+
this.host = host;
|
|
9
|
+
this.slotName = slotName;
|
|
10
|
+
this.slotFactory = slotFactory;
|
|
11
|
+
this.slotInitializer = slotInitializer;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
hostConnected() {
|
|
15
|
+
if (!this.__initialized) {
|
|
16
|
+
const { host, slotName, slotFactory } = this;
|
|
17
|
+
|
|
18
|
+
const slotted = host.querySelector(`[slot=${slotName}]`);
|
|
19
|
+
|
|
20
|
+
if (!slotted) {
|
|
21
|
+
const slotContent = slotFactory(host);
|
|
22
|
+
if (slotContent instanceof Element) {
|
|
23
|
+
slotContent.setAttribute('slot', slotName);
|
|
24
|
+
host.appendChild(slotContent);
|
|
25
|
+
this.__slotContent = slotContent;
|
|
26
|
+
}
|
|
27
|
+
} else {
|
|
28
|
+
this.__slotContent = slotted;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
this.slotInitializer(host, this.__slotContent);
|
|
32
|
+
|
|
33
|
+
this.__initialized = true;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2021 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { LabelMixin } from './label-mixin.js';
|
|
7
|
+
import { SlotTargetMixin } from './slot-target-mixin.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A mixin to forward any content from the default slot to the label node.
|
|
11
|
+
*/
|
|
12
|
+
declare function SlotLabelMixin<T extends new (...args: any[]) => {}>(base: T): T & SlotLabelMixinConstructor;
|
|
13
|
+
|
|
14
|
+
interface SlotLabelMixinConstructor {
|
|
15
|
+
new (...args: any[]): SlotLabelMixin;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface SlotLabelMixin extends SlotTargetMixin, LabelMixin {}
|
|
19
|
+
|
|
20
|
+
export { SlotLabelMixinConstructor, SlotLabelMixin };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2021 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
|
|
7
|
+
import { LabelMixin } from './label-mixin.js';
|
|
8
|
+
import { SlotTargetMixin } from './slot-target-mixin.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A mixin to forward any content from the default slot to the label node.
|
|
12
|
+
*
|
|
13
|
+
* @polymerMixin
|
|
14
|
+
* @mixes LabelMixin
|
|
15
|
+
* @mixes SlotTargetMixin
|
|
16
|
+
*/
|
|
17
|
+
export const SlotLabelMixin = dedupingMixin(
|
|
18
|
+
(superclass) =>
|
|
19
|
+
class SlotLabelMixinClass extends SlotTargetMixin(LabelMixin(superclass)) {
|
|
20
|
+
/** @protected */
|
|
21
|
+
get _slotTarget() {
|
|
22
|
+
return this._labelNode;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** @protected */
|
|
26
|
+
ready() {
|
|
27
|
+
super.ready();
|
|
28
|
+
|
|
29
|
+
if (this._labelNode) {
|
|
30
|
+
// The default slot's content is moved to the label node
|
|
31
|
+
// only after `LabelMixin` is initialized which means
|
|
32
|
+
// we should manually toggle the `has-label` attribute
|
|
33
|
+
// respecting the new label content.
|
|
34
|
+
this._toggleHasLabelAttribute();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
);
|
package/src/slot-styles-mixin.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2021 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
1
6
|
import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
|
|
2
7
|
|
|
3
8
|
const stylesMap = new WeakMap();
|
|
@@ -31,39 +36,41 @@ function insertStyles(styles, root) {
|
|
|
31
36
|
}
|
|
32
37
|
}
|
|
33
38
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
39
|
+
/**
|
|
40
|
+
* Mixin to insert styles into the outer scope to handle slotted components.
|
|
41
|
+
* This is useful e.g. to hide native `<input type="number">` controls.
|
|
42
|
+
*
|
|
43
|
+
* @polymerMixin
|
|
44
|
+
*/
|
|
45
|
+
export const SlotStylesMixin = dedupingMixin(
|
|
46
|
+
(superclass) =>
|
|
47
|
+
class SlotStylesMixinClass extends superclass {
|
|
48
|
+
/**
|
|
49
|
+
* List of styles to insert into root.
|
|
50
|
+
* @protected
|
|
51
|
+
*/
|
|
52
|
+
get slotStyles() {
|
|
53
|
+
return {};
|
|
54
|
+
}
|
|
43
55
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
56
|
+
/** @protected */
|
|
57
|
+
connectedCallback() {
|
|
58
|
+
super.connectedCallback();
|
|
47
59
|
|
|
48
|
-
|
|
49
|
-
|
|
60
|
+
this.__applySlotStyles();
|
|
61
|
+
}
|
|
50
62
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
63
|
+
/** @private */
|
|
64
|
+
__applySlotStyles() {
|
|
65
|
+
const root = this.getRootNode();
|
|
66
|
+
const rootStyles = getRootStyles(root);
|
|
55
67
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
68
|
+
this.slotStyles.forEach((styles) => {
|
|
69
|
+
if (!rootStyles.has(styles)) {
|
|
70
|
+
insertStyles(styles, root);
|
|
71
|
+
rootStyles.add(styles);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
62
75
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Mixin to insert styles into the outer scope to handle slotted components.
|
|
67
|
-
* This is useful e.g. to hide native `<input type="number">` controls.
|
|
68
|
-
*/
|
|
69
|
-
export const SlotStylesMixin = dedupingMixin(SlotStylesMixinImplementation);
|
|
76
|
+
);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2021 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A mixin to copy the content from a source slot to a target element.
|
|
9
|
+
*/
|
|
10
|
+
declare function SlotTargetMixin<T extends new (...args: any[]) => {}>(base: T): T & SlotTargetMixinConstructor;
|
|
11
|
+
|
|
12
|
+
interface SlotTargetMixinConstructor {
|
|
13
|
+
new (...args: any[]): SlotTargetMixin;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface SlotTargetMixin {
|
|
17
|
+
/**
|
|
18
|
+
* A reference to the source slot from which the content is copied to the target element.
|
|
19
|
+
*
|
|
20
|
+
* @protected
|
|
21
|
+
*/
|
|
22
|
+
_sourceSlot: HTMLSlotElement;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* A reference to the target element to which the content is copied from the source slot.
|
|
26
|
+
*
|
|
27
|
+
* @protected
|
|
28
|
+
*/
|
|
29
|
+
_slotTarget: HTMLElement;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export { SlotTargetMixinConstructor, SlotTargetMixin };
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2021 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { dedupingMixin } from '@polymer/polymer/lib/utils/mixin.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A mixin to copy the content from a source slot to a target element.
|
|
10
|
+
*
|
|
11
|
+
* @polymerMixin
|
|
12
|
+
*/
|
|
13
|
+
export const SlotTargetMixin = dedupingMixin(
|
|
14
|
+
(superclass) =>
|
|
15
|
+
class SlotTargetMixinClass extends superclass {
|
|
16
|
+
/** @protected */
|
|
17
|
+
ready() {
|
|
18
|
+
super.ready();
|
|
19
|
+
|
|
20
|
+
if (this._sourceSlot) {
|
|
21
|
+
this.__sourceSlotObserver = new MutationObserver(() => this.__checkAndCopyNodesToSlotTarget());
|
|
22
|
+
|
|
23
|
+
this.__checkAndCopyNodesToSlotTarget();
|
|
24
|
+
|
|
25
|
+
this._sourceSlot.addEventListener('slotchange', () => {
|
|
26
|
+
this.__checkAndCopyNodesToSlotTarget();
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* A reference to the source slot from which the nodes are copied to the target element.
|
|
33
|
+
*
|
|
34
|
+
* @type {HTMLSlotElement | null}
|
|
35
|
+
* @protected
|
|
36
|
+
*/
|
|
37
|
+
get _sourceSlot() {
|
|
38
|
+
console.warn(`Please implement the '_sourceSlot' property in <${this.localName}>`);
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* A reference to the target element to which the nodes are copied from the source slot.
|
|
44
|
+
*
|
|
45
|
+
* @type {HTMLElement | null}
|
|
46
|
+
* @protected
|
|
47
|
+
*/
|
|
48
|
+
get _slotTarget() {
|
|
49
|
+
console.warn(`Please implement the '_slotTarget' property in <${this.localName}>`);
|
|
50
|
+
return null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Copies every node from the source slot to the target element
|
|
55
|
+
* once the source slot' content is changed.
|
|
56
|
+
*
|
|
57
|
+
* @private
|
|
58
|
+
*/
|
|
59
|
+
__checkAndCopyNodesToSlotTarget() {
|
|
60
|
+
this.__sourceSlotObserver.disconnect();
|
|
61
|
+
|
|
62
|
+
if (!this._slotTarget) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Remove any existing clones from the slot target
|
|
67
|
+
if (this.__slotTargetClones) {
|
|
68
|
+
this.__slotTargetClones.forEach((node) => {
|
|
69
|
+
if (node.parentElement === this._slotTarget) {
|
|
70
|
+
this._slotTarget.removeChild(node);
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
delete this.__slotTargetClones;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Exclude whitespace text nodes
|
|
77
|
+
const nodes = this._sourceSlot
|
|
78
|
+
.assignedNodes({ flatten: true })
|
|
79
|
+
.filter((node) => !(node.nodeType == Node.TEXT_NODE && node.textContent.trim() === ''));
|
|
80
|
+
|
|
81
|
+
if (nodes.length > 0) {
|
|
82
|
+
this._slotTarget.innerHTML = '';
|
|
83
|
+
this.__copyNodesToSlotTarget(nodes);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Copies the nodes to the target element.
|
|
89
|
+
*
|
|
90
|
+
* @protected
|
|
91
|
+
* @param {!Array<!Node>} nodes
|
|
92
|
+
*/
|
|
93
|
+
__copyNodesToSlotTarget(nodes) {
|
|
94
|
+
this.__slotTargetClones = this.__slotTargetClones || [];
|
|
95
|
+
nodes.forEach((node) => {
|
|
96
|
+
// Clone the nodes and append the clones to the target slot
|
|
97
|
+
const clone = node.cloneNode(true);
|
|
98
|
+
this.__slotTargetClones.push(clone);
|
|
99
|
+
this._slotTarget.appendChild(clone);
|
|
100
|
+
// Observe all changes to the source node to have the clones updated
|
|
101
|
+
this.__sourceSlotObserver.observe(node, {
|
|
102
|
+
attributes: true,
|
|
103
|
+
childList: true,
|
|
104
|
+
subtree: true,
|
|
105
|
+
characterData: true
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2021 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { css } from 'lit';
|
|
7
|
+
|
|
8
|
+
export const clearButton = css`
|
|
9
|
+
[part='clear-button'] {
|
|
10
|
+
display: none;
|
|
11
|
+
cursor: default;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
[part='clear-button']::before {
|
|
15
|
+
content: '✕';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
:host([clear-button-visible][has-value]:not([disabled]):not([readonly])) [part='clear-button'] {
|
|
19
|
+
display: block;
|
|
20
|
+
}
|
|
21
|
+
`;
|