@aloudata/aloudata-design 3.1.6 → 3.1.8

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.
Files changed (92) hide show
  1. package/dist/ConfigProvider/getUserList.d.ts +47 -0
  2. package/dist/ConfigProvider/getUserList.js.map +1 -1
  3. package/dist/ConfigProvider/hooks/useGetUserList.d.ts +7 -0
  4. package/dist/ConfigProvider/hooks/useGetUserList.js +5 -1
  5. package/dist/ConfigProvider/hooks/useGetUserList.js.map +1 -1
  6. package/dist/ConfigProvider/index.d.ts +5 -1
  7. package/dist/ConfigProvider/index.js +6 -2
  8. package/dist/ConfigProvider/index.js.map +1 -1
  9. package/dist/Dropdown/index.d.ts +7 -2
  10. package/dist/Dropdown/index.js +52 -18
  11. package/dist/Dropdown/index.js.map +1 -1
  12. package/dist/MemberPicker/components/MultipleOption.d.ts +1 -0
  13. package/dist/MemberPicker/components/MultipleOption.js +3 -1
  14. package/dist/MemberPicker/components/MultipleOption.js.map +1 -1
  15. package/dist/MemberPicker/components/NickLabel.d.ts +5 -0
  16. package/dist/MemberPicker/components/NickLabel.js +14 -4
  17. package/dist/MemberPicker/components/NickLabel.js.map +1 -1
  18. package/dist/MemberPicker/components/Panel.d.ts +6 -1
  19. package/dist/MemberPicker/components/Panel.js +17 -5
  20. package/dist/MemberPicker/components/Panel.js.map +1 -1
  21. package/dist/MemberPicker/components/PanelWrapper.d.ts +3 -2
  22. package/dist/MemberPicker/components/PanelWrapper.js +27 -25
  23. package/dist/MemberPicker/components/PanelWrapper.js.map +1 -1
  24. package/dist/MemberPicker/components/SearchFeedback.d.ts +7 -0
  25. package/dist/MemberPicker/components/SearchFeedback.js +27 -0
  26. package/dist/MemberPicker/components/SearchFeedback.js.map +1 -0
  27. package/dist/MemberPicker/components/SingleOption.d.ts +1 -0
  28. package/dist/MemberPicker/components/SingleOption.js +3 -1
  29. package/dist/MemberPicker/components/SingleOption.js.map +1 -1
  30. package/dist/MemberPicker/components/UserGroupSelection.d.ts +6 -1
  31. package/dist/MemberPicker/components/UserGroupSelection.js +30 -23
  32. package/dist/MemberPicker/components/UserGroupSelection.js.map +1 -1
  33. package/dist/MemberPicker/dialog/DialogColumns.d.ts +5 -0
  34. package/dist/MemberPicker/dialog/DialogColumns.js +59 -0
  35. package/dist/MemberPicker/dialog/DialogColumns.js.map +1 -0
  36. package/dist/MemberPicker/dialog/DialogContent.d.ts +3 -0
  37. package/dist/MemberPicker/dialog/DialogContent.js +109 -0
  38. package/dist/MemberPicker/dialog/DialogContent.js.map +1 -0
  39. package/dist/MemberPicker/dialog/MemberOption.d.ts +16 -0
  40. package/dist/MemberPicker/dialog/MemberOption.js +101 -0
  41. package/dist/MemberPicker/dialog/MemberOption.js.map +1 -0
  42. package/dist/MemberPicker/dialog/MemberPickerDialog.d.ts +11 -0
  43. package/dist/MemberPicker/dialog/MemberPickerDialog.js +11 -0
  44. package/dist/MemberPicker/dialog/MemberPickerDialog.js.map +1 -0
  45. package/dist/MemberPicker/dialog/SelectedMemberPanel.d.ts +12 -0
  46. package/dist/MemberPicker/dialog/SelectedMemberPanel.js +37 -0
  47. package/dist/MemberPicker/dialog/SelectedMemberPanel.js.map +1 -0
  48. package/dist/MemberPicker/dialog/UserCandidatePanel.d.ts +13 -0
  49. package/dist/MemberPicker/dialog/UserCandidatePanel.js +168 -0
  50. package/dist/MemberPicker/dialog/UserCandidatePanel.js.map +1 -0
  51. package/dist/MemberPicker/dialog/UserGroupCandidatePanel.d.ts +14 -0
  52. package/dist/MemberPicker/dialog/UserGroupCandidatePanel.js +134 -0
  53. package/dist/MemberPicker/dialog/UserGroupCandidatePanel.js.map +1 -0
  54. package/dist/MemberPicker/dialog/helper.d.ts +20 -0
  55. package/dist/MemberPicker/dialog/helper.js +61 -0
  56. package/dist/MemberPicker/dialog/helper.js.map +1 -0
  57. package/dist/MemberPicker/dialog/types.d.ts +41 -0
  58. package/dist/MemberPicker/dialog/types.js +7 -0
  59. package/dist/MemberPicker/dialog/types.js.map +1 -0
  60. package/dist/MemberPicker/dialog/useDialogLocale.d.ts +103 -0
  61. package/dist/MemberPicker/dialog/useDialogLocale.js +12 -0
  62. package/dist/MemberPicker/dialog/useDialogLocale.js.map +1 -0
  63. package/dist/MemberPicker/dialog/useMemberPickerDraft.d.ts +27 -0
  64. package/dist/MemberPicker/dialog/useMemberPickerDraft.js +95 -0
  65. package/dist/MemberPicker/dialog/useMemberPickerDraft.js.map +1 -0
  66. package/dist/MemberPicker/dialog/useUserGroupCandidates.d.ts +29 -0
  67. package/dist/MemberPicker/dialog/useUserGroupCandidates.js +443 -0
  68. package/dist/MemberPicker/dialog/useUserGroupCandidates.js.map +1 -0
  69. package/dist/MemberPicker/index.d.ts +2 -0
  70. package/dist/MemberPicker/index.js +61 -35
  71. package/dist/MemberPicker/index.js.map +1 -1
  72. package/dist/MemberPicker/interface.d.ts +6 -0
  73. package/dist/MemberPicker/interface.js.map +1 -1
  74. package/dist/MemberPicker/useMemberSearch.d.ts +8 -0
  75. package/dist/MemberPicker/useMemberSearch.js +51 -0
  76. package/dist/MemberPicker/useMemberSearch.js.map +1 -0
  77. package/dist/Menu/index.d.ts +6 -0
  78. package/dist/Menu/index.js +21 -9
  79. package/dist/Menu/index.js.map +1 -1
  80. package/dist/Modal/index.js +1 -1
  81. package/dist/Modal/index.js.map +1 -1
  82. package/dist/aloudata-design.css +1 -1
  83. package/dist/index.d.ts +3 -0
  84. package/dist/index.js +2 -2
  85. package/dist/locale/default.d.ts +29 -0
  86. package/dist/locale/en_US.d.ts +29 -0
  87. package/dist/locale/en_US.js +29 -0
  88. package/dist/locale/en_US.js.map +1 -1
  89. package/dist/locale/zh_CN.d.ts +29 -0
  90. package/dist/locale/zh_CN.js +29 -0
  91. package/dist/locale/zh_CN.js.map +1 -1
  92. package/package.json +2 -1
@@ -1,12 +1,15 @@
1
1
  import { cn } from "../lib/utils.js";
2
2
  import Avatar from "../Avatar/index.js";
3
+ import DisabledContext from "../ConfigProvider/DisabledContext.js";
3
4
  import { LocaleContext, getTranslator } from "../locale/default.js";
4
5
  import { EUserType } from "../ConfigProvider/getUserList.js";
5
6
  import AldCustomConfigProvider from "../ConfigProvider/index.js";
6
7
  import Select_default from "../Select/index.js";
7
- /* empty css */
8
- import message from "../message/index.js";
9
8
  import { EMemberPicker } from "./interface.js";
9
+ import SearchFeedback from "./components/SearchFeedback.js";
10
+ import MemberPickerDialog from "./dialog/MemberPickerDialog.js";
11
+ import useMemberSearch from "./useMemberSearch.js";
12
+ /* empty css */
10
13
  import { getId } from "./utils/index.js";
11
14
  import { isUser, isUserGroup } from "./utils/getUsersWithUserId.js";
12
15
  import Panel from "./components/Panel.js";
@@ -14,18 +17,21 @@ import PanelWrapper from "./components/PanelWrapper.js";
14
17
  import React, { useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
15
18
  import { jsx, jsxs } from "react/jsx-runtime";
16
19
  import _ from "lodash";
17
- import { usePrevious, useRequest } from "ahooks";
20
+ import { usePrevious } from "ahooks";
18
21
  //#region src/MemberPicker/index.tsx
19
22
  var DEFAULT_MULTIPLE_DROPDOWN_WIDTH = 480;
20
23
  var Component = (props) => {
21
24
  const { locale } = useContext(LocaleContext);
22
25
  const t = getTranslator(locale);
23
- const { value, type = EMemberPicker.USER, onChange, multiple, dropdownWidth, open, onOpenChange, placeholder = t.MemberPicker.select, className, allowClear, disabled, onClear, size, prefix: propPrefix, lockedIds = [], footer, onCancel, filterItem, mode: propsMode, renderItem, renderSelectedTag, "data-testid": dataTestId, "aria-label": ariaLabel, ...restProps } = props;
26
+ const { value, type = EMemberPicker.USER, onChange, multiple, dropdownWidth, open, onOpenChange, placeholder = t.MemberPicker.select, className, allowClear, disabled, onClear, size, prefix: propPrefix, lockedIds = [], footer, onCancel, filterItem, mode: propsMode, canEnterGroup, renderItem, renderSelectedTag, "data-testid": dataTestId, "aria-label": ariaLabel, ...restProps } = props;
24
27
  const allowOverlap = props.allowOverlap ?? false;
25
- const { getUsersByIds, getUsersByKeywords } = AldCustomConfigProvider.useGetUserList();
28
+ const { getUsersByIds, getUsersByKeywords, getUsersByKeywordsWithMeta, getNextLevelGroup, getNextLevelGroupWithMeta } = AldCustomConfigProvider.useGetUserList();
29
+ const inheritedDisabled = useContext(DisabledContext);
30
+ const isDisabled = disabled ?? inheritedDisabled;
31
+ const usesDialog = !!multiple;
32
+ const usesGroupQuery = (type === EMemberPicker.GROUP || !getUsersByKeywords && !getUsersByKeywordsWithMeta) && !!(getNextLevelGroup || getNextLevelGroupWithMeta);
26
33
  const [selectedUserList, setSelectedUserList] = useState([]);
27
34
  const prevValue = usePrevious(value);
28
- const [searchUserList, setSearchUserList] = useState([]);
29
35
  const [searchString, setSearchString] = useState("");
30
36
  const [dropdownContentWidth, setDropdownContentWidth] = useState(dropdownWidth);
31
37
  const selectOwnerRef = useRef(null);
@@ -36,25 +42,20 @@ var Component = (props) => {
36
42
  }, []);
37
43
  const [dropdownOpen, setDropdownOpen] = useState(!!open);
38
44
  const queryByKeywords = useMemo(() => {
45
+ if (getUsersByKeywordsWithMeta) return getUsersByKeywordsWithMeta;
39
46
  if (getUsersByKeywords) return getUsersByKeywords;
40
47
  return (_params = {}) => Promise.reject({ message: t.MemberPicker.pleaseConfigGetUserByKeywordsMethod });
41
- }, [getUsersByKeywords, t.MemberPicker.pleaseConfigGetUserByKeywordsMethod]);
48
+ }, [
49
+ getUsersByKeywords,
50
+ getUsersByKeywordsWithMeta,
51
+ t.MemberPicker.pleaseConfigGetUserByKeywordsMethod
52
+ ]);
42
53
  const queryByIds = useMemo(() => {
43
54
  if (getUsersByIds) return getUsersByIds;
44
55
  return (_params = {}) => Promise.reject({ message: t.MemberPicker.pleaseConfigGetUserByIdsMethod });
45
56
  }, [getUsersByIds, t.MemberPicker.pleaseConfigGetUserByIdsMethod]);
46
- const { loading, run } = useRequest(() => queryByKeywords(searchString), {
47
- refreshDeps: [searchString],
48
- manual: true,
49
- cacheKey: "member-selector",
50
- cacheTime: 1e3 * 60 * 2,
51
- onSuccess: (result) => {
52
- setSearchUserList(result);
53
- },
54
- onError: (error) => {
55
- message.error(error.message);
56
- }
57
- });
57
+ const { result: searchResult, loading, failed, retry } = useMemberSearch(queryByKeywords, searchString, dropdownOpen && !usesGroupQuery && !usesDialog);
58
+ const searchUserList = searchResult.items;
58
59
  const totalUserList = useMemo(() => {
59
60
  const totalUsers = searchUserList.concat(selectedUserList.filter((item) => {
60
61
  return ((item.type === EUserType.USER ? item.nickname : item.name) || "").toUpperCase().includes(searchString.trim().toUpperCase());
@@ -72,14 +73,6 @@ var Component = (props) => {
72
73
  searchUserList,
73
74
  selectedUserList
74
75
  ]);
75
- useEffect(() => {
76
- if (!dropdownOpen) return;
77
- run();
78
- }, [
79
- dropdownOpen,
80
- run,
81
- searchString
82
- ]);
83
76
  useEffect(() => {
84
77
  if (_.isEqual(value, prevValue)) return;
85
78
  if (Array.isArray(value) && (isUser(value[0]) || isUserGroup(value[0]))) setSelectedUserList(value);
@@ -149,9 +142,15 @@ var Component = (props) => {
149
142
  }
150
143
  }, [triggerRef, dropdownContentWidth]);
151
144
  const onDropdownOpenChange = useCallback((open) => {
152
- setDropdownOpen(open);
145
+ if (isDisabled) return;
146
+ if (!usesDialog || typeof props.open !== "boolean") setDropdownOpen(open);
153
147
  onOpenChange?.(open);
154
- }, [onOpenChange]);
148
+ }, [
149
+ isDisabled,
150
+ usesDialog,
151
+ props.open,
152
+ onOpenChange
153
+ ]);
155
154
  const mode = useMemo(() => {
156
155
  if (multiple === true) {
157
156
  if (typeof propsMode === "object") return {
@@ -181,15 +180,15 @@ var Component = (props) => {
181
180
  listboxId,
182
181
  selectOpen
183
182
  ]);
184
- return /* @__PURE__ */ jsx("div", {
183
+ return /* @__PURE__ */ jsxs("div", {
185
184
  ref: selectOwnerRef,
186
185
  style: { display: "contents" },
187
- children: /* @__PURE__ */ jsx(Select_default, {
186
+ children: [/* @__PURE__ */ jsx(Select_default, {
188
187
  prefix: propPrefix,
189
188
  ...restProps,
190
189
  "data-testid": dataTestId,
191
190
  "aria-label": ariaLabel,
192
- showSearch: true,
191
+ showSearch: !usesDialog,
193
192
  searchValue: searchString,
194
193
  onSearch: onSearchValueChange,
195
194
  "aria-controls": listboxId,
@@ -231,7 +230,7 @@ var Component = (props) => {
231
230
  }
232
231
  }
233
232
  },
234
- disabled,
233
+ disabled: isDisabled,
235
234
  allowClear,
236
235
  onClear: () => {
237
236
  setSelectedUserList([]);
@@ -269,7 +268,7 @@ var Component = (props) => {
269
268
  };
270
269
  }),
271
270
  optionLabelProp: multiple ? "label" : "tag",
272
- open: selectOpen,
271
+ open: usesDialog ? false : selectOpen,
273
272
  onOpenChange: onDropdownOpenChange,
274
273
  popupMatchSelectWidth: panelWidth,
275
274
  allowOverlap,
@@ -282,6 +281,15 @@ var Component = (props) => {
282
281
  "aria-label": "Member selection results",
283
282
  className: cn({ "ald-member-picker-popup-body": allowOverlap }),
284
283
  children: /* @__PURE__ */ jsx(Panel, {
284
+ active: dropdownOpen,
285
+ searchFailed: failed,
286
+ useProvidedGroupSearch: type === EMemberPicker.BOTH && !usesGroupQuery,
287
+ searchFeedback: !usesGroupQuery && /* @__PURE__ */ jsx(SearchFeedback, {
288
+ failed,
289
+ hasMore: searchResult.hasMore,
290
+ pathWarningCode: searchResult.pathWarningCode,
291
+ retry
292
+ }),
285
293
  type,
286
294
  footer,
287
295
  value: selectedUserList,
@@ -296,17 +304,35 @@ var Component = (props) => {
296
304
  onCancel?.();
297
305
  setDropdownOpen(false);
298
306
  },
307
+ canEnterGroup,
299
308
  renderItem,
300
309
  renderSelectedTag,
301
310
  searchValue: searchString
302
311
  })
303
312
  });
304
313
  }
305
- })
314
+ }), usesDialog && !isDisabled && /* @__PURE__ */ jsx(MemberPickerDialog, {
315
+ open: selectOpen,
316
+ value: value ?? selectedUserList,
317
+ type,
318
+ lockedIds,
319
+ filterItem,
320
+ canEnterGroup,
321
+ renderItem,
322
+ renderSelectedTag,
323
+ onChange: (members) => {
324
+ setSelectedUserList(members);
325
+ if (props.multiple) props.onChange?.(members);
326
+ },
327
+ footer,
328
+ onCancel,
329
+ onClose: () => onDropdownOpenChange(false)
330
+ })]
306
331
  });
307
332
  };
308
333
  var MemberSelector = Component;
309
334
  MemberSelector.MemberPanel = PanelWrapper;
335
+ MemberSelector.Dialog = MemberPickerDialog;
310
336
  //#endregion
311
337
  export { MemberSelector as default };
312
338
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/MemberPicker/index.tsx"],"sourcesContent":["import { usePrevious, useRequest } from 'ahooks';\nimport { cn } from '../lib/utils';\nimport _ from 'lodash';\nimport React, {\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport Avatar from '../Avatar';\nimport ConfigProvider from '../ConfigProvider';\nimport './member-picker.css';\nimport {\n EUserType,\n IUser,\n IUserGroup,\n TUser,\n} from '../ConfigProvider/getUserList';\nimport { LocaleContext, getTranslator } from '../locale/default';\nimport message from '../message';\nimport Panel from './components/Panel';\nimport MemberPanel from './components/PanelWrapper';\nimport {\n EMemberPicker,\n IMemberPickerProps,\n TUserGroupValue,\n TUserValue,\n} from './interface';\nimport { getId } from './utils';\nimport { isUser, isUserGroup } from './utils/getUsersWithUserId';\nimport Select from '../Select';\nimport { Mode } from '../Select/BaseSelect';\n\nconst DEFAULT_MULTIPLE_DROPDOWN_WIDTH = 480;\n\nconst Component: React.FC<IMemberPickerProps> = (props) => {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n\n const {\n value,\n type = EMemberPicker.USER,\n onChange,\n multiple,\n dropdownWidth,\n open,\n onOpenChange,\n placeholder = t.MemberPicker.select,\n className,\n allowClear,\n disabled,\n onClear,\n size,\n prefix: propPrefix,\n lockedIds = [],\n footer,\n onCancel,\n filterItem,\n mode: propsMode,\n renderItem,\n renderSelectedTag,\n 'data-testid': dataTestId,\n 'aria-label': ariaLabel,\n ...restProps\n } = props;\n const allowOverlap = props.allowOverlap ?? false;\n const { getUsersByIds, getUsersByKeywords } = ConfigProvider.useGetUserList();\n const [selectedUserList, setSelectedUserList] = useState<TUser>([]);\n const prevValue = usePrevious(value);\n const [searchUserList, setSearchUserList] = useState<TUser>([]);\n const [searchString, setSearchString] = useState<string>('');\n const [dropdownContentWidth, setDropdownContentWidth] =\n useState(dropdownWidth);\n const selectOwnerRef = useRef<HTMLDivElement>(null);\n // 单选默认浮窗跟触发器等宽(true),调用方传 dropdownWidth 时用具体数字;\n // 多选默认 480,单条记录只有 头像+nickname 时触发器太窄装不下选中标签,故固定值。\n const panelWidth: number | boolean =\n dropdownWidth ?? (multiple ? DEFAULT_MULTIPLE_DROPDOWN_WIDTH : true);\n\n const triggerRef = useRef<HTMLDivElement>(null);\n const onSearchValueChange = useCallback((v: string) => {\n setSearchString(v);\n }, []);\n const [dropdownOpen, setDropdownOpen] = useState<boolean>(!!open);\n const queryByKeywords = useMemo(() => {\n if (getUsersByKeywords) {\n return getUsersByKeywords;\n }\n\n return (_params = {}) =>\n Promise.reject({\n message: t.MemberPicker.pleaseConfigGetUserByKeywordsMethod,\n });\n }, [getUsersByKeywords, t.MemberPicker.pleaseConfigGetUserByKeywordsMethod]);\n const queryByIds = useMemo(() => {\n if (getUsersByIds) {\n return getUsersByIds;\n }\n\n return (_params = {}) =>\n Promise.reject({\n message: t.MemberPicker.pleaseConfigGetUserByIdsMethod,\n });\n }, [getUsersByIds, t.MemberPicker.pleaseConfigGetUserByIdsMethod]);\n const { loading, run } = useRequest(() => queryByKeywords(searchString), {\n refreshDeps: [searchString],\n manual: true,\n cacheKey: 'member-selector',\n cacheTime: 1000 * 60 * 2, // 2分钟内不重复请求\n onSuccess: (result) => {\n setSearchUserList(result);\n },\n onError: (error) => {\n message.error(error.message);\n },\n });\n\n const totalUserList: TUser = useMemo(() => {\n const totalUsers = searchUserList.concat(\n selectedUserList.filter((item) => {\n const name =\n (item.type === EUserType.USER ? item.nickname : item.name) || '';\n\n return name.toUpperCase().includes(searchString.trim().toUpperCase());\n }),\n );\n\n return _.uniqBy(totalUsers, (data: IUser | IUserGroup) => {\n if (data.type === EUserType.USER) return data.userId;\n\n return data.groupId;\n }).filter((item) => {\n if (filterItem) {\n return filterItem(item);\n }\n\n return true;\n });\n }, [filterItem, searchString, searchUserList, selectedUserList]);\n\n useEffect(() => {\n if (!dropdownOpen) return;\n run();\n }, [dropdownOpen, run, searchString]);\n\n useEffect(() => {\n if (_.isEqual(value, prevValue)) {\n return;\n }\n if (Array.isArray(value) && (isUser(value[0]) || isUserGroup(value[0]))) {\n setSelectedUserList(value as TUser);\n } else if (isUser(value) || isUserGroup(value)) {\n setSelectedUserList([value]);\n } else {\n let param: Array<TUserValue | TUserGroupValue> = [];\n if (!value) return;\n if (Array.isArray(value) && value.length === 0) {\n setSelectedUserList([]);\n\n return;\n }\n if (!Array.isArray(value)) {\n param = [value];\n } else {\n param = value;\n }\n queryByIds(param).then((result) => {\n // 如果用户已被删除,则需要展示出id\n const valueNotInResult: TUser = param\n .filter((item) => {\n if (item.type === EUserType.USER) {\n return result\n .filter(isUser)\n .every((user) => user.userId !== item.userId);\n }\n\n return result\n .filter(isUserGroup)\n .every((user) => user.groupId !== item.groupId);\n })\n .map((item) => {\n if (item.type === EUserType.USER) {\n return {\n type: EUserType.USER,\n userId: item.userId,\n } as IUser;\n }\n\n return {\n type: EUserType.USER_GROUP,\n groupId: item.groupId,\n } as IUserGroup;\n });\n\n setSelectedUserList([...result, ...valueNotInResult]);\n });\n }\n }, [value, queryByIds, prevValue]);\n\n const onSelectedChange = useCallback(\n (users: TUser) => {\n if (multiple) {\n setSelectedUserList(users);\n onChange?.(users);\n } else {\n setSelectedUserList(users);\n onChange?.(users[0]);\n }\n setDropdownOpen(false);\n },\n [multiple, onChange, setDropdownOpen],\n );\n\n useEffect(() => {\n if (typeof open === 'boolean') {\n setDropdownOpen(open);\n }\n }, [open]);\n\n useEffect(() => {\n if (!dropdownContentWidth) {\n const resizeEle = triggerRef.current;\n if (!resizeEle) return;\n const resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const { width } = entry.contentRect;\n setDropdownContentWidth(width);\n }\n });\n resizeObserver.observe(resizeEle);\n\n return () => {\n resizeObserver.unobserve(resizeEle);\n };\n }\n }, [triggerRef, dropdownContentWidth]);\n const onDropdownOpenChange = useCallback(\n (open: boolean) => {\n setDropdownOpen(open);\n onOpenChange?.(open);\n },\n [onOpenChange],\n );\n const mode = useMemo(() => {\n if (multiple === true) {\n if (typeof propsMode === 'object')\n return {\n ...(propsMode || {}),\n type: 'multiple',\n responsive: _.isNil(propsMode.responsive)\n ? true\n : propsMode.responsive,\n } as Mode;\n return {\n type: 'multiple',\n responsive: true,\n } as Mode;\n }\n\n return multiple ? (multiple as Mode) : propsMode;\n }, [multiple, propsMode]);\n\n const selectOpen = typeof open === 'boolean' ? open : dropdownOpen;\n const listboxId = `ald-member-picker-listbox-${React.useId().replace(\n /:/g,\n '',\n )}`;\n const activeMember = totalUserList[0];\n const activeMemberId = activeMember\n ? `ald-member-picker-option-${getId(activeMember)}`\n : undefined;\n\n useEffect(() => {\n const owner = selectOwnerRef.current?.querySelector<HTMLElement>(\n '[role=\"combobox\"], input',\n );\n if (!owner) return;\n owner.setAttribute('aria-controls', listboxId);\n if (selectOpen && activeMemberId) {\n owner.setAttribute('aria-activedescendant', activeMemberId);\n } else {\n owner.removeAttribute('aria-activedescendant');\n }\n }, [activeMemberId, listboxId, selectOpen]);\n\n return (\n <div ref={selectOwnerRef} style={{ display: 'contents' }}>\n <Select\n prefix={propPrefix}\n {...restProps}\n data-testid={dataTestId}\n aria-label={ariaLabel}\n showSearch\n searchValue={searchString}\n onSearch={onSearchValueChange}\n aria-controls={listboxId}\n aria-activedescendant={selectOpen ? activeMemberId : undefined}\n size={size}\n className={cn('ald-member-picker-select', className)}\n value={selectedUserList.map((item) => {\n if (item.type === EUserType.USER_GROUP) {\n return item.groupId;\n } else {\n return item.userId;\n }\n })}\n onChange={(value) => {\n if (_.isEmpty(value)) {\n setSelectedUserList([]);\n if (multiple) {\n onChange?.([]);\n } else {\n onChange?.();\n }\n } else {\n const valueList = Array.isArray(value) ? value : [value];\n if (multiple) {\n const users = valueList\n .map((item) => {\n const user = totalUserList.find((user) => {\n if (user.type === EUserType.USER) {\n return user.userId === item;\n }\n\n return user.groupId === item;\n });\n\n return user;\n })\n .filter(Boolean) as TUser;\n setSelectedUserList(users);\n onChange?.(users);\n } else {\n const user = totalUserList.find((user) => {\n if (user.type === EUserType.USER) {\n return user.userId === value;\n }\n\n return user.groupId === value;\n });\n if (user) {\n setSelectedUserList([user]);\n onChange?.(user);\n } else {\n setSelectedUserList([]);\n onChange?.();\n }\n }\n }\n }}\n disabled={disabled}\n allowClear={allowClear}\n onClear={() => {\n setSelectedUserList([]);\n if (multiple) {\n onChange?.([]);\n } else {\n onChange?.();\n }\n onClear?.();\n }}\n popupClassName={cn(\n 'ald-member-picker-popup',\n allowOverlap && 'ald-member-picker-popup-adaptive',\n props.popupClassName,\n )}\n mode={mode}\n options={selectedUserList.map((item) => {\n if (item.type === EUserType.USER_GROUP)\n return {\n label: item.name || item.groupId,\n value: item.groupId,\n tag: (\n <div className={'ald-member-picker-tag'}>\n <Avatar type=\"team\" size={20}>\n {item.name || item.groupId}\n </Avatar>\n {item.name || item.groupId}\n </div>\n ),\n };\n\n return {\n label: item.nickname || item.name || item.userId,\n value: item.userId,\n tag: (\n <div className={'ald-member-picker-tag'}>\n <Avatar\n size={20}\n src={item.photo}\n type={item.type === EUserType.USER ? 'user' : 'team'}\n >\n {item.nickname || item.name || item.userId}\n </Avatar>\n {item.nickname || item.name || item.userId}\n </div>\n ),\n };\n })}\n optionLabelProp={multiple ? 'label' : 'tag'}\n open={selectOpen}\n onOpenChange={onDropdownOpenChange}\n popupMatchSelectWidth={panelWidth}\n allowOverlap={allowOverlap}\n placeholder={placeholder}\n dropdownRender={() => {\n return (\n <div\n ref={triggerRef}\n id={listboxId}\n role=\"group\"\n aria-label=\"Member selection results\"\n className={cn({\n 'ald-member-picker-popup-body': allowOverlap,\n })}\n >\n <Panel\n type={type}\n footer={footer}\n value={selectedUserList}\n dataList={totalUserList}\n lockedIds={lockedIds}\n multiple={!!multiple}\n loading={loading}\n dropdownWidth={dropdownContentWidth}\n onSearchValueChange={onSearchValueChange}\n onChange={onSelectedChange}\n onCancel={() => {\n onCancel?.();\n setDropdownOpen(false);\n }}\n renderItem={renderItem}\n renderSelectedTag={renderSelectedTag}\n searchValue={searchString}\n ></Panel>\n </div>\n );\n }}\n ></Select>\n </div>\n );\n};\n\nconst MemberSelector = Component as React.FC<IMemberPickerProps> & {\n MemberPanel: typeof MemberPanel;\n};\n\nMemberSelector.MemberPanel = MemberPanel;\nexport default MemberSelector;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/MemberPicker/index.tsx"],"sourcesContent":["import MemberPickerDialog from './dialog/MemberPickerDialog';\nimport DisabledContext from '../ConfigProvider/DisabledContext';\nimport useMemberSearch from './useMemberSearch';\nimport SearchFeedback from './components/SearchFeedback';\nimport { usePrevious } from 'ahooks';\nimport { cn } from '../lib/utils';\nimport _ from 'lodash';\nimport React, {\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport Avatar from '../Avatar';\nimport ConfigProvider from '../ConfigProvider';\nimport './member-picker.css';\nimport {\n EUserType,\n IUser,\n IUserGroup,\n TUser,\n} from '../ConfigProvider/getUserList';\nimport { LocaleContext, getTranslator } from '../locale/default';\nimport Panel from './components/Panel';\nimport MemberPanel from './components/PanelWrapper';\nimport {\n EMemberPicker,\n IMemberPickerProps,\n TUserGroupValue,\n TUserValue,\n} from './interface';\nimport { getId } from './utils';\nimport { isUser, isUserGroup } from './utils/getUsersWithUserId';\nimport Select from '../Select';\nimport { Mode } from '../Select/BaseSelect';\n\nconst DEFAULT_MULTIPLE_DROPDOWN_WIDTH = 480;\n\nconst Component: React.FC<IMemberPickerProps> = (props) => {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n\n const {\n value,\n type = EMemberPicker.USER,\n onChange,\n multiple,\n dropdownWidth,\n open,\n onOpenChange,\n placeholder = t.MemberPicker.select,\n className,\n allowClear,\n disabled,\n onClear,\n size,\n prefix: propPrefix,\n lockedIds = [],\n footer,\n onCancel,\n filterItem,\n mode: propsMode,\n canEnterGroup,\n renderItem,\n renderSelectedTag,\n 'data-testid': dataTestId,\n 'aria-label': ariaLabel,\n ...restProps\n } = props;\n const allowOverlap = props.allowOverlap ?? false;\n const {\n getUsersByIds,\n getUsersByKeywords,\n getUsersByKeywordsWithMeta,\n getNextLevelGroup,\n getNextLevelGroupWithMeta,\n } = ConfigProvider.useGetUserList();\n const inheritedDisabled = useContext(DisabledContext);\n const isDisabled = disabled ?? inheritedDisabled;\n // 呈现方式由选择模式唯一决定,多选使用弹窗,单选保持浮窗。\n const usesDialog = !!multiple;\n const usesGroupQuery =\n (type === EMemberPicker.GROUP ||\n (!getUsersByKeywords && !getUsersByKeywordsWithMeta)) &&\n !!(getNextLevelGroup || getNextLevelGroupWithMeta);\n const [selectedUserList, setSelectedUserList] = useState<TUser>([]);\n const prevValue = usePrevious(value);\n const [searchString, setSearchString] = useState<string>('');\n const [dropdownContentWidth, setDropdownContentWidth] =\n useState(dropdownWidth);\n const selectOwnerRef = useRef<HTMLDivElement>(null);\n // 单选默认浮窗跟触发器等宽(true),调用方传 dropdownWidth 时用具体数字;\n // 多选默认 480,单条记录只有 头像+nickname 时触发器太窄装不下选中标签,故固定值。\n const panelWidth: number | boolean =\n dropdownWidth ?? (multiple ? DEFAULT_MULTIPLE_DROPDOWN_WIDTH : true);\n\n const triggerRef = useRef<HTMLDivElement>(null);\n const onSearchValueChange = useCallback((v: string) => {\n setSearchString(v);\n }, []);\n const [dropdownOpen, setDropdownOpen] = useState<boolean>(!!open);\n const queryByKeywords = useMemo(() => {\n if (getUsersByKeywordsWithMeta) return getUsersByKeywordsWithMeta;\n if (getUsersByKeywords) {\n return getUsersByKeywords;\n }\n\n return (_params = {}) =>\n Promise.reject({\n message: t.MemberPicker.pleaseConfigGetUserByKeywordsMethod,\n });\n }, [\n getUsersByKeywords,\n getUsersByKeywordsWithMeta,\n t.MemberPicker.pleaseConfigGetUserByKeywordsMethod,\n ]);\n const queryByIds = useMemo(() => {\n if (getUsersByIds) {\n return getUsersByIds;\n }\n\n return (_params = {}) =>\n Promise.reject({\n message: t.MemberPicker.pleaseConfigGetUserByIdsMethod,\n });\n }, [getUsersByIds, t.MemberPicker.pleaseConfigGetUserByIdsMethod]);\n const {\n result: searchResult,\n loading,\n failed,\n retry,\n } = useMemberSearch<IUser | IUserGroup>(\n queryByKeywords,\n searchString,\n dropdownOpen && !usesGroupQuery && !usesDialog,\n );\n const searchUserList = searchResult.items;\n\n const totalUserList: TUser = useMemo(() => {\n const totalUsers = searchUserList.concat(\n selectedUserList.filter((item) => {\n const name =\n (item.type === EUserType.USER ? item.nickname : item.name) || '';\n\n return name.toUpperCase().includes(searchString.trim().toUpperCase());\n }),\n );\n\n return _.uniqBy(totalUsers, (data: IUser | IUserGroup) => {\n if (data.type === EUserType.USER) return data.userId;\n\n return data.groupId;\n }).filter((item) => {\n if (filterItem) {\n return filterItem(item);\n }\n\n return true;\n });\n }, [filterItem, searchString, searchUserList, selectedUserList]);\n\n useEffect(() => {\n if (_.isEqual(value, prevValue)) {\n return;\n }\n if (Array.isArray(value) && (isUser(value[0]) || isUserGroup(value[0]))) {\n setSelectedUserList(value as TUser);\n } else if (isUser(value) || isUserGroup(value)) {\n setSelectedUserList([value]);\n } else {\n let param: Array<TUserValue | TUserGroupValue> = [];\n if (!value) return;\n if (Array.isArray(value) && value.length === 0) {\n setSelectedUserList([]);\n\n return;\n }\n if (!Array.isArray(value)) {\n param = [value];\n } else {\n param = value;\n }\n queryByIds(param).then((result) => {\n // 如果用户已被删除,则需要展示出id\n const valueNotInResult: TUser = param\n .filter((item) => {\n if (item.type === EUserType.USER) {\n return result\n .filter(isUser)\n .every((user) => user.userId !== item.userId);\n }\n\n return result\n .filter(isUserGroup)\n .every((user) => user.groupId !== item.groupId);\n })\n .map((item) => {\n if (item.type === EUserType.USER) {\n return {\n type: EUserType.USER,\n userId: item.userId,\n } as IUser;\n }\n\n return {\n type: EUserType.USER_GROUP,\n groupId: item.groupId,\n } as IUserGroup;\n });\n\n setSelectedUserList([...result, ...valueNotInResult]);\n });\n }\n }, [value, queryByIds, prevValue]);\n\n const onSelectedChange = useCallback(\n (users: TUser) => {\n if (multiple) {\n setSelectedUserList(users);\n onChange?.(users);\n } else {\n setSelectedUserList(users);\n onChange?.(users[0]);\n }\n setDropdownOpen(false);\n },\n [multiple, onChange, setDropdownOpen],\n );\n\n useEffect(() => {\n if (typeof open === 'boolean') {\n setDropdownOpen(open);\n }\n }, [open]);\n\n useEffect(() => {\n if (!dropdownContentWidth) {\n const resizeEle = triggerRef.current;\n if (!resizeEle) return;\n const resizeObserver = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const { width } = entry.contentRect;\n setDropdownContentWidth(width);\n }\n });\n resizeObserver.observe(resizeEle);\n\n return () => {\n resizeObserver.unobserve(resizeEle);\n };\n }\n }, [triggerRef, dropdownContentWidth]);\n const onDropdownOpenChange = useCallback(\n (open: boolean) => {\n if (isDisabled) return;\n if (!usesDialog || typeof props.open !== 'boolean') setDropdownOpen(open);\n onOpenChange?.(open);\n },\n [isDisabled, usesDialog, props.open, onOpenChange],\n );\n const mode = useMemo(() => {\n if (multiple === true) {\n if (typeof propsMode === 'object')\n return {\n ...(propsMode || {}),\n type: 'multiple',\n responsive: _.isNil(propsMode.responsive)\n ? true\n : propsMode.responsive,\n } as Mode;\n return {\n type: 'multiple',\n responsive: true,\n } as Mode;\n }\n\n return multiple ? (multiple as Mode) : propsMode;\n }, [multiple, propsMode]);\n\n const selectOpen = typeof open === 'boolean' ? open : dropdownOpen;\n const listboxId = `ald-member-picker-listbox-${React.useId().replace(\n /:/g,\n '',\n )}`;\n const activeMember = totalUserList[0];\n const activeMemberId = activeMember\n ? `ald-member-picker-option-${getId(activeMember)}`\n : undefined;\n\n useEffect(() => {\n const owner = selectOwnerRef.current?.querySelector<HTMLElement>(\n '[role=\"combobox\"], input',\n );\n if (!owner) return;\n owner.setAttribute('aria-controls', listboxId);\n if (selectOpen && activeMemberId) {\n owner.setAttribute('aria-activedescendant', activeMemberId);\n } else {\n owner.removeAttribute('aria-activedescendant');\n }\n }, [activeMemberId, listboxId, selectOpen]);\n\n return (\n <div ref={selectOwnerRef} style={{ display: 'contents' }}>\n <Select\n prefix={propPrefix}\n {...restProps}\n data-testid={dataTestId}\n aria-label={ariaLabel}\n showSearch={!usesDialog}\n searchValue={searchString}\n onSearch={onSearchValueChange}\n aria-controls={listboxId}\n aria-activedescendant={selectOpen ? activeMemberId : undefined}\n size={size}\n className={cn('ald-member-picker-select', className)}\n value={selectedUserList.map((item) => {\n if (item.type === EUserType.USER_GROUP) {\n return item.groupId;\n } else {\n return item.userId;\n }\n })}\n onChange={(value) => {\n if (_.isEmpty(value)) {\n setSelectedUserList([]);\n if (multiple) {\n onChange?.([]);\n } else {\n onChange?.();\n }\n } else {\n const valueList = Array.isArray(value) ? value : [value];\n if (multiple) {\n const users = valueList\n .map((item) => {\n const user = totalUserList.find((user) => {\n if (user.type === EUserType.USER) {\n return user.userId === item;\n }\n\n return user.groupId === item;\n });\n\n return user;\n })\n .filter(Boolean) as TUser;\n setSelectedUserList(users);\n onChange?.(users);\n } else {\n const user = totalUserList.find((user) => {\n if (user.type === EUserType.USER) {\n return user.userId === value;\n }\n\n return user.groupId === value;\n });\n if (user) {\n setSelectedUserList([user]);\n onChange?.(user);\n } else {\n setSelectedUserList([]);\n onChange?.();\n }\n }\n }\n }}\n disabled={isDisabled}\n allowClear={allowClear}\n onClear={() => {\n setSelectedUserList([]);\n if (multiple) {\n onChange?.([]);\n } else {\n onChange?.();\n }\n onClear?.();\n }}\n popupClassName={cn(\n 'ald-member-picker-popup',\n allowOverlap && 'ald-member-picker-popup-adaptive',\n props.popupClassName,\n )}\n mode={mode}\n options={selectedUserList.map((item) => {\n if (item.type === EUserType.USER_GROUP)\n return {\n label: item.name || item.groupId,\n value: item.groupId,\n tag: (\n <div className={'ald-member-picker-tag'}>\n <Avatar type=\"team\" size={20}>\n {item.name || item.groupId}\n </Avatar>\n {item.name || item.groupId}\n </div>\n ),\n };\n\n return {\n label: item.nickname || item.name || item.userId,\n value: item.userId,\n tag: (\n <div className={'ald-member-picker-tag'}>\n <Avatar\n size={20}\n src={item.photo}\n type={item.type === EUserType.USER ? 'user' : 'team'}\n >\n {item.nickname || item.name || item.userId}\n </Avatar>\n {item.nickname || item.name || item.userId}\n </div>\n ),\n };\n })}\n optionLabelProp={multiple ? 'label' : 'tag'}\n open={usesDialog ? false : selectOpen}\n onOpenChange={onDropdownOpenChange}\n popupMatchSelectWidth={panelWidth}\n allowOverlap={allowOverlap}\n placeholder={placeholder}\n dropdownRender={() => {\n return (\n <div\n ref={triggerRef}\n id={listboxId}\n role=\"group\"\n aria-label=\"Member selection results\"\n className={cn({\n 'ald-member-picker-popup-body': allowOverlap,\n })}\n >\n <Panel\n active={dropdownOpen}\n searchFailed={failed}\n useProvidedGroupSearch={\n type === EMemberPicker.BOTH && !usesGroupQuery\n }\n searchFeedback={\n !usesGroupQuery && (\n <SearchFeedback\n failed={failed}\n hasMore={searchResult.hasMore}\n pathWarningCode={searchResult.pathWarningCode}\n retry={retry}\n />\n )\n }\n type={type}\n footer={footer}\n value={selectedUserList}\n dataList={totalUserList}\n lockedIds={lockedIds}\n multiple={!!multiple}\n loading={loading}\n dropdownWidth={dropdownContentWidth}\n onSearchValueChange={onSearchValueChange}\n onChange={onSelectedChange}\n onCancel={() => {\n onCancel?.();\n setDropdownOpen(false);\n }}\n canEnterGroup={canEnterGroup}\n renderItem={renderItem}\n renderSelectedTag={renderSelectedTag}\n searchValue={searchString}\n ></Panel>\n </div>\n );\n }}\n ></Select>\n {usesDialog && !isDisabled && (\n <MemberPickerDialog\n open={selectOpen}\n value={value ?? selectedUserList}\n type={type}\n lockedIds={lockedIds}\n filterItem={filterItem}\n canEnterGroup={canEnterGroup}\n renderItem={renderItem}\n renderSelectedTag={renderSelectedTag}\n onChange={(members) => {\n setSelectedUserList(members);\n if (props.multiple) props.onChange?.(members);\n }}\n footer={footer}\n onCancel={onCancel}\n onClose={() => onDropdownOpenChange(false)}\n />\n )}\n </div>\n );\n};\n\nconst MemberSelector = Component as React.FC<IMemberPickerProps> & {\n MemberPanel: typeof MemberPanel;\n Dialog: typeof MemberPickerDialog;\n};\n\nMemberSelector.MemberPanel = MemberPanel;\nMemberSelector.Dialog = MemberPickerDialog;\nexport default MemberSelector;\n"],"mappings":"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"}
@@ -20,6 +20,12 @@ export interface IBaseMemberSelectorProps extends Omit<ISelectProps, 'type'> {
20
20
  lockedIds?: Array<TUserValue | TUserGroupValue>;
21
21
  footer?: ReactNode;
22
22
  onCancel?: () => void;
23
+ /**
24
+ * 控制用户组是否允许进入下级。返回 false 时隐藏“下级”入口,且不提供
25
+ * renderItem 的 onNextLevel;不影响该组的选择。省略时保留原有层级行为。
26
+ * 平铺列表可传 () => false,也可按组判断;仅限制原有入口,不推断层级数据。
27
+ */
28
+ canEnterGroup?: (group: IUserGroup) => boolean;
23
29
  filterItem?: (item: IUser | IUserGroup) => boolean;
24
30
  renderItem?: (item: IUser | IUserGroup, context: {
25
31
  isSelected: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"interface.js","names":[],"sources":["../../src/MemberPicker/interface.ts"],"sourcesContent":["import { ReactNode } from 'react';\nimport { IUser, IUserGroup, TUser } from '../ConfigProvider/getUserList';\nimport { ISelectProps } from '../Select/interface';\nimport { RequiredProperties } from '../_utils/type';\nimport { Mode } from '../Select/BaseSelect';\n\nexport type TUserValue = RequiredProperties<IUser, 'type' | 'userId'>;\nexport type TUserGroupValue = RequiredProperties<\n IUserGroup,\n 'type' | 'groupId'\n>;\n\nexport type TMemberPickerValue =\n | TUserValue\n | TUserGroupValue\n | Array<TUserValue | TUserGroupValue>;\n\nexport enum EMemberPicker {\n GROUP = 'GROUP',\n USER = 'USER',\n BOTH = 'BOTH',\n}\n\nexport interface IBaseMemberSelectorProps extends Omit<ISelectProps, 'type'> {\n value?: TMemberPickerValue;\n dropdownWidth?: number;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n type?: EMemberPicker;\n lockedIds?: Array<TUserValue | TUserGroupValue>;\n footer?: ReactNode;\n onCancel?: () => void;\n filterItem?: (item: IUser | IUserGroup) => boolean;\n renderItem?: (\n item: IUser | IUserGroup,\n context: {\n isSelected: boolean;\n disabled: boolean;\n onClick: () => void;\n onNextLevel?: () => void;\n originNode: ReactNode;\n },\n ) => ReactNode;\n renderSelectedTag?: (\n user: IUser | IUserGroup,\n originNode: ReactNode,\n ) => ReactNode;\n}\n\nexport interface IMultipleMemberSelectorProps extends IBaseMemberSelectorProps {\n multiple: true | Mode;\n onChange?(v: TUser): void;\n}\n\nexport interface ISingleMemberSelectorProps extends IBaseMemberSelectorProps {\n multiple?: false;\n onChange?(v?: IUser | IUserGroup): void;\n}\n\nexport type IMemberPickerProps =\n | IMultipleMemberSelectorProps\n | ISingleMemberSelectorProps;\n\nexport type { IUser };\n"],"mappings":";AAiBA,IAAY,gBAAL,yBAAA,eAAA;AACL,eAAA,WAAA;AACA,eAAA,UAAA;AACA,eAAA,UAAA;;KACD"}
1
+ {"version":3,"file":"interface.js","names":[],"sources":["../../src/MemberPicker/interface.ts"],"sourcesContent":["import { ReactNode } from 'react';\nimport { IUser, IUserGroup, TUser } from '../ConfigProvider/getUserList';\nimport { ISelectProps } from '../Select/interface';\nimport { RequiredProperties } from '../_utils/type';\nimport { Mode } from '../Select/BaseSelect';\n\nexport type TUserValue = RequiredProperties<IUser, 'type' | 'userId'>;\nexport type TUserGroupValue = RequiredProperties<\n IUserGroup,\n 'type' | 'groupId'\n>;\n\nexport type TMemberPickerValue =\n | TUserValue\n | TUserGroupValue\n | Array<TUserValue | TUserGroupValue>;\n\nexport enum EMemberPicker {\n GROUP = 'GROUP',\n USER = 'USER',\n BOTH = 'BOTH',\n}\n\nexport interface IBaseMemberSelectorProps extends Omit<ISelectProps, 'type'> {\n value?: TMemberPickerValue;\n dropdownWidth?: number;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n type?: EMemberPicker;\n lockedIds?: Array<TUserValue | TUserGroupValue>;\n footer?: ReactNode;\n onCancel?: () => void;\n /**\n * 控制用户组是否允许进入下级。返回 false 时隐藏“下级”入口,且不提供\n * renderItem 的 onNextLevel;不影响该组的选择。省略时保留原有层级行为。\n * 平铺列表可传 () => false,也可按组判断;仅限制原有入口,不推断层级数据。\n */\n canEnterGroup?: (group: IUserGroup) => boolean;\n filterItem?: (item: IUser | IUserGroup) => boolean;\n renderItem?: (\n item: IUser | IUserGroup,\n context: {\n isSelected: boolean;\n disabled: boolean;\n onClick: () => void;\n onNextLevel?: () => void;\n originNode: ReactNode;\n },\n ) => ReactNode;\n renderSelectedTag?: (\n user: IUser | IUserGroup,\n originNode: ReactNode,\n ) => ReactNode;\n}\n\nexport interface IMultipleMemberSelectorProps extends IBaseMemberSelectorProps {\n multiple: true | Mode;\n onChange?(v: TUser): void;\n}\n\nexport interface ISingleMemberSelectorProps extends IBaseMemberSelectorProps {\n multiple?: false;\n onChange?(v?: IUser | IUserGroup): void;\n}\n\nexport type IMemberPickerProps =\n | IMultipleMemberSelectorProps\n | ISingleMemberSelectorProps;\n\nexport type { IUser };\n"],"mappings":";AAiBA,IAAY,gBAAL,yBAAA,eAAA;AACL,eAAA,WAAA;AACA,eAAA,UAAA;AACA,eAAA,UAAA;;KACD"}
@@ -0,0 +1,8 @@
1
+ import { MemberSearchResult } from '../ConfigProvider/getUserList';
2
+ /** 搜索状态只属于当前组件和当前请求;关闭、换关键字后拒绝旧响应回写。 */
3
+ export default function useMemberSearch<T>(query: (keyword: string) => Promise<T[] | MemberSearchResult<T>>, keyword: string, enabled?: boolean): {
4
+ result: MemberSearchResult<T>;
5
+ loading: boolean;
6
+ failed: boolean;
7
+ retry: () => void;
8
+ };
@@ -0,0 +1,51 @@
1
+ import { useCallback, useEffect, useState } from "react";
2
+ //#region src/MemberPicker/useMemberSearch.ts
3
+ /** 搜索状态只属于当前组件和当前请求;关闭、换关键字后拒绝旧响应回写。 */
4
+ function useMemberSearch(query, keyword, enabled = true) {
5
+ const [result, setResult] = useState({ items: [] });
6
+ const [loading, setLoading] = useState(false);
7
+ const [failed, setFailed] = useState(false);
8
+ const [revision, setRevision] = useState(0);
9
+ const retry = useCallback(() => setRevision((value) => value + 1), []);
10
+ useEffect(() => {
11
+ if (!enabled) {
12
+ setLoading(false);
13
+ return;
14
+ }
15
+ let active = true;
16
+ setLoading(true);
17
+ setResult({ items: [] });
18
+ setFailed(false);
19
+ const timer = setTimeout(() => {
20
+ query(keyword).then((response) => {
21
+ if (active) setResult(Array.isArray(response) ? { items: response } : response);
22
+ }).catch(() => {
23
+ if (active) {
24
+ setFailed(true);
25
+ setResult({ items: [] });
26
+ }
27
+ }).finally(() => {
28
+ if (active) setLoading(false);
29
+ });
30
+ }, keyword ? 300 : 0);
31
+ return () => {
32
+ active = false;
33
+ clearTimeout(timer);
34
+ };
35
+ }, [
36
+ query,
37
+ keyword,
38
+ enabled,
39
+ revision
40
+ ]);
41
+ return {
42
+ result,
43
+ loading,
44
+ failed,
45
+ retry
46
+ };
47
+ }
48
+ //#endregion
49
+ export { useMemberSearch as default };
50
+
51
+ //# sourceMappingURL=useMemberSearch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMemberSearch.js","names":[],"sources":["../../src/MemberPicker/useMemberSearch.ts"],"sourcesContent":["import { useCallback, useEffect, useState } from 'react';\nimport { MemberSearchResult } from '../ConfigProvider/getUserList';\n\n/** 搜索状态只属于当前组件和当前请求;关闭、换关键字后拒绝旧响应回写。 */\nexport default function useMemberSearch<T>(\n query: (keyword: string) => Promise<T[] | MemberSearchResult<T>>,\n keyword: string,\n enabled = true,\n) {\n const [result, setResult] = useState<MemberSearchResult<T>>({ items: [] });\n const [loading, setLoading] = useState(false);\n const [failed, setFailed] = useState(false);\n const [revision, setRevision] = useState(0);\n const retry = useCallback(() => setRevision((value) => value + 1), []);\n useEffect(() => {\n if (!enabled) {\n setLoading(false);\n return;\n }\n let active = true;\n setLoading(true);\n setResult({ items: [] });\n setFailed(false);\n const timer = setTimeout(\n () => {\n query(keyword)\n .then((response) => {\n if (active) {\n setResult(\n Array.isArray(response) ? { items: response } : response,\n );\n }\n })\n .catch(() => {\n if (active) {\n setFailed(true);\n setResult({ items: [] });\n }\n })\n .finally(() => {\n if (active) setLoading(false);\n });\n },\n keyword ? 300 : 0,\n );\n return () => {\n active = false;\n clearTimeout(timer);\n };\n }, [query, keyword, enabled, revision]);\n return { result, loading, failed, retry };\n}\n"],"mappings":";;;AAIA,SAAwB,gBACtB,OACA,SACA,UAAU,MACV;CACA,MAAM,CAAC,QAAQ,aAAa,SAAgC,EAAE,OAAO,EAAE,EAAE,CAAC;CAC1E,MAAM,CAAC,SAAS,cAAc,SAAS,MAAM;CAC7C,MAAM,CAAC,QAAQ,aAAa,SAAS,MAAM;CAC3C,MAAM,CAAC,UAAU,eAAe,SAAS,EAAE;CAC3C,MAAM,QAAQ,kBAAkB,aAAa,UAAU,QAAQ,EAAE,EAAE,EAAE,CAAC;AACtE,iBAAgB;AACd,MAAI,CAAC,SAAS;AACZ,cAAW,MAAM;AACjB;;EAEF,IAAI,SAAS;AACb,aAAW,KAAK;AAChB,YAAU,EAAE,OAAO,EAAE,EAAE,CAAC;AACxB,YAAU,MAAM;EAChB,MAAM,QAAQ,iBACN;AACJ,SAAM,QAAQ,CACX,MAAM,aAAa;AAClB,QAAI,OACF,WACE,MAAM,QAAQ,SAAS,GAAG,EAAE,OAAO,UAAU,GAAG,SACjD;KAEH,CACD,YAAY;AACX,QAAI,QAAQ;AACV,eAAU,KAAK;AACf,eAAU,EAAE,OAAO,EAAE,EAAE,CAAC;;KAE1B,CACD,cAAc;AACb,QAAI,OAAQ,YAAW,MAAM;KAC7B;KAEN,UAAU,MAAM,EACjB;AACD,eAAa;AACX,YAAS;AACT,gBAAa,MAAM;;IAEpB;EAAC;EAAO;EAAS;EAAS;EAAS,CAAC;AACvC,QAAO;EAAE;EAAQ;EAAS;EAAQ;EAAO"}
@@ -10,11 +10,17 @@ export interface MenuProps {
10
10
  ariaLabel?: string;
11
11
  /** @internal Requested initial keyboard position when the popup opens. */
12
12
  initialFocus?: 'first' | 'last';
13
+ /** @internal Whether the current popup entry originated from keyboard input. */
14
+ keyboardFocus?: boolean;
15
+ /** @internal Whether opening the popup should transfer focus to an item. */
16
+ captureFocus?: boolean;
13
17
  /** @internal Requests that the owning popup close, including on Escape. */
14
18
  onRequestClose?: (reason: 'click' | 'cancel' | 'blur' | 'scroll') => void;
15
19
  rootClosing?: boolean;
16
20
  /** @internal 由 Dropdown 注入,禁用内部定位/overflow 计算。不支持含 SubMenu 的菜单 */
17
21
  externalOverflow?: boolean;
22
+ /** @internal Dropdown 已按实际裁剪区域计算根菜单高度,保留其限制。 */
23
+ preserveRootHeight?: boolean;
18
24
  }
19
25
  export default function Menu(props: MenuProps): import("react/jsx-runtime").JSX.Element;
20
26
  export declare function isHeaderMenuItem(menuItem: MenuItemType): menuItem is MenuHeaderType;
@@ -2,19 +2,23 @@ import { cn } from "../lib/utils.js";
2
2
  import Memo from "../Icon/components/CheckLightLine.js";
3
3
  import Memo$1 from "../Icon/components/ChevronRightLine.js";
4
4
  /* empty css */
5
- import { useCallback, useMemo, useRef } from "react";
5
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
6
6
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
7
  import _ from "lodash";
8
8
  import { ControlledMenu, MenuDivider, MenuHeader, MenuItem, SubMenu } from "@szhsin/react-menu";
9
9
  //#region src/Menu/index.tsx
10
10
  function Menu(props) {
11
- const { className, items, onClick: onMenuClick, onBeforeLeafItemClick, selectedKeys, menuStyle, ariaLabel, initialFocus = "first", onRequestClose, rootClosing = false, externalOverflow } = props;
11
+ const { className, items, onClick: onMenuClick, onBeforeLeafItemClick, selectedKeys, menuStyle, ariaLabel, initialFocus = "first", keyboardFocus = false, captureFocus = true, onRequestClose, rootClosing = false, externalOverflow, preserveRootHeight = false } = props;
12
12
  const selectedKeySet = new Set(selectedKeys || []);
13
13
  const typeaheadRef = useRef({
14
14
  query: "",
15
15
  timestamp: 0
16
16
  });
17
- const menuItemFocus = useMemo(() => ({ position: initialFocus }), [initialFocus]);
17
+ const [isKeyboardFocus, setIsKeyboardFocus] = useState(keyboardFocus);
18
+ useEffect(() => {
19
+ setIsKeyboardFocus(keyboardFocus);
20
+ }, [keyboardFocus]);
21
+ const menuItemFocus = useMemo(() => captureFocus ? { position: initialFocus } : void 0, [captureFocus, initialFocus]);
18
22
  const onMenuKeyDown = useCallback((event) => {
19
23
  if (event.defaultPrevented || event.altKey || event.ctrlKey || event.metaKey || event.key.length !== 1) return;
20
24
  const now = Date.now();
@@ -71,14 +75,17 @@ function Menu(props) {
71
75
  }),
72
76
  disabled: item.disabled,
73
77
  "aria-label": item.ariaLabel || titleStr || void 0,
74
- itemProps: { className: isLeafSubMenu ? "ald-menu-submenu-leaf-trigger" : void 0 },
78
+ itemProps: {
79
+ className: isLeafSubMenu ? "ald-menu-submenu-leaf-trigger" : void 0,
80
+ onPointerMove: () => setIsKeyboardFocus(false)
81
+ },
75
82
  align: "start",
76
83
  direction: "right",
77
84
  gap: -8,
78
85
  position: "anchor",
79
86
  shift: 0,
80
87
  menuStyle: { ...menuStyle },
81
- menuClassName: cn("ald-menu-submenu-popup", isLeafSubMenu && "ald-menu-submenu-popup-leaf", !isLeafSubMenu && menuStyle?.maxHeight !== void 0 && "ald-menu-submenu-popup-scrollable", item.popupClassName, rootClosing && "ald-menu-submenu-popup-root-closing"),
88
+ menuClassName: cn("ald-menu-submenu-popup", isLeafSubMenu && "ald-menu-submenu-popup-leaf", !isLeafSubMenu && menuStyle?.maxHeight !== void 0 && "ald-menu-submenu-popup-scrollable", item.popupClassName, isKeyboardFocus && "ald-menu-focus-visible", rootClosing && "ald-menu-submenu-popup-root-closing"),
82
89
  overflow: subMenuOverflow,
83
90
  children: getMenuItems(item.children, currPath)
84
91
  }, item.key);
@@ -90,6 +97,7 @@ function Menu(props) {
90
97
  }),
91
98
  disabled: item.disabled,
92
99
  "aria-label": item.ariaLabel || titleStr || void 0,
100
+ onPointerMove: () => setIsKeyboardFocus(false),
93
101
  onClick: ({ syntheticEvent }) => {
94
102
  onBeforeLeafItemClick?.();
95
103
  const menuInfo = {
@@ -139,14 +147,18 @@ function Menu(props) {
139
147
  transitionTimeout: 200,
140
148
  submenuOpenDelay: 0,
141
149
  submenuCloseDelay: 0,
150
+ setDownOverflow: preserveRootHeight,
142
151
  menuStyle: { ...menuStyle },
143
152
  anchorRef: ref,
144
- className: cn(className, "ald-menu", isLeafRootMenu && !externalOverflow && "ald-menu-leaf", !isLeafRootMenu && menuStyle?.maxHeight !== void 0 && !externalOverflow && "ald-menu-scrollable"),
153
+ className: cn(className, "ald-menu", isKeyboardFocus && "ald-menu-focus-visible", isLeafRootMenu && !externalOverflow && "ald-menu-leaf", !isLeafRootMenu && menuStyle?.maxHeight !== void 0 && !externalOverflow && "ald-menu-scrollable"),
145
154
  position: externalOverflow ? "initial" : "auto",
146
155
  "aria-label": ariaLabel,
147
- captureFocus: true,
156
+ captureFocus,
148
157
  menuItemFocus,
149
- onKeyDown: onMenuKeyDown,
158
+ onKeyDown: (event) => {
159
+ setIsKeyboardFocus(true);
160
+ onMenuKeyDown(event);
161
+ },
150
162
  onClose: ({ reason }) => onRequestClose?.(reason),
151
163
  viewScroll: externalOverflow ? "initial" : "auto",
152
164
  overflow: externalOverflow ? "visible" : menuOverflow,
@@ -166,6 +178,6 @@ function isLeafMenu(menuItems) {
166
178
  return !_.some(menuItems, (item) => isSubMenuItem(item));
167
179
  }
168
180
  //#endregion
169
- export { Menu as default, isDivideMenuItem, isHeaderMenuItem, isSubMenuItem };
181
+ export { Menu as default, isDivideMenuItem, isHeaderMenuItem, isLeafMenu, isSubMenuItem };
170
182
 
171
183
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../src/Menu/index.tsx"],"sourcesContent":["import {\n ControlledMenu,\n MenuDivider,\n MenuHeader,\n MenuItem,\n SubMenu,\n} from '@szhsin/react-menu';\nimport { cn } from '../lib/utils';\nimport _ from 'lodash';\nimport React, { useCallback, useMemo, useRef } from 'react';\nimport { CheckLightLine, ChevronRightLine } from '../Icon';\nimport './menu.css';\n\nexport interface MenuProps {\n onClick?: (info: MenuInfo) => void;\n onBeforeLeafItemClick?: () => void;\n className?: string;\n items: MenuItemType[];\n selectedKeys?: string[];\n menuStyle?: React.CSSProperties;\n /** Accessible name for the command menu when its context is not otherwise clear. */\n ariaLabel?: string;\n /** @internal Requested initial keyboard position when the popup opens. */\n initialFocus?: 'first' | 'last';\n /** @internal Requests that the owning popup close, including on Escape. */\n onRequestClose?: (reason: 'click' | 'cancel' | 'blur' | 'scroll') => void;\n rootClosing?: boolean;\n /** @internal 由 Dropdown 注入,禁用内部定位/overflow 计算。不支持含 SubMenu 的菜单 */\n externalOverflow?: boolean;\n}\n\nexport default function Menu(props: MenuProps) {\n const {\n className,\n items,\n onClick: onMenuClick,\n onBeforeLeafItemClick,\n selectedKeys,\n menuStyle,\n ariaLabel,\n initialFocus = 'first',\n onRequestClose,\n rootClosing = false,\n externalOverflow,\n } = props;\n const selectedKeySet = new Set(selectedKeys || []);\n const typeaheadRef = useRef({ query: '', timestamp: 0 });\n const menuItemFocus = useMemo(\n () => ({ position: initialFocus }),\n [initialFocus],\n );\n const onMenuKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLUListElement>) => {\n if (\n event.defaultPrevented ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n event.key.length !== 1\n ) {\n return;\n }\n\n const now = Date.now();\n const previous = typeaheadRef.current;\n const query = `${now - previous.timestamp > 500 ? '' : previous.query}${\n event.key\n }`.toLocaleLowerCase();\n typeaheadRef.current = { query, timestamp: now };\n\n const menuItems = Array.from(\n event.currentTarget.querySelectorAll<HTMLElement>(\n '[role=\"menuitem\"]:not([aria-hidden=\"true\"]):not([aria-disabled=\"true\"])',\n ),\n );\n const activeIndex = menuItems.indexOf(\n document.activeElement as HTMLElement,\n );\n const orderedItems = [\n ...menuItems.slice(activeIndex + 1),\n ...menuItems.slice(0, activeIndex + 1),\n ];\n const match = orderedItems.find((item) => {\n const accessibleName =\n item.getAttribute('aria-label') || item.textContent || '';\n return accessibleName.trim().toLocaleLowerCase().startsWith(query);\n });\n\n if (match) {\n event.preventDefault();\n match.focus();\n }\n },\n [],\n );\n\n const hasDirectSelectedItem = (items: MenuItemType[]): boolean =>\n items.some((item) => {\n if (isSubMenuItem(item)) {\n return selectedKeySet.has(item.key);\n }\n if (isHeaderMenuItem(item) || isDivideMenuItem(item)) {\n return false;\n }\n return selectedKeySet.has(item.key);\n });\n\n const getMenuItems = (items: MenuItemType[], parentPath: string[] = []) => {\n const isSelectableGroup = hasDirectSelectedItem(items);\n\n return items.map((item, index) => {\n if (isDivideMenuItem(item)) {\n return <MenuDivider key={`divider_${index}`} />;\n }\n if (isHeaderMenuItem(item)) {\n return <MenuHeader key={`header_${index}`}>{item.label}</MenuHeader>;\n }\n const currPath = [...parentPath, item.key];\n const titleStr = _.isString(item.label) ? item.label : '';\n const isSelected = selectedKeys?.includes(item.key);\n\n if (isSubMenuItem(item)) {\n const isLeafSubMenu = isLeafMenu(item.children);\n const subMenuOverflow =\n isLeafSubMenu || menuStyle?.maxHeight !== undefined\n ? 'auto'\n : undefined;\n const subMenuItemLabel = (\n <div className=\"ald-menu-item-label\" title={titleStr}>\n {item.icon ? (\n <div className=\"ald-menu-item-label-icon\">{item.icon}</div>\n ) : null}\n <div className=\"ald-menu-item-label-text tw-text-typography-body-dense\">\n {item.label}\n </div>\n <div className=\"ald-menu-item-right\">\n {isSelectableGroup ? (\n <div className=\"ald-menu-item-selection-slot\" />\n ) : null}\n <ChevronRightLine size={16} />\n </div>\n </div>\n );\n\n return (\n <SubMenu\n key={item.key}\n label={subMenuItemLabel}\n disabled={item.disabled}\n aria-label={item.ariaLabel || titleStr || undefined}\n itemProps={{\n className: isLeafSubMenu\n ? 'ald-menu-submenu-leaf-trigger'\n : undefined,\n }}\n align=\"start\"\n direction=\"right\"\n gap={-8}\n position=\"anchor\"\n shift={0}\n menuStyle={{\n ...menuStyle,\n }}\n menuClassName={cn(\n 'ald-menu-submenu-popup',\n isLeafSubMenu && 'ald-menu-submenu-popup-leaf',\n !isLeafSubMenu &&\n menuStyle?.maxHeight !== undefined &&\n 'ald-menu-submenu-popup-scrollable',\n item.popupClassName,\n rootClosing && 'ald-menu-submenu-popup-root-closing',\n )}\n overflow={subMenuOverflow}\n >\n {getMenuItems(item.children, currPath)}\n </SubMenu>\n );\n }\n\n return (\n <MenuItem\n key={item.key}\n className={cn(item.className, {\n 'ald-menu-item-danger': item.danger,\n 'ald-menu-item-selected': isSelected,\n })}\n disabled={item.disabled}\n aria-label={item.ariaLabel || titleStr || undefined}\n onClick={({ syntheticEvent }) => {\n onBeforeLeafItemClick?.();\n const menuInfo = {\n key: item.key,\n keyPath: currPath,\n domEvent: syntheticEvent,\n };\n if (item.onClick) {\n item.onClick(menuInfo);\n }\n if (onMenuClick) {\n onMenuClick(menuInfo);\n }\n }}\n >\n <div className=\"ald-menu-item-label\" title={titleStr}>\n {item.icon ? (\n <div className=\"ald-menu-item-label-icon\">{item.icon}</div>\n ) : null}\n <div className=\"ald-menu-item-label-text tw-text-typography-body-dense\">\n {item.label}\n </div>\n {isSelectableGroup ? (\n <div className=\"ald-menu-item-right\">\n <div\n className={cn(\n 'ald-menu-item-selection-slot',\n isSelected &&\n 'ald-menu-item-selection-slot-selected ald-menu-item-selected-icon',\n )}\n >\n {isSelected ? <CheckLightLine /> : null}\n </div>\n </div>\n ) : null}\n </div>\n </MenuItem>\n );\n });\n };\n\n const ref = useRef(null);\n\n const isLeafRootMenu = isLeafMenu(items);\n const menuOverflow =\n isLeafRootMenu || menuStyle?.maxHeight !== undefined ? 'auto' : undefined;\n\n return (\n <>\n <div style={{ display: 'none' }} ref={ref} />\n <ControlledMenu\n state=\"open\"\n transition={{ open: true, close: true }}\n transitionTimeout={200}\n submenuOpenDelay={0}\n submenuCloseDelay={0}\n menuStyle={{\n ...menuStyle,\n }}\n anchorRef={ref}\n className={cn(\n className,\n 'ald-menu',\n isLeafRootMenu && !externalOverflow && 'ald-menu-leaf',\n !isLeafRootMenu &&\n menuStyle?.maxHeight !== undefined &&\n !externalOverflow &&\n 'ald-menu-scrollable',\n )}\n position={externalOverflow ? 'initial' : 'auto'}\n aria-label={ariaLabel}\n captureFocus\n menuItemFocus={menuItemFocus}\n onKeyDown={onMenuKeyDown}\n onClose={({ reason }) => onRequestClose?.(reason)}\n viewScroll={externalOverflow ? 'initial' : 'auto'}\n overflow={externalOverflow ? 'visible' : menuOverflow}\n >\n {getMenuItems(items || [])}\n </ControlledMenu>\n </>\n );\n}\n\nexport function isHeaderMenuItem(\n menuItem: MenuItemType,\n): menuItem is MenuHeaderType {\n return 'type' in menuItem && menuItem.type === 'header';\n}\n\nexport function isDivideMenuItem(\n menuItem: MenuItemType,\n): menuItem is MenuDividerType {\n return 'type' in menuItem && menuItem.type === 'divider';\n}\n\nexport function isSubMenuItem(menuItem: MenuItemType): menuItem is SubMenuType {\n return 'children' in menuItem && !!menuItem.children;\n}\n\nexport function isLeafMenu(menuItems: MenuItemType[]) {\n return !_.some(menuItems, (item) => isSubMenuItem(item));\n}\n\nexport type MenuItemType =\n | ItemType\n | MenuDividerType\n | SubMenuType\n | MenuHeaderType;\n\nexport interface ItemType {\n key: string;\n label: React.ReactNode;\n icon?: React.ReactNode;\n onClick?: (info: MenuInfo) => void;\n danger?: boolean;\n disabled?: boolean;\n className?: string;\n ariaLabel?: string;\n}\n\nexport interface MenuDividerType {\n key?: string;\n type: 'divider';\n}\n\nexport interface MenuHeaderType {\n key?: string;\n type: 'header';\n label: string;\n}\n\nexport interface SubMenuType {\n children: MenuItemType[];\n key: string;\n label: React.ReactNode;\n icon?: React.ReactNode;\n popupClassName?: string;\n disabled?: boolean;\n ariaLabel?: string;\n}\n\nexport interface MenuInfo {\n key: string;\n keyPath: string[];\n domEvent: MouseEvent | KeyboardEvent;\n // 阻止菜单关闭\n keepOpen?: boolean;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../src/Menu/index.tsx"],"sourcesContent":["import {\n ControlledMenu,\n MenuDivider,\n MenuHeader,\n MenuItem,\n SubMenu,\n} from '@szhsin/react-menu';\nimport { cn } from '../lib/utils';\nimport _ from 'lodash';\nimport React, {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { CheckLightLine, ChevronRightLine } from '../Icon';\nimport './menu.css';\n\nexport interface MenuProps {\n onClick?: (info: MenuInfo) => void;\n onBeforeLeafItemClick?: () => void;\n className?: string;\n items: MenuItemType[];\n selectedKeys?: string[];\n menuStyle?: React.CSSProperties;\n /** Accessible name for the command menu when its context is not otherwise clear. */\n ariaLabel?: string;\n /** @internal Requested initial keyboard position when the popup opens. */\n initialFocus?: 'first' | 'last';\n /** @internal Whether the current popup entry originated from keyboard input. */\n keyboardFocus?: boolean;\n /** @internal Whether opening the popup should transfer focus to an item. */\n captureFocus?: boolean;\n /** @internal Requests that the owning popup close, including on Escape. */\n onRequestClose?: (reason: 'click' | 'cancel' | 'blur' | 'scroll') => void;\n rootClosing?: boolean;\n /** @internal 由 Dropdown 注入,禁用内部定位/overflow 计算。不支持含 SubMenu 的菜单 */\n externalOverflow?: boolean;\n /** @internal Dropdown 已按实际裁剪区域计算根菜单高度,保留其限制。 */\n preserveRootHeight?: boolean;\n}\n\nexport default function Menu(props: MenuProps) {\n const {\n className,\n items,\n onClick: onMenuClick,\n onBeforeLeafItemClick,\n selectedKeys,\n menuStyle,\n ariaLabel,\n initialFocus = 'first',\n keyboardFocus = false,\n captureFocus = true,\n onRequestClose,\n rootClosing = false,\n externalOverflow,\n preserveRootHeight = false,\n } = props;\n const selectedKeySet = new Set(selectedKeys || []);\n const typeaheadRef = useRef({ query: '', timestamp: 0 });\n const [isKeyboardFocus, setIsKeyboardFocus] = useState(keyboardFocus);\n\n useEffect(() => {\n setIsKeyboardFocus(keyboardFocus);\n }, [keyboardFocus]);\n\n const menuItemFocus = useMemo(\n () => (captureFocus ? { position: initialFocus } : undefined),\n [captureFocus, initialFocus],\n );\n const onMenuKeyDown = useCallback(\n (event: React.KeyboardEvent<HTMLElement>) => {\n if (\n event.defaultPrevented ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n event.key.length !== 1\n ) {\n return;\n }\n\n const now = Date.now();\n const previous = typeaheadRef.current;\n const query = `${now - previous.timestamp > 500 ? '' : previous.query}${\n event.key\n }`.toLocaleLowerCase();\n typeaheadRef.current = { query, timestamp: now };\n\n const menuItems = Array.from(\n event.currentTarget.querySelectorAll<HTMLElement>(\n '[role=\"menuitem\"]:not([aria-hidden=\"true\"]):not([aria-disabled=\"true\"])',\n ),\n );\n const activeIndex = menuItems.indexOf(\n document.activeElement as HTMLElement,\n );\n const orderedItems = [\n ...menuItems.slice(activeIndex + 1),\n ...menuItems.slice(0, activeIndex + 1),\n ];\n const match = orderedItems.find((item) => {\n const accessibleName =\n item.getAttribute('aria-label') || item.textContent || '';\n return accessibleName.trim().toLocaleLowerCase().startsWith(query);\n });\n\n if (match) {\n event.preventDefault();\n match.focus();\n }\n },\n [],\n );\n\n const hasDirectSelectedItem = (items: MenuItemType[]): boolean =>\n items.some((item) => {\n if (isSubMenuItem(item)) {\n return selectedKeySet.has(item.key);\n }\n if (isHeaderMenuItem(item) || isDivideMenuItem(item)) {\n return false;\n }\n return selectedKeySet.has(item.key);\n });\n\n const getMenuItems = (items: MenuItemType[], parentPath: string[] = []) => {\n const isSelectableGroup = hasDirectSelectedItem(items);\n\n return items.map((item, index) => {\n if (isDivideMenuItem(item)) {\n return <MenuDivider key={`divider_${index}`} />;\n }\n if (isHeaderMenuItem(item)) {\n return <MenuHeader key={`header_${index}`}>{item.label}</MenuHeader>;\n }\n const currPath = [...parentPath, item.key];\n const titleStr = _.isString(item.label) ? item.label : '';\n const isSelected = selectedKeys?.includes(item.key);\n\n if (isSubMenuItem(item)) {\n const isLeafSubMenu = isLeafMenu(item.children);\n const subMenuOverflow =\n isLeafSubMenu || menuStyle?.maxHeight !== undefined\n ? 'auto'\n : undefined;\n const subMenuItemLabel = (\n <div className=\"ald-menu-item-label\" title={titleStr}>\n {item.icon ? (\n <div className=\"ald-menu-item-label-icon\">{item.icon}</div>\n ) : null}\n <div className=\"ald-menu-item-label-text tw-text-typography-body-dense\">\n {item.label}\n </div>\n <div className=\"ald-menu-item-right\">\n {isSelectableGroup ? (\n <div className=\"ald-menu-item-selection-slot\" />\n ) : null}\n <ChevronRightLine size={16} />\n </div>\n </div>\n );\n\n return (\n <SubMenu\n key={item.key}\n label={subMenuItemLabel}\n disabled={item.disabled}\n aria-label={item.ariaLabel || titleStr || undefined}\n itemProps={{\n className: isLeafSubMenu\n ? 'ald-menu-submenu-leaf-trigger'\n : undefined,\n onPointerMove: () => setIsKeyboardFocus(false),\n }}\n align=\"start\"\n direction=\"right\"\n gap={-8}\n position=\"anchor\"\n shift={0}\n menuStyle={{\n ...menuStyle,\n }}\n menuClassName={cn(\n 'ald-menu-submenu-popup',\n isLeafSubMenu && 'ald-menu-submenu-popup-leaf',\n !isLeafSubMenu &&\n menuStyle?.maxHeight !== undefined &&\n 'ald-menu-submenu-popup-scrollable',\n item.popupClassName,\n isKeyboardFocus && 'ald-menu-focus-visible',\n rootClosing && 'ald-menu-submenu-popup-root-closing',\n )}\n overflow={subMenuOverflow}\n >\n {getMenuItems(item.children, currPath)}\n </SubMenu>\n );\n }\n\n return (\n <MenuItem\n key={item.key}\n className={cn(item.className, {\n 'ald-menu-item-danger': item.danger,\n 'ald-menu-item-selected': isSelected,\n })}\n disabled={item.disabled}\n aria-label={item.ariaLabel || titleStr || undefined}\n onPointerMove={() => setIsKeyboardFocus(false)}\n onClick={({ syntheticEvent }) => {\n onBeforeLeafItemClick?.();\n const menuInfo = {\n key: item.key,\n keyPath: currPath,\n domEvent: syntheticEvent,\n };\n if (item.onClick) {\n item.onClick(menuInfo);\n }\n if (onMenuClick) {\n onMenuClick(menuInfo);\n }\n }}\n >\n <div className=\"ald-menu-item-label\" title={titleStr}>\n {item.icon ? (\n <div className=\"ald-menu-item-label-icon\">{item.icon}</div>\n ) : null}\n <div className=\"ald-menu-item-label-text tw-text-typography-body-dense\">\n {item.label}\n </div>\n {isSelectableGroup ? (\n <div className=\"ald-menu-item-right\">\n <div\n className={cn(\n 'ald-menu-item-selection-slot',\n isSelected &&\n 'ald-menu-item-selection-slot-selected ald-menu-item-selected-icon',\n )}\n >\n {isSelected ? <CheckLightLine /> : null}\n </div>\n </div>\n ) : null}\n </div>\n </MenuItem>\n );\n });\n };\n\n const ref = useRef(null);\n\n const isLeafRootMenu = isLeafMenu(items);\n const menuOverflow =\n isLeafRootMenu || menuStyle?.maxHeight !== undefined ? 'auto' : undefined;\n\n return (\n <>\n <div style={{ display: 'none' }} ref={ref} />\n <ControlledMenu\n state=\"open\"\n transition={{ open: true, close: true }}\n transitionTimeout={200}\n submenuOpenDelay={0}\n submenuCloseDelay={0}\n // Root positioning is owned by the surrounding surface (see menu.css).\n // Keep an explicit caller height: React-Menu otherwise replaces it with\n // its viewport limit. Descendant SubMenus still calculate their own overflow.\n setDownOverflow={preserveRootHeight}\n menuStyle={{\n ...menuStyle,\n }}\n anchorRef={ref}\n className={cn(\n className,\n 'ald-menu',\n isKeyboardFocus && 'ald-menu-focus-visible',\n isLeafRootMenu && !externalOverflow && 'ald-menu-leaf',\n !isLeafRootMenu &&\n menuStyle?.maxHeight !== undefined &&\n !externalOverflow &&\n 'ald-menu-scrollable',\n )}\n position={externalOverflow ? 'initial' : 'auto'}\n aria-label={ariaLabel}\n captureFocus={captureFocus}\n menuItemFocus={menuItemFocus}\n onKeyDown={(event) => {\n setIsKeyboardFocus(true);\n onMenuKeyDown(event);\n }}\n onClose={({ reason }) => onRequestClose?.(reason)}\n viewScroll={externalOverflow ? 'initial' : 'auto'}\n overflow={externalOverflow ? 'visible' : menuOverflow}\n >\n {getMenuItems(items || [])}\n </ControlledMenu>\n </>\n );\n}\n\nexport function isHeaderMenuItem(\n menuItem: MenuItemType,\n): menuItem is MenuHeaderType {\n return 'type' in menuItem && menuItem.type === 'header';\n}\n\nexport function isDivideMenuItem(\n menuItem: MenuItemType,\n): menuItem is MenuDividerType {\n return 'type' in menuItem && menuItem.type === 'divider';\n}\n\nexport function isSubMenuItem(menuItem: MenuItemType): menuItem is SubMenuType {\n return 'children' in menuItem && !!menuItem.children;\n}\n\nexport function isLeafMenu(menuItems: MenuItemType[]) {\n return !_.some(menuItems, (item) => isSubMenuItem(item));\n}\n\nexport type MenuItemType =\n | ItemType\n | MenuDividerType\n | SubMenuType\n | MenuHeaderType;\n\nexport interface ItemType {\n key: string;\n label: React.ReactNode;\n icon?: React.ReactNode;\n onClick?: (info: MenuInfo) => void;\n danger?: boolean;\n disabled?: boolean;\n className?: string;\n ariaLabel?: string;\n}\n\nexport interface MenuDividerType {\n key?: string;\n type: 'divider';\n}\n\nexport interface MenuHeaderType {\n key?: string;\n type: 'header';\n label: string;\n}\n\nexport interface SubMenuType {\n children: MenuItemType[];\n key: string;\n label: React.ReactNode;\n icon?: React.ReactNode;\n popupClassName?: string;\n disabled?: boolean;\n ariaLabel?: string;\n}\n\nexport interface MenuInfo {\n key: string;\n keyPath: string[];\n domEvent: MouseEvent | KeyboardEvent;\n // 阻止菜单关闭\n keepOpen?: boolean;\n}\n"],"mappings":"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"}
@@ -161,7 +161,7 @@ function OriginModal(props) {
161
161
  "aria-labelledby": title ? titleId : void 0,
162
162
  "aria-describedby": subTitle ? descriptionId : void 0,
163
163
  "aria-label": ariaLabel,
164
- className: cn("ald-modal ant-modal tw-pointer-events-auto tw-box-border tw-flex tw-flex-col tw-overflow-hidden tw-border-0 tw-bg-[var(--background-default)] tw-shadow-none tw-outline-none", fullscreen ? "ald-modal-fullscreen tw-fixed tw-inset-0 tw-size-full tw-rounded-none" : "tw-rounded-r-75", paddingLess && "ald-modal-padding-less", virtualScrollBar && "ald-modal-virtual-scroll-bar", hideHeaderBottomBorder && "ald-modal-hide-header-bottom-border", responsiveBounds && "ald-modal-responsive-bounds", className),
164
+ className: cn("ald-modal ant-modal tw-pointer-events-auto tw-box-border tw-flex tw-flex-col tw-overflow-hidden tw-bg-[var(--background-default)] tw-outline-none", fullscreen ? "ald-modal-fullscreen tw-fixed tw-inset-0 tw-size-full tw-rounded-none tw-border-0 tw-shadow-none" : "tw-rounded-r-75 tw-border tw-border-solid tw-border-[var(--border-default)] tw-shadow-[var(--elevation-bottom-bottom-lg)]", paddingLess && "ald-modal-padding-less", virtualScrollBar && "ald-modal-virtual-scroll-bar", hideHeaderBottomBorder && "ald-modal-hide-header-bottom-border", responsiveBounds && "ald-modal-responsive-bounds", className),
165
165
  style: {
166
166
  ...fullscreen ? {} : {
167
167
  width: responsiveBounds ? responsiveBoundsStyle.width : width || DEFAULT_WIDTH,