Skip to content

Commit 47dadcd

Browse files
committed
feat(dropdown): support the overlay display by different placement
1 parent e3382d5 commit 47dadcd

File tree

2 files changed

+52
-8
lines changed

2 files changed

+52
-8
lines changed

src/components/dropdown/index.tsx

+14-7
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import './style.scss';
22
import * as React from 'react';
33
import { classNames, prefixClaName } from 'mo/common/className';
44
import { useContextView } from '../contextview';
5-
import { triggerEvent, TriggerEvent } from 'mo/common/dom';
5+
import { triggerEvent, TriggerEvent, PlacementType, getPositionByPlacement } from 'mo/common/dom';
66

77
export interface IDropDown extends HTMLElementProps {
88
overlay: ReactNode;
99
trigger?: TriggerEvent;
10-
placement?: 'top' | 'right' | 'bottom' | 'left';
10+
placement?: PlacementType;
1111
}
1212

1313
export const defaultDropDownClassName = 'drop-down';
@@ -17,7 +17,7 @@ export function DropDown(props: React.PropsWithChildren<IDropDown>) {
1717
className,
1818
overlay,
1919
children,
20-
placement = 'bottom',
20+
placement = 'right',
2121
trigger = 'click',
2222
...others
2323
} = props;
@@ -34,10 +34,17 @@ export function DropDown(props: React.PropsWithChildren<IDropDown>) {
3434
[triggerEvent(trigger)]: function (e: React.MouseEvent) {
3535
const target = e.currentTarget;
3636
const rect = target.getBoundingClientRect();
37-
contextView.show({
38-
x: rect.x + rect.width,
39-
y: rect.y,
40-
});
37+
let position = getPositionByPlacement(placement, rect);
38+
contextView.show(position);
39+
// If placement is left or top,
40+
// need re calculate the position by menu size
41+
if (placement === 'left' || placement === 'top') {
42+
const overlay = contextView.view!.getBoundingClientRect();
43+
overlay.x = rect.x;
44+
overlay.y = rect.y;
45+
position = getPositionByPlacement(placement, overlay);
46+
contextView.show(position);
47+
}
4148
},
4249
};
4350

stories/components/11-DownDown.stories.tsx

+38-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { propsTable } from '../common/propsTable';
66
import { Menu } from 'mo/components/menu';
77
import { Icon } from 'mo/components/icon';
88
import { DropDown } from 'mo/components/dropdown';
9+
import { useState } from 'react';
10+
import { PlacementType } from 'mo/common/dom';
911

1012
const stories = storiesOf('DropDown', module);
1113
stories.addDecorator(withKnobs);
@@ -128,6 +130,14 @@ stories.add(
128130
},
129131
];
130132

133+
const [ placement, setPlacement ] = useState<PlacementType>('right');
134+
135+
const onSelectPlacement = (e) => {
136+
const value = e.target.value;
137+
console.log('onSelectPlacement:', value);
138+
setPlacement(value);
139+
}
140+
131141
return (
132142
<div>
133143
<h2>简述</h2>
@@ -154,7 +164,7 @@ stories.add(
154164
</DropDown>
155165
</div>
156166
<div>
157-
<h3>使用示例 1 - Click me!</h3>
167+
<h3>使用示例 2 - Click me!</h3>
158168
<DropDown
159169
style={{
160170
width: 45,
@@ -171,6 +181,33 @@ stories.add(
171181
<Icon type="menu" />
172182
</DropDown>
173183
</div>
184+
<div>
185+
<h3>
186+
使用示例 3 - Custom Placement
187+
188+
<select onChange={onSelectPlacement} defaultValue="right">
189+
<option value="top">Top</option>
190+
<option value="right">Right</option>
191+
<option value="bottom">Bottom</option>
192+
<option value="left">Left</option>
193+
</select>
194+
</h3>
195+
<DropDown
196+
style={{
197+
width: 45,
198+
height: 45,
199+
color: 'rgba(255, 255, 255, 0.4)',
200+
background: '#252526',
201+
}}
202+
trigger="click"
203+
placement={placement}
204+
overlay={
205+
<Menu style={{ width: 200 }} data={menuData} />
206+
}
207+
>
208+
<Icon type="menu" />
209+
</DropDown>
210+
</div>
174211
</div>
175212
);
176213
},

0 commit comments

Comments
 (0)