Responsive date strings in calendar days for small screen support and consistent wrapping.
This commit is contained in:
@@ -1,15 +1,61 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { formatDateCompact, fromLocalString } from '@/utils/date'
|
||||
import { computed, ref, onMounted, onBeforeUnmount } from 'vue'
|
||||
import { fromLocalString } from '@/utils/date'
|
||||
|
||||
const props = defineProps({
|
||||
day: Object,
|
||||
dragging: { type: Boolean, default: false },
|
||||
})
|
||||
|
||||
// Reactive viewport width detection
|
||||
const isNarrowView = ref(false)
|
||||
const isVeryNarrowView = ref(false)
|
||||
const isSmallView = ref(false)
|
||||
|
||||
function checkViewportWidth() {
|
||||
const width = window.innerWidth
|
||||
isSmallView.value = width < 800
|
||||
isNarrowView.value = width < 600
|
||||
isVeryNarrowView.value = width < 400
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
checkViewportWidth()
|
||||
window.addEventListener('resize', checkViewportWidth)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.removeEventListener('resize', checkViewportWidth)
|
||||
})
|
||||
|
||||
const formattedDate = computed(() => {
|
||||
const date = fromLocalString(props.day.date)
|
||||
return formatDateCompact(date)
|
||||
|
||||
let options = { day: 'numeric', month: 'short' }
|
||||
|
||||
if (isVeryNarrowView.value) {
|
||||
// Very narrow: show only day number
|
||||
options = { day: 'numeric' }
|
||||
} else if (isNarrowView.value) {
|
||||
// Narrow: show day and month, no weekday
|
||||
options = { day: 'numeric', month: 'short' }
|
||||
} else {
|
||||
// Wide: show weekday, day, and month
|
||||
options = { weekday: 'short', day: 'numeric', month: 'short' }
|
||||
}
|
||||
|
||||
let formatted = date.toLocaleDateString(undefined, options)
|
||||
|
||||
// Below 700px, replace first space with newline to force weekday on separate line
|
||||
if (isSmallView.value && !isNarrowView.value && !isVeryNarrowView.value) {
|
||||
formatted = formatted.replace(/\s/, '\n')
|
||||
}
|
||||
|
||||
// Replace the last space (between month and day) with nbsp to prevent breaking there
|
||||
// but keep the space after weekday (if present) as regular space to allow wrapping
|
||||
formatted = formatted.replace(/\s+(?=\S+$)/, '\u00A0')
|
||||
|
||||
return formatted
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -136,6 +182,7 @@ const formattedDate = computed(() => {
|
||||
color: var(--ink);
|
||||
line-height: 1;
|
||||
pointer-events: none;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.cell.weekend .compact-date {
|
||||
|
||||
@@ -192,17 +192,6 @@ function formatTodayString(date, weekday = "long", month = "long") {
|
||||
return formatted.charAt(0).toUpperCase() + formatted.slice(1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Format date as compact string for day cell corner (e.g., "Mon 15 Jan")
|
||||
*/
|
||||
function formatDateCompact(date) {
|
||||
return date.toLocaleDateString(undefined, {
|
||||
weekday: 'short',
|
||||
day: 'numeric',
|
||||
month: 'short'
|
||||
})
|
||||
}
|
||||
|
||||
export {
|
||||
// constants
|
||||
monthAbbr,
|
||||
@@ -229,7 +218,6 @@ export {
|
||||
formatDateRange,
|
||||
formatDateShort,
|
||||
formatDateLong,
|
||||
formatDateCompact,
|
||||
formatTodayString,
|
||||
lunarPhaseSymbol,
|
||||
// iso helpers re-export
|
||||
|
||||
Reference in New Issue
Block a user