Bugfix: RadioButtonList data structure

This commit is contained in:
leekelleher
2024-03-19 09:59:11 +00:00
parent ec4ca2c9d5
commit 4fbe34a972
3 changed files with 51 additions and 111 deletions

View File

@@ -1,55 +1,52 @@
import { css, html, nothing, repeat, customElement, property } from '@umbraco-cms/backoffice/external/lit';
import type { UUIBooleanInputEvent } from '@umbraco-cms/backoffice/external/uui';
import { FormControlMixin } from '@umbraco-cms/backoffice/external/uui';
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type { UUIBooleanInputEvent } from '@umbraco-cms/backoffice/external/uui';
@customElement('umb-input-radio-button-list')
export class UmbInputRadioButtonListElement extends FormControlMixin(UmbLitElement) {
/**
* List of items.
*/
@property({ attribute: false })
public list: Array<{ key: string; sortOrder: number; value: string }> = [];
#selected = '';
public set selected(key: string) {
this.#selected = key;
super.value = key;
}
public get selected(): string {
return this.#selected;
}
#value: string = '';
@property()
public set value(key: string) {
if (key !== this._value) {
this.selected = key;
}
public set value(value: string) {
this.#value = value;
}
public get value(): string {
return this.selected;
return this.#value;
}
@property({ type: Array })
public list: Array<{ label: string; value: string }> = [];
protected getFormElement() {
return undefined;
}
#setSelection(e: UUIBooleanInputEvent) {
e.stopPropagation();
if (e.target.value) this.selected = e.target.value;
this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }));
#onChange(event: UUIBooleanInputEvent) {
event.stopPropagation();
this.value = event.target.value;
this.dispatchEvent(new UmbChangeEvent());
}
render() {
if (!this.list) return nothing;
return html`<uui-radio-group .value=${this.value} @change=${this.#setSelection}>
${repeat(this.list, (item) => item, this.renderRadioButton)}
</uui-radio-group>`;
return html`
<uui-radio-group .value=${this.value} @change=${this.#onChange}>
${repeat(
this.list,
(item) => item,
(item) => this.#renderRadioButton(item),
)}
</uui-radio-group>
`;
}
renderRadioButton(item: { key: string; sortOrder: number; value: string }) {
return html`<uui-radio value="${item.value}" label="${item.value}"></uui-radio>`;
#renderRadioButton(item: (typeof this.list)[0]) {
return html`<uui-radio value="${item.value}" label="${item.label}"></uui-radio>`;
}
static styles = [

View File

@@ -13,21 +13,9 @@ type Story = StoryObj<UmbInputRadioButtonListElement>;
export const Overview: Story = {
args: {
list: [
{
key: '1',
sortOrder: 0,
value: 'One',
},
{
key: '2',
sortOrder: 1,
value: 'Two',
},
{
key: '3',
sortOrder: 2,
value: 'Three',
},
{ label: 'One', value: '1' },
{ label: 'Two', value: '2' },
{ label: 'Three', value: '3' },
],
},
};
@@ -35,45 +23,20 @@ export const Overview: Story = {
export const WithSelectedValue: Story = {
args: {
list: [
{
key: '1',
sortOrder: 0,
value: 'One',
},
{
key: '2',
sortOrder: 1,
value: 'Two',
},
{
key: '3',
sortOrder: 2,
value: 'Three',
},
{ label: 'One', value: '1' },
{ label: 'Two', value: '2' },
{ label: 'Three', value: '3' },
],
selected: '2',
value: 'Two',
value: '2',
},
};
export const SortOrder: Story = {
args: {
list: [
{
key: '1',
sortOrder: 4,
value: 'One',
},
{
key: '2',
sortOrder: 1,
value: 'Two',
},
{
key: '3',
sortOrder: 2,
value: 'Three',
},
{ label: 'One', value: '1' },
{ label: 'Two', value: '2' },
{ label: 'Three', value: '3' },
],
},
};

View File

@@ -1,59 +1,39 @@
import type { UmbInputRadioButtonListElement } from '../../../components/input-radio-button-list/input-radio-button-list.element.js';
import '../../../components/input-radio-button-list/input-radio-button-list.element.js';
import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UmbPropertyValueChangeEvent } from '@umbraco-cms/backoffice/property-editor';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import '../../../components/input-radio-button-list/input-radio-button-list.element.js';
/**
* @element umb-property-editor-ui-radio-button-list
*/
@customElement('umb-property-editor-ui-radio-button-list')
export class UmbPropertyEditorUIRadioButtonListElement extends UmbLitElement implements UmbPropertyEditorUiElement {
#value = '';
@property({ type: String })
public set value(value: string | undefined) {
this.#value = value?.trim() || '';
}
public get value(): string {
return this.#value;
}
@property()
value?: string = '';
public set config(config: UmbPropertyEditorConfigCollection | undefined) {
if (!config) return;
const listData: Record<number, { value: string; sortOrder: number }> | undefined = config.getValueByAlias('items');
if (!listData) return;
// formatting the items in the dictionary into an array
const sortedItems = [];
const values = Object.values<{ value: string; sortOrder: number }>(listData);
const keys = Object.keys(listData);
for (let i = 0; i < values.length; i++) {
sortedItems.push({ key: keys[i], sortOrder: values[i].sortOrder, value: values[i].value });
}
// ensure the items are sorted by the provided sort order
sortedItems.sort((a, b) => {
return a.sortOrder > b.sortOrder ? 1 : b.sortOrder > a.sortOrder ? -1 : 0;
});
this._list = sortedItems;
const listData: string[] | undefined = config?.getValueByAlias('items');
this._list = listData?.map((item) => ({ label: item, value: item })) ?? [];
}
@state()
private _list: Array<{ key: string; sortOrder: number; value: string }> = [];
private _list: UmbInputRadioButtonListElement['list'] = [];
#onChange(event: CustomEvent) {
this.value = (event.target as UmbInputRadioButtonListElement).selected;
this.dispatchEvent(new CustomEvent('property-value-change'));
const element = event.target as UmbInputRadioButtonListElement;
this.value = element.value;
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
render() {
return html`<umb-input-radio-button-list
@change="${this.#onChange}"
.selectedKey="${this.#value}"
.list="${this._list}"></umb-input-radio-button-list>`;
.list=${this._list}
.value=${this.value ?? ''}
@change=${this.#onChange}></umb-input-radio-button-list>`;
}
}