diff --git a/packages/devui-vue/devui/auto-complete/src/auto-complete-types.ts b/packages/devui-vue/devui/auto-complete/src/auto-complete-types.ts index 2c505a5e0e..968904ad7f 100644 --- a/packages/devui-vue/devui/auto-complete/src/auto-complete-types.ts +++ b/packages/devui-vue/devui/auto-complete/src/auto-complete-types.ts @@ -48,7 +48,7 @@ export const autoCompleteProps = { }, position: { type: Array as PropType>, - default: ['bottom-end'], + default: () => ['bottom', 'top', 'left', 'right'], }, disabled: { type: Boolean, diff --git a/packages/devui-vue/devui/auto-complete/src/auto-complete.tsx b/packages/devui-vue/devui/auto-complete/src/auto-complete.tsx index 83b143d231..c72f1ca31e 100644 --- a/packages/devui-vue/devui/auto-complete/src/auto-complete.tsx +++ b/packages/devui-vue/devui/auto-complete/src/auto-complete.tsx @@ -44,7 +44,6 @@ export default defineComponent({ const inputNs = useNamespace('auto-complete-input'); const isDisabled = computed(() => formContext?.disabled || disabled.value); const autoCompleteSize = computed(() => formContext?.size || props.size); - const align = computed(() => (position.value.some((item) => item.includes('start') || item.includes('end')) ? 'start' : null)); const { handleSearch, searchList, showNoResultItemTemplate, recentlyFocus } = useSearchFn( ctx, @@ -126,7 +125,6 @@ export default defineComponent({ diff --git a/packages/devui-vue/devui/cascader/src/cascader.tsx b/packages/devui-vue/devui/cascader/src/cascader.tsx index 7d0b2363ef..9992a17029 100644 --- a/packages/devui-vue/devui/cascader/src/cascader.tsx +++ b/packages/devui-vue/devui/cascader/src/cascader.tsx @@ -97,7 +97,6 @@ export default defineComponent({ ref={overlayRef} v-model={menuShow.value} position={position.value as Placement[]} - align="start" style={styles.value} onPositionChange={handlePositionChange}>
diff --git a/packages/devui-vue/devui/category-search/src/components/category-search-tag.tsx b/packages/devui-vue/devui/category-search/src/components/category-search-tag.tsx index 9c95a0b5f9..29cd0eea81 100644 --- a/packages/devui-vue/devui/category-search/src/components/category-search-tag.tsx +++ b/packages/devui-vue/devui/category-search/src/components/category-search-tag.tsx @@ -20,7 +20,7 @@ export default defineComponent({ rootCtx.slots[`${item.value.field}Tag`]!({ tag: item.value }) ) : isJoinLabelType.value ? ( <> - {item.value.label} + {item.value.label}: {Array.isArray(item.value.value?.cache) && item.value.value?.cache?.map((tag: any, index: number) => ( 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 398ed29ce2..89fa999aab 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 @@ -52,15 +52,6 @@ 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 = { @@ -149,7 +140,6 @@ export default defineComponent({ v-model={isPanelShow.value} ref={overlayRef} origin={originRef.value} - 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 432db91109..c1af2c2b0f 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 @@ -50,7 +50,7 @@ export const datePickerProCommonProps = { }, position: { type: Array as PropType, - default: () => ['bottom-start', 'top-start'], + default: () => ['bottom-start', 'top-start', 'left-start', 'right-start'], }, }; 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 b59f6bb530..922257530c 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 @@ -47,15 +47,6 @@ 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 = { @@ -98,7 +89,6 @@ export default defineComponent({ v-model={isPanelShow.value} ref={overlayRef} origin={originRef.value} - align={align.value} position={position.value} style={styles.value} onPositionChange={handlePositionChange}> diff --git a/packages/devui-vue/devui/dropdown/src/dropdown-types.ts b/packages/devui-vue/devui/dropdown/src/dropdown-types.ts index ccfc8fe3a6..7922b2dd1b 100644 --- a/packages/devui-vue/devui/dropdown/src/dropdown-types.ts +++ b/packages/devui-vue/devui/dropdown/src/dropdown-types.ts @@ -15,7 +15,6 @@ export type Placement = | 'bottom-end' | 'left-start' | 'left-end'; -export type Alignment = 'start' | 'end'; export type OffsetOptions = { mainAxis?: number; crossAxis?: number }; export type EmitEvent = (event: 'toggle', result: boolean) => void; @@ -35,11 +34,7 @@ export const dropdownProps = { }, position: { type: Array as PropType>, - default: ['bottom'], - }, - align: { - type: String as PropType | null, - default: null, + default: () => ['bottom', 'top', 'left', 'right'], }, offset: { type: [Number, Object] as PropType, diff --git a/packages/devui-vue/devui/dropdown/src/dropdown.tsx b/packages/devui-vue/devui/dropdown/src/dropdown.tsx index 2b13ec3a2b..5e91499467 100644 --- a/packages/devui-vue/devui/dropdown/src/dropdown.tsx +++ b/packages/devui-vue/devui/dropdown/src/dropdown.tsx @@ -15,7 +15,7 @@ export default defineComponent({ props: dropdownProps, emits: ['toggle'], setup(props: DropdownProps, { slots, attrs, emit, expose }) { - const { visible, position, align, offset, destroyOnHide, shiftOffset, showAnimation, teleport } = toRefs(props); + const { visible, position, offset, destroyOnHide, shiftOffset, showAnimation, teleport } = toRefs(props); const origin = ref(); const dropdownRef = ref(); const overlayRef = ref(); @@ -59,7 +59,6 @@ export default defineComponent({ ref={overlayRef} origin={origin.value} position={position.value} - align={align.value} offset={offset.value} shiftOffset={shiftOffset?.value} onPositionChange={handlePositionChange} diff --git a/packages/devui-vue/devui/editable-select/src/editable-select-types.ts b/packages/devui-vue/devui/editable-select/src/editable-select-types.ts index 22332314a7..ca5b50e98d 100644 --- a/packages/devui-vue/devui/editable-select/src/editable-select-types.ts +++ b/packages/devui-vue/devui/editable-select/src/editable-select-types.ts @@ -34,7 +34,7 @@ export const editableSelectProps = { }, position: { type: Array as PropType, - default: ['bottom'], + default: () => ['bottom', 'top', 'left', 'right'], }, options: { type: Array as PropType, diff --git a/packages/devui-vue/devui/editable-select/src/editable-select.tsx b/packages/devui-vue/devui/editable-select/src/editable-select.tsx index 68898e5927..cd0452c024 100644 --- a/packages/devui-vue/devui/editable-select/src/editable-select.tsx +++ b/packages/devui-vue/devui/editable-select/src/editable-select.tsx @@ -35,7 +35,6 @@ export default defineComponent({ const states = useSelectStates(); // data refs const { appendToBody, disabled, modelValue, position, placeholder, maxLength } = toRefs(props); - const align = computed(() => (position.value.some((item) => item.includes('start') || item.includes('end')) ? 'start' : null)); // input事件 const { onInput, onMouseenter, onMouseleave, setSoftFocus, handleBlur, handleFocus, handleClear } = useInputEvent( @@ -101,7 +100,6 @@ export default defineComponent({ v-model={states.visible} origin={originRef.value} position={position.value} - align={align.value} style={styles.value} onPositionChange={handlePositionChange}> diff --git a/packages/devui-vue/devui/form/src/components/form-item/form-item-types.ts b/packages/devui-vue/devui/form/src/components/form-item/form-item-types.ts index 856e2d422e..e6aa9d9390 100644 --- a/packages/devui-vue/devui/form/src/components/form-item/form-item-types.ts +++ b/packages/devui-vue/devui/form/src/components/form-item/form-item-types.ts @@ -1,6 +1,6 @@ import type { RuleItem, ValidateFieldsError } from 'async-validator'; -import type { ComputedRef, ExtractPropTypes, PropType, InjectionKey, Ref, SetupContext } from 'vue'; -import { LabelAlign, LabelSize, Layout } from '../../form-types'; +import type { ComputedRef, ExtractPropTypes, PropType, Ref, SetupContext } from 'vue'; +import { LabelAlign, LabelSize, Layout, RequirePosition } from '../../form-types'; import { FeedbackStatus } from '../form-control/form-control-types'; export type FormItemValidateState = '' | 'error' | 'pending' | 'success'; @@ -81,6 +81,7 @@ export type LabelData = ComputedRef<{ layout: Layout; labelSize: LabelSize; labelAlign: LabelAlign; + requiredPosition: RequirePosition; helpTips: string | HelpTips; formItemCtx: SetupContext; }>; diff --git a/packages/devui-vue/devui/form/src/components/form-item/form-item.tsx b/packages/devui-vue/devui/form/src/components/form-item/form-item.tsx index d31610c23d..959ed30992 100644 --- a/packages/devui-vue/devui/form/src/components/form-item/form-item.tsx +++ b/packages/devui-vue/devui/form/src/components/form-item/form-item.tsx @@ -24,6 +24,7 @@ export default defineComponent({ layout: formContext.layout, labelSize: formContext.labelSize, labelAlign: formContext.labelAlign, + requiredPosition: formContext.requirePosition, helpTips: helpTips.value, formItemCtx: ctx, })); diff --git a/packages/devui-vue/devui/form/src/components/form-label/form-label.scss b/packages/devui-vue/devui/form/src/components/form-label/form-label.scss index 413c97ef3c..2f465205bd 100644 --- a/packages/devui-vue/devui/form/src/components/form-label/form-label.scss +++ b/packages/devui-vue/devui/form/src/components/form-label/form-label.scss @@ -47,11 +47,21 @@ margin-right: 8px; margin-left: -12px; } +} + +.#{$devui-prefix}-form__label--required-right { + &::after { + content: '*'; + color: red; + display: inline-block; + margin-left: 8px; + } +} - &-hide { - &::before { - display: none; - } +.#{$devui-prefix}-form__label--required-hide { + &::before, + &::after { + display: none; } } diff --git a/packages/devui-vue/devui/form/src/components/form-label/use-form-label.ts b/packages/devui-vue/devui/form/src/components/form-label/use-form-label.ts index fa9a45f08f..ecc5782d26 100644 --- a/packages/devui-vue/devui/form/src/components/form-label/use-form-label.ts +++ b/packages/devui-vue/devui/form/src/components/form-label/use-form-label.ts @@ -25,7 +25,8 @@ export function useFormLabel() { const labelInnerClasses = computed(() => ({ [`${ns.e('label-span')}`]: true, - [`${ns.em('label', 'required')}`]: formItemContext.isRequired, + [`${ns.em('label', 'required')}`]: formItemContext.isRequired && labelData.value.requiredPosition === 'left', + [`${ns.em('label', 'required-right')}`]: formItemContext.isRequired && labelData.value.requiredPosition === 'right', [`${ns.em('label', 'required-hide')}`]: formItemContext.isRequired && formContext.hideRequiredMark, })); diff --git a/packages/devui-vue/devui/form/src/form-types.ts b/packages/devui-vue/devui/form/src/form-types.ts index 5e87bd5de7..e048378425 100644 --- a/packages/devui-vue/devui/form/src/form-types.ts +++ b/packages/devui-vue/devui/form/src/form-types.ts @@ -16,6 +16,7 @@ export type LabelAlign = 'start' | 'center' | 'end'; export type FormData = Record; export type StyleType = 'default' | 'gray'; export type AppendToBodyScrollStrategy = 'close' | 'reposition'; +export type RequirePosition = 'left' | 'right'; export type FormRules = Partial>>; export interface ValidateFailure { @@ -78,6 +79,10 @@ export const formProps = { type: String as PropType, default: 'reposition', }, + requirePosition: { + type: String as PropType, + default: 'left', + }, } as const; export interface UseFieldCollection { diff --git a/packages/devui-vue/devui/pagination/src/pagination-types.ts b/packages/devui-vue/devui/pagination/src/pagination-types.ts index a906bec74c..cc130a7751 100644 --- a/packages/devui-vue/devui/pagination/src/pagination-types.ts +++ b/packages/devui-vue/devui/pagination/src/pagination-types.ts @@ -19,7 +19,7 @@ export const paginationProps = { }, pageSizeDirection: { type: Array as PropType>, - default: () => ['bottom', 'top'], + default: () => ['bottom', 'top', 'left', 'bottom'], }, pageIndex: { type: Number, diff --git a/packages/devui-vue/devui/popover/src/popover-types.ts b/packages/devui-vue/devui/popover/src/popover-types.ts index 21742bb6ff..81b4a70203 100644 --- a/packages/devui-vue/devui/popover/src/popover-types.ts +++ b/packages/devui-vue/devui/popover/src/popover-types.ts @@ -15,7 +15,6 @@ export type Placement = | 'bottom-end' | 'left-start' | 'left-end'; -export type Alignment = 'start' | 'end'; export type OffsetOptions = { mainAxis?: number; crossAxis?: number }; export const popoverProps = { @@ -25,11 +24,7 @@ export const popoverProps = { }, position: { type: Array as PropType>, - default: ['bottom'], - }, - align: { - type: String as PropType | null, - default: null, + default: () => ['top', 'right', 'bottom', 'left'], }, offset: { type: [Number, Object] as PropType, diff --git a/packages/devui-vue/devui/popover/src/popover.tsx b/packages/devui-vue/devui/popover/src/popover.tsx index 9298fed7a5..c6a016b99a 100644 --- a/packages/devui-vue/devui/popover/src/popover.tsx +++ b/packages/devui-vue/devui/popover/src/popover.tsx @@ -14,7 +14,7 @@ export default defineComponent({ props: popoverProps, emits: ['show', 'hide'], setup(props: PopoverProps, { slots, attrs, emit }) { - const { content, popType, position, align, offset, showAnimation } = toRefs(props); + const { content, popType, position, offset, showAnimation } = toRefs(props); const origin = ref(); const popoverRef = ref(); const visible = ref(false); @@ -40,7 +40,6 @@ export default defineComponent({ ref={popoverRef} origin={origin.value} position={position.value} - align={align.value} offset={offset.value} class={[ns.e('content'), popType.value !== 'default' ? 'is-icon' : '']} show-arrow diff --git a/packages/devui-vue/devui/popover/src/use-popover.ts b/packages/devui-vue/devui/popover/src/use-popover.ts index 29dd88567a..16face2c76 100644 --- a/packages/devui-vue/devui/popover/src/use-popover.ts +++ b/packages/devui-vue/devui/popover/src/use-popover.ts @@ -50,6 +50,7 @@ export function usePopover( export function usePopoverEvent(props: PopoverProps, visible: Ref, origin: Ref): UsePopoverEvent { const { trigger, position, mouseEnterDelay, mouseLeaveDelay, disabled } = toRefs(props); const isClick: ComputedRef = computed(() => trigger.value === 'click'); + const isHover: ComputedRef = computed(() => trigger.value === 'hover'); const placement: Ref = ref(position.value[0].split('-')[0]); const isEnter: Ref = ref(false); @@ -69,13 +70,13 @@ export function usePopoverEvent(props: PopoverProps, visible: Ref, orig if (disabled.value) { return; } - if (!isClick.value) { + if (isHover.value) { isEnter.value = true; enter(); } }; const onMouseleave = () => { - if (!isClick.value) { + if (isHover.value) { isEnter.value = false; leave(); } diff --git a/packages/devui-vue/devui/select/src/select-types.ts b/packages/devui-vue/devui/select/src/select-types.ts index ad1f19d84f..eb96318b8a 100644 --- a/packages/devui-vue/devui/select/src/select-types.ts +++ b/packages/devui-vue/devui/select/src/select-types.ts @@ -13,6 +13,19 @@ export type Options = Array; export type ModelValue = number | string | Array; export type filterValue = boolean | ((query: string) => void); export type SelectSize = 'sm' | 'md' | 'lg'; +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 selectProps = { modelValue: { type: [String, Number, Array] as PropType, @@ -26,6 +39,10 @@ export const selectProps = { type: Array as PropType, default: () => [], }, + position: { + type: Array as PropType, + default: () => ['bottom', 'top', 'left', 'right'], + }, size: { type: String as PropType, default: '', diff --git a/packages/devui-vue/devui/select/src/select.tsx b/packages/devui-vue/devui/select/src/select.tsx index 8d720d9ad9..aacfa8be38 100644 --- a/packages/devui-vue/devui/select/src/select.tsx +++ b/packages/devui-vue/devui/select/src/select.tsx @@ -24,7 +24,7 @@ import SelectContent from './components/select-content'; import useSelectFunction from './composables/use-select-function'; import './select.scss'; import { createI18nTranslate } from '../../locale/create'; -import { FlexibleOverlay, Placement } from '../../overlay'; +import { FlexibleOverlay } from '../../overlay'; import LoadingDirective from '../../loading/src/loading-directive'; export default defineComponent({ @@ -77,7 +77,6 @@ export default defineComponent({ ctx.expose({ focus, blur, toggleChange }); const isRender = ref(false); const currentPosition = ref('bottom'); - const position = ref(['bottom-start', 'top-start']); const handlePositionChange = (pos: string) => { currentPosition.value = pos.split('-')[0] === 'top' ? 'top' : 'bottom'; @@ -141,10 +140,9 @@ export default defineComponent({ v-model={isRender.value} ref={dropdownRef} origin={originRef.value} - align="start" offset={4} fit-origin-width - position={position.value} + position={props.position} onPositionChange={handlePositionChange} style={styles.value} class={props.menuClass}> diff --git a/packages/devui-vue/devui/time-picker/src/time-picker-types.ts b/packages/devui-vue/devui/time-picker/src/time-picker-types.ts index af02dccacc..af3f96ef10 100644 --- a/packages/devui-vue/devui/time-picker/src/time-picker-types.ts +++ b/packages/devui-vue/devui/time-picker/src/time-picker-types.ts @@ -1,6 +1,20 @@ import { ExtractPropTypes, PropType } from 'vue'; import { sizeType } from './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 timePickerProps = { modelValue: { type: String, @@ -50,6 +64,10 @@ export const timePickerProps = { type: Boolean, default: true, }, + position: { + type: Array as PropType, + default: () => ['bottom', 'top', 'left', 'right'], + }, } as const; export type TimePickerProps = ExtractPropTypes; diff --git a/packages/devui-vue/devui/time-picker/src/time-picker.tsx b/packages/devui-vue/devui/time-picker/src/time-picker.tsx index b9d6e4a1a5..40cecb64e9 100644 --- a/packages/devui-vue/devui/time-picker/src/time-picker.tsx +++ b/packages/devui-vue/devui/time-picker/src/time-picker.tsx @@ -4,7 +4,7 @@ import { Icon } from '../../icon'; import useTimePicker from './composables/use-time-picker'; import TimePopup from './components/time-popup/index'; import DInput from '../../input/src/input'; -import { FlexibleOverlay, Placement } from '../../overlay'; +import { FlexibleOverlay } from '../../overlay'; import { useNamespace } from '@devui/shared/utils'; import './time-picker.scss'; @@ -20,7 +20,6 @@ export default defineComponent({ const activeMinute = ref('00'); const activeSecond = ref('00'); const format = props.format.toLowerCase(); - const position = ref(['bottom-start', 'top-start']); const currentPosition = ref('bottom'); const handlePositionChange = (pos: string) => { currentPosition.value = pos.split('-')[0] === 'top' ? 'top' : 'bottom'; @@ -94,8 +93,7 @@ export default defineComponent({ v-model={showPopup.value} ref={overlayRef} origin={inputDom.value?.$el} - position={position.value as Placement[]} - align="start" + position={props.position} style={styles.value} onPositionChange={handlePositionChange}> >, - default: 'top', - }, - align: { - type: String as PropType | null, - default: null, + default: () => ['top', 'right', 'bottom', 'left'], }, showAnimation: { type: Boolean, diff --git a/packages/devui-vue/devui/tooltip/src/tooltip.tsx b/packages/devui-vue/devui/tooltip/src/tooltip.tsx index add7287d26..d00bc200d7 100644 --- a/packages/devui-vue/devui/tooltip/src/tooltip.tsx +++ b/packages/devui-vue/devui/tooltip/src/tooltip.tsx @@ -11,7 +11,7 @@ export default defineComponent({ name: 'DTooltip', props: tooltipProps, setup(props: TooltipProps, { slots }) { - const { showAnimation, content, align, overlayClass, teleport } = toRefs(props); + const { showAnimation, content, overlayClass, teleport } = toRefs(props); const origin = ref(); const tooltipRef = ref(); const { visible, placement, positionArr, overlayStyles, onPositionChange, onMouseleave, onMouseenterOverlay } = useTooltip( @@ -38,7 +38,6 @@ export default defineComponent({ class={className.value} origin={origin.value} position={positionArr.value} - align={align.value} offset={6} show-arrow style={overlayStyles.value} diff --git a/packages/devui-vue/docs/components/form/index.md b/packages/devui-vue/docs/components/form/index.md index fcc57064b9..4df15edd0b 100644 --- a/packages/devui-vue/docs/components/form/index.md +++ b/packages/devui-vue/docs/components/form/index.md @@ -666,6 +666,7 @@ export default defineComponent({ | hide-required-mark | `boolean` | false | 可选,是否隐藏所有表单项的必选标记 | | | style-type | [StyleType](#styletype) | 'default' | 可选,设置表单为灰色表单 | | | append-to-body-scroll-strategy | [AppendToBodyScrollStrategy](#appendtobodyscrollstrategy) | 'reposition' | 可选,消息显示为 popover 时,滚动时 popover 处理策略,默认策略跟随宿主移动;`close`为滚动时关闭 | | +|require-position|`string`|'left'|可选,必填型号的位置,可选值为`left`和`right`|| ### Form 事件 diff --git a/packages/devui-vue/package.json b/packages/devui-vue/package.json index 25094b39ca..284193003c 100644 --- a/packages/devui-vue/package.json +++ b/packages/devui-vue/package.json @@ -1,6 +1,6 @@ { "name": "vue-devui", - "version": "1.6.17", + "version": "1.6.18", "license": "MIT", "description": "DevUI components based on Vite and Vue3", "keywords": [