This commit is contained in:
wangxueliang 2018-03-10 22:39:30 +08:00
commit 80ea759117
79 changed files with 5610 additions and 0 deletions

View File

@ -16,7 +16,9 @@ export default {
} else { } else {
this.$listeners[eventName](...args.slice(1)) this.$listeners[eventName](...args.slice(1))
} }
return true
} }
return false
}, },
}, },
} }

View File

@ -0,0 +1,106 @@
.@{prefixClass} {
&-input-wrap {
position: relative;
padding: 6px;
border-bottom: 1px solid #e9e9e9;
&:after {
content: '';
clear: both;
}
}
&-date-input-wrap {
overflow: hidden;
}
&-time-picker {
position: absolute;
width: 100%;
top: 34px;
background-color: white;
height: 217px;
&-panel {
width: 100%;
position: relative;
.@{timePickerClass}-panel {
&-input-wrap {
display: none;
}
&-inner {
border: none;
box-shadow: none;
}
&-select {
width: 84px;
ul {
max-height: 217px;
}
li {
text-align: center;
padding: 0;
}
}
}
}
}
&-time-picker-wrap {
float: left;
width: 100%;
.@{timePickerClass} {
width: 100%;
&-input {
padding: 0;
border: 1px solid transparent;
outline: 0;;
height:22px;
}
&-icon {
display: none;
}
}
}
&-input {
border: 1px solid transparent;
width: 100%;
color: #666;
cursor: text;
line-height: 1.5;
outline: 0;
height:22px;
&-invalid {
border-color: red;
}
}
&-clear-btn {
z-index: 9999;
position: absolute;
right: 6px;
cursor: pointer;
overflow: hidden;
width: 20px;
height: 20px;
text-align: center;
line-height: 20px;
top: 6px;
margin: 0;
}
&-clear-btn:after {
content: "x";
font-size: 12px;
color: #aaa;
display: inline-block;
line-height: 1;
width: 20px;
transition: color 0.3s ease;
}
&-clear-btn:hover:after {
color: #666;
}
}

View File

@ -0,0 +1,91 @@
.@{prefixClass}-full {
width: 275px;
&-header {
padding: 5px 10px;
text-align: center;
user-select: none;
-webkit-user-select: none;
border-bottom: 1px solid #ccc;
overflow: hidden;
&-month-select,
&-year-select {
width: 70px;
float: right;
margin-right: 5px;
}
&-switcher {
float: right;
display: inline-block;
&-normal:hover {
border-color: #23c0fa;
box-shadow: 0 0 2px rgba(45, 183, 245, 0.8);
cursor: pointer;
}
&-focus {
border-color: #3fc7fa;
background-color: #3fc7fa;
color: #fff;
}
> span {
float: left;
height: 28px;
line-height: 24px;
border: 1px solid #d9d9d9;
padding: 0 10px;
color: #666;
&:first-child {
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
border-right: none;
}
&:last-child {
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
border-left: none;
}
}
}
}
}
.@{prefixClass}-fullscreen {
width: auto;
.@{prefixClass}-full-header {
border-bottom: none;
}
.@{prefixClass} {
&-column-header {
text-align: right;
padding-right: 12px;
}
&-cell {
padding: 0;
}
&-cell .@{prefixClass}-date,
&-month-panel-cell .@{prefixClass}-month-panel-month {
display: block;
height: 116px;
width: auto;
border-radius: 0;
margin: 0 4px;
border: none;
border-top: 2px solid #eee;
text-align: right;
padding-right: 8px;
}
&-selected-day .@{prefixClass}-date,
&-month-panel-selected-cell .@{prefixClass}-month-panel-month {
background-color: #ebfaff;
color: #666;
}
&-today .@{prefixClass}-date,
&-month-panel-selected-cell .@{prefixClass}-month-panel-month {
border-top-color: #3FC7FA;
color: #3FC7FA;
}
}
}

View File

@ -0,0 +1,10 @@
.@{prefixClass}-picker {
position: absolute;
left: -9999px;
top: -9999px;
z-index: 1000;
&-hidden {
display: none;
}
}

View File

@ -0,0 +1,132 @@
@input-box-height: 35px;
.@{prefixClass}-range {
width: 502px;
overflow: hidden;
&-part {
width: 250px;
position: relative;
.@{prefixClass}-time-picker {
top: 69px;
&-panel {
&-select {
width: 77px;
}
}
}
}
&-left {
float: left;
.@{prefixClass}-time-picker-panel {
&-select:last-child {
border-right: 1px solid #e9e9e9;
}
}
}
&-right {
float: right;
.@{prefixClass}-time-picker-panel {
left: 21px;
&-select:first-child {
border-left: 1px solid #e9e9e9;
}
}
}
&-middle {
position: absolute;
margin-left: -10px;
text-align: center;
height: @input-box-height;
line-height: @input-box-height;
}
.@{prefixClass}-date-panel::after {
content:".";
display:block;
height:0;
clear:both;
visibility:hidden;
}
.@{prefixClass}-input-wrap {
height: @input-box-height;
}
.@{prefixClass}-input,
.@{timePickerClass}-input {
padding: 1px 7px;
height: 22px;
}
.@{prefixClass}-body,
.@{prefixClass}-decade-panel-body,
.@{prefixClass}-year-panel-body,
.@{prefixClass}-month-panel-body {
border-bottom: 1px solid #e9e9e9;
}
&.@{prefixClass}-week-number {
width: 574px;
.@{prefixClass}-range {
&-part {
width: 286px;
.@{prefixClass}-time-picker {
top: 69px;
&-panel {
&-select {
width: 89px;
}
}
}
}
&-right {
.@{prefixClass}-time-picker-panel {
left: 36px;
}
}
}
}
.@{prefixClass}-year-panel,
.@{prefixClass}-month-panel,
.@{prefixClass}-decade-panel {
top: @input-box-height;
}
.@{prefixClass}-month-panel .@{prefixClass}-year-panel {
top: 0;
}
.@{prefixClass}-decade-panel-table,
.@{prefixClass}-year-panel-table,
.@{prefixClass}-month-panel-table {
height: 198px;
}
.@{prefixClass}-in-range-cell {
background: #ebf4f8;
border-radius: 0;
}
&-bottom {
text-align: right;
}
.@{prefixClass}-footer{
border-top: none;
padding: 0;
&-btn {
padding: 10px 12px 10px 0;
}
}
.@{prefixClass}-ok-btn {
position: static;
}
.@{prefixClass}-today-btn {
float: left;
}
}

View File

@ -0,0 +1,16 @@
@prefixClass: rc-calendar;
@timePickerClass: rc-time-picker;
.@{prefixClass} {
box-sizing: border-box;
* {
box-sizing: border-box;
}
}
.@{prefixClass}-hidden {
display: none;
}
@import "Calendar.less";
@import "Picker.less";

View File

@ -0,0 +1,10 @@
@import "./common/index.less";
@import "index/Picker";
@import "index/Calendar";
@import "index/Time";
@import "index/TimePanel";
@import "index/MonthPanel";
@import "index/YearPanel";
@import "index/DecadePanel";
@import "common/RangeCalendar";
@import "common/FullCalendar";

View File

@ -0,0 +1,291 @@
.@{prefixClass} {
position: relative;
outline: none;
font-family: Arial, "Hiragino Sans GB", "Microsoft Yahei", "Microsoft Sans Serif", "WenQuanYi Micro Hei", sans-serif;
width: 253px;
border: 1px solid #ccc;
list-style: none;
font-size: 12px;
text-align: left;
background-color: #fff;
border-radius: 3px;
box-shadow: 0 1px 5px #ccc;
background-clip: padding-box;
border: 1px solid #ccc;
line-height: 1.5;
&-date-panel, &-panel {
position: relative;
outline: none;
}
&-week-number {
width: 286px;
&-cell {
text-align: center;
}
}
&-header {
padding: 0 10px;
height: 34px;
line-height: 30px;
text-align: center;
user-select: none;
-webkit-user-select: none;
border-bottom: 1px solid #ccc;
> a {
font-weight: bold;
display: inline-block;
padding: 0px 5px;
line-height: 34px;
text-align: center;
width: 30px;
&:hover {
cursor: pointer;
color: #23c0fa;
}
}
.@{prefixClass}-prev-month-btn {
position: absolute;
left: 25px;
&:after {
content: ''
}
}
.@{prefixClass}-next-month-btn {
position: absolute;
right: 25px;
&:after {
content: ''
}
}
}
&-year-select, &-month-select, &-day-select {
display: inline-block;
font-size: 12px;
font-weight: bold;
color: #666;
padding: 0 8px;
line-height: 34px;
&:hover {
cursor: pointer;
color: #23c0fa;
}
}
&-prev-month-btn,
&-next-month-btn,
&-prev-year-btn,
&-next-year-btn {
position: absolute;
top: 0;
cursor: pointer;
color: #999;
font-family: Arial, "Hiragino Sans GB", "Microsoft Yahei", "Microsoft Sans Serif", sans-serif;
padding: 0 5px;
font-size: 16px;
display: inline-block;
line-height: 34px;
&:hover {
color: #23c0fa;
}
}
&-next-year-btn {
right: 0;
&:after {
content: '»'
}
}
&-prev-year-btn {
left: 0;
&:after {
content: '«'
}
}
&-body {
padding: 9px 10px 10px;
height: 217px;
}
table {
border-collapse: collapse;
max-width: 100%;
background-color: transparent;
width: 100%;
}
table, td, th, td {
border: none;
}
&-table {
border-spacing: 0;
margin-bottom: 0;
}
&-column-header {
line-height: 18px;
padding: 6px 0;
width: 33px;
text-align: center;
.@{prefixClass}-column-header-inner {
display: block;
font-weight: normal;
}
}
&-week-number-header {
.@{prefixClass}-column-header-inner {
display: none;
}
}
&-cell {
padding: 1px 0;
}
&-date {
display: block;
margin: 0 auto;
color: #666;
border-radius: 4px 4px;
width: 26px;
height: 26px;
padding: 0;
background: transparent;
line-height: 26px;
text-align: center;
&:hover {
background: #ebfaff;
cursor: pointer;
}
}
&-selected-day &-date {
background: tint(#3fc7fa, 80%);
}
&-selected-date &-date {
background: #3fc7fa;
color: #fff;
&:hover {
background: #3fc7fa;
}
}
&-today &-date {
border: 1px solid #3fc7fa;
}
&-disabled-cell &-date {
cursor: not-allowed;
color: #bcbcbc;
background: #f3f3f3;
border-radius: 0;
width: auto;
&:hover {
background: #f3f3f3;
}
}
&-disabled-cell-first-of-row &-date {
border-top-left-radius: 4px;
border-bottom-left-radius: 4px;
}
&-disabled-cell-last-of-row &-date {
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
}
&-last-month-cell &-date, &-next-month-btn-day &-date {
color: #bbb;
}
&-footer {
border-top: 1px solid #ccc;
padding: 10px 0;
text-align: center;
position: relative;
.@{timePickerClass} {
width: 90px;
&-input {
height: 24px;
}
}
&-show-ok {
text-align: right;
.@{prefixClass} {
&-footer-btn {
padding-right: 12px;
}
&-time-picker-btn {
margin-left: 0;
padding: 0 12px;
}
&-today-btn {
float: left;
padding-left: 12px;
}
}
}
}
&-footer-btn {
margin-top: 2px;
&:after {
content: 'x';
height: 0;
font-size: 0;
overflow: hidden;
clear: both;
}
}
&-time-picker-btn {
margin-left: 10px;
}
&-today-btn, &-ok-btn, &-time-picker-btn {
display: inline-block;
text-align: center;
color: #f46830;
&:hover {
cursor: pointer;
color: #23c0fa;
}
&-disabled {
color: #bbb;
&:hover {
color: #bbb;
}
}
}
&-today-btn {
padding-left: 10px;
}
}

View File

@ -0,0 +1,115 @@
.@{prefixClass}-decade-panel {
left: 0;
top: 0;
bottom: 0;
right: 0;
background: #ffffff;
z-index: 10;
position: absolute;
outline: none;
}
.@{prefixClass}-decade-panel-hidden {
display: none;
}
.@{prefixClass}-decade-panel-header {
padding: 0 10px;
height: 34px;
line-height: 34px;
position: relative;
text-align: center;
user-select: none;
-webkit-user-select: none;
border-bottom: 1px solid #ccc;
> a {
font-weight: bold;
display: inline-block;
padding: 1px 5px;
text-align: center;
width: 30px;
&:hover {
cursor: pointer;
color: #23c0fa;
}
}
}
.@{prefixClass}-decade-panel-prev-century-btn, .@{prefixClass}-decade-panel-next-century-btn {
position: absolute;
top: 0;
}
.@{prefixClass}-decade-panel-next-century-btn {
&:after {
content: '»'
}
}
.@{prefixClass}-decade-panel-prev-century-btn {
user-select: none;
left: 0;
&:after {
content: '«'
}
}
.@{prefixClass}-decade-panel-next-century-btn {
user-select: none;
right: 0;
}
.@{prefixClass}-decade-panel-body {
padding: 9px 10px 10px;
position: absolute;
bottom: 0;
top: 34px;
}
.@{prefixClass}-decade-panel-table {
table-layout: fixed;
width: 100%;
height: 100%;
border-collapse: separate;
}
.@{prefixClass}-decade-panel-cell {
text-align: center;
}
.@{prefixClass}-decade-panel-decade {
display: block;
margin: 0 auto;
color: #666;
border-radius: 4px 4px;
height: 36px;
padding: 0;
background: transparent;
line-height: 36px;
text-align: center;
&:hover {
background: #ebfaff;
cursor: pointer;
}
}
.@{prefixClass}-decade-panel-selected-cell .@{prefixClass}-decade-panel-decade {
background: #3fc7fa;
color: #fff;
&:hover {
background: #3fc7fa;
color: #fff;
}
}
.@{prefixClass}-decade-panel-last-century-cell, .@{prefixClass}-decade-panel-next-century-cell {
.@{prefixClass}-decade-panel-decade{
user-select: none;
-webkit-user-select: none;
color: rgba(0, 0, 0, 0.25);
}
}

View File

@ -0,0 +1,22 @@
.input() {
height: 25px;
position: relative;
display: inline-block;
margin: 0 0;
padding: 4px 10px;
border-radius: 6px 6px;
border: 1px solid #d9d9d9;
background-color: #ffffff;
color: #666;
line-height: 1.5;
transform: border 0.3s cubic-bezier(0.35, 0, 0.25, 1), background 0.3s cubic-bezier(0.35, 0, 0.25, 1), box-shadow 0.3s cubic-bezier(0.35, 0, 0.25, 1);
&:hover {
border-color: #23c0fa;
}
&:focus {
border-color: #23c0fa;
box-shadow: 0 0 3px #23c0fa;
}
}

View File

@ -0,0 +1,135 @@
.@{prefixClass}-month-panel {
left: 0;
top:0;
bottom: 0;
right: 0;
background: #ffffff;
z-index: 10;
position: absolute;
outline: none;
}
.@{prefixClass}-month-panel-hidden {
display: none;
}
.@{prefixClass}-month-panel-header {
padding: 0 10px;
height: 34px;
line-height: 30px;
position: relative;
text-align: center;
user-select: none;
-webkit-user-select: none;
border-bottom: 1px solid #ccc;
> a {
font-weight: bold;
display: inline-block;
padding: 4px 5px;
text-align: center;
width: 30px;
&:hover {
cursor: pointer;
color: #23c0fa;
}
}
}
.@{prefixClass}-month-panel-prev-year-btn, .@{prefixClass}-month-panel-next-year-btn {
position: absolute;
top: 0;
}
.@{prefixClass}-month-panel-next-year-btn {
&:after {
content: '»'
}
}
.@{prefixClass}-month-panel-prev-year-btn {
user-select: none;
left: 0;
&:after {
content: '«'
}
}
.@{prefixClass}-month-panel .@{prefixClass}-month-panel-year-select {
width: 180px;
}
.@{prefixClass}-month-panel-year-select-arrow {
display: none;
}
.@{prefixClass}-month-panel-next-year-btn {
user-select: none;
right: 0;
}
.@{prefixClass}-month-panel-body {
padding: 9px 10px 10px;
position: absolute;
top: 34px;
bottom: 0;
}
.@{prefixClass}-month-panel-table {
table-layout: fixed;
width: 100%;
height: 100%;
border-collapse: separate;
}
.@{prefixClass}-month-panel-cell {
text-align: center;
.@{prefixClass}-month-panel-month {
display: block;
width: 46px;
margin: 0 auto;
color: #666;
border-radius: 4px 4px;
height: 36px;
padding: 0;
background: transparent;
line-height: 36px;
text-align: center;
&:hover {
background: #ebfaff;
cursor: pointer;
}
}
&-disabled{
.@{prefixClass}-month-panel-month {
color: #bfbfbf;
&:hover {
background: white;
cursor: not-allowed;
}
}
}
}
.@{prefixClass}-month-panel-selected-cell .@{prefixClass}-month-panel-month {
background: #3fc7fa;
color: #fff;
&:hover {
background: #3fc7fa;
color: #fff;
}
}
.@{prefixClass}-month-header-wrap {
position: relative;
height: 308px;
}

View File

@ -0,0 +1,110 @@
.@{prefixClass} {
&-picker {
.effect() {
animation-duration: .3s;
animation-fill-mode: both;
transform-origin: 0 0;
display: block !important;
}
&-slide-up-enter {
.effect();
opacity: 0;
animation-timing-function: cubic-bezier(0.08, 0.82, 0.17, 1);
animation-play-state: paused;
}
&-slide-up-appear {
.effect();
opacity: 0;
animation-timing-function: cubic-bezier(0.08, 0.82, 0.17, 1);
animation-play-state: paused;
}
&-slide-up-leave {
.effect();
opacity: 1;
animation-timing-function: cubic-bezier(0.6, 0.04, 0.98, 0.34);
animation-play-state: paused;
}
&-slide-up-enter&-slide-up-enter-active&-placement-bottomLeft,
&-slide-up-enter&-slide-up-enter-active&-placement-bottomRight,
&-slide-up-appear&-slide-up-appear-active&-placement-bottomLeft,
&-slide-up-appear&-slide-up-appear-active&-placement-bottomRight {
animation-name: rcDropdownSlideUpIn;
animation-play-state: running;
}
&-slide-up-enter&-slide-up-enter-active&-placement-topLeft,
&-slide-up-enter&-slide-up-enter-active&-placement-topRight,
&-slide-up-appear&-slide-up-appear-active&-placement-topLeft,
&-slide-up-appear&-slide-up-appear-active&-placement-topRight {
animation-name: rcDropdownSlideDownIn;
animation-play-state: running;
}
&-slide-up-leave&-slide-up-leave-active&-placement-bottomLeft,
&-slide-up-leave&-slide-up-leave-active&-placement-bottomRight {
animation-name: rcDropdownSlideUpOut;
animation-play-state: running;
}
&-slide-up-leave&-slide-up-leave-active&-placement-topLeft,
&-slide-up-leave&-slide-up-leave-active&-placement-topRight {
animation-name: rcDropdownSlideDownOut;
animation-play-state: running;
}
@keyframes rcDropdownSlideUpIn {
0% {
opacity: 0;
transform-origin: 0% 0%;
transform: scaleY(0);
}
100% {
opacity: 1;
transform-origin: 0% 0%;
transform: scaleY(1);
}
}
@keyframes rcDropdownSlideUpOut {
0% {
opacity: 1;
transform-origin: 0% 0%;
transform: scaleY(1);
}
100% {
opacity: 0;
transform-origin: 0% 0%;
transform: scaleY(0);
}
}
@keyframes rcDropdownSlideDownIn {
0% {
opacity: 0;
transform-origin: 100% 100%;
transform: scaleY(0);
}
100% {
opacity: 1;
transform-origin: 100% 100%;
transform: scaleY(1);
}
}
@keyframes rcDropdownSlideDownOut {
0% {
opacity: 1;
transform-origin: 100% 100%;
transform: scaleY(1);
}
100% {
opacity: 0;
transform-origin: 100% 100%;
transform: scaleY(0);
}
}
}
}

View File

@ -0,0 +1,6 @@
@import "./Input.less";
.@{prefixClass}-time-input {
.input();
width:40px;
}

View File

@ -0,0 +1,74 @@
.@{prefixClass}-time-panel {
left: 0;
top: 0;
bottom: 0;
right: 0;
background: #ffffff;
z-index: 10;
position: absolute;
outline: none;
}
.@{prefixClass}-time-panel-header {
padding: 0 10px;
height: 34px;
line-height: 34px;
position: relative;
text-align: center;
user-select: none;
-webkit-user-select: none;
border-bottom: 1px solid #ccc;
}
.@{prefixClass}-time-panel-body {
padding: 9px 10px 10px;
}
.@{prefixClass}-time-panel-title {
width: 180px;
font-weight: bold;
display: inline-block;
padding: 4px 5px;
text-align: center;
height: 30px;
line-height: 22px;
border-radius: 4px;
}
.@{prefixClass}-time-panel-table {
table-layout: fixed;
width: 100%;
height:255px;
border-collapse: separate;
}
.@{prefixClass}-time-panel-cell {
text-align: center;
height: 42px;
vertical-align: middle;
}
.@{prefixClass}-time-panel-time {
line-height: 26px;
display: block;
border-radius: 4px;
width:26px;
margin: 0 auto;
&:hover {
background: #ebfaff;
cursor: pointer;
}
}
.@{prefixClass}-time-panel-selected-cell .@{prefixClass}-time-panel-time {
background: #3fc7fa;
color: #fff;
&:hover {
background: #3fc7fa;
color: #fff;
}
}

View File

@ -0,0 +1,125 @@
.@{prefixClass}-year-panel {
left: 0;
top: 0;
bottom: 0;
right: 0;
background: #ffffff;
z-index: 10;
position: absolute;
outline: none;
}
.@{prefixClass}-year-panel-hidden {
display: none;
}
.@{prefixClass}-year-panel-header {
padding: 0 10px;
height: 34px;
line-height: 30px;
position: relative;
text-align: center;
user-select: none;
-webkit-user-select: none;
border-bottom: 1px solid #ccc;
> a {
font-weight: bold;
display: inline-block;
padding: 4px 5px;
text-align: center;
width: 30px;
&:hover {
cursor: pointer;
color: #23c0fa;
}
}
}
.@{prefixClass}-year-panel-prev-decade-btn, .@{prefixClass}-year-panel-next-decade-btn {
position: absolute;
top: 0;
}
.@{prefixClass}-year-panel-next-decade-btn {
&:after {
content: '»'
}
}
.@{prefixClass}-year-panel-prev-decade-btn {
user-select: none;
left: 0;
&:after {
content: '«'
}
}
.@{prefixClass}-year-panel .@{prefixClass}-year-panel-decade-select {
width: 180px;
}
.@{prefixClass}-year-panel-decade-select-arrow {
display: none;
}
.@{prefixClass}-year-panel-next-decade-btn {
user-select: none;
right: 0;
}
.@{prefixClass}-year-panel-body {
padding: 9px 10px 10px;
position: absolute;
bottom: 0;
top: 34px;
}
.@{prefixClass}-year-panel-table {
table-layout: fixed;
width: 100%;
height: 100%;
border-collapse: separate;
}
.@{prefixClass}-year-panel-cell {
text-align: center;
}
.@{prefixClass}-year-panel-year {
display: block;
width: 46px;
margin: 0 auto;
color: #666;
border-radius: 4px 4px;
height: 36px;
padding: 0;
background: transparent;
line-height: 36px;
text-align: center;
&:hover {
background: #ebfaff;
cursor: pointer;
}
}
.@{prefixClass}-year-panel-selected-cell .@{prefixClass}-year-panel-year {
background: #3fc7fa;
color: #fff;
&:hover {
background: #3fc7fa;
color: #fff;
}
}
.@{prefixClass}-year-panel-last-decade-cell, .@{prefixClass}-year-panel-next-decade-cell {
.@{prefixClass}-year-panel-year{
user-select: none;
-webkit-user-select: none;
color: rgba(0, 0, 0, 0.25);
}
}

View File

@ -0,0 +1,2 @@
import Calendar from './src/'
export default Calendar

View File

@ -0,0 +1,323 @@
<script>
import PropTypes from '@/components/_util/vue-types'
import BaseMixin from '@/components/_util/BaseMixin'
import { getOptionProps, hasProp } from '@/components/_util/props-util'
import { cloneElement } from '@/components/_util/vnode'
import KeyCode from '@/components/_util/KeyCode'
import DateTable from './date/DateTable'
import CalendarHeader from './calendar/CalendarHeader'
import CalendarFooter from './calendar/CalendarFooter'
import CalendarMixin from './mixin/CalendarMixin'
import CommonMixin from './mixin/CommonMixin'
import DateInput from './date/DateInput'
import { getTimeConfig, getTodayTime, syncTime } from './util'
function goStartMonth () {
const next = this.sValue.clone()
next.startOf('month')
this.setValue(next)
}
function goEndMonth () {
const next = this.sValue.clone()
next.endOf('month')
this.setValue(next)
}
function goTime (direction, unit) {
const next = this.sValue.clone()
next.add(direction, unit)
this.setValue(next)
}
function goMonth (direction) {
return goTime.call(this, direction, 'months')
}
function goYear (direction) {
return goTime.call(this, direction, 'years')
}
function goWeek (direction) {
return goTime.call(this, direction, 'weeks')
}
function goDay (direction) {
return goTime.call(this, direction, 'days')
}
const Calendar = {
props: {
prefixCls: PropTypes.string,
defaultValue: PropTypes.object,
value: PropTypes.object,
selectedValue: PropTypes.object,
mode: PropTypes.oneOf(['time', 'date', 'month', 'year', 'decade']),
locale: PropTypes.object,
showDateInput: PropTypes.bool.def(true),
showWeekNumber: PropTypes.bool,
showToday: PropTypes.bool.def(true),
showOk: PropTypes.bool,
// onSelect: PropTypes.func,
// onOk: PropTypes.func,
// onKeyDown: PropTypes.func,
timePicker: PropTypes.any,
dateInputPlaceholder: PropTypes.any,
// onClear: PropTypes.func,
// onChange: PropTypes.func,
// onPanelChange: PropTypes.func,
disabledDate: PropTypes.func,
disabledTime: PropTypes.any,
renderFooter: PropTypes.func,
renderSidebar: PropTypes.func,
},
mixins: [BaseMixin, CommonMixin, CalendarMixin],
data () {
return {
sMode: this.mode || 'date',
}
},
watch: {
mode (val) {
this.setState({ sMode: val })
},
},
methods: {
onKeyDown (event) {
if (event.target.nodeName.toLowerCase() === 'input') {
return undefined
}
const keyCode = event.keyCode
// mac
const ctrlKey = event.ctrlKey || event.metaKey
const { disabledDate, sValue: value } = this
switch (keyCode) {
case KeyCode.DOWN:
goWeek.call(this, 1)
event.preventDefault()
return 1
case KeyCode.UP:
goWeek.call(this, -1)
event.preventDefault()
return 1
case KeyCode.LEFT:
if (ctrlKey) {
goYear.call(this, -1)
} else {
goDay.call(this, -1)
}
event.preventDefault()
return 1
case KeyCode.RIGHT:
if (ctrlKey) {
goYear.call(this, 1)
} else {
goDay.call(this, 1)
}
event.preventDefault()
return 1
case KeyCode.HOME:
goStartMonth.call(this)
event.preventDefault()
return 1
case KeyCode.END:
goEndMonth.call(this)
event.preventDefault()
return 1
case KeyCode.PAGE_DOWN:
goMonth.call(this, 1)
event.preventDefault()
return 1
case KeyCode.PAGE_UP:
goMonth.call(this, -1)
event.preventDefault()
return 1
case KeyCode.ENTER:
if (!disabledDate || !disabledDate(value)) {
this.onSelect(value, {
source: 'keyboard',
})
}
event.preventDefault()
return 1
default:
this.__emit('keydown', event)
return 1
}
},
onClear () {
this.onSelect(null)
this.__emit('clear')
},
onOk () {
const { sSelectedValue } = this
if (this.isAllowedDate(sSelectedValue)) {
this.__emit('ok', sSelectedValue)
}
},
onDateInputChange (value) {
this.onSelect(value, {
source: 'dateInput',
})
},
onDateTableSelect (value) {
const { timePicker, sSelectedValue } = this
if (!sSelectedValue && timePicker) {
const timePickerDefaultValue = timePicker.props.defaultValue
if (timePickerDefaultValue) {
syncTime(timePickerDefaultValue, value)
}
}
this.onSelect(value)
},
onToday () {
const { sValue } = this
const now = getTodayTime(sValue)
this.onSelect(now, {
source: 'todayButton',
})
},
onPanelChange (value, mode) {
const { sValue } = this
if (!hasProp(this, 'mode')) {
this.setState({ sMode: mode })
}
this.__emit('panelChange', value || sValue, mode)
},
getRootDOMNode () {
return this.$el
},
openTimePicker () {
this.onPanelChange(null, 'time')
},
closeTimePicker () {
this.onPanelChange(null, 'date')
},
},
render () {
const {
locale, prefixCls, disabledDate,
dateInputPlaceholder, timePicker,
disabledTime, showDateInput, renderSidebar,
sValue, sSelectedValue, sMode,
$props: props,
} = this
const showTimePicker = sMode === 'time'
const disabledTimeConfig = showTimePicker && disabledTime && timePicker
? getTimeConfig(sSelectedValue, disabledTime) : null
let timePickerEle = null
if (timePicker && showTimePicker) {
const timePickerOriginProps = getOptionProps(timePicker)
const timePickerProps = {
props: {
showHour: true,
showSecond: true,
showMinute: true,
...timePickerOriginProps,
...disabledTimeConfig,
value: sSelectedValue,
disabledTime,
},
on: {
change: this.onDateInputChange,
},
}
if (timePickerOriginProps.defaultValue !== undefined) {
timePickerProps.props.defaultOpenValue = timePickerOriginProps.defaultValue
}
timePickerEle = cloneElement(timePicker, timePickerProps)
}
const dateInputElement = showDateInput ? (
<DateInput
format={this.getFormat()}
key='date-input'
value={sValue}
locale={locale}
placeholder={dateInputPlaceholder}
showClear
disabledTime={disabledTime}
disabledDate={disabledDate}
onClear={this.onClear}
prefixCls={prefixCls}
selectedValue={sSelectedValue}
onChange={this.onDateInputChange}
/>
) : null
const children = [
renderSidebar(),
(<div class={`${prefixCls}-panel`} key='panel'>
{dateInputElement}
<div class={`${prefixCls}-date-panel`}>
<CalendarHeader
locale={locale}
mode={sMode}
value={sValue}
onValueChange={this.setValue}
onPanelChange={this.onPanelChange}
showTimePicker={showTimePicker}
prefixCls={prefixCls}
/>
{timePicker && showTimePicker
? (<div class={`${prefixCls}-time-picker`}>
<div class={`${prefixCls}-time-picker-panel`}>
{timePickerEle }
</div>
</div>)
: null}
<div class={`${prefixCls}-body`}>
<DateTable
locale={locale}
value={sValue}
selectedValue={sSelectedValue}
prefixCls={prefixCls}
dateRender={props.dateRender}
onSelect={this.onDateTableSelect}
disabledDate={disabledDate}
showWeekNumber={props.showWeekNumber}
/>
</div>
<CalendarFooter
showOk={props.showOk}
renderFooter={props.renderFooter}
locale={locale}
prefixCls={prefixCls}
showToday={props.showToday}
disabledTime={disabledTime}
showTimePicker={showTimePicker}
showDateInput={props.showDateInput}
timePicker={timePicker}
selectedValue={sSelectedValue}
value={sValue}
disabledDate={disabledDate}
okDisabled={!this.isAllowedDate(sSelectedValue)}
onOk={this.onOk}
onSelect={this.onSelect}
onToday={this.onToday}
onOpenTimePicker={this.openTimePicker}
onCloseTimePicker={this.closeTimePicker}
/>
</div>
</div>),
]
return this.renderRoot({
children,
class: props.showWeekNumber ? `${prefixCls}-week-number` : '',
})
},
}
export default Calendar
</script>

View File

@ -0,0 +1,147 @@
<script>
import PropTypes from '@/components/_util/vue-types'
import BaseMixin from '@/components/_util/BaseMixin'
import { getOptionProps, hasProp } from '@/components/_util/props-util'
import DateTable from './date/DateTable'
import MonthTable from './month/MonthTable'
import CalendarMixin from './mixin/CalendarMixin'
import CommonMixin from './mixin/CommonMixin'
import CalendarHeader from './full-calendar/CalendarHeader'
const FullCalendar = {
props: {
defaultType: PropTypes.string.def('date'),
type: PropTypes.string,
prefixCls: PropTypes.string,
locale: PropTypes.object,
// onTypeChange: PropTypes.func,
fullscreen: PropTypes.bool.def(false),
monthCellRender: PropTypes.func,
dateCellRender: PropTypes.func,
showTypeSwitch: PropTypes.bool.def(true),
Select: PropTypes.func.isRequired,
headerComponents: PropTypes.array,
headerComponent: PropTypes.object, // The whole header component
headerRender: PropTypes.func,
showHeader: PropTypes.bool.def(true),
disabledDate: PropTypes.func,
},
mixins: [BaseMixin, CommonMixin, CalendarMixin],
data () {
let type
if (hasProp(this, 'type')) {
type = this.type
} else {
type = this.defaultType
}
return {
sType: type,
}
},
watch: {
type (val) {
this.setState({
sType: val,
})
},
},
methods: {
onMonthSelect (value) {
this.onSelect(value, {
target: 'month',
})
},
setType (type) {
if (!hasProp(this, 'type')) {
this.setState({
sType: type,
})
}
this.__emit('typeChange', type)
},
},
render () {
const props = getOptionProps(this)
const {
locale,
prefixCls,
fullscreen,
showHeader,
headerComponent,
headerRender,
disabledDate,
} = props
const { sValue: value, sType: type } = this
let header = null
if (showHeader) {
if (headerRender) {
header = headerRender(value, type, locale)
} else {
const TheHeader = headerComponent || CalendarHeader
const headerProps = {
props: {
...props,
prefixCls: `${prefixCls}-full`,
type,
value,
},
on: {
typeChange: this.setType,
valueChange: this.setValue,
},
key: 'calendar-header',
}
header = (
<TheHeader
{...headerProps}
/>
)
}
}
const table = type === 'date' ? (
<DateTable
dateRender={props.dateCellRender}
contentRender={props.dateCellContentRender}
locale={locale}
prefixCls={prefixCls}
onSelect={this.onSelect}
value={value}
disabledDate={disabledDate}
/>
) : (
<MonthTable
cellRender={props.monthCellRender}
contentRender={props.monthCellContentRender}
locale={locale}
onSelect={this.onMonthSelect}
prefixCls={`${prefixCls}-month-panel`}
value={value}
disabledDate={disabledDate}
/>
)
const children = [
header,
(<div key='calendar-body' class={`${prefixCls}-calendar-body`}>
{ table }
</div>),
]
const className = [`${prefixCls}-full`]
if (fullscreen) {
className.push(`${prefixCls}-fullscreen`)
}
return this.renderRoot({
children,
class: className.join(' '),
})
},
}
export default FullCalendar
</script>

View File

@ -0,0 +1,107 @@
<script>
import PropTypes from '@/components/_util/vue-types'
import BaseMixin from '@/components/_util/BaseMixin'
import KeyCode from '@/components/_util/KeyCode'
import CalendarHeader from './calendar/CalendarHeader'
import CalendarFooter from './calendar/CalendarFooter'
import CalendarMixin from './mixin/CalendarMixin'
import CommonMixin from './mixin/CommonMixin'
const MonthCalendar = {
props: {
monthCellRender: PropTypes.func,
dateCellRender: PropTypes.func,
},
mixins: [BaseMixin, CommonMixin, CalendarMixin],
data () {
return { mode: 'month' }
},
methods: {
onKeyDown (event) {
const keyCode = event.keyCode
const ctrlKey = event.ctrlKey || event.metaKey
const stateValue = this.sValue
const { disabledDate } = this
let value = stateValue
switch (keyCode) {
case KeyCode.DOWN:
value = stateValue.clone()
value.add(3, 'months')
break
case KeyCode.UP:
value = stateValue.clone()
value.add(-3, 'months')
break
case KeyCode.LEFT:
value = stateValue.clone()
if (ctrlKey) {
value.add(-1, 'years')
} else {
value.add(-1, 'months')
}
break
case KeyCode.RIGHT:
value = stateValue.clone()
if (ctrlKey) {
value.add(1, 'years')
} else {
value.add(1, 'months')
}
break
case KeyCode.ENTER:
if (!disabledDate || !disabledDate(stateValue)) {
this.onSelect(stateValue)
}
event.preventDefault()
return 1
default:
return undefined
}
if (value !== stateValue) {
this.setValue(value)
event.preventDefault()
return 1
}
},
handlePanelChange (_, mode) {
if (mode !== 'date') {
this.setState({ mode })
}
},
},
render () {
const { mode, sValue: value, $props: props } = this
const children = (
<div class={`${props.prefixCls}-month-calendar-content`}>
<div class={`${props.prefixCls}-month-header-wrap`}>
<CalendarHeader
prefixCls={props.prefixCls}
mode={mode}
value={value}
locale={props.locale}
disabledMonth={props.disabledDate}
monthCellRender={props.monthCellRender}
monthCellContentRender={props.monthCellContentRender}
onMonthSelect={this.onSelect}
onValueChange={this.setValue}
onPanelChange={this.handlePanelChange}
/>
</div>
<CalendarFooter
prefixCls={props.prefixCls}
renderFooter={props.renderFooter}
/>
</div>
)
return this.renderRoot({
class: `${props.prefixCls}-month-calendar`,
children,
})
},
}
export default MonthCalendar
</script>

View File

@ -0,0 +1,213 @@
<script>
import PropTypes from '@/components/_util/vue-types'
import BaseMixin from '@/components/_util/BaseMixin'
import { getOptionProps, hasProp, getEvents, getStyle } from '@/components/_util/props-util'
import { cloneElement } from '@/components/_util/vnode'
import createChainedFunction from '@/components/_util/createChainedFunction'
import KeyCode from '@/components/_util/KeyCode'
import placements from './picker/placements'
import Trigger from '@/components/trigger'
const Picker = {
props: {
animation: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
disabled: PropTypes.bool,
transitionName: PropTypes.string,
// onChange: PropTypes.func,
// onOpenChange: PropTypes.func,
children: PropTypes.func,
getCalendarContainer: PropTypes.func,
calendar: PropTypes.any,
open: PropTypes.bool,
defaultOpen: PropTypes.bool.def(false),
prefixCls: PropTypes.string.def('rc-calendar-picker'),
placement: PropTypes.any.def('bottomLeft'),
value: PropTypes.oneOfType([
PropTypes.object,
PropTypes.array,
]),
defaultValue: PropTypes.oneOfType([
PropTypes.object,
PropTypes.array,
]),
align: PropTypes.object.def({}),
},
mixins: [BaseMixin],
data () {
const props = this.$props
let open
if (hasProp(this, 'open')) {
open = props.open
} else {
open = props.defaultOpen
}
const value = props.value || props.defaultValue
return {
sOpen: open,
sValue: value,
}
},
watch: {
value (val) {
this.setState({
sValue: val,
})
},
open (val) {
this.setState({
sOpen: val,
})
},
},
mounted () {
this.preSOpen = this.sOpen
},
updated () {
if (!this.preSOpen && this.sOpen) {
// setTimeout is for making sure saveCalendarRef happen before focusCalendar
this.focusTimeout = setTimeout(this.focusCalendar, 0)
}
this.preSOpen = this.sOpen
},
beforeDestroy () {
clearTimeout(this.focusTimeout)
},
methods: {
onCalendarKeyDown (event) {
if (event.keyCode === KeyCode.ESC) {
event.stopPropagation()
this.close(this.focus)
}
},
onCalendarSelect (value, cause = {}) {
const props = this.$props
if (!hasProp(this, 'value')) {
this.setState({
sValue: value,
})
}
const calendarProps = getOptionProps(props.calendar)
if (
cause.source === 'keyboard' ||
(!calendarProps.timePicker && cause.source !== 'dateInput') ||
cause.source === 'todayButton') {
this.close(this.focus)
}
this.__emit('change', value)
},
onKeyDown (event) {
if (event.keyCode === KeyCode.DOWN && !this.sOpen) {
this.open()
event.preventDefault()
}
},
onCalendarOk () {
this.close(this.focus)
},
onCalendarClear () {
this.close(this.focus)
},
onVisibleChange (open) {
this.setOpen(open)
},
getCalendarElement () {
const props = this.$props
const calendarProps = getOptionProps(props.calendar)
const calendarEvents = getEvents(props.calendar)
const { sValue: value } = this
const defaultValue = value
const extraProps = {
ref: 'calendarInstance',
props: {
defaultValue: defaultValue || calendarProps.defaultValue,
selectedValue: value,
},
on: {
keydown: this.onCalendarKeyDown,
ok: createChainedFunction(calendarEvents.ok, this.onCalendarOk),
select: createChainedFunction(calendarEvents.select, this.onCalendarSelect),
clear: createChainedFunction(calendarEvents.clear, this.onCalendarClear),
},
}
return cloneElement(props.calendar, extraProps)
},
setOpen (open, callback) {
if (this.sOpen !== open) {
if (!hasProp(this, 'open')) {
this.setState({
sOpen: open,
}, callback)
}
this.__emit('openChange', open)
}
},
open (callback) {
this.setOpen(true, callback)
},
close (callback) {
this.setOpen(false, callback)
},
focus () {
if (!this.sOpen) {
this.$el.focus()
}
},
focusCalendar () {
if (this.sOpen && !!this.$refs.calendarInstance) {
this.$refs.calendarInstance.focus()
}
},
},
render () {
const props = getOptionProps(this)
const style = getStyle(this)
const {
prefixCls, placement,
getCalendarContainer,
align, animation,
disabled,
dropdownClassName,
transitionName, children,
} = props
const state = this.$data
return (<Trigger
popupAlign={align}
builtinPlacements={placements}
popupPlacement={placement}
action={(disabled && !state.sOpen) ? [] : ['click']}
destroyPopupOnHide
getPopupContainer={getCalendarContainer}
popupStyle={style}
popupAnimation={animation}
popupTransitionName={transitionName}
popupVisible={state.sOpen}
onPopupVisibleChange={this.onVisibleChange}
prefixCls={prefixCls}
popupClassName={dropdownClassName}
>
<template slot='popup'>
{this.getCalendarElement()}
</template>
{cloneElement(children(state, props), { on: { keydown: this.onKeyDown }})}
</Trigger>)
},
}
export default Picker
</script>

View File

@ -0,0 +1,624 @@
<script>
import PropTypes from '@/components/_util/vue-types'
import BaseMixin from '@/components/_util/BaseMixin'
import { getOptionProps, hasProp } from '@/components/_util/props-util'
import { cloneElement } from '@/components/_util/vnode'
import moment from 'moment'
import classnames from 'classnames'
import CalendarPart from './range-calendar/CalendarPart'
import TodayButton from './calendar/TodayButton'
import OkButton from './calendar/OkButton'
import TimePickerButton from './calendar/TimePickerButton'
import CommonMixin from './mixin/CommonMixin'
import { syncTime, getTodayTime, isAllowedDate } from './util/'
function noop () {}
function isEmptyArray (arr) {
return Array.isArray(arr) && (arr.length === 0 || arr.every(i => !i))
}
function isArraysEqual (a, b) {
if (a === b) return true
if (a === null || typeof a === 'undefined' || b === null || typeof b === 'undefined') {
return false
}
if (a.length !== b.length) return false
for (let i = 0; i < a.length; ++i) {
if (a[i] !== b[i]) return false
}
return true
}
function getValueFromSelectedValue (selectedValue) {
const [start, end] = selectedValue
const newEnd = end && end.isSame(start, 'month') ? end.clone().add(1, 'month') : end
return [start, newEnd]
}
function normalizeAnchor (props, init) {
const selectedValue = props.selectedValue || init && props.defaultSelectedValue
const value = props.value || init && props.defaultValue
const normalizedValue = value
? getValueFromSelectedValue(value)
: getValueFromSelectedValue(selectedValue)
return !isEmptyArray(normalizedValue)
? normalizedValue : init && [moment(), moment().add(1, 'months')]
}
function generateOptions (length, extraOptionGen) {
const arr = extraOptionGen ? extraOptionGen().concat() : []
for (let value = 0; value < length; value++) {
if (arr.indexOf(value) === -1) {
arr.push(value)
}
}
return arr
}
function onInputSelect (direction, value) {
if (!value) {
return
}
const originalValue = this.state.selectedValue
const selectedValue = originalValue.concat()
const index = direction === 'left' ? 0 : 1
selectedValue[index] = value
if (selectedValue[0] && this.compare(selectedValue[0], selectedValue[1]) > 0) {
selectedValue[1 - index] = this.state.showTimePicker ? selectedValue[index] : undefined
}
this.props.onInputSelect(selectedValue)
this.fireSelectValueChange(selectedValue)
}
const RangeCalendar = createReactClass({
propTypes: {
prefixCls: PropTypes.string,
dateInputPlaceholder: PropTypes.any,
defaultValue: PropTypes.any,
value: PropTypes.any,
hoverValue: PropTypes.any,
mode: PropTypes.arrayOf(PropTypes.oneOf(['date', 'month', 'year', 'decade'])),
showDateInput: PropTypes.bool,
timePicker: PropTypes.any,
showOk: PropTypes.bool,
showToday: PropTypes.bool,
defaultSelectedValue: PropTypes.array,
selectedValue: PropTypes.array,
onOk: PropTypes.func,
showClear: PropTypes.bool,
locale: PropTypes.object,
onChange: PropTypes.func,
onSelect: PropTypes.func,
onValueChange: PropTypes.func,
onHoverChange: PropTypes.func,
onPanelChange: PropTypes.func,
format: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
onClear: PropTypes.func,
type: PropTypes.any,
disabledDate: PropTypes.func,
disabledTime: PropTypes.func,
},
mixins: [CommonMixin],
getDefaultProps () {
return {
type: 'both',
defaultSelectedValue: [],
onValueChange: noop,
onHoverChange: noop,
onPanelChange: noop,
disabledTime: noop,
onInputSelect: noop,
showToday: true,
showDateInput: true,
}
},
getInitialState () {
const props = this.props
const selectedValue = props.selectedValue || props.defaultSelectedValue
const value = normalizeAnchor(props, 1)
return {
selectedValue,
prevSelectedValue: selectedValue,
firstSelectedValue: null,
hoverValue: props.hoverValue || [],
value,
showTimePicker: false,
mode: props.mode || ['date', 'date'],
}
},
componentWillReceiveProps (nextProps) {
const { state } = this
const newState = {}
if ('value' in nextProps) {
newState.value = normalizeAnchor(nextProps, 0)
this.setState(newState)
}
if ('hoverValue' in nextProps && !isArraysEqual(state.hoverValue, nextProps.hoverValue)) {
this.setState({ hoverValue: nextProps.hoverValue })
}
if ('selectedValue' in nextProps) {
newState.selectedValue = nextProps.selectedValue
newState.prevSelectedValue = nextProps.selectedValue
this.setState(newState)
}
if ('mode' in nextProps && !isArraysEqual(state.mode, nextProps.mode)) {
this.setState({ mode: nextProps.mode })
}
},
onDatePanelEnter () {
if (this.hasSelectedValue()) {
this.fireHoverValueChange(this.state.selectedValue.concat())
}
},
onDatePanelLeave () {
if (this.hasSelectedValue()) {
this.fireHoverValueChange([])
}
},
onSelect (value) {
const { type } = this.props
const { selectedValue, prevSelectedValue, firstSelectedValue } = this.state
let nextSelectedValue
if (type === 'both') {
if (!firstSelectedValue) {
syncTime(prevSelectedValue[0], value)
nextSelectedValue = [value]
} else if (this.compare(firstSelectedValue, value) < 0) {
syncTime(prevSelectedValue[1], value)
nextSelectedValue = [firstSelectedValue, value]
} else {
syncTime(prevSelectedValue[0], value)
syncTime(prevSelectedValue[1], firstSelectedValue)
nextSelectedValue = [value, firstSelectedValue]
}
} else if (type === 'start') {
syncTime(prevSelectedValue[0], value)
const endValue = selectedValue[1]
nextSelectedValue = endValue && this.compare(endValue, value) > 0
? [value, endValue] : [value]
} else { // type === 'end'
const startValue = selectedValue[0]
if (startValue && this.compare(startValue, value) <= 0) {
syncTime(prevSelectedValue[1], value)
nextSelectedValue = [startValue, value]
} else {
syncTime(prevSelectedValue[0], value)
nextSelectedValue = [value]
}
}
this.fireSelectValueChange(nextSelectedValue)
},
onDayHover (value) {
let hoverValue = []
const { selectedValue, firstSelectedValue } = this.state
const { type } = this.props
if (type === 'start' && selectedValue[1]) {
hoverValue = this.compare(value, selectedValue[1]) < 0
? [value, selectedValue[1]] : [value]
} else if (type === 'end' && selectedValue[0]) {
hoverValue = this.compare(value, selectedValue[0]) > 0
? [selectedValue[0], value] : []
} else {
if (!firstSelectedValue) {
return
}
hoverValue = this.compare(value, firstSelectedValue) < 0
? [value, firstSelectedValue] : [firstSelectedValue, value]
}
this.fireHoverValueChange(hoverValue)
},
onToday () {
const startValue = getTodayTime(this.state.value[0])
const endValue = startValue.clone().add(1, 'months')
this.setState({ value: [startValue, endValue] })
},
onOpenTimePicker () {
this.setState({
showTimePicker: true,
})
},
onCloseTimePicker () {
this.setState({
showTimePicker: false,
})
},
onOk () {
const { selectedValue } = this.state
if (this.isAllowedDateAndTime(selectedValue)) {
this.props.onOk(this.state.selectedValue)
}
},
onStartInputSelect (...oargs) {
const args = ['left'].concat(oargs)
return onInputSelect.apply(this, args)
},
onEndInputSelect (...oargs) {
const args = ['right'].concat(oargs)
return onInputSelect.apply(this, args)
},
onStartValueChange (leftValue) {
const value = [...this.state.value]
value[0] = leftValue
return this.fireValueChange(value)
},
onEndValueChange (rightValue) {
const value = [...this.state.value]
value[1] = rightValue
return this.fireValueChange(value)
},
onStartPanelChange (value, mode) {
const { props, state } = this
const newMode = [mode, state.mode[1]]
if (!('mode' in props)) {
this.setState({
mode: newMode,
})
}
const newValue = [value || state.value[0], state.value[1]]
props.onPanelChange(newValue, newMode)
},
onEndPanelChange (value, mode) {
const { props, state } = this
const newMode = [state.mode[0], mode]
if (!('mode' in props)) {
this.setState({
mode: newMode,
})
}
const newValue = [state.value[0], value || state.value[1]]
props.onPanelChange(newValue, newMode)
},
getStartValue () {
let value = this.state.value[0]
const selectedValue = this.state.selectedValue
// keep selectedTime when select date
if (selectedValue[0] && this.props.timePicker) {
value = value.clone()
syncTime(selectedValue[0], value)
}
if (this.state.showTimePicker && selectedValue[0]) {
return selectedValue[0]
}
return value
},
getEndValue () {
const { value, selectedValue, showTimePicker } = this.state
const endValue = value[1] ? value[1].clone() : value[0].clone().add(1, 'month')
// keep selectedTime when select date
if (selectedValue[1] && this.props.timePicker) {
syncTime(selectedValue[1], endValue)
}
if (showTimePicker) {
return selectedValue[1] ? selectedValue[1] : this.getStartValue()
}
return endValue
},
// get disabled hours for second picker
getEndDisableTime () {
const { selectedValue, value } = this.state
const { disabledTime } = this.props
const userSettingDisabledTime = disabledTime(selectedValue, 'end') || {}
const startValue = selectedValue && selectedValue[0] || value[0].clone()
// if startTime and endTime is same day..
// the second time picker will not able to pick time before first time picker
if (!selectedValue[1] || startValue.isSame(selectedValue[1], 'day')) {
const hours = startValue.hour()
const minutes = startValue.minute()
const second = startValue.second()
let { disabledHours, disabledMinutes, disabledSeconds } = userSettingDisabledTime
const oldDisabledMinutes = disabledMinutes ? disabledMinutes() : []
const olddisabledSeconds = disabledSeconds ? disabledSeconds() : []
disabledHours = generateOptions(hours, disabledHours)
disabledMinutes = generateOptions(minutes, disabledMinutes)
disabledSeconds = generateOptions(second, disabledSeconds)
return {
disabledHours () {
return disabledHours
},
disabledMinutes (hour) {
if (hour === hours) {
return disabledMinutes
}
return oldDisabledMinutes
},
disabledSeconds (hour, minute) {
if (hour === hours && minute === minutes) {
return disabledSeconds
}
return olddisabledSeconds
},
}
}
return userSettingDisabledTime
},
isAllowedDateAndTime (selectedValue) {
return isAllowedDate(selectedValue[0], this.props.disabledDate, this.disabledStartTime) &&
isAllowedDate(selectedValue[1], this.props.disabledDate, this.disabledEndTime)
},
isMonthYearPanelShow (mode) {
return ['month', 'year', 'decade'].indexOf(mode) > -1
},
hasSelectedValue () {
const { selectedValue } = this.state
return !!selectedValue[1] && !!selectedValue[0]
},
compare (v1, v2) {
if (this.props.timePicker) {
return v1.diff(v2)
}
return v1.diff(v2, 'days')
},
fireSelectValueChange (selectedValue, direct) {
const { timePicker } = this.props
const { prevSelectedValue } = this.state
if (timePicker && timePicker.props.defaultValue) {
const timePickerDefaultValue = timePicker.props.defaultValue
if (!prevSelectedValue[0] && selectedValue[0]) {
syncTime(timePickerDefaultValue[0], selectedValue[0])
}
if (!prevSelectedValue[1] && selectedValue[1]) {
syncTime(timePickerDefaultValue[1], selectedValue[1])
}
}
if (!('selectedValue' in this.props)) {
this.setState({
selectedValue,
})
}
//
if (!this.state.selectedValue[0] || !this.state.selectedValue[1]) {
const startValue = selectedValue[0] || moment()
const endValue = selectedValue[1] || startValue.clone().add(1, 'months')
this.setState({
selectedValue,
value: getValueFromSelectedValue([startValue, endValue]),
})
}
if (selectedValue[0] && !selectedValue[1]) {
this.setState({ firstSelectedValue: selectedValue[0] })
this.fireHoverValueChange(selectedValue.concat())
}
this.props.onChange(selectedValue)
if (direct || selectedValue[0] && selectedValue[1]) {
this.setState({
prevSelectedValue: selectedValue,
firstSelectedValue: null,
})
this.fireHoverValueChange([])
this.props.onSelect(selectedValue)
}
},
fireValueChange (value) {
const props = this.props
if (!('value' in props)) {
this.setState({
value,
})
}
props.onValueChange(value)
},
fireHoverValueChange (hoverValue) {
const props = this.props
if (!('hoverValue' in props)) {
this.setState({ hoverValue })
}
props.onHoverChange(hoverValue)
},
clear () {
this.fireSelectValueChange([], true)
this.props.onClear()
},
disabledStartTime (time) {
return this.props.disabledTime(time, 'start')
},
disabledEndTime (time) {
return this.props.disabledTime(time, 'end')
},
disabledStartMonth (month) {
const { value } = this.state
return month.isSameOrAfter(value[1], 'month')
},
disabledEndMonth (month) {
const { value } = this.state
return month.isSameOrBefore(value[0], 'month')
},
render () {
const { props, state } = this
const {
prefixCls, dateInputPlaceholder,
timePicker, showOk, locale, showClear,
showToday, type,
} = props
const {
hoverValue,
selectedValue,
mode,
showTimePicker,
} = state
const className = {
[props.className]: !!props.className,
[prefixCls]: 1,
[`${prefixCls}-hidden`]: !props.visible,
[`${prefixCls}-range`]: 1,
[`${prefixCls}-show-time-picker`]: showTimePicker,
[`${prefixCls}-week-number`]: props.showWeekNumber,
}
const classes = classnames(className)
const newProps = {
selectedValue: state.selectedValue,
onSelect: this.onSelect,
onDayHover: type === 'start' && selectedValue[1] ||
type === 'end' && selectedValue[0] || !!hoverValue.length
? this.onDayHover : undefined,
}
let placeholder1
let placeholder2
if (dateInputPlaceholder) {
if (Array.isArray(dateInputPlaceholder)) {
[placeholder1, placeholder2] = dateInputPlaceholder
} else {
placeholder1 = placeholder2 = dateInputPlaceholder
}
}
const showOkButton = showOk === true || showOk !== false && !!timePicker
const cls = classnames({
[`${prefixCls}-footer`]: true,
[`${prefixCls}-range-bottom`]: true,
[`${prefixCls}-footer-show-ok`]: showOkButton,
})
const startValue = this.getStartValue()
const endValue = this.getEndValue()
const todayTime = getTodayTime(startValue)
const thisMonth = todayTime.month()
const thisYear = todayTime.year()
const isTodayInView =
startValue.year() === thisYear && startValue.month() === thisMonth ||
endValue.year() === thisYear && endValue.month() === thisMonth
const nextMonthOfStart = startValue.clone().add(1, 'months')
const isClosestMonths = nextMonthOfStart.year() === endValue.year() &&
nextMonthOfStart.month() === endValue.month()
return (
<div
ref={this.saveRoot}
className={classes}
style={props.style}
tabIndex='0'
>
{props.renderSidebar()}
<div className={`${prefixCls}-panel`}>
{showClear && selectedValue[0] && selectedValue[1]
? <a
className={`${prefixCls}-clear-btn`}
role='button'
title={locale.clear}
onClick={this.clear}
/> : null}
<div
className={`${prefixCls}-date-panel`}
onMouseLeave={type !== 'both' ? this.onDatePanelLeave : undefined}
onMouseEnter={type !== 'both' ? this.onDatePanelEnter : undefined}
>
<CalendarPart
{...props}
{...newProps}
hoverValue={hoverValue}
direction='left'
disabledTime={this.disabledStartTime}
disabledMonth={this.disabledStartMonth}
format={this.getFormat()}
value={startValue}
mode={mode[0]}
placeholder={placeholder1}
onInputSelect={this.onStartInputSelect}
onValueChange={this.onStartValueChange}
onPanelChange={this.onStartPanelChange}
showDateInput={this.props.showDateInput}
timePicker={timePicker}
showTimePicker={showTimePicker}
enablePrev
enableNext={!isClosestMonths || this.isMonthYearPanelShow(mode[1])}
/>
<span className={`${prefixCls}-range-middle`}>~</span>
<CalendarPart
{...props}
{...newProps}
hoverValue={hoverValue}
direction='right'
format={this.getFormat()}
timePickerDisabledTime={this.getEndDisableTime()}
placeholder={placeholder2}
value={endValue}
mode={mode[1]}
onInputSelect={this.onEndInputSelect}
onValueChange={this.onEndValueChange}
onPanelChange={this.onEndPanelChange}
showDateInput={this.props.showDateInput}
timePicker={timePicker}
showTimePicker={showTimePicker}
disabledTime={this.disabledEndTime}
disabledMonth={this.disabledEndMonth}
enablePrev={!isClosestMonths || this.isMonthYearPanelShow(mode[0])}
enableNext
/>
</div>
<div className={cls}>
{props.renderFooter()}
{showToday || props.timePicker || showOkButton ? (
<div className={`${prefixCls}-footer-btn`}>
{showToday ? (
<TodayButton
{...props}
disabled={isTodayInView}
value={state.value[0]}
onToday={this.onToday}
text={locale.backToToday}
/>
) : null}
{props.timePicker
? <TimePickerButton
{...props}
showTimePicker={showTimePicker}
onOpenTimePicker={this.onOpenTimePicker}
onCloseTimePicker={this.onCloseTimePicker}
timePickerDisabled={!this.hasSelectedValue() || hoverValue.length}
/> : null}
{showOkButton
? <OkButton
{...props}
onOk={this.onOk}
okDisabled={!this.isAllowedDateAndTime(selectedValue) ||
!this.hasSelectedValue() || hoverValue.length
}
/> : null}
</div>
) : null}
</div>
</div>
</div>
)
},
})
export default RangeCalendar
</script>

View File

@ -0,0 +1,82 @@
<script>
import PropTypes from '@/components/_util/vue-types'
import BaseMixin from '@/components/_util/BaseMixin'
import { getOptionProps } from '@/components/_util/props-util'
import TodayButton from '../calendar/TodayButton'
import OkButton from '../calendar/OkButton'
import TimePickerButton from '../calendar/TimePickerButton'
const CalendarFooter = {
mixins: [BaseMixin],
props: {
prefixCls: PropTypes.string,
showDateInput: PropTypes.bool,
disabledTime: PropTypes.any,
timePicker: PropTypes.any,
selectedValue: PropTypes.any,
showOk: PropTypes.bool,
// onSelect: PropTypes.func,
value: PropTypes.object,
renderFooter: PropTypes.func,
defaultValue: PropTypes.object,
},
methods: {
onSelect (value) {
this.__emit('select', value)
},
getRootDOMNode () {
return this.$el
},
},
render () {
const props = getOptionProps(this)
const { $listeners } = this
const { value, prefixCls, showOk, timePicker, renderFooter, showToday } = props
let footerEl = null
const extraFooter = renderFooter()
if (showToday || timePicker || extraFooter) {
const btnProps = {
props: {
...props,
value: value,
},
on: $listeners,
}
let nowEl
if (showToday) {
nowEl = <TodayButton {...btnProps} />
}
delete btnProps.props.value
let okBtn
if (showOk === true || showOk !== false && !!timePicker) {
okBtn = <OkButton {...btnProps} />
}
let timePickerBtn
if (timePicker) {
timePickerBtn = <TimePickerButton {...btnProps} />
}
let footerBtn
if (nowEl || timePickerBtn || okBtn) {
footerBtn = (<span class={`${prefixCls}-footer-btn`}>
{[nowEl, timePickerBtn, okBtn]}
</span>)
}
const cls = {
[`${prefixCls}-footer`]: true,
[`${prefixCls}-footer-show-ok`]: okBtn,
}
footerEl = (
<div class={cls}>
{extraFooter}
{footerBtn}
</div>)
}
return footerEl
},
}
export default CalendarFooter
</script>

View File

@ -0,0 +1,212 @@
<script>
import PropTypes from '@/components/_util/vue-types'
import BaseMixin from '@/components/_util/BaseMixin'
import { getOptionProps } from '@/components/_util/props-util'
import MonthPanel from '../month/MonthPanel'
import YearPanel from '../year/YearPanel'
import DecadePanel from '../decade/DecadePanel'
function goMonth (direction) {
const next = this.value.clone()
next.add(direction, 'months')
this.__emit('valueChange', next)
}
function goYear (direction) {
const next = this.value.clone()
next.add(direction, 'years')
this.__emit('valueChange', next)
}
function showIf (condition, el) {
return condition ? el : null
}
const CalendarHeader = {
mixins: [BaseMixin],
props: {
prefixCls: PropTypes.string,
value: PropTypes.object,
// onValueChange: PropTypes.func,
showTimePicker: PropTypes.bool,
// onPanelChange: PropTypes.func,
locale: PropTypes.object,
enablePrev: PropTypes.any.def(1),
enableNext: PropTypes.any.def(1),
disabledMonth: PropTypes.func,
},
data () {
this.nextMonth = goMonth.bind(this, 1)
this.previousMonth = goMonth.bind(this, -1)
this.nextYear = goYear.bind(this, 1)
this.previousYear = goYear.bind(this, -1)
return {
yearPanelReferer: null,
}
},
methods: {
onMonthSelect (value) {
this.__emit('panelChange', value, 'date')
if (this.__emit('monthSelect', value)) {
this.__emit('valueChange', value)
}
},
onYearSelect (value) {
const referer = this.yearPanelReferer
this.setState({ yearPanelReferer: null })
this.__emit('panelChange', value, referer)
this.__emit('valueChange', value)
},
onDecadeSelect (value) {
this.__emit('panelChange', value, 'year')
this.__emit('valueChange', value)
},
monthYearElement (showTimePicker) {
const props = this.$props
const prefixCls = props.prefixCls
const locale = props.locale
const value = props.value
const localeData = value.localeData()
const monthBeforeYear = locale.monthBeforeYear
const selectClassName = `${prefixCls}-${monthBeforeYear ? 'my-select' : 'ym-select'}`
const year = (<a
class={`${prefixCls}-year-select`}
role='button'
onClick={showTimePicker ? null : () => this.showYearPanel('date')}
title={locale.yearSelect}
>
{value.format(locale.yearFormat)}
</a>)
const month = (<a
class={`${prefixCls}-month-select`}
role='button'
onClick={showTimePicker ? null : this.showMonthPanel}
title={locale.monthSelect}
>
{locale.monthFormat ? value.format(locale.monthFormat) : localeData.monthsShort(value)}
</a>)
let day
if (showTimePicker) {
day = (<a
class={`${prefixCls}-day-select`}
role='button'
>
{value.format(locale.dayFormat)}
</a>)
}
let my = []
if (monthBeforeYear) {
my = [month, day, year]
} else {
my = [year, month, day]
}
return (<span class={selectClassName}>
{my}
</span>)
},
showMonthPanel () {
// null means that users' interaction doesn't change value
this.__emit('panelChange', null, 'month')
},
showYearPanel (referer) {
this.setState({ yearPanelReferer: referer })
this.__emit('panelChange', null, 'year')
},
showDecadePanel () {
this.__emit('panelChange', null, 'decade')
},
},
render () {
const props = getOptionProps(this)
const {
prefixCls,
locale,
mode,
value,
showTimePicker,
enableNext,
enablePrev,
disabledMonth,
} = props
let panel = null
if (mode === 'month') {
panel = (
<MonthPanel
locale={locale}
defaultValue={value}
rootPrefixCls={prefixCls}
onSelect={this.onMonthSelect}
onYearPanelShow={() => this.showYearPanel('month')}
disabledDate={disabledMonth}
cellRender={props.monthCellRender}
contentRender={props.monthCellContentRender}
/>
)
}
if (mode === 'year') {
panel = (
<YearPanel
locale={locale}
defaultValue={value}
rootPrefixCls={prefixCls}
onSelect={this.onYearSelect}
onDecadePanelShow={this.showDecadePanel}
/>
)
}
if (mode === 'decade') {
panel = (
<DecadePanel
locale={locale}
defaultValue={value}
rootPrefixCls={prefixCls}
onSelect={this.onDecadeSelect}
/>
)
}
return (<div class={`${prefixCls}-header`}>
<div style={{ position: 'relative' }}>
{showIf(enablePrev && !showTimePicker,
<a
class={`${prefixCls}-prev-year-btn`}
role='button'
onClick={this.previousYear}
title={locale.previousYear}
/>)}
{showIf(enablePrev && !showTimePicker,
<a
class={`${prefixCls}-prev-month-btn`}
role='button'
onClick={this.previousMonth}
title={locale.previousMonth}
/>)}
{this.monthYearElement(showTimePicker)}
{showIf(enableNext && !showTimePicker,
<a
class={`${prefixCls}-next-month-btn`}
onClick={this.nextMonth}
title={locale.nextMonth}
/>)}
{showIf(enableNext && !showTimePicker,
<a
class={`${prefixCls}-next-year-btn`}
onClick={this.nextYear}
title={locale.nextYear}
/>)}
</div>
{panel}
</div>)
},
}
export default CalendarHeader
</script>

View File

@ -0,0 +1,23 @@
<script>
function noop () {}
export default {
functional: true,
render: function (createElement, context) {
const { data, listeners = {}} = context
const { prefixCls, locale, okDisabled } = data
const { ok = noop } = listeners
let className = `${prefixCls}-ok-btn`
if (okDisabled) {
className += ` ${prefixCls}-ok-btn-disabled`
}
return (<a
class={className}
role='button'
onClick={okDisabled ? noop : ok}
>
{locale.ok}
</a>)
},
}
</script>

View File

@ -0,0 +1,29 @@
<script>
function noop () {}
export default {
functional: true,
render: function (createElement, context) {
const { data, listeners = {}} = context
const {
prefixCls, locale, showTimePicker,
timePickerDisabled } = data
const { closeTimePicker = noop, openTimePicker = noop } = listeners
const className = {
[`${prefixCls}-time-picker-btn`]: true,
[`${prefixCls}-time-picker-btn-disabled`]: timePickerDisabled,
}
let onClick = noop
if (!timePickerDisabled) {
onClick = showTimePicker ? closeTimePicker : openTimePicker
}
return (<a
class={className}
role='button'
onClick={onClick}
>
{showTimePicker ? locale.dateSelect : locale.timeSelect}
</a>)
},
}
</script>

View File

@ -0,0 +1,37 @@
<script>
import { getTodayTimeStr, getTodayTime, isAllowedDate } from '../util/'
function noop () {}
export default {
functional: true,
render (createElement, context) {
const { data, listeners = {}} = context
const {
prefixCls,
locale,
value,
timePicker,
disabled,
disabledDate,
// onToday,
text,
} = data
const { today = noop } = listeners
const localeNow = (!text && timePicker ? locale.now : text) || locale.today
const disabledToday =
disabledDate && !isAllowedDate(getTodayTime(value), disabledDate)
const isDisabled = disabledToday || disabled
const disabledTodayClass = isDisabled
? `${prefixCls}-today-btn-disabled` : ''
return (
<a
class={`${prefixCls}-today-btn ${disabledTodayClass}`}
role='button'
onClick={isDisabled ? noop : today}
title={getTodayTimeStr(value)}
>
{localeNow}
</a>
)
},
}
</script>

View File

@ -0,0 +1,4 @@
export default {
DATE_ROW_COUNT: 6,
DATE_COL_COUNT: 7,
}

View File

@ -0,0 +1,148 @@
<script>
import PropTypes from '@/components/_util/vue-types'
import BaseMixin from '@/components/_util/BaseMixin'
import moment from 'moment'
const DateInput = {
mixins: [BaseMixin],
props: {
prefixCls: PropTypes.string,
timePicker: PropTypes.object,
value: PropTypes.object,
disabledTime: PropTypes.any,
format: PropTypes.string,
locale: PropTypes.object,
disabledDate: PropTypes.func,
// onChange: PropTypes.func,
// onClear: PropTypes.func,
placeholder: PropTypes.string,
// onSelect: PropTypes.func,
selectedValue: PropTypes.object,
},
data () {
const selectedValue = this.selectedValue
return {
str: selectedValue && selectedValue.format(this.props.format) || '',
invalid: false,
}
},
watch: {
selectedValue () {
this.updateState()
},
format () {
this.updateState()
},
},
updated () {
this.$nextTick(() => {
if (!this.invalid) {
this.$refs.dateInputInstance.setSelectionRange(this.cachedSelectionStart, this.cachedSelectionEnd)
}
})
},
methods: {
updateState () {
console.log('关注下')
this.cachedSelectionStart = this.$refs.dateInputInstance.selectionStart
this.cachedSelectionEnd = this.$refs.dateInputInstance.selectionEnd
// when popup show, click body will call this, bug!
const selectedValue = this.selectedValue
this.setState({
str: selectedValue && selectedValue.format(this.format) || '',
invalid: false,
})
},
onInputChange (event) {
const str = event.target.value
this.setState({
str,
})
let value
const { disabledDate, format } = this
if (str) {
const parsed = moment(str, format, true)
if (!parsed.isValid()) {
this.setState({
invalid: true,
})
return
}
value = this.value.clone()
value
.year(parsed.year())
.month(parsed.month())
.date(parsed.date())
.hour(parsed.hour())
.minute(parsed.minute())
.second(parsed.second())
if (value && (!disabledDate || !disabledDate(value))) {
const originalValue = this.selectedValue
if (originalValue && value) {
if (!originalValue.isSame(value)) {
this.__emit('change', value)
}
} else if (originalValue !== value) {
this.__emit('change', value)
}
} else {
this.setState({
invalid: true,
})
return
}
} else {
this.__emit('change', null)
}
this.setState({
invalid: false,
})
},
onClear () {
this.setState({
str: '',
})
this.__emit('clear', null)
},
getRootDOMNode () {
return this.$el
},
focus () {
if (this.$refs.dateInputInstance) {
this.$refs.dateInputInstance.focus()
}
},
},
render () {
const { invalid, str, locale, prefixCls, placeholder, disabled, showClear } = this
const invalidClass = invalid ? `${prefixCls}-input-invalid` : ''
return (<div class={`${prefixCls}-input-wrap`}>
<div class={`${prefixCls}-date-input-wrap`}>
<input
ref='dateInputInstance'
class={`${prefixCls}-input ${invalidClass}`}
value={str}
disabled={disabled}
placeholder={placeholder}
onChange={this.onInputChange}
/>
</div>
{showClear ? <a
class={`${prefixCls}-clear-btn`}
role='button'
title={locale.clear}
onClick={this.onClear}
/> : null}
</div>)
},
}
export default DateInput
</script>

View File

@ -0,0 +1,243 @@
<script>
import PropTypes from '@/components/_util/vue-types'
import { getOptionProps } from '@/components/_util/props-util'
import cx from 'classnames'
import DateConstants from './DateConstants'
import { getTitleString, getTodayTime } from '../util/'
function isSameDay (one, two) {
return one && two && one.isSame(two, 'day')
}
function beforeCurrentMonthYear (current, today) {
if (current.year() < today.year()) {
return 1
}
return current.year() === today.year() &&
current.month() < today.month()
}
function afterCurrentMonthYear (current, today) {
if (current.year() > today.year()) {
return 1
}
return current.year() === today.year() &&
current.month() > today.month()
}
function getIdFromDate (date) {
return `rc-calendar-${date.year()}-${date.month()}-${date.date()}`
}
const DateTBody = {
props: {
contentRender: PropTypes.func,
dateRender: PropTypes.func,
disabledDate: PropTypes.func,
prefixCls: PropTypes.string,
selectedValue: PropTypes.oneOfType([PropTypes.object, PropTypes.arrayOf(PropTypes.object)]),
value: PropTypes.object,
hoverValue: PropTypes.any.def([]),
showWeekNumber: PropTypes.bool,
},
render () {
const props = getOptionProps(this)
const {
contentRender, prefixCls, selectedValue, value,
showWeekNumber, dateRender, disabledDate,
hoverValue,
} = props
let iIndex
let jIndex
let current
const dateTable = []
const today = getTodayTime(value)
const cellClass = `${prefixCls}-cell`
const weekNumberCellClass = `${prefixCls}-week-number-cell`
const dateClass = `${prefixCls}-date`
const todayClass = `${prefixCls}-today`
const selectedClass = `${prefixCls}-selected-day`
const selectedDateClass = `${prefixCls}-selected-date` // do not move with mouse operation
const selectedStartDateClass = `${prefixCls}-selected-start-date`
const selectedEndDateClass = `${prefixCls}-selected-end-date`
const inRangeClass = `${prefixCls}-in-range-cell`
const lastMonthDayClass = `${prefixCls}-last-month-cell`
const nextMonthDayClass = `${prefixCls}-next-month-btn-day`
const disabledClass = `${prefixCls}-disabled-cell`
const firstDisableClass = `${prefixCls}-disabled-cell-first-of-row`
const lastDisableClass = `${prefixCls}-disabled-cell-last-of-row`
const month1 = value.clone()
month1.date(1)
const day = month1.day()
const lastMonthDiffDay = (day + 7 - value.localeData().firstDayOfWeek()) % 7
// calculate last month
const lastMonth1 = month1.clone()
lastMonth1.add(0 - lastMonthDiffDay, 'days')
let passed = 0
for (iIndex = 0; iIndex < DateConstants.DATE_ROW_COUNT; iIndex++) {
for (jIndex = 0; jIndex < DateConstants.DATE_COL_COUNT; jIndex++) {
current = lastMonth1
if (passed) {
current = current.clone()
current.add(passed, 'days')
}
dateTable.push(current)
passed++
}
}
const tableHtml = []
passed = 0
for (iIndex = 0; iIndex < DateConstants.DATE_ROW_COUNT; iIndex++) {
let isCurrentWeek
let weekNumberCell
let isActiveWeek = false
const dateCells = []
if (showWeekNumber) {
weekNumberCell = (
<td
key={dateTable[passed].week()}
role='gridcell'
class={weekNumberCellClass}
>
{dateTable[passed].week()}
</td>
)
}
for (jIndex = 0; jIndex < DateConstants.DATE_COL_COUNT; jIndex++) {
let next = null
let last = null
current = dateTable[passed]
if (jIndex < DateConstants.DATE_COL_COUNT - 1) {
next = dateTable[passed + 1]
}
if (jIndex > 0) {
last = dateTable[passed - 1]
}
let cls = cellClass
let disabled = false
let selected = false
if (isSameDay(current, today)) {
cls += ` ${todayClass}`
isCurrentWeek = true
}
const isBeforeCurrentMonthYear = beforeCurrentMonthYear(current, value)
const isAfterCurrentMonthYear = afterCurrentMonthYear(current, value)
if (selectedValue && Array.isArray(selectedValue)) {
const rangeValue = hoverValue.length ? hoverValue : selectedValue
if (!isBeforeCurrentMonthYear && !isAfterCurrentMonthYear) {
const startValue = rangeValue[0]
const endValue = rangeValue[1]
if (startValue) {
if (isSameDay(current, startValue)) {
selected = true
isActiveWeek = true
cls += ` ${selectedStartDateClass}`
}
}
if (startValue && endValue) {
if (isSameDay(current, endValue)) {
selected = true
isActiveWeek = true
cls += ` ${selectedEndDateClass}`
} else if (current.isAfter(startValue, 'day') &&
current.isBefore(endValue, 'day')) {
cls += ` ${inRangeClass}`
}
}
}
} else if (isSameDay(current, value)) {
// keyboard change value, highlight works
selected = true
isActiveWeek = true
}
if (isSameDay(current, selectedValue)) {
cls += ` ${selectedDateClass}`
}
if (isBeforeCurrentMonthYear) {
cls += ` ${lastMonthDayClass}`
}
if (isAfterCurrentMonthYear) {
cls += ` ${nextMonthDayClass}`
}
if (disabledDate) {
if (disabledDate(current, value)) {
disabled = true
if (!last || !disabledDate(last, value)) {
cls += ` ${firstDisableClass}`
}
if (!next || !disabledDate(next, value)) {
cls += ` ${lastDisableClass}`
}
}
}
if (selected) {
cls += ` ${selectedClass}`
}
if (disabled) {
cls += ` ${disabledClass}`
}
let dateHtml
if (dateRender) {
dateHtml = dateRender(current, value)
} else {
const content = contentRender ? contentRender(current, value) : current.date()
dateHtml = (
<div
key={getIdFromDate(current)}
class={dateClass}
aria-selected={selected}
aria-disabled={disabled}
>
{content}
</div>)
}
dateCells.push(
<td
key={passed}
onClick={disabled ? undefined : props.onSelect.bind(null, current)}
onMouseenter={disabled
? undefined : props.onDayHover && props.onDayHover.bind(null, current) || undefined}
role='gridcell'
title={getTitleString(current)} class={cls}
>
{dateHtml}
</td>)
passed++
}
tableHtml.push(
<tr
key={iIndex}
role='row'
class={cx({
[`${prefixCls}-current-week`]: isCurrentWeek,
[`${prefixCls}-active-week`]: isActiveWeek,
})}
>
{weekNumberCell}
{dateCells}
</tr>)
}
return (<tbody class={`${prefixCls}-tbody`}>
{tableHtml}
</tbody>)
},
}
export default DateTBody
</script>

View File

@ -0,0 +1,54 @@
<script>
import DateConstants from './DateConstants'
import moment from 'moment'
export default {
functional: true,
render (createElement, context) {
const { data: props } = context
const value = props.value
const localeData = value.localeData()
const prefixCls = props.prefixCls
const veryShortWeekdays = []
const weekDays = []
const firstDayOfWeek = localeData.firstDayOfWeek()
let showWeekNumberEl
const now = moment()
for (let dateColIndex = 0; dateColIndex < DateConstants.DATE_COL_COUNT; dateColIndex++) {
const index = (firstDayOfWeek + dateColIndex) % DateConstants.DATE_COL_COUNT
now.day(index)
veryShortWeekdays[dateColIndex] = localeData.weekdaysMin(now)
weekDays[dateColIndex] = localeData.weekdaysShort(now)
}
if (props.showWeekNumber) {
showWeekNumberEl = (
<th
role='columnheader'
class={`${prefixCls}-column-header ${prefixCls}-week-number-header`}
>
<span class={`${prefixCls}-column-header-inner`}>x</span>
</th>)
}
const weekDaysEls = weekDays.map((day, xindex) => {
return (
<th
key={xindex}
role='columnheader'
title={day}
class={`${prefixCls}-column-header`}
>
<span class={`${prefixCls}-column-header-inner`}>
{veryShortWeekdays[xindex]}
</span>
</th>)
})
return (<thead>
<tr role='row'>
{showWeekNumberEl}
{weekDaysEls}
</tr>
</thead>)
},
}
</script>

View File

@ -0,0 +1,20 @@
<script>
import DateTHead from './DateTHead'
import DateTBody from './DateTBody'
export default {
functional: true,
render (createElement, context) {
const { data, listeners = {}} = context
const prefixCls = data.prefixCls
const props = {
props: data,
on: listeners,
}
return (<table class = {`${prefixCls}-table`} cellSpacing='0' role='grid'>
<DateTHead {...props}/>
<DateTBody {...props}/>
</table>)
},
}
</script>

View File

@ -0,0 +1,131 @@
<script>
import PropTypes from '@/components/_util/vue-types'
import BaseMixin from '@/components/_util/BaseMixin'
const ROW = 4
const COL = 3
function noop () {}
function goYear (direction) {
const next = this.sValue.clone()
next.add(direction, 'years')
this.setState({
sValue: next,
})
}
function chooseDecade (year, event) {
const next = this.sValue.clone()
next.year(year)
next.month(this.sValue.month())
this.__emit('select', next)
event.preventDefault()
}
export default {
mixins: [BaseMixin],
props: {
locale: PropTypes.object,
value: PropTypes.object,
defaultValue: PropTypes.object,
rootPrefixCls: PropTypes.string,
},
data () {
this.prefixCls = `${this.rootPrefixCls}-decade-panel`
this.nextCentury = goYear.bind(this, 100)
this.previousCentury = goYear.bind(this, -100)
this.state = {
sValue: this.value || this.defaultValue,
}
},
render () {
const value = this.sValue
const locale = this.locale
const currentYear = value.year()
const startYear = parseInt(currentYear / 100, 10) * 100
const preYear = startYear - 10
const endYear = startYear + 99
const decades = []
let index = 0
const prefixCls = this.prefixCls
for (let rowIndex = 0; rowIndex < ROW; rowIndex++) {
decades[rowIndex] = []
for (let colIndex = 0; colIndex < COL; colIndex++) {
const startDecade = preYear + index * 10
const endDecade = preYear + index * 10 + 9
decades[rowIndex][colIndex] = {
startDecade,
endDecade,
}
index++
}
}
const decadesEls = decades.map((row, decadeIndex) => {
const tds = row.map(decadeData => {
const dStartDecade = decadeData.startDecade
const dEndDecade = decadeData.endDecade
const isLast = dStartDecade < startYear
const isNext = dEndDecade > endYear
const classNameMap = {
[`${prefixCls}-cell`]: 1,
[`${prefixCls}-selected-cell`]: dStartDecade <= currentYear && currentYear <= dEndDecade,
[`${prefixCls}-last-century-cell`]: isLast,
[`${prefixCls}-next-century-cell`]: isNext,
}
const content = `${dStartDecade}-${dEndDecade}`
let clickHandler = noop
if (isLast) {
clickHandler = this.previousCentury
} else if (isNext) {
clickHandler = this.nextCentury
} else {
clickHandler = chooseDecade.bind(this, dStartDecade)
}
return (<td
key={dStartDecade}
onClick={clickHandler}
role='gridcell'
class={classNameMap}
>
<a
class={`${prefixCls}-decade`}
>
{content}
</a>
</td>)
})
return (<tr key={decadeIndex} role='row'>{tds}</tr>)
})
return (
<div class={this.prefixCls}>
<div class={`${prefixCls}-header`}>
<a
class={`${prefixCls}-prev-century-btn`}
role='button'
onClick={this.previousCentury}
title={locale.previousCentury}
/>
<div class={`${prefixCls}-century`}>
{startYear}-{endYear}
</div>
<a
class={`${prefixCls}-next-century-btn`}
role='button'
onClick={this.nextCentury}
title={locale.nextCentury}
/>
</div>
<div class={`${prefixCls}-body`}>
<table class={`${prefixCls}-table`} cellSpacing='0' role='grid'>
<tbody class={`${prefixCls}-tbody`}>
{decadesEls}
</tbody>
</table>
</div>
</div>)
},
}
</script>

View File

@ -0,0 +1,138 @@
<script>
import PropTypes from '@/components/_util/vue-types'
import BaseMixin from '@/components/_util/BaseMixin'
import { getMonthName } from '../util'
const CalendarHeader = {
mixins: [BaseMixin],
props: {
value: PropTypes.object,
locale: PropTypes.object,
yearSelectOffset: PropTypes.number.def(10),
yearSelectTotal: PropTypes.number.def(20),
// onValueChange: PropTypes.func,
// onTypeChange: PropTypes.func,
Select: PropTypes.func,
prefixCls: PropTypes.string,
type: PropTypes.string,
showTypeSwitch: PropTypes.bool,
headerComponents: PropTypes.array,
},
methods: {
onYearChange (year) {
const newValue = this.value.clone()
newValue.year(parseInt(year, 10))
this.__emit('valueChange', newValue)
},
onMonthChange (month) {
const newValue = this.value.clone()
newValue.month(parseInt(month, 10))
this.__emit('valueChange', newValue)
},
yearSelectElement (year) {
const { yearSelectOffset, yearSelectTotal, prefixCls, Select } = this
const start = year - yearSelectOffset
const end = start + yearSelectTotal
const options = []
for (let index = start; index < end; index++) {
options.push(<Select.Option key={`${index}`}>{index}</Select.Option>)
}
return (
<Select
class={`${prefixCls}-header-year-select`}
onChange={this.onYearChange}
dropdownStyle={{ zIndex: 2000 }}
dropdownMenuStyle={{ maxHeight: '250px', overflow: 'auto', fontSize: '12px' }}
optionLabelProp='children'
value={String(year)}
showSearch={false}
>
{ options }
</Select>
)
},
monthSelectElement (month) {
const { value, Select, prefixCls } = this
const t = value.clone()
const options = []
for (let index = 0; index < 12; index++) {
t.month(index)
options.push(
<Select.Option key={`${index}`}>
{getMonthName(t)}
</Select.Option>
)
}
return (
<Select
class={`${prefixCls}-header-month-select`}
dropdownStyle={{ zIndex: 2000 }}
dropdownMenuStyle={{ maxHeight: '250px', overflow: 'auto', overflowX: 'hidden', fontSize: '12px' }}
optionLabelProp='children'
value={String(month)}
showSearch={false}
onChange={this.onMonthChange}
>
{ options }
</Select>
)
},
changeTypeToDate () {
this.__emit('typeChange', 'date')
},
changeTypeToMonth () {
this.__emit('typeChange', 'month')
},
},
render () {
const { value, locale, prefixCls, type, showTypeSwitch, headerComponents } = this
const year = value.year()
const month = value.month()
const yearSelect = this.yearSelectElement(year)
const monthSelect = type === 'month' ? null : this.monthSelectElement(month)
const switchCls = `${prefixCls}-header-switcher`
const typeSwitcher = showTypeSwitch ? (
<span class={switchCls}>
{ type === 'date'
? <span class={`${switchCls}-focus`}>{locale.month}</span>
: <span
onClick={this.changeTypeToDate}
class={`${switchCls}-normal`}
>
{locale.month}
</span>
}
{ type === 'month'
? <span class={`${switchCls}-focus`}>{locale.year}</span>
: <span
onClick={this.changeTypeToMonth}
class={`${switchCls}-normal`}
>
{locale.year}
</span>
}
</span>
) : null
return (
<div class={`${prefixCls}-header`}>
{ typeSwitcher }
{ monthSelect }
{ yearSelect }
{ headerComponents }
</div>
)
},
}
export default CalendarHeader
</script>

View File

@ -0,0 +1,3 @@
import Calendar from './Calendar'
export default Calendar

View File

@ -0,0 +1,27 @@
export default {
today: 'اليوم',
now: 'الأن',
backToToday: 'العودة إلى اليوم',
ok: 'تأكيد',
clear: 'مسح',
month: 'الشهر',
year: 'السنة',
timeSelect: 'اختيار الوقت',
dateSelect: 'اختيار التاريخ',
monthSelect: 'اختيار الشهر',
yearSelect: 'اختيار السنة',
decadeSelect: 'اختيار العقد',
yearFormat: 'YYYY',
dateFormat: 'M/D/YYYY',
dayFormat: 'D',
dateTimeFormat: 'M/D/YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'الشهر السابق (PageUp)',
nextMonth: 'الشهر التالى(PageDown)',
previousYear: 'العام السابق (Control + left)',
nextYear: 'العام التالى (Control + right)',
previousDecade: 'العقد السابق',
nextDecade: 'العقد التالى',
previousCentury: 'القرن السابق',
nextCentury: 'القرن التالى',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Днес',
now: 'Сега',
backToToday: 'Към днес',
ok: 'Добре',
clear: 'Изчистване',
month: 'Месец',
year: 'Година',
timeSelect: 'Избор на час',
dateSelect: 'Избор на дата',
monthSelect: 'Избор на месец',
yearSelect: 'Избор на година',
decadeSelect: 'Десетилетие',
yearFormat: 'YYYY',
dateFormat: 'D M YYYY',
dayFormat: 'D',
dateTimeFormat: 'D M YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Предишен месец (PageUp)',
nextMonth: 'Следващ месец (PageDown)',
previousYear: 'Последна година (Control + left)',
nextYear: 'Следваща година (Control + right)',
previousDecade: 'Предишно десетилетие',
nextDecade: 'Следващо десетилетие',
previousCentury: 'Последен век',
nextCentury: 'Следващ век',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Avui',
now: 'Ara',
backToToday: 'Tornar a avui',
ok: 'Acceptar',
clear: 'Netejar',
month: 'Mes',
year: 'Any',
timeSelect: 'Seleccionar hora',
dateSelect: 'Seleccionar data',
monthSelect: 'Escollir un mes',
yearSelect: 'Escollir un any',
decadeSelect: 'Escollir una dècada',
yearFormat: 'YYYY',
dateFormat: 'D/M/YYYY',
dayFormat: 'D',
dateTimeFormat: 'D/M/YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Mes anterior (PageUp)',
nextMonth: 'Mes següent (PageDown)',
previousYear: 'Any anterior (Control + left)',
nextYear: 'Mes següent (Control + right)',
previousDecade: 'Dècada anterior',
nextDecade: 'Dècada següent',
previousCentury: 'Segle anterior',
nextCentury: 'Segle següent',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Dnes',
now: 'Nyní',
backToToday: 'Zpět na dnešek',
ok: 'Ok',
clear: 'Vymazat',
month: 'Měsíc',
year: 'Rok',
timeSelect: 'Vybrat čas',
dateSelect: 'Vybrat datum',
monthSelect: 'Vyberte měsíc',
yearSelect: 'Vyberte rok',
decadeSelect: 'Vyberte dekádu',
yearFormat: 'YYYY',
dateFormat: 'D.M.YYYY',
dayFormat: 'D',
dateTimeFormat: 'D.M.YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Předchozí měsíc (PageUp)',
nextMonth: 'Následující (PageDown)',
previousYear: 'Předchozí rok (Control + left)',
nextYear: 'Následující rok (Control + right)',
previousDecade: 'Předchozí dekáda',
nextDecade: 'Následující dekáda',
previousCentury: 'Předchozí století',
nextCentury: 'Následující století',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'I dag',
now: 'Nu',
backToToday: 'Gå til i dag',
ok: 'Ok',
clear: 'Annuller',
month: 'Måned',
year: 'År',
timeSelect: 'Vælg tidspunkt',
dateSelect: 'Vælg dato',
monthSelect: 'Vælg måned',
yearSelect: 'Vælg år',
decadeSelect: 'Vælg årti',
yearFormat: 'YYYY',
dateFormat: 'D/M/YYYY',
dayFormat: 'D',
dateTimeFormat: 'D/M/YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Forrige måned(PageUp)',
nextMonth: 'Næste måned (PageDown)',
previousYear: 'Forrige år (Control + left)',
nextYear: 'Næste r (Control + right)',
previousDecade: 'Forrige årti',
nextDecade: 'Næste årti',
previousCentury: 'Forrige århundrede',
nextCentury: 'Næste århundrede',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Heute',
now: 'Jetzt',
backToToday: 'Zurück zu Heute',
ok: 'OK',
clear: 'Zurücksetzen',
month: 'Monat',
year: 'Jahr',
timeSelect: 'Zeit wählen',
dateSelect: 'Datum wählen',
monthSelect: 'Wähle einen Monat',
yearSelect: 'Wähle ein Jahr',
decadeSelect: 'Wähle ein Jahrzehnt',
yearFormat: 'YYYY',
dateFormat: 'D.M.YYYY',
dayFormat: 'D',
dateTimeFormat: 'D.M.YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Vorheriger Monat (PageUp)',
nextMonth: 'Nächster Monat (PageDown)',
previousYear: 'Vorheriges Jahr (Ctrl + left)',
nextYear: 'Nächstes Jahr (Ctrl + right)',
previousDecade: 'Vorheriges Jahrzehnt',
nextDecade: 'Nächstes Jahrzehnt',
previousCentury: 'Vorheriges Jahrhundert',
nextCentury: 'Nächstes Jahrhundert',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Σήμερα',
now: 'Τώρα',
backToToday: 'Πίσω στη σημερινή μέρα',
ok: 'Ok',
clear: 'Καθαρισμός',
month: 'Μήνας',
year: 'Έτος',
timeSelect: 'Επιλογή ώρας',
dateSelect: 'Επιλογή ημερομηνίας',
monthSelect: 'Επιλογή μήνα',
yearSelect: 'Επιλογή έτους',
decadeSelect: 'Επιλογή δεκαετίας',
yearFormat: 'YYYY',
dateFormat: 'D/M/YYYY',
dayFormat: 'D',
dateTimeFormat: 'D/M/YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Προηγούμενος μήνας (PageUp)',
nextMonth: 'Επόμενος μήνας (PageDown)',
previousYear: 'Προηγούμενο έτος (Control + αριστερά)',
nextYear: 'Επόμενο έτος (Control + δεξιά)',
previousDecade: 'Προηγούμενη δεκαετία',
nextDecade: 'Επόμενη δεκαετία',
previousCentury: 'Προηγούμενος αιώνας',
nextCentury: 'Επόμενος αιώνας',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Today',
now: 'Now',
backToToday: 'Back to today',
ok: 'Ok',
clear: 'Clear',
month: 'Month',
year: 'Year',
timeSelect: 'Select time',
dateSelect: 'Select date',
monthSelect: 'Choose a month',
yearSelect: 'Choose a year',
decadeSelect: 'Choose a decade',
yearFormat: 'YYYY',
dateFormat: 'D/M/YYYY',
dayFormat: 'D',
dateTimeFormat: 'D/M/YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Previous month (PageUp)',
nextMonth: 'Next month (PageDown)',
previousYear: 'Last year (Control + left)',
nextYear: 'Next year (Control + right)',
previousDecade: 'Last decade',
nextDecade: 'Next decade',
previousCentury: 'Last century',
nextCentury: 'Next century',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Today',
now: 'Now',
backToToday: 'Back to today',
ok: 'Ok',
clear: 'Clear',
month: 'Month',
year: 'Year',
timeSelect: 'Select time',
dateSelect: 'Select date',
monthSelect: 'Choose a month',
yearSelect: 'Choose a year',
decadeSelect: 'Choose a decade',
yearFormat: 'YYYY',
dateFormat: 'M/D/YYYY',
dayFormat: 'D',
dateTimeFormat: 'M/D/YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Previous month (PageUp)',
nextMonth: 'Next month (PageDown)',
previousYear: 'Last year (Control + left)',
nextYear: 'Next year (Control + right)',
previousDecade: 'Last decade',
nextDecade: 'Next decade',
previousCentury: 'Last century',
nextCentury: 'Next century',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Hoy',
now: 'Ahora',
backToToday: 'Volver a hoy',
ok: 'Aceptar',
clear: 'Limpiar',
month: 'Mes',
year: 'Año',
timeSelect: 'Seleccionar hora',
dateSelect: 'Seleccionar fecha',
monthSelect: 'Elegir un mes',
yearSelect: 'Elegir un año',
decadeSelect: 'Elegir una década',
yearFormat: 'YYYY',
dateFormat: 'D/M/YYYY',
dayFormat: 'D',
dateTimeFormat: 'D/M/YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Mes anterior (PageUp)',
nextMonth: 'Mes siguiente (PageDown)',
previousYear: 'Año anterior (Control + left)',
nextYear: 'Año siguiente (Control + right)',
previousDecade: 'Década anterior',
nextDecade: 'Década siguiente',
previousCentury: 'Siglo anterior',
nextCentury: 'Siglo siguiente',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Täna',
now: 'Praegu',
backToToday: 'Tagasi tänase juurde',
ok: 'Ok',
clear: 'Tühista',
month: 'Kuu',
year: 'Aasta',
timeSelect: 'Vali aeg',
dateSelect: 'Vali kuupäev',
monthSelect: 'Vali kuu',
yearSelect: 'Vali aasta',
decadeSelect: 'Vali dekaad',
yearFormat: 'YYYY',
dateFormat: 'D.M.YYYY',
dayFormat: 'D',
dateTimeFormat: 'D.M.YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Eelmine kuu (PageUp)',
nextMonth: 'Järgmine kuu (PageDown)',
previousYear: 'Eelmine aasta (Control + left)',
nextYear: 'Järgmine aasta (Control + right)',
previousDecade: 'Eelmine dekaad',
nextDecade: 'Järgmine dekaad',
previousCentury: 'Eelmine sajand',
nextCentury: 'Järgmine sajand',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'امروز',
now: 'اکنون',
backToToday: 'بازگشت به روز',
ok: 'باشه',
clear: 'پاک کردن',
month: 'ماه',
year: 'سال',
timeSelect: 'انتخاب زمان',
dateSelect: 'انتخاب تاریخ',
monthSelect: 'یک ماه را انتخاب کنید',
yearSelect: 'یک سال را انتخاب کنید',
decadeSelect: 'یک دهه را انتخاب کنید',
yearFormat: 'YYYY',
dateFormat: 'M/D/YYYY',
dayFormat: 'D',
dateTimeFormat: 'M/D/YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'ماه قبل (PageUp)',
nextMonth: 'ماه بعد (PageDown)',
previousYear: 'سال قبل (Control + left)',
nextYear: 'سال بعد (Control + right)',
previousDecade: 'دهه قبل',
nextDecade: 'دهه بعد',
previousCentury: 'قرن قبل',
nextCentury: 'قرن بعد',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Tänään',
now: 'Nyt',
backToToday: 'Tämä päivä',
ok: 'Ok',
clear: 'Tyhjennä',
month: 'Kuukausi',
year: 'Vuosi',
timeSelect: 'Valise aika',
dateSelect: 'Valitse päivä',
monthSelect: 'Valitse kuukausi',
yearSelect: 'Valitse vuosi',
decadeSelect: 'Valitse vuosikymmen',
yearFormat: 'YYYY',
dateFormat: 'D.M.YYYY',
dayFormat: 'D',
dateTimeFormat: 'D.M.YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Edellinen kuukausi (PageUp)',
nextMonth: 'Seuraava kuukausi (PageDown)',
previousYear: 'Edellinen vuosi (Control + left)',
nextYear: 'Seuraava vuosi (Control + right)',
previousDecade: 'Edellinen vuosikymmen',
nextDecade: 'Seuraava vuosikymmen',
previousCentury: 'Edellinen vuosisata',
nextCentury: 'Seuraava vuosisata',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Aujourd\'hui',
now: 'Maintenant',
backToToday: 'Aujourd\'hui',
ok: 'Ok',
clear: 'Rétablir',
month: 'Mois',
year: 'Année',
timeSelect: 'Sélectionner l\'heure',
dateSelect: 'Sélectionner l\'heure',
monthSelect: 'Choisissez un mois',
yearSelect: 'Choisissez une année',
decadeSelect: 'Choisissez une décennie',
yearFormat: 'YYYY',
dateFormat: 'D/M/YYYY',
dayFormat: 'D',
dateTimeFormat: 'D/M/YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Mois précédent (PageUp)',
nextMonth: 'Mois suivant (PageDown)',
previousYear: 'Année précédente (Ctrl + gauche)',
nextYear: 'Année prochaine (Ctrl + droite)',
previousDecade: 'Décennie précédente',
nextDecade: 'Décennie suivante',
previousCentury: 'Siècle précédent',
nextCentury: 'Siècle suivant',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Aujourd\'hui',
now: 'Maintenant',
backToToday: 'Aujourd\'hui',
ok: 'Ok',
clear: 'Rétablir',
month: 'Mois',
year: 'Année',
timeSelect: 'Sélectionner l\'heure',
dateSelect: 'Sélectionner l\'heure',
monthSelect: 'Choisissez un mois',
yearSelect: 'Choisissez une année',
decadeSelect: 'Choisissez une décennie',
yearFormat: 'YYYY',
dateFormat: 'DD/MM/YYYY',
dayFormat: 'DD',
dateTimeFormat: 'DD/MM/YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Mois précédent (PageUp)',
nextMonth: 'Mois suivant (PageDown)',
previousYear: 'Année précédente (Ctrl + gauche)',
nextYear: 'Année prochaine (Ctrl + droite)',
previousDecade: 'Décennie précédente',
nextDecade: 'Décennie suivante',
previousCentury: 'Siècle précédent',
nextCentury: 'Siècle suivant',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Ma', // 'Today',
now: 'Most', // 'Now',
backToToday: 'Vissza a mai napra', // 'Back to today',
ok: 'Ok',
clear: 'Törlés', // 'Clear',
month: 'Hónap', // 'Month',
year: 'Év', // 'Year',
timeSelect: 'Időpont kiválasztása', // 'Select time',
dateSelect: 'Dátum kiválasztása', // 'Select date',
monthSelect: 'Hónap kiválasztása', // 'Choose a month',
yearSelect: 'Év kiválasztása', // 'Choose a year',
decadeSelect: 'Évtized kiválasztása', // 'Choose a decade',
yearFormat: 'YYYY',
dateFormat: 'YYYY/MM/DD', // 'M/D/YYYY',
dayFormat: 'DD', // 'D',
dateTimeFormat: 'YYYY/MM/DD HH:mm:ss', // 'M/D/YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Előző hónap (PageUp)', // 'Previous month (PageUp)',
nextMonth: 'Következő hónap (PageDown)', // 'Next month (PageDown)',
previousYear: 'Múlt év (Control + left)', // 'Last year (Control + left)',
nextYear: 'Jövő év (Control + right)', // 'Next year (Control + right)',
previousDecade: 'Előző évtized', // 'Last decade',
nextDecade: 'Következő évtized', // 'Next decade',
previousCentury: 'Múlt évszázad', // 'Last century',
nextCentury: 'Jövő évszázad', // 'Next century',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Í dag',
now: 'Núna',
backToToday: 'Til baka til dagsins í dag',
ok: 'Í lagi',
clear: 'Hreinsa',
month: 'Mánuður',
year: 'Ár',
timeSelect: 'Velja tíma',
dateSelect: 'Velja dag',
monthSelect: 'Velja mánuð',
yearSelect: 'Velja ár',
decadeSelect: 'Velja áratug',
yearFormat: 'YYYY',
dateFormat: 'D/M/YYYY',
dayFormat: 'D',
dateTimeFormat: 'D/M/YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Fyrri mánuður (PageUp)',
nextMonth: 'Næsti mánuður (PageDown)',
previousYear: 'Fyrra ár (Control + left)',
nextYear: 'Næsta ár (Control + right)',
previousDecade: 'Fyrri áratugur',
nextDecade: 'Næsti áratugur',
previousCentury: 'Fyrri öld',
nextCentury: 'Næsta öld',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Oggi',
now: 'adesso',
backToToday: 'Torna ad oggi',
ok: 'Ok',
clear: 'Chiaro',
month: 'Mese',
year: 'Anno',
timeSelect: 'Seleziona il tempo',
dateSelect: 'Select date',
monthSelect: 'Seleziona la data',
yearSelect: 'Scegli un anno',
decadeSelect: 'Scegli un decennio',
yearFormat: 'YYYY',
dateFormat: 'D/M/YYYY',
dayFormat: 'D',
dateTimeFormat: 'D/M/YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Il mese scorso (PageUp)',
nextMonth: 'Il prossimo mese (PageDown)',
previousYear: 'L\'anno scorso (Control + sinistra)',
nextYear: 'L\'anno prossimo (Control + destra)',
previousDecade: 'Ultimo decennio',
nextDecade: 'Prossimo decennio',
previousCentury: 'Secolo precedente',
nextCentury: 'Prossimo secolo',
};

View File

@ -0,0 +1,26 @@
export default {
today: '今日',
now: '現在時刻',
backToToday: '今日に戻る',
ok: '決定',
timeSelect: '時間を選択',
dateSelect: '日時を選択',
clear: 'クリア',
month: '月',
year: '年',
previousMonth: '前月 (ページアップキー)',
nextMonth: '翌月 (ページダウンキー)',
monthSelect: '月を選択',
yearSelect: '年を選択',
decadeSelect: '年代を選択',
yearFormat: 'YYYY年',
dayFormat: 'D日',
dateFormat: 'YYYY年M月D日',
dateTimeFormat: 'YYYY年M月D日 HH時mm分ss秒',
previousYear: '前年 (Controlを押しながら左キー)',
nextYear: '翌年 (Controlを押しながら右キー)',
previousDecade: '前の年代',
nextDecade: '次の年代',
previousCentury: '前の世紀',
nextCentury: '次の世紀',
};

View File

@ -0,0 +1,27 @@
export default {
today: '오늘',
now: '현재 시각',
backToToday: '오늘로 돌아가기',
ok: '확인',
clear: '지우기',
month: '월',
year: '년',
timeSelect: '시간 선택',
dateSelect: '날짜 선택',
monthSelect: '달 선택',
yearSelect: '연 선택',
decadeSelect: '연대 선택',
yearFormat: 'YYYY년',
dateFormat: 'YYYY-MM-DD',
dayFormat: 'Do',
dateTimeFormat: 'YYYY-MM-DD HH:mm:ss',
monthBeforeYear: false,
previousMonth: '이전 달 (PageUp)',
nextMonth: '다음 달 (PageDown)',
previousYear: '이전 해 (Control + left)',
nextYear: '다음 해 (Control + right)',
previousDecade: '이전 연대',
nextDecade: '다음 연대',
previousCentury: '이전 세기',
nextCentury: '다음 세기',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Îro',
now: 'Niha',
backToToday: 'Vegere îro',
ok: 'Temam',
clear: 'Paqij bike',
month: 'Meh',
year: 'Sal',
timeSelect: 'Demê hilbijêre',
dateSelect: 'Dîrok hilbijêre',
monthSelect: 'Meh hilbijêre',
yearSelect: 'Sal hilbijêre',
decadeSelect: 'Dehsal hilbijêre',
yearFormat: 'YYYY',
dateFormat: 'D/M/YYYY',
dayFormat: 'D',
dateTimeFormat: 'D/M/YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Meha peş (PageUp))',
nextMonth: 'Meha paş (PageDown)',
previousYear: 'Sala peş (Control + şep)',
nextYear: 'Sala paş (Control + rast)',
previousDecade: 'Dehsalen peş',
nextDecade: 'Dehsalen paş',
previousCentury: 'Sedsalen peş',
nextCentury: 'Sedsalen paş',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'I dag',
now: 'Nå',
backToToday: 'Gå til i dag',
ok: 'Ok',
clear: 'Annuller',
month: 'Måned',
year: 'År',
timeSelect: 'Velg tidspunkt',
dateSelect: 'Velg dato',
monthSelect: 'Velg måned',
yearSelect: 'Velg år',
decadeSelect: 'Velg årti',
yearFormat: 'YYYY',
dateFormat: 'DD.MM.YYYY',
dayFormat: 'DD',
dateTimeFormat: 'DD.MM.YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Forrige måned(PageUp)',
nextMonth: 'Neste måned (PageDown)',
previousYear: 'Forrige år (Control + left)',
nextYear: 'Neste år (Control + right)',
previousDecade: 'Forrige tiår',
nextDecade: 'Neste tiår',
previousCentury: 'Forrige århundre',
nextCentury: 'Neste århundre',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Vandaag',
now: 'Nu',
backToToday: 'Terug naar vandaag',
ok: 'Ok',
clear: 'Reset',
month: 'Maand',
year: 'Jaar',
timeSelect: 'Selecteer tijd',
dateSelect: 'Selecteer datum',
monthSelect: 'Kies een maand',
yearSelect: 'Kies een jaar',
decadeSelect: 'Kies een decennium',
yearFormat: 'YYYY',
dateFormat: 'D-M-YYYY',
dayFormat: 'D',
dateTimeFormat: 'D-M-YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Vorige maand (PageUp)',
nextMonth: 'Volgende maand (PageDown)',
previousYear: 'Vorig jaar (Control + left)',
nextYear: 'Volgend jaar (Control + right)',
previousDecade: 'Vorig decennium',
nextDecade: 'Volgend decennium',
previousCentury: 'Vorige eeuw',
nextCentury: 'Volgende eeuw',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Vandaag',
now: 'Nu',
backToToday: 'Terug naar vandaag',
ok: 'Ok',
clear: 'Reset',
month: 'Maand',
year: 'Jaar',
timeSelect: 'Selecteer tijd',
dateSelect: 'Selecteer datum',
monthSelect: 'Kies een maand',
yearSelect: 'Kies een jaar',
decadeSelect: 'Kies een decennium',
yearFormat: 'YYYY',
dateFormat: 'D-M-YYYY',
dayFormat: 'D',
dateTimeFormat: 'D-M-YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Vorige maand (PageUp)',
nextMonth: 'Volgende maand (PageDown)',
previousYear: 'Vorig jaar (Control + left)',
nextYear: 'Volgend jaar (Control + right)',
previousDecade: 'Vorig decennium',
nextDecade: 'Volgend decennium',
previousCentury: 'Vorige eeuw',
nextCentury: 'Volgende eeuw',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Dzisiaj',
now: 'Teraz',
backToToday: 'Ustaw dzisiaj',
ok: 'Ok',
clear: 'Wyczyść',
month: 'Miesiąc',
year: 'Rok',
timeSelect: 'Ustaw czas',
dateSelect: 'Ustaw datę',
monthSelect: 'Wybierz miesiąc',
yearSelect: 'Wybierz rok',
decadeSelect: 'Wybierz dekadę',
yearFormat: 'YYYY',
dateFormat: 'D/M/YYYY',
dayFormat: 'D',
dateTimeFormat: 'D/M/YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Poprzedni miesiąc (PageUp)',
nextMonth: 'Następny miesiąc (PageDown)',
previousYear: 'Ostatni rok (Ctrl + left)',
nextYear: 'Następny rok (Ctrl + right)',
previousDecade: 'Ostatnia dekada',
nextDecade: 'Następna dekada',
previousCentury: 'Ostatni wiek',
nextCentury: 'Następny wiek',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Hoje',
now: 'Agora',
backToToday: 'Voltar para hoje',
ok: 'Ok',
clear: 'Limpar',
month: 'Mês',
year: 'Ano',
timeSelect: 'Selecionar tempo',
dateSelect: 'Selecionar data',
monthSelect: 'Escolher mês',
yearSelect: 'Escolher ano',
decadeSelect: 'Escolher década',
yearFormat: 'YYYY',
dateFormat: 'D/M/YYYY',
dayFormat: 'D',
dateTimeFormat: 'D/M/YYYY HH:mm:ss',
monthBeforeYear: false,
previousMonth: 'Mês anterior (PageUp)',
nextMonth: 'Próximo mês (PageDown)',
previousYear: 'Ano anterior (Control + esquerda)',
nextYear: 'Próximo ano (Control + direita)',
previousDecade: 'Década anterior',
nextDecade: 'Próxima década',
previousCentury: 'Século anterior',
nextCentury: 'Próximo século',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Hoje',
now: 'Agora',
backToToday: 'Hoje',
ok: 'Ok',
clear: 'Limpar',
month: 'Mês',
year: 'Ano',
timeSelect: 'Selecionar hora',
dateSelect: 'Selecionar data',
monthSelect: 'Selecionar mês',
yearSelect: 'Selecionar ano',
decadeSelect: 'Selecionar década',
yearFormat: 'YYYY',
dateFormat: 'D/M/YYYY',
dayFormat: 'D',
dateTimeFormat: 'D/M/YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Mês anterior (PageUp)',
nextMonth: 'Mês seguinte (PageDown)',
previousYear: 'Ano anterior (Control + left)',
nextYear: 'Ano seguinte (Control + right)',
previousDecade: 'Década anterior',
nextDecade: 'Década seguinte',
previousCentury: 'Século anterior',
nextCentury: 'Século seguinte',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Сегодня',
now: 'Сейчас',
backToToday: 'Текущая дата',
ok: 'Ok',
clear: 'Очистить',
month: 'Месяц',
year: 'Год',
timeSelect: 'Выбрать время',
dateSelect: 'Выбрать дату',
monthSelect: 'Выбрать месяц',
yearSelect: 'Выбрать год',
decadeSelect: 'Выбрать десятилетие',
yearFormat: 'YYYY',
dateFormat: 'D-M-YYYY',
dayFormat: 'D',
dateTimeFormat: 'D-M-YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Предыдущий месяц (PageUp)',
nextMonth: 'Следующий месяц (PageDown)',
previousYear: 'Предыдущий год (Control + left)',
nextYear: 'Следующий год (Control + right)',
previousDecade: 'Предыдущее десятилетие',
nextDecade: 'Следущее десятилетие',
previousCentury: 'Предыдущий век',
nextCentury: 'Следующий век',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Dnes',
now: 'Teraz',
backToToday: 'Späť na dnes',
ok: 'Ok',
clear: 'Vymazať',
month: 'Mesiac',
year: 'Rok',
timeSelect: 'Vybrať čas',
dateSelect: 'Vybrať dátum',
monthSelect: 'Vybrať mesiac',
yearSelect: 'Vybrať rok',
decadeSelect: 'Vybrať dekádu',
yearFormat: 'YYYY',
dateFormat: 'D.M.YYYY',
dayFormat: 'D',
dateTimeFormat: 'D.M.YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Predchádzajúci mesiac (PageUp)',
nextMonth: 'Nasledujúci mesiac (PageDown)',
previousYear: 'Predchádzajúci rok (Control + left)',
nextYear: 'Nasledujúci rok (Control + right)',
previousDecade: 'Predchádzajúca dekáda',
nextDecade: 'Nasledujúca dekáda',
previousCentury: 'Predchádzajúce storočie',
nextCentury: 'Nasledujúce storočie',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Danas',
now: 'Sada',
backToToday: 'Vrati se na danas',
ok: 'U redu',
clear: 'Obriši',
month: 'Mesec',
year: 'Godina',
timeSelect: 'Izaberi vreme',
dateSelect: 'Izaberi datum',
monthSelect: 'Izaberi mesec',
yearSelect: 'Izaberi godinu',
decadeSelect: 'Izaberi deceniju',
yearFormat: 'YYYY',
dateFormat: 'DD.MM.YYYY',
dayFormat: 'D',
dateTimeFormat: 'DD.MM.YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Prethodni mesec (PageUp)',
nextMonth: 'Sledeći mesec (PageDown)',
previousYear: 'Prethodna godina (Control + left)',
nextYear: 'Sledeća godina (Control + right)',
previousDecade: 'Prethodna decenija',
nextDecade: 'Sledeća decenija',
previousCentury: 'Prethodni vek',
nextCentury: 'Sledeći vek',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'I dag',
now: 'Nu',
backToToday: 'Till idag',
ok: 'Ok',
clear: 'Avbryt',
month: 'Månad',
year: 'År',
timeSelect: 'Välj tidpunkt',
dateSelect: 'Välj datum',
monthSelect: 'Välj månad',
yearSelect: 'Välj år',
decadeSelect: 'Välj årtionde',
yearFormat: 'YYYY',
dateFormat: 'YYYY-MM-DD',
dayFormat: 'D',
dateTimeFormat: 'YYYY-MM-DD H:mm:ss',
monthBeforeYear: true,
previousMonth: 'Förra månaden (PageUp)',
nextMonth: 'Nästa månad (PageDown)',
previousYear: 'Föreg år (Control + left)',
nextYear: 'Nästa år (Control + right)',
previousDecade: 'Föreg årtionde',
nextDecade: 'Nästa årtionde',
previousCentury: 'Föreg århundrade',
nextCentury: 'Nästa århundrade',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'วันนี้',
now: 'ตอนนี้',
backToToday: 'กลับไปยังวันนี้',
ok: 'ตกลง',
clear: 'ลบล้าง',
month: 'เดือน',
year: 'ปี',
timeSelect: 'เลือกเวลา',
dateSelect: 'เลือกวัน',
monthSelect: 'เลือกเดือน',
yearSelect: 'เลือกปี',
decadeSelect: 'เลือกทศวรรษ',
yearFormat: 'YYYY',
dateFormat: 'D/M/YYYY',
dayFormat: 'D',
dateTimeFormat: 'D/M/YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'เดือนก่อนหน้า (PageUp)',
nextMonth: 'เดือนถัดไป (PageDown)',
previousYear: 'ปีก่อนหน้า (Control + left)',
nextYear: 'ปีถัดไป (Control + right)',
previousDecade: 'ทศวรรษก่อนหน้า',
nextDecade: 'ทศวรรษถัดไป',
previousCentury: 'ศตวรรษก่อนหน้า',
nextCentury: 'ศตวรรษถัดไป',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Bugün',
now: 'Şimdi',
backToToday: 'Bugüne Geri Dön',
ok: 'tamam',
clear: 'Temizle',
month: 'Ay',
year: 'Yıl',
timeSelect: 'Zaman Seç',
dateSelect: 'Tarih Seç',
monthSelect: 'Ay Seç',
yearSelect: 'Yıl Seç',
decadeSelect: 'On Yıl Seç',
yearFormat: 'YYYY',
dateFormat: 'M/D/YYYY',
dayFormat: 'D',
dateTimeFormat: 'M/D/YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Önceki Ay (PageUp)',
nextMonth: 'Sonraki Ay (PageDown)',
previousYear: 'Önceki Yıl (Control + Sol)',
nextYear: 'Sonraki Yıl (Control + Sağ)',
previousDecade: 'Önceki On Yıl',
nextDecade: 'Sonraki On Yıl',
previousCentury: 'Önceki Yüzyıl',
nextCentury: 'Sonraki Yüzyıl',
};

View File

@ -0,0 +1,26 @@
export default {
today: 'بۈگۈن',
now: 'ھازىر',
backToToday: 'بۈگۈنگە قايتىش',
ok: 'مۇقىملاشتۇرۇش',
timeSelect: 'ۋاقىت تاللاش',
dateSelect: 'كۈن تاللاش',
clear: 'تازىلاش',
month: 'ئاي',
year: 'يىل',
previousMonth: 'ئالدىنقى ئاي(ئالدىنقى بەت )',
nextMonth: 'كېلەركى ئاي (كېلەركى بەت)',
monthSelect: 'ئاي تاللاش',
yearSelect: 'يىل تاللاش',
decadeSelect: 'يىللارنى تاللاش',
yearFormat: 'YYYY-يىلى',
dayFormat: 'D-كۈنى',
dateFormat: 'YYYY-يىلىM-ئاينىڭD-كۈنى',
dateTimeFormat: 'YYYY-يىلىM—ئاينىڭD-كۈنى، HH:mm:ss',
previousYear: 'ئالدىنقى يىلى (Controlبىلەن يۆنىلىش كونۇپكىسى)',
nextYear: 'كېلەركى يىلى (Controlبىلەن يۆنىلىش كونۇپكىسى)',
previousDecade: 'ئالدىنقى يىللار',
nextDecade: 'كېيىنكى يىللار',
previousCentury: 'ئالدىنقى ئەسىر',
nextCentury: 'كېيىنكى ئەسىر',
};

View File

@ -0,0 +1,27 @@
export default {
today: 'Сьогодні',
now: 'Зараз',
backToToday: 'Поточна дата',
ok: 'Ok',
clear: 'Очистити',
month: 'Місяць',
year: 'Рік',
timeSelect: 'Обрати час',
dateSelect: 'Обрати дату',
monthSelect: 'Обрати місяць',
yearSelect: 'Обрати рік',
decadeSelect: 'Обрати десятиріччя',
yearFormat: 'YYYY',
dateFormat: 'D-M-YYYY',
dayFormat: 'D',
dateTimeFormat: 'D-M-YYYY HH:mm:ss',
monthBeforeYear: true,
previousMonth: 'Попередній місяць (PageUp)',
nextMonth: 'Наступний місяць (PageDown)',
previousYear: 'Попередній рік (Control + left)',
nextYear: 'Наступний рік (Control + right)',
previousDecade: 'Попереднє десятиріччя',
nextDecade: 'Наступне десятиріччя',
previousCentury: 'Попереднє століття',
nextCentury: 'Наступне століття',
};

View File

@ -0,0 +1,26 @@
export default {
today: '今天',
now: '此刻',
backToToday: '返回今天',
ok: '确定',
timeSelect: '选择时间',
dateSelect: '选择日期',
clear: '清除',
month: '月',
year: '年',
previousMonth: '上个月 (翻页上键)',
nextMonth: '下个月 (翻页下键)',
monthSelect: '选择月份',
yearSelect: '选择年份',
decadeSelect: '选择年代',
yearFormat: 'YYYY年',
dayFormat: 'D日',
dateFormat: 'YYYY年M月D日',
dateTimeFormat: 'YYYY年M月D日 HH时mm分ss秒',
previousYear: '上一年 (Control键加左方向键)',
nextYear: '下一年 (Control键加右方向键)',
previousDecade: '上一年代',
nextDecade: '下一年代',
previousCentury: '上一世纪',
nextCentury: '下一世纪',
};

View File

@ -0,0 +1,26 @@
export default {
today: '今天',
now: '此刻',
backToToday: '返回今天',
ok: '確定',
timeSelect: '選擇時間',
dateSelect: '選擇日期',
clear: '清除',
month: '月',
year: '年',
previousMonth: '上個月 (翻頁上鍵)',
nextMonth: '下個月 (翻頁下鍵)',
monthSelect: '選擇月份',
yearSelect: '選擇年份',
decadeSelect: '選擇年代',
yearFormat: 'YYYY年',
dayFormat: 'D日',
dateFormat: 'YYYY年M月D日',
dateTimeFormat: 'YYYY年M月D日 HH時mm分ss秒',
previousYear: '上一年 (Control鍵加左方向鍵)',
nextYear: '下一年 (Control鍵加右方向鍵)',
previousDecade: '上一年代',
nextDecade: '下一年代',
previousCentury: '上一世紀',
nextCentury: '下一世紀',
};

View File

@ -0,0 +1,117 @@
import PropTypes from '@/components/_util/vue-types'
import BaseMixin from '@/components/_util/BaseMixin'
import { hasProp } from '@/components/_util/props-util'
import moment from 'moment'
import { isAllowedDate, getTodayTime } from '../util/index'
function getNow () {
return moment()
}
function getNowByCurrentStateValue (value) {
let ret
if (value) {
ret = getTodayTime(value)
} else {
ret = getNow()
}
return ret
}
const CalendarMixin = {
mixins: [BaseMixin],
props: {
value: PropTypes.object,
defaultValue: PropTypes.object,
// onKeyDown: PropTypes.func,
},
data () {
const props = this.$props
const sValue = props.value || props.defaultValue || getNow()
return {
sValue,
sSelectedValue: props.selectedValue || props.defaultSelectedValue,
}
},
watch: {
value (val) {
const sValue = val || this.defaultValue || getNowByCurrentStateValue(this.sValue)
this.setState({
sValue,
})
},
selectedValue (val) {
this.setState({
sSelectedValue: val,
})
},
},
methods: {
onSelect (value, cause) {
if (value) {
this.setValue(value)
}
this.setSelectedValue(value, cause)
},
renderRoot (newProps) {
const props = this.props
const prefixCls = props.prefixCls
const className = {
[prefixCls]: 1,
[`${prefixCls}-hidden`]: !props.visible,
// [props.className]: !!props.className,
[newProps.class]: !!newProps.class,
}
return (
<div
ref='rootInstance'
class={className}
tabIndex='0'
onKeydown={this.onKeyDown}
>
{newProps.children}
</div>
)
},
setSelectedValue (selectedValue, cause) {
// if (this.isAllowedDate(selectedValue)) {
if (!hasProp(this, 'selectedValue')) {
this.setState({
sSelectedValue: selectedValue,
})
}
this.__emit('select', selectedValue, cause)
// }
},
setValue (value) {
const originalValue = this.sValue
if (!hasProp(this, 'value')) {
this.setState({
sValue: value,
})
}
if (
originalValue && value && !originalValue.isSame(value) ||
(!originalValue && value) ||
(originalValue && !value)
) {
this.__emit('change', value)
}
},
isAllowedDate (value) {
const disabledDate = this.disabledDate
const disabledTime = this.disabledTime
return isAllowedDate(value, disabledDate, disabledTime)
},
},
}
export default CalendarMixin

View File

@ -0,0 +1,53 @@
import PropTypes from '@/components/_util/vue-types'
import enUs from '../locale/en_US'
export default {
props: {
locale: PropTypes.object.def(enUs),
visible: PropTypes.bool.def(true),
// onSelect: PropTypes.func,
prefixCls: PropTypes.string.def('rc-calendat'),
// onChange: PropTypes.func,
// onOk: PropTypes.func,
},
// getDefaultProps () {
// return {
// locale: enUs,
// visible: true,
// prefixCls: 'rc-calendar',
// renderFooter () {
// return null
// },
// renderSidebar () {
// return null
// },
// }
// },
// shouldComponentUpdate (nextProps) {
// return this.props.visible || nextProps.visible
// },
methods: {
getFormat () {
let { format } = this
const { locale, timePicker } = this
if (!format) {
if (timePicker) {
format = locale.dateTimeFormat
} else {
format = locale.dateFormat
}
}
return format
},
focus () {
if (this.$refs.rootInstance) {
this.$refs.rootInstance.focus()
}
},
},
}

View File

@ -0,0 +1,110 @@
<script>
import PropTypes from '@/components/_util/vue-types'
import BaseMixin from '@/components/_util/BaseMixin'
import { hasProp } from '@/components/_util/props-util'
import MonthTable from './MonthTable'
function goYear (direction) {
const next = this.sValue.clone()
next.add(direction, 'year')
this.setAndChangeValue(next)
}
function noop () {
}
const MonthPanel = {
mixins: [BaseMixin],
props: {
// onChange: PropTypes.func,
disabledDate: PropTypes.func,
// onSelect: PropTypes.func,
},
data () {
const { value, defaultValue } = this
// bind methods
this.nextYear = goYear.bind(this, 1)
this.previousYear = goYear.bind(this, -1)
return {
sValue: value || defaultValue,
}
},
watch: {
value (val) {
this.setState({
sValue: val,
})
},
},
methods: {
setAndChangeValue (value) {
this.setValue(value)
this.__emit('change', value)
},
setAndSelectValue (value) {
this.setValue(value)
this.__emit('select', value)
},
setValue (value) {
if (!hasProp(this, 'value')) {
this.setState({
sValue: value,
})
}
},
},
render () {
const { sValue, cellRender, contentRender, locale, rootPrefixCls, disabledDate, $listeners = {}} = this
const year = sValue.year()
const prefixCls = `${rootPrefixCls}-month-panel`
return (
<div class={prefixCls}>
<div>
<div class={`${prefixCls}-header`}>
<a
class={`${prefixCls}-prev-year-btn`}
role='button'
onClick={this.previousYear}
title={locale.previousYear}
/>
<a
class={`${prefixCls}-year-select`}
role='button'
onClick={$listeners.yearPanelShow || noop}
title={locale.yearSelect}
>
<span class={`${prefixCls}-year-select-content`}>{year}</span>
<span class={`${prefixCls}-year-select-arrow`}>x</span>
</a>
<a
class={`${prefixCls}-next-year-btn`}
role='button'
onClick={this.nextYear}
title={locale.nextYear}
/>
</div>
<div class={`${prefixCls}-body`}>
<MonthTable
disabledDate={disabledDate}
onSelect={this.setAndSelectValue}
locale={locale}
value={sValue}
cellRender={cellRender}
contentRender={contentRender}
prefixCls={prefixCls}
/>
</div>
</div>
</div>)
},
}
export default MonthPanel
</script>

View File

@ -0,0 +1,135 @@
<script>
import PropTypes from '@/components/_util/vue-types'
import BaseMixin from '@/components/_util/BaseMixin'
import { getTodayTime, getMonthName } from '../util/index'
const ROW = 4
const COL = 3
function chooseMonth (month) {
const next = this.sValue.clone()
next.month(month)
this.setAndSelectValue(next)
}
function noop () {
}
const MonthTable = {
mixins: [BaseMixin],
props: {
cellRender: PropTypes.func,
prefixCls: PropTypes.string,
value: PropTypes.object,
},
data () {
return {
sValue: this.value,
}
},
watch: {
value (val) {
this.setState({
sValue: val,
})
},
},
methods: {
setAndSelectValue (value) {
this.setState({
sValue: value,
})
this.__emit('select', value)
},
months () {
const value = this.sValue
const current = value.clone()
const months = []
let index = 0
for (let rowIndex = 0; rowIndex < ROW; rowIndex++) {
months[rowIndex] = []
for (let colIndex = 0; colIndex < COL; colIndex++) {
current.month(index)
const content = getMonthName(current)
months[rowIndex][colIndex] = {
value: index,
content,
title: content,
}
index++
}
}
return months
},
},
render () {
const props = this.$props
const value = this.sValue
const today = getTodayTime(value)
const months = this.months()
const currentMonth = value.month()
const { prefixCls, locale, contentRender, cellRender } = props
const monthsEls = months.map((month, index) => {
const tds = month.map(monthData => {
let disabled = false
if (props.disabledDate) {
const testValue = value.clone()
testValue.month(monthData.value)
disabled = props.disabledDate(testValue)
}
const classNameMap = {
[`${prefixCls}-cell`]: 1,
[`${prefixCls}-cell-disabled`]: disabled,
[`${prefixCls}-selected-cell`]: monthData.value === currentMonth,
[`${prefixCls}-current-cell`]: today.year() === value.year() &&
monthData.value === today.month(),
}
let cellEl
if (cellRender) {
const currentValue = value.clone()
currentValue.month(monthData.value)
cellEl = cellRender(currentValue, locale)
} else {
let content
if (contentRender) {
const currentValue = value.clone()
currentValue.month(monthData.value)
content = contentRender(currentValue, locale)
} else {
content = monthData.content
}
cellEl = (
<a class={`${prefixCls}-month`}>
{content}
</a>
)
}
return (
<td
role='gridcell'
key={monthData.value}
onClick={disabled ? noop : chooseMonth.bind(this, monthData.value)}
title={monthData.title}
class={classNameMap}
>
{cellEl}
</td>)
})
return (<tr key={index} role='row'>{tds}</tr>)
})
return (
<table class={`${prefixCls}-table`} cellSpacing='0' role='grid'>
<tbody class={`${prefixCls}-tbody`}>
{monthsEls}
</tbody>
</table>
)
},
}
export default MonthTable
</script>

View File

@ -0,0 +1,35 @@
const autoAdjustOverflow = {
adjustX: 1,
adjustY: 1,
}
const targetOffset = [0, 0]
const placements = {
bottomLeft: {
points: ['tl', 'tl'],
overflow: autoAdjustOverflow,
offset: [0, -3],
targetOffset,
},
bottomRight: {
points: ['tr', 'tr'],
overflow: autoAdjustOverflow,
offset: [0, -3],
targetOffset,
},
topRight: {
points: ['br', 'br'],
overflow: autoAdjustOverflow,
offset: [0, 3],
targetOffset,
},
topLeft: {
points: ['bl', 'bl'],
overflow: autoAdjustOverflow,
offset: [0, 3],
targetOffset,
},
}
export default placements

View File

@ -0,0 +1,144 @@
<script>
import PropTypes from '@/components/_util/vue-types'
import BaseMixin from '@/components/_util/BaseMixin'
import { getOptionProps } from '@/components/_util/props-util'
import { cloneElement } from '@/components/_util/vnode'
import CalendarHeader from '../calendar/CalendarHeader'
import DateTable from '../date/DateTable'
import DateInput from '../date/DateInput'
import { getTimeConfig } from '../util/index'
function noop () {}
const CalendarPart = {
mixins: [BaseMixin],
props: {
prefixCls: PropTypes.string,
value: PropTypes.any,
hoverValue: PropTypes.any,
selectedValue: PropTypes.any,
direction: PropTypes.any,
locale: PropTypes.any,
showDateInput: PropTypes.bool,
showTimePicker: PropTypes.bool,
format: PropTypes.any,
placeholder: PropTypes.any,
disabledDate: PropTypes.any,
timePicker: PropTypes.any,
disabledTime: PropTypes.any,
// onInputSelect: PropTypes.func,
timePickerDisabledTime: PropTypes.object,
enableNext: PropTypes.any,
enablePrev: PropTypes.any,
},
render () {
const { $props: props, $listeners = {}} = this
const {
prefixCls,
value,
hoverValue,
selectedValue,
mode,
direction,
locale, format, placeholder,
disabledDate, timePicker, disabledTime,
timePickerDisabledTime, showTimePicker,
enablePrev, enableNext, disabledMonth,
showDateInput, dateRender, showWeekNumber,
} = props
const { inputSelect = noop,
valueChange = noop,
panelChange = noop,
select = noop,
dayHover = noop,
} = $listeners
const shouldShowTimePicker = showTimePicker && timePicker
const disabledTimeConfig = shouldShowTimePicker && disabledTime
? getTimeConfig(selectedValue, disabledTime) : null
const rangeClassName = `${prefixCls}-range`
const newProps = {
locale,
value,
prefixCls,
showTimePicker,
}
const index = direction === 'left' ? 0 : 1
const timePickerProps = getOptionProps(timePicker)
console.log('timePickerProps', timePickerProps)
const timePickerEle = shouldShowTimePicker &&
cloneElement(timePicker, {
props: {
showHour: true,
showMinute: true,
showSecond: true,
...timePickerProps,
...disabledTimeConfig,
...timePickerDisabledTime,
defaultOpenValue: value,
value: selectedValue[index],
},
on: {
change: inputSelect,
},
})
const dateInputElement = showDateInput &&
<DateInput
format={format}
locale={locale}
prefixCls={prefixCls}
timePicker={timePicker}
disabledDate={disabledDate}
placeholder={placeholder}
disabledTime={disabledTime}
value={value}
showClear={false}
selectedValue={selectedValue[index]}
onChange={inputSelect}
/>
const headerProps = {
props: {
...newProps,
mode,
enableNext,
enablePrev,
disabledMonth,
},
on: {
valueChange,
panelChange,
},
}
const tableProps = {
props: {
...newProps,
hoverValue,
selectedValue,
dateRender,
disabledDate,
showWeekNumber,
},
on: {
select,
dayHover,
},
}
return (
<div class={`${rangeClassName}-part ${rangeClassName}-${direction}`}>
{dateInputElement}
<div style={{ outline: 'none' }}>
<CalendarHeader {...headerProps}/>
{showTimePicker ? <div class={`${prefixCls}-time-picker`}>
<div class={`${prefixCls}-time-picker-panel`}>
{timePickerEle}
</div>
</div> : null}
<div class={`${prefixCls}-body`}>
<DateTable {...tableProps}/>
</div>
</div>
</div>)
},
}
export default CalendarPart
</script>

View File

@ -0,0 +1,91 @@
import moment from 'moment'
const defaultDisabledTime = {
disabledHours () {
return []
},
disabledMinutes () {
return []
},
disabledSeconds () {
return []
},
}
export function getTodayTime (value) {
const today = moment()
today.locale(value.locale()).utcOffset(value.utcOffset())
return today
}
export function getTitleString (value) {
return value.format('LL')
}
export function getTodayTimeStr (value) {
const today = getTodayTime(value)
return getTitleString(today)
}
export function getMonthName (month) {
const locale = month.locale()
const localeData = month.localeData()
return localeData[locale === 'zh-cn' ? 'months' : 'monthsShort'](month)
}
export function syncTime (from, to) {
if (!moment.isMoment(from) || !moment.isMoment(to)) return
to.hour(from.hour())
to.minute(from.minute())
to.second(from.second())
}
export function getTimeConfig (value, disabledTime) {
let disabledTimeConfig = disabledTime ? disabledTime(value) : {}
disabledTimeConfig = {
...defaultDisabledTime,
...disabledTimeConfig,
}
return disabledTimeConfig
}
export function isTimeValidByConfig (value, disabledTimeConfig) {
let invalidTime = false
if (value) {
const hour = value.hour()
const minutes = value.minute()
const seconds = value.second()
const disabledHours = disabledTimeConfig.disabledHours()
if (disabledHours.indexOf(hour) === -1) {
const disabledMinutes = disabledTimeConfig.disabledMinutes(hour)
if (disabledMinutes.indexOf(minutes) === -1) {
const disabledSeconds = disabledTimeConfig.disabledSeconds(hour, minutes)
invalidTime = disabledSeconds.indexOf(seconds) !== -1
} else {
invalidTime = true
}
} else {
invalidTime = true
}
}
return !invalidTime
}
export function isTimeValid (value, disabledTime) {
const disabledTimeConfig = getTimeConfig(value, disabledTime)
return isTimeValidByConfig(value, disabledTimeConfig)
}
export function isAllowedDate (value, disabledDate, disabledTime) {
if (disabledDate) {
if (disabledDate(value)) {
return false
}
}
if (disabledTime) {
if (!isTimeValid(value, disabledTime)) {
return false
}
}
return true
}

View File

@ -0,0 +1,145 @@
<script>
import PropTypes from '@/components/_util/vue-types'
import BaseMixin from '@/components/_util/BaseMixin'
const ROW = 4
const COL = 3
function noop () {}
function goYear (direction) {
const value = this.sValue.clone()
value.add(direction, 'year')
this.setState({
sValue: value,
})
}
function chooseYear (year) {
const value = this.sValue.clone()
value.year(year)
value.month(this.sValue.month())
this.__emit('select', value)
}
export default {
mixins: [BaseMixin],
props: {
rootPrefixCls: PropTypes.string,
value: PropTypes.object,
defaultValue: PropTypes.object,
},
data () {
this.nextDecade = goYear.bind(this, 10)
this.previousDecade = goYear.bind(this, -10)
return {
sValue: this.value || this.defaultValue,
}
},
methods: {
years () {
const value = this.sValue
const currentYear = value.year()
const startYear = parseInt(currentYear / 10, 10) * 10
const previousYear = startYear - 1
const years = []
let index = 0
for (let rowIndex = 0; rowIndex < ROW; rowIndex++) {
years[rowIndex] = []
for (let colIndex = 0; colIndex < COL; colIndex++) {
const year = previousYear + index
const content = String(year)
years[rowIndex][colIndex] = {
content,
year,
title: content,
}
index++
}
}
return years
},
},
render () {
const props = this.$props
const value = this.sValue
const locale = props.locale
const years = this.years()
const currentYear = value.year()
const startYear = parseInt(currentYear / 10, 10) * 10
const endYear = startYear + 9
const prefixCls = `${this.rootPrefixCls}-year-panel`
const yeasEls = years.map((row, index) => {
const tds = row.map(yearData => {
const classNameMap = {
[`${prefixCls}-cell`]: 1,
[`${prefixCls}-selected-cell`]: yearData.year === currentYear,
[`${prefixCls}-last-decade-cell`]: yearData.year < startYear,
[`${prefixCls}-next-decade-cell`]: yearData.year > endYear,
}
let clickHandler = noop
if (yearData.year < startYear) {
clickHandler = this.previousDecade
} else if (yearData.year > endYear) {
clickHandler = this.nextDecade
} else {
clickHandler = chooseYear.bind(this, yearData.year)
}
return (
<td
role='gridcell'
title={yearData.title}
key={yearData.content}
onClick={clickHandler}
class={classNameMap}
>
<a
class={`${prefixCls}-year`}
>
{yearData.content}
</a>
</td>)
})
return (<tr key={index} role='row'>{tds}</tr>)
})
return (
<div class={this.prefixCls}>
<div>
<div class={`${prefixCls}-header`}>
<a
class={`${prefixCls}-prev-decade-btn`}
role='button'
onClick={this.previousDecade}
title={locale.previousDecade}
/>
<a
class={`${prefixCls}-decade-select`}
role='button'
onClick={props.onDecadePanelShow}
title={locale.decadeSelect}
>
<span class={`${prefixCls}-decade-select-content`}>
{startYear}-{endYear}
</span>
<span class={`${prefixCls}-decade-select-arrow`}>x</span>
</a>
<a
class={`${prefixCls}-next-decade-btn`}
role='button'
onClick={this.nextDecade}
title={locale.nextDecade}
/>
</div>
<div class={`${prefixCls}-body`}>
<table class={`${prefixCls}-table`} cellSpacing='0' role='grid'>
<tbody class={`${prefixCls}-tbody`}>
{yeasEls}
</tbody>
</table>
</div>
</div>
</div>)
},
}
</script>