Merge pull request #497 from umbraco/date-property-editor

Looks good
This commit is contained in:
Niels Lyngsø
2023-03-09 11:13:03 +01:00
committed by GitHub
6 changed files with 208 additions and 16 deletions

View File

@@ -15,15 +15,25 @@ export const manifest: ManifestPropertyEditorUI = {
{
alias: 'format',
label: 'Date format',
description: 'If left empty then the format is YYYY-MM-DD. (see momentjs.com for supported formats)',
description: 'If left empty then the format is YYYY-MM-DD',
propertyEditorUI: 'Umb.PropertyEditorUI.TextBox',
},
{
alias: 'offsetTime',
label: 'Offset time',
description: 'When enabled the time displayed will be offset with the servers timezone, this is useful for scenarios like scheduled publishing when an editor is in a different timezone than the hosted server',
propertyEditorUI: 'Umb.PropertyEditorUI.Toggle',
},
],
defaultData: [
{
alias: 'format',
value: 'YYYY-MM-DD HH:mm:ss',
},
{
alias: 'offsetTime',
value: false
}
],
},
},

View File

@@ -1,7 +1,10 @@
import { html } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { customElement, property, state } from 'lit/decorators.js';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { InputType } from '@umbraco-ui/uui';
import { UmbPropertyValueChangeEvent } from '../..';
import { UmbLitElement } from '@umbraco-cms/element';
import { PropertyEditorConfigDefaultData } from '@umbraco-cms/extensions-registry';
/**
* @element umb-property-editor-ui-date-picker
@@ -10,14 +13,68 @@ import { UmbLitElement } from '@umbraco-cms/element';
export class UmbPropertyEditorUIDatePickerElement extends UmbLitElement {
static styles = [UUITextStyles];
private _value?: Date;
private _valueString?: string;
@property()
value = '';
set value(value: string | undefined) {
if (value) {
const d = new Date(value);
this._value = d;
this._valueString = `${d.getFullYear()}-${
d.getMonth() + 1
}-${d.getDate()}T${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}`;
} else {
this._value = undefined;
this._valueString = undefined;
}
}
get value() {
return this._valueString;
}
private _onInput(e: InputEvent) {
const dateField = e.target as HTMLInputElement;
this.value = dateField.value;
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
private _format?: string;
@state()
private _inputType: InputType = 'datetime-local';
private _offsetTime?: boolean;
@property({ type: Array, attribute: false })
public config = [];
public set config(config: Array<PropertyEditorConfigDefaultData>) {
// Format string prevalue/config
this._format = config.find((x) => x.alias === 'format')?.value;
const pickTime = this._format?.includes('H') || this._format?.includes('m');
if (pickTime) {
this._inputType = 'datetime-local';
} else {
this._inputType = 'date';
}
// Based on the type of format string change the UUI-input type
const timeFormatPattern = /^h{1,2}:m{1,2}(:s{1,2})?\s?a?$/gim;
if (this._format?.toLowerCase().match(timeFormatPattern)) {
this._inputType = 'time';
}
// TODO: Warren - Need to deal with offSetTime prevalue/config
// Currently the date picker in uui-iinput does not change based on this config
this._offsetTime = config.find((x) => x.alias === 'offsetTime')?.value;
}
render() {
return html`<div>umb-property-editor-ui-date-picker</div>`;
return html` <uui-input
.type=${this._inputType}
@input=${this._onInput}
.value=${this._valueString}
label="Pick a date or time"></uui-input>`;
}
}

View File

@@ -8,8 +8,51 @@ export default {
title: 'Property Editor UIs/Date Picker',
component: 'umb-property-editor-ui-date-picker',
id: 'umb-property-editor-ui-date-picker',
} as Meta;
args: {
config: [
{
alias: 'format',
value: 'YYYY-MM-DD HH:mm:ss'
}
]
}
} as Meta<UmbPropertyEditorUIDatePickerElement>;
export const AAAOverview: Story<UmbPropertyEditorUIDatePickerElement> = () =>
html`<umb-property-editor-ui-date-picker></umb-property-editor-ui-date-picker>`;
AAAOverview.storyName = 'Overview';
const Template: Story<UmbPropertyEditorUIDatePickerElement> = ({config, value}) => html`<umb-property-editor-ui-date-picker .config=${config} .value=${value}></umb-property-editor-ui-date-picker>`;
export const Overview = Template.bind({});
export const WithDateValue = Template.bind({});
WithDateValue.args = {
value: '2021-01-24 15:20'
};
export const WithFormat = Template.bind({});
WithFormat.args = {
config: [
{
alias: 'format',
value: 'dd/MM/yyyy HH:mm:ss'
}
]
};
export const TimeOnly = Template.bind({});
TimeOnly.args = {
config: [
{
alias: 'format',
value: 'HH:mm:ss'
}
]
};
export const DateOnly = Template.bind({});
DateOnly.args = {
config: [
{
alias: 'format',
value: 'dd/MM/yyyy'
}
]
};

View File

@@ -1,21 +1,44 @@
import { expect, fixture, html } from '@open-wc/testing';
import { UUIInputElement } from '@umbraco-ui/uui';
import { UmbPropertyEditorUIDatePickerElement } from './property-editor-ui-date-picker.element';
import { defaultA11yConfig } from '@umbraco-cms/test-utils';
describe('UmbPropertyEditorUIDatePickerElement', () => {
let element: UmbPropertyEditorUIDatePickerElement;
let inputElement: UUIInputElement;
beforeEach(async () => {
element = await fixture(
html` <umb-property-editor-ui-date-picker></umb-property-editor-ui-date-picker> `
);
element = await fixture(
html` <umb-property-editor-ui-date-picker></umb-property-editor-ui-date-picker> `
);
inputElement = element.shadowRoot?.querySelector('uui-input') as UUIInputElement;
});
it('is defined with its own instance', () => {
expect(element).to.be.instanceOf(UmbPropertyEditorUIDatePickerElement);
expect(element).to.be.instanceOf(UmbPropertyEditorUIDatePickerElement);
});
it('should have an input element', () => {
expect(inputElement).to.exist;
});
it('should show a datetime-local input by default', () => {
expect(inputElement.type).to.equal('datetime-local');
});
it('should show a type=date field if the format only contains a date', async () => {
element.config = [{alias: 'format', value: 'YYYY-MM-dd'}];
await element.updateComplete;
expect(inputElement.type).to.equal('date');
});
it('should show a type=time field if the format only contains a time', async () => {
element.config = [{alias: 'format', value: 'HH:mm'}];
await element.updateComplete;
expect(inputElement.type).to.equal('time');
});
it('passes the a11y audit', async () => {
await expect(element).shadowDom.to.be.accessible(defaultA11yConfig);
await expect(element).shadowDom.to.be.accessible(defaultA11yConfig);
});
});

View File

@@ -206,7 +206,54 @@ export const data: Array<DataTypeModel & { type: 'data-type' }> = [
parentKey: null,
propertyEditorAlias: 'Umbraco.DateTime',
propertyEditorUiAlias: 'Umb.PropertyEditorUI.DatePicker',
data: [],
data: [
{
alias: 'format',
value: 'YYYY-MM-DD',
},
{
alias: 'offsetTime',
value: true,
},
],
},
{
$type: 'data-type',
name: 'Date Picker With Time',
type: 'data-type',
key: 'dt-datePicker-time',
parentKey: null,
propertyEditorAlias: 'Umbraco.DateTime',
propertyEditorUiAlias: 'Umb.PropertyEditorUI.DatePicker',
data: [
{
alias: 'format',
value: 'YYYY-MM-DD HH:mm:ss',
},
{
alias: 'offsetTime',
value: true,
},
],
},
{
$type: 'data-type',
name: 'Time',
type: 'data-type',
key: 'dt-time',
parentKey: null,
propertyEditorAlias: 'Umbraco.DateTime',
propertyEditorUiAlias: 'Umb.PropertyEditorUI.DatePicker',
data: [
{
alias: 'format',
value: 'HH:mm:ss',
},
{
alias: 'offsetTime',
value: false,
},
],
},
{
$type: 'data-type',

View File

@@ -59,7 +59,19 @@ export const data: Array<DocumentModel> = [
alias: 'datePicker',
culture: null,
segment: null,
value: null,
value: '2023-12-24',
},
{
alias: 'datePickerTime',
culture: null,
segment: null,
value: '2023-12-24 14:52',
},
{
alias: 'time',
culture: null,
segment: null,
value: '14:52:00',
},
{
alias: 'email',