diff --git a/packages/devui-vue/devui/category-search/src/category-search.tsx b/packages/devui-vue/devui/category-search/src/category-search.tsx index 6f85d396d5..00978efe6c 100644 --- a/packages/devui-vue/devui/category-search/src/category-search.tsx +++ b/packages/devui-vue/devui/category-search/src/category-search.tsx @@ -12,51 +12,53 @@ import { useCategorySearch } from './composables/use-category-search'; import './category-search.scss'; export default defineComponent({ - name: 'DCategorySearch', - props: categorySearchProps, - emits: ['search', 'selectedTagsChange', 'createFilter', 'clearAll', 'searchKeyChange'], - setup(props: CategorySearchProps, ctx: SetupContext) { - const { - rootRef, - scrollBarRef, - inputRef, - isHover, - containerClasses, - innerSelectedTags, - joinLabelTypes, - showExtendedConfig, - operationConfig, - onSearch, - } = useCategorySearch(props, ctx); + name: 'DCategorySearch', + props: categorySearchProps, + emits: ['search', 'selectedTagsChange', 'createFilter', 'clearAll', 'searchKeyChange'], + setup(props: CategorySearchProps, ctx: SetupContext) { + const { + rootRef, + scrollBarRef, + inputRef, + isHover, + containerClasses, + innerSelectedTags, + joinLabelTypes, + showExtendedConfig, + operationConfig, + onSearch, + } = useCategorySearch(props, ctx); - return () => ( -
(isHover.value = true)} - onMouseleave={() => (isHover.value = false)}> -
- -
-
- -
- {showExtendedConfig.value && ( -
- {operationConfig.clear?.show && ( - <>{ctx.slots.clear?.() ?? } - )} - {operationConfig.save?.show && <>{ctx.slots.save?.() ?? }} - {operationConfig.more?.show && <>{ctx.slots.more?.() ?? }} - {ctx.slots.operation?.()} -
- )} -
- ); - }, + return () => ( +
(isHover.value = true)} + onMouseleave={() => (isHover.value = false)}> + {ctx.slots.searchIcon?.() ?? ( +
+ +
+ )} +
+ +
+ {showExtendedConfig.value && ( +
+ {operationConfig.clear?.show && ( + <>{ctx.slots.clear?.() ?? } + )} + {operationConfig.save?.show && <>{ctx.slots.save?.() ?? }} + {operationConfig.more?.show && <>{ctx.slots.more?.() ?? }} + {ctx.slots.operation?.()} +
+ )} +
+ ); + }, }); diff --git a/packages/devui-vue/devui/checkbox/src/checkbox-types.ts b/packages/devui-vue/devui/checkbox/src/checkbox-types.ts index 2cfc384107..5768ccb7f5 100644 --- a/packages/devui-vue/devui/checkbox/src/checkbox-types.ts +++ b/packages/devui-vue/devui/checkbox/src/checkbox-types.ts @@ -37,7 +37,6 @@ const commonProps = { }, size: { type: String as PropType, - default: 'md', }, showGlowStyle: { type: Boolean, diff --git a/packages/devui-vue/devui/checkbox/src/use-checkbox.ts b/packages/devui-vue/devui/checkbox/src/use-checkbox.ts index 1e49c0824f..82b483d903 100644 --- a/packages/devui-vue/devui/checkbox/src/use-checkbox.ts +++ b/packages/devui-vue/devui/checkbox/src/use-checkbox.ts @@ -143,7 +143,7 @@ export function useCheckboxGroup(props: CheckboxGroupProps, ctx: SetupContext): ); // 组件 size 优先于表单 size - const checkboxGroupSize = computed(() => props.size || formContext?.size || ''); + const checkboxGroupSize = computed(() => props.size || formContext?.size || 'md'); provide(checkboxGroupInjectionKey, { disabled: toRef(props, 'disabled'), diff --git a/packages/devui-vue/devui/date-picker-pro/src/components/range-date-picker-pro.tsx b/packages/devui-vue/devui/date-picker-pro/src/components/range-date-picker-pro.tsx index bce48fd41c..398ed29ce2 100644 --- a/packages/devui-vue/devui/date-picker-pro/src/components/range-date-picker-pro.tsx +++ b/packages/devui-vue/devui/date-picker-pro/src/components/range-date-picker-pro.tsx @@ -19,7 +19,7 @@ export default defineComponent({ setup(props: RangeDatePickerProProps, ctx: SetupContext) { const app = getCurrentInstance(); const t = createI18nTranslate('DDatePickerPro', app); - const { showGlowStyle } = toRefs(props); + const { showGlowStyle, position } = toRefs(props); const ns = useNamespace('range-date-picker-pro'); const { @@ -44,7 +44,6 @@ export default defineComponent({ handlerClearTime, onChangeRangeFocusType, } = useRangePickerPro(props, ctx); - const position = ref(['bottom-start', 'top-start']); const currentPosition = ref('bottom'); const handlePositionChange = (pos: string) => { currentPosition.value = pos.split('-')[0] === 'top' ? 'top' : 'bottom'; @@ -53,6 +52,15 @@ export default defineComponent({ transformOrigin: currentPosition.value === 'top' ? '0% 100%' : '0% 0%', 'z-index': 'var(--devui-z-index-dropdown, 1052)', })); + const align = computed(() => { + if (position.value.some((item: string) => item.includes('start'))) { + return 'start'; + } + if (position.value.some((item: string) => item.includes('end'))) { + return 'end'; + } + return undefined; + }); return () => { const vSlots = { @@ -141,7 +149,7 @@ export default defineComponent({ v-model={isPanelShow.value} ref={overlayRef} origin={originRef.value} - align="start" + align={align.value} position={position.value} style={styles.value} onPositionChange={handlePositionChange}> diff --git a/packages/devui-vue/devui/date-picker-pro/src/date-picker-pro-types.ts b/packages/devui-vue/devui/date-picker-pro/src/date-picker-pro-types.ts index f83b1343f1..432db91109 100644 --- a/packages/devui-vue/devui/date-picker-pro/src/date-picker-pro-types.ts +++ b/packages/devui-vue/devui/date-picker-pro/src/date-picker-pro-types.ts @@ -3,6 +3,20 @@ import type { Dayjs } from 'dayjs'; import { ArrType } from '../../time-picker/src/types'; import type { InputSize } from '../../input/src/input-types'; +export type Placement = + | 'top' + | 'right' + | 'bottom' + | 'left' + | 'top-start' + | 'top-end' + | 'right-start' + | 'right-end' + | 'bottom-start' + | 'bottom-end' + | 'left-start' + | 'left-end'; + export const datePickerProCommonProps = { format: { type: String, @@ -34,6 +48,10 @@ export const datePickerProCommonProps = { type: Boolean, default: true, }, + position: { + type: Array as PropType, + default: () => ['bottom-start', 'top-start'], + }, }; export const datePickerProProps = { diff --git a/packages/devui-vue/devui/date-picker-pro/src/date-picker-pro.tsx b/packages/devui-vue/devui/date-picker-pro/src/date-picker-pro.tsx index 54ce7df432..b59f6bb530 100644 --- a/packages/devui-vue/devui/date-picker-pro/src/date-picker-pro.tsx +++ b/packages/devui-vue/devui/date-picker-pro/src/date-picker-pro.tsx @@ -3,7 +3,7 @@ import type { SetupContext } from 'vue'; import { datePickerProProps, DatePickerProProps } from './date-picker-pro-types'; import usePickerPro from './use-picker-pro'; import { Input } from '../../input'; -import { FlexibleOverlay, Placement } from '../../overlay'; +import { FlexibleOverlay } from '../../overlay'; import DatePickerProPanel from './components/date-picker-panel'; import { IconCalendar } from './components/icon-calendar'; import { IconClose } from './components/icon-close'; @@ -18,7 +18,7 @@ export default defineComponent({ setup(props: DatePickerProProps, ctx: SetupContext) { const app = getCurrentInstance(); const t = createI18nTranslate('DDatePickerPro', app); - const { showGlowStyle } = toRefs(props); + const { showGlowStyle, position } = toRefs(props); const ns = useNamespace('date-picker-pro'); const { @@ -39,7 +39,6 @@ export default defineComponent({ onSelectedDate, handlerClearTime, } = usePickerPro(props, ctx, t); - const position = ref(['bottom-start', 'top-start']); const currentPosition = ref('bottom'); const handlePositionChange = (pos: string) => { currentPosition.value = pos.split('-')[0] === 'top' ? 'top' : 'bottom'; @@ -48,6 +47,15 @@ export default defineComponent({ transformOrigin: currentPosition.value === 'top' ? '0% 100%' : '0% 0%', 'z-index': 'var(--devui-z-index-dropdown, 1052)', })); + const align = computed(() => { + if (position.value.some((item: string) => item.includes('start'))) { + return 'start'; + } + if (position.value.some((item: string) => item.includes('end'))) { + return 'end'; + } + return undefined; + }); return () => { const vSlots = { @@ -90,7 +98,7 @@ export default defineComponent({ v-model={isPanelShow.value} ref={overlayRef} origin={originRef.value} - align="start" + align={align.value} position={position.value} style={styles.value} onPositionChange={handlePositionChange}> diff --git a/packages/devui-vue/devui/menu/src/components/sub-menu/sub-menu.tsx b/packages/devui-vue/devui/menu/src/components/sub-menu/sub-menu.tsx index b4b8480f29..cfd0371c90 100644 --- a/packages/devui-vue/devui/menu/src/components/sub-menu/sub-menu.tsx +++ b/packages/devui-vue/devui/menu/src/components/sub-menu/sub-menu.tsx @@ -1,14 +1,6 @@ import { randomId } from '../../../../shared/utils/random-id'; import type { ComponentInternalInstance, Ref } from 'vue'; -import { - defineComponent, - getCurrentInstance, - inject, - onMounted, - ref, - watch, - watchEffect -} from 'vue'; +import { defineComponent, getCurrentInstance, inject, onMounted, ref, watch, watchEffect } from 'vue'; import { useNamespace } from '../../../../shared/hooks/use-namespace'; import { useClick } from '../../composables/use-click'; import { addLayer, clearSelect, getLayer, pushElement } from '../../composables/use-layer-operate'; @@ -16,6 +8,7 @@ import { useNearestMenuElement } from '../../composables/use-nearest-menu-elemen import MenuTransition from '../menu-transition/menu-transition'; import { SubMenuProps, subMenuProps } from './sub-menu-types'; import { useShowSubMenu } from './use-sub-menu'; +import { SelectArrowIcon } from '../../../../svg-icons'; const ns = useNamespace('menu'); const subNs = useNamespace('submenu'); @@ -31,7 +24,7 @@ export default defineComponent({ setup(props: SubMenuProps, ctx) { const isShow = ref(true); const { - vnode: { key } + vnode: { key }, } = getCurrentInstance() as ComponentInternalInstance; let key_ = String(key); const defaultOpenKeys = inject('openKeys') as Ref; @@ -63,7 +56,7 @@ export default defineComponent({ if (idx >= 0 && cur.tagName === 'UL') { defaultOpenKeys.value.splice(idx, 1); } else { - if (cur.tagName === 'UL'){ + if (cur.tagName === 'UL') { defaultOpenKeys.value.push(key_); } } @@ -72,7 +65,7 @@ export default defineComponent({ type: 'submenu-change', state: isOpen.value, key: key_, - el: ele + el: ele, }); } }; @@ -93,12 +86,13 @@ export default defineComponent({ watch( () => defaultOpenKeys, (n) => { - if (n.value.includes(key_)){ + if (n.value.includes(key_)) { isOpen.value = true; } else { isOpen.value = false; } - },{deep: true} + }, + { deep: true } ); onMounted(() => { const subMenuTitle = title.value as unknown as HTMLElement; @@ -142,18 +136,19 @@ export default defineComponent({ onClick={clickHandle} class={[subMenuClass, class_layer.value, props['disabled'] && `${subMenuClass}-disabled`]} ref={subMenu}> -
+
{ctx.slots?.icon?.()} {props.title} + @@ -162,8 +157,7 @@ export default defineComponent({
+ v-show={!props.disabled}> {ctx.slots.default?.()}
) : ( diff --git a/packages/devui-vue/devui/menu/src/styles/vertical.scss b/packages/devui-vue/devui/menu/src/styles/vertical.scss index 9d3886741c..0452369e28 100644 --- a/packages/devui-vue/devui/menu/src/styles/vertical.scss +++ b/packages/devui-vue/devui/menu/src/styles/vertical.scss @@ -6,8 +6,7 @@ } .#{$devui-prefix}-menu-vertical { padding: 0; - transition: - width $devui-animation-duration-slow $devui-animation-ease-in-smooth, + transition: width $devui-animation-duration-slow $devui-animation-ease-in-smooth, padding $devui-animation-duration-slow $devui-animation-ease-in-smooth; border-right: $devui-line 1px solid; @@ -48,6 +47,7 @@ .#{$devui-prefix}-menu-item-vertical-wrapper { padding-left: 0 !important; + margin: 4px 0 !important; } .#{$devui-prefix}-menu-item { @@ -108,7 +108,6 @@ cursor: pointer; width: 100%; height: 40px; - margin: 4px 0; line-height: 40px; padding-left: 18px; align-items: center; @@ -227,4 +226,18 @@ .#{$devui-prefix}-submenu-disabled::after { content: unset; } + + .#{$devui-prefix}-menu__arrow-icon { + width: 16px; + height: 16px; + transition: transform $devui-animation-duration-slow $devui-animation-ease-in-out-smooth; + + path { + fill: $devui-text-weak; + } + + &.is-opened { + transform: rotate(180deg); + } + } } diff --git a/packages/devui-vue/docs/components/category-search/index.md b/packages/devui-vue/docs/components/category-search/index.md index b793d8227b..2830a311e7 100644 --- a/packages/devui-vue/docs/components/category-search/index.md +++ b/packages/devui-vue/docs/components/category-search/index.md @@ -391,6 +391,7 @@ export default defineComponent({ | save | 自定义保存图标 | | | | more | 自定义更多图标 | | | | operation | 自定义除`clear`、`save`、`more`外的其他图标 | | [自定义扩展按钮](#自定义扩展按钮) | +| searchIcon | 自定义搜索图标 | | | ### CategorySearch 方法 diff --git a/packages/devui-vue/docs/components/date-picker-pro/index.md b/packages/devui-vue/docs/components/date-picker-pro/index.md index 8e9fc66c25..0ca1c47613 100644 --- a/packages/devui-vue/docs/components/date-picker-pro/index.md +++ b/packages/devui-vue/docs/components/date-picker-pro/index.md @@ -530,18 +530,19 @@ export default defineComponent({ ### DatePickerPro 参数 -| 参数名 | 类型 | 默认 | 说明 | 跳转 Demo | -| :------------- | :---------------- | :------------------------------------------------------- | :------------------------------------------------------- | :---------------------------------------------------- | -| v-model | `Date` | '' | 必选,选中项绑定的值 | [基本用法](#基本用法) | -| format | [Format](#format) | 'YYYY/MM/DD' \| 'YYYY/MM/DD HH:mm:ss' | 可选,绑定值的日期格式,根据是否 showTime 区别不同默认值 | [日期格式](#日期格式) | -| placeholder | `string` | '请选择日期' | 可选,输入框的 placeholder | [基本用法](#基本用法) | -| showTime | `boolean` | false | 可选,是否显示时分秒 | [显示时间](#显示时间) | -| size | `string` | 'md' | 可选,输入框的尺寸 | [基本用法](#基本用法) | -| disabled | `boolean` | false | 可选,是否禁用选择器 | [禁用选择器](#禁用选择器) | -| calendarRange | `[number,number]` | [1970, 2099] | 可选,设置日历面板显示时间范围 | [设置日历面板可选时间范围](#设置日历面板可选时间范围) | -| limitDateRange | `[Date,Date]` | [new Date(calendarRange[0]), new Date(calendarRange[1])] | 可选,设置日历面板可选时间范围 | [设置日历面板可选时间范围](#设置日历面板可选时间范围) | -| type | `string` | 'date' | 可选,设置日期选择器类型(date/year/month) | [年月选择器](#年月选择器) | -|show-glow-style|`boolean`|true|可选,是否显示悬浮发光效果|| +| 参数名 | 类型 | 默认 | 说明 | 跳转 Demo | +| :-------------- | :---------------------- | :------------------------------------------------------- | :------------------------------------------------------- | :---------------------------------------------------- | +| v-model | `Date` | '' | 必选,选中项绑定的值 | [基本用法](#基本用法) | +| format | [Format](#format) | 'YYYY/MM/DD' \| 'YYYY/MM/DD HH:mm:ss' | 可选,绑定值的日期格式,根据是否 showTime 区别不同默认值 | [日期格式](#日期格式) | +| placeholder | `string` | '请选择日期' | 可选,输入框的 placeholder | [基本用法](#基本用法) | +| showTime | `boolean` | false | 可选,是否显示时分秒 | [显示时间](#显示时间) | +| size | `string` | 'md' | 可选,输入框的尺寸 | [基本用法](#基本用法) | +| disabled | `boolean` | false | 可选,是否禁用选择器 | [禁用选择器](#禁用选择器) | +| calendarRange | `[number,number]` | [1970, 2099] | 可选,设置日历面板显示时间范围 | [设置日历面板可选时间范围](#设置日历面板可选时间范围) | +| limitDateRange | `[Date,Date]` | [new Date(calendarRange[0]), new Date(calendarRange[1])] | 可选,设置日历面板可选时间范围 | [设置日历面板可选时间范围](#设置日历面板可选时间范围) | +| type | `string` | 'date' | 可选,设置日期选择器类型(date/year/month) | [年月选择器](#年月选择器) | +| show-glow-style | `boolean` | true | 可选,是否显示悬浮发光效果 | | +| position | [Placement[]](#placement) | ['bottom-start','top-start'] | 可选,自定义下拉面板位置 | | ### DatePickerPro 事件 @@ -589,19 +590,20 @@ type Format = string; ### RangeDatePickerPro 参数 -| 参数名 | 类型 | 默认 | 说明 | 跳转 Demo | -| :------------- | :---------------- | :------------------------------------------------------- | :------------------------------------------------------- | :---------------------------------------------------- | -| v-model | `[Date, Date]` | ['',''] | 必选,选中项绑定的值 | [范围选择器](#范围选择器) | -| format | [Format](#format) | 'YYYY/MM/DD' \| 'YYYY/MM/DD HH:mm:ss' | 可选,绑定值的日期格式,根据是否 showTime 区别不同默认值 | [日期格式](#日期格式) | -| placeholder | `Array` | ['请选择开始日期', '请选择结束日期'] | 可选,输入框的 placeholder | [范围选择器](#范围选择器) | -| showTime | `boolean` | false | 可选,是否显示时分秒 | [范围选择器](#范围选择器) | -| separator | `string` | '-' | 可选,范围选择器的分割符 | [范围选择器](#范围选择器) | -| size | `string` | 'md' | 可选,输入框的尺寸 | | -| disabled | `boolean` | false | 可选,是否禁用选择器 | [禁用选择器](#禁用选择器) | -| calendarRange | `[number,number]` | [1970,2099] | 可选,设置日历面板显示时间范围 | [设置日历面板可选时间范围](#设置日历面板可选时间范围) | -| limitDateRange | `[Date,Date]` | [new Date(calendarRange[0]), new Date(calendarRange[1])] | 可选,设置日历面板可选时间范围 | [设置日历面板可选时间范围](#设置日历面板可选时间范围) | -| type | `string` | 'date' | 可选,设置日期选择器类型(date/year/month) | [范围选择器](#范围选择器) | -|show-glow-style|`boolean`|true|可选,是否显示悬浮发光效果|| +| 参数名 | 类型 | 默认 | 说明 | 跳转 Demo | +| :-------------- | :---------------- | :------------------------------------------------------- | :------------------------------------------------------- | :---------------------------------------------------- | +| v-model | `[Date, Date]` | ['',''] | 必选,选中项绑定的值 | [范围选择器](#范围选择器) | +| format | [Format](#format) | 'YYYY/MM/DD' \| 'YYYY/MM/DD HH:mm:ss' | 可选,绑定值的日期格式,根据是否 showTime 区别不同默认值 | [日期格式](#日期格式) | +| placeholder | `Array` | ['请选择开始日期', '请选择结束日期'] | 可选,输入框的 placeholder | [范围选择器](#范围选择器) | +| showTime | `boolean` | false | 可选,是否显示时分秒 | [范围选择器](#范围选择器) | +| separator | `string` | '-' | 可选,范围选择器的分割符 | [范围选择器](#范围选择器) | +| size | `string` | 'md' | 可选,输入框的尺寸 | | +| disabled | `boolean` | false | 可选,是否禁用选择器 | [禁用选择器](#禁用选择器) | +| calendarRange | `[number,number]` | [1970,2099] | 可选,设置日历面板显示时间范围 | [设置日历面板可选时间范围](#设置日历面板可选时间范围) | +| limitDateRange | `[Date,Date]` | [new Date(calendarRange[0]), new Date(calendarRange[1])] | 可选,设置日历面板可选时间范围 | [设置日历面板可选时间范围](#设置日历面板可选时间范围) | +| type | `string` | 'date' | 可选,设置日期选择器类型(date/year/month) | [范围选择器](#范围选择器) | +| show-glow-style | `boolean` | true | 可选,是否显示悬浮发光效果 | | +| position | [Placement[]](#placement) | ['bottom-start','top-start'] | 可选,自定义下拉面板位置 | | ### RangeDatePickerPro 事件 @@ -618,3 +620,23 @@ type Format = string; | :-------- | :---------------------------------------------------------------- | :------------------------------------------------ | | rightArea | 自定义 RangeDatePickerPro 日历面板右侧内容, 如:日期范围快捷选项 | [自定义日期范围面板区域](#自定义日期范围面板区域) | | footer | 自定义 RangeDatePickerPro 日历面板下侧内容 | [自定义日期范围面板区域](#自定义日期范围面板区域) | + +### 类型定义 + +#### Placement + +```ts +type Placement = + | 'top' + | 'right' + | 'bottom' + | 'left' + | 'top-start' + | 'top-end' + | 'right-start' + | 'right-end' + | 'bottom-start' + | 'bottom-end' + | 'left-start' + | 'left-end'; +``` diff --git a/packages/devui-vue/package.json b/packages/devui-vue/package.json index 7332cc4771..09d6746b06 100644 --- a/packages/devui-vue/package.json +++ b/packages/devui-vue/package.json @@ -1,6 +1,6 @@ { "name": "vue-devui", - "version": "1.6.10", + "version": "1.6.11", "license": "MIT", "description": "DevUI components based on Vite and Vue3", "keywords": [