forked from opentiny/tiny-vue
feat:日历视图支持点击事件 (#3279)
This commit is contained in:
parent
bec9bbdf77
commit
1eb420845f
|
|
@ -252,6 +252,19 @@ export default {
|
|||
pcDemo: 'multi-select',
|
||||
mfDemo: 'multi-select'
|
||||
},
|
||||
{
|
||||
name: 'date-click',
|
||||
desc: {
|
||||
'zh-CN': '日期点击事件,回调参数为当前点击日期和日程事件',
|
||||
'en-US': 'Date click event, The callback parameters are the current click date and schedule event'
|
||||
},
|
||||
mode: ['pc', 'mobile-first'],
|
||||
pcDemo: 'calendar-event',
|
||||
mfDemo: 'calendar-event',
|
||||
meta: {
|
||||
stable: '3.23.0'
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'week-change',
|
||||
desc: {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
:events="eventslist"
|
||||
:year="2023"
|
||||
:month="5"
|
||||
@date-click="dateClick"
|
||||
@prev-week-click="prevWeekClick"
|
||||
@next-week-click="nextWeekClick"
|
||||
@week-change="weekChange"
|
||||
|
|
@ -25,6 +26,9 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
dateClick(date, events) {
|
||||
TinyModal.message({ message: `点击日期: ${date};日程事件:${JSON.stringify(events)}`, status: 'info' })
|
||||
},
|
||||
prevWeekClick(date) {
|
||||
TinyModal.message({ message: `上一周按钮点击事件: ${date[0].value}`, status: 'info' })
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
:events="eventslist"
|
||||
:year="2023"
|
||||
:month="5"
|
||||
@date-click="dateClick"
|
||||
@prev-week-click="prevWeekClick"
|
||||
@next-week-click="nextWeekClick"
|
||||
@week-change="weekChange"
|
||||
|
|
@ -19,6 +20,10 @@ import { TinyCalendarView, TinyModal } from '@opentiny/vue'
|
|||
|
||||
const eventslist = ref([])
|
||||
|
||||
const dateClick = (date, events) => {
|
||||
TinyModal.message({ message: `点击日期: ${date};日程事件:${JSON.stringify(events)}`, status: 'info' })
|
||||
}
|
||||
|
||||
const prevWeekClick = (date) => {
|
||||
TinyModal.message({ message: `上一周按钮点击事件: ${date[0].value}`, status: 'info' })
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,9 @@ test('事件', async ({ page }) => {
|
|||
const rightSvg = page.locator('.header-right > .tiny-svg')
|
||||
const mode = page.locator('label').nth(2)
|
||||
const modalVal = page.getByText('模式切换事件:schedule')
|
||||
const date = page.getByText('30周一')
|
||||
const dateVal = page.locator('div').filter({ hasText: '点击日期: 2022-5-30;日程事件:[]' }).nth(1)
|
||||
|
||||
await timeBtn.click()
|
||||
await page.waitForTimeout(100)
|
||||
await leftYear.click()
|
||||
|
|
@ -27,4 +30,7 @@ test('事件', async ({ page }) => {
|
|||
await mode.click()
|
||||
await page.waitForTimeout(100)
|
||||
await expect(modalVal).toBeVisible()
|
||||
await date.click()
|
||||
await page.waitForTimeout(100)
|
||||
await expect(dateVal).toBeVisible()
|
||||
})
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
:events="eventslist"
|
||||
:year="2023"
|
||||
:month="5"
|
||||
@date-click="dateClick"
|
||||
@prev-week-click="prevWeekClick"
|
||||
@next-week-click="nextWeekClick"
|
||||
@week-change="weekChange"
|
||||
|
|
@ -26,6 +27,9 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
dateClick(date, events) {
|
||||
TinyModal.message({ message: `点击日期: ${date};日程事件:${JSON.stringify(events)}`, status: 'info' })
|
||||
},
|
||||
prevWeekClick(date) {
|
||||
TinyModal.message({ message: `上一周按钮点击事件: ${date[0].value}`, status: 'info' })
|
||||
},
|
||||
|
|
|
|||
|
|
@ -167,6 +167,7 @@ export default {
|
|||
desc: {
|
||||
'zh-CN':
|
||||
'<p>日历抛出的事件有以下这些:</p>\n' +
|
||||
'<p>date-click:日期点击事件</p>\n' +
|
||||
'<p>new-schedule:新增日程按钮点击事件</p>\n' +
|
||||
'<p>selected-date-change:选中日期改变事件</p>\n' +
|
||||
'<p>prev-week-click:上一周按钮点击事件</p>\n' +
|
||||
|
|
@ -177,6 +178,7 @@ export default {
|
|||
'<p>mode-change:模式切换事件</p>',
|
||||
'en-US':
|
||||
'<p>Calendar throws the following events:</p>\n' +
|
||||
'<p>date-click:日期点击事件: Date click event</p>\n' +
|
||||
'<p>new-schedule: Add a schedule button click event</p>\n' +
|
||||
'<p>selected-date-change: selected date change event</p>\n' +
|
||||
'<p>prev-week-click: button click event of the last week</p>\n' +
|
||||
|
|
@ -371,11 +373,12 @@ export default {
|
|||
value: true
|
||||
},
|
||||
description:
|
||||
'日历抛出的事件包括:new-schedule、selected-date-change、prev-week-click、next-week-click、week-change、year-change、month-change、mode-change。',
|
||||
'日历抛出的事件包括:date-click、new-schedule、selected-date-change、prev-week-click、next-week-click、week-change、year-change、month-change、mode-change。',
|
||||
cloud: {
|
||||
value: false
|
||||
},
|
||||
apis: [
|
||||
'date-click',
|
||||
'new-schedule',
|
||||
'selected-date-change',
|
||||
'prev-week-click',
|
||||
|
|
|
|||
|
|
@ -307,8 +307,19 @@ function splitEvent(props, event) {
|
|||
return result
|
||||
}
|
||||
|
||||
export const computedSelectDay = ({ state }) =>
|
||||
(day) => {
|
||||
if (!day || !day.value || day.disabled) return false
|
||||
|
||||
if (state.multiSelect) {
|
||||
return state.selectedDates.includes(day.value)
|
||||
} else{
|
||||
return state.selectedDate === day.value
|
||||
}
|
||||
}
|
||||
|
||||
export const selectDay =
|
||||
({ state, emit }) =>
|
||||
({ props, state, emit, api }) =>
|
||||
(day, i) => {
|
||||
if (!day || !day.value || day.disabled) return
|
||||
|
||||
|
|
@ -323,9 +334,11 @@ export const selectDay =
|
|||
state.selectedDates.push(date)
|
||||
}
|
||||
|
||||
const dateEvent = dealEvents(props, api, state.selectedDates)
|
||||
|
||||
emit('update:modelValue', state.selectedDates)
|
||||
emit('selected-date-change', state.selectedDates)
|
||||
emit('date-click', date)
|
||||
emit('date-click', state.selectedDates, dateEvent)
|
||||
} else {
|
||||
if (day.isNext) {
|
||||
const { year, month } = nextMonth(state.activeYear, state.activeMonth)
|
||||
|
|
@ -342,12 +355,26 @@ export const selectDay =
|
|||
state.selectedDate =
|
||||
day.value.toString().length > 2 ? day.value : `${state.activeYear}-${state.activeMonth}-${day.value}`
|
||||
state.showSelectedDateEvents = true
|
||||
|
||||
const dateEvent = dealEvents(props, api, [state.selectedDate])
|
||||
|
||||
emit('update:modelValue', state.selectedDate)
|
||||
emit('date-click', state.selectedDate)
|
||||
emit('date-click', state.selectedDate, dateEvent[0])
|
||||
}
|
||||
}
|
||||
|
||||
const dealEvents = (props, api, date) => {
|
||||
return date.map(item => {
|
||||
let event = api.getEventByTime(item, props._constants.DAY_START_TIME, props._constants.DAY_END_TIME)
|
||||
event.forEach(e => {
|
||||
delete e.dayArr;
|
||||
delete e.dayNumber;
|
||||
});
|
||||
return event
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
export const getEventByMonth =
|
||||
({ state }) =>
|
||||
(year, month) => {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import {
|
||||
computedCalendar,
|
||||
handleEvents,
|
||||
computedSelectDay,
|
||||
selectDay,
|
||||
getEventByTime,
|
||||
isToday,
|
||||
|
|
@ -47,6 +48,7 @@ export const api = [
|
|||
'isToday',
|
||||
'dateIsToday',
|
||||
'getEventByTime',
|
||||
'computedSelectDay',
|
||||
'selectDay',
|
||||
'toToday',
|
||||
'getPrevWeek',
|
||||
|
|
@ -270,7 +272,8 @@ const initApi = ({ vm, api, state, t, props, emit, nextTick }) => {
|
|||
computeCascaderOptions: computeCascaderOptions(t),
|
||||
isToday: isToday(state),
|
||||
dateIsToday: dateIsToday(),
|
||||
selectDay: selectDay({ state, emit }),
|
||||
selectDay: selectDay({ props, state, emit, api }),
|
||||
computedSelectDay: computedSelectDay({ state }),
|
||||
getEventByTime: getEventByTime({ props, state }),
|
||||
toToday: toToday({ state, api, nextTick }),
|
||||
getAllWednesdaysInYear: getAllWednesdaysInYear({ state }),
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@
|
|||
|
||||
>li{
|
||||
@apply leading-10;
|
||||
@apply cursor-pointer;
|
||||
|
||||
>span{
|
||||
@apply text-sm;
|
||||
|
|
@ -351,6 +352,7 @@
|
|||
|
||||
>li{
|
||||
@apply leading-10;
|
||||
@apply cursor-pointer;
|
||||
|
||||
.date{
|
||||
@apply relative;
|
||||
|
|
@ -358,7 +360,11 @@
|
|||
@apply text-base;
|
||||
@apply text-color-text-primary;
|
||||
|
||||
&.is-today{
|
||||
&.is-today {
|
||||
@apply text-color-brand;
|
||||
}
|
||||
|
||||
&.current {
|
||||
@apply text-color-brand;
|
||||
}
|
||||
}
|
||||
|
|
@ -407,7 +413,11 @@
|
|||
.week-day{
|
||||
@apply text-sm;
|
||||
@apply text-color-text-placeholder;
|
||||
&.is-today{
|
||||
&.is-today {
|
||||
@apply text-color-brand;
|
||||
}
|
||||
|
||||
&.current {
|
||||
@apply text-color-brand;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -159,12 +159,12 @@
|
|||
|
||||
// x 和 y 滚动条交汇处
|
||||
::-webkit-scrollbar-corner {
|
||||
background: var(--tv-color-bg-scrollbar-track);
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
// 滚动条轨道
|
||||
::-webkit-scrollbar-track {
|
||||
background: var(--tv-color-bg-scrollbar-track);
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
// 滚动滑块
|
||||
|
|
|
|||
|
|
@ -360,6 +360,7 @@
|
|||
|
||||
> li {
|
||||
line-height: 40px;
|
||||
cursor: pointer;
|
||||
|
||||
.date {
|
||||
position: relative;
|
||||
|
|
@ -370,6 +371,10 @@
|
|||
&.is-today {
|
||||
color: var(--tv-CalendarView-week-date-today-text-color);
|
||||
}
|
||||
|
||||
&.current {
|
||||
color: var(--tv-CalendarView-week-date-today-text-color);
|
||||
}
|
||||
}
|
||||
|
||||
.mark {
|
||||
|
|
@ -418,7 +423,11 @@
|
|||
color: #8d959e;
|
||||
|
||||
&.is-today {
|
||||
color: #1890ff;
|
||||
color: var(--tv-CalendarView-week-date-today-text-color);
|
||||
}
|
||||
|
||||
&.current {
|
||||
color: var(--tv-CalendarView-week-date-today-text-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
}
|
||||
|
||||
.month-table() {
|
||||
width: 100%;
|
||||
font-size: var(--tv-MonthTable-font-size);
|
||||
margin: -1px;
|
||||
border-collapse: collapse;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
import { mountPcMode } from '@opentiny-internal/vue-test-utils'
|
||||
import { describe, expect, test } from 'vitest'
|
||||
import CalendarView from '@opentiny/vue-calendar-view'
|
||||
import { nextTick } from 'vue'
|
||||
|
||||
describe('PC Mode', () => {
|
||||
const mount = mountPcMode
|
||||
|
||||
test('value', async () => {
|
||||
const wrapper = mount(() => <CalendarView year={2023} month={5}></CalendarView>)
|
||||
|
||||
await nextTick()
|
||||
expect(wrapper.find('.tiny-calendar-view').exists()).toBe(true)
|
||||
})
|
||||
})
|
||||
|
|
@ -159,7 +159,8 @@
|
|||
data-tag="tiny-calendar-view-weekitem"
|
||||
v-for="(date, index) in state.weekDates"
|
||||
:key="date.value"
|
||||
class="leading-10"
|
||||
class="leading-10 cursor-pointer"
|
||||
@click="selectDay(date)"
|
||||
>
|
||||
<slot
|
||||
name="header"
|
||||
|
|
@ -170,7 +171,7 @@
|
|||
>
|
||||
<span
|
||||
class="relative mr-2.5 text-base"
|
||||
:class="[dateIsToday(date.value) ? 'text-color-brand' : 'text-color-text-primary']"
|
||||
:class="[dateIsToday(date.value) || computedSelectDay(date) ? 'text-color-brand' : 'text-color-text-primary']"
|
||||
>
|
||||
<span>{{ date.value.split('-')[2] }}</span>
|
||||
<span
|
||||
|
|
@ -181,7 +182,7 @@
|
|||
</span>
|
||||
<span
|
||||
class="text-sm"
|
||||
:class="[dateIsToday(date.value) ? 'text-color-brand' : 'text-color-text-placeholder']"
|
||||
:class="[dateIsToday(date.value) || computedSelectDay(date) ? 'text-color-brand' : 'text-color-text-placeholder']"
|
||||
>{{ dateIsToday(date.value) ? t('ui.datepicker.today') : t(`ui.calendarView.weekDays.${index}`) }}</span
|
||||
>
|
||||
</slot>
|
||||
|
|
|
|||
|
|
@ -107,7 +107,7 @@
|
|||
<icon-chevron-left></icon-chevron-left>
|
||||
</div>
|
||||
<ul class="header-main">
|
||||
<li v-for="(date, index) in state.weekDates" :key="date.value">
|
||||
<li v-for="(date, index) in state.weekDates" :key="date.value" @click="selectDay(date)">
|
||||
<slot
|
||||
name="header"
|
||||
:slot-scope="{
|
||||
|
|
@ -115,7 +115,7 @@
|
|||
weekDay: t(`ui.calendarView.weekDays.${index}`)
|
||||
}"
|
||||
>
|
||||
<span class="date" :class="dateIsToday(date.value) && 'is-today'">
|
||||
<span class="date" :class="[dateIsToday(date.value) && 'is-today', { current: computedSelectDay(date) }]">
|
||||
<span>{{ date.value.split('-')[2] }}</span>
|
||||
<span
|
||||
v-if="isShowMark(date.value)"
|
||||
|
|
@ -123,7 +123,7 @@
|
|||
:class="[date.value.split('-')[2] > 9 ? 'is-two-digit' : '', markColor ? `mark-${markColor}` : '']"
|
||||
></span>
|
||||
</span>
|
||||
<span class="week-day" :class="dateIsToday(date.value) && 'is-today'">{{
|
||||
<span class="week-day" :class="[dateIsToday(date.value) && 'is-today', { current: computedSelectDay(date) }]">{{
|
||||
dateIsToday(date.value) ? t('ui.datepicker.today') : t(`ui.calendarView.weekDays.${index}`)
|
||||
}}</span>
|
||||
</slot>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
class="tiny-picker-panel tiny-date-picker tiny-popper"
|
||||
:class="[
|
||||
{
|
||||
'has-sidebar': slots.sidebar || state.shortcuts,
|
||||
'has-sidebar': slots.sidebar || state.shortcuts?.length,
|
||||
'has-time': state.showTime
|
||||
},
|
||||
state.popperClass
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
class="tiny-picker-panel tiny-date-range-picker tiny-popper"
|
||||
:class="[
|
||||
{
|
||||
'has-sidebar': slots.sidebar || state.shortcuts,
|
||||
'has-sidebar': slots.sidebar || state.shortcuts?.length,
|
||||
'has-time': state.showTime
|
||||
},
|
||||
state.popperClass
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
class="tiny-picker-panel tiny-date-range-picker tiny-popper"
|
||||
:class="[
|
||||
{
|
||||
'has-sidebar': slots.sidebar || state.shortcuts
|
||||
'has-sidebar': slots.sidebar || state.shortcuts?.length,
|
||||
},
|
||||
state.popperClass
|
||||
]"
|
||||
|
|
|
|||
Loading…
Reference in New Issue