property editor dropdown

This commit is contained in:
Lone Iversen
2023-09-26 09:48:20 +02:00
committed by Jacob Overgaard
parent 5387ee7660
commit 90c3e5c0f1
6 changed files with 188 additions and 9 deletions

View File

@@ -299,7 +299,20 @@ export const data: Array<DataTypeResponseModel | FolderTreeItemResponseModel> =
parentId: null,
propertyEditorAlias: 'Umbraco.DropDown.Flexible',
propertyEditorUiAlias: 'Umb.PropertyEditorUi.Dropdown',
values: [],
values: [
{
alias: 'multiple',
value: false,
},
{
alias: 'items',
value: {
0: { sortOrder: 1, value: 'First Option' },
1: { sortOrder: 2, value: 'Second Option' },
2: { sortOrder: 3, value: 'I Am the third Option' },
},
},
],
},
{
type: 'data-type',

View File

@@ -0,0 +1 @@
export * from './input-dropdown-list.element.js';

View File

@@ -0,0 +1,54 @@
import { css, html, nothing, customElement, property, query, state } from '@umbraco-cms/backoffice/external/lit';
import { FormControlMixin, UUISelectEvent } from '@umbraco-cms/backoffice/external/uui';
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
@customElement('umb-input-dropdown-list')
export class UmbInputDropdownListElement extends FormControlMixin(UmbLitElement) {
@property({ type: Array })
public options?: Array<Option>;
@property({ type: String })
public placeholder?: string;
//TODO: show multiple lines when either a) uui-select has the option to do so or b) combobox has popover issue fixed and use this instead of uui-select.
@property({ type: Boolean })
public multiple?: boolean;
@query('uui-select')
private selectEle!: HTMLInputElement;
protected getFormElement() {
return this.selectEle;
}
#onChange(e: UUISelectEvent) {
e.stopPropagation();
if (e.target.value) this.value = e.target.value;
this.dispatchEvent(new CustomEvent('change', { bubbles: true, composed: true }));
}
render() {
if (!this.options) return nothing;
return html`<uui-select
label=${this.localize.term('formProviderFieldTypes_dropdownName')}
.placeholder=${this.placeholder ?? ''}
.options=${this.options}
@change=${this.#onChange}></uui-select>`;
}
static styles = [
css`
:host {
display: block;
}
`,
];
}
export default UmbInputDropdownListElement;
declare global {
interface HTMLElementTagNameMap {
'umb-input-dropdown-list': UmbInputDropdownListElement;
}
}

View File

@@ -0,0 +1,50 @@
import { Meta, StoryObj } from '@storybook/web-components';
import './input-dropdown-list.element.js';
import type { UmbInputDropdownListElement } from './input-dropdown-list.element.js';
const meta: Meta<UmbInputDropdownListElement> = {
title: 'Components/Inputs/Dropdown List',
component: 'umb-input-dropdown-list',
};
export default meta;
type Story = StoryObj<UmbInputDropdownListElement>;
export const Overview: Story = {
args: {
options: [
{
name: 'One',
value: 'One',
},
{
name: 'Two',
value: 'Two',
},
{
name: 'Three',
value: 'Three',
},
],
},
};
export const WithSelectedValue: Story = {
args: {
options: [
{
name: 'One',
value: 'One',
},
{
name: 'Two',
value: 'Two',
selected: true,
},
{
name: 'Three',
value: 'Three',
},
],
},
};

View File

@@ -0,0 +1,18 @@
import { expect, fixture, html } from '@open-wc/testing';
import { UmbInputDropdownListElement } from './input-dropdown-list.element.js';
import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils';
describe('UmbInputDateElement', () => {
let element: UmbInputDropdownListElement;
beforeEach(async () => {
element = await fixture(html` <umb-input-dropdown-list></umb-input-dropdown-list> `);
});
it('is defined with its own instance', () => {
expect(element).to.be.instanceOf(UmbInputDropdownListElement);
});
it('passes the a11y audit', async () => {
await expect(element).shadowDom.to.be.accessible(defaultA11yConfig);
});
});

View File

@@ -1,22 +1,65 @@
import { html, customElement, property } from '@umbraco-cms/backoffice/external/lit';
import { UmbTextStyles } from "@umbraco-cms/backoffice/style";
import { UmbPropertyEditorExtensionElement } from '@umbraco-cms/backoffice/extension-registry';
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
import { UUISelectEvent } from '@umbraco-ui/uui';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
import { html, customElement, property, state } from '@umbraco-cms/backoffice/external/lit';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
import { UmbPropertyEditorExtensionElement } from '@umbraco-cms/backoffice/extension-registry';
import '../../../components/input-dropdown/input-dropdown-list.element.js';
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
/**
* @element umb-property-editor-ui-dropdown
*/
@customElement('umb-property-editor-ui-dropdown')
export class UmbPropertyEditorUIDropdownElement extends UmbLitElement implements UmbPropertyEditorExtensionElement {
@property()
value = '';
#value = '';
@property({ type: String })
public get value(): string {
return this.#value;
}
public set value(value: string | undefined) {
this.#value = value?.trim() || '';
}
@state()
_multiple?: boolean;
@state()
private _list: Array<Option> = [];
@property({ attribute: false })
public config?: UmbPropertyEditorConfigCollection;
public set config(config: UmbPropertyEditorConfigCollection | undefined) {
if (!config) return;
this._multiple = config?.getValueByAlias('multiple');
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.map((x) => ({ value: x.value, name: x.value, selected: x.value === this.value }));
}
#onChange(event: UUISelectEvent) {
this.value = event.target.value as string;
this.dispatchEvent(new CustomEvent('property-value-change'));
}
render() {
return html`<div>umb-property-editor-ui-dropdown</div>`;
return html`<umb-input-dropdown-list
@change="${this.#onChange}"
?multiple=${this._multiple}
.options="${this._list}"></umb-input-dropdown-list>`;
}
static styles = [UmbTextStyles];