Commit b27858ddb52b2f6238294eea561e129c6194b1ab

Authored by Sergio Crisostomo
1 parent 3d50db5b

add date panel label format logic

src/components/date-picker/panel/date-panel-label.vue 0 → 100644
  1 +<template>
  2 + <span>
  3 + <span
  4 + v-if="datePanelLabel"
  5 + v-show="datePanelLabel.labels[0].type === 'year' || currentView === 'date'"
  6 + :class="[datePrefixCls + '-header-label']"
  7 + @click="datePanelLabel.labels[0].handler">{{ datePanelLabel.labels[0].label }}</span>
  8 + <template v-if="datePanelLabel && currentView === 'date'">{{ datePanelLabel.separator }}</template>
  9 + <span
  10 + v-if="datePanelLabel"
  11 + v-show="datePanelLabel.labels[1].type === 'year' || currentView === 'date'"
  12 + :class="[datePrefixCls + '-header-label']"
  13 + @click="datePanelLabel.labels[1].handler">{{ datePanelLabel.labels[1].label }}</span>
  14 + </span>
  15 +</template>
  16 +
  17 +<script>
  18 +export default {
  19 + props: {
  20 + datePanelLabel: Object,
  21 + currentView: String,
  22 + datePrefixCls: String
  23 + }
  24 +};
  25 +</script>
... ...
src/components/date-picker/panel/date-range.vue
... ... @@ -16,13 +16,10 @@
16 16 :class="iconBtnCls('prev')"
17 17 @click="prevMonth"
18 18 v-show="leftCurrentView === 'date'"><Icon type="ios-arrow-left"></Icon></span>
19   - <span
20   - :class="[datePrefixCls + '-header-label']"
21   - @click="showYearPicker('left')">{{ leftYearLabel }}</span>
22   - <span
23   - :class="[datePrefixCls + '-header-label']"
24   - @click="showMonthPicker('left')"
25   - v-show="leftCurrentView === 'date'">{{ leftMonthLabel }}</span>
  19 + <date-panel-label
  20 + :date-panel-label="leftDatePanelLabel"
  21 + :current-view="leftCurrentView"
  22 + :date-prefix-cls="datePrefixCls"/>
26 23 <span
27 24 :class="iconBtnCls('next', '-double')"
28 25 @click="nextYear('left')"
... ... @@ -66,13 +63,10 @@
66 63 :class="iconBtnCls('prev', '-double')"
67 64 @click="prevYear('right')"
68 65 v-show="rightCurrentView === 'year' || rightCurrentView === 'month'"><Icon type="ios-arrow-left"></Icon></span>
69   - <span
70   - :class="[datePrefixCls + '-header-label']"
71   - @click="showYearPicker('right')">{{ rightYearLabel }}</span>
72   - <span
73   - :class="[datePrefixCls + '-header-label']"
74   - @click="showMonthPicker('right')"
75   - v-show="rightCurrentView === 'date'">{{ rightMonthLabel }}</span>
  66 + <date-panel-label
  67 + :date-panel-label="rightDatePanelLabel"
  68 + :current-view="rightCurrentView"
  69 + :date-prefix-cls="datePrefixCls"/>
76 70 <span
77 71 :class="iconBtnCls('next', '-double')"
78 72 @click="nextYear('right')"><Icon type="ios-arrow-right"></Icon></span>
... ... @@ -138,7 +132,8 @@
138 132 import MonthTable from '../base/month-table.vue';
139 133 import TimePicker from './time-range.vue';
140 134 import Confirm from '../base/confirm.vue';
141   - import { toDate, prevMonth, nextMonth, initTimeDate } from '../util';
  135 + import { toDate, prevMonth, nextMonth, initTimeDate, formatDateLabels } from '../util';
  136 + import datePanelLabel from './date-panel-label.vue';
142 137  
143 138 import Mixin from './mixin';
144 139 import Locale from '../../../mixins/locale';
... ... @@ -149,7 +144,7 @@
149 144 export default {
150 145 name: 'DatePicker',
151 146 mixins: [ Mixin, Locale ],
152   - components: { Icon, DateTable, YearTable, MonthTable, TimePicker, Confirm },
  147 + components: { Icon, DateTable, YearTable, MonthTable, TimePicker, Confirm, datePanelLabel },
153 148 data () {
154 149 return {
155 150 prefixCls: prefixCls,
... ... @@ -195,26 +190,9 @@
195 190 return this.date;
196 191 }
197 192 },
198   - leftYearLabel () {
199   - const tYear = this.t('i.datepicker.year');
200   - if (this.leftCurrentView === 'year') {
201   - const year = this.leftTableYear;
202   - if (!year) return '';
203   - const startYear = Math.floor(year / 10) * 10;
204   - return `${startYear}${tYear} - ${startYear + 9}${tYear}`;
205   - } else {
206   - const year = this.leftCurrentView === 'month' ? this.leftTableYear : this.leftYear;
207   - if (!year) return '';
208   - return `${year}${tYear}`;
209   - }
210   - },
211 193 leftMonth () {
212 194 return this.date.getMonth();
213 195 },
214   - leftMonthLabel () {
215   - const month = this.leftMonth + 1;
216   - return this.t(`i.datepicker.month${month}`);
217   - },
218 196 rightYear () {
219 197 return this.rightDate.getFullYear();
220 198 },
... ... @@ -225,26 +203,9 @@
225 203 return this.date;
226 204 }
227 205 },
228   - rightYearLabel () {
229   - const tYear = this.t('i.datepicker.year');
230   - if (this.rightCurrentView === 'year') {
231   - const year = this.rightTableYear;
232   - if (!year) return '';
233   - const startYear = Math.floor(year / 10) * 10;
234   - return `${startYear}${tYear} - ${startYear + 9}${tYear}`;
235   - } else {
236   - const year = this.rightCurrentView === 'month' ? this.rightTableYear : this.rightYear;
237   - if (!year) return '';
238   - return `${year}${tYear}`;
239   - }
240   - },
241 206 rightMonth () {
242 207 return this.rightDate.getMonth();
243 208 },
244   - rightMonthLabel () {
245   - const month = this.rightMonth + 1;
246   - return this.t(`i.datepicker.month${month}`);
247   - },
248 209 rightDate () {
249 210 const newDate = new Date(this.date);
250 211 const month = newDate.getMonth();
... ... @@ -258,6 +219,14 @@
258 219 }
259 220 return newDate;
260 221 },
  222 + leftDatePanelLabel () {
  223 + if (!this.leftYear) return null; // not ready yet
  224 + return this.panelLabelConfig('left');
  225 + },
  226 + rightDatePanelLabel () {
  227 + if (!this.leftYear) return null; // not ready yet
  228 + return this.panelLabelConfig('right');
  229 + },
261 230 timeDisabled () {
262 231 return !(this.minDate && this.maxDate);
263 232 }
... ... @@ -288,6 +257,22 @@
288 257 }
289 258 },
290 259 methods: {
  260 + panelLabelConfig (direction) {
  261 + const locale = this.t('i.locale');
  262 + const datePanelLabel = this.t('i.datepicker.datePanelLabel');
  263 + const handler = type => {
  264 + const fn = type == 'month' ? this.showMonthPicker : this.showYearPicker;
  265 + return () => fn(direction);
  266 + };
  267 +
  268 + const date = new Date(this[`${direction}Year`], this[`${direction}Month`]);
  269 + const { labels, separator } = formatDateLabels(locale, datePanelLabel, date);
  270 +
  271 + return {
  272 + separator: separator,
  273 + labels: labels.map(obj => ((obj.handler = handler(obj.type)), obj))
  274 + };
  275 + },
291 276 resetDate () {
292 277 this.date = new Date(this.date);
293 278 this.leftTableYear = this.date.getFullYear();
... ...
src/components/date-picker/panel/date.vue
... ... @@ -15,13 +15,10 @@
15 15 :class="iconBtnCls('prev')"
16 16 @click="changeMonth(-1)"
17 17 v-show="currentView === 'date'"><Icon type="ios-arrow-left"></Icon></span>
18   - <span
19   - :class="[datePrefixCls + '-header-label']"
20   - @click="showYearPicker">{{ yearLabel }}</span>
21   - <span
22   - :class="[datePrefixCls + '-header-label']"
23   - @click="showMonthPicker"
24   - v-show="currentView === 'date'">{{ monthLabel }}</span>
  18 + <date-panel-label
  19 + :date-panel-label="datePanelLabel"
  20 + :current-view="currentView"
  21 + :date-prefix-cls="datePrefixCls"/>
25 22 <span
26 23 :class="iconBtnCls('next', '-double')"
27 24 @click="changeYear(+1)"><Icon type="ios-arrow-right"></Icon></span>
... ... @@ -83,11 +80,12 @@
83 80 import MonthTable from '../base/month-table.vue';
84 81 import TimePicker from './time.vue';
85 82 import Confirm from '../base/confirm.vue';
  83 + import datePanelLabel from './date-panel-label.vue';
86 84  
87 85 import Mixin from './mixin';
88 86 import Locale from '../../../mixins/locale';
89 87  
90   - import { initTimeDate, siblingMonth } from '../util';
  88 + import { initTimeDate, siblingMonth, formatDateLabels } from '../util';
91 89  
92 90 const prefixCls = 'ivu-picker-panel';
93 91 const datePrefixCls = 'ivu-date-picker';
... ... @@ -95,7 +93,7 @@
95 93 export default {
96 94 name: 'DatePicker',
97 95 mixins: [ Mixin, Locale ],
98   - components: { Icon, DateTable, YearTable, MonthTable, TimePicker, Confirm },
  96 + components: { Icon, DateTable, YearTable, MonthTable, TimePicker, Confirm, datePanelLabel },
99 97 data () {
100 98 return {
101 99 prefixCls: prefixCls,
... ... @@ -123,19 +121,21 @@
123 121 }
124 122 ];
125 123 },
126   - yearLabel () {
127   - const tYear = this.t('i.datepicker.year');
128   - const year = this.year;
129   - if (!year) return '';
130   - if (this.currentView === 'year') {
131   - const startYear = Math.floor(year / 10) * 10;
132   - return `${startYear}${tYear} - ${startYear + 9}${tYear}`;
133   - }
134   - return `${year}${tYear}`;
135   - },
136   - monthLabel () {
137   - const month = this.month + 1;
138   - return this.t(`i.datepicker.month${month}`);
  124 + datePanelLabel () {
  125 + if (!this.year) return null; // not ready yet
  126 + const locale = this.t('i.locale');
  127 + const datePanelLabel = this.t('i.datepicker.datePanelLabel');
  128 + const date = new Date(this.year, this.month);
  129 + const { labels, separator } = formatDateLabels(locale, datePanelLabel, date);
  130 +
  131 + const handler = type => {
  132 + return () => (this.currentView = type);
  133 + };
  134 +
  135 + return {
  136 + separator: separator,
  137 + labels: labels.map(obj => ((obj.handler = handler(obj.type)), obj))
  138 + };
139 139 }
140 140 },
141 141 watch: {
... ... @@ -196,12 +196,6 @@
196 196 this.date = siblingMonth(this.date, dir);
197 197 this.setMonthYear(this.date);
198 198 },
199   - showYearPicker () {
200   - this.currentView = 'year';
201   - },
202   - showMonthPicker () {
203   - this.currentView = 'month';
204   - },
205 199 handleToggleTime () {
206 200 if (this.currentView === 'date') {
207 201 this.currentView = 'time';
... ...
src/components/date-picker/util.js
... ... @@ -61,3 +61,64 @@ export const initTimeDate = function() {
61 61 date.setSeconds(0);
62 62 return date;
63 63 };
  64 +
  65 +export const formatDateLabels = (function() {
  66 + /*
  67 + Formats:
  68 + yyyy - 4 digit year
  69 + m - month, numeric, 1 - 12
  70 + m - month, numeric, 01 - 12
  71 + mmm - month, 3 letters, as in `toLocaleDateString`
  72 + Mmm - month, 3 letters, capitalize the return from `toLocaleDateString`
  73 + mmmm - month, full name, as in `toLocaleDateString`
  74 + Mmmm - month, full name, capitalize the return from `toLocaleDateString`
  75 + */
  76 +
  77 + const formats = {
  78 + yyyy: date => date.getFullYear(),
  79 + m: date => date.getMonth(),
  80 + mm: date => ('0' + date.getMonth()).slice(-2),
  81 + mmm: (date, locale) => {
  82 + const monthName = date.toLocaleDateString(locale, {
  83 + month: 'long'
  84 + });
  85 + return monthName.slice(0, 3);
  86 + },
  87 + Mmm: (date, locale) => {
  88 + const monthName = date.toLocaleDateString(locale, {
  89 + month: 'long'
  90 + });
  91 + return (monthName[0].toUpperCase() + monthName.slice(1).toLowerCase()).slice(0, 3);
  92 + },
  93 + mmmm: (date, locale) =>
  94 + date.toLocaleDateString(locale, {
  95 + month: 'long'
  96 + }),
  97 + Mmmm: (date, locale) => {
  98 + const monthName = date.toLocaleDateString(locale, {
  99 + month: 'long'
  100 + });
  101 + return monthName[0].toUpperCase() + monthName.slice(1).toLowerCase();
  102 + }
  103 + };
  104 + const formatRegex = new RegExp(['yyyy', 'Mmmm', 'mmmm', 'Mmm', 'mmm', 'mm', 'm'].join('|'), 'g');
  105 +
  106 + return function(locale, format, date) {
  107 + const componetsRegex = /(\[[^\]]+\])([^\[\]]+)(\[[^\]]+\])/;
  108 + const components = format.match(componetsRegex).slice(1);
  109 + const separator = components[1];
  110 + const labels = [components[0], components[2]].map(component => {
  111 + const label = component.replace(/\[[^\]]+\]/, str => {
  112 + return str.slice(1, -1).replace(formatRegex, match => formats[match](date, locale));
  113 + });
  114 + return {
  115 + label: label,
  116 + type: component.includes('yy') ? 'year' : 'month'
  117 + };
  118 + });
  119 + return {
  120 + separator: separator,
  121 + labels: labels
  122 + };
  123 + };
  124 +})();
... ...