@vaadin/field-base 23.0.0-alpha5 → 23.0.0-beta1
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/package.json +3 -3
- package/src/input-field-mixin.js +15 -0
- package/src/slot-target-controller.d.ts +31 -0
- package/src/slot-target-controller.js +119 -0
- package/src/slot-label-mixin.d.ts +0 -15
- package/src/slot-label-mixin.js +0 -25
- package/src/slot-target-mixin.d.ts +0 -25
- package/src/slot-target-mixin.js +0 -110
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/field-base",
|
|
3
|
-
"version": "23.0.0-
|
|
3
|
+
"version": "23.0.0-beta1",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
"dependencies": {
|
|
33
33
|
"@open-wc/dedupe-mixin": "^1.3.0",
|
|
34
34
|
"@polymer/polymer": "^3.0.0",
|
|
35
|
-
"@vaadin/component-base": "23.0.0-
|
|
35
|
+
"@vaadin/component-base": "23.0.0-beta1",
|
|
36
36
|
"lit": "^2.0.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
@@ -40,5 +40,5 @@
|
|
|
40
40
|
"@vaadin/testing-helpers": "^0.3.2",
|
|
41
41
|
"sinon": "^9.2.1"
|
|
42
42
|
},
|
|
43
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "467244b76021176c109df675799b07029b293e58"
|
|
44
44
|
}
|
package/src/input-field-mixin.js
CHANGED
|
@@ -120,6 +120,21 @@ export const InputFieldMixin = (superclass) =>
|
|
|
120
120
|
this.validate();
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
/**
|
|
124
|
+
* Override an event listener from `InputMixin`
|
|
125
|
+
* to mark as valid after user started typing.
|
|
126
|
+
* @param {Event} event
|
|
127
|
+
* @protected
|
|
128
|
+
* @override
|
|
129
|
+
*/
|
|
130
|
+
_onInput(event) {
|
|
131
|
+
super._onInput(event);
|
|
132
|
+
|
|
133
|
+
if (this.invalid) {
|
|
134
|
+
this.validate();
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
123
138
|
/**
|
|
124
139
|
* Override a method from `InputMixin` to validate the field
|
|
125
140
|
* when a new value is set programmatically.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2021 - 2022 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 SlotTargetController implements ReactiveController {
|
|
9
|
+
constructor(
|
|
10
|
+
sourceSlot: HTMLSlotElement,
|
|
11
|
+
targetFactory: () => HTMLElement,
|
|
12
|
+
copyCallback?: (nodes: HTMLElement[]) => void
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
hostConnected(): void;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The source `<slot>` element to copy nodes from.
|
|
19
|
+
*/
|
|
20
|
+
protected sourceSlot: HTMLSlotElement;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Function used to get a reference to slot target.
|
|
24
|
+
*/
|
|
25
|
+
protected targetFactory: () => HTMLElement;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Function called after copying nodes to target.
|
|
29
|
+
*/
|
|
30
|
+
protected copyCallback?: (nodes: HTMLElement[]) => void;
|
|
31
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A controller to copy the content from a source slot to a target element.
|
|
9
|
+
*/
|
|
10
|
+
export class SlotTargetController {
|
|
11
|
+
constructor(sourceSlot, targetFactory, callback) {
|
|
12
|
+
/**
|
|
13
|
+
* The source `<slot>` element to copy nodes from.
|
|
14
|
+
*/
|
|
15
|
+
this.sourceSlot = sourceSlot;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Function used to get a reference to slot target.
|
|
19
|
+
*/
|
|
20
|
+
this.targetFactory = targetFactory;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Function called after copying nodes to target.
|
|
24
|
+
*/
|
|
25
|
+
this.copyCallback = callback;
|
|
26
|
+
|
|
27
|
+
if (sourceSlot) {
|
|
28
|
+
sourceSlot.addEventListener('slotchange', () => {
|
|
29
|
+
// Copy in progress, ignore this event.
|
|
30
|
+
if (this.__copying) {
|
|
31
|
+
this.__copying = false;
|
|
32
|
+
} else {
|
|
33
|
+
this.__checkAndCopyNodesToSlotTarget();
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
hostConnected() {
|
|
40
|
+
this.__sourceSlotObserver = new MutationObserver(() => this.__checkAndCopyNodesToSlotTarget());
|
|
41
|
+
|
|
42
|
+
// Ensure the content is up to date when host is connected
|
|
43
|
+
// to handle e.g. mutating text content while disconnected.
|
|
44
|
+
this.__checkAndCopyNodesToSlotTarget();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Copies every node from the source slot to the target element
|
|
49
|
+
* once the source slot' content is changed.
|
|
50
|
+
*
|
|
51
|
+
* @private
|
|
52
|
+
*/
|
|
53
|
+
__checkAndCopyNodesToSlotTarget() {
|
|
54
|
+
this.__sourceSlotObserver.disconnect();
|
|
55
|
+
|
|
56
|
+
// Ensure slot target element is up to date.
|
|
57
|
+
const slotTarget = this.targetFactory();
|
|
58
|
+
|
|
59
|
+
if (!slotTarget) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Remove any existing clones from the slot target
|
|
64
|
+
if (this.__slotTargetClones) {
|
|
65
|
+
this.__slotTargetClones.forEach((node) => {
|
|
66
|
+
if (node.parentElement === slotTarget) {
|
|
67
|
+
slotTarget.removeChild(node);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
delete this.__slotTargetClones;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Exclude whitespace text nodes
|
|
74
|
+
const nodes = this.sourceSlot
|
|
75
|
+
.assignedNodes({ flatten: true })
|
|
76
|
+
.filter((node) => !(node.nodeType == Node.TEXT_NODE && node.textContent.trim() === ''));
|
|
77
|
+
|
|
78
|
+
if (nodes.length > 0) {
|
|
79
|
+
slotTarget.innerHTML = '';
|
|
80
|
+
|
|
81
|
+
// Ignore next slotchange
|
|
82
|
+
this.__copying = true;
|
|
83
|
+
|
|
84
|
+
this.__copyNodesToSlotTarget(nodes, slotTarget);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Copies the nodes to the target element.
|
|
90
|
+
*
|
|
91
|
+
* @param {!Array<!Node>} nodes
|
|
92
|
+
* @param {HTMLElement} slotTarget
|
|
93
|
+
* @private
|
|
94
|
+
*/
|
|
95
|
+
__copyNodesToSlotTarget(nodes, slotTarget) {
|
|
96
|
+
this.__slotTargetClones = this.__slotTargetClones || [];
|
|
97
|
+
|
|
98
|
+
nodes.forEach((node) => {
|
|
99
|
+
// Clone the nodes and append the clones to the target
|
|
100
|
+
const clone = node.cloneNode(true);
|
|
101
|
+
this.__slotTargetClones.push(clone);
|
|
102
|
+
|
|
103
|
+
slotTarget.appendChild(clone);
|
|
104
|
+
|
|
105
|
+
// Observe all changes to the source node to have the clones updated
|
|
106
|
+
this.__sourceSlotObserver.observe(node, {
|
|
107
|
+
attributes: true,
|
|
108
|
+
childList: true,
|
|
109
|
+
subtree: true,
|
|
110
|
+
characterData: true
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
// Run callback e.g. to show a deprecation warning
|
|
115
|
+
if (typeof this.copyCallback === 'function') {
|
|
116
|
+
this.copyCallback(nodes);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
4
|
-
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
-
*/
|
|
6
|
-
import { Constructor } from '@open-wc/dedupe-mixin';
|
|
7
|
-
import { LabelMixinClass } from './label-mixin.js';
|
|
8
|
-
import { SlotTargetMixinClass } from './slot-target-mixin.js';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* A mixin to forward any content from the default slot to the label node.
|
|
12
|
-
*/
|
|
13
|
-
export declare function SlotLabelMixin<T extends Constructor<HTMLElement>>(
|
|
14
|
-
base: T
|
|
15
|
-
): T & Constructor<LabelMixinClass> & Constructor<SlotTargetMixinClass>;
|
package/src/slot-label-mixin.js
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright (c) 2021 - 2022 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
|
-
);
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright (c) 2021 - 2022 Vaadin Ltd.
|
|
4
|
-
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
-
*/
|
|
6
|
-
import { Constructor } from '@open-wc/dedupe-mixin';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* A mixin to copy the content from a source slot to a target element.
|
|
10
|
-
*/
|
|
11
|
-
export declare function SlotTargetMixin<T extends Constructor<HTMLElement>>(
|
|
12
|
-
base: T
|
|
13
|
-
): T & Constructor<SlotTargetMixinClass>;
|
|
14
|
-
|
|
15
|
-
export declare class SlotTargetMixinClass {
|
|
16
|
-
/**
|
|
17
|
-
* A reference to the source slot from which the content is copied to the target element.
|
|
18
|
-
*/
|
|
19
|
-
protected readonly _sourceSlot: HTMLSlotElement;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* A reference to the target element to which the content is copied from the source slot.
|
|
23
|
-
*/
|
|
24
|
-
protected readonly _slotTarget: HTMLElement;
|
|
25
|
-
}
|
package/src/slot-target-mixin.js
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright (c) 2021 - 2022 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
|
-
);
|