Skip to content

Commit

Permalink
feat(dropdown): support panel top and bottom content
Browse files Browse the repository at this point in the history
  • Loading branch information
uyarn committed Jul 26, 2023
1 parent 6a50b97 commit 287ec86
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 12 deletions.
29 changes: 23 additions & 6 deletions src/dropdown/DropdownMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,20 @@ import { DropdownOption } from './type';
import useGlobalIcon from '../hooks/useGlobalIcon';

const DropdownMenu: React.FC<DropdownProps> = (props) => {
const { options = [], maxHeight = 300, minColumnWidth = 10, maxColumnWidth = 160, direction } = props;
const {
options = [],
maxHeight = 300,
minColumnWidth = 10,
maxColumnWidth = 160,
direction,
panelTopContent,
panelBottomContent,
} = props;

const { classPrefix } = useConfig();
const dropdownClass = `${classPrefix}-dropdown`;
const dropdownMenuClass = `${dropdownClass}__menu`;

const [panelTopContentHeight, setPanelTopContentHeight] = useState(null);
const { ChevronRightIcon, ChevronLeftIcon } = useGlobalIcon({
ChevronRightIcon: TdIconChevronRight,
ChevronLeftIcon: TdIconChevronLeft,
Expand All @@ -28,10 +36,16 @@ const DropdownMenu: React.FC<DropdownProps> = (props) => {
useEffect(() => {
if (menuRef.current) {
const menuHeight = menuRef.current.childNodes?.length * 30;

setTimeout(() => {
if (panelTopContent) {
const panelTopHeight =
parseInt(getComputedStyle(menuRef.current.childNodes?.[0] as HTMLElement)?.height, 10) || 0;
setPanelTopContentHeight(panelTopHeight);
}
});
if (menuHeight >= maxHeight) setIsOverMaxHeight(true);
}
}, [maxHeight]);
}, [maxHeight, panelTopContent]);

const handleItemClick = (options: {
data: DropdownOption;
Expand All @@ -56,7 +70,8 @@ const DropdownMenu: React.FC<DropdownProps> = (props) => {
data.forEach?.((menu, idx) => {
const optionItem = { ...(menu as DropdownOption) };
const onViewIdx = Math.ceil(calcScrollTopMap[deep] / 30);
const itemIdx = idx >= onViewIdx ? idx - onViewIdx : idx;
const isOverflow = idx >= onViewIdx;
const itemIdx = isOverflow ? idx - onViewIdx : idx;
if (optionItem.children) {
optionItem.children = renderOptions(optionItem.children, deep + 1);
renderContent = (
Expand Down Expand Up @@ -92,7 +107,7 @@ const DropdownMenu: React.FC<DropdownProps> = (props) => {
})}
style={{
position: 'absolute',
top: `${itemIdx * 30}px`,
top: `${itemIdx * 30 + (isOverflow ? 0 : panelTopContentHeight)}px`,
}}
>
<div
Expand Down Expand Up @@ -156,7 +171,9 @@ const DropdownMenu: React.FC<DropdownProps> = (props) => {
ref={menuRef}
onScroll={throttleUpdate}
>
{panelTopContent ? <div className={`${dropdownClass}__top-content`}>{panelTopContent}</div> : null}
{renderOptions(options, 0)}
{panelBottomContent ? <div className={`${dropdownClass}__bottom-content`}>{panelBottomContent}</div> : null}
</div>
);
};
Expand Down
File renamed without changes.
10 changes: 6 additions & 4 deletions src/dropdown/dropdown.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,18 @@ name | type | default | description | required
-- | -- | -- | -- | --
className | String | - | 类名 | N
style | Object | - | 样式,Typescript:`React.CSSProperties` | N
direction | String | right | optionsleft/right | N
direction | String | right | options: left/right | N
disabled | Boolean | false | \- | N
hideAfterItemClick | Boolean | true | \- | N
maxColumnWidth | String / Number | 100 | \- | N
maxHeight | Number | 300 | \- | N
minColumnWidth | String / Number | 10 | \- | N
options | Array | [] | Typescript:`Array<DropdownOption>` `type DropdownOption = { children?: Array<TdDropdownItemProps> } & TdDropdownItemProps & Record<string, any>`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/dropdown/type.ts) | N
placement | String | bottom-left | options:top/left/right/bottom/top-left/top-right/bottom-left/bottom-right/left-top/left-bottom/right-top/right-bottom | N
panelBottomContent | TNode | - | bottom content of the dropdown panel。Typescript:`string \| TNode`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N
panelTopContent | TNode | - | top content of the dropdown panel。Typescript:`string \| TNode`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N
placement | String | bottom-left | options: top/left/right/bottom/top-left/top-right/bottom-left/bottom-right/left-top/left-bottom/right-top/right-bottom | N
popupProps | Object | - | Typescript:`PopupProps`[Popup API Documents](./popup?tab=api)[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/dropdown/type.ts) | N
trigger | String | hover | optionshover/click/focus/context-menu | N
trigger | String | hover | options: hover/click/focus/context-menu | N
onClick | Function | | Typescript:`(dropdownItem: DropdownOption, context: { e: MouseEvent }) => void`<br/> | N

### DropdownItem Props
Expand All @@ -30,6 +32,6 @@ content | TNode | '' | Typescript:`string \| TNode`。[see more ts definition]
disabled | Boolean | false | \- | N
divider | Boolean | false | \- | N
prefixIcon | TElement | - | Typescript:`TNode`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N
theme | String | default | optionsdefault/success/warning/error。Typescript:`DropdownItemTheme` `type DropdownItemTheme = 'default' \| 'success' \| 'warning' \| 'error'`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/dropdown/type.ts) | N
theme | String | default | options: default/success/warning/error。Typescript:`DropdownItemTheme` `type DropdownItemTheme = 'default' \| 'success' \| 'warning' \| 'error'`[see more ts definition](https://github.com/Tencent/tdesign-react/blob/develop/src/dropdown-menu/type.ts) | N
value | String / Number / Object | - | Typescript:`string \| number \| { [key: string]: any }` | N
onClick | Function | | Typescript:`(dropdownItem: DropdownOption, context: { e: MouseEvent }) => void`<br/> | N
4 changes: 3 additions & 1 deletion src/dropdown/dropdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ maxColumnWidth | String / Number | 100 | 选项最大宽度,内容超出时,
maxHeight | Number | 300 | 弹窗最大高度,单位:px 。统一控制每一列的高度 | N
minColumnWidth | String / Number | 10 | 选项最小宽度。值为字符串时,值就是最小宽度;值为数字时,单位:px | N
options | Array | [] | 下拉操作项。TS 类型:`Array<DropdownOption>` `type DropdownOption = { children?: Array<TdDropdownItemProps> } & TdDropdownItemProps & Record<string, any>`[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/dropdown/type.ts) | N
panelBottomContent | TNode | - | 面板内的底部内容。TS 类型:`string \| TNode`[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N
panelTopContent | TNode | - | 面板内的顶部内容。TS 类型:`string \| TNode`[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N
placement | String | bottom-left | 弹窗定位方式,可选值同 Popup 组件。可选项:top/left/right/bottom/top-left/top-right/bottom-left/bottom-right/left-top/left-bottom/right-top/right-bottom | N
popupProps | Object | - | 透传 Popup 组件属性,方便更加自由地控制。比如使用 popupProps.overlayStyle 设置浮层样式。TS 类型:`PopupProps`[Popup API Documents](./popup?tab=api)[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/dropdown/type.ts) | N
trigger | String | hover | 触发下拉显示的方式。可选项:hover/click/focus/context-menu | N
Expand All @@ -36,6 +38,6 @@ content | TNode | '' | 下拉操作项内容。TS 类型:`string \| TNode`。[
disabled | Boolean | false | 是否禁用操作项 | N
divider | Boolean | false | 是否显示操作项之间的分隔线(分隔线默认在下方) | N
prefixIcon | TElement | - | 组件前置图标。TS 类型:`TNode`[通用类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/common.ts) | N
theme | String | default | 下拉菜单选项主题。可选项:default/success/warning/error。TS 类型:`DropdownItemTheme` `type DropdownItemTheme = 'default' \| 'success' \| 'warning' \| 'error'`[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/dropdown/type.ts) | N
theme | String | default | 下拉菜单选项主题。可选项:default/success/warning/error。TS 类型:`DropdownItemTheme` `type DropdownItemTheme = 'default' \| 'success' \| 'warning' \| 'error'`[详细类型定义](https://github.com/Tencent/tdesign-react/blob/develop/src/dropdown-menu/type.ts) | N
value | String / Number / Object | - | 下拉操作项唯一标识。TS 类型:`string \| number \| { [key: string]: any }` | N
onClick | Function | | TS 类型:`(dropdownItem: DropdownOption, context: { e: MouseEvent }) => void`<br/>点击时触发 | N
10 changes: 9 additions & 1 deletion src/dropdown/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,14 @@ export interface TdDropdownProps {
* @default []
*/
options?: Array<DropdownOption>;
/**
* 面板内的底部内容
*/
panelBottomContent?: TNode;
/**
* 面板内的顶部内容
*/
panelTopContent?: TNode;
/**
* 弹窗定位方式,可选值同 Popup 组件
* @default bottom-left
Expand Down Expand Up @@ -100,7 +108,7 @@ export interface TdDropdownItemProps {
/**
* 组件前置图标
*/
prefixIcon?: TNode;
prefixIcon?: TElement;
/**
* 下拉菜单选项主题
* @default default
Expand Down

0 comments on commit 287ec86

Please sign in to comment.