Skip to content

Commit 5f37f8c

Browse files
Use generic picker for target-picker (#27850)
Co-authored-by: Petar Petrov <[email protected]>
1 parent f222702 commit 5f37f8c

17 files changed

+1015
-1472
lines changed

src/components/device/ha-device-picker.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,6 @@ export class HaDevicePicker extends LitElement {
197197
const placeholder =
198198
this.placeholder ??
199199
this.hass.localize("ui.components.device-picker.placeholder");
200-
const notFoundLabel = this.hass.localize(
201-
"ui.components.device-picker.no_match"
202-
);
203200

204201
const valueRenderer = this._valueRenderer(this._configEntryLookup);
205202

@@ -209,7 +206,10 @@ export class HaDevicePicker extends LitElement {
209206
.autofocus=${this.autofocus}
210207
.label=${this.label}
211208
.searchLabel=${this.searchLabel}
212-
.notFoundLabel=${notFoundLabel}
209+
.notFoundLabel=${this._notFoundLabel}
210+
.emptyLabel=${this.hass.localize(
211+
"ui.components.device-picker.no_devices"
212+
)}
213213
.placeholder=${placeholder}
214214
.value=${this.value}
215215
.rowRenderer=${this._rowRenderer}
@@ -233,6 +233,11 @@ export class HaDevicePicker extends LitElement {
233233
this.value = value;
234234
fireEvent(this, "value-changed", { value });
235235
}
236+
237+
private _notFoundLabel = (search: string) =>
238+
this.hass.localize("ui.components.device-picker.no_match", {
239+
term: html`<b>${search}</b>`,
240+
});
236241
}
237242

238243
declare global {

src/components/entity/ha-entity-picker.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -269,9 +269,6 @@ export class HaEntityPicker extends LitElement {
269269
const placeholder =
270270
this.placeholder ??
271271
this.hass.localize("ui.components.entity.entity-picker.placeholder");
272-
const notFoundLabel = this.hass.localize(
273-
"ui.components.entity.entity-picker.no_match"
274-
);
275272

276273
return html`
277274
<ha-generic-picker
@@ -282,7 +279,7 @@ export class HaEntityPicker extends LitElement {
282279
.label=${this.label}
283280
.helper=${this.helper}
284281
.searchLabel=${this.searchLabel}
285-
.notFoundLabel=${notFoundLabel}
282+
.notFoundLabel=${this._notFoundLabel}
286283
.placeholder=${placeholder}
287284
.value=${this.addButton ? undefined : this.value}
288285
.rowRenderer=${this._rowRenderer}
@@ -356,6 +353,11 @@ export class HaEntityPicker extends LitElement {
356353
fireEvent(this, "value-changed", { value });
357354
fireEvent(this, "change");
358355
}
356+
357+
private _notFoundLabel = (search: string) =>
358+
this.hass.localize("ui.components.entity.entity-picker.no_match", {
359+
term: html`<b>${search}</b>`,
360+
});
359361
}
360362

361363
declare global {

src/components/entity/ha-statistic-picker.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -271,15 +271,13 @@ export class HaStatisticPicker extends LitElement {
271271
const secondary = [areaName, entityName ? deviceName : undefined]
272272
.filter(Boolean)
273273
.join(isRTL ? " ◂ " : " ▸ ");
274-
const a11yLabel = [deviceName, entityName].filter(Boolean).join(" - ");
275274

276275
const sortingPrefix = `${TYPE_ORDER.indexOf("entity")}`;
277276
output.push({
278277
id,
279278
statistic_id: id,
280279
primary,
281280
secondary,
282-
a11y_label: a11yLabel,
283281
stateObj: stateObj,
284282
type: "entity",
285283
sorting_label: [sortingPrefix, deviceName, entityName].join("_"),
@@ -458,17 +456,17 @@ export class HaStatisticPicker extends LitElement {
458456
const placeholder =
459457
this.placeholder ??
460458
this.hass.localize("ui.components.statistic-picker.placeholder");
461-
const notFoundLabel = this.hass.localize(
462-
"ui.components.statistic-picker.no_match"
463-
);
464459

465460
return html`
466461
<ha-generic-picker
467462
.hass=${this.hass}
468463
.autofocus=${this.autofocus}
469464
.allowCustomValue=${this.allowCustomEntity}
470465
.label=${this.label}
471-
.notFoundLabel=${notFoundLabel}
466+
.notFoundLabel=${this._notFoundLabel}
467+
.emptyLabel=${this.hass.localize(
468+
"ui.components.statistic-picker.no_statistics"
469+
)}
472470
.placeholder=${placeholder}
473471
.value=${this.value}
474472
.rowRenderer=${this._rowRenderer}
@@ -521,6 +519,11 @@ export class HaStatisticPicker extends LitElement {
521519
await this.updateComplete;
522520
await this._picker?.open();
523521
}
522+
523+
private _notFoundLabel = (search: string) =>
524+
this.hass.localize("ui.components.statistic-picker.no_match", {
525+
term: html`<b>${search}</b>`,
526+
});
524527
}
525528

526529
declare global {

src/components/ha-area-picker.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -369,9 +369,10 @@ export class HaAreaPicker extends LitElement {
369369
.autofocus=${this.autofocus}
370370
.label=${this.label}
371371
.helper=${this.helper}
372-
.notFoundLabel=${this.hass.localize(
373-
"ui.components.area-picker.no_match"
374-
)}
372+
.notFoundLabel=${this._notFoundLabel}
373+
.emptyLabel=${this.hass.localize("ui.components.area-picker.no_areas")}
374+
.disabled=${this.disabled}
375+
.required=${this.required}
375376
.placeholder=${placeholder}
376377
.value=${this.value}
377378
.getItems=${this._getItems}
@@ -425,6 +426,11 @@ export class HaAreaPicker extends LitElement {
425426
fireEvent(this, "value-changed", { value });
426427
fireEvent(this, "change");
427428
}
429+
430+
private _notFoundLabel = (search: string) =>
431+
this.hass.localize("ui.components.area-picker.no_match", {
432+
term: html`<b>${search}</b>`,
433+
});
428434
}
429435

430436
declare global {

src/components/ha-floor-picker.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,8 +383,9 @@ export class HaFloorPicker extends LitElement {
383383
.hass=${this.hass}
384384
.autofocus=${this.autofocus}
385385
.label=${this.label}
386-
.notFoundLabel=${this.hass.localize(
387-
"ui.components.floor-picker.no_match"
386+
.notFoundLabel=${this._notFoundLabel}
387+
.emptyLabel=${this.hass.localize(
388+
"ui.components.floor-picker.no_floors"
388389
)}
389390
.placeholder=${placeholder}
390391
.value=${this.value}
@@ -444,6 +445,11 @@ export class HaFloorPicker extends LitElement {
444445
fireEvent(this, "value-changed", { value });
445446
fireEvent(this, "change");
446447
}
448+
449+
private _notFoundLabel = (search: string) =>
450+
this.hass.localize("ui.components.floor-picker.no_match", {
451+
term: html`<b>${search}</b>`,
452+
});
447453
}
448454

449455
declare global {

src/components/ha-generic-picker.ts

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ import "./ha-svg-icon";
2525
export class HaGenericPicker extends LitElement {
2626
@property({ attribute: false }) public hass?: HomeAssistant;
2727

28-
// eslint-disable-next-line lit/no-native-attributes
29-
@property({ type: Boolean }) public autofocus = false;
30-
3128
@property({ type: Boolean }) public disabled = false;
3229

3330
@property({ type: Boolean }) public required = false;
@@ -49,8 +46,11 @@ export class HaGenericPicker extends LitElement {
4946
@property({ attribute: "hide-clear-icon", type: Boolean })
5047
public hideClearIcon = false;
5148

52-
@property({ attribute: false, type: Array })
53-
public getItems?: () => PickerComboBoxItem[];
49+
@property({ attribute: false })
50+
public getItems?: (
51+
searchString?: string,
52+
section?: string
53+
) => (PickerComboBoxItem | string)[];
5454

5555
@property({ attribute: false, type: Array })
5656
public getAdditionalItems?: (searchString?: string) => PickerComboBoxItem[];
@@ -64,8 +64,11 @@ export class HaGenericPicker extends LitElement {
6464
@property({ attribute: false })
6565
public searchFn?: PickerComboBoxSearchFn<PickerComboBoxItem>;
6666

67-
@property({ attribute: "not-found-label", type: String })
68-
public notFoundLabel?: string;
67+
@property({ attribute: false })
68+
public notFoundLabel?: string | ((search: string) => string);
69+
70+
@property({ attribute: "empty-label" })
71+
public emptyLabel?: string;
6972

7073
@property({ attribute: "popover-placement" })
7174
public popoverPlacement:
@@ -85,6 +88,25 @@ export class HaGenericPicker extends LitElement {
8588
/** If set picker shows an add button instead of textbox when value isn't set */
8689
@property({ attribute: "add-button-label" }) public addButtonLabel?: string;
8790

91+
/** Section filter buttons for the list, section headers needs to be defined in getItems as strings */
92+
@property({ attribute: false }) public sections?: (
93+
| {
94+
id: string;
95+
label: string;
96+
}
97+
| "separator"
98+
)[];
99+
100+
@property({ attribute: false }) public sectionTitleFunction?: (listInfo: {
101+
firstIndex: number;
102+
lastIndex: number;
103+
firstItem: PickerComboBoxItem | string;
104+
secondItem: PickerComboBoxItem | string;
105+
itemsCount: number;
106+
}) => string | undefined;
107+
108+
@property({ attribute: "selected-section" }) public selectedSection?: string;
109+
88110
@query(".container") private _containerElement?: HTMLDivElement;
89111

90112
@query("ha-picker-combo-box") private _comboBox?: HaPickerComboBox;
@@ -97,6 +119,11 @@ export class HaGenericPicker extends LitElement {
97119

98120
@state() private _openedNarrow = false;
99121

122+
static shadowRootOptions = {
123+
...LitElement.shadowRootOptions,
124+
delegatesFocus: true,
125+
};
126+
100127
private _narrow = false;
101128

102129
// helper to set new value after closing picker, to avoid flicker
@@ -189,16 +216,19 @@ export class HaGenericPicker extends LitElement {
189216
<ha-picker-combo-box
190217
.hass=${this.hass}
191218
.allowCustomValue=${this.allowCustomValue}
192-
.label=${this.searchLabel ??
193-
(this.hass?.localize("ui.common.search") || "Search")}
219+
.label=${this.searchLabel}
194220
.value=${this.value}
195221
@value-changed=${this._valueChanged}
196222
.rowRenderer=${this.rowRenderer}
197223
.notFoundLabel=${this.notFoundLabel}
224+
.emptyLabel=${this.emptyLabel}
198225
.getItems=${this.getItems}
199226
.getAdditionalItems=${this.getAdditionalItems}
200227
.searchFn=${this.searchFn}
201228
.mode=${dialogMode ? "dialog" : "popover"}
229+
.sections=${this.sections}
230+
.sectionTitleFunction=${this.sectionTitleFunction}
231+
.selectedSection=${this.selectedSection}
202232
></ha-picker-combo-box>
203233
`;
204234
}

src/components/ha-label-picker.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,8 +224,9 @@ export class HaLabelPicker extends SubscribeMixin(LitElement) {
224224
.hass=${this.hass}
225225
.autofocus=${this.autofocus}
226226
.label=${this.label}
227-
.notFoundLabel=${this.hass.localize(
228-
"ui.components.label-picker.no_match"
227+
.notFoundLabel=${this._notFoundLabel}
228+
.emptyLabel=${this.hass.localize(
229+
"ui.components.label-picker.no_labels"
229230
)}
230231
.addButtonLabel=${this.hass.localize("ui.components.label-picker.add")}
231232
.placeholder=${placeholder}
@@ -288,6 +289,11 @@ export class HaLabelPicker extends SubscribeMixin(LitElement) {
288289
fireEvent(this, "change");
289290
}, 0);
290291
}
292+
293+
private _notFoundLabel = (search: string) =>
294+
this.hass.localize("ui.components.label-picker.no_match", {
295+
term: html`<b>${search}</b>`,
296+
});
291297
}
292298

293299
declare global {

src/components/ha-language-picker.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,10 @@ export class HaLanguagePicker extends LitElement {
125125
.hass=${this.hass}
126126
.autofocus=${this.autofocus}
127127
popover-placement="bottom-end"
128-
.notFoundLabel=${this.hass?.localize(
129-
"ui.components.language-picker.no_match"
130-
)}
128+
.notFoundLabel=${this._notFoundLabel}
129+
.emptyLabel=${this.hass?.localize(
130+
"ui.components.language-picker.no_languages"
131+
) || "No languages available"}
131132
.placeholder=${this.label ??
132133
(this.hass?.localize("ui.components.language-picker.language") ||
133134
"Language")}
@@ -172,6 +173,15 @@ export class HaLanguagePicker extends LitElement {
172173
this.value = ev.detail.value;
173174
fireEvent(this, "value-changed", { value: this.value });
174175
}
176+
177+
private _notFoundLabel = (search: string) => {
178+
const term = html`<b>${search}</b>`;
179+
return this.hass
180+
? this.hass.localize("ui.components.language-picker.no_match", {
181+
term,
182+
})
183+
: html`No languages found for ${term}`;
184+
};
175185
}
176186

177187
declare global {

0 commit comments

Comments
 (0)