diff --git a/.changeset/eighty-terms-agree.md b/.changeset/eighty-terms-agree.md new file mode 100644 index 000000000..f25fdd48e --- /dev/null +++ b/.changeset/eighty-terms-agree.md @@ -0,0 +1,5 @@ +--- +"@hi-ui/hiui": patch +--- + +DatePicker feat: 增加 strideSelectMode API & format 支持函数 diff --git a/.changeset/funny-peaches-carry.md b/.changeset/funny-peaches-carry.md new file mode 100644 index 000000000..cf7840497 --- /dev/null +++ b/.changeset/funny-peaches-carry.md @@ -0,0 +1,5 @@ +--- +"@hi-ui/date-picker": minor +--- + +feat: 增加 strideSelectMode API & format 支持函数 diff --git a/.changeset/kind-beers-check.md b/.changeset/kind-beers-check.md new file mode 100644 index 000000000..78f4b8fe3 --- /dev/null +++ b/.changeset/kind-beers-check.md @@ -0,0 +1,5 @@ +--- +"@hi-ui/hiui": patch +--- + +Drawer feat: add onOutsideClick api diff --git a/.changeset/pink-jokes-flow.md b/.changeset/pink-jokes-flow.md new file mode 100644 index 000000000..864a926bf --- /dev/null +++ b/.changeset/pink-jokes-flow.md @@ -0,0 +1,6 @@ +--- +"@hi-ui/hiui": patch +--- + +Menu fix: 修复 disabled 不生效问题 +Badge 支持字符串和数字 hover 时显示完整内容 diff --git a/.changeset/shiny-rivers-jam.md b/.changeset/shiny-rivers-jam.md new file mode 100644 index 000000000..ede800762 --- /dev/null +++ b/.changeset/shiny-rivers-jam.md @@ -0,0 +1,6 @@ +--- +"@hi-ui/badge": patch +--- + +Badge 支持字符串和数字 hover 时显示完整内容 + diff --git a/.changeset/shy-crabs-clean.md b/.changeset/shy-crabs-clean.md new file mode 100644 index 000000000..cfecfaa86 --- /dev/null +++ b/.changeset/shy-crabs-clean.md @@ -0,0 +1,5 @@ +--- +"@hi-ui/drawer": minor +--- + +feat: add onOutsideClick api diff --git a/.changeset/stupid-meals-repair.md b/.changeset/stupid-meals-repair.md new file mode 100644 index 000000000..d59da3962 --- /dev/null +++ b/.changeset/stupid-meals-repair.md @@ -0,0 +1,5 @@ +--- +"@hi-ui/menu": patch +--- + +fix: 修复 disabled 不生效问题 diff --git a/packages/ui/date-picker/src/DatePicker.tsx b/packages/ui/date-picker/src/DatePicker.tsx index 52f48951d..45a651365 100644 --- a/packages/ui/date-picker/src/DatePicker.tsx +++ b/packages/ui/date-picker/src/DatePicker.tsx @@ -75,6 +75,7 @@ export const DatePicker = forwardRef( onClose, cellRender, footerRender, + strideSelectMode = 'auto', ...otherProps }, ref @@ -172,20 +173,20 @@ export const DatePicker = forwardRef( valueAdapter, uncontrolledValue, ]) - const [outDate, changeOutDate] = useDate({ value, type, defaultValue, cacheDate, - format, + format: typeof format === 'function' ? undefined : format, weekOffset: safeWeekOffset, locale, + strideSelectMode, }) const realFormat = useFormat({ type, showTime, - format, + format: typeof format === 'function' ? undefined : format, locale, }) @@ -421,6 +422,7 @@ export const DatePicker = forwardRef( size, cellRender, footerRender, + strideSelectMode, }} >
diff --git a/packages/ui/date-picker/src/components/calendar.tsx b/packages/ui/date-picker/src/components/calendar.tsx index 5fea02ae0..729afca3c 100644 --- a/packages/ui/date-picker/src/components/calendar.tsx +++ b/packages/ui/date-picker/src/components/calendar.tsx @@ -84,7 +84,7 @@ const Calendar = ({ _class.push(`${prefixCls}__cell--out`) break default: - _class.push(`${prefixCls}__cell--${td.type}`) + !td.weekNum && _class.push(`${prefixCls}__cell--${td.type}`) break } @@ -120,24 +120,21 @@ const Calendar = ({ if (!['SPAN', 'DIV'].includes(td.nodeName) || td.getAttribute('type') === 'disabled') { return false } + const clickVal = parseInt(value) const _date = moment(renderDate) as any const cellType = td.getAttribute('type') const cellWeekType = td.getAttribute('weektype') - // 如果点击的是周数,则直接拿到该周的周一日期返回 - if (cellType === 'week') { - onPick(moment().isoWeek(clickVal)) - return false - } - if (type !== 'weekrange' || isBelongFullOurOfRange) { if (cellType === 'prev' || cellWeekType === 'prev') { _date.subtract(1, 'months') } + if (cellType === 'next' || cellWeekType === 'next') { _date.add(1, 'months') } + _date[view](clickVal) } else { // 点击的上个月的部分,鼠标还在本月的panel上,则视作,鼠标正在本月第一天 diff --git a/packages/ui/date-picker/src/components/input.tsx b/packages/ui/date-picker/src/components/input.tsx index 0ca41a577..35418ab35 100644 --- a/packages/ui/date-picker/src/components/input.tsx +++ b/packages/ui/date-picker/src/components/input.tsx @@ -36,8 +36,10 @@ const Input = ({ const cacheValues = useRef(null) const [value, setValue] = useState('') + useEffect(() => { let vals = date && moment(date).format(realFormat) + if (type.includes('week') && date) { // const _date = moment(date).year(y) // vals = moment(_date).format(realFormat) @@ -51,19 +53,30 @@ const Input = ({ week: getBelongWeek(date, weekOffset), }) } else { - const y = moment(date).weekYear() - const _date = moment(date).year(y) - vals = moment(_date).format(realFormat) + if (typeof format === 'function') { + vals = format(date) + } else { + const y = moment(date).weekYear() + const _date = moment(date).year(y) + + vals = moment(_date).format(realFormat) + } } } + setValue(vals) + cacheValues.current = vals }, [date, weekOffset, i18n, type, format, realFormat, locale]) + const inputChangeEvent = (e: React.ChangeEvent) => { const val = e.target.value + setValue(val) + if (val && val.trim().length === realFormat.length) { const nVal = moment(val) + if (nVal.isValid()) { onChange(nVal, dir) } else { @@ -71,6 +84,7 @@ const Input = ({ } } } + return (
{ } setView(_view) const _innerDates = genNewDates(calRenderDates, date) + if (view === 'date') { onPick(_innerDates, showTime) return } + setCalRenderDates(_innerDates) }, [calRenderDates, onPick, onSelect, showTime, type, view, weekOffset] diff --git a/packages/ui/date-picker/src/components/range-panel.tsx b/packages/ui/date-picker/src/components/range-panel.tsx index 10b8784ec..417217bb8 100644 --- a/packages/ui/date-picker/src/components/range-panel.tsx +++ b/packages/ui/date-picker/src/components/range-panel.tsx @@ -36,6 +36,7 @@ const RangePanel = () => { showPanel, prefixCls, disabledDate, + strideSelectMode, } = useContext(DPContext) const calendarClickIsEnd = useRef(false) const [showRangeMask, setShowRangeMask] = useState(false) @@ -51,6 +52,7 @@ const RangePanel = () => { useEffect(() => { const _outDate = cloneDeep(outDate) + setRange({ start: _outDate[0], end: _outDate[1], @@ -95,11 +97,44 @@ const RangePanel = () => { newRange.end = newRange.start newRange.start = date } + // 此处是明显的语法错误,故而注释修改 // onSelect(date, calendarClickIsEnd) onSelect(date as any, !calendarClickIsEnd.current) + if (type === 'weekrange') { - onPick([newRange.start!.startOf('week'), newRange.end!.endOf('week')], showTime) + // 固定模式下,即使跨月选择了日期,仍然显示当前月的日期选择面板 + if (strideSelectMode === 'fixed') { + const { start, end } = newRange + // 开始周周一日期 + const startOfWeek = start.clone()!.startOf('week') + // 结束周周日日期 + const endOfWeek = end!.clone()!.endOf('week') + // 当月最后一天 + const endOfMonth = end!.clone().endOf('month') + // 重新计算出的开始日期,逻辑:(开始周日期不能是上个月的日期) + // 如果当前日期是当月第一天,则返回当前日期,否则 + // 如果当前日期小于当前周周一,则返回当月第一天,否则返回当前周周一 + const rangeStart = + start.date() === 1 + ? start + : startOfWeek.date() > start.date() + ? start.clone().startOf('month') + : startOfWeek + // 重新计算出的结束日期,逻辑:(结束周日期不能是下个月的日期) + // 如果当前日期是当月最后一天,则返回当前日期,否则 + // 如果当前日期大于当前周周日,则返回当月最后一天,否则返回当前周周日 + const rangeEnd = + end?.date() === endOfMonth.date() + ? end + : end!.date() > endOfWeek.date() + ? endOfMonth + : endOfWeek + + onPick([rangeStart, rangeEnd], showTime) + } else { + onPick([newRange.start!.startOf('week'), newRange.end!.endOf('week')], showTime) + } } else { onPick([newRange.start, newRange.end], showTime) } diff --git a/packages/ui/date-picker/src/components/root.tsx b/packages/ui/date-picker/src/components/root.tsx index 25de2fa74..249aaefd8 100644 --- a/packages/ui/date-picker/src/components/root.tsx +++ b/packages/ui/date-picker/src/components/root.tsx @@ -43,6 +43,7 @@ const Root = ({ min, max, size, + strideSelectMode, } = useContext(DPContext) const [inputData, setInputData] = useState(outDate) @@ -52,9 +53,21 @@ const Root = ({ placeholder, i18n, }) + useEffect(() => { - setInputData(value ? parseValue(value, type, weekOffset, format) : outDate) - }, [value, format, type, outDate, weekOffset]) + setInputData( + value + ? parseValue( + value, + type, + weekOffset, + typeof format === 'string' ? format : undefined, + strideSelectMode + ) + : outDate + ) + }, [value, format, type, outDate, weekOffset, strideSelectMode]) + const onPickerClickEvent = (index: number) => { if (disabled) return onTrigger(index) diff --git a/packages/ui/date-picker/src/hooks/useCalenderData.tsx b/packages/ui/date-picker/src/hooks/useCalenderData.tsx index 75a3e4b90..a74f12dee 100644 --- a/packages/ui/date-picker/src/hooks/useCalenderData.tsx +++ b/packages/ui/date-picker/src/hooks/useCalenderData.tsx @@ -339,6 +339,7 @@ const getDateRows = ({ } } + // 新增功能:周选择显示周数 // 如果是周类型,则计算出每一行的周数并放入每行数组第一个 if (type === 'week' || type === 'weekrange') { const year = _date.year() diff --git a/packages/ui/date-picker/src/hooks/useData.ts b/packages/ui/date-picker/src/hooks/useData.ts index de3fbcd2e..b81ca7638 100644 --- a/packages/ui/date-picker/src/hooks/useData.ts +++ b/packages/ui/date-picker/src/hooks/useData.ts @@ -11,12 +11,27 @@ interface IUseDateConfig { cacheDate: React.MutableRefObject<(moment.Moment | null)[]> type: DatePickerTypeEnum weekOffset: number + strideSelectMode?: 'auto' | 'fixed' } + export const useDate = (config: IUseDateConfig) => { - const { value, defaultValue, cacheDate, type, format, locale, weekOffset } = config + const { + value, + defaultValue, + cacheDate, + type, + format, + locale, + weekOffset, + strideSelectMode, + } = config + const [outDate, setOutDate] = useState<(moment.Moment | null)[]>(() => { - const d = parseValue(value || defaultValue, type, weekOffset, format as any) as any + const _value = value || defaultValue + const d = parseValue(_value, type, weekOffset, format as any, strideSelectMode) as any + cacheDate.current = d + return d }) @@ -25,14 +40,19 @@ export const useDate = (config: IUseDateConfig) => { dates[0] && moment(dates[0]).isValid() ? dates[0] : null, dates[1] && moment(dates[1]).isValid() ? dates[1] : null, ] + setOutDate(_datas as any) } + useEffect(() => { if (value === undefined) return - const d = parseValue(value, type, weekOffset, format as any) as any + + const d = parseValue(value, type, weekOffset, format as any, strideSelectMode) as any + setOutDate(d) + cacheDate.current = d - }, [value, type, weekOffset, format, locale, setOutDate, cacheDate]) + }, [value, type, weekOffset, format, locale, setOutDate, cacheDate, strideSelectMode]) return [outDate, changeOutDate] as const } diff --git a/packages/ui/date-picker/src/types.ts b/packages/ui/date-picker/src/types.ts index 29b3b36b6..3d6bdd7b4 100644 --- a/packages/ui/date-picker/src/types.ts +++ b/packages/ui/date-picker/src/types.ts @@ -3,6 +3,7 @@ import { HiBaseHTMLProps } from '@hi-ui/core' import { PopperOverlayProps } from '@hi-ui/popper' import { TimePickerPanelType } from '@hi-ui/time-picker' import { CalendarColInfo } from './hooks/useCalenderData' +import { Moment } from 'moment' export type CalendarViewEnum = 'date' | 'year' | 'month' @@ -157,7 +158,7 @@ export interface DatePickerProps extends Omit, 'placehold /** * 展示的日期格式,配置参考 [moment.js](http://momentjs.cn/docs/#/displaying/format/) */ - format?: string + format?: string | ((date: Moment) => string) /** * 快捷面板 */ @@ -265,4 +266,11 @@ export interface DatePickerProps extends Omit, 'placehold * 自定义渲染页脚 */ footerRender?: (...actionContents: React.ReactElement[]) => React.ReactNode + /** + * 跨月选择模式 + * 'auto' 自动切换模式,跨月选择时自动切换到跨月的日期选择面板; + * 'fixed' 固定模式,不自动切换(仅周范围选择下生效) + * @default 'auto' + */ + strideSelectMode?: 'auto' | 'fixed' } diff --git a/packages/ui/date-picker/src/utils/index.tsx b/packages/ui/date-picker/src/utils/index.tsx index 28ef8302d..6f498e798 100644 --- a/packages/ui/date-picker/src/utils/index.tsx +++ b/packages/ui/date-picker/src/utils/index.tsx @@ -294,22 +294,31 @@ export const parseValue = ( value: DatePickerValueV3, type: DatePickerTypeEnum, weekOffset: number, - format?: string + format?: string, + strideSelectMode?: 'auto' | 'fixed' ) => { if (!value) return [null] + // 暂时无法理解为何此处自行获取了 type // const _format = getLocaleTypeFormatMap(locale)[type] // const _value = moment(value as any, _format) - const _value = moment(value as any, format) + const _value = moment(value as any, typeof format === 'string' ? format : undefined) const isValid = moment(_value).isValid() + if (value && typeof value === 'object' && (type.includes('range') || type === 'timeperiod')) { const rangeValue = value as DateRange + if (type === 'weekrange') { + if (strideSelectMode === 'fixed') { + return [moment(rangeValue.start), moment(rangeValue.end)] + } + return [ rangeValue.start ? getBelongWeekBoundary(moment(rangeValue.start), weekOffset) : null, rangeValue.end ? getBelongWeekBoundary(moment(rangeValue.end), weekOffset, false) : null, ] } + return [ rangeValue.start && moment(rangeValue.start).isValid() ? moment(rangeValue.start, format) @@ -317,5 +326,6 @@ export const parseValue = ( rangeValue.end && moment(rangeValue.end).isValid() ? moment(rangeValue.end, format) : null, ] } + return [isValid ? _value : null] } diff --git a/packages/ui/date-picker/stories/cell-render.stories.tsx b/packages/ui/date-picker/stories/cell-render.stories.tsx index 4a846374d..e95720d53 100644 --- a/packages/ui/date-picker/stories/cell-render.stories.tsx +++ b/packages/ui/date-picker/stories/cell-render.stories.tsx @@ -1,4 +1,5 @@ import React from 'react' +import moment from 'moment' import DatePicker from '../src' /** @@ -53,8 +54,38 @@ export const CellRender = () => { { + // console.log('format', value) + + const lastDay = value.clone().endOf('month').date() + const startOfWeek = value.clone().startOf('week') + const endOfWeek = value.clone().endOf('week') + const week = value.clone().week() + const weekYear = value.clone().weekYear() + + // 如果当前日期是当月第一天或者或者小于周一,并且周一不是当月第一天,则该周视为 B 周 + if ( + (value.date() === 1 || startOfWeek.date() > value.date()) && + startOfWeek.date() !== 1 + ) { + return `${weekYear}-${week}B` + } + + // 如果当前日期是当月最后一天或者大于周日,并且周日不是最后一天,则该周视为 A 周 + if ( + (value.date() === lastDay || value.date() > endOfWeek.date()) && + endOfWeek.date() !== lastDay + ) { + return `${weekYear}-${week}A` + } + + return `${weekYear}-${week}` + }} + // 自定义渲染出 AB 周,逻辑: + // 在当前月周选择面板下,如果当月第一天位于第一行并且不是周一,则该周视为B周 + // 如果当前月最后一天位于最后一行并且不是周日,则该周视为A周 cellRender={(cellInfo) => { // console.log('cellInfo', cellInfo) @@ -94,6 +125,21 @@ export const CellRender = () => { }} onChange={(date, dateStr) => { console.log('onChange', date, dateStr) + + const _date = date as Date[] + const start = moment(_date?.[0]) + const end = moment(_date?.[1]) + const lastDay = end.clone().endOf('month').date() + + // 如果开始日期是当月第一天并且不是周一,则该周视为 B 周 + if (start.date() === 1 && start.clone().startOf('week').date() !== 1) { + console.log('start week', dateStr?.[0] + 'B') + } + + // 如果当前日期是当月最后一天并且不是周末,则该周视为 A 周 + if (end.date() === lastDay && end.clone().endOf('week').date() !== lastDay) { + console.log('end week', dateStr?.[1] + 'A') + } }} />
diff --git a/packages/ui/drawer/src/Drawer.tsx b/packages/ui/drawer/src/Drawer.tsx index f7f8c5d3a..3ccc25767 100644 --- a/packages/ui/drawer/src/Drawer.tsx +++ b/packages/ui/drawer/src/Drawer.tsx @@ -10,6 +10,8 @@ import { useToggle } from '@hi-ui/use-toggle' import { isNumeric } from '@hi-ui/type-assertion' import { CloseOutlined } from '@hi-ui/icons' import { IconButton } from '@hi-ui/icon-button' +import { mergeRefs } from '@hi-ui/react-utils' +import { useOutsideClick } from '@hi-ui/use-outside-click' import { DrawerPlacementEnum } from './types' const DRAWER_PREFIX = getPrefixCls('drawer') @@ -42,6 +44,7 @@ export const Drawer = forwardRef( showMask = true, placement = 'right', drawerConfig, + onOutsideClick, ...rest }, ref @@ -70,6 +73,11 @@ export const Drawer = forwardRef( } }, [visible, transitionVisibleAction, transitionExitedAction]) + const modalProps = getModalProps(rootProps, ref) + const innerRef = React.useRef(null) + + useOutsideClick(innerRef, onOutsideClick) + const onExitedLatest = useLatestCallback(onExitedProp) const onExited = useCallback(() => { transitionExitedAction.on() @@ -95,7 +103,10 @@ export const Drawer = forwardRef( >
, 'title'>, UseM * 是否展示右上角关闭按钮 */ closeable?: boolean + /** + * 外界元素点击数触发 + */ + onOutsideClick?: (evt: Event) => void /** * 自定义关闭时 icon。暂不对外暴露 * @private diff --git a/packages/ui/drawer/stories/index.stories.tsx b/packages/ui/drawer/stories/index.stories.tsx index 5d8e66884..c321b8f94 100644 --- a/packages/ui/drawer/stories/index.stories.tsx +++ b/packages/ui/drawer/stories/index.stories.tsx @@ -4,6 +4,7 @@ import Drawer from '../src' export * from './basic.stories' export * from './header.stories' export * from './mask.stories' +export * from './outside-click.stories' export * from './container.stories' export * from './nested.stories' export * from './extra.stories' diff --git a/packages/ui/drawer/stories/outside-click.stories.tsx b/packages/ui/drawer/stories/outside-click.stories.tsx new file mode 100644 index 000000000..2d7b4bd85 --- /dev/null +++ b/packages/ui/drawer/stories/outside-click.stories.tsx @@ -0,0 +1,90 @@ +import React from 'react' +import Drawer from '../src' +import Button from '@hi-ui/button' +import Tree, { TreeDataItem } from '@hi-ui/tree' + +/** + * @title 点击外部事件处理 + * @desc 常用于无蒙层模式下,切换列表项详情内容 + */ +export const OutsideClick = () => { + const [visible, setVisible] = React.useState(false) + const [data] = React.useState([ + { + id: 1, + title: '小米', + children: [ + { + id: 2, + title: '研发', + disabled: true, + children: [ + { id: 3, title: '后端', disabled: true }, + { id: 4, title: '运维' }, + { id: 5, title: '前端' }, + ], + }, + { id: 6, title: '产品' }, + ], + }, + { + id: 11, + title: '大米', + children: [ + { id: 22, title: '可视化' }, + { id: 66, title: 'HiUI' }, + ], + }, + ]) + const [currentData, setCurrentData] = React.useState() + const wrapperRef = React.useRef(null) + + return ( + <> +

OutsideClick

+
+
+ { + // console.log('node', node) + + if (id) { + setVisible(true) + setCurrentData(node?.raw) + } else { + setVisible(false) + } + }} + /> +
+ setVisible(false)} + // 点击列表外部内容时关闭抽屉 + onOutsideClick={(e) => { + // console.log('target', e.target) + + if (!wrapperRef.current?.contains(e.target as Element)) { + setVisible(false) + } + }} + footer={ +
+ + +
+ } + > + {currentData?.title} +
+
+ + ) +} diff --git a/packages/ui/menu/src/MenuItem.tsx b/packages/ui/menu/src/MenuItem.tsx index ba92c9580..bb3b24ab7 100644 --- a/packages/ui/menu/src/MenuItem.tsx +++ b/packages/ui/menu/src/MenuItem.tsx @@ -90,14 +90,9 @@ export const MenuItem = forwardRef( })} onClick={() => { if (isArrayNonEmpty(children)) { - if (clickSubMenu) { - clickSubMenu(id) - } + !disabled && clickSubMenu?.(id) } else { - if (clickMenu) { - // @ts-ignore - clickMenu(id, raw) - } + !disabled && clickMenu?.(id, raw as MenuDataItem) if ( closeAllPopper && !(placement === 'vertical' && expandedType === 'collapse' && mini === false) @@ -121,7 +116,7 @@ export const MenuItem = forwardRef( placement === 'vertical' && expandedType === 'collapse' && !showAllSubMenus && - (expandedIds?.includes(id) ? ( + (!disabled && expandedIds?.includes(id) ? ( ) : ( @@ -144,7 +139,7 @@ export const MenuItem = forwardRef( {hasChildren && placement === 'horizontal' && level === 1 && - (expandedIds?.includes(id) ? ( + (!disabled && expandedIds?.includes(id) ? ( ) : ( @@ -156,7 +151,7 @@ export const MenuItem = forwardRef( !mini && !showAllSubMenus && expandedType === 'collapse' ? ( - +
    {children!.map((child) => ( ( gutterGap={16} className={overlayClassName} onClose={() => { - if (closePopper) { - closePopper(id) - } + closePopper?.(id) }} >
      @@ -218,9 +211,7 @@ export const MenuItem = forwardRef( disabledPortal className={overlayClassName} onClose={() => { - if (closePopper) { - closePopper(id) - } + closePopper?.(id) }} >
        @@ -251,9 +242,7 @@ export const MenuItem = forwardRef( gutterGap={16} className={overlayClassName} onClose={() => { - if (closePopper) { - closePopper(id) - } + closePopper?.(id) }} >
          @@ -279,9 +268,7 @@ export const MenuItem = forwardRef( gutterGap={16} className={overlayClassName} onClose={() => { - if (closePopper) { - closePopper(id) - } + closePopper?.(id) }} >
            @@ -308,9 +295,7 @@ export const MenuItem = forwardRef( gutterGap={16} className={overlayClassName} onClose={() => { - if (closePopper) { - closePopper(id) - } + closePopper?.(id) }} >
            @@ -323,15 +308,14 @@ export const MenuItem = forwardRef( {child.children.map((item) => (
            { - if (clickMenu) { - clickMenu(item.id, item) - } - if (closePopper) { - closePopper(id) + if (!item.disabled) { + clickMenu?.(item.id, item) + closePopper?.(id) } }} className={cx(`${prefixCls}-item`, { [`${prefixCls}-item--active`]: activeId === item.id, + [`${prefixCls}-item--disabled`]: item.disabled })} key={item.id} > @@ -358,9 +342,7 @@ export const MenuItem = forwardRef( gutterGap={level === 1 ? 8 : 16} className={overlayClassName} onClose={() => { - if (closePopper) { - closePopper(id) - } + closePopper?.(id) }} >
              @@ -386,9 +368,7 @@ export const MenuItem = forwardRef( gutterGap={level === 1 ? 8 : 16} className={overlayClassName} onClose={() => { - if (closePopper) { - closePopper(id) - } + closePopper?.(id) }} >
                @@ -415,9 +395,7 @@ export const MenuItem = forwardRef( gutterGap={8} className={overlayClassName} onClose={() => { - if (closePopper) { - closePopper(id) - } + closePopper?.(id) }} >
                @@ -431,13 +409,12 @@ export const MenuItem = forwardRef(
                { - if (clickMenu) { - clickMenu(item.id, item) - } - if (closePopper) { - closePopper(id) + if (!item.disabled) { + clickMenu?.(item.id, item) + closePopper?.(id) } }} key={item.id} @@ -476,7 +453,7 @@ if (__DEV__) { } const Arrow = ({ prefixCls, direction }: any) => { - let icon = null + let icon switch (direction) { case 'up': icon = diff --git a/packages/ui/menu/src/styles/menu.scss b/packages/ui/menu/src/styles/menu.scss index c4ec80c6b..b3005a50d 100644 --- a/packages/ui/menu/src/styles/menu.scss +++ b/packages/ui/menu/src/styles/menu.scss @@ -1,6 +1,12 @@ @import '~@hi-ui/core-css/lib/index.scss'; $prefix: '#{$component-prefix}-menu' !default; +$disabled-color: use-color('gray', 400) !default; + +@mixin menu-item-disabled() { + color: $disabled-color; + cursor: not-allowed; +} .#{$prefix}-fat-menu { background-color: use-color-static('white'); @@ -41,6 +47,10 @@ $prefix: '#{$component-prefix}-menu' !default; &:not(.#{$prefix}-item--active):hover { background-color: use-color('gray', 100); } + + &--disabled { + @include menu-item-disabled; + } } ul { @@ -92,6 +102,10 @@ $prefix: '#{$component-prefix}-menu' !default; &:not(.#{$prefix}-item__inner--active):hover { background-color: use-color('gray', 100); } + + &--disabled { + @include menu-item-disabled; + } } &__content { @@ -143,6 +157,10 @@ $prefix: '#{$component-prefix}-menu' !default; height: 100%; flex-shrink: 0; } + + &--disabled { + @include menu-item-disabled; + } } &__wrapper { @@ -220,6 +238,20 @@ $prefix: '#{$component-prefix}-menu' !default; white-space: nowrap; max-width: none; } + + &--disabled { + @include menu-item-disabled; + + &:hover { + .#{$prefix}-item__inner { + border-color: use-color-static('white'); + } + } + + .#{$prefix}-item__content { + color: $disabled-color; + } + } } } @@ -309,6 +341,10 @@ $prefix: '#{$component-prefix}-menu' !default; white-space: nowrap; text-indent: 0.5px; } + + &--disabled { + @include menu-item-disabled; + } } }