datetime picker and input
This commit is contained in:
@@ -45,6 +45,15 @@ export class UmbPropertyEditorUIDatePickerElement extends UmbLitElement implemen
|
||||
@state()
|
||||
private _inputType: InputType = 'datetime-local';
|
||||
|
||||
@state()
|
||||
private _min?: string;
|
||||
|
||||
@state()
|
||||
private _max?: string;
|
||||
|
||||
@state()
|
||||
private _step?: number;
|
||||
|
||||
private _offsetTime?: boolean;
|
||||
|
||||
@property({ type: Array, attribute: false })
|
||||
@@ -66,19 +75,31 @@ export class UmbPropertyEditorUIDatePickerElement extends UmbLitElement implemen
|
||||
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
|
||||
//TODO:
|
||||
this._offsetTime = config.find((x) => x.alias === 'offsetTime')?.value;
|
||||
|
||||
const min = config.find((x) => x.alias === 'min');
|
||||
if (min) this._min = min.value;
|
||||
|
||||
const max = config.find((x) => x.alias === 'max');
|
||||
if (max) this._max = max.value;
|
||||
|
||||
const step = config.find((x) => x.alias === 'step');
|
||||
if (step) this._step = step.value;
|
||||
|
||||
this.requestUpdate('_inputType', oldVal);
|
||||
}
|
||||
|
||||
render() {
|
||||
return html` <uui-input
|
||||
return html`<umb-date-input
|
||||
.type=${this._inputType}
|
||||
@input=${this._onInput}
|
||||
.value=${this._valueString}
|
||||
label="Pick a date or time"></uui-input>`;
|
||||
.datetime=${this._valueString}
|
||||
.min=${this._min}
|
||||
.max=${this._max}
|
||||
.step=${this._step}
|
||||
.offsetTime=${this._offsetTime}
|
||||
label="Pick a date or time"></umb-date-input>`;
|
||||
}
|
||||
|
||||
static styles = [UUITextStyles];
|
||||
|
||||
@@ -38,6 +38,24 @@ WithFormat.args = {
|
||||
],
|
||||
};
|
||||
|
||||
export const Timeframe = Template.bind({});
|
||||
Timeframe.args = {
|
||||
config: [
|
||||
{
|
||||
alias: 'format',
|
||||
value: 'dd/MM/yyyy HH:mm:ss',
|
||||
},
|
||||
{
|
||||
alias: 'min',
|
||||
value: '2021-01-20 00:00',
|
||||
},
|
||||
{
|
||||
alias: 'max',
|
||||
value: '2021-01-30 00:00',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export const TimeOnly = Template.bind({});
|
||||
TimeOnly.args = {
|
||||
config: [
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
import { css, html } from 'lit';
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { customElement, property } from 'lit/decorators.js';
|
||||
import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins';
|
||||
import { ifDefined } from 'lit/directives/if-defined.js';
|
||||
import { UUIInputEvent } from '@umbraco-ui/uui';
|
||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||
|
||||
@customElement('umb-date-input')
|
||||
export class UmbDateInputElement extends FormControlMixin(UmbLitElement) {
|
||||
static styles = [
|
||||
UUITextStyles,
|
||||
css`
|
||||
:host {
|
||||
display: flex;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
protected getFormElement() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@property({ type: String })
|
||||
type = 'date';
|
||||
|
||||
@property({ type: String })
|
||||
datetime = '';
|
||||
|
||||
@property({ type: String })
|
||||
min?: string;
|
||||
|
||||
@property({ type: String })
|
||||
max?: string;
|
||||
|
||||
@property({ type: Number })
|
||||
step?: number;
|
||||
|
||||
@property({ type: Boolean })
|
||||
offsetTime = false; //TODO
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
this.value = this.datetime;
|
||||
}
|
||||
|
||||
#onDatetimeChange(e: UUIInputEvent) {
|
||||
e.stopPropagation();
|
||||
|
||||
const pickedTime = e.target.value as string;
|
||||
this.datetime = pickedTime;
|
||||
|
||||
// Set property editor value to UTC
|
||||
const date = new Date(pickedTime);
|
||||
const isoDate = date.toISOString();
|
||||
this.value = `${isoDate.substring(0, 10)} ${isoDate.substring(11, 19)}`;
|
||||
|
||||
this.dispatchEvent(new CustomEvent('change'));
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<uui-input
|
||||
id="datetime"
|
||||
@change="${this.#onDatetimeChange}"
|
||||
label="Pick a date or time"
|
||||
.type="${this.type}"
|
||||
min="${ifDefined(this.min)}"
|
||||
max="${ifDefined(this.max)}"
|
||||
.step="${this.step}"
|
||||
.value="${this.datetime}"></uui-input>`;
|
||||
}
|
||||
}
|
||||
|
||||
export default UmbDateInputElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-date-input': UmbDateInputElement;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import { Meta, StoryObj } from '@storybook/web-components';
|
||||
import './date-input.element';
|
||||
import type { UmbDateInputElement } from './date-input.element';
|
||||
|
||||
const meta: Meta<UmbDateInputElement> = {
|
||||
title: 'Components/Inputs/Date',
|
||||
component: 'umb-date-input',
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<UmbDateInputElement>;
|
||||
|
||||
export const Overview: Story = {
|
||||
args: {},
|
||||
};
|
||||
|
||||
export const WithOpacity: Story = {
|
||||
args: {},
|
||||
};
|
||||
|
||||
export const WithSwatches: Story = {
|
||||
args: {},
|
||||
};
|
||||
@@ -1,15 +1,15 @@
|
||||
import { expect, fixture, html } from '@open-wc/testing';
|
||||
import { UmbInputDatePickerElement } from './input-date-picker.element';
|
||||
import { UmbDateInputElement } from './date-input.element';
|
||||
import { defaultA11yConfig } from '@umbraco-cms/internal/test-utils';
|
||||
describe('UmbInputDatePickerElement', () => {
|
||||
let element: UmbInputDatePickerElement;
|
||||
describe('UmbDateInputElement', () => {
|
||||
let element: UmbDateInputElement;
|
||||
|
||||
beforeEach(async () => {
|
||||
element = await fixture(html` <umb-input-date-picker></umb-input-date-picker> `);
|
||||
element = await fixture(html` <umb-date-input></umb-date-input> `);
|
||||
});
|
||||
|
||||
it('is defined with its own instance', () => {
|
||||
expect(element).to.be.instanceOf(UmbInputDatePickerElement);
|
||||
expect(element).to.be.instanceOf(UmbDateInputElement);
|
||||
});
|
||||
|
||||
it('passes the a11y audit', async () => {
|
||||
@@ -1,99 +0,0 @@
|
||||
import { css, html, nothing } from 'lit';
|
||||
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
|
||||
import { customElement, property, state } from 'lit/decorators.js';
|
||||
import { FormControlMixin } from '@umbraco-ui/uui-base/lib/mixins';
|
||||
import { UUIInputEvent, UUISelectEvent } from '@umbraco-ui/uui';
|
||||
import { UmbLitElement } from '@umbraco-cms/internal/lit-element';
|
||||
|
||||
@customElement('umb-input-date-picker')
|
||||
export class UmbInputDatePickerElement extends FormControlMixin(UmbLitElement) {
|
||||
static styles = [
|
||||
UUITextStyles,
|
||||
css`
|
||||
:host {
|
||||
display: flex;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
protected getFormElement() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@property({ type: String })
|
||||
type = 'date';
|
||||
|
||||
@property({ type: String })
|
||||
datetime = '';
|
||||
|
||||
@property({ type: Boolean })
|
||||
enableTimezones = false;
|
||||
|
||||
@state()
|
||||
private _currentTimezone?: string;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
options: Array<Option> = [
|
||||
{ name: 'Carrot', value: 'orange' },
|
||||
{ name: 'Cucumber', value: 'green' },
|
||||
{ name: 'Aubergine', value: 'purple' },
|
||||
{ name: 'Blueberry', value: 'Blue' },
|
||||
{ name: 'Banana', value: 'yellow' },
|
||||
{ name: 'Strawberry', value: 'red' },
|
||||
];
|
||||
|
||||
connectedCallback(): void {
|
||||
super.connectedCallback();
|
||||
this.value = this.datetime;
|
||||
}
|
||||
|
||||
#onDatetimeChange(e: UUIInputEvent) {
|
||||
e.stopPropagation();
|
||||
|
||||
this.datetime = e.target.value as string;
|
||||
const append = this._currentTimezone ? `,${this._currentTimezone}` : '';
|
||||
this.value = this.datetime + append;
|
||||
|
||||
this.dispatchEvent(new CustomEvent('change'));
|
||||
}
|
||||
|
||||
#onTimezoneChange(e: UUISelectEvent) {
|
||||
e.stopPropagation();
|
||||
|
||||
const tz = e.target.value as string;
|
||||
this._currentTimezone = tz;
|
||||
this.value = `${this.datetime},${tz}`;
|
||||
|
||||
this.dispatchEvent(new CustomEvent('change'));
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`<uui-input
|
||||
id="datetime"
|
||||
@change="${this.#onDatetimeChange}"
|
||||
label="Pick a date or time"
|
||||
.type="${this.type}"
|
||||
.value="${this.datetime}"></uui-input>
|
||||
${this.enableTimezones ? this.#renderTimezone() : nothing}`;
|
||||
}
|
||||
|
||||
#renderTimezone() {
|
||||
return html`<uui-select
|
||||
id="timezone"
|
||||
@change="${this.#onTimezoneChange}"
|
||||
label="Select timezone"
|
||||
placeholder="Pick timezone"
|
||||
.options="${this.options}"></uui-select>`;
|
||||
}
|
||||
}
|
||||
|
||||
export default UmbInputDatePickerElement;
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
'umb-input-date-picker': UmbInputDatePickerElement;
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
import { Meta, StoryObj } from '@storybook/web-components';
|
||||
import './input-date-picker.element';
|
||||
import type { UmbInputDatePickerElement } from './input-date-picker.element';
|
||||
|
||||
const meta: Meta<UmbInputDatePickerElement> = {
|
||||
title: 'Components/Inputs/Date Picker',
|
||||
component: 'umb-input-date-picker',
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<UmbInputDatePickerElement>;
|
||||
|
||||
export const Overview: Story = {
|
||||
args: {},
|
||||
};
|
||||
|
||||
export const WithOpacity: Story = {
|
||||
args: {},
|
||||
};
|
||||
|
||||
export const WithSwatches: Story = {
|
||||
args: {},
|
||||
};
|
||||
Reference in New Issue
Block a user