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

260 lines
5.4 KiB
Vue
Raw Normal View History

2018-02-19 08:58:37 +01:00
<template>
2018-02-21 07:30:03 +01:00
<div class="mk-calendar" :data-melt="design == 4 || design == 5">
2018-02-19 08:58:37 +01:00
<template v-if="design == 0 || design == 1">
2018-04-14 18:04:40 +02:00
<button @click="prev" title="%i18n:@prev%">%fa:chevron-circle-left%</button>
2018-05-20 13:26:38 +02:00
<p class="title">{{ '%i18n:@title%'.replace('{1}', year).replace('{2}', month) }}</p>
2018-04-14 18:04:40 +02:00
<button @click="next" title="%i18n:@next%">%fa:chevron-circle-right%</button>
2018-02-19 08:58:37 +01:00
</template>
<div class="calendar">
2018-02-19 10:26:20 +01:00
<template v-if="design == 0 || design == 2 || design == 4">
2018-02-19 08:58:37 +01: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 10:26:20 +01:00
</template>
<div v-for="n in paddingDays"></div>
<div class="day" v-for="(day, i) in days"
2018-02-19 08:58:37 +01: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)"
2018-05-20 13:26:38 +02:00
:title="isOutOfRange(i + 1) ? null : '%i18n:@go%'"
2018-02-19 08:58:37 +01:00
>
<div>{{ i + 1 }}</div>
</div>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
const eachMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
function isLeapYear(year) {
2018-07-27 12:15:38 +02:00
return !(year & (year % 25 ? 3 : 15));
2018-02-19 08:58:37 +01:00
}
export default Vue.extend({
props: {
design: {
default: 0
},
start: {
2018-02-19 15:37:09 +01:00
type: Date,
2018-02-19 08:58:37 +01:00
required: false
}
},
data() {
return {
today: new Date(),
year: new Date().getFullYear(),
month: new Date().getMonth() + 1,
selected: new Date(),
weekdayText: [
2018-05-20 13:26:38 +02:00
'%i18n:common.weekday-short.sunday%',
'%i18n:common.weekday-short.monday%',
'%i18n:common.weekday-short.tuesday%',
'%i18n:common.weekday-short.wednesday%',
'%i18n:common.weekday-short.thursday%',
'%i18n:common.weekday-short.friday%',
'%i18n:common.weekday-short.saturday%'
2018-02-19 08:58:37 +01: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 15:37:09 +01:00
(this.start ? test < (this.start as any).getTime() : false);
2018-02-19 08:58:37 +01: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 09:03:22 +01:00
this.$emit('chosen', this.selected);
2018-02-19 08:58:37 +01:00
}
}
});
</script>
<style lang="stylus" scoped>
2018-09-26 13:19:35 +02:00
2018-03-03 05:47:55 +01:00
2018-04-19 21:51:04 +02:00
root(isDark)
color isDark ? #c5ced6 : #777
2018-09-26 13:28:13 +02:00
background var(--face)
2018-09-22 13:39:12 +02:00
box-shadow var(--shadow)
border-radius var(--round)
2018-05-26 16:34:20 +02:00
overflow hidden
2018-02-19 08:58:37 +01: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-05-26 16:34:20 +02:00
color isDark ? #c5ced6 : #888
2018-04-29 01:51:17 +02:00
box-shadow 0 1px rgba(#000, 0.07)
2018-02-19 08:58:37 +01:00
2018-05-26 16:34:20 +02:00
if isDark
background #313543
2018-02-19 08:58:37 +01:00
> [data-fa]
margin-right 4px
> button
position absolute
z-index 2
top 0
padding 0
width 42px
font-size 0.9em
line-height 42px
2018-05-26 16:34:20 +02:00
color isDark ? #9baec8 : #ccc
2018-02-19 08:58:37 +01:00
&:hover
2018-05-26 16:34:20 +02:00
color isDark ? #b2c1d5 : #aaa
2018-02-19 08:58:37 +01:00
&:active
2018-05-26 16:34:20 +02:00
color isDark ? #b2c1d5 : #999
2018-02-19 08:58:37 +01: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-05-26 16:34:20 +02:00
color isDark ? #43d5dc : #19a2a9
2018-02-19 08:58:37 +01:00
&[data-is-donichi]
2018-05-26 16:34:20 +02:00
color isDark ? #ff6679 : #ef95a0
2018-02-19 08:58:37 +01:00
&[data-today]
2018-05-26 16:34:20 +02:00
box-shadow 0 0 0 1px isDark ? #43d5dc : #19a2a9 inset
2018-02-19 08:58:37 +01:00
border-radius 6px
&[data-is-donichi]
2018-05-26 16:34:20 +02:00
box-shadow 0 0 0 1px isDark ? #ff6679 : #ef95a0 inset
2018-02-19 08:58:37 +01:00
&.day
cursor pointer
2018-05-26 16:34:20 +02:00
color isDark ? #c5ced6 : #777
2018-02-19 08:58:37 +01:00
> div
border-radius 6px
&:hover > div
2018-05-26 16:34:20 +02:00
background rgba(#000, isDark ? 0.1 : 0.025)
2018-02-19 08:58:37 +01:00
&:active > div
2018-05-26 16:34:20 +02:00
background rgba(#000, isDark ? 0.2 : 0.05)
2018-02-19 08:58:37 +01:00
&[data-is-donichi]
2018-05-26 16:34:20 +02:00
color isDark ? #ff6679 : #ef95a0
2018-02-19 08:58:37 +01:00
&[data-is-out-of-range]
cursor default
2018-05-26 16:34:20 +02:00
color rgba(isDark ? #c5ced6 : #777, 0.5)
2018-02-19 08:58:37 +01:00
&[data-is-donichi]
2018-05-26 16:34:20 +02:00
color rgba(isDark ? #ff6679 : #ef95a0, 0.5)
2018-02-19 08:58:37 +01:00
&[data-selected]
font-weight bold
> div
2018-05-26 16:34:20 +02:00
background rgba(#000, isDark ? 0.1 : 0.025)
2018-02-19 08:58:37 +01:00
&:active > div
2018-05-26 16:34:20 +02:00
background rgba(#000, isDark ? 0.2 : 0.05)
2018-02-19 08:58:37 +01:00
&[data-today]
> div
2018-09-26 13:19:35 +02:00
color var(--primaryForeground)
background var(--primary)
2018-02-19 08:58:37 +01:00
&:hover > div
2018-09-26 13:19:35 +02:00
background var(--primaryLighten10)
2018-02-19 08:58:37 +01:00
&:active > div
2018-09-26 13:19:35 +02:00
background var(--primaryDarken10)
2018-02-19 08:58:37 +01:00
2018-04-19 21:51:04 +02:00
.mk-calendar[data-darkmode]
root(true)
.mk-calendar:not([data-darkmode])
root(false)
2018-02-19 08:58:37 +01:00
</style>