Logic refactoring of date-picker

This commit is contained in:
scottkiener-at-safelite 2026-05-29 11:23:10 -04:00
parent 8a472aa335
commit 7fd7362982

View file

@ -6,13 +6,7 @@
aria-label="Previous dates"
@click="goBack">
<img
v-if="canGoBack"
src="@/assets/img/icons/chevron-right-blue.svg"
class="date-picker__nav-icon date-picker__nav-icon--flipped"
alt="" />
<img
v-else
src="@/assets/img/icons/chevron-right-grey.svg"
:src="navIconSrc(canGoBack)"
class="date-picker__nav-icon date-picker__nav-icon--flipped"
alt="" />
</button>
@ -38,16 +32,7 @@
:disabled="!canGoForward"
aria-label="Next dates"
@click="goForward">
<img
v-if="canGoForward"
src="@/assets/img/icons/chevron-right-blue.svg"
class="date-picker__nav-icon"
alt="" />
<img
v-else
src="@/assets/img/icons/chevron-right-grey.svg"
class="date-picker__nav-icon"
alt="" />
<img :src="navIconSrc(canGoForward)" class="date-picker__nav-icon" alt="" />
</button>
</div>
</template>
@ -73,6 +58,7 @@ const MONTH_ABBRS = [
const MOBILE_WINDOW_SIZE = 3;
const DESKTOP_WINDOW_SIZE = 5;
const DESKTOP_BREAKPOINT_PX = Breakpoints.MD;
const MAX_DATE_RANGE = 180;
function toLocalDateString(date) {
const y = date.getFullYear();
@ -86,6 +72,10 @@ function parseLocalDate(str) {
return new Date(year, month - 1, day);
}
function getWindowSize() {
return window.innerWidth >= DESKTOP_BREAKPOINT_PX ? DESKTOP_WINDOW_SIZE : MOBILE_WINDOW_SIZE;
}
export default {
name: "datePicker",
props: {
@ -114,10 +104,7 @@ export default {
data() {
return {
windowStart: 0,
windowSize:
window.innerWidth >= DESKTOP_BREAKPOINT_PX
? DESKTOP_WINDOW_SIZE
: MOBILE_WINDOW_SIZE,
windowSize: getWindowSize(),
pendingAutoSelect: false,
initialized: false,
};
@ -154,9 +141,8 @@ export default {
},
canGoForward() {
if (this.isLoadingDates || !this.allDates.length) return false;
const lastDateIsVisible = this.windowStart + this.windowSize >= this.allDates.length;
if (this.allDates.length >= 180 && lastDateIsVisible) return false;
return true;
const atEnd = this.windowStart + this.windowSize >= this.allDates.length;
return !(atEnd && this.allDates.length >= MAX_DATE_RANGE);
},
},
watch: {
@ -177,12 +163,11 @@ export default {
mounted() {
this.updateWindowSize();
window.addEventListener("resize", this.updateWindowSize);
if (this.modelValue && this.allDates.length) {
if (!this.allDates.length) return;
if (this.modelValue) {
const index = this.allDates.findIndex((d) => d.value === this.modelValue);
if (index !== -1) {
this.windowStart = Math.floor(index / this.windowSize) * this.windowSize;
}
} else if (!this.modelValue && this.allDates.length) {
if (index !== -1) this.windowStart = this.getWindowStart(index);
} else {
this.initializeWindow();
}
},
@ -191,10 +176,15 @@ export default {
},
methods: {
updateWindowSize() {
this.windowSize =
window.innerWidth >= DESKTOP_BREAKPOINT_PX
? DESKTOP_WINDOW_SIZE
: MOBILE_WINDOW_SIZE;
this.windowSize = getWindowSize();
},
navIconSrc(enabled) {
return enabled
? require("@/assets/img/icons/chevron-right-blue.svg")
: require("@/assets/img/icons/chevron-right-grey.svg");
},
getWindowStart(index) {
return Math.floor(index / this.windowSize) * this.windowSize;
},
goBack() {
this.windowStart = Math.max(0, this.windowStart - this.windowSize);
@ -226,7 +216,7 @@ export default {
const firstAvailable = this.allDates.find((d) => d.isAvailable);
if (firstAvailable) {
const index = this.allDates.indexOf(firstAvailable);
this.windowStart = Math.floor(index / this.windowSize) * this.windowSize;
this.windowStart = this.getWindowStart(index);
this.$emit("update:modelValue", firstAvailable.value);
} else {
this.windowStart = Math.max(0, this.allDates.length - this.windowSize);
@ -312,18 +302,19 @@ export default {
}
}
&__day-abbr {
&__day-abbr,
&__day-date {
font-family: $font-family-sans-serif-bold;
font-size: $font-size-14;
color: $blue;
}
&__day-abbr {
text-transform: uppercase;
line-height: 1.2;
}
&__day-date {
font-family: $font-family-sans-serif-bold;
font-size: $font-size-14;
color: $blue;
line-height: 1.4;
white-space: nowrap;
}