sharkey/src/client/app/desktop/views/components/calendar.vue

249 lines
5.3 KiB
Vue
Raw Normal View History

2018-02-19 16:58:37 +09:00
<template>
2018-02-21 15:30:03 +09:00
<div class="mk-calendar" :data-melt="design == 4 || design == 5">
2018-02-19 16:58:37 +09:00
<template v-if="design == 0 || design == 1">
<button @click="prev" :title="$t('prev')"><fa icon="chevron-circle-left"/></button>
<p class="title">{{ $t('title', { year, month }) }}</p>
<button @click="next" :title="$t('next')"><fa icon="chevron-circle-right"/></button>
2018-02-19 16:58:37 +09:00
</template>
<div class="calendar">
2018-02-19 18:26:20 +09:00
<template v-if="design == 0 || design == 2 || design == 4">
2018-02-19 16:58:37 +09:00
<div class="weekday"
v-for="(day, i) in Array(7).fill(0)"
:data-today="year == today.getFullYear() && month == today.getMonth() + 1 && today.getDay() == i"
:data-is-donichi="i == 0 || i == 6"
>{{ weekdayText[i] }}</div>
2018-02-19 18:26:20 +09:00
</template>
<div v-for="n in paddingDays"></div>
<div class="day" v-for="(day, i) in days"
2018-02-19 16:58:37 +09:00
:data-today="isToday(i + 1)"
:data-selected="isSelected(i + 1)"
:data-is-out-of-range="isOutOfRange(i + 1)"
:data-is-donichi="isDonichi(i + 1)"
@click="go(i + 1)"
:title="isOutOfRange(i + 1) ? null : $t('go')"
2018-02-19 16:58:37 +09:00
>
<div>{{ i + 1 }}</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../../i18n';
2018-02-19 16:58:37 +09:00
const eachMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
function isLeapYear(year) {
2018-07-27 19:15:38 +09:00
return !(year & (year % 25 ? 3 : 15));
2018-02-19 16:58:37 +09:00
}
export default Vue.extend({
i18n: i18n('desktop/views/components/calendar.vue'),
2018-02-19 16:58:37 +09:00
props: {
design: {
default: 0
},
start: {
2018-02-19 23:37:09 +09:00
type: Date,
2018-02-19 16:58:37 +09:00
required: false
}
},
data() {
return {
today: new Date(),
year: new Date().getFullYear(),
month: new Date().getMonth() + 1,
selected: new Date(),
weekdayText: [
this.$t('@.weekday-short.sunday'),
this.$t('@.weekday-short.monday'),
this.$t('@.weekday-short.tuesday'),
this.$t('@.weekday-short.wednesday'),
this.$t('@.weekday-short.thursday'),
this.$t('@.weekday-short.friday'),
this.$t('@.weekday-short.saturday')
2018-02-19 16:58:37 +09:00
]
};
},
computed: {
paddingDays(): number {
const date = new Date(this.year, this.month - 1, 1);
return date.getDay();
},
days(): number {
let days = eachMonthDays[this.month - 1];
// うるう年なら+1日
if (this.month == 2 && isLeapYear(this.year)) days++;
return days;
}
},
methods: {
isToday(day) {
return this.year == this.today.getFullYear() && this.month == this.today.getMonth() + 1 && day == this.today.getDate();
},
isSelected(day) {
return this.year == this.selected.getFullYear() && this.month == this.selected.getMonth() + 1 && day == this.selected.getDate();
},
isOutOfRange(day) {
const test = (new Date(this.year, this.month - 1, day)).getTime();
return test > this.today.getTime() ||
2018-02-19 23:37:09 +09:00
(this.start ? test < (this.start as any).getTime() : false);
2018-02-19 16:58:37 +09:00
},
isDonichi(day) {
const weekday = (new Date(this.year, this.month - 1, day)).getDay();
return weekday == 0 || weekday == 6;
},
prev() {
if (this.month == 1) {
this.year = this.year - 1;
this.month = 12;
} else {
this.month--;
}
},
next() {
if (this.month == 12) {
this.year = this.year + 1;
this.month = 1;
} else {
this.month++;
}
},
go(day) {
if (this.isOutOfRange(day)) return;
const date = new Date(this.year, this.month - 1, day, 23, 59, 59, 999);
this.selected = date;
2018-02-19 17:03:22 +09:00
this.$emit('chosen', this.selected);
2018-02-19 16:58:37 +09:00
}
}
});
</script>
<style lang="stylus" scoped>
2018-09-27 16:49:18 +09:00
.mk-calendar
color var(--calendarDay)
2018-09-26 20:28:13 +09:00
background var(--face)
2018-09-22 20:39:12 +09:00
box-shadow var(--shadow)
border-radius var(--round)
2018-05-26 23:34:20 +09:00
overflow hidden
2018-02-19 16:58:37 +09:00
&[data-melt]
background transparent !important
border none !important
> .title
z-index 1
margin 0
padding 0 16px
text-align center
line-height 42px
font-size 0.9em
font-weight bold
2018-09-27 16:49:18 +09:00
color var(--faceHeaderText)
background var(--faceHeader)
2018-12-30 14:00:57 +09:00
box-shadow 0 var(--lineWidth) rgba(#000, 0.07)
2018-02-19 16:58:37 +09:00
> [data-icon]
2018-02-19 16:58:37 +09:00
margin-right 4px
> button
position absolute
z-index 2
top 0
padding 0
width 42px
font-size 0.9em
line-height 42px
2018-09-27 14:32:48 +09:00
color var(--faceTextButton)
2018-02-19 16:58:37 +09:00
&:hover
2018-09-27 14:32:48 +09:00
color var(--faceTextButtonHover)
2018-02-19 16:58:37 +09:00
&:active
2018-09-27 16:49:18 +09:00
color var(--faceTextButtonActive)
2018-02-19 16:58:37 +09:00
&:first-of-type
left 0
&:last-of-type
right 0
> .calendar
display flex
flex-wrap wrap
padding 16px
*
user-select none
> div
width calc(100% * (1/7))
text-align center
line-height 32px
font-size 14px
&.weekday
2018-09-27 16:49:18 +09:00
color var(--calendarWeek)
2018-02-19 16:58:37 +09:00
&[data-is-donichi]
2018-09-27 16:49:18 +09:00
color var(--calendarSaturdayOrSunday)
2018-02-19 16:58:37 +09:00
&[data-today]
2018-12-30 14:00:57 +09:00
box-shadow 0 0 0 var(--lineWidth) var(--calendarWeek) inset
2018-02-19 16:58:37 +09:00
border-radius 6px
&[data-is-donichi]
2018-12-30 14:00:57 +09:00
box-shadow 0 0 0 var(--lineWidth) var(--calendarSaturdayOrSunday) inset
2018-02-19 16:58:37 +09:00
&.day
cursor pointer
2018-09-27 16:49:18 +09:00
color var(--calendarDay)
2018-02-19 16:58:37 +09:00
> div
border-radius 6px
&:hover > div
2018-09-27 16:49:18 +09:00
background var(--faceClearButtonHover)
2018-02-19 16:58:37 +09:00
&:active > div
2018-09-27 16:49:18 +09:00
background var(--faceClearButtonActive)
2018-02-19 16:58:37 +09:00
&[data-is-donichi]
2018-09-27 16:49:18 +09:00
color var(--calendarSaturdayOrSunday)
2018-02-19 16:58:37 +09:00
&[data-is-out-of-range]
cursor default
2018-09-27 16:49:18 +09:00
opacity 0.5
2018-02-19 16:58:37 +09:00
&[data-selected]
font-weight bold
> div
2018-09-27 16:49:18 +09:00
background var(--faceClearButtonHover)
2018-02-19 16:58:37 +09:00
&:active > div
2018-09-27 16:49:18 +09:00
background var(--faceClearButtonActive)
2018-02-19 16:58:37 +09:00
&[data-today]
> div
2018-09-26 20:19:35 +09:00
color var(--primaryForeground)
background var(--primary)
2018-02-19 16:58:37 +09:00
&:hover > div
2018-09-26 20:19:35 +09:00
background var(--primaryLighten10)
2018-02-19 16:58:37 +09:00
&:active > div
2018-09-26 20:19:35 +09:00
background var(--primaryDarken10)
2018-02-19 16:58:37 +09:00
</style>