Re-use icon picker property editor

It seems the Umb.PropertyEditorUi.IconPicker can be used in settings properties of a property editor. However unlike e.g. Eye Dropper Color Picker, it doesn’t seem to be available directly as a property editor: Icon picker as property editor · Issue #20632 · umbraco/Umbraco-CMS · GitHub

I researched a bit and it seems property & property dataset components can be used to re-use this:

I have something like this:

import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type {
	UmbPropertyEditorUiElement,
} from '@umbraco-cms/backoffice/property-editor';
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
//import type { UmbPropertyDatasetElement } from '@umbraco-cms/backoffice/property';
import { UMB_PROPERTY_DATASET_CONTEXT } from "@umbraco-cms/backoffice/property";

/**
 * @element mcb-property-editor-ui-icon-picker
 */
@customElement('mcb-property-editor-ui-icon-picker')
export class McbPropertyEditorUIIconPickerElement extends UmbLitElement implements UmbPropertyEditorUiElement {

	_datasetContext?: typeof UMB_PROPERTY_DATASET_CONTEXT.TYPE;

	@property()
	public get alias() {
		return this._alias;
	}
	public set alias(value) {
		this._alias = value;
		this._observeProperty();
	}
	_alias?: string;

	@state()
	_value?: string;

	getValue() {
		return this._value;
	}
	setValue(value: string) {
		if (this._alias) {
			this._datasetContext?.setPropertyValue(this._alias, value);
			this.dispatchEvent(new UmbChangeEvent());
		}
	}

	protected async _observeProperty() {
		if (!this._datasetContext || !this._alias) return;
		this.observe(
			await this._datasetContext.propertyValueByAlias(this._alias),
			(value) => {
				this._value = value as string;
			},
			'observeValue',
		);
	}

	constructor() {
		super();
		this.consumeContext(UMB_PROPERTY_DATASET_CONTEXT, async (variantContext) => {
			this._datasetContext = variantContext;
			this._observeProperty();
		});
	}

	#onDataChange(e: Event) {
		//const oldValue = this._value;
		//this._value = (e.target as UmbPropertyDatasetElement).value;
		//this.requestUpdate('value', oldValue);
	}

	override render() {
		return html`
			<umb-property-dataset .value=${this._value} @change=${this.#onDataChange}>
				<umb-property
					alias=${this.alias}
					label="Test"
					description="Test Test"
					property-editor-ui-alias="Umb.PropertyEditorUi.IconPicker">
				</umb-property>
			</umb-property-dataset>
		`;
	}
}

export default McbPropertyEditorUIIconPickerElement;

declare global {
	interface HTMLElementTagNameMap {
		'mcb-property-editor-ui-icon-picker': McbPropertyEditorUIIconPickerElement;
	}
}

In this case wrapped inside a custom property editor ui component.
However I am not quite sure how the value of the property should be updated in this scenario?

Also here it isn’t ideal to render label/description, but I can probably omit these - or hide label/description?

Alternatively I can of course implement much of the same logic from icon picker instead, but I would prefer not to re-invent the wheel :slight_smile: