From 488313b56ca22f053afadd16ae9f325cd65ef2d9 Mon Sep 17 00:00:00 2001 From: Warren Buckley Date: Thu, 2 Feb 2023 15:33:28 +0000 Subject: [PATCH] Work with Jacob pairing session Co-authored-by: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> --- .../property-editor-ui-date-picker.element.ts | 69 +++++++++++-------- .../property-editor-ui-date-picker.stories.ts | 51 ++++++++++++-- .../property-editor-ui-date-picker.test.ts | 33 +++++++-- 3 files changed, 115 insertions(+), 38 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.element.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.element.ts index 4c239f3da5..29033f6511 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.element.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.element.ts @@ -1,6 +1,7 @@ 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'; @@ -13,8 +14,28 @@ import { PropertyEditorConfigDefaultData } from '@umbraco-cms/extensions-registr 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(): string | undefined { + if (this._value) { + const d = this._value; + return `${d.getFullYear()}-${d.getMonth() + 1}-${d.getDate()} ${d.getHours()}:${d.getMinutes()}:${d.getSeconds()}`; + } + return undefined; + } private updateValue(e: InputEvent) { const dateField = e.target as HTMLInputElement; @@ -24,8 +45,8 @@ export class UmbPropertyEditorUIDatePickerElement extends UmbLitElement { private _format?: string; - // TODO: Warren [Can I get the underlying UUI-input type/enum so I can ensure only valid input types set] - private _inputType?: string = "date"; + @state() + private _inputType: InputType = "datetime-local"; private _offsetTime?: boolean; @@ -36,38 +57,28 @@ export class UmbPropertyEditorUIDatePickerElement extends UmbLitElement { // Format string prevalue/config this._format = config.find((x) => x.alias === 'format')?.value; - - // TODO: Warren - // When this is set to true then you need to check the Umbraco.Sys.ServerVariables that comes from C# server in a global JS obejct - this._offsetTime = config.find((x) => x.alias === 'offsetTime')?.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 - switch (this._format) { - case 'YYYY-MM-DD': - this._inputType = "date"; - break; - - case 'YYYY-MM-DD HH:mm:ss': - this._inputType = "datetime-local"; - break; - - case 'HH:mm:ss': - this._inputType = "time"; - break; - - default: - break; + const timeFormatPattern = /^h{1,2}:m{1,2}(:s{1,2})?\s?a?$/gmi; + if (this._format?.toLowerCase().match(timeFormatPattern)) { + this._inputType = "time"; } + + // TODO: Warren - could this be handled in the C# server side code? + // When this is set to true then you need to check the Umbraco.Sys.ServerVariables that comes from C# server in a global JS obejct + // How do we handle this ? + this._offsetTime = config.find((x) => x.alias === 'offsetTime')?.value; } render() { return html` - -
- Chosen Value: ${this.value}
- Config Format: ${this._format}
- Config TimeOffset enabled?: ${this._offsetTime}
-
`; + `; } } diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.stories.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.stories.ts index 783f397430..b3f5beae7e 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.stories.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.stories.ts @@ -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; -export const AAAOverview: Story = () => - html``; -AAAOverview.storyName = 'Overview'; +const Template: Story = ({config, value}) => html``; + +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' + } + ] +}; \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.test.ts b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.test.ts index 48583babe9..05c9ab0920 100644 --- a/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.test.ts +++ b/src/Umbraco.Web.UI.Client/src/backoffice/shared/property-editors/uis/date-picker/property-editor-ui-date-picker.test.ts @@ -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` ` - ); + element = await fixture( + html` ` + ); + 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); }); });