@triptease/tt-multi-date-picker 0.3.1 → 0.4.0

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.
@@ -159,13 +159,16 @@ class TtMultiDatePicker extends lit_1.LitElement {
159
159
  <p class="instructions">Click a date to select it. Shift+click to select a range.</p>
160
160
  <div class="calendar-grid" @click=${this._handleDayClick} @keydown=${this._handleKeyDown} tabindex="0">
161
161
  ${monthList.map((month) => (0, lit_1.html) `
162
- <tt-calendar
163
- display-only
164
- month="${month.toFormat('yyyy-MM')}"
165
- .highlightedRanges=${this.value}
166
- min-date="${(0, if_defined_js_1.ifDefined)(this.minDate)}"
167
- max-date="${(0, if_defined_js_1.ifDefined)(this.maxDate)}"
168
- ></tt-calendar>
162
+ <div class="month-panel">
163
+ <h3 class="month-label">${month.toFormat('MMMM yyyy')}</h3>
164
+ <tt-calendar
165
+ display-only
166
+ month="${month.toFormat('yyyy-MM')}"
167
+ .highlightedRanges=${this.value}
168
+ min-date="${(0, if_defined_js_1.ifDefined)(this.minDate)}"
169
+ max-date="${(0, if_defined_js_1.ifDefined)(this.maxDate)}"
170
+ ></tt-calendar>
171
+ </div>
169
172
  `)}
170
173
  </div>
171
174
  ${this.value.length > 0
@@ -1 +1 @@
1
- {"version":3,"file":"TtMultiDatePicker.js","sourceRoot":"","sources":["../../../src/TtMultiDatePicker.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { DateTime } from 'luxon';\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js';\nimport { chevron } from '@triptease/icons';\nimport '@triptease/tt-calendar/tt-calendar.js';\nimport { styles } from './styles.js';\nimport { toggleDate, extendRange } from './selection-model.js';\nimport type { Selection } from './selection-model.js';\n\nexport class TtMultiDatePicker extends LitElement {\n static formAssociated = true;\n static override styles = styles;\n\n private _internals: ElementInternals;\n\n @property({ type: Number })\n months: 3 | 6 | 12 = 6;\n\n @property({ attribute: 'start-month' })\n startMonth?: string;\n\n @property({ attribute: false })\n value: Selection = [];\n\n @property({ reflect: true }) name: string = '';\n @property({ type: Boolean, reflect: true }) required: boolean = false;\n @property({ attribute: 'min-date' }) minDate?: string;\n @property({ attribute: 'max-date' }) maxDate?: string;\n\n @state()\n private _currentStartMonth: DateTime = DateTime.local().startOf('month');\n\n private _lastClickedDate?: string;\n\n @state()\n private _focusedDate: DateTime = DateTime.local();\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n }\n\n override connectedCallback() {\n super.connectedCallback();\n if (this.startMonth) {\n this._currentStartMonth = DateTime.fromISO(this.startMonth + '-01');\n }\n this._syncForm();\n }\n\n private _syncForm() {\n const val = this.value.length > 0 ? JSON.stringify(this.value) : null;\n this._internals.setFormValue(val);\n if (this.required && this.value.length === 0) {\n this._internals.setValidity({ valueMissing: true }, 'Please select at least one date');\n } else {\n this._internals.setValidity({});\n }\n }\n\n formResetCallback() {\n this.value = [];\n this._lastClickedDate = undefined;\n this._syncForm();\n }\n\n private _getMonthList(): DateTime[] {\n return Array.from({ length: this.months }, (_, i) => this._currentStartMonth.plus({ months: i }));\n }\n\n private _previousPage() {\n this._currentStartMonth = this._currentStartMonth.minus({ months: this.months });\n }\n\n private _nextPage() {\n this._currentStartMonth = this._currentStartMonth.plus({ months: this.months });\n }\n\n private _getDateRangeLabel(): string {\n const first = this._currentStartMonth;\n const last = this._currentStartMonth.plus({ months: this.months - 1 });\n return `${first.toFormat('MMMM yyyy')} — ${last.toFormat('MMMM yyyy')}`;\n }\n\n private _getCalendarForDate(date: DateTime): Element | undefined {\n const monthStr = date.toFormat('yyyy-MM');\n const calendars = this.shadowRoot!.querySelectorAll('tt-calendar');\n for (const cal of calendars) {\n if (cal.getAttribute('month') === monthStr) return cal;\n }\n return undefined;\n }\n\n private _moveFocus(date: DateTime) {\n this._focusedDate = date;\n this.updateComplete.then(() => {\n const cal = this._getCalendarForDate(date) as (Element & { focusDay: (d: DateTime) => void }) | undefined;\n cal?.focusDay(date);\n });\n }\n\n private _applySelection(dateStr: string, shiftKey: boolean) {\n if (shiftKey && this._lastClickedDate) {\n this.value = extendRange(this.value, this._lastClickedDate, dateStr);\n } else {\n this.value = toggleDate(this.value, dateStr);\n }\n\n this._lastClickedDate = dateStr;\n this._syncForm();\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));\n }\n\n private _handleDayClick(event: MouseEvent) {\n const target = event.composedPath()[0] as HTMLElement;\n const dayCell = target.closest?.('.day') ?? (target.classList?.contains('day') ? target : null);\n const dateStr = dayCell?.getAttribute('data-date');\n if (!dateStr) return;\n\n this._focusedDate = DateTime.fromISO(dateStr);\n this._applySelection(dateStr, event.shiftKey);\n }\n\n private _handleKeyDown(event: KeyboardEvent) {\n switch (event.key) {\n case 'ArrowRight':\n event.preventDefault();\n this._moveFocus(this._focusedDate.plus({ days: 1 }));\n break;\n case 'ArrowLeft':\n event.preventDefault();\n this._moveFocus(this._focusedDate.minus({ days: 1 }));\n break;\n case 'ArrowDown':\n event.preventDefault();\n this._moveFocus(this._focusedDate.plus({ weeks: 1 }));\n break;\n case 'ArrowUp':\n event.preventDefault();\n this._moveFocus(this._focusedDate.minus({ weeks: 1 }));\n break;\n case 'Home':\n event.preventDefault();\n this._moveFocus(this._focusedDate.startOf('week'));\n break;\n case 'End':\n event.preventDefault();\n this._moveFocus(this._focusedDate.endOf('week'));\n break;\n case 'PageDown':\n event.preventDefault();\n this._nextPage();\n break;\n case 'PageUp':\n event.preventDefault();\n this._previousPage();\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n this._applySelection(this._focusedDate.toISODate()!, event.shiftKey);\n break;\n }\n }\n\n private _clearAll() {\n this.value = [];\n this._lastClickedDate = undefined;\n this._syncForm();\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));\n }\n\n override render() {\n const monthList = this._getMonthList();\n\n return html`\n <div class=\"navigation\">\n <button @click=${this._previousPage} aria-label=\"Previous ${this.months} months\">${unsafeSVG(chevron)}</button>\n <h2>${this._getDateRangeLabel()}</h2>\n <button @click=${this._nextPage} aria-label=\"Next ${this.months} months\" class=\"right\">\n ${unsafeSVG(chevron)}\n </button>\n </div>\n <p class=\"instructions\">Click a date to select it. Shift+click to select a range.</p>\n <div class=\"calendar-grid\" @click=${this._handleDayClick} @keydown=${this._handleKeyDown} tabindex=\"0\">\n ${monthList.map(\n (month) => html`\n <tt-calendar\n display-only\n month=\"${month.toFormat('yyyy-MM')}\"\n .highlightedRanges=${this.value}\n min-date=\"${ifDefined(this.minDate)}\"\n max-date=\"${ifDefined(this.maxDate)}\"\n ></tt-calendar>\n `\n )}\n </div>\n ${this.value.length > 0\n ? html`\n <div class=\"footer\">\n <span class=\"selection-summary\">${this.value.length} selection${this.value.length > 1 ? 's' : ''}</span>\n <button data-action=\"clear\" data-theme=\"secondary\" @click=${this._clearAll}>Clear all</button>\n </div>\n `\n : nothing}\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"TtMultiDatePicker.js","sourceRoot":"","sources":["../../../src/TtMultiDatePicker.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { DateTime } from 'luxon';\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js';\nimport { chevron } from '@triptease/icons';\nimport '@triptease/tt-calendar/tt-calendar.js';\nimport { styles } from './styles.js';\nimport { toggleDate, extendRange } from './selection-model.js';\nimport type { Selection } from './selection-model.js';\n\nexport class TtMultiDatePicker extends LitElement {\n static formAssociated = true;\n static override styles = styles;\n\n private _internals: ElementInternals;\n\n @property({ type: Number })\n months: 3 | 6 | 12 = 6;\n\n @property({ attribute: 'start-month' })\n startMonth?: string;\n\n @property({ attribute: false })\n value: Selection = [];\n\n @property({ reflect: true }) name: string = '';\n @property({ type: Boolean, reflect: true }) required: boolean = false;\n @property({ attribute: 'min-date' }) minDate?: string;\n @property({ attribute: 'max-date' }) maxDate?: string;\n\n @state()\n private _currentStartMonth: DateTime = DateTime.local().startOf('month');\n\n private _lastClickedDate?: string;\n\n @state()\n private _focusedDate: DateTime = DateTime.local();\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n }\n\n override connectedCallback() {\n super.connectedCallback();\n if (this.startMonth) {\n this._currentStartMonth = DateTime.fromISO(this.startMonth + '-01');\n }\n this._syncForm();\n }\n\n private _syncForm() {\n const val = this.value.length > 0 ? JSON.stringify(this.value) : null;\n this._internals.setFormValue(val);\n if (this.required && this.value.length === 0) {\n this._internals.setValidity({ valueMissing: true }, 'Please select at least one date');\n } else {\n this._internals.setValidity({});\n }\n }\n\n formResetCallback() {\n this.value = [];\n this._lastClickedDate = undefined;\n this._syncForm();\n }\n\n private _getMonthList(): DateTime[] {\n return Array.from({ length: this.months }, (_, i) => this._currentStartMonth.plus({ months: i }));\n }\n\n private _previousPage() {\n this._currentStartMonth = this._currentStartMonth.minus({ months: this.months });\n }\n\n private _nextPage() {\n this._currentStartMonth = this._currentStartMonth.plus({ months: this.months });\n }\n\n private _getDateRangeLabel(): string {\n const first = this._currentStartMonth;\n const last = this._currentStartMonth.plus({ months: this.months - 1 });\n return `${first.toFormat('MMMM yyyy')} — ${last.toFormat('MMMM yyyy')}`;\n }\n\n private _getCalendarForDate(date: DateTime): Element | undefined {\n const monthStr = date.toFormat('yyyy-MM');\n const calendars = this.shadowRoot!.querySelectorAll('tt-calendar');\n for (const cal of calendars) {\n if (cal.getAttribute('month') === monthStr) return cal;\n }\n return undefined;\n }\n\n private _moveFocus(date: DateTime) {\n this._focusedDate = date;\n this.updateComplete.then(() => {\n const cal = this._getCalendarForDate(date) as (Element & { focusDay: (d: DateTime) => void }) | undefined;\n cal?.focusDay(date);\n });\n }\n\n private _applySelection(dateStr: string, shiftKey: boolean) {\n if (shiftKey && this._lastClickedDate) {\n this.value = extendRange(this.value, this._lastClickedDate, dateStr);\n } else {\n this.value = toggleDate(this.value, dateStr);\n }\n\n this._lastClickedDate = dateStr;\n this._syncForm();\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));\n }\n\n private _handleDayClick(event: MouseEvent) {\n const target = event.composedPath()[0] as HTMLElement;\n const dayCell = target.closest?.('.day') ?? (target.classList?.contains('day') ? target : null);\n const dateStr = dayCell?.getAttribute('data-date');\n if (!dateStr) return;\n\n this._focusedDate = DateTime.fromISO(dateStr);\n this._applySelection(dateStr, event.shiftKey);\n }\n\n private _handleKeyDown(event: KeyboardEvent) {\n switch (event.key) {\n case 'ArrowRight':\n event.preventDefault();\n this._moveFocus(this._focusedDate.plus({ days: 1 }));\n break;\n case 'ArrowLeft':\n event.preventDefault();\n this._moveFocus(this._focusedDate.minus({ days: 1 }));\n break;\n case 'ArrowDown':\n event.preventDefault();\n this._moveFocus(this._focusedDate.plus({ weeks: 1 }));\n break;\n case 'ArrowUp':\n event.preventDefault();\n this._moveFocus(this._focusedDate.minus({ weeks: 1 }));\n break;\n case 'Home':\n event.preventDefault();\n this._moveFocus(this._focusedDate.startOf('week'));\n break;\n case 'End':\n event.preventDefault();\n this._moveFocus(this._focusedDate.endOf('week'));\n break;\n case 'PageDown':\n event.preventDefault();\n this._nextPage();\n break;\n case 'PageUp':\n event.preventDefault();\n this._previousPage();\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n this._applySelection(this._focusedDate.toISODate()!, event.shiftKey);\n break;\n }\n }\n\n private _clearAll() {\n this.value = [];\n this._lastClickedDate = undefined;\n this._syncForm();\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));\n }\n\n override render() {\n const monthList = this._getMonthList();\n\n return html`\n <div class=\"navigation\">\n <button @click=${this._previousPage} aria-label=\"Previous ${this.months} months\">${unsafeSVG(chevron)}</button>\n <h2>${this._getDateRangeLabel()}</h2>\n <button @click=${this._nextPage} aria-label=\"Next ${this.months} months\" class=\"right\">\n ${unsafeSVG(chevron)}\n </button>\n </div>\n <p class=\"instructions\">Click a date to select it. Shift+click to select a range.</p>\n <div class=\"calendar-grid\" @click=${this._handleDayClick} @keydown=${this._handleKeyDown} tabindex=\"0\">\n ${monthList.map(\n (month) => html`\n <div class=\"month-panel\">\n <h3 class=\"month-label\">${month.toFormat('MMMM yyyy')}</h3>\n <tt-calendar\n display-only\n month=\"${month.toFormat('yyyy-MM')}\"\n .highlightedRanges=${this.value}\n min-date=\"${ifDefined(this.minDate)}\"\n max-date=\"${ifDefined(this.maxDate)}\"\n ></tt-calendar>\n </div>\n `\n )}\n </div>\n ${this.value.length > 0\n ? html`\n <div class=\"footer\">\n <span class=\"selection-summary\">${this.value.length} selection${this.value.length > 1 ? 's' : ''}</span>\n <button data-action=\"clear\" data-theme=\"secondary\" @click=${this._clearAll}>Clear all</button>\n </div>\n `\n : nothing}\n `;\n }\n}\n"]}
@@ -41,6 +41,7 @@ exports.styles = [
41
41
 
42
42
  tt-calendar {
43
43
  --tt-calendar-range-bg: var(--color-primary-400);
44
+ --tt-calendar-range-color: var(--color-text-100);
44
45
  }
45
46
 
46
47
  .calendar-grid {
@@ -50,6 +51,14 @@ exports.styles = [
50
51
  padding: var(--space-scale-3);
51
52
  }
52
53
 
54
+ .month-label {
55
+ font-size: var(--font-size-200);
56
+ font-weight: var(--font-weight-semibold);
57
+ color: var(--color-text-500);
58
+ margin: 0 0 var(--space-scale-1) 0;
59
+ text-align: center;
60
+ }
61
+
53
62
  .footer {
54
63
  display: flex;
55
64
  justify-content: space-between;
@@ -1 +1 @@
1
- {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../src/styles.ts"],"names":[],"mappings":";;;AAAA,6BAA0B;AAC1B,mDAAiE;AAEpD,QAAA,MAAM,GAAG;IACpB,YAAU;IACV,IAAA,SAAG,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDF;CACF,CAAC","sourcesContent":["import { css } from 'lit';\nimport { styles as baseStyles } from '@triptease/stylesheet/lit';\n\nexport const styles = [\n baseStyles,\n css`\n :host {\n display: block;\n }\n\n .navigation {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: var(--space-scale-2) var(--space-scale-3);\n border-bottom: 1px solid var(--color-border-200);\n }\n\n .navigation button svg {\n display: block;\n }\n\n .navigation button.right svg {\n transform: rotate(180deg);\n }\n\n .navigation h2 {\n font-weight: var(--font-weight-semibold);\n font-size: var(--font-size-400);\n color: var(--color-text-500);\n }\n\n .instructions {\n margin: 0;\n padding: var(--space-scale-1) var(--space-scale-3);\n font-size: var(--font-size-100);\n color: var(--color-text-400);\n }\n\n tt-calendar {\n --tt-calendar-range-bg: var(--color-primary-400);\n }\n\n .calendar-grid {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: var(--space-scale-3);\n padding: var(--space-scale-3);\n }\n\n .footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: var(--space-scale-2) var(--space-scale-3);\n border-top: 1px solid var(--color-border-200);\n }\n\n .selection-summary {\n font-size: var(--font-size-100);\n color: var(--color-text-400);\n }\n `,\n];\n"]}
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../src/styles.ts"],"names":[],"mappings":";;;AAAA,6BAA0B;AAC1B,mDAAiE;AAEpD,QAAA,MAAM,GAAG;IACpB,YAAU;IACV,IAAA,SAAG,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEF;CACF,CAAC","sourcesContent":["import { css } from 'lit';\nimport { styles as baseStyles } from '@triptease/stylesheet/lit';\n\nexport const styles = [\n baseStyles,\n css`\n :host {\n display: block;\n }\n\n .navigation {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: var(--space-scale-2) var(--space-scale-3);\n border-bottom: 1px solid var(--color-border-200);\n }\n\n .navigation button svg {\n display: block;\n }\n\n .navigation button.right svg {\n transform: rotate(180deg);\n }\n\n .navigation h2 {\n font-weight: var(--font-weight-semibold);\n font-size: var(--font-size-400);\n color: var(--color-text-500);\n }\n\n .instructions {\n margin: 0;\n padding: var(--space-scale-1) var(--space-scale-3);\n font-size: var(--font-size-100);\n color: var(--color-text-400);\n }\n\n tt-calendar {\n --tt-calendar-range-bg: var(--color-primary-400);\n --tt-calendar-range-color: var(--color-text-100);\n }\n\n .calendar-grid {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: var(--space-scale-3);\n padding: var(--space-scale-3);\n }\n\n .month-label {\n font-size: var(--font-size-200);\n font-weight: var(--font-weight-semibold);\n color: var(--color-text-500);\n margin: 0 0 var(--space-scale-1) 0;\n text-align: center;\n }\n\n .footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: var(--space-scale-2) var(--space-scale-3);\n border-top: 1px solid var(--color-border-200);\n }\n\n .selection-summary {\n font-size: var(--font-size-100);\n color: var(--color-text-400);\n }\n `,\n];\n"]}
@@ -156,13 +156,16 @@ export class TtMultiDatePicker extends LitElement {
156
156
  <p class="instructions">Click a date to select it. Shift+click to select a range.</p>
157
157
  <div class="calendar-grid" @click=${this._handleDayClick} @keydown=${this._handleKeyDown} tabindex="0">
158
158
  ${monthList.map((month) => html `
159
- <tt-calendar
160
- display-only
161
- month="${month.toFormat('yyyy-MM')}"
162
- .highlightedRanges=${this.value}
163
- min-date="${ifDefined(this.minDate)}"
164
- max-date="${ifDefined(this.maxDate)}"
165
- ></tt-calendar>
159
+ <div class="month-panel">
160
+ <h3 class="month-label">${month.toFormat('MMMM yyyy')}</h3>
161
+ <tt-calendar
162
+ display-only
163
+ month="${month.toFormat('yyyy-MM')}"
164
+ .highlightedRanges=${this.value}
165
+ min-date="${ifDefined(this.minDate)}"
166
+ max-date="${ifDefined(this.maxDate)}"
167
+ ></tt-calendar>
168
+ </div>
166
169
  `)}
167
170
  </div>
168
171
  ${this.value.length > 0
@@ -1 +1 @@
1
- {"version":3,"file":"TtMultiDatePicker.js","sourceRoot":"","sources":["../../../src/TtMultiDatePicker.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { DateTime } from 'luxon';\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js';\nimport { chevron } from '@triptease/icons';\nimport '@triptease/tt-calendar/tt-calendar.js';\nimport { styles } from './styles.js';\nimport { toggleDate, extendRange } from './selection-model.js';\nimport type { Selection } from './selection-model.js';\n\nexport class TtMultiDatePicker extends LitElement {\n static formAssociated = true;\n static override styles = styles;\n\n private _internals: ElementInternals;\n\n @property({ type: Number })\n months: 3 | 6 | 12 = 6;\n\n @property({ attribute: 'start-month' })\n startMonth?: string;\n\n @property({ attribute: false })\n value: Selection = [];\n\n @property({ reflect: true }) name: string = '';\n @property({ type: Boolean, reflect: true }) required: boolean = false;\n @property({ attribute: 'min-date' }) minDate?: string;\n @property({ attribute: 'max-date' }) maxDate?: string;\n\n @state()\n private _currentStartMonth: DateTime = DateTime.local().startOf('month');\n\n private _lastClickedDate?: string;\n\n @state()\n private _focusedDate: DateTime = DateTime.local();\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n }\n\n override connectedCallback() {\n super.connectedCallback();\n if (this.startMonth) {\n this._currentStartMonth = DateTime.fromISO(this.startMonth + '-01');\n }\n this._syncForm();\n }\n\n private _syncForm() {\n const val = this.value.length > 0 ? JSON.stringify(this.value) : null;\n this._internals.setFormValue(val);\n if (this.required && this.value.length === 0) {\n this._internals.setValidity({ valueMissing: true }, 'Please select at least one date');\n } else {\n this._internals.setValidity({});\n }\n }\n\n formResetCallback() {\n this.value = [];\n this._lastClickedDate = undefined;\n this._syncForm();\n }\n\n private _getMonthList(): DateTime[] {\n return Array.from({ length: this.months }, (_, i) => this._currentStartMonth.plus({ months: i }));\n }\n\n private _previousPage() {\n this._currentStartMonth = this._currentStartMonth.minus({ months: this.months });\n }\n\n private _nextPage() {\n this._currentStartMonth = this._currentStartMonth.plus({ months: this.months });\n }\n\n private _getDateRangeLabel(): string {\n const first = this._currentStartMonth;\n const last = this._currentStartMonth.plus({ months: this.months - 1 });\n return `${first.toFormat('MMMM yyyy')} — ${last.toFormat('MMMM yyyy')}`;\n }\n\n private _getCalendarForDate(date: DateTime): Element | undefined {\n const monthStr = date.toFormat('yyyy-MM');\n const calendars = this.shadowRoot!.querySelectorAll('tt-calendar');\n for (const cal of calendars) {\n if (cal.getAttribute('month') === monthStr) return cal;\n }\n return undefined;\n }\n\n private _moveFocus(date: DateTime) {\n this._focusedDate = date;\n this.updateComplete.then(() => {\n const cal = this._getCalendarForDate(date) as (Element & { focusDay: (d: DateTime) => void }) | undefined;\n cal?.focusDay(date);\n });\n }\n\n private _applySelection(dateStr: string, shiftKey: boolean) {\n if (shiftKey && this._lastClickedDate) {\n this.value = extendRange(this.value, this._lastClickedDate, dateStr);\n } else {\n this.value = toggleDate(this.value, dateStr);\n }\n\n this._lastClickedDate = dateStr;\n this._syncForm();\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));\n }\n\n private _handleDayClick(event: MouseEvent) {\n const target = event.composedPath()[0] as HTMLElement;\n const dayCell = target.closest?.('.day') ?? (target.classList?.contains('day') ? target : null);\n const dateStr = dayCell?.getAttribute('data-date');\n if (!dateStr) return;\n\n this._focusedDate = DateTime.fromISO(dateStr);\n this._applySelection(dateStr, event.shiftKey);\n }\n\n private _handleKeyDown(event: KeyboardEvent) {\n switch (event.key) {\n case 'ArrowRight':\n event.preventDefault();\n this._moveFocus(this._focusedDate.plus({ days: 1 }));\n break;\n case 'ArrowLeft':\n event.preventDefault();\n this._moveFocus(this._focusedDate.minus({ days: 1 }));\n break;\n case 'ArrowDown':\n event.preventDefault();\n this._moveFocus(this._focusedDate.plus({ weeks: 1 }));\n break;\n case 'ArrowUp':\n event.preventDefault();\n this._moveFocus(this._focusedDate.minus({ weeks: 1 }));\n break;\n case 'Home':\n event.preventDefault();\n this._moveFocus(this._focusedDate.startOf('week'));\n break;\n case 'End':\n event.preventDefault();\n this._moveFocus(this._focusedDate.endOf('week'));\n break;\n case 'PageDown':\n event.preventDefault();\n this._nextPage();\n break;\n case 'PageUp':\n event.preventDefault();\n this._previousPage();\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n this._applySelection(this._focusedDate.toISODate()!, event.shiftKey);\n break;\n }\n }\n\n private _clearAll() {\n this.value = [];\n this._lastClickedDate = undefined;\n this._syncForm();\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));\n }\n\n override render() {\n const monthList = this._getMonthList();\n\n return html`\n <div class=\"navigation\">\n <button @click=${this._previousPage} aria-label=\"Previous ${this.months} months\">${unsafeSVG(chevron)}</button>\n <h2>${this._getDateRangeLabel()}</h2>\n <button @click=${this._nextPage} aria-label=\"Next ${this.months} months\" class=\"right\">\n ${unsafeSVG(chevron)}\n </button>\n </div>\n <p class=\"instructions\">Click a date to select it. Shift+click to select a range.</p>\n <div class=\"calendar-grid\" @click=${this._handleDayClick} @keydown=${this._handleKeyDown} tabindex=\"0\">\n ${monthList.map(\n (month) => html`\n <tt-calendar\n display-only\n month=\"${month.toFormat('yyyy-MM')}\"\n .highlightedRanges=${this.value}\n min-date=\"${ifDefined(this.minDate)}\"\n max-date=\"${ifDefined(this.maxDate)}\"\n ></tt-calendar>\n `\n )}\n </div>\n ${this.value.length > 0\n ? html`\n <div class=\"footer\">\n <span class=\"selection-summary\">${this.value.length} selection${this.value.length > 1 ? 's' : ''}</span>\n <button data-action=\"clear\" data-theme=\"secondary\" @click=${this._clearAll}>Clear all</button>\n </div>\n `\n : nothing}\n `;\n }\n}\n"]}
1
+ {"version":3,"file":"TtMultiDatePicker.js","sourceRoot":"","sources":["../../../src/TtMultiDatePicker.ts"],"names":[],"mappings":"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","sourcesContent":["import { html, LitElement, nothing } from 'lit';\nimport { property, state } from 'lit/decorators.js';\nimport { ifDefined } from 'lit/directives/if-defined.js';\nimport { DateTime } from 'luxon';\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js';\nimport { chevron } from '@triptease/icons';\nimport '@triptease/tt-calendar/tt-calendar.js';\nimport { styles } from './styles.js';\nimport { toggleDate, extendRange } from './selection-model.js';\nimport type { Selection } from './selection-model.js';\n\nexport class TtMultiDatePicker extends LitElement {\n static formAssociated = true;\n static override styles = styles;\n\n private _internals: ElementInternals;\n\n @property({ type: Number })\n months: 3 | 6 | 12 = 6;\n\n @property({ attribute: 'start-month' })\n startMonth?: string;\n\n @property({ attribute: false })\n value: Selection = [];\n\n @property({ reflect: true }) name: string = '';\n @property({ type: Boolean, reflect: true }) required: boolean = false;\n @property({ attribute: 'min-date' }) minDate?: string;\n @property({ attribute: 'max-date' }) maxDate?: string;\n\n @state()\n private _currentStartMonth: DateTime = DateTime.local().startOf('month');\n\n private _lastClickedDate?: string;\n\n @state()\n private _focusedDate: DateTime = DateTime.local();\n\n constructor() {\n super();\n this._internals = this.attachInternals();\n }\n\n override connectedCallback() {\n super.connectedCallback();\n if (this.startMonth) {\n this._currentStartMonth = DateTime.fromISO(this.startMonth + '-01');\n }\n this._syncForm();\n }\n\n private _syncForm() {\n const val = this.value.length > 0 ? JSON.stringify(this.value) : null;\n this._internals.setFormValue(val);\n if (this.required && this.value.length === 0) {\n this._internals.setValidity({ valueMissing: true }, 'Please select at least one date');\n } else {\n this._internals.setValidity({});\n }\n }\n\n formResetCallback() {\n this.value = [];\n this._lastClickedDate = undefined;\n this._syncForm();\n }\n\n private _getMonthList(): DateTime[] {\n return Array.from({ length: this.months }, (_, i) => this._currentStartMonth.plus({ months: i }));\n }\n\n private _previousPage() {\n this._currentStartMonth = this._currentStartMonth.minus({ months: this.months });\n }\n\n private _nextPage() {\n this._currentStartMonth = this._currentStartMonth.plus({ months: this.months });\n }\n\n private _getDateRangeLabel(): string {\n const first = this._currentStartMonth;\n const last = this._currentStartMonth.plus({ months: this.months - 1 });\n return `${first.toFormat('MMMM yyyy')} — ${last.toFormat('MMMM yyyy')}`;\n }\n\n private _getCalendarForDate(date: DateTime): Element | undefined {\n const monthStr = date.toFormat('yyyy-MM');\n const calendars = this.shadowRoot!.querySelectorAll('tt-calendar');\n for (const cal of calendars) {\n if (cal.getAttribute('month') === monthStr) return cal;\n }\n return undefined;\n }\n\n private _moveFocus(date: DateTime) {\n this._focusedDate = date;\n this.updateComplete.then(() => {\n const cal = this._getCalendarForDate(date) as (Element & { focusDay: (d: DateTime) => void }) | undefined;\n cal?.focusDay(date);\n });\n }\n\n private _applySelection(dateStr: string, shiftKey: boolean) {\n if (shiftKey && this._lastClickedDate) {\n this.value = extendRange(this.value, this._lastClickedDate, dateStr);\n } else {\n this.value = toggleDate(this.value, dateStr);\n }\n\n this._lastClickedDate = dateStr;\n this._syncForm();\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));\n }\n\n private _handleDayClick(event: MouseEvent) {\n const target = event.composedPath()[0] as HTMLElement;\n const dayCell = target.closest?.('.day') ?? (target.classList?.contains('day') ? target : null);\n const dateStr = dayCell?.getAttribute('data-date');\n if (!dateStr) return;\n\n this._focusedDate = DateTime.fromISO(dateStr);\n this._applySelection(dateStr, event.shiftKey);\n }\n\n private _handleKeyDown(event: KeyboardEvent) {\n switch (event.key) {\n case 'ArrowRight':\n event.preventDefault();\n this._moveFocus(this._focusedDate.plus({ days: 1 }));\n break;\n case 'ArrowLeft':\n event.preventDefault();\n this._moveFocus(this._focusedDate.minus({ days: 1 }));\n break;\n case 'ArrowDown':\n event.preventDefault();\n this._moveFocus(this._focusedDate.plus({ weeks: 1 }));\n break;\n case 'ArrowUp':\n event.preventDefault();\n this._moveFocus(this._focusedDate.minus({ weeks: 1 }));\n break;\n case 'Home':\n event.preventDefault();\n this._moveFocus(this._focusedDate.startOf('week'));\n break;\n case 'End':\n event.preventDefault();\n this._moveFocus(this._focusedDate.endOf('week'));\n break;\n case 'PageDown':\n event.preventDefault();\n this._nextPage();\n break;\n case 'PageUp':\n event.preventDefault();\n this._previousPage();\n break;\n case 'Enter':\n case ' ':\n event.preventDefault();\n this._applySelection(this._focusedDate.toISODate()!, event.shiftKey);\n break;\n }\n }\n\n private _clearAll() {\n this.value = [];\n this._lastClickedDate = undefined;\n this._syncForm();\n this.dispatchEvent(new Event('change', { bubbles: true, composed: true }));\n }\n\n override render() {\n const monthList = this._getMonthList();\n\n return html`\n <div class=\"navigation\">\n <button @click=${this._previousPage} aria-label=\"Previous ${this.months} months\">${unsafeSVG(chevron)}</button>\n <h2>${this._getDateRangeLabel()}</h2>\n <button @click=${this._nextPage} aria-label=\"Next ${this.months} months\" class=\"right\">\n ${unsafeSVG(chevron)}\n </button>\n </div>\n <p class=\"instructions\">Click a date to select it. Shift+click to select a range.</p>\n <div class=\"calendar-grid\" @click=${this._handleDayClick} @keydown=${this._handleKeyDown} tabindex=\"0\">\n ${monthList.map(\n (month) => html`\n <div class=\"month-panel\">\n <h3 class=\"month-label\">${month.toFormat('MMMM yyyy')}</h3>\n <tt-calendar\n display-only\n month=\"${month.toFormat('yyyy-MM')}\"\n .highlightedRanges=${this.value}\n min-date=\"${ifDefined(this.minDate)}\"\n max-date=\"${ifDefined(this.maxDate)}\"\n ></tt-calendar>\n </div>\n `\n )}\n </div>\n ${this.value.length > 0\n ? html`\n <div class=\"footer\">\n <span class=\"selection-summary\">${this.value.length} selection${this.value.length > 1 ? 's' : ''}</span>\n <button data-action=\"clear\" data-theme=\"secondary\" @click=${this._clearAll}>Clear all</button>\n </div>\n `\n : nothing}\n `;\n }\n}\n"]}
@@ -38,6 +38,7 @@ export const styles = [
38
38
 
39
39
  tt-calendar {
40
40
  --tt-calendar-range-bg: var(--color-primary-400);
41
+ --tt-calendar-range-color: var(--color-text-100);
41
42
  }
42
43
 
43
44
  .calendar-grid {
@@ -47,6 +48,14 @@ export const styles = [
47
48
  padding: var(--space-scale-3);
48
49
  }
49
50
 
51
+ .month-label {
52
+ font-size: var(--font-size-200);
53
+ font-weight: var(--font-weight-semibold);
54
+ color: var(--color-text-500);
55
+ margin: 0 0 var(--space-scale-1) 0;
56
+ text-align: center;
57
+ }
58
+
50
59
  .footer {
51
60
  display: flex;
52
61
  justify-content: space-between;
@@ -1 +1 @@
1
- {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../src/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,UAAU;IACV,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyDF;CACF,CAAC","sourcesContent":["import { css } from 'lit';\nimport { styles as baseStyles } from '@triptease/stylesheet/lit';\n\nexport const styles = [\n baseStyles,\n css`\n :host {\n display: block;\n }\n\n .navigation {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: var(--space-scale-2) var(--space-scale-3);\n border-bottom: 1px solid var(--color-border-200);\n }\n\n .navigation button svg {\n display: block;\n }\n\n .navigation button.right svg {\n transform: rotate(180deg);\n }\n\n .navigation h2 {\n font-weight: var(--font-weight-semibold);\n font-size: var(--font-size-400);\n color: var(--color-text-500);\n }\n\n .instructions {\n margin: 0;\n padding: var(--space-scale-1) var(--space-scale-3);\n font-size: var(--font-size-100);\n color: var(--color-text-400);\n }\n\n tt-calendar {\n --tt-calendar-range-bg: var(--color-primary-400);\n }\n\n .calendar-grid {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: var(--space-scale-3);\n padding: var(--space-scale-3);\n }\n\n .footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: var(--space-scale-2) var(--space-scale-3);\n border-top: 1px solid var(--color-border-200);\n }\n\n .selection-summary {\n font-size: var(--font-size-100);\n color: var(--color-text-400);\n }\n `,\n];\n"]}
1
+ {"version":3,"file":"styles.js","sourceRoot":"","sources":["../../../src/styles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAC;AAC1B,OAAO,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAEjE,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,UAAU;IACV,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEF;CACF,CAAC","sourcesContent":["import { css } from 'lit';\nimport { styles as baseStyles } from '@triptease/stylesheet/lit';\n\nexport const styles = [\n baseStyles,\n css`\n :host {\n display: block;\n }\n\n .navigation {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: var(--space-scale-2) var(--space-scale-3);\n border-bottom: 1px solid var(--color-border-200);\n }\n\n .navigation button svg {\n display: block;\n }\n\n .navigation button.right svg {\n transform: rotate(180deg);\n }\n\n .navigation h2 {\n font-weight: var(--font-weight-semibold);\n font-size: var(--font-size-400);\n color: var(--color-text-500);\n }\n\n .instructions {\n margin: 0;\n padding: var(--space-scale-1) var(--space-scale-3);\n font-size: var(--font-size-100);\n color: var(--color-text-400);\n }\n\n tt-calendar {\n --tt-calendar-range-bg: var(--color-primary-400);\n --tt-calendar-range-color: var(--color-text-100);\n }\n\n .calendar-grid {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: var(--space-scale-3);\n padding: var(--space-scale-3);\n }\n\n .month-label {\n font-size: var(--font-size-200);\n font-weight: var(--font-weight-semibold);\n color: var(--color-text-500);\n margin: 0 0 var(--space-scale-1) 0;\n text-align: center;\n }\n\n .footer {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: var(--space-scale-2) var(--space-scale-3);\n border-top: 1px solid var(--color-border-200);\n }\n\n .selection-summary {\n font-size: var(--font-size-100);\n color: var(--color-text-400);\n }\n `,\n];\n"]}
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Multi-date and date range selection calendar web component",
4
4
  "license": "MIT",
5
5
  "author": "@triptease",
6
- "version": "0.3.1",
6
+ "version": "0.4.0",
7
7
  "type": "module",
8
8
  "main": "dist/esm/src/index.js",
9
9
  "module": "dist/esm/src/index.js",
@@ -38,7 +38,7 @@
38
38
  "dependencies": {
39
39
  "@triptease/icons": "1.4.1",
40
40
  "@triptease/stylesheet": "2.1.9",
41
- "@triptease/tt-calendar": "6.3.0",
41
+ "@triptease/tt-calendar": "6.4.0",
42
42
  "lit": "^3.1.4",
43
43
  "luxon": "^3.6.1"
44
44
  },