diff --git a/package.json b/package.json index da13c892..0668cee5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "vxe-pc-ui", - "version": "3.3.46", + "version": "3.3.47", "description": "A vue based PC component library", "scripts": { "update": "npm install --legacy-peer-deps", diff --git a/packages/calendar/src/calendar.ts b/packages/calendar/src/calendar.ts index dc5300c1..d6d8c187 100644 --- a/packages/calendar/src/calendar.ts +++ b/packages/calendar/src/calendar.ts @@ -618,7 +618,7 @@ export default defineVxeComponent({ reactData.currentDate = currentDate $xeCalendar.dateMonthHandle(currentDate, 0) }, - dateToggleTypeEvent () { + dateToggleTypeEvent (evnt: MouseEvent) { const $xeCalendar = this const reactData = $xeCalendar.reactData @@ -629,6 +629,7 @@ export default defineVxeComponent({ datePanelType = 'month' } reactData.datePanelType = datePanelType + $xeCalendar.changeViewEvent(evnt) }, datePrevEvent (evnt: Event) { const $xeCalendar = this @@ -659,6 +660,7 @@ export default defineVxeComponent({ } } $xeCalendar.dispatchEvent('date-prev', { type }, evnt) + $xeCalendar.changeViewEvent(evnt) } }, dateTodayMonthEvent (evnt: Event) { @@ -671,6 +673,7 @@ export default defineVxeComponent({ $xeCalendar.dateChange(reactData.currentDate) } $xeCalendar.dispatchEvent('date-today', { type: props.type }, evnt) + $xeCalendar.changeViewEvent(evnt) }, dateNextEvent (evnt: Event) { const $xeCalendar = this @@ -701,6 +704,7 @@ export default defineVxeComponent({ } } $xeCalendar.dispatchEvent('date-next', { type }, evnt) + $xeCalendar.changeViewEvent(evnt) } }, isDateDisabled (item: { date: Date }) { @@ -712,6 +716,42 @@ export default defineVxeComponent({ const { datePanelType } = reactData return disabledMethod && disabledMethod({ type: datePanelType, viewType: datePanelType, date: item.date, $calendar: $xeCalendar as VxeCalendarConstructor }) }, + changeViewEvent (evnt: Event | null) { + const $xeCalendar = this + const reactData = $xeCalendar.reactData + + const { datePanelType } = reactData + const yearDatas = $xeCalendar.computeYearDatas + const quarterDatas = $xeCalendar.computeQuarterDatas + const monthDatas = $xeCalendar.computeMonthDatas + const weekDates = $xeCalendar.computeWeekDates + const dayDatas = $xeCalendar.computeDayDatas + const viewDates: Date[] = [] + let dataList: { date: Date }[][] = [] + switch (datePanelType) { + case 'year': + dataList = yearDatas + break + case 'quarter': + dataList = quarterDatas + break + case 'month': + dataList = monthDatas + break + case 'week': + dataList = weekDates + break + case 'day': + dataList = dayDatas + break + } + dataList.forEach(rows => { + rows.forEach(item => { + viewDates.push(item.date) + }) + }) + $xeCalendar.dispatchEvent('view-change', { viewType: datePanelType, viewDates }, evnt) + }, dateSelectItem (date: Date) { const $xeCalendar = this const props = $xeCalendar @@ -723,6 +763,7 @@ export default defineVxeComponent({ if (datePanelType === 'year') { reactData.datePanelType = 'month' $xeCalendar.dateCheckMonth(date) + $xeCalendar.changeViewEvent(null) } else { $xeCalendar.dateChange(date) } @@ -732,6 +773,7 @@ export default defineVxeComponent({ if (datePanelType === 'year') { reactData.datePanelType = 'quarter' $xeCalendar.dateCheckMonth(date) + $xeCalendar.changeViewEvent(null) } else { $xeCalendar.dateChange(date) } @@ -739,9 +781,11 @@ export default defineVxeComponent({ if (datePanelType === 'month') { reactData.datePanelType = type === 'week' ? type : 'day' $xeCalendar.dateCheckMonth(date) + $xeCalendar.changeViewEvent(null) } else if (datePanelType === 'year') { reactData.datePanelType = 'month' $xeCalendar.dateCheckMonth(date) + $xeCalendar.changeViewEvent(null) } else { $xeCalendar.dateChange(date) } diff --git a/packages/menu/src/menu.ts b/packages/menu/src/menu.ts index 82ec660f..05157d7e 100644 --- a/packages/menu/src/menu.ts +++ b/packages/menu/src/menu.ts @@ -4,6 +4,7 @@ import XEUtils from 'xe-utils' import { getConfig, getIcon, createEvent, permission, globalMixins, globalEvents, renderEmptyElement } from '../../ui' import { toCssUnit } from '../../ui/src/dom' import { getLastZIndex, nextZIndex } from '../../ui/src/utils' +import { getSlotVNs } from '../../ui/src/vn' import VxeLoadingComponent from '../../loading/index' import type { VxeMenuDefines, MenuReactData, VxeMenuPropTypes, VxeLayoutAsideConstructor, VxeMenuEmits, VxeLayoutAsidePropTypes, VxeComponentPermissionInfo, VxeComponentSizeType, ValueOf } from '../../../types' @@ -66,7 +67,7 @@ export default defineVxeComponent({ return collapsed } if ($xeLayoutAside) { - return $xeLayoutAside.collapsed + return !!$xeLayoutAside.collapsed } return false }, @@ -112,6 +113,20 @@ export default defineVxeComponent({ $xeMenu.$emit('model-value', value) } }, + callSlot (slotFunc: any, params: any, h: CreateElement) { + const $xeMenu = this + const slots = $xeMenu.$scopedSlots + + if (slotFunc) { + if (XEUtils.isString(slotFunc)) { + slotFunc = slots[slotFunc] || null + } + if (XEUtils.isFunction(slotFunc)) { + return getSlotVNs(slotFunc.call($xeMenu, params, h)) + } + } + return [] + }, getMenuTitle (item: VxeMenuPropTypes.MenuOption) { return `${item.title || item.name}` }, @@ -269,11 +284,14 @@ export default defineVxeComponent({ // renderMenuTitle (h:CreateElement, item: VxeMenuDefines.MenuItem) { const $xeMenu = this + const slots = $xeMenu.$scopedSlots - const { icon, isExpand, hasChild } = item + const { icon, isExpand, hasChild, slots: itemSlots } = item + const optionSlot = itemSlots ? itemSlots.default : slots.option const title = $xeMenu.getMenuTitle(item) + const isCollapsed = $xeMenu.computeIsCollapsed return [ - h('span', { + h('div', { class: 'vxe-menu--item-link-icon' }, icon ? [ @@ -282,14 +300,21 @@ export default defineVxeComponent({ }) ] : []), - h('span', { - class: 'vxe-menu--item-link-title', - attrs: { - title - } - }, title), + optionSlot + ? h('div', { + class: 'vxe-menu--item-custom-title' + }, $xeMenu.callSlot(optionSlot, { + option: item as any, + collapsed: isCollapsed + }, h)) + : h('div', { + class: 'vxe-menu--item-link-title', + attrs: { + title + } + }, title), hasChild - ? h('span', { + ? h('div', { class: 'vxe-menu--item-link-collapse', on: { click (evnt: KeyboardEvent) { diff --git a/styles/components/menu.scss b/styles/components/menu.scss index fe9479f8..841dfe0f 100644 --- a/styles/components/menu.scss +++ b/styles/components/menu.scss @@ -4,6 +4,7 @@ position: relative; &.is--collapsed { .vxe-menu--item-link-title, + .vxe-menu--item-custom-title, .vxe-menu--item-link-collapse { display: none; } @@ -30,6 +31,7 @@ } &:not(.is--enter) { .vxe-menu--item-link-title, + .vxe-menu--item-custom-title, .vxe-menu--item-link-collapse { display: none; } @@ -53,7 +55,8 @@ } } .vxe-menu--item-link, -.vxe-menu--item-link-title { +.vxe-menu--item-link-title, +.vxe-menu--item-custom-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -63,7 +66,8 @@ width: var(--vxe-ui-menu-icon-width); text-align: center; } -.vxe-menu--item-link-title { +.vxe-menu--item-link-title, +.vxe-menu--item-custom-title { flex-grow: 1; padding-left: 0.2em; } diff --git a/types/components/calendar.d.ts b/types/components/calendar.d.ts index 50fe310a..f9881995 100644 --- a/types/components/calendar.d.ts +++ b/types/components/calendar.d.ts @@ -85,7 +85,8 @@ export type VxeCalendarEmits = [ 'click', 'date-prev', 'date-today', - 'date-next' + 'date-next', + 'view-change' ] export namespace VxeCalendarDefines { @@ -135,13 +136,55 @@ export namespace VxeCalendarDefines { viewType: DatePanelType date: Date } + + export interface ChangeEventParams extends CalendarEventParams { + value: string + } + export interface ClickEventParams extends CalendarEventParams { } + export interface DatePrevEventParams extends CalendarEventParams { + type: DatePanelType + } + export interface DateTodayEventParams extends CalendarEventParams { + type: DatePanelType + } + export interface DateNextEventParams extends CalendarEventParams { + type: DatePanelType + } + export interface ViewChangeEventParams extends CalendarEventParams { + viewType: DatePanelType + viewDates: Date[] + } } -export type VxeCalendarEventProps = {} +export type VxeCalendarEventProps = { + onInput?: VxeCalendarEvents.Input + onChange?: VxeCalendarEvents.Change + onClick?: VxeCalendarEvents.Click + onDatePrev?: VxeCalendarEvents.DatePrev + onDateToday?: VxeCalendarEvents.DateToday + onDateNext?: VxeCalendarEvents.DateNext + onViewChange?: VxeCalendarEvents.ViewChange +} -export interface VxeCalendarListeners { } +export interface VxeCalendarListeners { + input?: VxeCalendarEvents.Input + change?: VxeCalendarEvents.Change + click?: VxeCalendarEvents.Click + datePrev?: VxeCalendarEvents.DatePrev + dateToday?: VxeCalendarEvents.DateToday + dateNext?: VxeCalendarEvents.DateNext + viewChange?: VxeCalendarEvents.ViewChange +} -export namespace VxeCalendarEvents { } +export namespace VxeCalendarEvents { + export type Input = (params: VxeCalendarDefines.InputEventParams) => void + export type Change = (params: VxeCalendarDefines.ChangeEventParams) => void + export type Click = (params: VxeCalendarDefines.ClickEventParams) => void + export type DatePrev = (params: VxeCalendarDefines.DatePrevEventParams) => void + export type DateToday = (params: VxeCalendarDefines.DateTodayEventParams) => void + export type DateNext = (params: VxeCalendarDefines.DateNextEventParams) => void + export type ViewChange = (params: VxeCalendarDefines.ViewChangeEventParams) => void +} export namespace VxeCalendarSlotTypes { export interface DefaultSlotParams {} diff --git a/types/components/menu.d.ts b/types/components/menu.d.ts index 738a65eb..814279ae 100644 --- a/types/components/menu.d.ts +++ b/types/components/menu.d.ts @@ -1,3 +1,4 @@ +import { CreateElement } from 'vue' import { DefineVxeComponentApp, DefineVxeComponentOptions, DefineVxeComponentInstance, VxeComponentEventParams, ValueOf, VxeComponentSizeType, VxeComponentStyleType, VxeComponentPermissionCodeType } from '@vxe-ui/core' import { VxeLinkPropTypes } from './link' @@ -21,18 +22,6 @@ export namespace VxeMenuPropTypes { export type Size = VxeComponentSizeType export type Loading = boolean - export interface MenuOneOption extends MenuOption { - children?: MenuTwoOption[] - } - - export interface MenuTwoOption extends MenuOption { - children?: MenuThreeOption[] - } - - export interface MenuThreeOption extends MenuOption { - children?: MenuOption[] - } - export interface MenuOption { name?: VxeMenuPropTypes.ModelValue title?: string | number @@ -40,6 +29,13 @@ export namespace VxeMenuPropTypes { routerLink?: VxeLinkPropTypes.RouterLink expanded?: boolean permissionCode?: VxeComponentPermissionCodeType + children?: MenuOption[] + slots?: { + default?: string | ((params: { + option: Required + collapsed: boolean + }, h: CreateElement) => VxeComponentSlotType | VxeComponentSlotType[]) | null + } } export type Collapsed = boolean @@ -127,6 +123,14 @@ export namespace VxeMenuSlotTypes { export interface VxeMenuSlots { default?: (params: VxeMenuSlotTypes.DefaultSlotParams) => any + /** + * 自定义弹窗容器选项模板 + */ + option?: ((params: { + option: Required + collapsed: boolean + [key: string]: any + }) => any) | undefined } export const Menu: typeof VxeMenu diff --git a/types/components/option.d.ts b/types/components/option.d.ts index 3c8c3a48..467a5d8a 100644 --- a/types/components/option.d.ts +++ b/types/components/option.d.ts @@ -29,7 +29,7 @@ export namespace VxeOptionPropTypes { default?: string | ((params: { option: any $select: VxeSelectConstructor - }) => VxeComponentSlotType | VxeComponentSlotType[]) | null + }, h: CreateElement) => VxeComponentSlotType | VxeComponentSlotType[]) | null } }