property editor dropdown
This commit is contained in:
committed by
Jacob Overgaard
parent
5387ee7660
commit
90c3e5c0f1
@@ -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',
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export * from './input-dropdown-list.element.js';
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
@@ -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];
|
||||
|
||||
Reference in New Issue
Block a user