@@ -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
|
||||
}
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
@@ -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>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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'
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -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);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user