@aloudata/aloudata-design 3.1.5 → 3.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ConfigProvider/getUserList.d.ts +47 -0
- package/dist/ConfigProvider/getUserList.js.map +1 -1
- package/dist/ConfigProvider/hooks/useGetUserList.d.ts +7 -0
- package/dist/ConfigProvider/hooks/useGetUserList.js +5 -1
- package/dist/ConfigProvider/hooks/useGetUserList.js.map +1 -1
- package/dist/ConfigProvider/index.d.ts +5 -1
- package/dist/ConfigProvider/index.js +6 -2
- package/dist/ConfigProvider/index.js.map +1 -1
- package/dist/Dropdown/index.d.ts +7 -2
- package/dist/Dropdown/index.js +32 -23
- package/dist/Dropdown/index.js.map +1 -1
- package/dist/MemberPicker/components/MultipleOption.d.ts +1 -0
- package/dist/MemberPicker/components/MultipleOption.js +3 -1
- package/dist/MemberPicker/components/MultipleOption.js.map +1 -1
- package/dist/MemberPicker/components/NickLabel.d.ts +5 -0
- package/dist/MemberPicker/components/NickLabel.js +14 -4
- package/dist/MemberPicker/components/NickLabel.js.map +1 -1
- package/dist/MemberPicker/components/Panel.d.ts +4 -0
- package/dist/MemberPicker/components/Panel.js +13 -4
- package/dist/MemberPicker/components/Panel.js.map +1 -1
- package/dist/MemberPicker/components/PanelWrapper.js +25 -24
- package/dist/MemberPicker/components/PanelWrapper.js.map +1 -1
- package/dist/MemberPicker/components/SearchFeedback.d.ts +7 -0
- package/dist/MemberPicker/components/SearchFeedback.js +27 -0
- package/dist/MemberPicker/components/SearchFeedback.js.map +1 -0
- package/dist/MemberPicker/components/SingleOption.d.ts +1 -0
- package/dist/MemberPicker/components/SingleOption.js +3 -1
- package/dist/MemberPicker/components/SingleOption.js.map +1 -1
- package/dist/MemberPicker/components/UserGroupSelection.d.ts +4 -1
- package/dist/MemberPicker/components/UserGroupSelection.js +29 -22
- package/dist/MemberPicker/components/UserGroupSelection.js.map +1 -1
- package/dist/MemberPicker/dialog/DialogColumns.d.ts +5 -0
- package/dist/MemberPicker/dialog/DialogColumns.js +59 -0
- package/dist/MemberPicker/dialog/DialogColumns.js.map +1 -0
- package/dist/MemberPicker/dialog/DialogContent.d.ts +3 -0
- package/dist/MemberPicker/dialog/DialogContent.js +106 -0
- package/dist/MemberPicker/dialog/DialogContent.js.map +1 -0
- package/dist/MemberPicker/dialog/MemberOption.d.ts +16 -0
- package/dist/MemberPicker/dialog/MemberOption.js +101 -0
- package/dist/MemberPicker/dialog/MemberOption.js.map +1 -0
- package/dist/MemberPicker/dialog/MemberPickerDialog.d.ts +11 -0
- package/dist/MemberPicker/dialog/MemberPickerDialog.js +11 -0
- package/dist/MemberPicker/dialog/MemberPickerDialog.js.map +1 -0
- package/dist/MemberPicker/dialog/SelectedMemberPanel.d.ts +12 -0
- package/dist/MemberPicker/dialog/SelectedMemberPanel.js +37 -0
- package/dist/MemberPicker/dialog/SelectedMemberPanel.js.map +1 -0
- package/dist/MemberPicker/dialog/UserCandidatePanel.d.ts +13 -0
- package/dist/MemberPicker/dialog/UserCandidatePanel.js +168 -0
- package/dist/MemberPicker/dialog/UserCandidatePanel.js.map +1 -0
- package/dist/MemberPicker/dialog/UserGroupCandidatePanel.d.ts +13 -0
- package/dist/MemberPicker/dialog/UserGroupCandidatePanel.js +134 -0
- package/dist/MemberPicker/dialog/UserGroupCandidatePanel.js.map +1 -0
- package/dist/MemberPicker/dialog/helper.d.ts +20 -0
- package/dist/MemberPicker/dialog/helper.js +61 -0
- package/dist/MemberPicker/dialog/helper.js.map +1 -0
- package/dist/MemberPicker/dialog/types.d.ts +41 -0
- package/dist/MemberPicker/dialog/types.js +7 -0
- package/dist/MemberPicker/dialog/types.js.map +1 -0
- package/dist/MemberPicker/dialog/useDialogLocale.d.ts +103 -0
- package/dist/MemberPicker/dialog/useDialogLocale.js +12 -0
- package/dist/MemberPicker/dialog/useDialogLocale.js.map +1 -0
- package/dist/MemberPicker/dialog/useMemberPickerDraft.d.ts +27 -0
- package/dist/MemberPicker/dialog/useMemberPickerDraft.js +95 -0
- package/dist/MemberPicker/dialog/useMemberPickerDraft.js.map +1 -0
- package/dist/MemberPicker/dialog/useUserGroupCandidates.d.ts +29 -0
- package/dist/MemberPicker/dialog/useUserGroupCandidates.js +443 -0
- package/dist/MemberPicker/dialog/useUserGroupCandidates.js.map +1 -0
- package/dist/MemberPicker/index.d.ts +2 -0
- package/dist/MemberPicker/index.js +58 -34
- package/dist/MemberPicker/index.js.map +1 -1
- package/dist/MemberPicker/useMemberSearch.d.ts +8 -0
- package/dist/MemberPicker/useMemberSearch.js +51 -0
- package/dist/MemberPicker/useMemberSearch.js.map +1 -0
- package/dist/Menu/index.d.ts +2 -0
- package/dist/Menu/index.js +3 -2
- package/dist/Menu/index.js.map +1 -1
- package/dist/Modal/index.js +1 -1
- package/dist/Modal/index.js.map +1 -1
- package/dist/aloudata-design.css +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -2
- package/dist/locale/default.d.ts +29 -0
- package/dist/locale/en_US.d.ts +29 -0
- package/dist/locale/en_US.js +29 -0
- package/dist/locale/en_US.js.map +1 -1
- package/dist/locale/zh_CN.d.ts +29 -0
- package/dist/locale/zh_CN.js +29 -0
- package/dist/locale/zh_CN.js.map +1 -1
- package/package.json +2 -1
|
@@ -23,6 +23,11 @@ export interface IUser {
|
|
|
23
23
|
export interface IUserGroup {
|
|
24
24
|
type: EUserType.USER_GROUP;
|
|
25
25
|
groupId: string;
|
|
26
|
+
/** 搜索展示的根到自身路径;选择值及名称仍保持原语义。 */
|
|
27
|
+
path?: Array<{
|
|
28
|
+
groupId: string;
|
|
29
|
+
name: string;
|
|
30
|
+
}> | null;
|
|
26
31
|
name: string;
|
|
27
32
|
parentId: string | null;
|
|
28
33
|
frontId: string | null;
|
|
@@ -35,7 +40,49 @@ export interface IGetUserListParams {
|
|
|
35
40
|
export type { TUserValue, TUserGroupValue };
|
|
36
41
|
export type getUsersByIdsType = ((params: Array<TUserValue | TUserGroupValue>) => Promise<TUser>) | undefined;
|
|
37
42
|
export type getUsersByKeywordsType = ((params: string) => Promise<TUser>) | undefined;
|
|
43
|
+
/** 每个搜索请求独立返回元信息,避免不同选择器共享可变提示状态。 */
|
|
44
|
+
export interface MemberSearchResult<T> {
|
|
45
|
+
items: T[];
|
|
46
|
+
hasMore?: boolean;
|
|
47
|
+
pathWarningCode?: string | null;
|
|
48
|
+
}
|
|
49
|
+
/** 分页与权限由业务适配器处理;关键字非空表示跨层级搜索。 */
|
|
50
|
+
export interface MemberUserPageRequest {
|
|
51
|
+
keyword: string;
|
|
52
|
+
pager: {
|
|
53
|
+
pageNumber: number;
|
|
54
|
+
pageSize: number;
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
export interface MemberUserPage {
|
|
58
|
+
data: IUser[];
|
|
59
|
+
pageNumber: number;
|
|
60
|
+
hasMore: boolean;
|
|
61
|
+
}
|
|
62
|
+
export interface MemberGroupPageRequest {
|
|
63
|
+
parentGroupId?: string;
|
|
64
|
+
keyword?: string;
|
|
65
|
+
pager: {
|
|
66
|
+
pageNumber: number;
|
|
67
|
+
pageSize: number;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
export interface MemberGroupPage {
|
|
71
|
+
data: IUserGroup[];
|
|
72
|
+
pageNumber: number;
|
|
73
|
+
hasMore: boolean;
|
|
74
|
+
pathWarningCode?: string | null;
|
|
75
|
+
/** 旧接口只提供一页且没有继续加载能力时明确提示。 */
|
|
76
|
+
truncated?: boolean;
|
|
77
|
+
}
|
|
38
78
|
export type getUserListType = {
|
|
79
|
+
getMemberPickerUserPage?: (request: MemberUserPageRequest) => Promise<MemberUserPage>;
|
|
80
|
+
getMemberPickerGroupPage?: (request: MemberGroupPageRequest) => Promise<MemberGroupPage>;
|
|
81
|
+
getUsersByKeywordsWithMeta?: (keyword: string) => Promise<MemberSearchResult<IUser | IUserGroup>>;
|
|
82
|
+
getNextLevelGroupWithMeta?: (params: {
|
|
83
|
+
parentGroupId?: string;
|
|
84
|
+
keyword: string;
|
|
85
|
+
}) => Promise<MemberSearchResult<IUserGroup>>;
|
|
39
86
|
getUsersByIds?: getUsersByIdsType;
|
|
40
87
|
getUsersByKeywords?: getUsersByKeywordsType;
|
|
41
88
|
getMemberPickerItemMoreInfoKey?: (user: IUser) => string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getUserList.js","names":[],"sources":["../../src/ConfigProvider/getUserList.tsx"],"sourcesContent":["import * as React from 'react';\nimport { TUserGroupValue, TUserValue } from '../MemberPicker/interface';\n\nexport enum EUserType {\n USER = 'USER',\n USER_GROUP = 'USER_GROUP',\n}\nexport enum EUserSource {\n ALOUDATA = 'Aloudata',\n}\nexport interface IUser {\n type: EUserType.USER;\n userId: string;\n account?: string;\n nickname?: string;\n photo?: string;\n name: string;\n ban?: boolean; // 是否禁用\n [key: string]: unknown;\n email?: string;\n phone?: string;\n userSource?: EUserSource; // 用户来源\n}\nexport interface IUserGroup {\n type: EUserType.USER_GROUP;\n groupId: string;\n name: string;\n parentId: string | null;\n frontId: string | null;\n}\n\nexport type TUser = Array<IUser | IUserGroup>;\nexport interface IGetUserListParams {\n name?: string;\n id?: string;\n}\nexport type { TUserValue, TUserGroupValue };\nexport type getUsersByIdsType =\n | ((params: Array<TUserValue | TUserGroupValue>) => Promise<TUser>)\n | undefined;\nexport type getUsersByKeywordsType =\n | ((params: string) => Promise<TUser>)\n | undefined;\nexport type getUserListType = {\n getUsersByIds?: getUsersByIdsType;\n getUsersByKeywords?: getUsersByKeywordsType;\n getMemberPickerItemMoreInfoKey?: (user: IUser) => string; // 获取每一条用户数据右侧的标识符信息\n getNextLevelGroup?: (params: {\n parentGroupId?: string;\n keyword: string;\n }) => Promise<IUserGroup[]>; // 获取下一级用户组,如果包含这个参数则用户组会切换到异步模式\n};\nconst GetUserListContext = React.createContext<getUserListType>({});\nexport interface IGetUserListContextProps {\n getUsersByIds?: getUsersByIdsType;\n getUsersByKeywords?: getUsersByKeywordsType;\n children?: React.ReactNode;\n}\n\nexport const SizeContextProvider: React.FC<IGetUserListContextProps> = ({\n children,\n getUsersByIds,\n getUsersByKeywords,\n}) => (\n <GetUserListContext.Consumer>\n {(originGetUserList) => (\n <GetUserListContext.Provider\n value={{\n getUsersByIds: getUsersByIds || originGetUserList.getUsersByIds,\n getUsersByKeywords:\n getUsersByKeywords || originGetUserList.getUsersByKeywords,\n }}\n >\n {children}\n </GetUserListContext.Provider>\n )}\n </GetUserListContext.Consumer>\n);\n\nexport default GetUserListContext;\n"],"mappings":";;;AAGA,IAAY,YAAL,yBAAA,WAAA;AACL,WAAA,UAAA;AACA,WAAA,gBAAA;;KACD;
|
|
1
|
+
{"version":3,"file":"getUserList.js","names":[],"sources":["../../src/ConfigProvider/getUserList.tsx"],"sourcesContent":["import * as React from 'react';\nimport { TUserGroupValue, TUserValue } from '../MemberPicker/interface';\n\nexport enum EUserType {\n USER = 'USER',\n USER_GROUP = 'USER_GROUP',\n}\nexport enum EUserSource {\n ALOUDATA = 'Aloudata',\n}\nexport interface IUser {\n type: EUserType.USER;\n userId: string;\n account?: string;\n nickname?: string;\n photo?: string;\n name: string;\n ban?: boolean; // 是否禁用\n [key: string]: unknown;\n email?: string;\n phone?: string;\n userSource?: EUserSource; // 用户来源\n}\nexport interface IUserGroup {\n type: EUserType.USER_GROUP;\n groupId: string;\n /** 搜索展示的根到自身路径;选择值及名称仍保持原语义。 */\n path?: Array<{ groupId: string; name: string }> | null;\n name: string;\n parentId: string | null;\n frontId: string | null;\n}\n\nexport type TUser = Array<IUser | IUserGroup>;\nexport interface IGetUserListParams {\n name?: string;\n id?: string;\n}\nexport type { TUserValue, TUserGroupValue };\nexport type getUsersByIdsType =\n | ((params: Array<TUserValue | TUserGroupValue>) => Promise<TUser>)\n | undefined;\nexport type getUsersByKeywordsType =\n | ((params: string) => Promise<TUser>)\n | undefined;\n/** 每个搜索请求独立返回元信息,避免不同选择器共享可变提示状态。 */\nexport interface MemberSearchResult<T> {\n items: T[];\n hasMore?: boolean;\n pathWarningCode?: string | null;\n}\n/** 分页与权限由业务适配器处理;关键字非空表示跨层级搜索。 */\nexport interface MemberUserPageRequest {\n keyword: string;\n pager: { pageNumber: number; pageSize: number };\n}\nexport interface MemberUserPage {\n data: IUser[];\n pageNumber: number;\n hasMore: boolean;\n}\nexport interface MemberGroupPageRequest {\n parentGroupId?: string;\n keyword?: string;\n pager: { pageNumber: number; pageSize: number };\n}\nexport interface MemberGroupPage {\n data: IUserGroup[];\n pageNumber: number;\n hasMore: boolean;\n pathWarningCode?: string | null;\n /** 旧接口只提供一页且没有继续加载能力时明确提示。 */\n truncated?: boolean;\n}\nexport type getUserListType = {\n getMemberPickerUserPage?: (\n request: MemberUserPageRequest,\n ) => Promise<MemberUserPage>;\n getMemberPickerGroupPage?: (\n request: MemberGroupPageRequest,\n ) => Promise<MemberGroupPage>;\n getUsersByKeywordsWithMeta?: (\n keyword: string,\n ) => Promise<MemberSearchResult<IUser | IUserGroup>>;\n getNextLevelGroupWithMeta?: (params: {\n parentGroupId?: string;\n keyword: string;\n }) => Promise<MemberSearchResult<IUserGroup>>;\n getUsersByIds?: getUsersByIdsType;\n getUsersByKeywords?: getUsersByKeywordsType;\n getMemberPickerItemMoreInfoKey?: (user: IUser) => string; // 获取每一条用户数据右侧的标识符信息\n getNextLevelGroup?: (params: {\n parentGroupId?: string;\n keyword: string;\n }) => Promise<IUserGroup[]>; // 获取下一级用户组,如果包含这个参数则用户组会切换到异步模式\n};\nconst GetUserListContext = React.createContext<getUserListType>({});\nexport interface IGetUserListContextProps {\n getUsersByIds?: getUsersByIdsType;\n getUsersByKeywords?: getUsersByKeywordsType;\n children?: React.ReactNode;\n}\n\nexport const SizeContextProvider: React.FC<IGetUserListContextProps> = ({\n children,\n getUsersByIds,\n getUsersByKeywords,\n}) => (\n <GetUserListContext.Consumer>\n {(originGetUserList) => (\n <GetUserListContext.Provider\n value={{\n ...originGetUserList,\n getUsersByIds: getUsersByIds || originGetUserList.getUsersByIds,\n getUsersByKeywords:\n getUsersByKeywords || originGetUserList.getUsersByKeywords,\n }}\n >\n {children}\n </GetUserListContext.Provider>\n )}\n </GetUserListContext.Consumer>\n);\n\nexport default GetUserListContext;\n"],"mappings":";;;AAGA,IAAY,YAAL,yBAAA,WAAA;AACL,WAAA,UAAA;AACA,WAAA,gBAAA;;KACD;AA0FD,IAAM,qBAAqB,QAAM,cAA+B,EAAE,CAAC"}
|
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
declare function useGetUserList(): {
|
|
2
|
+
getMemberPickerUserPage: ((request: import('../getUserList').MemberUserPageRequest) => Promise<import('../getUserList').MemberUserPage>) | undefined;
|
|
3
|
+
getMemberPickerGroupPage: ((request: import('../getUserList').MemberGroupPageRequest) => Promise<import('../getUserList').MemberGroupPage>) | undefined;
|
|
2
4
|
getUsersByIds: import('../getUserList').getUsersByIdsType;
|
|
3
5
|
getUsersByKeywords: import('../getUserList').getUsersByKeywordsType;
|
|
6
|
+
getUsersByKeywordsWithMeta: ((keyword: string) => Promise<import('../getUserList').MemberSearchResult<import('../getUserList').IUser | import('../getUserList').IUserGroup>>) | undefined;
|
|
7
|
+
getNextLevelGroupWithMeta: ((params: {
|
|
8
|
+
parentGroupId?: string | undefined;
|
|
9
|
+
keyword: string;
|
|
10
|
+
}) => Promise<import('../getUserList').MemberSearchResult<import('../getUserList').IUserGroup>>) | undefined;
|
|
4
11
|
getMemberPickerItemMoreInfoKey: ((user: import('../getUserList').IUser) => string) | undefined;
|
|
5
12
|
getNextLevelGroup: ((params: {
|
|
6
13
|
parentGroupId?: string | undefined;
|
|
@@ -2,10 +2,14 @@ import GetUserListContext from "../getUserList.js";
|
|
|
2
2
|
import { useContext } from "react";
|
|
3
3
|
//#region src/ConfigProvider/hooks/useGetUserList.ts
|
|
4
4
|
function useGetUserList() {
|
|
5
|
-
const { getUsersByIds, getUsersByKeywords, getMemberPickerItemMoreInfoKey, getNextLevelGroup } = useContext(GetUserListContext);
|
|
5
|
+
const { getMemberPickerUserPage, getMemberPickerGroupPage, getUsersByIds, getUsersByKeywords, getUsersByKeywordsWithMeta, getNextLevelGroupWithMeta, getMemberPickerItemMoreInfoKey, getNextLevelGroup } = useContext(GetUserListContext);
|
|
6
6
|
return {
|
|
7
|
+
getMemberPickerUserPage,
|
|
8
|
+
getMemberPickerGroupPage,
|
|
7
9
|
getUsersByIds,
|
|
8
10
|
getUsersByKeywords,
|
|
11
|
+
getUsersByKeywordsWithMeta,
|
|
12
|
+
getNextLevelGroupWithMeta,
|
|
9
13
|
getMemberPickerItemMoreInfoKey,
|
|
10
14
|
getNextLevelGroup
|
|
11
15
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useGetUserList.js","names":[],"sources":["../../../src/ConfigProvider/hooks/useGetUserList.ts"],"sourcesContent":["import { useContext } from 'react';\nimport GetUserListContext from '../getUserList';\n\nfunction useGetUserList() {\n const {\n getUsersByIds,\n getUsersByKeywords,\n getMemberPickerItemMoreInfoKey,\n getNextLevelGroup,\n } = useContext(GetUserListContext);\n\n return {\n getUsersByIds,\n getUsersByKeywords,\n getMemberPickerItemMoreInfoKey,\n getNextLevelGroup,\n };\n}\n\nexport default useGetUserList;\n"],"mappings":";;;AAGA,SAAS,iBAAiB;CACxB,MAAM,EACJ,eACA,oBACA,gCACA,sBACE,WAAW,mBAAmB;AAElC,QAAO;EACL;EACA;EACA;EACA;EACD"}
|
|
1
|
+
{"version":3,"file":"useGetUserList.js","names":[],"sources":["../../../src/ConfigProvider/hooks/useGetUserList.ts"],"sourcesContent":["import { useContext } from 'react';\nimport GetUserListContext from '../getUserList';\n\nfunction useGetUserList() {\n const {\n getMemberPickerUserPage,\n getMemberPickerGroupPage,\n getUsersByIds,\n getUsersByKeywords,\n getUsersByKeywordsWithMeta,\n getNextLevelGroupWithMeta,\n getMemberPickerItemMoreInfoKey,\n getNextLevelGroup,\n } = useContext(GetUserListContext);\n\n return {\n getMemberPickerUserPage,\n getMemberPickerGroupPage,\n getUsersByIds,\n getUsersByKeywords,\n getUsersByKeywordsWithMeta,\n getNextLevelGroupWithMeta,\n getMemberPickerItemMoreInfoKey,\n getNextLevelGroup,\n };\n}\n\nexport default useGetUserList;\n"],"mappings":";;;AAGA,SAAS,iBAAiB;CACxB,MAAM,EACJ,yBACA,0BACA,eACA,oBACA,4BACA,2BACA,gCACA,sBACE,WAAW,mBAAmB;AAElC,QAAO;EACL;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACD"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { default as React } from 'react';
|
|
2
|
-
import { IUser, IUserGroup, getUsersByIdsType, getUsersByKeywordsType } from './getUserList.js';
|
|
2
|
+
import { IUser, IUserGroup, getUsersByIdsType, getUserListType, getUsersByKeywordsType } from './getUserList.js';
|
|
3
3
|
import { default as useGetUserList } from './hooks/useGetUserList.js';
|
|
4
4
|
import { default as SizeContext, SizeType } from './sizeContext.js';
|
|
5
5
|
export declare const ConfigContext: React.Context<{
|
|
@@ -25,8 +25,12 @@ export type configConsumerProps = any;
|
|
|
25
25
|
export type globalConfig = any;
|
|
26
26
|
interface AldCustomConfigProviderProps {
|
|
27
27
|
children?: React.ReactNode;
|
|
28
|
+
getMemberPickerUserPage?: getUserListType['getMemberPickerUserPage'];
|
|
29
|
+
getMemberPickerGroupPage?: getUserListType['getMemberPickerGroupPage'];
|
|
28
30
|
getUsersByIds?: getUsersByIdsType;
|
|
29
31
|
getUsersByKeywords?: getUsersByKeywordsType;
|
|
32
|
+
getUsersByKeywordsWithMeta?: getUserListType['getUsersByKeywordsWithMeta'];
|
|
33
|
+
getNextLevelGroupWithMeta?: getUserListType['getNextLevelGroupWithMeta'];
|
|
30
34
|
getMemberPickerItemMoreInfoKey?: (user: IUser) => string;
|
|
31
35
|
getNextLevelGroup?: (params: {
|
|
32
36
|
parentGroupId?: string;
|
|
@@ -12,7 +12,7 @@ var ConfigContext = createContext({ getPrefixCls: (suffixCls, customizePrefixCls
|
|
|
12
12
|
} });
|
|
13
13
|
ConfigContext.Consumer;
|
|
14
14
|
var AldCustomConfigProvider = (props) => {
|
|
15
|
-
const { children, getUsersByIds, getUsersByKeywords, getMemberPickerItemMoreInfoKey, getNextLevelGroup, componentSize, componentDisabled, prefixCls = "ald", direction, virtual } = props;
|
|
15
|
+
const { children, getMemberPickerUserPage, getMemberPickerGroupPage, getUsersByIds, getUsersByKeywords, getUsersByKeywordsWithMeta, getNextLevelGroupWithMeta, getMemberPickerItemMoreInfoKey, getNextLevelGroup, componentSize, componentDisabled, prefixCls = "ald", direction, virtual } = props;
|
|
16
16
|
const config = React.useMemo(() => ({
|
|
17
17
|
getPrefixCls: (suffixCls, customizePrefixCls) => {
|
|
18
18
|
if (customizePrefixCls) return customizePrefixCls;
|
|
@@ -26,10 +26,14 @@ var AldCustomConfigProvider = (props) => {
|
|
|
26
26
|
virtual
|
|
27
27
|
]);
|
|
28
28
|
let childNode = children;
|
|
29
|
-
if (getUsersByIds || getUsersByKeywords) childNode = /* @__PURE__ */ jsx(GetUserListContext.Provider, {
|
|
29
|
+
if (getMemberPickerUserPage || getMemberPickerGroupPage || getUsersByIds || getUsersByKeywords || getNextLevelGroup || getUsersByKeywordsWithMeta || getNextLevelGroupWithMeta) childNode = /* @__PURE__ */ jsx(GetUserListContext.Provider, {
|
|
30
30
|
value: {
|
|
31
|
+
getMemberPickerUserPage,
|
|
32
|
+
getMemberPickerGroupPage,
|
|
31
33
|
getUsersByIds,
|
|
32
34
|
getUsersByKeywords,
|
|
35
|
+
getUsersByKeywordsWithMeta,
|
|
36
|
+
getNextLevelGroupWithMeta,
|
|
33
37
|
getMemberPickerItemMoreInfoKey,
|
|
34
38
|
getNextLevelGroup
|
|
35
39
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/ConfigProvider/index.tsx"],"sourcesContent":["import React, { createContext } from 'react';\nimport { LocaleContext, defaultLocale } from '../locale/default';\nimport DisabledContext from './DisabledContext';\nimport getUserListContext, {\n IUser,\n IUserGroup,\n getUsersByIdsType,\n getUsersByKeywordsType,\n} from './getUserList';\nimport useGetUserList from './hooks/useGetUserList';\nimport SizeContext, { type SizeType } from './sizeContext';\n\nexport const ConfigContext = createContext<{\n getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => string;\n direction?: 'ltr' | 'rtl';\n virtual?: boolean;\n}>({\n getPrefixCls: (suffixCls, customizePrefixCls) => {\n if (customizePrefixCls) return customizePrefixCls;\n return suffixCls ? `ald-${suffixCls}` : 'ald';\n },\n});\n\nexport const ConfigConsumer = ConfigContext.Consumer;\n\nexport type CSPConfig = { nonce?: string };\nexport type DirectionType = 'ltr' | 'rtl';\nexport type RenderEmptyHandler = (componentName?: string) => React.ReactNode;\nexport type ConfigConsumerProps = {\n getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => string;\n direction?: DirectionType;\n};\n\nexport type configConsumerProps = any;\n\nexport type globalConfig = any;\n\ninterface AldCustomConfigProviderProps {\n children?: React.ReactNode;\n getUsersByIds?: getUsersByIdsType;\n getUsersByKeywords?: getUsersByKeywordsType;\n getMemberPickerItemMoreInfoKey?: (user: IUser) => string;\n getNextLevelGroup?: (params: {\n parentGroupId?: string;\n keyword: string;\n }) => Promise<IUserGroup[]>;\n locale?: any;\n theme?: any;\n componentSize?: SizeType;\n componentDisabled?: boolean;\n prefixCls?: string;\n direction?: DirectionType;\n virtual?: boolean;\n}\n\nconst AldCustomConfigProvider: React.FC<AldCustomConfigProviderProps> & {\n ConfigContext: typeof ConfigContext;\n SizeContext: typeof SizeContext;\n useConfig: () => { componentSize: string };\n useGetUserList: typeof useGetUserList;\n} = (props) => {\n const {\n children,\n getUsersByIds,\n getUsersByKeywords,\n getMemberPickerItemMoreInfoKey,\n getNextLevelGroup,\n componentSize,\n componentDisabled,\n prefixCls = 'ald',\n direction,\n virtual,\n } = props;\n\n const config = React.useMemo(\n () => ({\n getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => {\n if (customizePrefixCls) return customizePrefixCls;\n return suffixCls ? `${prefixCls}-${suffixCls}` : prefixCls;\n },\n direction,\n virtual,\n }),\n [direction, prefixCls, virtual],\n );\n\n let childNode = children;\n if (getUsersByIds
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/ConfigProvider/index.tsx"],"sourcesContent":["import React, { createContext } from 'react';\nimport { LocaleContext, defaultLocale } from '../locale/default';\nimport DisabledContext from './DisabledContext';\nimport getUserListContext, {\n IUser,\n IUserGroup,\n getUsersByIdsType,\n getUserListType,\n getUsersByKeywordsType,\n} from './getUserList';\nimport useGetUserList from './hooks/useGetUserList';\nimport SizeContext, { type SizeType } from './sizeContext';\n\nexport const ConfigContext = createContext<{\n getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => string;\n direction?: 'ltr' | 'rtl';\n virtual?: boolean;\n}>({\n getPrefixCls: (suffixCls, customizePrefixCls) => {\n if (customizePrefixCls) return customizePrefixCls;\n return suffixCls ? `ald-${suffixCls}` : 'ald';\n },\n});\n\nexport const ConfigConsumer = ConfigContext.Consumer;\n\nexport type CSPConfig = { nonce?: string };\nexport type DirectionType = 'ltr' | 'rtl';\nexport type RenderEmptyHandler = (componentName?: string) => React.ReactNode;\nexport type ConfigConsumerProps = {\n getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => string;\n direction?: DirectionType;\n};\n\nexport type configConsumerProps = any;\n\nexport type globalConfig = any;\n\ninterface AldCustomConfigProviderProps {\n children?: React.ReactNode;\n getMemberPickerUserPage?: getUserListType['getMemberPickerUserPage'];\n getMemberPickerGroupPage?: getUserListType['getMemberPickerGroupPage'];\n getUsersByIds?: getUsersByIdsType;\n getUsersByKeywords?: getUsersByKeywordsType;\n getUsersByKeywordsWithMeta?: getUserListType['getUsersByKeywordsWithMeta'];\n getNextLevelGroupWithMeta?: getUserListType['getNextLevelGroupWithMeta'];\n getMemberPickerItemMoreInfoKey?: (user: IUser) => string;\n getNextLevelGroup?: (params: {\n parentGroupId?: string;\n keyword: string;\n }) => Promise<IUserGroup[]>;\n locale?: any;\n theme?: any;\n componentSize?: SizeType;\n componentDisabled?: boolean;\n prefixCls?: string;\n direction?: DirectionType;\n virtual?: boolean;\n}\n\nconst AldCustomConfigProvider: React.FC<AldCustomConfigProviderProps> & {\n ConfigContext: typeof ConfigContext;\n SizeContext: typeof SizeContext;\n useConfig: () => { componentSize: string };\n useGetUserList: typeof useGetUserList;\n} = (props) => {\n const {\n children,\n getMemberPickerUserPage,\n getMemberPickerGroupPage,\n getUsersByIds,\n getUsersByKeywords,\n getUsersByKeywordsWithMeta,\n getNextLevelGroupWithMeta,\n getMemberPickerItemMoreInfoKey,\n getNextLevelGroup,\n componentSize,\n componentDisabled,\n prefixCls = 'ald',\n direction,\n virtual,\n } = props;\n\n const config = React.useMemo(\n () => ({\n getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => {\n if (customizePrefixCls) return customizePrefixCls;\n return suffixCls ? `${prefixCls}-${suffixCls}` : prefixCls;\n },\n direction,\n virtual,\n }),\n [direction, prefixCls, virtual],\n );\n\n let childNode = children;\n if (\n getMemberPickerUserPage ||\n getMemberPickerGroupPage ||\n getUsersByIds ||\n getUsersByKeywords ||\n getNextLevelGroup ||\n getUsersByKeywordsWithMeta ||\n getNextLevelGroupWithMeta\n ) {\n childNode = (\n <getUserListContext.Provider\n value={{\n getMemberPickerUserPage,\n getMemberPickerGroupPage,\n getUsersByIds,\n getUsersByKeywords,\n getUsersByKeywordsWithMeta,\n getNextLevelGroupWithMeta,\n getMemberPickerItemMoreInfoKey,\n getNextLevelGroup,\n }}\n >\n {children}\n </getUserListContext.Provider>\n );\n }\n\n return (\n <LocaleContext.Provider value={props.locale || defaultLocale}>\n <ConfigContext.Provider value={config}>\n <SizeContext.Provider value={componentSize}>\n <DisabledContext.Provider value={componentDisabled}>\n {childNode}\n </DisabledContext.Provider>\n </SizeContext.Provider>\n </ConfigContext.Provider>\n </LocaleContext.Provider>\n );\n};\n\nAldCustomConfigProvider.ConfigContext = ConfigContext;\nAldCustomConfigProvider.SizeContext = SizeContext;\nAldCustomConfigProvider.useConfig = () => ({ componentSize: 'middle' });\nAldCustomConfigProvider.useGetUserList = useGetUserList;\n\nexport default AldCustomConfigProvider;\n"],"mappings":";;;;;;;;AAaA,IAAa,gBAAgB,cAI1B,EACD,eAAe,WAAW,uBAAuB;AAC/C,KAAI,mBAAoB,QAAO;AAC/B,QAAO,YAAY,OAAO,cAAc;GAE3C,CAAC;AAE4B,cAAc;AAoC5C,IAAM,2BAKD,UAAU;CACb,MAAM,EACJ,UACA,yBACA,0BACA,eACA,oBACA,4BACA,2BACA,gCACA,mBACA,eACA,mBACA,YAAY,OACZ,WACA,YACE;CAEJ,MAAM,SAAS,MAAM,eACZ;EACL,eAAe,WAAoB,uBAAgC;AACjE,OAAI,mBAAoB,QAAO;AAC/B,UAAO,YAAY,GAAG,UAAU,GAAG,cAAc;;EAEnD;EACA;EACD,GACD;EAAC;EAAW;EAAW;EAAQ,CAChC;CAED,IAAI,YAAY;AAChB,KACE,2BACA,4BACA,iBACA,sBACA,qBACA,8BACA,0BAEA,aACE,oBAAC,mBAAmB,UAApB;EACE,OAAO;GACL;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD;EAEA;EAC2B,CAAA;AAIlC,QACE,oBAAC,cAAc,UAAf;EAAwB,OAAO,MAAM,UAAU;YAC7C,oBAAC,cAAc,UAAf;GAAwB,OAAO;aAC7B,oBAAC,YAAY,UAAb;IAAsB,OAAO;cAC3B,oBAAC,gBAAgB,UAAjB;KAA0B,OAAO;eAC9B;KACwB,CAAA;IACN,CAAA;GACA,CAAA;EACF,CAAA;;AAI7B,wBAAwB,gBAAgB;AACxC,wBAAwB,cAAc;AACtC,wBAAwB,mBAAmB,EAAE,eAAe,UAAU;AACtE,wBAAwB,iBAAiB"}
|
package/dist/Dropdown/index.d.ts
CHANGED
|
@@ -98,9 +98,14 @@ export interface IDropdownProps {
|
|
|
98
98
|
*/
|
|
99
99
|
popupMatchTriggerWidth?: boolean | number;
|
|
100
100
|
/**
|
|
101
|
-
* @description
|
|
102
|
-
* @default
|
|
101
|
+
* @description 空间不足时允许浮层覆盖触发器;空间充足时保留 placement 和 offset。设为 false 禁止覆盖。
|
|
102
|
+
* @default true
|
|
103
103
|
*/
|
|
104
104
|
allowOverlap?: boolean;
|
|
105
|
+
/**
|
|
106
|
+
* @description 内容超出浮层实际可用区域时限制高度并滚动。默认 body 浮层以视口为界;自定义容器保留自身裁剪边界。
|
|
107
|
+
* @default true
|
|
108
|
+
*/
|
|
109
|
+
autoAdjustHeight?: boolean;
|
|
105
110
|
}
|
|
106
111
|
export default function Dropdown(props: IDropdownProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/Dropdown/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { cn } from "../lib/utils.js";
|
|
2
2
|
import { useFloatingPopupZIndex } from "../_utils/floatingLayer.js";
|
|
3
3
|
/* empty css */
|
|
4
|
-
import Menu from "../Menu/index.js";
|
|
4
|
+
import Menu, { isLeafMenu } from "../Menu/index.js";
|
|
5
5
|
import { ensureWeakRefFallback } from "../_utils/weakRefFallback.js";
|
|
6
6
|
import { cloneElement, useCallback, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
7
7
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -40,7 +40,7 @@ function hasTrigger(trigger, action) {
|
|
|
40
40
|
return Array.isArray(trigger) ? trigger.includes(action) : trigger === action;
|
|
41
41
|
}
|
|
42
42
|
function Dropdown(props) {
|
|
43
|
-
const { children, destroyPopupOnHide = true, getPopupContainer, menu, overlayClassName, placement = "bottom-start", trigger = "click", open, onOpenChange = () => {}, closeOnFocusOut = true, overlayStyle, overlayInnerStyle, dropdownRender, disabled, offset: offsetProps = 4, delay = 0, autoUpdatePos = false, initialFocus = -1, popupMatchTriggerWidth = false, allowOverlap =
|
|
43
|
+
const { children, destroyPopupOnHide = true, getPopupContainer, menu, overlayClassName, placement = "bottom-start", trigger = "click", open, onOpenChange = () => {}, closeOnFocusOut = true, overlayStyle, overlayInnerStyle, dropdownRender, disabled, offset: offsetProps = 4, delay = 0, autoUpdatePos = false, initialFocus = -1, popupMatchTriggerWidth = false, allowOverlap = true, autoAdjustHeight = true } = props;
|
|
44
44
|
const [isOpen, setIsOpen] = useState(open || false);
|
|
45
45
|
const lastResolvedFloatingStylesRef = useRef(null);
|
|
46
46
|
const lastResolvedSideRef = useRef(resolvePlacementSide(placement));
|
|
@@ -65,6 +65,8 @@ function Dropdown(props) {
|
|
|
65
65
|
if (!isOpenControlled) setIsOpen(newOpen);
|
|
66
66
|
onOpenChangeFn(newOpen);
|
|
67
67
|
}, [isOpenControlled, onOpenChangeFn]);
|
|
68
|
+
const hasSubmenu = !isLeafMenu(menu?.items || []);
|
|
69
|
+
const surfaceScrolls = autoAdjustHeight && !hasSubmenu;
|
|
68
70
|
const nodeId = useFloatingNodeId();
|
|
69
71
|
const { refs, floatingStyles, context, placement: floatingPlacement, x, y } = useFloating({
|
|
70
72
|
nodeId,
|
|
@@ -72,23 +74,30 @@ function Dropdown(props) {
|
|
|
72
74
|
open: isOpen,
|
|
73
75
|
onOpenChange: onChangeOpen,
|
|
74
76
|
middleware: [
|
|
75
|
-
offset(
|
|
76
|
-
flip({
|
|
77
|
-
padding: 8,
|
|
78
|
-
...allowOverlap && { fallbackStrategy: "bestFit" }
|
|
79
|
-
}),
|
|
77
|
+
offset(offsetProps),
|
|
78
|
+
flip({ padding: 8 }),
|
|
80
79
|
shift({
|
|
81
80
|
padding: 8,
|
|
82
|
-
...allowOverlap && {
|
|
81
|
+
...allowOverlap && { crossAxis: true }
|
|
83
82
|
}),
|
|
84
83
|
size({
|
|
85
|
-
|
|
86
|
-
...allowOverlap && { padding: 8 },
|
|
84
|
+
padding: 8,
|
|
87
85
|
apply({ availableHeight, elements }) {
|
|
88
|
-
if (!
|
|
89
|
-
|
|
86
|
+
if (!autoAdjustHeight) {
|
|
87
|
+
elements.floating.style.removeProperty("--ald-dropdown-max-height");
|
|
88
|
+
elements.floating.style.removeProperty("--ald-dropdown-menu-max-height");
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
const maxHeight = Math.max(0, availableHeight);
|
|
92
|
+
elements.floating.style.setProperty("--ald-dropdown-max-height", `${maxHeight}px`);
|
|
93
|
+
if (hasSubmenu) {
|
|
94
|
+
const surface = elements.floating.firstElementChild;
|
|
95
|
+
const menuElement = surface?.querySelector(".ald-menu > .szh-menu");
|
|
96
|
+
const extraHeight = surface && menuElement ? Math.max(0, surface.offsetHeight - menuElement.offsetHeight) : 0;
|
|
97
|
+
elements.floating.style.setProperty("--ald-dropdown-menu-max-height", `${Math.max(0, maxHeight - extraHeight)}px`);
|
|
98
|
+
}
|
|
90
99
|
}
|
|
91
|
-
})
|
|
100
|
+
}, [autoAdjustHeight, hasSubmenu])
|
|
92
101
|
],
|
|
93
102
|
whileElementsMounted: autoUpdatePos ? autoUpdate : void 0
|
|
94
103
|
});
|
|
@@ -243,14 +252,10 @@ function Dropdown(props) {
|
|
|
243
252
|
onChangeOpen(false);
|
|
244
253
|
}, [menu, onChangeOpen]);
|
|
245
254
|
const onMenuRequestClose = useCallback((reason) => {
|
|
246
|
-
if (reason === "blur"
|
|
255
|
+
if (reason === "blur") return;
|
|
247
256
|
onChangeOpen(false);
|
|
248
257
|
if (reason === "cancel") window.setTimeout(() => targetElement?.focus(), 0);
|
|
249
|
-
}, [
|
|
250
|
-
closeOnFocusOut,
|
|
251
|
-
onChangeOpen,
|
|
252
|
-
targetElement
|
|
253
|
-
]);
|
|
258
|
+
}, [onChangeOpen, targetElement]);
|
|
254
259
|
const menuInstance = useMemo(() => {
|
|
255
260
|
return /* @__PURE__ */ jsx(Menu, {
|
|
256
261
|
...menu,
|
|
@@ -261,6 +266,7 @@ function Dropdown(props) {
|
|
|
261
266
|
minWidth: 0,
|
|
262
267
|
maxWidth: "none"
|
|
263
268
|
} : void 0,
|
|
269
|
+
...autoAdjustHeight && hasSubmenu ? { maxHeight: "var(--ald-dropdown-menu-max-height)" } : void 0,
|
|
264
270
|
...menu?.menuStyle
|
|
265
271
|
},
|
|
266
272
|
onBeforeLeafItemClick: isOpenControlled ? void 0 : markRootClosing,
|
|
@@ -268,10 +274,13 @@ function Dropdown(props) {
|
|
|
268
274
|
initialFocus: menuInitialFocus,
|
|
269
275
|
onRequestClose: onMenuRequestClose,
|
|
270
276
|
onClick: onMenuItemClick,
|
|
271
|
-
externalOverflow:
|
|
277
|
+
externalOverflow: surfaceScrolls,
|
|
278
|
+
preserveRootHeight: autoAdjustHeight && hasSubmenu && menu?.menuStyle?.maxHeight === void 0
|
|
272
279
|
});
|
|
273
280
|
}, [
|
|
274
|
-
|
|
281
|
+
autoAdjustHeight,
|
|
282
|
+
hasSubmenu,
|
|
283
|
+
surfaceScrolls,
|
|
275
284
|
isAnimatingOut,
|
|
276
285
|
isOpenControlled,
|
|
277
286
|
markRootClosing,
|
|
@@ -325,7 +334,7 @@ function Dropdown(props) {
|
|
|
325
334
|
},
|
|
326
335
|
"aria-labelledby": headingId,
|
|
327
336
|
children: /* @__PURE__ */ jsx("div", {
|
|
328
|
-
className: cn("ald-dropdown-surface",
|
|
337
|
+
className: cn("ald-dropdown-surface", surfaceScrolls && "ald-dropdown-surface-overlap", "tw-flex tw-flex-col tw-items-start tw-text-sm"),
|
|
329
338
|
style: {
|
|
330
339
|
...matchedSurfaceStyle,
|
|
331
340
|
...overlayInnerStyle,
|
|
@@ -360,7 +369,7 @@ function Dropdown(props) {
|
|
|
360
369
|
closeOnFocusOut,
|
|
361
370
|
resolvedFloatingSide,
|
|
362
371
|
resolvedFloatingStyles,
|
|
363
|
-
|
|
372
|
+
surfaceScrolls
|
|
364
373
|
]);
|
|
365
374
|
const popup = shouldKeepMounted ? renderFloatingContent() : null;
|
|
366
375
|
const { setReference } = refs;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/Dropdown/index.tsx"],"sourcesContent":["import './dropdown.css';\nimport {\n FloatingFocusManager,\n FloatingFocusManagerProps,\n FloatingNode,\n FloatingTree,\n OffsetOptions,\n UseHoverProps,\n autoUpdate,\n flip,\n offset,\n safePolygon,\n shift,\n size,\n useClick,\n useDismiss,\n useFloating,\n useFloatingNodeId,\n useFloatingParentNodeId,\n useHover,\n useId,\n useInteractions,\n useTransitionStyles,\n} from '@floating-ui/react';\nimport type { Placement } from '@floating-ui/react';\nimport { useMemoizedFn } from 'ahooks';\nimport { cn } from '../lib/utils';\nimport React, {\n cloneElement,\n useCallback,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport ReactDOM from 'react-dom';\nimport Menu, { MenuInfo, MenuProps } from '../Menu';\nimport { useFloatingPopupZIndex } from '../_utils/floatingLayer';\nimport { ensureWeakRefFallback } from '../_utils/weakRefFallback';\n\nconst OVERLAY_TRANSITION_MS = 200;\n\nensureWeakRefFallback();\n\nfunction resolvePlacementSide(\n currentPlacement: string,\n): 'top' | 'bottom' | 'left' | 'right' {\n const [side] = currentPlacement.split('-');\n if (\n side === 'top' ||\n side === 'bottom' ||\n side === 'left' ||\n side === 'right'\n ) {\n return side;\n }\n if (currentPlacement.startsWith('top')) {\n return 'top';\n }\n if (currentPlacement.startsWith('bottom')) {\n return 'bottom';\n }\n if (currentPlacement.startsWith('left')) {\n return 'left';\n }\n if (currentPlacement.startsWith('right')) {\n return 'right';\n }\n return 'bottom';\n}\n\nfunction parsePopupMatchWidth(value: unknown): number | undefined {\n if (typeof value === 'number') {\n return value;\n }\n\n if (typeof value === 'string' && value.trim() !== '') {\n const parsedValue = Number(value);\n return Number.isNaN(parsedValue) ? undefined : parsedValue;\n }\n\n return undefined;\n}\n\nexport type ActionType = 'hover' | 'click' | 'contextMenu';\nexport type PlacementType =\n | 'top'\n | 'bottom'\n | 'left'\n | 'right'\n | 'top-start'\n | 'top-end'\n | 'bottom-start'\n | 'bottom-end'\n | 'left-start'\n | 'left-end'\n | 'right-start'\n | 'right-end'\n // Legacy antd-style placement names\n | 'topLeft'\n | 'topRight'\n | 'bottomLeft'\n | 'bottomRight';\n\nconst legacyPlacementMap = {\n topLeft: 'top-start',\n topRight: 'top-end',\n bottomLeft: 'bottom-start',\n bottomRight: 'bottom-end',\n} as const;\n\nfunction normalizePlacement(placement: PlacementType): Placement {\n return (legacyPlacementMap[placement as keyof typeof legacyPlacementMap] ??\n placement) as Placement;\n}\n\nexport interface IDropdownProps {\n children: React.ReactNode;\n /**\n * @description 菜单弹出位置的偏移量\n */\n offset?: OffsetOptions;\n /**\n * @description 关闭后是否销毁 Dropdown\n * @default false\n */\n destroyPopupOnHide?: boolean;\n /**\n * @description 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位\n * @default () => document.body\n */\n getPopupContainer?: () => HTMLElement;\n /**\n * @description 菜单\n * @type Menu | () => Menu\n * @default -\n */\n menu?: MenuProps;\n // /**\n // * @description 菜单\n // * @type Menu | () => Menu\n // * @default -\n // */\n // menu?: ReactElement | (() => ReactElement);\n /**\n * @description 下拉根元素的类名称\n * @default -\n */\n overlayClassName?: string;\n /**\n * @description 菜单弹出位置\n * @default bottomLeft\n */\n placement?: PlacementType;\n /**\n * @description 触发下拉的行为\n * @type ActionType, 其中 ActionType 为 'hover' | 'click' | 'contextMenu';\n * @default click\n */\n trigger?: ActionType | ActionType[];\n /**\n * @description 菜单是否显示\n * @default -\n */\n open?: boolean;\n /**\n * @description 菜单显示状态改变时调用,参数为 open,点击菜单按钮导致的消失不会触发\n * @default -\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * @description 焦点移出触发元素和浮层时是否关闭 Dropdown\n * @default true\n */\n closeOnFocusOut?: boolean;\n /**\n * @description 下拉框外层 overlay 的内联样式(与定位 transform 合并)\n * @default -\n */\n overlayStyle?: React.CSSProperties;\n /**\n * @description 下拉框内层 surface 的内联样式。\n * 用于覆盖 surface 默认约束(默认 min-width:160px、max-width:320px);\n * 自定义 dropdownRender 内容若需大于 320px 宽,传 `{ width: 400, maxWidth: 'none' }` 即可。\n * @default -\n */\n overlayInnerStyle?: React.CSSProperties;\n\n /**\n * @description 自定义下拉框内容\n * @default -\n */\n dropdownRender?: (menus: React.ReactNode) => React.ReactNode;\n /**\n * @description 是否禁用\n * @default false\n */\n // 透传给子元素,antd的dropdown用cloneElement生成dropdown的子元素,劫持了disabled属性,因此如果Dropdown上没有disabled属性,子元素不能获得该属性\n disabled?: boolean;\n /**\n * @description 鼠标移入后延迟显示下拉框的时间,单位为毫秒\n * @default 0\n */\n delay?: UseHoverProps['delay'];\n /**\n * @description 是否在下拉框变化的时候自动更新位置\n * @default false\n */\n autoUpdatePos?: boolean;\n /**\n * @description 初始化焦点,参照:https://floating-ui.com/docs/floatingfocusmanager#initialfocus\n */\n initialFocus?: FloatingFocusManagerProps['initialFocus'];\n\n /**\n * @description 菜单是否跟随触发元素宽度\n * @default false\n */\n popupMatchTriggerWidth?: boolean | number;\n /**\n * @description 空间不足时自动计算菜单最大高度并启用滚动,启用后 offset 固定为 0\n * @default false\n */\n allowOverlap?: boolean;\n}\n\nfunction hasTrigger(\n trigger: ActionType | ActionType[],\n action: ActionType,\n): boolean {\n return Array.isArray(trigger) ? trigger.includes(action) : trigger === action;\n}\n\nexport default function Dropdown(props: IDropdownProps) {\n const {\n children,\n destroyPopupOnHide = true,\n getPopupContainer,\n menu,\n overlayClassName,\n placement = 'bottom-start',\n trigger = 'click',\n open,\n onOpenChange = () => {},\n closeOnFocusOut = true,\n overlayStyle,\n overlayInnerStyle,\n dropdownRender,\n disabled,\n offset: offsetProps = 4,\n delay = 0,\n autoUpdatePos = false,\n // 默认不自动 focus\n initialFocus = -1,\n popupMatchTriggerWidth = false,\n allowOverlap = false,\n } = props;\n const [isOpen, setIsOpen] = useState<boolean>(open || false);\n const lastResolvedFloatingStylesRef = useRef<React.CSSProperties | null>(\n null,\n );\n const lastResolvedSideRef = useRef<'top' | 'bottom' | 'left' | 'right'>(\n resolvePlacementSide(placement),\n );\n const currentFloatingStylesRef = useRef<React.CSSProperties | null>(null);\n const currentFloatingSideRef = useRef<'top' | 'bottom' | 'left' | 'right'>(\n resolvePlacementSide(placement),\n );\n const [targetElement, setTargetElement] = useState<HTMLElement | null>(null);\n const [menuInitialFocus, setMenuInitialFocus] = useState<'first' | 'last'>(\n 'first',\n );\n const popupMatchTriggerWidthNumber = parsePopupMatchWidth(\n popupMatchTriggerWidth,\n );\n const [matchedTriggerWidth, setMatchedTriggerWidth] = useState<\n number | undefined\n >(popupMatchTriggerWidthNumber);\n const popupZIndex = useFloatingPopupZIndex();\n\n const onOpenChangeFn = useMemoizedFn(onOpenChange);\n const isOpenControlled = open !== undefined;\n\n const markRootClosing = useCallback(() => {\n document.body.classList.add('ald-dropdown-root-closing');\n lastResolvedFloatingStylesRef.current =\n currentFloatingStylesRef.current ?? lastResolvedFloatingStylesRef.current;\n lastResolvedSideRef.current =\n currentFloatingSideRef.current ?? lastResolvedSideRef.current;\n }, []);\n\n useLayoutEffect(() => {\n if (isOpenControlled) {\n setIsOpen(!!open);\n }\n }, [isOpenControlled, open]);\n\n const onChangeOpen = useCallback(\n (newOpen: boolean) => {\n if (!isOpenControlled) {\n setIsOpen(newOpen);\n }\n onOpenChangeFn(newOpen);\n },\n [isOpenControlled, onOpenChangeFn],\n );\n\n const nodeId = useFloatingNodeId();\n const normalizedPlacement = normalizePlacement(placement);\n const {\n refs,\n floatingStyles,\n context,\n placement: floatingPlacement,\n x,\n y,\n } = useFloating({\n nodeId,\n placement: normalizedPlacement,\n open: isOpen,\n onOpenChange: onChangeOpen,\n middleware: [\n offset(allowOverlap ? 0 : offsetProps),\n flip({\n padding: 8,\n ...(allowOverlap && { fallbackStrategy: 'bestFit' }),\n }),\n shift({\n padding: 8,\n ...(allowOverlap && { mainAxis: true }),\n }),\n size({\n altBoundary: true,\n ...(allowOverlap && { padding: 8 }),\n apply({ availableHeight, elements }) {\n if (!allowOverlap) {\n return;\n }\n\n elements.floating.style.setProperty(\n '--ald-dropdown-max-height',\n `${Math.max(100, availableHeight)}px`,\n );\n },\n }),\n ],\n whileElementsMounted: autoUpdatePos ? autoUpdate : undefined,\n });\n const { isMounted, styles: transitionStyles } = useTransitionStyles(context, {\n duration: OVERLAY_TRANSITION_MS,\n initial: {\n opacity: 0,\n transform: 'var(--ald-dropdown-enter-transform)',\n },\n close: {\n opacity: 0,\n transform: 'var(--ald-dropdown-exit-transform)',\n },\n common: {\n transitionTimingFunction: 'ease-in-out',\n },\n });\n const isAnimatingOut = !isOpen && isMounted;\n\n useLayoutEffect(() => {\n if (isAnimatingOut) {\n document.body.classList.add('ald-dropdown-root-closing');\n } else {\n document.body.classList.remove('ald-dropdown-root-closing');\n }\n\n return () => {\n if (isAnimatingOut) {\n document.body.classList.remove('ald-dropdown-root-closing');\n }\n };\n }, [isAnimatingOut]);\n\n const click = useClick(context, {\n enabled: hasTrigger(trigger, 'click'),\n });\n const hover = useHover(context, {\n enabled: hasTrigger(trigger, 'hover'),\n handleClose: safePolygon({}),\n delay: delay,\n });\n const dismiss = useDismiss(context, {});\n\n const propsList = useMemo(() => {\n const res = [dismiss];\n\n if (hasTrigger(trigger, 'hover')) {\n res.unshift(hover);\n }\n if (hasTrigger(trigger, 'click')) {\n res.unshift(click);\n }\n return res;\n }, [trigger, click, dismiss, hover]);\n\n const { getReferenceProps, getFloatingProps } = useInteractions(propsList);\n\n const headingId = useId();\n\n useLayoutEffect(() => {\n if (!popupMatchTriggerWidth || !isOpen) {\n setMatchedTriggerWidth(undefined);\n return;\n }\n\n if (popupMatchTriggerWidthNumber !== undefined) {\n setMatchedTriggerWidth(popupMatchTriggerWidthNumber);\n return;\n }\n\n const referenceElement = targetElement;\n if (!referenceElement) {\n return;\n }\n\n const updateMatchedWidth = () => {\n const nextWidth = referenceElement.getBoundingClientRect().width;\n setMatchedTriggerWidth((currentWidth) =>\n currentWidth === nextWidth ? currentWidth : nextWidth,\n );\n };\n\n updateMatchedWidth();\n\n if (typeof ResizeObserver === 'undefined') {\n window.addEventListener('resize', updateMatchedWidth);\n return () => {\n window.removeEventListener('resize', updateMatchedWidth);\n };\n }\n\n let resizeAnimationFrame: number | undefined;\n const scheduleMatchedWidthUpdate = () => {\n if (resizeAnimationFrame !== undefined) {\n cancelAnimationFrame(resizeAnimationFrame);\n }\n resizeAnimationFrame = requestAnimationFrame(updateMatchedWidth);\n };\n\n const observer = new ResizeObserver(scheduleMatchedWidthUpdate);\n observer.observe(referenceElement);\n\n return () => {\n if (resizeAnimationFrame !== undefined) {\n cancelAnimationFrame(resizeAnimationFrame);\n }\n observer.disconnect();\n };\n }, [\n isOpen,\n popupMatchTriggerWidth,\n popupMatchTriggerWidthNumber,\n targetElement,\n ]);\n\n const child = children as React.ReactElement;\n const childProps = child.props || {};\n const referenceProps = getReferenceProps();\n const updateMatchedWidthFromElement = useCallback(\n (element: HTMLElement) => {\n if (!popupMatchTriggerWidth) {\n return;\n }\n\n setMatchedTriggerWidth((currentWidth) => {\n const nextWidth =\n popupMatchTriggerWidthNumber !== undefined\n ? popupMatchTriggerWidthNumber\n : element.getBoundingClientRect().width;\n return currentWidth === nextWidth ? currentWidth : nextWidth;\n });\n },\n [popupMatchTriggerWidth, popupMatchTriggerWidthNumber],\n );\n const openMenuFromKeyboard = useCallback(\n (event: React.KeyboardEvent<HTMLElement>, position: 'first' | 'last') => {\n if (disabled) {\n return;\n }\n\n event.preventDefault();\n refs.setPositionReference(event.currentTarget);\n updateMatchedWidthFromElement(event.currentTarget);\n setMenuInitialFocus(position);\n onChangeOpen(true);\n },\n [disabled, onChangeOpen, refs, updateMatchedWidthFromElement],\n );\n const modifiedChild = cloneElement(child, {\n ...childProps,\n disabled,\n // ref: (node: HTMLDivElement) => refs.setReference(node),\n ...referenceProps,\n 'aria-haspopup': menu ? 'menu' : undefined,\n 'aria-expanded': menu ? isOpen : undefined,\n onClick: (event: React.MouseEvent<HTMLElement>) => {\n refs.setPositionReference(event.currentTarget);\n updateMatchedWidthFromElement(event.currentTarget);\n setMenuInitialFocus('first');\n childProps.onClick?.(event);\n const { onClick: referenceOnClick } = referenceProps;\n if (typeof referenceOnClick === 'function') {\n referenceOnClick(event);\n }\n },\n onKeyDown: (event: React.KeyboardEvent<HTMLElement>) => {\n childProps.onKeyDown?.(event);\n if (event.defaultPrevented) {\n return;\n }\n if (event.key === 'ArrowDown') {\n openMenuFromKeyboard(event, 'first');\n return;\n }\n if (event.key === 'ArrowUp') {\n openMenuFromKeyboard(event, 'last');\n return;\n }\n if (event.key === 'Enter' || event.key === ' ') {\n openMenuFromKeyboard(event, 'first');\n return;\n }\n const { onKeyDown: referenceOnKeyDown } = referenceProps;\n if (typeof referenceOnKeyDown === 'function') {\n referenceOnKeyDown(event);\n }\n },\n onContextMenu: (event: React.MouseEvent<HTMLElement>) => {\n childProps.onContextMenu?.(event);\n if (\n event.defaultPrevented ||\n disabled ||\n !hasTrigger(trigger, 'contextMenu')\n ) {\n return;\n }\n\n event.preventDefault();\n refs.setPositionReference({\n getBoundingClientRect: () =>\n new DOMRect(event.clientX, event.clientY, 0, 0),\n });\n setMenuInitialFocus('first');\n onChangeOpen(true);\n },\n });\n\n const onMenuItemClick = useCallback(\n (info: MenuInfo) => {\n if (menu?.onClick) {\n menu.onClick(info);\n }\n if (info.keepOpen) {\n document.body.classList.remove('ald-dropdown-root-closing');\n return;\n }\n onChangeOpen(false);\n },\n [menu, onChangeOpen],\n );\n const onMenuRequestClose = useCallback(\n (reason: 'click' | 'cancel' | 'blur' | 'scroll') => {\n if (reason === 'blur' && !closeOnFocusOut) {\n return;\n }\n\n onChangeOpen(false);\n if (reason === 'cancel') {\n window.setTimeout(() => targetElement?.focus(), 0);\n }\n },\n [closeOnFocusOut, onChangeOpen, targetElement],\n );\n\n const menuInstance = useMemo(() => {\n const menuProps = {\n ...menu,\n items: menu?.items || [],\n menuStyle: {\n ...(popupMatchTriggerWidth\n ? {\n width: '100%',\n minWidth: 0,\n maxWidth: 'none',\n }\n : undefined),\n ...menu?.menuStyle,\n },\n onBeforeLeafItemClick: isOpenControlled ? undefined : markRootClosing,\n rootClosing: isAnimatingOut,\n initialFocus: menuInitialFocus,\n onRequestClose: onMenuRequestClose,\n };\n return (\n <Menu\n {...menuProps}\n onClick={onMenuItemClick}\n externalOverflow={allowOverlap}\n />\n );\n }, [\n allowOverlap,\n isAnimatingOut,\n isOpenControlled,\n markRootClosing,\n menu,\n onMenuItemClick,\n onMenuRequestClose,\n popupMatchTriggerWidth,\n menuInitialFocus,\n ]);\n\n const popupElement = useMemo(() => {\n return typeof dropdownRender === 'function'\n ? dropdownRender(menuInstance)\n : menuInstance;\n }, [dropdownRender, menuInstance]);\n\n const mergedMatchedTriggerWidth =\n popupMatchTriggerWidthNumber ?? matchedTriggerWidth;\n const matchedOverlayStyle =\n popupMatchTriggerWidth && mergedMatchedTriggerWidth !== undefined\n ? ({\n width: `${mergedMatchedTriggerWidth}px`,\n minWidth: 0,\n } satisfies React.CSSProperties)\n : undefined;\n\n const matchedSurfaceStyle = popupMatchTriggerWidth\n ? ({\n width: '100%',\n minWidth: 0,\n maxWidth: 'none',\n } satisfies React.CSSProperties)\n : undefined;\n\n const floatingSide = resolvePlacementSide(String(floatingPlacement));\n const shouldKeepMounted = !destroyPopupOnHide || isMounted;\n const isPositionReady = x !== null && y !== null;\n const overlayHidden =\n (!isOpen && !isAnimatingOut) || (isOpen && !isPositionReady);\n const resolvedFloatingStyles = isAnimatingOut\n ? lastResolvedFloatingStylesRef.current ?? floatingStyles\n : floatingStyles;\n const resolvedFloatingSide = isAnimatingOut\n ? lastResolvedSideRef.current\n : floatingSide;\n\n if (isOpen && isPositionReady) {\n currentFloatingStylesRef.current = { ...floatingStyles };\n currentFloatingSideRef.current = floatingSide;\n lastResolvedFloatingStylesRef.current = { ...floatingStyles };\n lastResolvedSideRef.current = floatingSide;\n }\n\n // 渲染浮动内容到自定义容器\n const renderFloatingContent = useCallback(() => {\n const surface = (\n <div\n {...(isAnimatingOut ? {} : getFloatingProps())}\n className={cn(\n 'ald-dropdown-overlay',\n // tw-outline-none:FloatingFocusManager 打开时会聚焦浮层容器,不抑制 outline 会渲染出蓝色焦点框\n 'tw-pointer-events-auto tw-z-[1001] tw-max-w-none tw-outline-none',\n overlayClassName,\n { 'ald-dropdown-overlay-hidden': overlayHidden },\n )}\n ref={refs.setFloating}\n style={{\n zIndex: popupZIndex,\n ...resolvedFloatingStyles,\n ...matchedOverlayStyle,\n ...overlayStyle,\n }}\n aria-labelledby={headingId}\n >\n <div\n className={cn(\n 'ald-dropdown-surface',\n allowOverlap && 'ald-dropdown-surface-overlap',\n 'tw-flex tw-flex-col tw-items-start tw-text-sm',\n )}\n style={{\n ...matchedSurfaceStyle,\n ...overlayInnerStyle,\n ...transitionStyles,\n }}\n data-state={isOpen ? 'open' : 'closed'}\n data-side={resolvedFloatingSide}\n >\n {popupElement}\n </div>\n </div>\n );\n\n const popupElem = (\n <FloatingFocusManager\n context={context}\n disabled={isAnimatingOut}\n modal={false}\n initialFocus={initialFocus}\n closeOnFocusOut={closeOnFocusOut}\n >\n {surface}\n </FloatingFocusManager>\n );\n\n const popupContainer =\n typeof getPopupContainer === 'function'\n ? getPopupContainer()\n : document.body;\n return ReactDOM.createPortal(popupElem, popupContainer);\n }, [\n context,\n getFloatingProps,\n getPopupContainer,\n headingId,\n popupElement,\n refs.setFloating,\n overlayClassName,\n overlayStyle,\n overlayInnerStyle,\n matchedOverlayStyle,\n matchedSurfaceStyle,\n transitionStyles,\n popupZIndex,\n overlayHidden,\n isAnimatingOut,\n isOpen,\n initialFocus,\n closeOnFocusOut,\n resolvedFloatingSide,\n resolvedFloatingStyles,\n allowOverlap,\n ]);\n\n const popup = shouldKeepMounted ? renderFloatingContent() : null;\n const { setReference } = refs;\n\n const setTargetRef = useCallback(\n (node: HTMLElement | null) => {\n if (node) {\n // display: contents 元素没有 box model,getBoundingClientRect() 返回零值\n // 需要获取实际的第一个子元素作为 floating-ui 的参考元素\n const target =\n node.style.display === 'contents'\n ? (node.firstElementChild as HTMLElement) || node\n : node;\n setTargetElement((currentTarget) =>\n currentTarget === target ? currentTarget : target,\n );\n setReference(target);\n } else {\n setTargetElement(null);\n setReference(null);\n }\n },\n [setReference],\n );\n\n const content = (\n <>\n <span ref={setTargetRef} style={{ display: 'contents' }}>\n {modifiedChild}\n </span>\n <FloatingNode id={nodeId}>{popup}</FloatingNode>\n </>\n );\n\n const parentId = useFloatingParentNodeId();\n if (!parentId) {\n return <FloatingTree>{content}</FloatingTree>;\n }\n\n return content;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/Dropdown/index.tsx"],"sourcesContent":["import './dropdown.css';\nimport {\n FloatingFocusManager,\n FloatingFocusManagerProps,\n FloatingNode,\n FloatingTree,\n OffsetOptions,\n UseHoverProps,\n autoUpdate,\n flip,\n offset,\n safePolygon,\n shift,\n size,\n useClick,\n useDismiss,\n useFloating,\n useFloatingNodeId,\n useFloatingParentNodeId,\n useHover,\n useId,\n useInteractions,\n useTransitionStyles,\n} from '@floating-ui/react';\nimport type { Placement } from '@floating-ui/react';\nimport { useMemoizedFn } from 'ahooks';\nimport { cn } from '../lib/utils';\nimport React, {\n cloneElement,\n useCallback,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport ReactDOM from 'react-dom';\nimport Menu, { MenuInfo, MenuProps, isLeafMenu } from '../Menu';\nimport { useFloatingPopupZIndex } from '../_utils/floatingLayer';\nimport { ensureWeakRefFallback } from '../_utils/weakRefFallback';\n\nconst OVERLAY_TRANSITION_MS = 200;\n\nensureWeakRefFallback();\n\nfunction resolvePlacementSide(\n currentPlacement: string,\n): 'top' | 'bottom' | 'left' | 'right' {\n const [side] = currentPlacement.split('-');\n if (\n side === 'top' ||\n side === 'bottom' ||\n side === 'left' ||\n side === 'right'\n ) {\n return side;\n }\n if (currentPlacement.startsWith('top')) {\n return 'top';\n }\n if (currentPlacement.startsWith('bottom')) {\n return 'bottom';\n }\n if (currentPlacement.startsWith('left')) {\n return 'left';\n }\n if (currentPlacement.startsWith('right')) {\n return 'right';\n }\n return 'bottom';\n}\n\nfunction parsePopupMatchWidth(value: unknown): number | undefined {\n if (typeof value === 'number') {\n return value;\n }\n\n if (typeof value === 'string' && value.trim() !== '') {\n const parsedValue = Number(value);\n return Number.isNaN(parsedValue) ? undefined : parsedValue;\n }\n\n return undefined;\n}\n\nexport type ActionType = 'hover' | 'click' | 'contextMenu';\nexport type PlacementType =\n | 'top'\n | 'bottom'\n | 'left'\n | 'right'\n | 'top-start'\n | 'top-end'\n | 'bottom-start'\n | 'bottom-end'\n | 'left-start'\n | 'left-end'\n | 'right-start'\n | 'right-end'\n // Legacy antd-style placement names\n | 'topLeft'\n | 'topRight'\n | 'bottomLeft'\n | 'bottomRight';\n\nconst legacyPlacementMap = {\n topLeft: 'top-start',\n topRight: 'top-end',\n bottomLeft: 'bottom-start',\n bottomRight: 'bottom-end',\n} as const;\n\nfunction normalizePlacement(placement: PlacementType): Placement {\n return (legacyPlacementMap[placement as keyof typeof legacyPlacementMap] ??\n placement) as Placement;\n}\n\nexport interface IDropdownProps {\n children: React.ReactNode;\n /**\n * @description 菜单弹出位置的偏移量\n */\n offset?: OffsetOptions;\n /**\n * @description 关闭后是否销毁 Dropdown\n * @default false\n */\n destroyPopupOnHide?: boolean;\n /**\n * @description 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位\n * @default () => document.body\n */\n getPopupContainer?: () => HTMLElement;\n /**\n * @description 菜单\n * @type Menu | () => Menu\n * @default -\n */\n menu?: MenuProps;\n // /**\n // * @description 菜单\n // * @type Menu | () => Menu\n // * @default -\n // */\n // menu?: ReactElement | (() => ReactElement);\n /**\n * @description 下拉根元素的类名称\n * @default -\n */\n overlayClassName?: string;\n /**\n * @description 菜单弹出位置\n * @default bottomLeft\n */\n placement?: PlacementType;\n /**\n * @description 触发下拉的行为\n * @type ActionType, 其中 ActionType 为 'hover' | 'click' | 'contextMenu';\n * @default click\n */\n trigger?: ActionType | ActionType[];\n /**\n * @description 菜单是否显示\n * @default -\n */\n open?: boolean;\n /**\n * @description 菜单显示状态改变时调用,参数为 open,点击菜单按钮导致的消失不会触发\n * @default -\n */\n onOpenChange?: (open: boolean) => void;\n /**\n * @description 焦点移出触发元素和浮层时是否关闭 Dropdown\n * @default true\n */\n closeOnFocusOut?: boolean;\n /**\n * @description 下拉框外层 overlay 的内联样式(与定位 transform 合并)\n * @default -\n */\n overlayStyle?: React.CSSProperties;\n /**\n * @description 下拉框内层 surface 的内联样式。\n * 用于覆盖 surface 默认约束(默认 min-width:160px、max-width:320px);\n * 自定义 dropdownRender 内容若需大于 320px 宽,传 `{ width: 400, maxWidth: 'none' }` 即可。\n * @default -\n */\n overlayInnerStyle?: React.CSSProperties;\n\n /**\n * @description 自定义下拉框内容\n * @default -\n */\n dropdownRender?: (menus: React.ReactNode) => React.ReactNode;\n /**\n * @description 是否禁用\n * @default false\n */\n // 透传给子元素,antd的dropdown用cloneElement生成dropdown的子元素,劫持了disabled属性,因此如果Dropdown上没有disabled属性,子元素不能获得该属性\n disabled?: boolean;\n /**\n * @description 鼠标移入后延迟显示下拉框的时间,单位为毫秒\n * @default 0\n */\n delay?: UseHoverProps['delay'];\n /**\n * @description 是否在下拉框变化的时候自动更新位置\n * @default false\n */\n autoUpdatePos?: boolean;\n /**\n * @description 初始化焦点,参照:https://floating-ui.com/docs/floatingfocusmanager#initialfocus\n */\n initialFocus?: FloatingFocusManagerProps['initialFocus'];\n\n /**\n * @description 菜单是否跟随触发元素宽度\n * @default false\n */\n popupMatchTriggerWidth?: boolean | number;\n /**\n * @description 空间不足时允许浮层覆盖触发器;空间充足时保留 placement 和 offset。设为 false 禁止覆盖。\n * @default true\n */\n allowOverlap?: boolean;\n /**\n * @description 内容超出浮层实际可用区域时限制高度并滚动。默认 body 浮层以视口为界;自定义容器保留自身裁剪边界。\n * @default true\n */\n autoAdjustHeight?: boolean;\n}\n\nfunction hasTrigger(\n trigger: ActionType | ActionType[],\n action: ActionType,\n): boolean {\n return Array.isArray(trigger) ? trigger.includes(action) : trigger === action;\n}\n\nexport default function Dropdown(props: IDropdownProps) {\n const {\n children,\n destroyPopupOnHide = true,\n getPopupContainer,\n menu,\n overlayClassName,\n placement = 'bottom-start',\n trigger = 'click',\n open,\n onOpenChange = () => {},\n closeOnFocusOut = true,\n overlayStyle,\n overlayInnerStyle,\n dropdownRender,\n disabled,\n offset: offsetProps = 4,\n delay = 0,\n autoUpdatePos = false,\n // 默认不自动 focus\n initialFocus = -1,\n popupMatchTriggerWidth = false,\n allowOverlap = true,\n autoAdjustHeight = true,\n } = props;\n const [isOpen, setIsOpen] = useState<boolean>(open || false);\n const lastResolvedFloatingStylesRef = useRef<React.CSSProperties | null>(\n null,\n );\n const lastResolvedSideRef = useRef<'top' | 'bottom' | 'left' | 'right'>(\n resolvePlacementSide(placement),\n );\n const currentFloatingStylesRef = useRef<React.CSSProperties | null>(null);\n const currentFloatingSideRef = useRef<'top' | 'bottom' | 'left' | 'right'>(\n resolvePlacementSide(placement),\n );\n const [targetElement, setTargetElement] = useState<HTMLElement | null>(null);\n const [menuInitialFocus, setMenuInitialFocus] = useState<'first' | 'last'>(\n 'first',\n );\n const popupMatchTriggerWidthNumber = parsePopupMatchWidth(\n popupMatchTriggerWidth,\n );\n const [matchedTriggerWidth, setMatchedTriggerWidth] = useState<\n number | undefined\n >(popupMatchTriggerWidthNumber);\n const popupZIndex = useFloatingPopupZIndex();\n\n const onOpenChangeFn = useMemoizedFn(onOpenChange);\n const isOpenControlled = open !== undefined;\n\n const markRootClosing = useCallback(() => {\n document.body.classList.add('ald-dropdown-root-closing');\n lastResolvedFloatingStylesRef.current =\n currentFloatingStylesRef.current ?? lastResolvedFloatingStylesRef.current;\n lastResolvedSideRef.current =\n currentFloatingSideRef.current ?? lastResolvedSideRef.current;\n }, []);\n\n useLayoutEffect(() => {\n if (isOpenControlled) {\n setIsOpen(!!open);\n }\n }, [isOpenControlled, open]);\n\n const onChangeOpen = useCallback(\n (newOpen: boolean) => {\n if (!isOpenControlled) {\n setIsOpen(newOpen);\n }\n onOpenChangeFn(newOpen);\n },\n [isOpenControlled, onOpenChangeFn],\n );\n\n // 多级菜单必须保留 Menu 内部滚动:子菜单通过其根容器逃离滚动的 ul,\n // 若改为 surface 滚动,子菜单也会被外层裁剪。\n const hasSubmenu = !isLeafMenu(menu?.items || []);\n const surfaceScrolls = autoAdjustHeight && !hasSubmenu;\n const nodeId = useFloatingNodeId();\n const normalizedPlacement = normalizePlacement(placement);\n const {\n refs,\n floatingStyles,\n context,\n placement: floatingPlacement,\n x,\n y,\n } = useFloating({\n nodeId,\n placement: normalizedPlacement,\n open: isOpen,\n onOpenChange: onChangeOpen,\n middleware: [\n offset(offsetProps),\n flip({\n padding: 8,\n }),\n shift({\n padding: 8,\n // mainAxis 只沿对齐轴避让;整行触发器左右均无空间时,\n // 还需沿 crossAxis 移回视口,允许浮层覆盖触发器。\n ...(allowOverlap && { crossAxis: true }),\n }),\n size(\n {\n // 和 flip/shift 使用同一个浮层裁剪边界。body portal 不应被触发器的\n // ScrollArea 限高;自定义 getPopupContainer 的真实裁剪仍然生效。\n padding: 8,\n apply({ availableHeight, elements }) {\n if (!autoAdjustHeight) {\n elements.floating.style.removeProperty(\n '--ald-dropdown-max-height',\n );\n elements.floating.style.removeProperty(\n '--ald-dropdown-menu-max-height',\n );\n return;\n }\n\n // max-height 保持短内容的自然高度;极小视口也不能用 100px 下限撑出屏幕。\n const maxHeight = Math.max(0, availableHeight);\n elements.floating.style.setProperty(\n '--ald-dropdown-max-height',\n `${maxHeight}px`,\n );\n if (hasSubmenu) {\n const surface = elements.floating\n .firstElementChild as HTMLElement | null;\n const menuElement = surface?.querySelector<HTMLElement>(\n '.ald-menu > .szh-menu',\n );\n // 限制菜单自身高度时,扣除 surface 的边框、padding 和自定义内容。\n const extraHeight =\n surface && menuElement\n ? Math.max(0, surface.offsetHeight - menuElement.offsetHeight)\n : 0;\n elements.floating.style.setProperty(\n '--ald-dropdown-menu-max-height',\n `${Math.max(0, maxHeight - extraHeight)}px`,\n );\n }\n },\n },\n [autoAdjustHeight, hasSubmenu],\n ),\n ],\n whileElementsMounted: autoUpdatePos ? autoUpdate : undefined,\n });\n const { isMounted, styles: transitionStyles } = useTransitionStyles(context, {\n duration: OVERLAY_TRANSITION_MS,\n initial: {\n opacity: 0,\n transform: 'var(--ald-dropdown-enter-transform)',\n },\n close: {\n opacity: 0,\n transform: 'var(--ald-dropdown-exit-transform)',\n },\n common: {\n transitionTimingFunction: 'ease-in-out',\n },\n });\n const isAnimatingOut = !isOpen && isMounted;\n\n useLayoutEffect(() => {\n if (isAnimatingOut) {\n document.body.classList.add('ald-dropdown-root-closing');\n } else {\n document.body.classList.remove('ald-dropdown-root-closing');\n }\n\n return () => {\n if (isAnimatingOut) {\n document.body.classList.remove('ald-dropdown-root-closing');\n }\n };\n }, [isAnimatingOut]);\n\n const click = useClick(context, {\n enabled: hasTrigger(trigger, 'click'),\n });\n const hover = useHover(context, {\n enabled: hasTrigger(trigger, 'hover'),\n handleClose: safePolygon({}),\n delay: delay,\n });\n const dismiss = useDismiss(context, {});\n\n const propsList = useMemo(() => {\n const res = [dismiss];\n\n if (hasTrigger(trigger, 'hover')) {\n res.unshift(hover);\n }\n if (hasTrigger(trigger, 'click')) {\n res.unshift(click);\n }\n return res;\n }, [trigger, click, dismiss, hover]);\n\n const { getReferenceProps, getFloatingProps } = useInteractions(propsList);\n\n const headingId = useId();\n\n useLayoutEffect(() => {\n if (!popupMatchTriggerWidth || !isOpen) {\n setMatchedTriggerWidth(undefined);\n return;\n }\n\n if (popupMatchTriggerWidthNumber !== undefined) {\n setMatchedTriggerWidth(popupMatchTriggerWidthNumber);\n return;\n }\n\n const referenceElement = targetElement;\n if (!referenceElement) {\n return;\n }\n\n const updateMatchedWidth = () => {\n const nextWidth = referenceElement.getBoundingClientRect().width;\n setMatchedTriggerWidth((currentWidth) =>\n currentWidth === nextWidth ? currentWidth : nextWidth,\n );\n };\n\n updateMatchedWidth();\n\n if (typeof ResizeObserver === 'undefined') {\n window.addEventListener('resize', updateMatchedWidth);\n return () => {\n window.removeEventListener('resize', updateMatchedWidth);\n };\n }\n\n let resizeAnimationFrame: number | undefined;\n const scheduleMatchedWidthUpdate = () => {\n if (resizeAnimationFrame !== undefined) {\n cancelAnimationFrame(resizeAnimationFrame);\n }\n resizeAnimationFrame = requestAnimationFrame(updateMatchedWidth);\n };\n\n const observer = new ResizeObserver(scheduleMatchedWidthUpdate);\n observer.observe(referenceElement);\n\n return () => {\n if (resizeAnimationFrame !== undefined) {\n cancelAnimationFrame(resizeAnimationFrame);\n }\n observer.disconnect();\n };\n }, [\n isOpen,\n popupMatchTriggerWidth,\n popupMatchTriggerWidthNumber,\n targetElement,\n ]);\n\n const child = children as React.ReactElement;\n const childProps = child.props || {};\n const referenceProps = getReferenceProps();\n const updateMatchedWidthFromElement = useCallback(\n (element: HTMLElement) => {\n if (!popupMatchTriggerWidth) {\n return;\n }\n\n setMatchedTriggerWidth((currentWidth) => {\n const nextWidth =\n popupMatchTriggerWidthNumber !== undefined\n ? popupMatchTriggerWidthNumber\n : element.getBoundingClientRect().width;\n return currentWidth === nextWidth ? currentWidth : nextWidth;\n });\n },\n [popupMatchTriggerWidth, popupMatchTriggerWidthNumber],\n );\n const openMenuFromKeyboard = useCallback(\n (event: React.KeyboardEvent<HTMLElement>, position: 'first' | 'last') => {\n if (disabled) {\n return;\n }\n\n event.preventDefault();\n refs.setPositionReference(event.currentTarget);\n updateMatchedWidthFromElement(event.currentTarget);\n setMenuInitialFocus(position);\n onChangeOpen(true);\n },\n [disabled, onChangeOpen, refs, updateMatchedWidthFromElement],\n );\n const modifiedChild = cloneElement(child, {\n ...childProps,\n disabled,\n // ref: (node: HTMLDivElement) => refs.setReference(node),\n ...referenceProps,\n 'aria-haspopup': menu ? 'menu' : undefined,\n 'aria-expanded': menu ? isOpen : undefined,\n onClick: (event: React.MouseEvent<HTMLElement>) => {\n refs.setPositionReference(event.currentTarget);\n updateMatchedWidthFromElement(event.currentTarget);\n setMenuInitialFocus('first');\n childProps.onClick?.(event);\n const { onClick: referenceOnClick } = referenceProps;\n if (typeof referenceOnClick === 'function') {\n referenceOnClick(event);\n }\n },\n onKeyDown: (event: React.KeyboardEvent<HTMLElement>) => {\n childProps.onKeyDown?.(event);\n if (event.defaultPrevented) {\n return;\n }\n if (event.key === 'ArrowDown') {\n openMenuFromKeyboard(event, 'first');\n return;\n }\n if (event.key === 'ArrowUp') {\n openMenuFromKeyboard(event, 'last');\n return;\n }\n if (event.key === 'Enter' || event.key === ' ') {\n openMenuFromKeyboard(event, 'first');\n return;\n }\n const { onKeyDown: referenceOnKeyDown } = referenceProps;\n if (typeof referenceOnKeyDown === 'function') {\n referenceOnKeyDown(event);\n }\n },\n onContextMenu: (event: React.MouseEvent<HTMLElement>) => {\n childProps.onContextMenu?.(event);\n if (\n event.defaultPrevented ||\n disabled ||\n !hasTrigger(trigger, 'contextMenu')\n ) {\n return;\n }\n\n event.preventDefault();\n refs.setPositionReference({\n getBoundingClientRect: () =>\n new DOMRect(event.clientX, event.clientY, 0, 0),\n });\n setMenuInitialFocus('first');\n onChangeOpen(true);\n },\n });\n\n const onMenuItemClick = useCallback(\n (info: MenuInfo) => {\n if (menu?.onClick) {\n menu.onClick(info);\n }\n if (info.keepOpen) {\n document.body.classList.remove('ald-dropdown-root-closing');\n return;\n }\n onChangeOpen(false);\n },\n [menu, onChangeOpen],\n );\n const onMenuRequestClose = useCallback(\n (reason: 'click' | 'cancel' | 'blur' | 'scroll') => {\n // FloatingFocusManager owns focusout for the whole surface, including custom content.\n if (reason === 'blur') {\n return;\n }\n\n onChangeOpen(false);\n if (reason === 'cancel') {\n window.setTimeout(() => targetElement?.focus(), 0);\n }\n },\n [onChangeOpen, targetElement],\n );\n\n const menuInstance = useMemo(() => {\n const menuProps = {\n ...menu,\n items: menu?.items || [],\n menuStyle: {\n ...(popupMatchTriggerWidth\n ? {\n width: '100%',\n minWidth: 0,\n maxWidth: 'none',\n }\n : undefined),\n ...(autoAdjustHeight && hasSubmenu\n ? { maxHeight: 'var(--ald-dropdown-menu-max-height)' }\n : undefined),\n ...menu?.menuStyle,\n },\n onBeforeLeafItemClick: isOpenControlled ? undefined : markRootClosing,\n rootClosing: isAnimatingOut,\n initialFocus: menuInitialFocus,\n onRequestClose: onMenuRequestClose,\n };\n return (\n <Menu\n {...menuProps}\n onClick={onMenuItemClick}\n externalOverflow={surfaceScrolls}\n preserveRootHeight={\n autoAdjustHeight &&\n hasSubmenu &&\n menu?.menuStyle?.maxHeight === undefined\n }\n />\n );\n }, [\n autoAdjustHeight,\n hasSubmenu,\n surfaceScrolls,\n isAnimatingOut,\n isOpenControlled,\n markRootClosing,\n menu,\n onMenuItemClick,\n onMenuRequestClose,\n popupMatchTriggerWidth,\n menuInitialFocus,\n ]);\n\n const popupElement = useMemo(() => {\n return typeof dropdownRender === 'function'\n ? dropdownRender(menuInstance)\n : menuInstance;\n }, [dropdownRender, menuInstance]);\n\n const mergedMatchedTriggerWidth =\n popupMatchTriggerWidthNumber ?? matchedTriggerWidth;\n const matchedOverlayStyle =\n popupMatchTriggerWidth && mergedMatchedTriggerWidth !== undefined\n ? ({\n width: `${mergedMatchedTriggerWidth}px`,\n minWidth: 0,\n } satisfies React.CSSProperties)\n : undefined;\n\n const matchedSurfaceStyle = popupMatchTriggerWidth\n ? ({\n width: '100%',\n minWidth: 0,\n maxWidth: 'none',\n } satisfies React.CSSProperties)\n : undefined;\n\n const floatingSide = resolvePlacementSide(String(floatingPlacement));\n const shouldKeepMounted = !destroyPopupOnHide || isMounted;\n const isPositionReady = x !== null && y !== null;\n const overlayHidden =\n (!isOpen && !isAnimatingOut) || (isOpen && !isPositionReady);\n const resolvedFloatingStyles = isAnimatingOut\n ? lastResolvedFloatingStylesRef.current ?? floatingStyles\n : floatingStyles;\n const resolvedFloatingSide = isAnimatingOut\n ? lastResolvedSideRef.current\n : floatingSide;\n\n if (isOpen && isPositionReady) {\n currentFloatingStylesRef.current = { ...floatingStyles };\n currentFloatingSideRef.current = floatingSide;\n lastResolvedFloatingStylesRef.current = { ...floatingStyles };\n lastResolvedSideRef.current = floatingSide;\n }\n\n // 渲染浮动内容到自定义容器\n const renderFloatingContent = useCallback(() => {\n const surface = (\n <div\n {...(isAnimatingOut ? {} : getFloatingProps())}\n className={cn(\n 'ald-dropdown-overlay',\n // tw-outline-none:FloatingFocusManager 打开时会聚焦浮层容器,不抑制 outline 会渲染出蓝色焦点框\n 'tw-pointer-events-auto tw-z-[1001] tw-max-w-none tw-outline-none',\n overlayClassName,\n { 'ald-dropdown-overlay-hidden': overlayHidden },\n )}\n ref={refs.setFloating}\n style={{\n zIndex: popupZIndex,\n ...resolvedFloatingStyles,\n ...matchedOverlayStyle,\n ...overlayStyle,\n }}\n aria-labelledby={headingId}\n >\n <div\n className={cn(\n 'ald-dropdown-surface',\n surfaceScrolls && 'ald-dropdown-surface-overlap',\n 'tw-flex tw-flex-col tw-items-start tw-text-sm',\n )}\n style={{\n ...matchedSurfaceStyle,\n ...overlayInnerStyle,\n ...transitionStyles,\n }}\n data-state={isOpen ? 'open' : 'closed'}\n data-side={resolvedFloatingSide}\n >\n {popupElement}\n </div>\n </div>\n );\n\n const popupElem = (\n <FloatingFocusManager\n context={context}\n disabled={isAnimatingOut}\n modal={false}\n initialFocus={initialFocus}\n closeOnFocusOut={closeOnFocusOut}\n >\n {surface}\n </FloatingFocusManager>\n );\n\n const popupContainer =\n typeof getPopupContainer === 'function'\n ? getPopupContainer()\n : document.body;\n return ReactDOM.createPortal(popupElem, popupContainer);\n }, [\n context,\n getFloatingProps,\n getPopupContainer,\n headingId,\n popupElement,\n refs.setFloating,\n overlayClassName,\n overlayStyle,\n overlayInnerStyle,\n matchedOverlayStyle,\n matchedSurfaceStyle,\n transitionStyles,\n popupZIndex,\n overlayHidden,\n isAnimatingOut,\n isOpen,\n initialFocus,\n closeOnFocusOut,\n resolvedFloatingSide,\n resolvedFloatingStyles,\n surfaceScrolls,\n ]);\n\n const popup = shouldKeepMounted ? renderFloatingContent() : null;\n const { setReference } = refs;\n\n const setTargetRef = useCallback(\n (node: HTMLElement | null) => {\n if (node) {\n // display: contents 元素没有 box model,getBoundingClientRect() 返回零值\n // 需要获取实际的第一个子元素作为 floating-ui 的参考元素\n const target =\n node.style.display === 'contents'\n ? (node.firstElementChild as HTMLElement) || node\n : node;\n setTargetElement((currentTarget) =>\n currentTarget === target ? currentTarget : target,\n );\n setReference(target);\n } else {\n setTargetElement(null);\n setReference(null);\n }\n },\n [setReference],\n );\n\n const content = (\n <>\n <span ref={setTargetRef} style={{ display: 'contents' }}>\n {modifiedChild}\n </span>\n <FloatingNode id={nodeId}>{popup}</FloatingNode>\n </>\n );\n\n const parentId = useFloatingParentNodeId();\n if (!parentId) {\n return <FloatingTree>{content}</FloatingTree>;\n }\n\n return content;\n}\n"],"mappings":"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"}
|
|
@@ -9,6 +9,7 @@ interface IMultipleOptionProps {
|
|
|
9
9
|
onNextLevel?: (userGroup: IUserGroup) => void;
|
|
10
10
|
hasNextLevel?: boolean;
|
|
11
11
|
showUserId?: boolean;
|
|
12
|
+
searchValue?: string;
|
|
12
13
|
}
|
|
13
14
|
export default function MultipleList(params: IMultipleOptionProps): import("react/jsx-runtime").JSX.Element;
|
|
14
15
|
export {};
|
|
@@ -15,7 +15,7 @@ function MultipleList(params) {
|
|
|
15
15
|
const { locale } = useContext(LocaleContext);
|
|
16
16
|
const t = getTranslator(locale);
|
|
17
17
|
const { getMemberPickerItemMoreInfoKey } = AldCustomConfigProvider.useGetUserList();
|
|
18
|
-
const { disabled, user, selected, onChange, className, onNextLevel, hasNextLevel = true, showUserId = false } = params;
|
|
18
|
+
const { disabled, user, selected, onChange, className, onNextLevel, hasNextLevel = true, searchValue, showUserId = false } = params;
|
|
19
19
|
const onClick = () => {
|
|
20
20
|
if (disabled) return;
|
|
21
21
|
onChange?.(!selected, user);
|
|
@@ -44,6 +44,8 @@ function MultipleList(params) {
|
|
|
44
44
|
}), /* @__PURE__ */ jsxs("div", {
|
|
45
45
|
className: "ald-member-picker-option-content",
|
|
46
46
|
children: [/* @__PURE__ */ jsx(NickLabel_default, {
|
|
47
|
+
searchValue,
|
|
48
|
+
path: isUserGroup(user) ? user.path : void 0,
|
|
47
49
|
type: user.type,
|
|
48
50
|
id: getId(user),
|
|
49
51
|
name: user.name,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MultipleOption.js","names":[],"sources":["../../../src/MemberPicker/components/MultipleOption.tsx"],"sourcesContent":["import { cn } from '../../lib/utils';\nimport React, { useContext } from 'react';\nimport Badge from '../../Badge';\nimport Checkbox from '../../Checkbox';\nimport ConfigProvider from '../../ConfigProvider';\nimport { EUserType, IUserGroup } from '../../ConfigProvider/getUserList';\nimport TextLink from '../../TextLink/index';\nimport { LocaleContext, getTranslator } from '../../locale/default';\nimport { IUser } from '../interface';\nimport { getAccount, getId, getPhoto } from '../utils';\nimport { isUser, isUserGroup } from '../utils/getUsersWithUserId';\nimport NickLabel from './NickLabel';\n\ninterface IMultipleOptionProps {\n selected: boolean;\n disabled?: boolean;\n user: IUser | IUserGroup;\n onChange?: (selected: boolean, user: IUser | IUserGroup) => void;\n className?: string;\n onNextLevel?: (userGroup: IUserGroup) => void;\n hasNextLevel?: boolean;\n showUserId?: boolean;\n}\nexport default function MultipleList(params: IMultipleOptionProps) {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n\n const { getMemberPickerItemMoreInfoKey } = ConfigProvider.useGetUserList();\n\n const {\n disabled,\n user,\n selected,\n onChange,\n className,\n onNextLevel,\n hasNextLevel = true,\n showUserId = false,\n } = params;\n\n const onClick = () => {\n if (disabled) return;\n\n onChange?.(!selected, user);\n };\n\n return (\n <div\n role=\"option\"\n id={`ald-member-picker-option-${getId(user)}`}\n aria-selected={selected}\n aria-disabled={disabled || undefined}\n tabIndex={-1}\n className={cn('ald-member-picker-option', className, {\n ['ald-member-picker-option-disabled']: disabled,\n })}\n onClick={onClick}\n onKeyDown={(event) => {\n if (disabled) return;\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n onClick();\n }\n }}\n >\n <div className={'ald-member-picker-label'}>\n <Checkbox\n className={'ald-member-picker-checkbox'}\n checked={selected}\n disabled={disabled}\n ></Checkbox>\n <div className={'ald-member-picker-option-content'}>\n <NickLabel\n type={user.type}\n id={getId(user)}\n name={user.name as string}\n photo={getPhoto(user)}\n account={getAccount(user)}\n addonBefore={\n showUserId &&\n user.type === EUserType.USER && (\n <span className={'ald-member-picker-option-id'}>\n {getMemberPickerItemMoreInfoKey\n ? getMemberPickerItemMoreInfoKey(user)\n : user.userId}\n </span>\n )\n }\n ></NickLabel>\n {/* 如果是用户的话并且user.ban为true,则展示 已停用 Tag */}\n {isUser(user) && user.ban && (\n <Badge\n status=\"default\"\n count={t.MemberPicker.ban}\n className={'ald-member-picker-ban-badge'}\n ></Badge>\n )}\n </div>\n </div>\n {isUserGroup(user) && hasNextLevel && (\n <TextLink\n className=\"ald-member-picker-btn\"\n size=\"small\"\n disabled={disabled}\n onClick={(e) => {\n onNextLevel?.(user);\n e.stopPropagation();\n e.preventDefault();\n }}\n >\n {t.MemberPicker.subLevel}\n </TextLink>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"MultipleOption.js","names":[],"sources":["../../../src/MemberPicker/components/MultipleOption.tsx"],"sourcesContent":["import { cn } from '../../lib/utils';\nimport React, { useContext } from 'react';\nimport Badge from '../../Badge';\nimport Checkbox from '../../Checkbox';\nimport ConfigProvider from '../../ConfigProvider';\nimport { EUserType, IUserGroup } from '../../ConfigProvider/getUserList';\nimport TextLink from '../../TextLink/index';\nimport { LocaleContext, getTranslator } from '../../locale/default';\nimport { IUser } from '../interface';\nimport { getAccount, getId, getPhoto } from '../utils';\nimport { isUser, isUserGroup } from '../utils/getUsersWithUserId';\nimport NickLabel from './NickLabel';\n\ninterface IMultipleOptionProps {\n selected: boolean;\n disabled?: boolean;\n user: IUser | IUserGroup;\n onChange?: (selected: boolean, user: IUser | IUserGroup) => void;\n className?: string;\n onNextLevel?: (userGroup: IUserGroup) => void;\n hasNextLevel?: boolean;\n showUserId?: boolean;\n searchValue?: string;\n}\nexport default function MultipleList(params: IMultipleOptionProps) {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n\n const { getMemberPickerItemMoreInfoKey } = ConfigProvider.useGetUserList();\n\n const {\n disabled,\n user,\n selected,\n onChange,\n className,\n onNextLevel,\n hasNextLevel = true,\n searchValue,\n showUserId = false,\n } = params;\n\n const onClick = () => {\n if (disabled) return;\n\n onChange?.(!selected, user);\n };\n\n return (\n <div\n role=\"option\"\n id={`ald-member-picker-option-${getId(user)}`}\n aria-selected={selected}\n aria-disabled={disabled || undefined}\n tabIndex={-1}\n className={cn('ald-member-picker-option', className, {\n ['ald-member-picker-option-disabled']: disabled,\n })}\n onClick={onClick}\n onKeyDown={(event) => {\n if (disabled) return;\n if (event.key === 'Enter' || event.key === ' ') {\n event.preventDefault();\n onClick();\n }\n }}\n >\n <div className={'ald-member-picker-label'}>\n <Checkbox\n className={'ald-member-picker-checkbox'}\n checked={selected}\n disabled={disabled}\n ></Checkbox>\n <div className={'ald-member-picker-option-content'}>\n <NickLabel\n searchValue={searchValue}\n path={isUserGroup(user) ? user.path : undefined}\n type={user.type}\n id={getId(user)}\n name={user.name as string}\n photo={getPhoto(user)}\n account={getAccount(user)}\n addonBefore={\n showUserId &&\n user.type === EUserType.USER && (\n <span className={'ald-member-picker-option-id'}>\n {getMemberPickerItemMoreInfoKey\n ? getMemberPickerItemMoreInfoKey(user)\n : user.userId}\n </span>\n )\n }\n ></NickLabel>\n {/* 如果是用户的话并且user.ban为true,则展示 已停用 Tag */}\n {isUser(user) && user.ban && (\n <Badge\n status=\"default\"\n count={t.MemberPicker.ban}\n className={'ald-member-picker-ban-badge'}\n ></Badge>\n )}\n </div>\n </div>\n {isUserGroup(user) && hasNextLevel && (\n <TextLink\n className=\"ald-member-picker-btn\"\n size=\"small\"\n disabled={disabled}\n onClick={(e) => {\n onNextLevel?.(user);\n e.stopPropagation();\n e.preventDefault();\n }}\n >\n {t.MemberPicker.subLevel}\n </TextLink>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAwBA,SAAwB,aAAa,QAA8B;CACjE,MAAM,EAAE,WAAW,WAAW,cAAc;CAC5C,MAAM,IAAI,cAAc,OAAO;CAE/B,MAAM,EAAE,mCAAmC,wBAAe,gBAAgB;CAE1E,MAAM,EACJ,UACA,MACA,UACA,UACA,WACA,aACA,eAAe,MACf,aACA,aAAa,UACX;CAEJ,MAAM,gBAAgB;AACpB,MAAI,SAAU;AAEd,aAAW,CAAC,UAAU,KAAK;;AAG7B,QACE,qBAAC,OAAD;EACE,MAAK;EACL,IAAI,4BAA4B,MAAM,KAAK;EAC3C,iBAAe;EACf,iBAAe,YAAY;EAC3B,UAAU;EACV,WAAW,GAAG,4BAA4B,WAAW,GAClD,sCAAsC,UACxC,CAAC;EACO;EACT,YAAY,UAAU;AACpB,OAAI,SAAU;AACd,OAAI,MAAM,QAAQ,WAAW,MAAM,QAAQ,KAAK;AAC9C,UAAM,gBAAgB;AACtB,aAAS;;;YAdf,CAkBE,qBAAC,OAAD;GAAK,WAAW;aAAhB,CACE,oBAAC,UAAD;IACE,WAAW;IACX,SAAS;IACC;IACA,CAAA,EACZ,qBAAC,OAAD;IAAK,WAAW;cAAhB,CACE,oBAAC,mBAAD;KACe;KACb,MAAM,YAAY,KAAK,GAAG,KAAK,OAAO;KACtC,MAAM,KAAK;KACX,IAAI,MAAM,KAAK;KACf,MAAM,KAAK;KACX,OAAO,SAAS,KAAK;KACrB,SAAS,WAAW,KAAK;KACzB,aACE,cACA,KAAK,SAAS,UAAU,QACtB,oBAAC,QAAD;MAAM,WAAW;gBACd,iCACG,+BAA+B,KAAK,GACpC,KAAK;MACJ,CAAA;KAGA,CAAA,EAEZ,OAAO,KAAK,IAAI,KAAK,OACpB,oBAAC,OAAD;KACE,QAAO;KACP,OAAO,EAAE,aAAa;KACtB,WAAW;KACJ,CAAA,CAEP;MACF;MACL,YAAY,KAAK,IAAI,gBACpB,oBAAC,UAAD;GACE,WAAU;GACV,MAAK;GACK;GACV,UAAU,MAAM;AACd,kBAAc,KAAK;AACnB,MAAE,iBAAiB;AACnB,MAAE,gBAAgB;;aAGnB,EAAE,aAAa;GACP,CAAA,CAET"}
|
|
@@ -7,6 +7,11 @@ interface INickLabelProps {
|
|
|
7
7
|
account?: string;
|
|
8
8
|
type: EUserType;
|
|
9
9
|
addonBefore?: ReactNode;
|
|
10
|
+
path?: Array<{
|
|
11
|
+
groupId: string;
|
|
12
|
+
name: string;
|
|
13
|
+
}> | null;
|
|
14
|
+
searchValue?: string;
|
|
10
15
|
}
|
|
11
16
|
declare const _default: React.NamedExoticComponent<INickLabelProps>;
|
|
12
17
|
export default _default;
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import Avatar from "../../Avatar/index.js";
|
|
2
2
|
import { EUserType } from "../../ConfigProvider/getUserList.js";
|
|
3
|
+
import HighlightText from "../../HighlightText/index.js";
|
|
3
4
|
import { memo } from "react";
|
|
4
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
5
6
|
//#region src/MemberPicker/components/NickLabel.tsx
|
|
6
|
-
var NickLabel = ({ photo, name, id, account, type, addonBefore }) => {
|
|
7
|
+
var NickLabel = ({ photo, name, id, account, type, addonBefore, path, searchValue }) => {
|
|
7
8
|
const innerName = name || id;
|
|
9
|
+
const searchPath = searchValue?.trim() && path?.length ? path : void 0;
|
|
10
|
+
const title = searchPath ? searchPath.map((node) => node.name).join(" / ") : account ? `${name}(${account})` : name;
|
|
8
11
|
return /* @__PURE__ */ jsxs("div", {
|
|
9
12
|
className: "ald-member-picker-nick-label",
|
|
10
13
|
children: [/* @__PURE__ */ jsx(Avatar, {
|
|
@@ -14,8 +17,15 @@ var NickLabel = ({ photo, name, id, account, type, addonBefore }) => {
|
|
|
14
17
|
children: innerName
|
|
15
18
|
}, innerName), /* @__PURE__ */ jsxs("div", {
|
|
16
19
|
className: "ald-member-picker-nick-label-name",
|
|
17
|
-
title
|
|
18
|
-
children: [
|
|
20
|
+
title,
|
|
21
|
+
children: [searchPath ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
22
|
+
searchPath.slice(0, -1).map((node) => node.name).join(" / "),
|
|
23
|
+
searchPath.length > 1 && " / ",
|
|
24
|
+
/* @__PURE__ */ jsx(HighlightText, {
|
|
25
|
+
keyword: searchValue || "",
|
|
26
|
+
children: innerName
|
|
27
|
+
})
|
|
28
|
+
] }) : innerName, addonBefore]
|
|
19
29
|
})]
|
|
20
30
|
});
|
|
21
31
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"NickLabel.js","names":[],"sources":["../../../src/MemberPicker/components/NickLabel.tsx"],"sourcesContent":["import React, { ReactNode, memo } from 'react';\nimport Avatar from '../../Avatar';\nimport { EUserType } from '../../ConfigProvider/getUserList';\n\ninterface INickLabelProps {\n name?: string;\n id: string;\n photo?: React.ReactNode;\n account?: string;\n type: EUserType;\n addonBefore?: ReactNode;\n}\nconst NickLabel: React.FC<INickLabelProps> = ({\n photo,\n name,\n id,\n account,\n type,\n addonBefore,\n}) => {\n const innerName = name || id;\n\n return (\n <div className=\"ald-member-picker-nick-label\">\n <Avatar\n key={innerName}\n src={photo}\n size={20}\n type={type === EUserType.USER ? 'user' : 'team'}\n >\n {innerName}\n </Avatar>\n <div
|
|
1
|
+
{"version":3,"file":"NickLabel.js","names":[],"sources":["../../../src/MemberPicker/components/NickLabel.tsx"],"sourcesContent":["import React, { ReactNode, memo } from 'react';\nimport Avatar from '../../Avatar';\nimport HighlightText from '../../HighlightText';\nimport { EUserType } from '../../ConfigProvider/getUserList';\n\ninterface INickLabelProps {\n name?: string;\n id: string;\n photo?: React.ReactNode;\n account?: string;\n type: EUserType;\n addonBefore?: ReactNode;\n path?: Array<{ groupId: string; name: string }> | null;\n searchValue?: string;\n}\nconst NickLabel: React.FC<INickLabelProps> = ({\n photo,\n name,\n id,\n account,\n type,\n addonBefore,\n path,\n searchValue,\n}) => {\n const innerName = name || id;\n const searchPath = searchValue?.trim() && path?.length ? path : undefined;\n const title = searchPath\n ? searchPath.map((node) => node.name).join(' / ')\n : account\n ? `${name}(${account})`\n : name;\n\n return (\n <div className=\"ald-member-picker-nick-label\">\n <Avatar\n key={innerName}\n src={photo}\n size={20}\n type={type === EUserType.USER ? 'user' : 'team'}\n >\n {innerName}\n </Avatar>\n <div className=\"ald-member-picker-nick-label-name\" title={title}>\n {searchPath ? (\n <>\n {searchPath\n .slice(0, -1)\n .map((node) => node.name)\n .join(' / ')}\n {searchPath.length > 1 && ' / '}\n <HighlightText keyword={searchValue || ''}>\n {innerName}\n </HighlightText>\n </>\n ) : (\n innerName\n )}\n {addonBefore}\n </div>\n </div>\n );\n};\n\nexport default memo(NickLabel);\n"],"mappings":";;;;;;AAeA,IAAM,aAAwC,EAC5C,OACA,MACA,IACA,SACA,MACA,aACA,MACA,kBACI;CACJ,MAAM,YAAY,QAAQ;CAC1B,MAAM,aAAa,aAAa,MAAM,IAAI,MAAM,SAAS,OAAO;CAChE,MAAM,QAAQ,aACV,WAAW,KAAK,SAAS,KAAK,KAAK,CAAC,KAAK,MAAM,GAC/C,UACA,GAAG,KAAK,GAAG,QAAQ,KACnB;AAEJ,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,oBAAC,QAAD;GAEE,KAAK;GACL,MAAM;GACN,MAAM,SAAS,UAAU,OAAO,SAAS;aAExC;GACM,EANF,UAME,EACT,qBAAC,OAAD;GAAK,WAAU;GAA2C;aAA1D,CACG,aACC,qBAAA,UAAA,EAAA,UAAA;IACG,WACE,MAAM,GAAG,GAAG,CACZ,KAAK,SAAS,KAAK,KAAK,CACxB,KAAK,MAAM;IACb,WAAW,SAAS,KAAK;IAC1B,oBAAC,eAAD;KAAe,SAAS,eAAe;eACpC;KACa,CAAA;IACf,EAAA,CAAA,GAEH,WAED,YACG;KACF;;;AAIV,IAAA,oBAAe,KAAK,UAAU"}
|