Skip to content

Commit 69e1fb9

Browse files
committed
feat(editable-select):给可编辑下拉框增加appendToBody
1 parent b5f139a commit 69e1fb9

File tree

6 files changed

+317
-155
lines changed

6 files changed

+317
-155
lines changed
Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { App } from 'vue'
22
import EditableSelect from './src/editable-select'
3-
4-
EditableSelect.install = function(app: App): void {
3+
import EselectDropdown from './src/components/dropdown'
4+
EditableSelect.install = function (app: App): void {
55
app.component(EditableSelect.name, EditableSelect)
66
}
77

@@ -12,6 +12,7 @@ export default {
1212
category: '数据录入',
1313
status: undefined, // TODO: 组件若开发完成则填入"已完成",并删除该注释
1414
install(app: App): void {
15-
app.use(EditableSelect as any)
15+
app.use(EditableSelect as any)
16+
app.use(EselectDropdown as any)
1617
}
1718
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { defineComponent, inject } from 'vue'
2+
import { OptionItem, selectDropdownProps } from '../editable-select-types'
3+
import { className } from '../utils'
4+
export default defineComponent({
5+
name: 'DSelectDropdown',
6+
props: selectDropdownProps,
7+
setup(props) {
8+
const select = inject('InjectionKey') as any
9+
const {
10+
props: selectProps,
11+
dropdownRef,
12+
visible,
13+
selectOptionClick,
14+
renderDefaultSlots,
15+
renderEmptySlots,
16+
selectedIndex,
17+
loadMore
18+
} = select
19+
const { maxHeight } = selectProps
20+
return () => {
21+
const getLiCls = (item: OptionItem, index: number) => {
22+
const { disabledKey } = selectProps
23+
return className('devui-dropdown-item', {
24+
disabled: disabledKey ? !!item[disabledKey] : false,
25+
selected: selectedIndex.value === index
26+
})
27+
}
28+
return (
29+
<div class='devui-dropdown-menu' v-show={visible}>
30+
<ul
31+
ref={dropdownRef}
32+
class='devui-list-unstyled scroll-height'
33+
style={{
34+
maxHeight: maxHeight + 'px'
35+
}}
36+
onScroll={loadMore}
37+
>
38+
{props.options.map((o, index) => {
39+
return (
40+
<li class={getLiCls(o, index)} onClick={($evnet) => selectOptionClick($evnet, o)}>
41+
{renderDefaultSlots(o)}
42+
</li>
43+
)
44+
})}
45+
<li class='devui-no-result-template' v-show={props.options.length === 0}>
46+
<div class='devui-no-data-tip'>{renderEmptySlots()}</div>
47+
</li>
48+
</ul>
49+
</div>
50+
)
51+
}
52+
}
53+
})

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

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
import type { PropType, ExtractPropTypes } from 'vue'
2+
type HorizontalConnectionPos = 'left' | 'center' | 'right';
3+
type VerticalConnectionPos = 'top' | 'center' | 'bottom';
4+
5+
export interface ConnectionPosition {
6+
originX: HorizontalConnectionPos
7+
originY: VerticalConnectionPos
8+
overlayX: HorizontalConnectionPos
9+
overlayY: VerticalConnectionPos
10+
}
211
export interface OptionItem {
312
name: string
413
[key: string]: any
514
}
615
export type Options = Array<string | OptionItem>
716
export const editableSelectProps = {
8-
/* test: {
9-
type: Object as PropType<{ xxx: xxx }>
10-
} */
17+
appendToBody: {
18+
type: Boolean,
19+
default: false
20+
},
1121
modelValue: {
1222
type: [String, Number] as PropType<string | number>
1323
},
@@ -16,7 +26,8 @@ export const editableSelectProps = {
1626
default: () => []
1727
},
1828
width: {
19-
type: Number
29+
type: Number,
30+
default: 450
2031
},
2132
maxHeight: {
2233
type: Number
@@ -47,7 +58,17 @@ export const editableSelectProps = {
4758
},
4859
searchFn: {
4960
type: Function as PropType<(term: string) => Array<Options>>,
61+
},
62+
loadMore: {
63+
type: Function as PropType<() => Array<Options>>
5064
}
5165
} as const
5266

67+
export const selectDropdownProps = {
68+
options: {
69+
type: Array as PropType<OptionItem[]>,
70+
default: () => []
71+
}
72+
} as const
5373
export type EditableSelectProps = ExtractPropTypes<typeof editableSelectProps>
74+
export type SelectDropdownProps = ExtractPropTypes<typeof selectDropdownProps>

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

Lines changed: 106 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,134 @@
11
@import '../../style/theme/color';
22
@import '../../style/core/animation';
3+
.devui-editable-select {
4+
.devui-form-group {
5+
input::-ms-clear {
6+
display: none;
7+
}
8+
9+
ul.devui-list-unstyled {
10+
margin: 0;
11+
overflow-y: auto;
12+
padding: 0;
13+
}
14+
15+
.devui-dropdown-bg {
16+
background: $devui-list-item-hover-bg;
17+
}
318

4-
.devui-form-group {
5-
input::-ms-clear {
6-
display: none;
19+
.devui-popup-tips {
20+
color: $devui-text-weak;
21+
padding: 4px 12px;
22+
}
23+
24+
.devui-form-control {
25+
outline: none;
26+
padding-right: 24px;
27+
}
728
}
829

9-
ul.devui-list-unstyled {
10-
margin: 0;
11-
overflow-y: auto;
12-
padding: 0;
30+
.devui-select-open {
31+
.devui-select-chevron-icon {
32+
transform: rotate(180deg);
33+
34+
svg path {
35+
fill: $devui-text-weak;
36+
}
37+
}
1338
}
1439

15-
.devui-dropdown-bg {
16-
background: $devui-list-item-hover-bg;
40+
.devui-form-control-feedback {
41+
.devui-select-chevron-icon {
42+
display: inline-flex;
43+
vertical-align: middle;
44+
transition: transform $devui-animation-duration-slow $devui-animation-ease-in-out-smooth;
45+
}
1746
}
1847

19-
.devui-popup-tips {
20-
color: $devui-text-weak;
21-
padding: 4px 12px;
48+
.devui-has-feedback > .devui-form-control-feedback {
49+
line-height: 26px;
2250
}
2351

24-
.devui-form-control {
25-
outline: none;
26-
padding-right: 24px;
52+
.devui-dropdown-bg.devui-dropdown-bg {
53+
background-color: inherit;
54+
}
55+
// 下拉部分
56+
.devui-dropdown-menu {
57+
width: 100%;
58+
display: block;
59+
}
60+
61+
.devui-dropdown-item {
62+
cursor: pointer;
63+
display: block;
64+
width: 100%;
65+
padding: 8px 12px;
66+
clear: both;
67+
border: 0;
68+
overflow: hidden;
69+
text-overflow: ellipsis;
70+
white-space: nowrap;
71+
line-height: 14px;
72+
}
73+
74+
.devui-dropdown-menu {
75+
.devui-dropdown-item:not(.disabled) {
76+
&.selected {
77+
color: $devui-list-item-active-text;
78+
background-color: $devui-list-item-active-bg;
79+
}
80+
}
2781
}
28-
}
2982

30-
.devui-select-open {
31-
.devui-select-chevron-icon {
32-
transform: rotate(180deg);
83+
.devui-no-result-template,
84+
.devui-is-searching-template {
85+
display: block;
86+
width: 100%;
87+
padding: 8px 12px;
88+
clear: both;
89+
border: 0;
90+
overflow: hidden;
91+
text-overflow: ellipsis;
92+
white-space: nowrap;
93+
cursor: not-allowed;
94+
background-color: $devui-disabled-bg;
95+
color: $devui-disabled-text;
96+
line-height: 14px;
3397

34-
svg path {
35-
fill: $devui-text-weak;
98+
&:hover,
99+
&:active,
100+
&:hover:active {
101+
background-color: $devui-unavailable;
36102
}
37103
}
38-
}
104+
// 选项disabled
105+
.devui-dropdown-item.disabled,
106+
.devui-dropdown-item.disabled:hover {
107+
cursor: not-allowed;
108+
color: $devui-disabled-text;
109+
}
39110

40-
.devui-form-control-feedback {
41-
.devui-select-chevron-icon {
42-
display: inline-flex;
43-
vertical-align: middle;
44-
transition: transform $devui-animation-duration-slow $devui-animation-ease-in-out-smooth;
111+
ul.devui-list-unstyled {
112+
margin: 0;
113+
overflow-y: auto;
114+
padding: 0;
45115
}
46-
}
47116

48-
.devui-has-feedback > .devui-form-control-feedback {
49-
line-height: 26px;
50-
}
117+
.devui-dropdown-bg {
118+
background: $devui-list-item-hover-bg;
119+
}
51120

52-
.devui-dropdown-bg.devui-dropdown-bg {
53-
background-color: inherit;
121+
.devui-popup-tips {
122+
color: $devui-text-weak;
123+
padding: 4px 12px;
124+
}
54125
}
55-
// 下拉部分
56-
.devui-editable-select {
126+
127+
.devui-dropdown {
57128
.devui-dropdown-menu {
58129
width: 100%;
59130
display: block;
60131
}
61-
62132
.devui-dropdown-item {
63133
cursor: pointer;
64134
display: block;

0 commit comments

Comments
 (0)