Skip to content

Commit 231b8b3

Browse files
authored
修复表单、分类搜索、Popover组件问题,弹出类组件自动识别方向
1 parent 45052b2 commit 231b8b3

File tree

28 files changed

+80
-72
lines changed

28 files changed

+80
-72
lines changed

packages/devui-vue/devui/auto-complete/src/auto-complete-types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ export const autoCompleteProps = {
4848
},
4949
position: {
5050
type: Array as PropType<Array<Placement>>,
51-
default: ['bottom-end'],
51+
default: () => ['bottom', 'top', 'left', 'right'],
5252
},
5353
disabled: {
5454
type: Boolean,

packages/devui-vue/devui/auto-complete/src/auto-complete.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ export default defineComponent({
4444
const inputNs = useNamespace('auto-complete-input');
4545
const isDisabled = computed(() => formContext?.disabled || disabled.value);
4646
const autoCompleteSize = computed(() => formContext?.size || props.size);
47-
const align = computed(() => (position.value.some((item) => item.includes('start') || item.includes('end')) ? 'start' : null));
4847

4948
const { handleSearch, searchList, showNoResultItemTemplate, recentlyFocus } = useSearchFn(
5049
ctx,
@@ -126,7 +125,6 @@ export default defineComponent({
126125
<FlexibleOverlay
127126
origin={origin.value}
128127
position={position.value}
129-
align={align.value}
130128
v-model={visible.value}
131129
onPositionChange={handlePositionChange}
132130
style={overlayStyles.value}>

packages/devui-vue/devui/cascader/src/cascader.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ export default defineComponent({
9797
ref={overlayRef}
9898
v-model={menuShow.value}
9999
position={position.value as Placement[]}
100-
align="start"
101100
style={styles.value}
102101
onPositionChange={handlePositionChange}>
103102
<div class={ns.e('drop-menu-animation')}>

packages/devui-vue/devui/category-search/src/components/category-search-tag.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export default defineComponent({
2020
rootCtx.slots[`${item.value.field}Tag`]!({ tag: item.value })
2121
) : isJoinLabelType.value ? (
2222
<>
23-
<span>{item.value.label}</span>
23+
<span>{item.value.label}: </span>
2424
<span class='dp-category-search-multi-tag' style={{ maxWidth: tagMaxWidth?.value + 'px' }}>
2525
{Array.isArray(item.value.value?.cache) &&
2626
item.value.value?.cache?.map((tag: any, index: number) => (

packages/devui-vue/devui/date-picker-pro/src/components/range-date-picker-pro.tsx

-10
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,6 @@ export default defineComponent({
5252
transformOrigin: currentPosition.value === 'top' ? '0% 100%' : '0% 0%',
5353
'z-index': 'var(--devui-z-index-dropdown, 1052)',
5454
}));
55-
const align = computed(() => {
56-
if (position.value.some((item: string) => item.includes('start'))) {
57-
return 'start';
58-
}
59-
if (position.value.some((item: string) => item.includes('end'))) {
60-
return 'end';
61-
}
62-
return undefined;
63-
});
6455

6556
return () => {
6657
const vSlots = {
@@ -149,7 +140,6 @@ export default defineComponent({
149140
v-model={isPanelShow.value}
150141
ref={overlayRef}
151142
origin={originRef.value}
152-
align={align.value}
153143
position={position.value}
154144
style={styles.value}
155145
onPositionChange={handlePositionChange}>

packages/devui-vue/devui/date-picker-pro/src/date-picker-pro-types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ export const datePickerProCommonProps = {
5050
},
5151
position: {
5252
type: Array as PropType<Placement[]>,
53-
default: () => ['bottom-start', 'top-start'],
53+
default: () => ['bottom-start', 'top-start', 'left-start', 'right-start'],
5454
},
5555
};
5656

packages/devui-vue/devui/date-picker-pro/src/date-picker-pro.tsx

-10
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,6 @@ export default defineComponent({
4747
transformOrigin: currentPosition.value === 'top' ? '0% 100%' : '0% 0%',
4848
'z-index': 'var(--devui-z-index-dropdown, 1052)',
4949
}));
50-
const align = computed(() => {
51-
if (position.value.some((item: string) => item.includes('start'))) {
52-
return 'start';
53-
}
54-
if (position.value.some((item: string) => item.includes('end'))) {
55-
return 'end';
56-
}
57-
return undefined;
58-
});
5950

6051
return () => {
6152
const vSlots = {
@@ -98,7 +89,6 @@ export default defineComponent({
9889
v-model={isPanelShow.value}
9990
ref={overlayRef}
10091
origin={originRef.value}
101-
align={align.value}
10292
position={position.value}
10393
style={styles.value}
10494
onPositionChange={handlePositionChange}>

packages/devui-vue/devui/dropdown/src/dropdown-types.ts

+1-6
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ export type Placement =
1515
| 'bottom-end'
1616
| 'left-start'
1717
| 'left-end';
18-
export type Alignment = 'start' | 'end';
1918
export type OffsetOptions = { mainAxis?: number; crossAxis?: number };
2019

2120
export type EmitEvent = (event: 'toggle', result: boolean) => void;
@@ -35,11 +34,7 @@ export const dropdownProps = {
3534
},
3635
position: {
3736
type: Array as PropType<Array<Placement>>,
38-
default: ['bottom'],
39-
},
40-
align: {
41-
type: String as PropType<Alignment> | null,
42-
default: null,
37+
default: () => ['bottom', 'top', 'left', 'right'],
4338
},
4439
offset: {
4540
type: [Number, Object] as PropType<number | OffsetOptions>,

packages/devui-vue/devui/dropdown/src/dropdown.tsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export default defineComponent({
1515
props: dropdownProps,
1616
emits: ['toggle'],
1717
setup(props: DropdownProps, { slots, attrs, emit, expose }) {
18-
const { visible, position, align, offset, destroyOnHide, shiftOffset, showAnimation, teleport } = toRefs(props);
18+
const { visible, position, offset, destroyOnHide, shiftOffset, showAnimation, teleport } = toRefs(props);
1919
const origin = ref<HTMLElement | undefined>();
2020
const dropdownRef = ref<HTMLElement | undefined>();
2121
const overlayRef = ref();
@@ -59,7 +59,6 @@ export default defineComponent({
5959
ref={overlayRef}
6060
origin={origin.value}
6161
position={position.value}
62-
align={align.value}
6362
offset={offset.value}
6463
shiftOffset={shiftOffset?.value}
6564
onPositionChange={handlePositionChange}

packages/devui-vue/devui/editable-select/src/editable-select-types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export const editableSelectProps = {
3434
},
3535
position: {
3636
type: Array as PropType<Placement[]>,
37-
default: ['bottom'],
37+
default: () => ['bottom', 'top', 'left', 'right'],
3838
},
3939
options: {
4040
type: Array as PropType<Options>,

packages/devui-vue/devui/editable-select/src/editable-select.tsx

-2
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ export default defineComponent({
3535
const states = useSelectStates();
3636
// data refs
3737
const { appendToBody, disabled, modelValue, position, placeholder, maxLength } = toRefs(props);
38-
const align = computed(() => (position.value.some((item) => item.includes('start') || item.includes('end')) ? 'start' : null));
3938

4039
// input事件
4140
const { onInput, onMouseenter, onMouseleave, setSoftFocus, handleBlur, handleFocus, handleClear } = useInputEvent(
@@ -101,7 +100,6 @@ export default defineComponent({
101100
v-model={states.visible}
102101
origin={originRef.value}
103102
position={position.value}
104-
align={align.value}
105103
style={styles.value}
106104
onPositionChange={handlePositionChange}>
107105
<Dropdown options={filteredOptions.value} width={props.width} maxHeight={props.maxHeight} v-slots={ctx.slots}></Dropdown>

packages/devui-vue/devui/form/src/components/form-item/form-item-types.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { RuleItem, ValidateFieldsError } from 'async-validator';
2-
import type { ComputedRef, ExtractPropTypes, PropType, InjectionKey, Ref, SetupContext } from 'vue';
3-
import { LabelAlign, LabelSize, Layout } from '../../form-types';
2+
import type { ComputedRef, ExtractPropTypes, PropType, Ref, SetupContext } from 'vue';
3+
import { LabelAlign, LabelSize, Layout, RequirePosition } from '../../form-types';
44
import { FeedbackStatus } from '../form-control/form-control-types';
55

66
export type FormItemValidateState = '' | 'error' | 'pending' | 'success';
@@ -81,6 +81,7 @@ export type LabelData = ComputedRef<{
8181
layout: Layout;
8282
labelSize: LabelSize;
8383
labelAlign: LabelAlign;
84+
requiredPosition: RequirePosition;
8485
helpTips: string | HelpTips;
8586
formItemCtx: SetupContext;
8687
}>;

packages/devui-vue/devui/form/src/components/form-item/form-item.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export default defineComponent({
2424
layout: formContext.layout,
2525
labelSize: formContext.labelSize,
2626
labelAlign: formContext.labelAlign,
27+
requiredPosition: formContext.requirePosition,
2728
helpTips: helpTips.value,
2829
formItemCtx: ctx,
2930
}));

packages/devui-vue/devui/form/src/components/form-label/form-label.scss

+14-4
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,21 @@
4747
margin-right: 8px;
4848
margin-left: -12px;
4949
}
50+
}
51+
52+
.#{$devui-prefix}-form__label--required-right {
53+
&::after {
54+
content: '*';
55+
color: red;
56+
display: inline-block;
57+
margin-left: 8px;
58+
}
59+
}
5060

51-
&-hide {
52-
&::before {
53-
display: none;
54-
}
61+
.#{$devui-prefix}-form__label--required-hide {
62+
&::before,
63+
&::after {
64+
display: none;
5565
}
5666
}
5767

packages/devui-vue/devui/form/src/components/form-label/use-form-label.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ export function useFormLabel() {
2525

2626
const labelInnerClasses = computed(() => ({
2727
[`${ns.e('label-span')}`]: true,
28-
[`${ns.em('label', 'required')}`]: formItemContext.isRequired,
28+
[`${ns.em('label', 'required')}`]: formItemContext.isRequired && labelData.value.requiredPosition === 'left',
29+
[`${ns.em('label', 'required-right')}`]: formItemContext.isRequired && labelData.value.requiredPosition === 'right',
2930
[`${ns.em('label', 'required-hide')}`]: formItemContext.isRequired && formContext.hideRequiredMark,
3031
}));
3132

packages/devui-vue/devui/form/src/form-types.ts

+5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export type LabelAlign = 'start' | 'center' | 'end';
1616
export type FormData = Record<string, unknown>;
1717
export type StyleType = 'default' | 'gray';
1818
export type AppendToBodyScrollStrategy = 'close' | 'reposition';
19+
export type RequirePosition = 'left' | 'right';
1920

2021
export type FormRules = Partial<Record<string, Array<FormRuleItem>>>;
2122
export interface ValidateFailure {
@@ -78,6 +79,10 @@ export const formProps = {
7879
type: String as PropType<AppendToBodyScrollStrategy>,
7980
default: 'reposition',
8081
},
82+
requirePosition: {
83+
type: String as PropType<RequirePosition>,
84+
default: 'left',
85+
},
8186
} as const;
8287

8388
export interface UseFieldCollection {

packages/devui-vue/devui/pagination/src/pagination-types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export const paginationProps = {
1919
},
2020
pageSizeDirection: {
2121
type: Array as PropType<Array<PageSizeDirection>>,
22-
default: () => ['bottom', 'top'],
22+
default: () => ['bottom', 'top', 'left', 'bottom'],
2323
},
2424
pageIndex: {
2525
type: Number,

packages/devui-vue/devui/popover/src/popover-types.ts

+1-6
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ export type Placement =
1515
| 'bottom-end'
1616
| 'left-start'
1717
| 'left-end';
18-
export type Alignment = 'start' | 'end';
1918
export type OffsetOptions = { mainAxis?: number; crossAxis?: number };
2019

2120
export const popoverProps = {
@@ -25,11 +24,7 @@ export const popoverProps = {
2524
},
2625
position: {
2726
type: Array as PropType<Array<Placement>>,
28-
default: ['bottom'],
29-
},
30-
align: {
31-
type: String as PropType<Alignment> | null,
32-
default: null,
27+
default: () => ['top', 'right', 'bottom', 'left'],
3328
},
3429
offset: {
3530
type: [Number, Object] as PropType<number | OffsetOptions>,

packages/devui-vue/devui/popover/src/popover.tsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export default defineComponent({
1414
props: popoverProps,
1515
emits: ['show', 'hide'],
1616
setup(props: PopoverProps, { slots, attrs, emit }) {
17-
const { content, popType, position, align, offset, showAnimation } = toRefs(props);
17+
const { content, popType, position, offset, showAnimation } = toRefs(props);
1818
const origin = ref<HTMLElement>();
1919
const popoverRef = ref<HTMLElement>();
2020
const visible = ref(false);
@@ -40,7 +40,6 @@ export default defineComponent({
4040
ref={popoverRef}
4141
origin={origin.value}
4242
position={position.value}
43-
align={align.value}
4443
offset={offset.value}
4544
class={[ns.e('content'), popType.value !== 'default' ? 'is-icon' : '']}
4645
show-arrow

packages/devui-vue/devui/popover/src/use-popover.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ export function usePopover(
5050
export function usePopoverEvent(props: PopoverProps, visible: Ref<boolean>, origin: Ref): UsePopoverEvent {
5151
const { trigger, position, mouseEnterDelay, mouseLeaveDelay, disabled } = toRefs(props);
5252
const isClick: ComputedRef<boolean> = computed(() => trigger.value === 'click');
53+
const isHover: ComputedRef<boolean> = computed(() => trigger.value === 'hover');
5354
const placement: Ref<string> = ref(position.value[0].split('-')[0]);
5455
const isEnter: Ref<boolean> = ref(false);
5556

@@ -69,13 +70,13 @@ export function usePopoverEvent(props: PopoverProps, visible: Ref<boolean>, orig
6970
if (disabled.value) {
7071
return;
7172
}
72-
if (!isClick.value) {
73+
if (isHover.value) {
7374
isEnter.value = true;
7475
enter();
7576
}
7677
};
7778
const onMouseleave = () => {
78-
if (!isClick.value) {
79+
if (isHover.value) {
7980
isEnter.value = false;
8081
leave();
8182
}

packages/devui-vue/devui/select/src/select-types.ts

+17
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,19 @@ export type Options = Array<OptionItem>;
1313
export type ModelValue = number | string | Array<number | string>;
1414
export type filterValue = boolean | ((query: string) => void);
1515
export type SelectSize = 'sm' | 'md' | 'lg';
16+
export type Placement =
17+
| 'top'
18+
| 'right'
19+
| 'bottom'
20+
| 'left'
21+
| 'top-start'
22+
| 'top-end'
23+
| 'right-start'
24+
| 'right-end'
25+
| 'bottom-start'
26+
| 'bottom-end'
27+
| 'left-start'
28+
| 'left-end';
1629
export const selectProps = {
1730
modelValue: {
1831
type: [String, Number, Array] as PropType<ModelValue>,
@@ -26,6 +39,10 @@ export const selectProps = {
2639
type: Array as PropType<Options>,
2740
default: () => [],
2841
},
42+
position: {
43+
type: Array as PropType<Placement[]>,
44+
default: () => ['bottom', 'top', 'left', 'right'],
45+
},
2946
size: {
3047
type: String as PropType<SelectSize>,
3148
default: '',

packages/devui-vue/devui/select/src/select.tsx

+2-4
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import SelectContent from './components/select-content';
2424
import useSelectFunction from './composables/use-select-function';
2525
import './select.scss';
2626
import { createI18nTranslate } from '../../locale/create';
27-
import { FlexibleOverlay, Placement } from '../../overlay';
27+
import { FlexibleOverlay } from '../../overlay';
2828
import LoadingDirective from '../../loading/src/loading-directive';
2929

3030
export default defineComponent({
@@ -77,7 +77,6 @@ export default defineComponent({
7777
ctx.expose({ focus, blur, toggleChange });
7878
const isRender = ref<boolean>(false);
7979
const currentPosition = ref('bottom');
80-
const position = ref<Placement[]>(['bottom-start', 'top-start']);
8180

8281
const handlePositionChange = (pos: string) => {
8382
currentPosition.value = pos.split('-')[0] === 'top' ? 'top' : 'bottom';
@@ -141,10 +140,9 @@ export default defineComponent({
141140
v-model={isRender.value}
142141
ref={dropdownRef}
143142
origin={originRef.value}
144-
align="start"
145143
offset={4}
146144
fit-origin-width
147-
position={position.value}
145+
position={props.position}
148146
onPositionChange={handlePositionChange}
149147
style={styles.value}
150148
class={props.menuClass}>

0 commit comments

Comments
 (0)