@triptease/tt-date-picker 6.3.3 → 6.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/src/TtDatePicker.js +8 -0
- package/dist/cjs/src/TtDatePicker.js.map +1 -1
- package/dist/cjs/src/styles.js +20 -0
- package/dist/cjs/src/styles.js.map +1 -1
- package/dist/esm/src/TtDatePicker.js +8 -0
- package/dist/esm/src/TtDatePicker.js.map +1 -1
- package/dist/esm/src/styles.js +20 -0
- package/dist/esm/src/styles.js.map +1 -1
- package/dist/esm/test/date-picker.test.js +36 -0
- package/dist/esm/test/date-picker.test.js.map +1 -1
- package/package.json +2 -2
|
@@ -39,6 +39,7 @@ class TtDatePicker extends lit_1.LitElement {
|
|
|
39
39
|
};
|
|
40
40
|
this._onDialogClose = () => {
|
|
41
41
|
this._open = false;
|
|
42
|
+
this.internals.states.delete('open-above');
|
|
42
43
|
};
|
|
43
44
|
this.onFocusOut = (event) => {
|
|
44
45
|
if (!this._open)
|
|
@@ -131,6 +132,13 @@ class TtDatePicker extends lit_1.LitElement {
|
|
|
131
132
|
}
|
|
132
133
|
showCalendar() {
|
|
133
134
|
if (!this._open) {
|
|
135
|
+
const rect = this.getBoundingClientRect();
|
|
136
|
+
if (!this.openLeft && rect.top > window.innerHeight - rect.bottom) {
|
|
137
|
+
this.internals.states.add('open-above');
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
this.internals.states.delete('open-above');
|
|
141
|
+
}
|
|
134
142
|
this.dialog.show();
|
|
135
143
|
if (this.openLeft) {
|
|
136
144
|
this.style.setProperty('--calendar-left-distance', '-192px');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TtDatePicker.js","sourceRoot":"","sources":["../../../src/TtDatePicker.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, LitElement, nothing, PropertyValues } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js';\nimport { DateTime } from 'luxon';\nimport { Calendar } from '@triptease/tt-calendar';\nimport { calendarIcon } from '@triptease/icons';\nimport { TtDialog } from '@triptease/tt-dialog';\nimport { DateInput } from '@triptease/tt-date-input';\nimport { DateSelectionEvent } from '@triptease/tt-calendar/date-selection-context.js';\nimport { dateConverter } from './helpers.js';\nimport { styles } from './styles.js';\n\nexport class TtDatePicker extends LitElement {\n static styles = [\n styles,\n css`\n [part='controls'] {\n min-width: 19.1ch;\n }\n `,\n ];\n\n static formAssociated = true;\n\n static shadowRootOptions = {\n ...LitElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n @query('tt-calendar')\n calendar!: Calendar;\n\n @query('tt-dialog')\n dialog!: TtDialog;\n\n @property({ type: String })\n public value?: string;\n\n @property({\n type: Date,\n converter: dateConverter,\n })\n public minDate?: Date;\n\n @property({\n type: Date,\n converter: dateConverter,\n })\n public maxDate?: Date;\n\n @property({ type: Boolean, attribute: 'open-left' })\n public openLeft = false;\n\n @property({ type: Boolean })\n public disabled = false;\n\n // Internal DateTime properties for calculations\n private get _valueDateTime(): DateTime | undefined {\n return this.value ? DateTime.fromISO(this.value) : undefined;\n }\n\n private get _minDateTime(): DateTime | undefined {\n return this.minDate ? DateTime.fromJSDate(this.minDate) : undefined;\n }\n\n private get _maxDateTime(): DateTime | undefined {\n return this.maxDate ? DateTime.fromJSDate(this.maxDate) : undefined;\n }\n\n @state()\n private _open: boolean = false;\n\n @query('tt-date-input')\n private dateInput!: DateInput;\n\n public internals: ReturnType<typeof this.attachInternals>;\n\n private get _formValue(): string {\n return this.value ?? '';\n }\n\n constructor() {\n super();\n this.internals = this.attachInternals();\n }\n\n onDateChange(e: Event) {\n if (DateSelectionEvent.is(e)) {\n this.value = e.detail;\n } else if (e.type === 'change') {\n this.value = (e.target as HTMLInputElement).value;\n }\n\n this.dispatchEvent(new InputEvent('change'));\n this.dialog.hide();\n }\n\n get form(): HTMLFormElement | null {\n return this.internals.form;\n }\n\n public updated(changedProperties: PropertyValues) {\n super.updated(changedProperties);\n\n if (changedProperties.has('value')) {\n this.internals.setFormValue(this._formValue);\n this.validate();\n }\n\n if (changedProperties.has('disabled')) {\n if (this.disabled) {\n this.internals.setFormValue(null);\n this.internals.states.add('disabled');\n this.inert = true;\n } else {\n this.internals.states.delete('disabled');\n this.internals.setFormValue(this._formValue);\n this.inert = false;\n }\n }\n }\n\n private validate() {\n const wasValid = this.internals.validity.valid;\n const oldMessage = this.internals.validationMessage;\n this.internals.setValidity({});\n\n if (this._valueDateTime) {\n const minDateIsValid =\n !this._minDateTime || this._valueDateTime > this._minDateTime || this._valueDateTime.equals(this._minDateTime);\n if (!minDateIsValid) {\n this.internals.setValidity(\n { rangeUnderflow: true },\n `Date should be equal or after ${this._minDateTime?.toLocaleString({\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n })}`\n );\n return;\n }\n const maxDateIsValid =\n !this._maxDateTime || this._valueDateTime.equals(this._maxDateTime) || this._valueDateTime < this._maxDateTime;\n if (!maxDateIsValid) {\n this.internals.setValidity(\n { rangeOverflow: true },\n `Date should be before or equal to ${this._maxDateTime?.toLocaleString({\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n })}`\n );\n return;\n }\n }\n if (wasValid !== this.internals.validity.valid || oldMessage !== this.internals.validationMessage) {\n this.requestUpdate();\n }\n }\n\n public connectedCallback() {\n super.connectedCallback();\n\n this.addEventListener('date-selection', this.onDateChange);\n this.addEventListener('dialog-open', this._onDialogOpen);\n this.addEventListener('dialog-close', this._onDialogClose);\n this.addEventListener('focusout', this.onFocusOut);\n this.addEventListener('focus', this._onFocus);\n }\n\n private _onDialogOpen = () => {\n this._open = true;\n };\n\n private _onDialogClose = () => {\n this._open = false;\n };\n\n public onFocusOut = (event: FocusEvent) => {\n if (!this._open) return;\n\n const target = (event.relatedTarget ?? event.explicitOriginalTarget) as HTMLElement | null;\n\n if (!this.contains(target)) {\n this.dialog.hide();\n }\n };\n\n private _onFocus = () => {\n this.dateInput.focus();\n };\n\n public disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener('date-selection', this.onDateChange);\n this.removeEventListener('dialog-open', this._onDialogOpen);\n this.removeEventListener('dialog-close', this._onDialogClose);\n this.removeEventListener('focusout', this.onFocusOut);\n this.removeEventListener('focus', this._onFocus);\n }\n\n showCalendar() {\n if (!this._open) {\n this.dialog.show();\n\n if (this.openLeft) {\n this.style.setProperty('--calendar-left-distance', '-192px');\n }\n } else {\n this.dialog.hide();\n }\n }\n\n render() {\n return html`\n <div part=\"controls\" aria-invalid=${!this.internals.validity.valid} aria-disabled=\"${this.disabled}\">\n <div name=\"container\" part=\"container\">\n <tt-date-input @change=${this.onDateChange} .value=${this.value} .disabled=${this.disabled}></tt-date-input>\n </div>\n <button\n name=\"Show calendar\"\n @click=${this.showCalendar}\n class=\"show-calendar\"\n aria-label=\"Choose date, ${this}\"\n ?disabled=${this.disabled}\n >\n ${unsafeSVG(calendarIcon)}\n </button>\n </div>\n <tt-dialog name=\"calendar\" aria-label=\"Choose date\" part=\"dialog\">\n <tt-calendar\n .value=\"${this.value}\"\n .minDate=${this.minDate}\n .maxDate=${this.maxDate}\n part=\"calendar\"\n ></tt-calendar>\n </tt-dialog>\n <div class=\"errormessage\" id=\"error-msg-${this.id}\" role=\"alert\" aria-atomic=\"true\" part=\"error\">\n ${this.internals.validity.valid ? nothing : this.internals.validationMessage}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'tt-date-picker': TtDatePicker;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"TtDatePicker.js","sourceRoot":"","sources":["../../../src/TtDatePicker.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, LitElement, nothing, PropertyValues } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js';\nimport { DateTime } from 'luxon';\nimport { Calendar } from '@triptease/tt-calendar';\nimport { calendarIcon } from '@triptease/icons';\nimport { TtDialog } from '@triptease/tt-dialog';\nimport { DateInput } from '@triptease/tt-date-input';\nimport { DateSelectionEvent } from '@triptease/tt-calendar/date-selection-context.js';\nimport { dateConverter } from './helpers.js';\nimport { styles } from './styles.js';\n\nexport class TtDatePicker extends LitElement {\n static styles = [\n styles,\n css`\n [part='controls'] {\n min-width: 19.1ch;\n }\n `,\n ];\n\n static formAssociated = true;\n\n static shadowRootOptions = {\n ...LitElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n @query('tt-calendar')\n calendar!: Calendar;\n\n @query('tt-dialog')\n dialog!: TtDialog;\n\n @property({ type: String })\n public value?: string;\n\n @property({\n type: Date,\n converter: dateConverter,\n })\n public minDate?: Date;\n\n @property({\n type: Date,\n converter: dateConverter,\n })\n public maxDate?: Date;\n\n @property({ type: Boolean, attribute: 'open-left' })\n public openLeft = false;\n\n @property({ type: Boolean })\n public disabled = false;\n\n // Internal DateTime properties for calculations\n private get _valueDateTime(): DateTime | undefined {\n return this.value ? DateTime.fromISO(this.value) : undefined;\n }\n\n private get _minDateTime(): DateTime | undefined {\n return this.minDate ? DateTime.fromJSDate(this.minDate) : undefined;\n }\n\n private get _maxDateTime(): DateTime | undefined {\n return this.maxDate ? DateTime.fromJSDate(this.maxDate) : undefined;\n }\n\n @state()\n private _open: boolean = false;\n\n @query('tt-date-input')\n private dateInput!: DateInput;\n\n public internals: ReturnType<typeof this.attachInternals>;\n\n private get _formValue(): string {\n return this.value ?? '';\n }\n\n constructor() {\n super();\n this.internals = this.attachInternals();\n }\n\n onDateChange(e: Event) {\n if (DateSelectionEvent.is(e)) {\n this.value = e.detail;\n } else if (e.type === 'change') {\n this.value = (e.target as HTMLInputElement).value;\n }\n\n this.dispatchEvent(new InputEvent('change'));\n this.dialog.hide();\n }\n\n get form(): HTMLFormElement | null {\n return this.internals.form;\n }\n\n public updated(changedProperties: PropertyValues) {\n super.updated(changedProperties);\n\n if (changedProperties.has('value')) {\n this.internals.setFormValue(this._formValue);\n this.validate();\n }\n\n if (changedProperties.has('disabled')) {\n if (this.disabled) {\n this.internals.setFormValue(null);\n this.internals.states.add('disabled');\n this.inert = true;\n } else {\n this.internals.states.delete('disabled');\n this.internals.setFormValue(this._formValue);\n this.inert = false;\n }\n }\n }\n\n private validate() {\n const wasValid = this.internals.validity.valid;\n const oldMessage = this.internals.validationMessage;\n this.internals.setValidity({});\n\n if (this._valueDateTime) {\n const minDateIsValid =\n !this._minDateTime || this._valueDateTime > this._minDateTime || this._valueDateTime.equals(this._minDateTime);\n if (!minDateIsValid) {\n this.internals.setValidity(\n { rangeUnderflow: true },\n `Date should be equal or after ${this._minDateTime?.toLocaleString({\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n })}`\n );\n return;\n }\n const maxDateIsValid =\n !this._maxDateTime || this._valueDateTime.equals(this._maxDateTime) || this._valueDateTime < this._maxDateTime;\n if (!maxDateIsValid) {\n this.internals.setValidity(\n { rangeOverflow: true },\n `Date should be before or equal to ${this._maxDateTime?.toLocaleString({\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n })}`\n );\n return;\n }\n }\n if (wasValid !== this.internals.validity.valid || oldMessage !== this.internals.validationMessage) {\n this.requestUpdate();\n }\n }\n\n public connectedCallback() {\n super.connectedCallback();\n\n this.addEventListener('date-selection', this.onDateChange);\n this.addEventListener('dialog-open', this._onDialogOpen);\n this.addEventListener('dialog-close', this._onDialogClose);\n this.addEventListener('focusout', this.onFocusOut);\n this.addEventListener('focus', this._onFocus);\n }\n\n private _onDialogOpen = () => {\n this._open = true;\n };\n\n private _onDialogClose = () => {\n this._open = false;\n this.internals.states.delete('open-above');\n };\n\n public onFocusOut = (event: FocusEvent) => {\n if (!this._open) return;\n\n const target = (event.relatedTarget ?? event.explicitOriginalTarget) as HTMLElement | null;\n\n if (!this.contains(target)) {\n this.dialog.hide();\n }\n };\n\n private _onFocus = () => {\n this.dateInput.focus();\n };\n\n public disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener('date-selection', this.onDateChange);\n this.removeEventListener('dialog-open', this._onDialogOpen);\n this.removeEventListener('dialog-close', this._onDialogClose);\n this.removeEventListener('focusout', this.onFocusOut);\n this.removeEventListener('focus', this._onFocus);\n }\n\n showCalendar() {\n if (!this._open) {\n const rect = this.getBoundingClientRect();\n if (!this.openLeft && rect.top > window.innerHeight - rect.bottom) {\n this.internals.states.add('open-above');\n } else {\n this.internals.states.delete('open-above');\n }\n\n this.dialog.show();\n\n if (this.openLeft) {\n this.style.setProperty('--calendar-left-distance', '-192px');\n }\n } else {\n this.dialog.hide();\n }\n }\n\n render() {\n return html`\n <div part=\"controls\" aria-invalid=${!this.internals.validity.valid} aria-disabled=\"${this.disabled}\">\n <div name=\"container\" part=\"container\">\n <tt-date-input @change=${this.onDateChange} .value=${this.value} .disabled=${this.disabled}></tt-date-input>\n </div>\n <button\n name=\"Show calendar\"\n @click=${this.showCalendar}\n class=\"show-calendar\"\n aria-label=\"Choose date, ${this}\"\n ?disabled=${this.disabled}\n >\n ${unsafeSVG(calendarIcon)}\n </button>\n </div>\n <tt-dialog name=\"calendar\" aria-label=\"Choose date\" part=\"dialog\">\n <tt-calendar\n .value=\"${this.value}\"\n .minDate=${this.minDate}\n .maxDate=${this.maxDate}\n part=\"calendar\"\n ></tt-calendar>\n </tt-dialog>\n <div class=\"errormessage\" id=\"error-msg-${this.id}\" role=\"alert\" aria-atomic=\"true\" part=\"error\">\n ${this.internals.validity.valid ? nothing : this.internals.validationMessage}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'tt-date-picker': TtDatePicker;\n }\n}\n"]}
|
package/dist/cjs/src/styles.js
CHANGED
|
@@ -75,6 +75,26 @@ exports.styles = (0, lit_1.css) `
|
|
|
75
75
|
position-anchor: --date-picker;
|
|
76
76
|
position: fixed;
|
|
77
77
|
z-index: 1;
|
|
78
|
+
inset-block-start: anchor(bottom);
|
|
79
|
+
margin-block-start: var(--space-scale-1);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
[part='dialog']::part(dialog) {
|
|
83
|
+
margin-top: 0;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
:host(:state(open-above)) [part='dialog'] {
|
|
87
|
+
inset-block-start: auto;
|
|
88
|
+
margin-block-start: 0;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
:host(:state(open-above)) [part='dialog']::part(dialog) {
|
|
92
|
+
position: fixed;
|
|
93
|
+
position-anchor: --date-picker;
|
|
94
|
+
bottom: anchor(top);
|
|
95
|
+
top: auto;
|
|
96
|
+
left: anchor(left);
|
|
97
|
+
margin-bottom: var(--space-scale-1);
|
|
78
98
|
}
|
|
79
99
|
}
|
|
80
100
|
`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../src/styles.ts"],"names":[],"mappings":";;;AAAA,6BAA0B;AAEb,QAAA,MAAM,GAAG,IAAA,SAAG,EAAA
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../src/styles.ts"],"names":[],"mappings":";;;AAAA,6BAA0B;AAEb,QAAA,MAAM,GAAG,IAAA,SAAG,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+FxB,CAAC","sourcesContent":["import { css } from 'lit';\n\nexport const styles = css`\n :host {\n position: relative;\n anchor-name: --date-picker;\n anchor-scope: --date-picker;\n }\n\n :host(:state(disabled)) {\n pointer-events: none;\n opacity: 0.5;\n }\n\n tt-side-panel::part(side-panel) {\n border-right: 1px solid var(--color-border-200);\n }\n\n tt-side-panel:empty {\n display: none;\n }\n\n [part='container'] {\n padding: var(--space-scale-1) var(--space-scale-1-5);\n gap: var(--space-scale-1);\n }\n\n [part='controls'] {\n display: flex;\n border: 1px solid var(--color-border-200);\n border-radius: var(--border-radius);\n width: fit-content;\n height: var(--date-picker-height, fit-content);\n background-color: var(--color-surface-100);\n font-size: var(--font-size-200);\n color: var(--color-text-400);\n align-items: stretch;\n justify-content: space-around;\n padding: 0;\n\n &[aria-invalid='true'] {\n outline: 2px solid var(--color-alert-strong);\n }\n\n button {\n border: 0;\n padding-inline: var(--space-scale-1);\n background-color: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n align-self: stretch;\n border-left: 1px solid var(--color-border-200);\n box-sizing: border-box;\n color: var(--color-text-400);\n }\n\n &:has(+ tt-dialog[open]) .show-calendar svg,\n .show-calendar:hover svg {\n color: var(--color-primary-400);\n }\n }\n\n [part='dialog']::part(dialog) {\n margin-top: var(--space-scale-1);\n flex-direction: row-reverse;\n }\n\n /** If supported, use CSS anchor positioning, which allows the dialog to escape overflow containers */\n @supports (position-anchor: --date-picker) {\n [part='dialog'] {\n position-anchor: --date-picker;\n position: fixed;\n z-index: 1;\n inset-block-start: anchor(bottom);\n margin-block-start: var(--space-scale-1);\n }\n\n [part='dialog']::part(dialog) {\n margin-top: 0;\n }\n\n :host(:state(open-above)) [part='dialog'] {\n inset-block-start: auto;\n margin-block-start: 0;\n }\n\n :host(:state(open-above)) [part='dialog']::part(dialog) {\n position: fixed;\n position-anchor: --date-picker;\n bottom: anchor(top);\n top: auto;\n left: anchor(left);\n margin-bottom: var(--space-scale-1);\n }\n }\n`;\n"]}
|
|
@@ -36,6 +36,7 @@ export class TtDatePicker extends LitElement {
|
|
|
36
36
|
};
|
|
37
37
|
this._onDialogClose = () => {
|
|
38
38
|
this._open = false;
|
|
39
|
+
this.internals.states.delete('open-above');
|
|
39
40
|
};
|
|
40
41
|
this.onFocusOut = (event) => {
|
|
41
42
|
if (!this._open)
|
|
@@ -128,6 +129,13 @@ export class TtDatePicker extends LitElement {
|
|
|
128
129
|
}
|
|
129
130
|
showCalendar() {
|
|
130
131
|
if (!this._open) {
|
|
132
|
+
const rect = this.getBoundingClientRect();
|
|
133
|
+
if (!this.openLeft && rect.top > window.innerHeight - rect.bottom) {
|
|
134
|
+
this.internals.states.add('open-above');
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
this.internals.states.delete('open-above');
|
|
138
|
+
}
|
|
131
139
|
this.dialog.show();
|
|
132
140
|
if (this.openLeft) {
|
|
133
141
|
this.style.setProperty('--calendar-left-distance', '-192px');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TtDatePicker.js","sourceRoot":"","sources":["../../../src/TtDatePicker.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, LitElement, nothing, PropertyValues } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js';\nimport { DateTime } from 'luxon';\nimport { Calendar } from '@triptease/tt-calendar';\nimport { calendarIcon } from '@triptease/icons';\nimport { TtDialog } from '@triptease/tt-dialog';\nimport { DateInput } from '@triptease/tt-date-input';\nimport { DateSelectionEvent } from '@triptease/tt-calendar/date-selection-context.js';\nimport { dateConverter } from './helpers.js';\nimport { styles } from './styles.js';\n\nexport class TtDatePicker extends LitElement {\n static styles = [\n styles,\n css`\n [part='controls'] {\n min-width: 19.1ch;\n }\n `,\n ];\n\n static formAssociated = true;\n\n static shadowRootOptions = {\n ...LitElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n @query('tt-calendar')\n calendar!: Calendar;\n\n @query('tt-dialog')\n dialog!: TtDialog;\n\n @property({ type: String })\n public value?: string;\n\n @property({\n type: Date,\n converter: dateConverter,\n })\n public minDate?: Date;\n\n @property({\n type: Date,\n converter: dateConverter,\n })\n public maxDate?: Date;\n\n @property({ type: Boolean, attribute: 'open-left' })\n public openLeft = false;\n\n @property({ type: Boolean })\n public disabled = false;\n\n // Internal DateTime properties for calculations\n private get _valueDateTime(): DateTime | undefined {\n return this.value ? DateTime.fromISO(this.value) : undefined;\n }\n\n private get _minDateTime(): DateTime | undefined {\n return this.minDate ? DateTime.fromJSDate(this.minDate) : undefined;\n }\n\n private get _maxDateTime(): DateTime | undefined {\n return this.maxDate ? DateTime.fromJSDate(this.maxDate) : undefined;\n }\n\n @state()\n private _open: boolean = false;\n\n @query('tt-date-input')\n private dateInput!: DateInput;\n\n public internals: ReturnType<typeof this.attachInternals>;\n\n private get _formValue(): string {\n return this.value ?? '';\n }\n\n constructor() {\n super();\n this.internals = this.attachInternals();\n }\n\n onDateChange(e: Event) {\n if (DateSelectionEvent.is(e)) {\n this.value = e.detail;\n } else if (e.type === 'change') {\n this.value = (e.target as HTMLInputElement).value;\n }\n\n this.dispatchEvent(new InputEvent('change'));\n this.dialog.hide();\n }\n\n get form(): HTMLFormElement | null {\n return this.internals.form;\n }\n\n public updated(changedProperties: PropertyValues) {\n super.updated(changedProperties);\n\n if (changedProperties.has('value')) {\n this.internals.setFormValue(this._formValue);\n this.validate();\n }\n\n if (changedProperties.has('disabled')) {\n if (this.disabled) {\n this.internals.setFormValue(null);\n this.internals.states.add('disabled');\n this.inert = true;\n } else {\n this.internals.states.delete('disabled');\n this.internals.setFormValue(this._formValue);\n this.inert = false;\n }\n }\n }\n\n private validate() {\n const wasValid = this.internals.validity.valid;\n const oldMessage = this.internals.validationMessage;\n this.internals.setValidity({});\n\n if (this._valueDateTime) {\n const minDateIsValid =\n !this._minDateTime || this._valueDateTime > this._minDateTime || this._valueDateTime.equals(this._minDateTime);\n if (!minDateIsValid) {\n this.internals.setValidity(\n { rangeUnderflow: true },\n `Date should be equal or after ${this._minDateTime?.toLocaleString({\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n })}`\n );\n return;\n }\n const maxDateIsValid =\n !this._maxDateTime || this._valueDateTime.equals(this._maxDateTime) || this._valueDateTime < this._maxDateTime;\n if (!maxDateIsValid) {\n this.internals.setValidity(\n { rangeOverflow: true },\n `Date should be before or equal to ${this._maxDateTime?.toLocaleString({\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n })}`\n );\n return;\n }\n }\n if (wasValid !== this.internals.validity.valid || oldMessage !== this.internals.validationMessage) {\n this.requestUpdate();\n }\n }\n\n public connectedCallback() {\n super.connectedCallback();\n\n this.addEventListener('date-selection', this.onDateChange);\n this.addEventListener('dialog-open', this._onDialogOpen);\n this.addEventListener('dialog-close', this._onDialogClose);\n this.addEventListener('focusout', this.onFocusOut);\n this.addEventListener('focus', this._onFocus);\n }\n\n private _onDialogOpen = () => {\n this._open = true;\n };\n\n private _onDialogClose = () => {\n this._open = false;\n };\n\n public onFocusOut = (event: FocusEvent) => {\n if (!this._open) return;\n\n const target = (event.relatedTarget ?? event.explicitOriginalTarget) as HTMLElement | null;\n\n if (!this.contains(target)) {\n this.dialog.hide();\n }\n };\n\n private _onFocus = () => {\n this.dateInput.focus();\n };\n\n public disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener('date-selection', this.onDateChange);\n this.removeEventListener('dialog-open', this._onDialogOpen);\n this.removeEventListener('dialog-close', this._onDialogClose);\n this.removeEventListener('focusout', this.onFocusOut);\n this.removeEventListener('focus', this._onFocus);\n }\n\n showCalendar() {\n if (!this._open) {\n this.dialog.show();\n\n if (this.openLeft) {\n this.style.setProperty('--calendar-left-distance', '-192px');\n }\n } else {\n this.dialog.hide();\n }\n }\n\n render() {\n return html`\n <div part=\"controls\" aria-invalid=${!this.internals.validity.valid} aria-disabled=\"${this.disabled}\">\n <div name=\"container\" part=\"container\">\n <tt-date-input @change=${this.onDateChange} .value=${this.value} .disabled=${this.disabled}></tt-date-input>\n </div>\n <button\n name=\"Show calendar\"\n @click=${this.showCalendar}\n class=\"show-calendar\"\n aria-label=\"Choose date, ${this}\"\n ?disabled=${this.disabled}\n >\n ${unsafeSVG(calendarIcon)}\n </button>\n </div>\n <tt-dialog name=\"calendar\" aria-label=\"Choose date\" part=\"dialog\">\n <tt-calendar\n .value=\"${this.value}\"\n .minDate=${this.minDate}\n .maxDate=${this.maxDate}\n part=\"calendar\"\n ></tt-calendar>\n </tt-dialog>\n <div class=\"errormessage\" id=\"error-msg-${this.id}\" role=\"alert\" aria-atomic=\"true\" part=\"error\">\n ${this.internals.validity.valid ? nothing : this.internals.validationMessage}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'tt-date-picker': TtDatePicker;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"TtDatePicker.js","sourceRoot":"","sources":["../../../src/TtDatePicker.ts"],"names":[],"mappings":"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","sourcesContent":["import { css, html, LitElement, nothing, PropertyValues } from 'lit';\nimport { property, query, state } from 'lit/decorators.js';\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js';\nimport { DateTime } from 'luxon';\nimport { Calendar } from '@triptease/tt-calendar';\nimport { calendarIcon } from '@triptease/icons';\nimport { TtDialog } from '@triptease/tt-dialog';\nimport { DateInput } from '@triptease/tt-date-input';\nimport { DateSelectionEvent } from '@triptease/tt-calendar/date-selection-context.js';\nimport { dateConverter } from './helpers.js';\nimport { styles } from './styles.js';\n\nexport class TtDatePicker extends LitElement {\n static styles = [\n styles,\n css`\n [part='controls'] {\n min-width: 19.1ch;\n }\n `,\n ];\n\n static formAssociated = true;\n\n static shadowRootOptions = {\n ...LitElement.shadowRootOptions,\n delegatesFocus: true,\n };\n\n @query('tt-calendar')\n calendar!: Calendar;\n\n @query('tt-dialog')\n dialog!: TtDialog;\n\n @property({ type: String })\n public value?: string;\n\n @property({\n type: Date,\n converter: dateConverter,\n })\n public minDate?: Date;\n\n @property({\n type: Date,\n converter: dateConverter,\n })\n public maxDate?: Date;\n\n @property({ type: Boolean, attribute: 'open-left' })\n public openLeft = false;\n\n @property({ type: Boolean })\n public disabled = false;\n\n // Internal DateTime properties for calculations\n private get _valueDateTime(): DateTime | undefined {\n return this.value ? DateTime.fromISO(this.value) : undefined;\n }\n\n private get _minDateTime(): DateTime | undefined {\n return this.minDate ? DateTime.fromJSDate(this.minDate) : undefined;\n }\n\n private get _maxDateTime(): DateTime | undefined {\n return this.maxDate ? DateTime.fromJSDate(this.maxDate) : undefined;\n }\n\n @state()\n private _open: boolean = false;\n\n @query('tt-date-input')\n private dateInput!: DateInput;\n\n public internals: ReturnType<typeof this.attachInternals>;\n\n private get _formValue(): string {\n return this.value ?? '';\n }\n\n constructor() {\n super();\n this.internals = this.attachInternals();\n }\n\n onDateChange(e: Event) {\n if (DateSelectionEvent.is(e)) {\n this.value = e.detail;\n } else if (e.type === 'change') {\n this.value = (e.target as HTMLInputElement).value;\n }\n\n this.dispatchEvent(new InputEvent('change'));\n this.dialog.hide();\n }\n\n get form(): HTMLFormElement | null {\n return this.internals.form;\n }\n\n public updated(changedProperties: PropertyValues) {\n super.updated(changedProperties);\n\n if (changedProperties.has('value')) {\n this.internals.setFormValue(this._formValue);\n this.validate();\n }\n\n if (changedProperties.has('disabled')) {\n if (this.disabled) {\n this.internals.setFormValue(null);\n this.internals.states.add('disabled');\n this.inert = true;\n } else {\n this.internals.states.delete('disabled');\n this.internals.setFormValue(this._formValue);\n this.inert = false;\n }\n }\n }\n\n private validate() {\n const wasValid = this.internals.validity.valid;\n const oldMessage = this.internals.validationMessage;\n this.internals.setValidity({});\n\n if (this._valueDateTime) {\n const minDateIsValid =\n !this._minDateTime || this._valueDateTime > this._minDateTime || this._valueDateTime.equals(this._minDateTime);\n if (!minDateIsValid) {\n this.internals.setValidity(\n { rangeUnderflow: true },\n `Date should be equal or after ${this._minDateTime?.toLocaleString({\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n })}`\n );\n return;\n }\n const maxDateIsValid =\n !this._maxDateTime || this._valueDateTime.equals(this._maxDateTime) || this._valueDateTime < this._maxDateTime;\n if (!maxDateIsValid) {\n this.internals.setValidity(\n { rangeOverflow: true },\n `Date should be before or equal to ${this._maxDateTime?.toLocaleString({\n month: 'short',\n day: 'numeric',\n year: 'numeric',\n })}`\n );\n return;\n }\n }\n if (wasValid !== this.internals.validity.valid || oldMessage !== this.internals.validationMessage) {\n this.requestUpdate();\n }\n }\n\n public connectedCallback() {\n super.connectedCallback();\n\n this.addEventListener('date-selection', this.onDateChange);\n this.addEventListener('dialog-open', this._onDialogOpen);\n this.addEventListener('dialog-close', this._onDialogClose);\n this.addEventListener('focusout', this.onFocusOut);\n this.addEventListener('focus', this._onFocus);\n }\n\n private _onDialogOpen = () => {\n this._open = true;\n };\n\n private _onDialogClose = () => {\n this._open = false;\n this.internals.states.delete('open-above');\n };\n\n public onFocusOut = (event: FocusEvent) => {\n if (!this._open) return;\n\n const target = (event.relatedTarget ?? event.explicitOriginalTarget) as HTMLElement | null;\n\n if (!this.contains(target)) {\n this.dialog.hide();\n }\n };\n\n private _onFocus = () => {\n this.dateInput.focus();\n };\n\n public disconnectedCallback() {\n super.disconnectedCallback();\n this.removeEventListener('date-selection', this.onDateChange);\n this.removeEventListener('dialog-open', this._onDialogOpen);\n this.removeEventListener('dialog-close', this._onDialogClose);\n this.removeEventListener('focusout', this.onFocusOut);\n this.removeEventListener('focus', this._onFocus);\n }\n\n showCalendar() {\n if (!this._open) {\n const rect = this.getBoundingClientRect();\n if (!this.openLeft && rect.top > window.innerHeight - rect.bottom) {\n this.internals.states.add('open-above');\n } else {\n this.internals.states.delete('open-above');\n }\n\n this.dialog.show();\n\n if (this.openLeft) {\n this.style.setProperty('--calendar-left-distance', '-192px');\n }\n } else {\n this.dialog.hide();\n }\n }\n\n render() {\n return html`\n <div part=\"controls\" aria-invalid=${!this.internals.validity.valid} aria-disabled=\"${this.disabled}\">\n <div name=\"container\" part=\"container\">\n <tt-date-input @change=${this.onDateChange} .value=${this.value} .disabled=${this.disabled}></tt-date-input>\n </div>\n <button\n name=\"Show calendar\"\n @click=${this.showCalendar}\n class=\"show-calendar\"\n aria-label=\"Choose date, ${this}\"\n ?disabled=${this.disabled}\n >\n ${unsafeSVG(calendarIcon)}\n </button>\n </div>\n <tt-dialog name=\"calendar\" aria-label=\"Choose date\" part=\"dialog\">\n <tt-calendar\n .value=\"${this.value}\"\n .minDate=${this.minDate}\n .maxDate=${this.maxDate}\n part=\"calendar\"\n ></tt-calendar>\n </tt-dialog>\n <div class=\"errormessage\" id=\"error-msg-${this.id}\" role=\"alert\" aria-atomic=\"true\" part=\"error\">\n ${this.internals.validity.valid ? nothing : this.internals.validationMessage}\n </div>\n `;\n }\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'tt-date-picker': TtDatePicker;\n }\n}\n"]}
|
package/dist/esm/src/styles.js
CHANGED
|
@@ -72,6 +72,26 @@ export const styles = css `
|
|
|
72
72
|
position-anchor: --date-picker;
|
|
73
73
|
position: fixed;
|
|
74
74
|
z-index: 1;
|
|
75
|
+
inset-block-start: anchor(bottom);
|
|
76
|
+
margin-block-start: var(--space-scale-1);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
[part='dialog']::part(dialog) {
|
|
80
|
+
margin-top: 0;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
:host(:state(open-above)) [part='dialog'] {
|
|
84
|
+
inset-block-start: auto;
|
|
85
|
+
margin-block-start: 0;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
:host(:state(open-above)) [part='dialog']::part(dialog) {
|
|
89
|
+
position: fixed;
|
|
90
|
+
position-anchor: --date-picker;
|
|
91
|
+
bottom: anchor(top);
|
|
92
|
+
top: auto;
|
|
93
|
+
left: anchor(left);
|
|
94
|
+
margin-bottom: var(--space-scale-1);
|
|
75
95
|
}
|
|
76
96
|
}
|
|
77
97
|
`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../src/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA
|
|
1
|
+
{"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../src/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAE1B,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+FxB,CAAC","sourcesContent":["import { css } from 'lit';\n\nexport const styles = css`\n :host {\n position: relative;\n anchor-name: --date-picker;\n anchor-scope: --date-picker;\n }\n\n :host(:state(disabled)) {\n pointer-events: none;\n opacity: 0.5;\n }\n\n tt-side-panel::part(side-panel) {\n border-right: 1px solid var(--color-border-200);\n }\n\n tt-side-panel:empty {\n display: none;\n }\n\n [part='container'] {\n padding: var(--space-scale-1) var(--space-scale-1-5);\n gap: var(--space-scale-1);\n }\n\n [part='controls'] {\n display: flex;\n border: 1px solid var(--color-border-200);\n border-radius: var(--border-radius);\n width: fit-content;\n height: var(--date-picker-height, fit-content);\n background-color: var(--color-surface-100);\n font-size: var(--font-size-200);\n color: var(--color-text-400);\n align-items: stretch;\n justify-content: space-around;\n padding: 0;\n\n &[aria-invalid='true'] {\n outline: 2px solid var(--color-alert-strong);\n }\n\n button {\n border: 0;\n padding-inline: var(--space-scale-1);\n background-color: transparent;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n align-self: stretch;\n border-left: 1px solid var(--color-border-200);\n box-sizing: border-box;\n color: var(--color-text-400);\n }\n\n &:has(+ tt-dialog[open]) .show-calendar svg,\n .show-calendar:hover svg {\n color: var(--color-primary-400);\n }\n }\n\n [part='dialog']::part(dialog) {\n margin-top: var(--space-scale-1);\n flex-direction: row-reverse;\n }\n\n /** If supported, use CSS anchor positioning, which allows the dialog to escape overflow containers */\n @supports (position-anchor: --date-picker) {\n [part='dialog'] {\n position-anchor: --date-picker;\n position: fixed;\n z-index: 1;\n inset-block-start: anchor(bottom);\n margin-block-start: var(--space-scale-1);\n }\n\n [part='dialog']::part(dialog) {\n margin-top: 0;\n }\n\n :host(:state(open-above)) [part='dialog'] {\n inset-block-start: auto;\n margin-block-start: 0;\n }\n\n :host(:state(open-above)) [part='dialog']::part(dialog) {\n position: fixed;\n position-anchor: --date-picker;\n bottom: anchor(top);\n top: auto;\n left: anchor(left);\n margin-bottom: var(--space-scale-1);\n }\n }\n`;\n"]}
|
|
@@ -43,6 +43,42 @@ describe('TtDatePicker', () => {
|
|
|
43
43
|
expect(eventValue).to.equal(expectedEndDate);
|
|
44
44
|
});
|
|
45
45
|
});
|
|
46
|
+
it('should add open-above state when there is more space above than below', async () => {
|
|
47
|
+
const datePicker = await fixture(html ` <tt-date-picker></tt-date-picker> `);
|
|
48
|
+
datePicker.getBoundingClientRect = () => ({ top: 9999, bottom: 10000, left: 0, right: 200, width: 200, height: 1, x: 0, y: 9999, toJSON: () => { } });
|
|
49
|
+
const button = datePicker.shadowRoot.querySelector('[name="Show calendar"]');
|
|
50
|
+
button.click();
|
|
51
|
+
await elementUpdated(datePicker);
|
|
52
|
+
expect(datePicker.internals.states.has('open-above')).to.be.true;
|
|
53
|
+
});
|
|
54
|
+
it('should not add open-above state when there is more space below', async () => {
|
|
55
|
+
const datePicker = await fixture(html ` <tt-date-picker></tt-date-picker> `);
|
|
56
|
+
datePicker.getBoundingClientRect = () => ({ top: 0, bottom: 40, left: 0, right: 200, width: 200, height: 40, x: 0, y: 0, toJSON: () => { } });
|
|
57
|
+
const button = datePicker.shadowRoot.querySelector('[name="Show calendar"]');
|
|
58
|
+
button.click();
|
|
59
|
+
await elementUpdated(datePicker);
|
|
60
|
+
expect(datePicker.internals.states.has('open-above')).to.be.false;
|
|
61
|
+
});
|
|
62
|
+
it('should clear open-above state when dialog is closed', async () => {
|
|
63
|
+
const datePicker = await fixture(html ` <tt-date-picker></tt-date-picker> `);
|
|
64
|
+
datePicker.getBoundingClientRect = () => ({ top: 9999, bottom: 10000, left: 0, right: 200, width: 200, height: 1, x: 0, y: 9999, toJSON: () => { } });
|
|
65
|
+
const button = datePicker.shadowRoot.querySelector('[name="Show calendar"]');
|
|
66
|
+
button.click();
|
|
67
|
+
await elementUpdated(datePicker);
|
|
68
|
+
expect(datePicker.internals.states.has('open-above')).to.be.true;
|
|
69
|
+
const dialog = datePicker.shadowRoot.querySelector('tt-dialog');
|
|
70
|
+
dialog.hide();
|
|
71
|
+
await elementUpdated(datePicker);
|
|
72
|
+
expect(datePicker.internals.states.has('open-above')).to.be.false;
|
|
73
|
+
});
|
|
74
|
+
it('should not add open-above state when open-left is set', async () => {
|
|
75
|
+
const datePicker = await fixture(html ` <tt-date-picker open-left></tt-date-picker> `);
|
|
76
|
+
datePicker.getBoundingClientRect = () => ({ top: 9999, bottom: 10000, left: 0, right: 200, width: 200, height: 1, x: 0, y: 9999, toJSON: () => { } });
|
|
77
|
+
const button = datePicker.shadowRoot.querySelector('[name="Show calendar"]');
|
|
78
|
+
button.click();
|
|
79
|
+
await elementUpdated(datePicker);
|
|
80
|
+
expect(datePicker.internals.states.has('open-above')).to.be.false;
|
|
81
|
+
});
|
|
46
82
|
it('should disable the date picker when disabled attribute is set', async () => {
|
|
47
83
|
const datePicker = await fixture(html `
|
|
48
84
|
<tt-date-picker value="2025-05-01" disabled></tt-date-picker>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"date-picker.test.js","sourceRoot":"","sources":["../../../test/date-picker.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { elementUpdated, expect, fixture, oneDefaultPreventedEvent, oneEvent } from '@open-wc/testing';\nimport { html } from 'lit';\nimport { Settings } from 'luxon';\nimport { TtDialog } from '@triptease/tt-dialog';\nimport '../src/index.js'; // This handles the registration\nimport { TtDatePicker } from '../src/index.js';\n\ndescribe('TtDatePicker', () => {\n afterEach(() => {\n Settings.defaultZone = 'system';\n });\n\n ['Australia/Brisbane', 'America/New_York', 'Europe/London', 'Asia/Tokyo', 'Etc/UTC'].forEach((timezone) => {\n it('should include date value in form submission data', async () => {\n Settings.defaultZone = timezone;\n const form = await fixture<HTMLFormElement>(html`\n <form method=\"post\" action=\"#\">\n <input type=\"text\" name=\"other_field\" value=\"test_value\" />\n <tt-date-picker name=\"booking_date\" value=\"2025-04-16\"></tt-date-picker>\n <button type=\"submit\">Submit</button>\n </form>\n `);\n\n const datePicker = form.querySelector('tt-date-picker') as TtDatePicker;\n expect(datePicker).to.exist;\n\n await elementUpdated(datePicker);\n\n setTimeout(() => form.querySelector('button')!.click());\n await oneDefaultPreventedEvent(form, 'submit');\n\n const formData = new FormData(form);\n const dateValue = formData.get('booking_date');\n const expectedDate = `2025-04-16`;\n\n expect(dateValue).to.equal(expectedDate);\n });\n\n it(`should emit change event on date selection for ${timezone}`, async () => {\n Settings.defaultZone = timezone;\n const datePicker = await fixture<TtDatePicker>(html` <tt-date-picker value=\"2025-05-01\"></tt-date-picker> `);\n\n const showCalendarButton = datePicker.shadowRoot!.querySelector('[name=\"Show calendar\"]') as HTMLButtonElement;\n showCalendarButton.click();\n await elementUpdated(datePicker);\n\n const changeEventPromise = oneEvent(datePicker, 'change');\n\n const calendar = datePicker.shadowRoot!.querySelector('tt-calendar')!;\n const desiredDate = calendar.shadowRoot!.querySelector(\n '[role=\"gridcell\"][data-date=\"2025-05-02\"]'\n ) as HTMLLIElement;\n desiredDate.click();\n await elementUpdated(datePicker);\n\n const event = await changeEventPromise;\n const eventValue = (event.target as TtDatePicker).value;\n\n const expectedEndDate = '2025-05-02';\n\n expect(eventValue).to.equal(expectedEndDate);\n });\n });\n\n it('should disable the date picker when disabled attribute is set', async () => {\n const datePicker = await fixture<TtDatePicker>(html`\n <tt-date-picker value=\"2025-05-01\" disabled></tt-date-picker>\n `);\n\n expect(datePicker.inert).to.be.true;\n\n const showCalendarButton = datePicker.shadowRoot!.querySelector('button.show-calendar') as HTMLButtonElement;\n showCalendarButton.click();\n\n const dialog = datePicker.shadowRoot!.querySelector('tt-dialog') as TtDialog;\n expect(dialog.open).to.be.false;\n });\n});\n"]}
|
|
1
|
+
{"version":3,"file":"date-picker.test.js","sourceRoot":"","sources":["../../../test/date-picker.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { elementUpdated, expect, fixture, oneDefaultPreventedEvent, oneEvent } from '@open-wc/testing';\nimport { html } from 'lit';\nimport { Settings } from 'luxon';\nimport { TtDialog } from '@triptease/tt-dialog';\nimport '../src/index.js'; // This handles the registration\nimport { TtDatePicker } from '../src/index.js';\n\ndescribe('TtDatePicker', () => {\n afterEach(() => {\n Settings.defaultZone = 'system';\n });\n\n ['Australia/Brisbane', 'America/New_York', 'Europe/London', 'Asia/Tokyo', 'Etc/UTC'].forEach((timezone) => {\n it('should include date value in form submission data', async () => {\n Settings.defaultZone = timezone;\n const form = await fixture<HTMLFormElement>(html`\n <form method=\"post\" action=\"#\">\n <input type=\"text\" name=\"other_field\" value=\"test_value\" />\n <tt-date-picker name=\"booking_date\" value=\"2025-04-16\"></tt-date-picker>\n <button type=\"submit\">Submit</button>\n </form>\n `);\n\n const datePicker = form.querySelector('tt-date-picker') as TtDatePicker;\n expect(datePicker).to.exist;\n\n await elementUpdated(datePicker);\n\n setTimeout(() => form.querySelector('button')!.click());\n await oneDefaultPreventedEvent(form, 'submit');\n\n const formData = new FormData(form);\n const dateValue = formData.get('booking_date');\n const expectedDate = `2025-04-16`;\n\n expect(dateValue).to.equal(expectedDate);\n });\n\n it(`should emit change event on date selection for ${timezone}`, async () => {\n Settings.defaultZone = timezone;\n const datePicker = await fixture<TtDatePicker>(html` <tt-date-picker value=\"2025-05-01\"></tt-date-picker> `);\n\n const showCalendarButton = datePicker.shadowRoot!.querySelector('[name=\"Show calendar\"]') as HTMLButtonElement;\n showCalendarButton.click();\n await elementUpdated(datePicker);\n\n const changeEventPromise = oneEvent(datePicker, 'change');\n\n const calendar = datePicker.shadowRoot!.querySelector('tt-calendar')!;\n const desiredDate = calendar.shadowRoot!.querySelector(\n '[role=\"gridcell\"][data-date=\"2025-05-02\"]'\n ) as HTMLLIElement;\n desiredDate.click();\n await elementUpdated(datePicker);\n\n const event = await changeEventPromise;\n const eventValue = (event.target as TtDatePicker).value;\n\n const expectedEndDate = '2025-05-02';\n\n expect(eventValue).to.equal(expectedEndDate);\n });\n });\n\n it('should add open-above state when there is more space above than below', async () => {\n const datePicker = await fixture<TtDatePicker>(html` <tt-date-picker></tt-date-picker> `);\n\n datePicker.getBoundingClientRect = () =>\n ({ top: 9999, bottom: 10000, left: 0, right: 200, width: 200, height: 1, x: 0, y: 9999, toJSON: () => {} } as DOMRect);\n\n const button = datePicker.shadowRoot!.querySelector('[name=\"Show calendar\"]') as HTMLButtonElement;\n button.click();\n await elementUpdated(datePicker);\n\n expect(datePicker.internals.states.has('open-above')).to.be.true;\n });\n\n it('should not add open-above state when there is more space below', async () => {\n const datePicker = await fixture<TtDatePicker>(html` <tt-date-picker></tt-date-picker> `);\n\n datePicker.getBoundingClientRect = () =>\n ({ top: 0, bottom: 40, left: 0, right: 200, width: 200, height: 40, x: 0, y: 0, toJSON: () => {} } as DOMRect);\n\n const button = datePicker.shadowRoot!.querySelector('[name=\"Show calendar\"]') as HTMLButtonElement;\n button.click();\n await elementUpdated(datePicker);\n\n expect(datePicker.internals.states.has('open-above')).to.be.false;\n });\n\n it('should clear open-above state when dialog is closed', async () => {\n const datePicker = await fixture<TtDatePicker>(html` <tt-date-picker></tt-date-picker> `);\n\n datePicker.getBoundingClientRect = () =>\n ({ top: 9999, bottom: 10000, left: 0, right: 200, width: 200, height: 1, x: 0, y: 9999, toJSON: () => {} } as DOMRect);\n\n const button = datePicker.shadowRoot!.querySelector('[name=\"Show calendar\"]') as HTMLButtonElement;\n button.click();\n await elementUpdated(datePicker);\n expect(datePicker.internals.states.has('open-above')).to.be.true;\n\n const dialog = datePicker.shadowRoot!.querySelector('tt-dialog') as TtDialog;\n dialog.hide();\n await elementUpdated(datePicker);\n\n expect(datePicker.internals.states.has('open-above')).to.be.false;\n });\n\n it('should not add open-above state when open-left is set', async () => {\n const datePicker = await fixture<TtDatePicker>(html` <tt-date-picker open-left></tt-date-picker> `);\n\n datePicker.getBoundingClientRect = () =>\n ({ top: 9999, bottom: 10000, left: 0, right: 200, width: 200, height: 1, x: 0, y: 9999, toJSON: () => {} } as DOMRect);\n\n const button = datePicker.shadowRoot!.querySelector('[name=\"Show calendar\"]') as HTMLButtonElement;\n button.click();\n await elementUpdated(datePicker);\n\n expect(datePicker.internals.states.has('open-above')).to.be.false;\n });\n\n it('should disable the date picker when disabled attribute is set', async () => {\n const datePicker = await fixture<TtDatePicker>(html`\n <tt-date-picker value=\"2025-05-01\" disabled></tt-date-picker>\n `);\n\n expect(datePicker.inert).to.be.true;\n\n const showCalendarButton = datePicker.shadowRoot!.querySelector('button.show-calendar') as HTMLButtonElement;\n showCalendarButton.click();\n\n const dialog = datePicker.shadowRoot!.querySelector('tt-dialog') as TtDialog;\n expect(dialog.open).to.be.false;\n });\n});\n"]}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "Webcomponent tt-date-picker following open-wc recommendations",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "@triptease",
|
|
6
|
-
"version": "6.3.
|
|
6
|
+
"version": "6.3.5",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "dist/esm/src/index.js",
|
|
9
9
|
"module": "dist/esm/src/index.js",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"@triptease/icons": "1.4.1",
|
|
41
41
|
"@triptease/tt-calendar": "6.3.0",
|
|
42
42
|
"@triptease/tt-date-input": "6.1.2",
|
|
43
|
-
"@triptease/tt-dialog": "5.2.
|
|
43
|
+
"@triptease/tt-dialog": "5.2.2",
|
|
44
44
|
"@types/luxon": "^3.6.2",
|
|
45
45
|
"lit": "^3.1.4",
|
|
46
46
|
"luxon": "^3.6.1"
|