Skip to content

Commit 3724a45

Browse files
authored
Picker search result item icons for Documents and Members (#18250)
* Refactored `UmbDefaultPickerSearchResultItemElement` Abstracted to `UmbPickerSearchResultItemElementBase` for reuse * Exported types * Adds element for 'Umb.PickerSearchResultItem.Document' to handle the icon (and, in future, the URL/route) * Adds element for 'Umb.PickerSearchResultItem.Member' to handle the icon.
1 parent 4d931e5 commit 3724a45

File tree

9 files changed

+136
-51
lines changed

9 files changed

+136
-51
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
export * from './manager/index.js';
2+
export * from './result-item/index.js';
23
export * from './picker-search-field.element.js';
34
export * from './picker-search-result.element.js';
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,31 @@
1-
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
2-
import { customElement, html, nothing, property, state } from '@umbraco-cms/backoffice/external/lit';
3-
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
4-
import type { UmbPickerContext } from '@umbraco-cms/backoffice/picker';
5-
import { UMB_PICKER_CONTEXT } from '@umbraco-cms/backoffice/picker';
1+
import { UmbPickerSearchResultItemElementBase } from '../picker-search-result-item-element-base.js';
2+
import { customElement, html, nothing } from '@umbraco-cms/backoffice/external/lit';
63
import type { UmbSearchResultItemModel } from '@umbraco-cms/backoffice/search';
74

8-
const elementName = 'umb-default-picker-search-result-item';
9-
@customElement(elementName)
10-
export class UmbDefaultPickerSearchResultItemElement extends UmbLitElement {
11-
#item: UmbSearchResultItemModel | undefined;
12-
@property({ type: Object })
13-
public get item(): UmbSearchResultItemModel | undefined {
14-
return this.#item;
15-
}
16-
public set item(value: UmbSearchResultItemModel | undefined) {
17-
this.#item = value;
18-
this.#observeIsSelected();
19-
}
20-
21-
@state()
22-
_isSelected = false;
23-
24-
#pickerContext?: UmbPickerContext;
25-
26-
constructor() {
27-
super();
28-
29-
this.consumeContext(UMB_PICKER_CONTEXT, (context) => {
30-
this.#pickerContext = context;
31-
this.#observeIsSelected();
32-
});
33-
}
34-
35-
#observeIsSelected() {
36-
const selectionManager = this.#pickerContext?.selection;
37-
if (!selectionManager) return;
38-
39-
const unique = this.item?.unique;
40-
if (unique === undefined) return;
41-
42-
this.observe(selectionManager.selection, () => {
43-
this._isSelected = selectionManager.isSelected(unique);
44-
});
45-
}
46-
5+
@customElement('umb-default-picker-search-result-item')
6+
export class UmbDefaultPickerSearchResultItemElement extends UmbPickerSearchResultItemElementBase<UmbSearchResultItemModel> {
477
override render() {
488
const item = this.item;
499
if (!item) return nothing;
50-
5110
return html`
5211
<umb-ref-item
5312
name=${item.name}
5413
id=${item.unique}
5514
icon=${item.icon ?? 'icon-document'}
5615
select-only
5716
selectable
58-
@selected=${() => this.#pickerContext?.selection.select(item.unique)}
59-
@deselected=${() => this.#pickerContext?.selection.deselect(item.unique)}
60-
?selected=${this._isSelected}>
17+
?selected=${this._isSelected}
18+
@deselected=${() => this.pickerContext?.selection.deselect(item.unique)}
19+
@selected=${() => this.pickerContext?.selection.select(item.unique)}>
6120
</umb-ref-item>
6221
`;
6322
}
64-
65-
static override readonly styles = [UmbTextStyles];
6623
}
6724

6825
export { UmbDefaultPickerSearchResultItemElement as element };
6926

7027
declare global {
7128
interface HTMLElementTagNameMap {
72-
[elementName]: UmbDefaultPickerSearchResultItemElement;
29+
'umb-default-picker-search-result-item': UmbDefaultPickerSearchResultItemElement;
7330
}
7431
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { UmbDefaultPickerSearchResultItemContext } from './default-picker-search-result-item.context.js';
2+
export { UMB_PICKER_SEARCH_RESULT_ITEM_CONTEXT } from './default-picker-search-result-item.context.token.js';
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { UmbPickerSearchResultItemElementBase } from './picker-search-result-item-element-base.js';
2+
export * from './default/index.js';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import type { UmbNamedEntityModel } from '@umbraco-cms/backoffice/entity';
2+
import { html, nothing, property, state } from '@umbraco-cms/backoffice/external/lit';
3+
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
4+
import { UMB_PICKER_CONTEXT } from '@umbraco-cms/backoffice/picker';
5+
import type { UmbPickerContext } from '@umbraco-cms/backoffice/picker';
6+
7+
export abstract class UmbPickerSearchResultItemElementBase<ItemType extends UmbNamedEntityModel> extends UmbLitElement {
8+
#item: ItemType | undefined;
9+
10+
protected pickerContext?: UmbPickerContext;
11+
12+
@property({ type: Object })
13+
public set item(value: ItemType | undefined) {
14+
this.#item = value;
15+
this.#observeIsSelected();
16+
}
17+
public get item(): ItemType | undefined {
18+
return this.#item;
19+
}
20+
21+
@state()
22+
_isSelected = false;
23+
24+
constructor() {
25+
super();
26+
27+
this.consumeContext(UMB_PICKER_CONTEXT, (context) => {
28+
this.pickerContext = context;
29+
this.#observeIsSelected();
30+
});
31+
}
32+
33+
#observeIsSelected() {
34+
const selectionManager = this.pickerContext?.selection;
35+
if (!selectionManager) return;
36+
37+
const unique = this.item?.unique;
38+
if (unique === undefined) return;
39+
40+
this.observe(selectionManager.selection, () => {
41+
this._isSelected = selectionManager.isSelected(unique);
42+
});
43+
}
44+
45+
override render() {
46+
const item = this.item;
47+
if (!item) return nothing;
48+
return html`
49+
<umb-ref-item
50+
name=${item.name}
51+
select-only
52+
selectable
53+
?selected=${this._isSelected}
54+
@deselected=${() => this.pickerContext?.selection.deselect(item.unique)}
55+
@selected=${() => this.pickerContext?.selection.select(item.unique)}>
56+
</umb-ref-item>
57+
`;
58+
}
59+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import type { UmbDocumentSearchItemModel } from '../search/types.js';
2+
import { customElement, html, nothing } from '@umbraco-cms/backoffice/external/lit';
3+
import { UmbPickerSearchResultItemElementBase } from '@umbraco-cms/backoffice/picker';
4+
5+
@customElement('umb-document-picker-search-result-item')
6+
export class UmbDocumentPickerSearchResultItemElement extends UmbPickerSearchResultItemElementBase<UmbDocumentSearchItemModel> {
7+
override render() {
8+
if (!this.item) return nothing;
9+
const item = this.item;
10+
return html`
11+
<umb-ref-item
12+
name=${item.name}
13+
id=${item.unique}
14+
icon=${item.documentType.icon ?? 'icon-document'}
15+
select-only
16+
selectable
17+
?selected=${this._isSelected}
18+
@deselected=${() => this.pickerContext?.selection.deselect(item.unique)}
19+
@selected=${() => this.pickerContext?.selection.select(item.unique)}>
20+
</umb-ref-item>
21+
`;
22+
}
23+
}
24+
25+
export { UmbDocumentPickerSearchResultItemElement as element };
26+
27+
declare global {
28+
interface HTMLElementTagNameMap {
29+
'umb-document-picker-search-result-item': UmbDocumentPickerSearchResultItemElement;
30+
}
31+
}

src/Umbraco.Web.UI.Client/src/packages/documents/documents/picker/manifests.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export const manifests: Array<UmbExtensionManifest> = [
66
kind: 'default',
77
alias: 'Umb.PickerSearchResultItem.Document',
88
name: 'Document Picker Search Result Item',
9+
element: () => import('./document-picker-search-result-item.element.js'),
910
forEntityTypes: [UMB_DOCUMENT_ENTITY_TYPE],
1011
},
1112
];

src/Umbraco.Web.UI.Client/src/packages/members/member/picker/manifests.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export const manifests: Array<UmbExtensionManifest> = [
66
kind: 'default',
77
alias: 'Umb.PickerSearchResultItem.Member',
88
name: 'Member Picker Search Result Item',
9+
element: () => import('./member-picker-search-result-item.element.js'),
910
forEntityTypes: [UMB_MEMBER_ENTITY_TYPE],
1011
},
1112
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import type { UmbMemberSearchItemModel } from '../search/types.js';
2+
import { customElement, html, nothing } from '@umbraco-cms/backoffice/external/lit';
3+
import { UmbPickerSearchResultItemElementBase } from '@umbraco-cms/backoffice/picker';
4+
5+
@customElement('umb-member-picker-search-result-item')
6+
export class UmbMemberPickerSearchResultItemElement extends UmbPickerSearchResultItemElementBase<UmbMemberSearchItemModel> {
7+
override render() {
8+
if (!this.item) return nothing;
9+
const item = this.item;
10+
return html`
11+
<umb-ref-item
12+
name=${item.name}
13+
id=${item.unique}
14+
icon=${item.memberType.icon ?? 'icon-user'}
15+
select-only
16+
selectable
17+
?selected=${this._isSelected}
18+
@deselected=${() => this.pickerContext?.selection.deselect(item.unique)}
19+
@selected=${() => this.pickerContext?.selection.select(item.unique)}>
20+
</umb-ref-item>
21+
`;
22+
}
23+
}
24+
25+
export { UmbMemberPickerSearchResultItemElement as element };
26+
27+
declare global {
28+
interface HTMLElementTagNameMap {
29+
'umb-member-picker-search-result-item': UmbMemberPickerSearchResultItemElement;
30+
}
31+
}

0 commit comments

Comments
 (0)