@fluid-topics/ft-text-field 2.2.8 → 2.2.10
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/build/ft-text-field-suggestion.d.ts +14 -5
- package/build/ft-text-field-suggestion.js +104 -29
- package/build/ft-text-field-suggestion.styles.js +9 -3
- package/build/ft-text-field.d.ts +1 -1
- package/build/ft-text-field.js +22 -18
- package/build/ft-text-field.light.js +587 -232
- package/build/ft-text-field.min.js +585 -243
- package/build/models.d.ts +2 -1
- package/package.json +7 -7
|
@@ -3,18 +3,27 @@ import { FtTextFieldSuggestionProperties } from "./ft-text-field-suggestion.prop
|
|
|
3
3
|
export declare class SuggestionSelectedEvent extends CustomEvent<string> {
|
|
4
4
|
constructor(value: string);
|
|
5
5
|
}
|
|
6
|
+
export declare class SuggestionRemovedEvent extends CustomEvent<string> {
|
|
7
|
+
constructor(value: string);
|
|
8
|
+
}
|
|
6
9
|
export declare class FtTextFieldSuggestion extends FtLitElement implements FtTextFieldSuggestionProperties {
|
|
7
10
|
static elementDefinitions: ElementDefinitionsMap;
|
|
8
11
|
value?: string;
|
|
9
12
|
helper?: string;
|
|
10
|
-
|
|
13
|
+
removable: boolean;
|
|
14
|
+
removeButtonLabel?: string;
|
|
15
|
+
private suggestion?;
|
|
16
|
+
private removeButton?;
|
|
11
17
|
private assignedNodes;
|
|
12
18
|
static styles: import("lit").CSSResult;
|
|
13
19
|
render(): import("lit-html").TemplateResult<1>;
|
|
14
|
-
focus(options?: FocusOptions): void;
|
|
15
|
-
click(): void;
|
|
16
|
-
|
|
20
|
+
focus(options?: FocusOptions, targetRemoveButton?: boolean): void;
|
|
21
|
+
click(targetRemoveButton?: boolean): void;
|
|
22
|
+
isRemoveButtonFocused(): boolean;
|
|
23
|
+
private selectSuggestion;
|
|
24
|
+
private removeSuggestion;
|
|
17
25
|
getValue(): string;
|
|
18
26
|
getTextContent(): string;
|
|
19
|
-
private
|
|
27
|
+
private suggestionKeyDown;
|
|
28
|
+
private removeButtonKeyDown;
|
|
20
29
|
}
|
|
@@ -8,61 +8,126 @@ import { FtLitElement, } from "@fluid-topics/ft-wc-utils";
|
|
|
8
8
|
import { html, nothing, } from "lit";
|
|
9
9
|
import { property, query, queryAssignedNodes, } from "lit/decorators.js";
|
|
10
10
|
import { FtRipple } from "@fluid-topics/ft-ripple";
|
|
11
|
-
import { FtTypography } from "@fluid-topics/ft-typography";
|
|
11
|
+
import { FtTypography, FtTypographyVariants, } from "@fluid-topics/ft-typography";
|
|
12
12
|
import { suggestionStyles } from "./ft-text-field-suggestion.styles";
|
|
13
|
-
import { FtIcon } from "@fluid-topics/ft-icon";
|
|
13
|
+
import { FtIcon, FtIcons, } from "@fluid-topics/ft-icon";
|
|
14
14
|
import { classMap } from "lit/directives/class-map.js";
|
|
15
|
+
import { FtButton } from "@fluid-topics/ft-button";
|
|
15
16
|
export class SuggestionSelectedEvent extends CustomEvent {
|
|
16
17
|
constructor(value) {
|
|
17
18
|
super("suggestion-selected", { detail: value, bubbles: true, composed: true });
|
|
18
19
|
}
|
|
19
20
|
}
|
|
21
|
+
export class SuggestionRemovedEvent extends CustomEvent {
|
|
22
|
+
constructor(value) {
|
|
23
|
+
super("suggestion-removed", { detail: value, bubbles: true, composed: true });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
20
26
|
export class FtTextFieldSuggestion extends FtLitElement {
|
|
27
|
+
constructor() {
|
|
28
|
+
super(...arguments);
|
|
29
|
+
this.removable = false;
|
|
30
|
+
}
|
|
21
31
|
render() {
|
|
22
32
|
const classes = {
|
|
23
33
|
"ft-text-field-suggestion": true,
|
|
24
34
|
"ft-text-field-suggestion--with-helper": !!this.helper,
|
|
25
35
|
};
|
|
26
36
|
return html `
|
|
27
|
-
<div class="${classMap(classes)}"
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
<
|
|
40
|
-
|
|
37
|
+
<div class="${classMap(classes)}">
|
|
38
|
+
<div
|
|
39
|
+
class="ft-text-field-suggestion--suggestion"
|
|
40
|
+
tabindex="-1"
|
|
41
|
+
@keydown=${this.suggestionKeyDown}
|
|
42
|
+
@click=${this.selectSuggestion}
|
|
43
|
+
>
|
|
44
|
+
<ft-ripple></ft-ripple>
|
|
45
|
+
${this.helper ? html `
|
|
46
|
+
<ft-typography class="ft-text-field-suggestion--helper-text" variant="caption">
|
|
47
|
+
${this.helper}
|
|
48
|
+
</ft-typography>` : nothing}
|
|
49
|
+
<ft-typography part="label"
|
|
50
|
+
variant="${FtTypographyVariants.body1}"
|
|
51
|
+
class="ft-text-field-suggestion--label">
|
|
52
|
+
<slot></slot>
|
|
53
|
+
</ft-typography>
|
|
54
|
+
</div>
|
|
55
|
+
${this.removable ? html `
|
|
56
|
+
<ft-button icon="${FtIcons.CLOSE}"
|
|
57
|
+
part="remove-button"
|
|
58
|
+
class="ft-text-field-suggestion--remove"
|
|
59
|
+
round
|
|
60
|
+
label="${this.removeButtonLabel}"
|
|
61
|
+
tooltipPosition="left"
|
|
62
|
+
tabindex="-1"
|
|
63
|
+
@keydown=${this.removeButtonKeyDown}
|
|
64
|
+
@click=${this.removeSuggestion}>
|
|
65
|
+
</ft-button>
|
|
66
|
+
` : nothing}
|
|
41
67
|
</div>
|
|
42
68
|
`;
|
|
43
69
|
}
|
|
44
|
-
focus(options) {
|
|
45
|
-
var _a;
|
|
46
|
-
(
|
|
70
|
+
focus(options, targetRemoveButton) {
|
|
71
|
+
var _a, _b;
|
|
72
|
+
if (targetRemoveButton && this.removable) {
|
|
73
|
+
(_a = this.removeButton) === null || _a === void 0 ? void 0 : _a.focus();
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
(_b = this.suggestion) === null || _b === void 0 ? void 0 : _b.focus(options);
|
|
77
|
+
}
|
|
47
78
|
}
|
|
48
|
-
click() {
|
|
79
|
+
click(targetRemoveButton) {
|
|
49
80
|
var _a;
|
|
50
|
-
(_a = this.
|
|
81
|
+
(_a = (targetRemoveButton ? this.removeButton : this.suggestion)) === null || _a === void 0 ? void 0 : _a.click();
|
|
51
82
|
}
|
|
52
|
-
|
|
83
|
+
isRemoveButtonFocused() {
|
|
84
|
+
var _a, _b;
|
|
85
|
+
return (_b = (_a = this.removeButton) === null || _a === void 0 ? void 0 : _a.matches(":focus-within")) !== null && _b !== void 0 ? _b : false;
|
|
86
|
+
}
|
|
87
|
+
selectSuggestion() {
|
|
53
88
|
this.dispatchEvent(new SuggestionSelectedEvent(this.getValue()));
|
|
54
89
|
}
|
|
90
|
+
removeSuggestion() {
|
|
91
|
+
this.dispatchEvent(new SuggestionRemovedEvent(this.getValue()));
|
|
92
|
+
}
|
|
55
93
|
getValue() {
|
|
56
94
|
return this.value || this.getTextContent();
|
|
57
95
|
}
|
|
58
96
|
getTextContent() {
|
|
59
97
|
return this.assignedNodes.map((n) => n.textContent).join("").trim();
|
|
60
98
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
99
|
+
suggestionKeyDown(event) {
|
|
100
|
+
var _a;
|
|
101
|
+
switch (event.key) {
|
|
102
|
+
case "Enter":
|
|
103
|
+
case " ":
|
|
104
|
+
event.preventDefault();
|
|
105
|
+
event.stopPropagation();
|
|
106
|
+
this.selectSuggestion();
|
|
107
|
+
break;
|
|
108
|
+
case "ArrowRight":
|
|
109
|
+
if (this.removable) {
|
|
110
|
+
event.preventDefault();
|
|
111
|
+
event.stopPropagation();
|
|
112
|
+
(_a = this.removeButton) === null || _a === void 0 ? void 0 : _a.focus();
|
|
113
|
+
}
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
removeButtonKeyDown(event) {
|
|
118
|
+
var _a;
|
|
119
|
+
switch (event.key) {
|
|
120
|
+
case "Enter":
|
|
121
|
+
case " ":
|
|
122
|
+
event.preventDefault();
|
|
123
|
+
event.stopPropagation();
|
|
124
|
+
this.removeSuggestion();
|
|
125
|
+
break;
|
|
126
|
+
case "ArrowLeft":
|
|
127
|
+
event.preventDefault();
|
|
128
|
+
event.stopPropagation();
|
|
129
|
+
(_a = this.suggestion) === null || _a === void 0 ? void 0 : _a.focus();
|
|
130
|
+
break;
|
|
66
131
|
}
|
|
67
132
|
}
|
|
68
133
|
}
|
|
@@ -70,6 +135,7 @@ FtTextFieldSuggestion.elementDefinitions = {
|
|
|
70
135
|
"ft-ripple": FtRipple,
|
|
71
136
|
"ft-typography": FtTypography,
|
|
72
137
|
"ft-icon": FtIcon,
|
|
138
|
+
"ft-button": FtButton,
|
|
73
139
|
};
|
|
74
140
|
FtTextFieldSuggestion.styles = suggestionStyles;
|
|
75
141
|
__decorate([
|
|
@@ -79,8 +145,17 @@ __decorate([
|
|
|
79
145
|
property()
|
|
80
146
|
], FtTextFieldSuggestion.prototype, "helper", void 0);
|
|
81
147
|
__decorate([
|
|
82
|
-
|
|
83
|
-
], FtTextFieldSuggestion.prototype, "
|
|
148
|
+
property({ type: Boolean })
|
|
149
|
+
], FtTextFieldSuggestion.prototype, "removable", void 0);
|
|
150
|
+
__decorate([
|
|
151
|
+
property()
|
|
152
|
+
], FtTextFieldSuggestion.prototype, "removeButtonLabel", void 0);
|
|
153
|
+
__decorate([
|
|
154
|
+
query(".ft-text-field-suggestion--suggestion")
|
|
155
|
+
], FtTextFieldSuggestion.prototype, "suggestion", void 0);
|
|
156
|
+
__decorate([
|
|
157
|
+
query(".ft-text-field-suggestion--remove")
|
|
158
|
+
], FtTextFieldSuggestion.prototype, "removeButton", void 0);
|
|
84
159
|
__decorate([
|
|
85
160
|
queryAssignedNodes()
|
|
86
161
|
], FtTextFieldSuggestion.prototype, "assignedNodes", void 0);
|
|
@@ -2,28 +2,34 @@ import { css } from "lit";
|
|
|
2
2
|
import { FtTextFieldCssVariables } from "./ft-text-field.styles";
|
|
3
3
|
// language=CSS
|
|
4
4
|
export const suggestionStyles = css `
|
|
5
|
-
.ft-text-field-suggestion {
|
|
5
|
+
.ft-text-field-suggestion--suggestion {
|
|
6
6
|
position: relative;
|
|
7
7
|
padding: 8px 16px;
|
|
8
8
|
cursor: pointer;
|
|
9
9
|
min-height: 44px;
|
|
10
10
|
box-sizing: border-box;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.ft-text-field-suggestion--suggestion,
|
|
14
|
+
.ft-text-field-suggestion--remove {
|
|
11
15
|
outline: none;
|
|
12
16
|
}
|
|
13
17
|
|
|
14
18
|
.ft-text-field-suggestion,
|
|
19
|
+
.ft-text-field-suggestion--suggestion,
|
|
15
20
|
.ft-text-field-suggestion--label {
|
|
16
21
|
display: flex;
|
|
17
22
|
align-items: center;
|
|
18
|
-
gap: 8px;
|
|
19
23
|
}
|
|
20
24
|
|
|
25
|
+
.ft-text-field-suggestion--suggestion,
|
|
21
26
|
.ft-text-field-suggestion--label {
|
|
22
27
|
flex-grow: 1;
|
|
23
28
|
flex-shrink: 1;
|
|
29
|
+
gap: 8px;
|
|
24
30
|
}
|
|
25
31
|
|
|
26
|
-
.ft-text-field-suggestion--with-helper {
|
|
32
|
+
.ft-text-field-suggestion--with-helper > .ft-text-field-suggestion--suggestion {
|
|
27
33
|
display: flex;
|
|
28
34
|
flex-direction: column;
|
|
29
35
|
align-items: flex-start;
|
package/build/ft-text-field.d.ts
CHANGED
|
@@ -49,7 +49,6 @@ export declare class FtTextField extends FtTextField_base implements FtTextField
|
|
|
49
49
|
protected render(): import("lit-html").TemplateResult<1>;
|
|
50
50
|
private resolveInputType;
|
|
51
51
|
private renderSuggestions;
|
|
52
|
-
private onSuggestionClick;
|
|
53
52
|
private renderPasswordIcon;
|
|
54
53
|
private renderIcon;
|
|
55
54
|
protected update(props: PropertyValues): void;
|
|
@@ -68,6 +67,7 @@ export declare class FtTextField extends FtTextField_base implements FtTextField
|
|
|
68
67
|
private handleClick;
|
|
69
68
|
private handleKeyboardNavigation;
|
|
70
69
|
private onSuggestionSelected;
|
|
70
|
+
private onSuggestionRemoved;
|
|
71
71
|
private onFocus;
|
|
72
72
|
private onMainPanelBlur;
|
|
73
73
|
private togglePasswordVisibility;
|
package/build/ft-text-field.js
CHANGED
|
@@ -127,7 +127,9 @@ export class FtTextField extends toFtFormComponent(FtLitElement) {
|
|
|
127
127
|
</div>
|
|
128
128
|
<div class="ft-text-field--suggestions"
|
|
129
129
|
part="suggestions"
|
|
130
|
-
@suggestion-selected=${this.onSuggestionSelected}
|
|
130
|
+
@suggestion-selected=${this.onSuggestionSelected}
|
|
131
|
+
@suggestion-removed=${this.onSuggestionRemoved}
|
|
132
|
+
>
|
|
131
133
|
${this.renderSuggestions()}
|
|
132
134
|
${!this.hideCurrentValueSuggestion && shouldDisplayQueryAsNewSuggestion
|
|
133
135
|
? html `
|
|
@@ -159,15 +161,19 @@ export class FtTextField extends toFtFormComponent(FtLitElement) {
|
|
|
159
161
|
renderSuggestions() {
|
|
160
162
|
if (this.suggestionsProvider) {
|
|
161
163
|
return html `
|
|
162
|
-
${repeat(this.providedSuggestions, (suggestion) =>
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
164
|
+
${repeat(this.providedSuggestions, (suggestion) => {
|
|
165
|
+
var _a;
|
|
166
|
+
return html `
|
|
167
|
+
<ft-text-field-suggestion part="suggestion"
|
|
168
|
+
value="${suggestion.value}"
|
|
169
|
+
?removable=${suggestion.removable} }
|
|
170
|
+
removeButtonLabel="${(_a = suggestion.removeButtonLabel) !== null && _a !== void 0 ? _a : nothing}"
|
|
171
|
+
>
|
|
172
|
+
${suggestion.icon ? html `<ft-icon .value=${suggestion.icon}></ft-icon>` : nothing}
|
|
168
173
|
${suggestion.label}
|
|
169
174
|
</ft-text-field-suggestion>
|
|
170
|
-
|
|
175
|
+
`;
|
|
176
|
+
})}
|
|
171
177
|
`;
|
|
172
178
|
}
|
|
173
179
|
else {
|
|
@@ -176,12 +182,6 @@ export class FtTextField extends toFtFormComponent(FtLitElement) {
|
|
|
176
182
|
`;
|
|
177
183
|
}
|
|
178
184
|
}
|
|
179
|
-
onSuggestionClick(event, handler) {
|
|
180
|
-
if (handler) {
|
|
181
|
-
event.preventDefault();
|
|
182
|
-
handler(event);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
185
|
renderPasswordIcon() {
|
|
186
186
|
return html `
|
|
187
187
|
<ft-icon class="ft-text-field--icon"
|
|
@@ -251,7 +251,7 @@ export class FtTextField extends toFtFormComponent(FtLitElement) {
|
|
|
251
251
|
if (props.has("focused") && !this.hideSuggestions && this.visibleSuggestions.length > 0) {
|
|
252
252
|
this.setSuggestionPosition();
|
|
253
253
|
}
|
|
254
|
-
if (props.has("
|
|
254
|
+
if (props.has("providedSuggestions")) {
|
|
255
255
|
this.visibleSuggestions = [...this.providedSuggestionsInDom];
|
|
256
256
|
}
|
|
257
257
|
if (props.has("autocomplete")) {
|
|
@@ -316,12 +316,12 @@ export class FtTextField extends toFtFormComponent(FtLitElement) {
|
|
|
316
316
|
this.hideSuggestions = false;
|
|
317
317
|
}
|
|
318
318
|
handleKeyboardNavigation(event) {
|
|
319
|
-
var _a;
|
|
319
|
+
var _a, _b;
|
|
320
320
|
if ((event.key === "ArrowDown" || event.key === "ArrowUp")) {
|
|
321
321
|
event.preventDefault();
|
|
322
322
|
event.stopPropagation();
|
|
323
323
|
this.hideSuggestions = false;
|
|
324
|
-
const currentSuggestion = this.visibleSuggestions.findIndex((element) => element.matches(
|
|
324
|
+
const currentSuggestion = this.visibleSuggestions.findIndex((element) => element.matches(":focus-within"));
|
|
325
325
|
let target;
|
|
326
326
|
if (event.key === "ArrowDown") {
|
|
327
327
|
target = currentSuggestion < this.visibleSuggestions.length - 1 ? currentSuggestion + 1 : 0;
|
|
@@ -329,7 +329,7 @@ export class FtTextField extends toFtFormComponent(FtLitElement) {
|
|
|
329
329
|
else {
|
|
330
330
|
target = currentSuggestion > 0 ? currentSuggestion - 1 : this.visibleSuggestions.length - 1;
|
|
331
331
|
}
|
|
332
|
-
(_a = this.visibleSuggestions[target]) === null || _a === void 0 ? void 0 : _a.focus();
|
|
332
|
+
(_a = this.visibleSuggestions[target]) === null || _a === void 0 ? void 0 : _a.focus(undefined, (_b = this.visibleSuggestions[currentSuggestion]) === null || _b === void 0 ? void 0 : _b.isRemoveButtonFocused());
|
|
333
333
|
}
|
|
334
334
|
if (event.key == "Escape" || event.key == "Enter") {
|
|
335
335
|
this.hideSuggestions = true;
|
|
@@ -341,6 +341,10 @@ export class FtTextField extends toFtFormComponent(FtLitElement) {
|
|
|
341
341
|
(_a = this.input) === null || _a === void 0 ? void 0 : _a.focus();
|
|
342
342
|
setTimeout(() => this.hideSuggestions = true, 0);
|
|
343
343
|
}
|
|
344
|
+
onSuggestionRemoved() {
|
|
345
|
+
// update suggestions after all handlers processed the event
|
|
346
|
+
setTimeout(() => this.updateSuggestions());
|
|
347
|
+
}
|
|
344
348
|
onFocus() {
|
|
345
349
|
this.focused = true;
|
|
346
350
|
this.hideSuggestions = false;
|