159 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			159 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <script setup>
 | |
| import { computed } from 'vue'
 | |
| import { formatDateCompact, fromLocalString } from '@/utils/date'
 | |
| 
 | |
| const props = defineProps({
 | |
|   day: Object,
 | |
|   dragging: { type: Boolean, default: false },
 | |
| })
 | |
| 
 | |
| const formattedDate = computed(() => {
 | |
|   const date = fromLocalString(props.day.date)
 | |
|   return formatDateCompact(date)
 | |
| })
 | |
| </script>
 | |
| 
 | |
| <template>
 | |
|   <div
 | |
|     class="cell"
 | |
|     :style="props.dragging ? 'touch-action:none;' : 'touch-action:pan-y;'"
 | |
|     :class="[
 | |
|       props.day.monthClass,
 | |
|       {
 | |
|         today: props.day.isToday,
 | |
|         weekend: props.day.isWeekend,
 | |
|         firstday: props.day.isFirstDay,
 | |
|         selected: props.day.isSelected,
 | |
|         holiday: props.day.isHoliday,
 | |
|       },
 | |
|     ]"
 | |
|     :data-date="props.day.date"
 | |
|   >
 | |
|     <span class="compact-date">{{ formattedDate }}</span>
 | |
|     <h1 class="day-number">{{ props.day.displayText }}</h1>
 | |
|     <span v-if="props.day.lunarPhase" class="lunar-phase">{{ props.day.lunarPhase }}</span>
 | |
|     <div v-if="props.day.holiday" class="holiday-info" dir="auto" :title="props.day.holiday.name">
 | |
|       {{ props.day.holiday.name }}
 | |
|     </div>
 | |
|   </div>
 | |
| </template>
 | |
| 
 | |
| <style scoped>
 | |
| .cell {
 | |
|   position: relative;
 | |
|   user-select: none;
 | |
|   display: grid;
 | |
|   /* Updated grid for centered day number */
 | |
|   grid-template-columns: 1fr;
 | |
|   grid-template-rows: 1fr auto;
 | |
|   /* Named grid areas */
 | |
|   grid-template-areas:
 | |
|     'day-number'
 | |
|     'holiday-info';
 | |
|   padding: 0.25em;
 | |
|   overflow: visible;
 | |
|   width: 100%;
 | |
|   height: var(--row-h);
 | |
|   font-weight: 700;
 | |
|   transition: background-color 0.15s ease;
 | |
|   align-items: center;
 | |
|   justify-items: center;
 | |
| }
 | |
| .cell h1.day-number {
 | |
|   position: absolute;
 | |
|   font-size: 5vmin;
 | |
|   font-weight: 800;
 | |
|   color: var(--ink);
 | |
|   transition: all 0.15s ease;
 | |
| }
 | |
| .cell.firstday h1.day-number {
 | |
|   font-weight: 400;
 | |
| }
 | |
| .cell.weekend h1.day-number {
 | |
|   color: var(--weekend);
 | |
| }
 | |
| .cell.firstday h1.day-number {
 | |
|   color: var(--firstday);
 | |
| }
 | |
| .cell.today::before {
 | |
|   content: '';
 | |
|   position: absolute;
 | |
|   top: 50%;
 | |
|   left: 50%;
 | |
|   transform: translate(-50%, -50%);
 | |
|   width: calc(100% + .2rem);
 | |
|   height: calc(100% + .2rem);
 | |
|   border-radius: 1rem;
 | |
|   background: transparent;
 | |
|   border: 0.3em solid var(--today);
 | |
|   z-index: 15;
 | |
|   pointer-events: none;
 | |
| }
 | |
| .cell.selected h1.day-number {
 | |
|   opacity: 0.3;
 | |
|   filter: brightness(1.2);
 | |
| }
 | |
| .cell {
 | |
|   background-image: linear-gradient(
 | |
|     135deg,
 | |
|     var(--holiday-grad-start, rgba(255, 255, 255, 0.3)) 0%,
 | |
|     var(--holiday-grad-end, rgba(255, 255, 255, 0)) 70%
 | |
|   );
 | |
| }
 | |
| @media (prefers-color-scheme: dark) {
 | |
|   .cell {
 | |
|     background-image: linear-gradient(
 | |
|       135deg,
 | |
|       var(--holiday-grad-start, rgba(255, 255, 255, 0.05)) 0%,
 | |
|       var(--holiday-grad-end, rgba(255, 255, 255, 0)) 70%
 | |
|     );
 | |
|   }
 | |
| }
 | |
| .lunar-phase {
 | |
|   grid-area: lunar-phase;
 | |
|   position: absolute;
 | |
|   inset-block-start: 0.5em;
 | |
|   inset-inline-end: 0.2em;
 | |
|   font-size: 0.8em;
 | |
|   opacity: 0.7;
 | |
| }
 | |
| 
 | |
| .compact-date {
 | |
|   position: absolute;
 | |
|   top: 0.25em;
 | |
|   left: 0.25em;
 | |
|   inset-inline-end: 1rem; /* Space for lunar phase */
 | |
|   font-weight: 400;
 | |
|   color: var(--ink);
 | |
|   line-height: 1;
 | |
|   pointer-events: none;
 | |
| }
 | |
| 
 | |
| .cell.weekend .compact-date {
 | |
|   color: var(--weekend);
 | |
| }
 | |
| .cell.firstday .compact-date {
 | |
|   color: var(--firstday);
 | |
| }
 | |
| .cell.today .compact-date {
 | |
|   color: var(--strong);
 | |
| }
 | |
| .cell.selected .compact-date {
 | |
|   color: var(--strong);
 | |
| }
 | |
| 
 | |
| .holiday-info {
 | |
|   grid-area: holiday-info;
 | |
|   align-self: end;
 | |
|   overflow: hidden;
 | |
|   max-width: 100%;
 | |
|   color: var(--holiday);
 | |
|   font-size: 1em;
 | |
|   font-weight: 400;
 | |
|   line-height: 1.0;
 | |
|   padding-inline: 0.15em;
 | |
|   padding-block: 0;
 | |
|   pointer-events: auto;
 | |
| }
 | |
| </style>
 | 
