@aloudata/aloudata-design 3.1.7 → 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.
- package/dist/Dropdown/index.js +22 -1
- package/dist/Dropdown/index.js.map +1 -1
- package/dist/MemberPicker/components/Panel.d.ts +2 -1
- package/dist/MemberPicker/components/Panel.js +4 -1
- package/dist/MemberPicker/components/Panel.js.map +1 -1
- package/dist/MemberPicker/components/PanelWrapper.d.ts +3 -2
- package/dist/MemberPicker/components/PanelWrapper.js +2 -1
- package/dist/MemberPicker/components/PanelWrapper.js.map +1 -1
- package/dist/MemberPicker/components/UserGroupSelection.d.ts +3 -1
- package/dist/MemberPicker/components/UserGroupSelection.js +2 -2
- package/dist/MemberPicker/components/UserGroupSelection.js.map +1 -1
- package/dist/MemberPicker/dialog/DialogContent.d.ts +1 -1
- package/dist/MemberPicker/dialog/DialogContent.js +5 -2
- package/dist/MemberPicker/dialog/DialogContent.js.map +1 -1
- package/dist/MemberPicker/dialog/MemberPickerDialog.d.ts +1 -1
- package/dist/MemberPicker/dialog/MemberPickerDialog.js.map +1 -1
- package/dist/MemberPicker/dialog/UserGroupCandidatePanel.d.ts +2 -1
- package/dist/MemberPicker/dialog/UserGroupCandidatePanel.js +2 -2
- package/dist/MemberPicker/dialog/UserGroupCandidatePanel.js.map +1 -1
- package/dist/MemberPicker/index.js +3 -1
- package/dist/MemberPicker/index.js.map +1 -1
- package/dist/MemberPicker/interface.d.ts +6 -0
- package/dist/MemberPicker/interface.js.map +1 -1
- package/dist/Menu/index.d.ts +4 -0
- package/dist/Menu/index.js +19 -8
- package/dist/Menu/index.js.map +1 -1
- package/dist/aloudata-design.css +1 -1
- package/package.json +1 -1
package/dist/Dropdown/index.js
CHANGED
|
@@ -48,6 +48,8 @@ function Dropdown(props) {
|
|
|
48
48
|
const currentFloatingSideRef = useRef(resolvePlacementSide(placement));
|
|
49
49
|
const [targetElement, setTargetElement] = useState(null);
|
|
50
50
|
const [menuInitialFocus, setMenuInitialFocus] = useState("first");
|
|
51
|
+
const [menuKeyboardFocus, setMenuKeyboardFocus] = useState(false);
|
|
52
|
+
const [menuCaptureFocus, setMenuCaptureFocus] = useState(true);
|
|
51
53
|
const popupMatchTriggerWidthNumber = parsePopupMatchWidth(popupMatchTriggerWidth);
|
|
52
54
|
const [matchedTriggerWidth, setMatchedTriggerWidth] = useState(popupMatchTriggerWidthNumber);
|
|
53
55
|
const popupZIndex = useFloatingPopupZIndex();
|
|
@@ -195,6 +197,8 @@ function Dropdown(props) {
|
|
|
195
197
|
refs.setPositionReference(event.currentTarget);
|
|
196
198
|
updateMatchedWidthFromElement(event.currentTarget);
|
|
197
199
|
setMenuInitialFocus(position);
|
|
200
|
+
setMenuKeyboardFocus(true);
|
|
201
|
+
setMenuCaptureFocus(true);
|
|
198
202
|
onChangeOpen(true);
|
|
199
203
|
}, [
|
|
200
204
|
disabled,
|
|
@@ -212,6 +216,8 @@ function Dropdown(props) {
|
|
|
212
216
|
refs.setPositionReference(event.currentTarget);
|
|
213
217
|
updateMatchedWidthFromElement(event.currentTarget);
|
|
214
218
|
setMenuInitialFocus("first");
|
|
219
|
+
setMenuKeyboardFocus(false);
|
|
220
|
+
setMenuCaptureFocus(false);
|
|
215
221
|
childProps.onClick?.(event);
|
|
216
222
|
const { onClick: referenceOnClick } = referenceProps;
|
|
217
223
|
if (typeof referenceOnClick === "function") referenceOnClick(event);
|
|
@@ -240,7 +246,18 @@ function Dropdown(props) {
|
|
|
240
246
|
event.preventDefault();
|
|
241
247
|
refs.setPositionReference({ getBoundingClientRect: () => new DOMRect(event.clientX, event.clientY, 0, 0) });
|
|
242
248
|
setMenuInitialFocus("first");
|
|
249
|
+
setMenuKeyboardFocus(false);
|
|
250
|
+
setMenuCaptureFocus(true);
|
|
243
251
|
onChangeOpen(true);
|
|
252
|
+
},
|
|
253
|
+
onMouseEnter: (event) => {
|
|
254
|
+
childProps.onMouseEnter?.(event);
|
|
255
|
+
if (hasTrigger(trigger, "hover")) {
|
|
256
|
+
setMenuKeyboardFocus(false);
|
|
257
|
+
setMenuCaptureFocus(false);
|
|
258
|
+
}
|
|
259
|
+
const { onMouseEnter: referenceOnMouseEnter } = referenceProps;
|
|
260
|
+
if (typeof referenceOnMouseEnter === "function") referenceOnMouseEnter(event);
|
|
244
261
|
}
|
|
245
262
|
});
|
|
246
263
|
const onMenuItemClick = useCallback((info) => {
|
|
@@ -272,6 +289,8 @@ function Dropdown(props) {
|
|
|
272
289
|
onBeforeLeafItemClick: isOpenControlled ? void 0 : markRootClosing,
|
|
273
290
|
rootClosing: isAnimatingOut,
|
|
274
291
|
initialFocus: menuInitialFocus,
|
|
292
|
+
keyboardFocus: menuKeyboardFocus,
|
|
293
|
+
captureFocus: menuCaptureFocus,
|
|
275
294
|
onRequestClose: onMenuRequestClose,
|
|
276
295
|
onClick: onMenuItemClick,
|
|
277
296
|
externalOverflow: surfaceScrolls,
|
|
@@ -288,7 +307,9 @@ function Dropdown(props) {
|
|
|
288
307
|
onMenuItemClick,
|
|
289
308
|
onMenuRequestClose,
|
|
290
309
|
popupMatchTriggerWidth,
|
|
291
|
-
menuInitialFocus
|
|
310
|
+
menuInitialFocus,
|
|
311
|
+
menuKeyboardFocus,
|
|
312
|
+
menuCaptureFocus
|
|
292
313
|
]);
|
|
293
314
|
const popupElement = useMemo(() => {
|
|
294
315
|
return typeof dropdownRender === "function" ? dropdownRender(menuInstance) : menuInstance;
|
|
@@ -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, 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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"}
|
|
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 [menuKeyboardFocus, setMenuKeyboardFocus] = useState(false);\n const [menuCaptureFocus, setMenuCaptureFocus] = useState(true);\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 setMenuKeyboardFocus(true);\n setMenuCaptureFocus(true);\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 setMenuKeyboardFocus(false);\n setMenuCaptureFocus(false);\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 setMenuKeyboardFocus(false);\n setMenuCaptureFocus(true);\n onChangeOpen(true);\n },\n onMouseEnter: (event: React.MouseEvent<HTMLElement>) => {\n childProps.onMouseEnter?.(event);\n if (hasTrigger(trigger, 'hover')) {\n setMenuKeyboardFocus(false);\n setMenuCaptureFocus(false);\n }\n const { onMouseEnter: referenceOnMouseEnter } = referenceProps;\n if (typeof referenceOnMouseEnter === 'function') {\n referenceOnMouseEnter(event);\n }\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 keyboardFocus: menuKeyboardFocus,\n captureFocus: menuCaptureFocus,\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 menuKeyboardFocus,\n menuCaptureFocus,\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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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { IBaseMemberSelectorProps, EMemberPicker, IUser } from '../interface';
|
|
1
2
|
import { ReactNode } from 'react';
|
|
2
3
|
import { IUserGroup, TUser, TUserGroupValue, TUserValue } from '../../ConfigProvider/getUserList';
|
|
3
|
-
import { EMemberPicker, IUser } from '../interface';
|
|
4
4
|
interface IPanelProps {
|
|
5
5
|
searchFeedback?: ReactNode;
|
|
6
6
|
searchFailed?: boolean;
|
|
@@ -18,6 +18,7 @@ interface IPanelProps {
|
|
|
18
18
|
className?: string;
|
|
19
19
|
lockedIds: Array<TUserValue | TUserGroupValue>;
|
|
20
20
|
footer?: ReactNode;
|
|
21
|
+
canEnterGroup?: IBaseMemberSelectorProps['canEnterGroup'];
|
|
21
22
|
renderItem?: (item: IUser | IUserGroup, context: {
|
|
22
23
|
isSelected: boolean;
|
|
23
24
|
disabled: boolean;
|
|
@@ -14,7 +14,7 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
14
14
|
function Panel(props) {
|
|
15
15
|
const { locale } = useContext(LocaleContext);
|
|
16
16
|
const t = getTranslator(locale);
|
|
17
|
-
const { type, multiple, dropdownWidth, value, onChange, dataList, onSearchValueChange, className, lockedIds, footer, onCancel, renderItem, renderSelectedTag, filterItem, searchValue = "", showSearch } = props;
|
|
17
|
+
const { type, multiple, dropdownWidth, value, onChange, dataList, onSearchValueChange, className, lockedIds, footer, onCancel, canEnterGroup, renderItem, renderSelectedTag, filterItem, searchValue = "", showSearch } = props;
|
|
18
18
|
const [selectedUsers, setSelected] = useState([]);
|
|
19
19
|
const onSelectionChange = useCallback((selected, user) => {
|
|
20
20
|
if (multiple) if (selected) setSelected([...selectedUsers, user]);
|
|
@@ -75,6 +75,7 @@ function Panel(props) {
|
|
|
75
75
|
multiple: true,
|
|
76
76
|
lockedIds,
|
|
77
77
|
loading: props.loading,
|
|
78
|
+
canEnterGroup,
|
|
78
79
|
renderItem
|
|
79
80
|
});
|
|
80
81
|
if (type === EMemberPicker.USER) return userSelection;
|
|
@@ -108,6 +109,7 @@ function Panel(props) {
|
|
|
108
109
|
props.searchFailed,
|
|
109
110
|
props.useProvidedGroupSearch,
|
|
110
111
|
type,
|
|
112
|
+
canEnterGroup,
|
|
111
113
|
renderItem,
|
|
112
114
|
filterItem
|
|
113
115
|
]);
|
|
@@ -167,6 +169,7 @@ function Panel(props) {
|
|
|
167
169
|
multiple: false,
|
|
168
170
|
lockedIds,
|
|
169
171
|
loading: props.loading,
|
|
172
|
+
canEnterGroup,
|
|
170
173
|
renderItem
|
|
171
174
|
})] })]
|
|
172
175
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Panel.js","names":[],"sources":["../../../src/MemberPicker/components/Panel.tsx"],"sourcesContent":["import { cn } from '../../lib/utils';\n\nimport React, {\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n EUserType,\n IUserGroup,\n TUser,\n TUserGroupValue,\n TUserValue,\n} from '../../ConfigProvider/getUserList';\nimport Tabs from '../../Tabs';\nimport { LocaleContext, getTranslator } from '../../locale/default';\nimport { EMemberPicker, IUser } from '../interface';\nimport { getId } from '../utils';\nimport { isUser, isUserGroup } from '../utils/getUsersWithUserId';\nimport MemberSelection from './MemberSelection';\nimport SelectedMemberTags from './SelectedMemberTags';\nimport SelectorFooter from './SelectorFooter';\nimport UserGroupSelection from './UserGroupSelection';\n\ninterface IPanelProps {\n searchFeedback?: ReactNode;\n searchFailed?: boolean;\n useProvidedGroupSearch?: boolean;\n active?: boolean;\n type: EMemberPicker;\n multiple?: boolean;\n onChange?: (value: TUser) => void;\n dropdownWidth?: number;\n value?: TUser | (IUser | IUserGroup);\n dataList: TUser;\n onSearchValueChange?: (value: string) => void;\n onCancel?: () => void;\n loading: boolean;\n className?: string;\n lockedIds: Array<TUserValue | TUserGroupValue>;\n footer?: ReactNode;\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 filterItem?: (item: IUser | IUserGroup) => boolean;\n searchValue?: string;\n showSearch?: boolean;\n}\n\nexport const userDisplayNameIsRepeated = (\n userList: TUser,\n displayName?: string,\n) => {\n return (\n userList.filter(\n (user) => user.type === EUserType.USER && user.nickname === displayName,\n ).length > 1\n );\n};\n\nexport default function Panel(props: IPanelProps) {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n\n const {\n type,\n multiple,\n dropdownWidth,\n value,\n onChange,\n dataList,\n onSearchValueChange,\n className,\n lockedIds,\n footer,\n onCancel,\n renderItem,\n renderSelectedTag,\n filterItem,\n searchValue = '',\n showSearch,\n } = props;\n\n const [selectedUsers, setSelected] = useState<TUser>([]);\n\n const onSelectionChange = useCallback(\n (selected: boolean, user: IUser | IUserGroup) => {\n if (multiple) {\n if (selected) {\n setSelected([...selectedUsers, user]);\n } else {\n setSelected(\n selectedUsers.filter((item) => getId(item) !== getId(user)),\n );\n }\n } else {\n if (selected) {\n setSelected([user]);\n onChange?.([user]);\n } else {\n setSelected([]);\n onChange?.([]);\n }\n }\n },\n [multiple, selectedUsers, onChange],\n );\n\n const onRemove = useCallback(\n (user: IUser | IUserGroup) => {\n setSelected(selectedUsers.filter((item) => getId(item) !== getId(user)));\n },\n [selectedUsers],\n );\n\n const panelwidth = useMemo(() => {\n if (dropdownWidth) {\n return dropdownWidth;\n } else if (multiple) {\n return 480;\n } else {\n return 160;\n }\n }, [dropdownWidth, multiple]);\n\n useEffect(() => {\n if (value) {\n if (Array.isArray(value)) {\n setSelected(value);\n } else {\n setSelected([value]);\n }\n }\n }, [setSelected, value]);\n\n const renderDropdown = useCallback(() => {\n const userSelection = (\n <MemberSelection\n className={'ald-member-picker-member-selection-multiple'}\n userList={dataList.filter(isUser)}\n filterItem={filterItem}\n width={(panelwidth - 6) / 2}\n selectedUsers={selectedUsers.filter(isUser)}\n onChange={onSelectionChange}\n onSearchValueChange={onSearchValueChange}\n searchValue={searchValue}\n showSearch={showSearch}\n multiple={true}\n lockedIds={lockedIds}\n loading={props.loading}\n renderItem={renderItem}\n ></MemberSelection>\n );\n const userGroupSelection = (\n <UserGroupSelection\n active={props.active}\n useProvidedSearch={props.useProvidedGroupSearch && !!searchValue.trim()}\n parentSearchFailed={props.searchFailed}\n className={'ald-member-picker-member-selection-multiple'}\n userGroupList={dataList.filter(isUserGroup)}\n filterItem={filterItem}\n width={(panelwidth - 6) / 2}\n selectedUsersGroup={selectedUsers.filter(isUserGroup)}\n onChange={onSelectionChange}\n onSearchValueChange={onSearchValueChange}\n searchValue={searchValue}\n showSearch={showSearch}\n multiple={true}\n lockedIds={lockedIds}\n loading={props.loading}\n renderItem={renderItem}\n ></UserGroupSelection>\n );\n if (type === EMemberPicker.USER) {\n return userSelection;\n }\n if (type === EMemberPicker.GROUP) {\n return userGroupSelection;\n }\n if (type === EMemberPicker.BOTH) {\n return (\n <Tabs\n centered\n destroyInactiveTabPane\n items={[\n {\n key: 'user',\n label: t.MemberPicker.users,\n children: userSelection,\n },\n {\n key: 'userGroup',\n label: t.MemberPicker.userGroups,\n children: userGroupSelection,\n },\n ]}\n className=\"ald-member-tabs\"\n ></Tabs>\n );\n }\n }, [\n t,\n dataList,\n panelwidth,\n selectedUsers,\n onSelectionChange,\n onSearchValueChange,\n searchValue,\n showSearch,\n lockedIds,\n props.loading,\n props.active,\n props.searchFailed,\n props.useProvidedGroupSearch,\n type,\n renderItem,\n filterItem,\n ]);\n\n // 单选 + 调用方未传 dropdownWidth 时让 wrapper 跟随父级(popupMatchSelectWidth=true 的浮窗 = 触发器宽度),\n // 否则按具体数字(多选 480 / 调用方自定义)固定宽度。\n const wrapperWidth: number | string =\n dropdownWidth ?? (multiple ? panelwidth : '100%');\n\n return (\n <div\n className={cn(className, 'ald-member-picker-wrapper', {\n ['ald-member-picker-multiple']: multiple,\n ['ald-member-picker-single']: !multiple,\n })}\n style={{ width: wrapperWidth }}\n >\n {props.searchFeedback}\n {multiple ? (\n <>\n <div className=\"ald-member-picker-inner\">\n <div className=\"ald-member-picker-member-selection-wrapper\">\n {renderDropdown()}\n </div>\n <SelectedMemberTags\n className={'ald-member-picker-selected-member-tags'}\n selectedUsers={selectedUsers}\n width={(panelwidth - 3) / 2}\n onRemove={onRemove}\n lockedIds={lockedIds}\n userList={dataList}\n renderSelectedTag={renderSelectedTag}\n ></SelectedMemberTags>\n </div>\n <SelectorFooter\n className={'ald-member-picker-selector-footer'}\n onCancel={onCancel}\n onOk={() => {\n onChange?.(selectedUsers);\n }}\n footer={footer}\n ></SelectorFooter>\n </>\n ) : (\n <>\n {type === EMemberPicker.USER && (\n <MemberSelection\n className={'ald-member-picker-member-selection-single'}\n userList={dataList.filter(isUser)}\n width={panelwidth - 2}\n onChange={onSelectionChange}\n selectedUsers={selectedUsers.filter(isUser)}\n onSearchValueChange={onSearchValueChange}\n searchValue={searchValue}\n showSearch={showSearch}\n multiple={false && multiple}\n lockedIds={lockedIds}\n loading={props.loading}\n renderItem={renderItem}\n ></MemberSelection>\n )}\n {type === EMemberPicker.GROUP && (\n <UserGroupSelection\n active={props.active}\n useProvidedSearch={\n props.useProvidedGroupSearch && !!searchValue.trim()\n }\n parentSearchFailed={props.searchFailed}\n className={'ald-member-picker-member-selection-multiple'}\n userGroupList={dataList.filter(isUserGroup)}\n width={(panelwidth - 3) / 2}\n selectedUsersGroup={selectedUsers.filter(isUserGroup)}\n onChange={onSelectionChange}\n onSearchValueChange={onSearchValueChange}\n searchValue={searchValue}\n showSearch={showSearch}\n multiple={false}\n lockedIds={lockedIds}\n loading={props.loading}\n renderItem={renderItem}\n ></UserGroupSelection>\n )}\n </>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Panel.js","names":[],"sources":["../../../src/MemberPicker/components/Panel.tsx"],"sourcesContent":["import type { IBaseMemberSelectorProps } from '../interface';\nimport { cn } from '../../lib/utils';\n\nimport React, {\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n EUserType,\n IUserGroup,\n TUser,\n TUserGroupValue,\n TUserValue,\n} from '../../ConfigProvider/getUserList';\nimport Tabs from '../../Tabs';\nimport { LocaleContext, getTranslator } from '../../locale/default';\nimport { EMemberPicker, IUser } from '../interface';\nimport { getId } from '../utils';\nimport { isUser, isUserGroup } from '../utils/getUsersWithUserId';\nimport MemberSelection from './MemberSelection';\nimport SelectedMemberTags from './SelectedMemberTags';\nimport SelectorFooter from './SelectorFooter';\nimport UserGroupSelection from './UserGroupSelection';\n\ninterface IPanelProps {\n searchFeedback?: ReactNode;\n searchFailed?: boolean;\n useProvidedGroupSearch?: boolean;\n active?: boolean;\n type: EMemberPicker;\n multiple?: boolean;\n onChange?: (value: TUser) => void;\n dropdownWidth?: number;\n value?: TUser | (IUser | IUserGroup);\n dataList: TUser;\n onSearchValueChange?: (value: string) => void;\n onCancel?: () => void;\n loading: boolean;\n className?: string;\n lockedIds: Array<TUserValue | TUserGroupValue>;\n footer?: ReactNode;\n canEnterGroup?: IBaseMemberSelectorProps['canEnterGroup'];\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 filterItem?: (item: IUser | IUserGroup) => boolean;\n searchValue?: string;\n showSearch?: boolean;\n}\n\nexport const userDisplayNameIsRepeated = (\n userList: TUser,\n displayName?: string,\n) => {\n return (\n userList.filter(\n (user) => user.type === EUserType.USER && user.nickname === displayName,\n ).length > 1\n );\n};\n\nexport default function Panel(props: IPanelProps) {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n\n const {\n type,\n multiple,\n dropdownWidth,\n value,\n onChange,\n dataList,\n onSearchValueChange,\n className,\n lockedIds,\n footer,\n onCancel,\n canEnterGroup,\n renderItem,\n renderSelectedTag,\n filterItem,\n searchValue = '',\n showSearch,\n } = props;\n\n const [selectedUsers, setSelected] = useState<TUser>([]);\n\n const onSelectionChange = useCallback(\n (selected: boolean, user: IUser | IUserGroup) => {\n if (multiple) {\n if (selected) {\n setSelected([...selectedUsers, user]);\n } else {\n setSelected(\n selectedUsers.filter((item) => getId(item) !== getId(user)),\n );\n }\n } else {\n if (selected) {\n setSelected([user]);\n onChange?.([user]);\n } else {\n setSelected([]);\n onChange?.([]);\n }\n }\n },\n [multiple, selectedUsers, onChange],\n );\n\n const onRemove = useCallback(\n (user: IUser | IUserGroup) => {\n setSelected(selectedUsers.filter((item) => getId(item) !== getId(user)));\n },\n [selectedUsers],\n );\n\n const panelwidth = useMemo(() => {\n if (dropdownWidth) {\n return dropdownWidth;\n } else if (multiple) {\n return 480;\n } else {\n return 160;\n }\n }, [dropdownWidth, multiple]);\n\n useEffect(() => {\n if (value) {\n if (Array.isArray(value)) {\n setSelected(value);\n } else {\n setSelected([value]);\n }\n }\n }, [setSelected, value]);\n\n const renderDropdown = useCallback(() => {\n const userSelection = (\n <MemberSelection\n className={'ald-member-picker-member-selection-multiple'}\n userList={dataList.filter(isUser)}\n filterItem={filterItem}\n width={(panelwidth - 6) / 2}\n selectedUsers={selectedUsers.filter(isUser)}\n onChange={onSelectionChange}\n onSearchValueChange={onSearchValueChange}\n searchValue={searchValue}\n showSearch={showSearch}\n multiple={true}\n lockedIds={lockedIds}\n loading={props.loading}\n renderItem={renderItem}\n ></MemberSelection>\n );\n const userGroupSelection = (\n <UserGroupSelection\n active={props.active}\n useProvidedSearch={props.useProvidedGroupSearch && !!searchValue.trim()}\n parentSearchFailed={props.searchFailed}\n className={'ald-member-picker-member-selection-multiple'}\n userGroupList={dataList.filter(isUserGroup)}\n filterItem={filterItem}\n width={(panelwidth - 6) / 2}\n selectedUsersGroup={selectedUsers.filter(isUserGroup)}\n onChange={onSelectionChange}\n onSearchValueChange={onSearchValueChange}\n searchValue={searchValue}\n showSearch={showSearch}\n multiple={true}\n lockedIds={lockedIds}\n loading={props.loading}\n canEnterGroup={canEnterGroup}\n renderItem={renderItem}\n ></UserGroupSelection>\n );\n if (type === EMemberPicker.USER) {\n return userSelection;\n }\n if (type === EMemberPicker.GROUP) {\n return userGroupSelection;\n }\n if (type === EMemberPicker.BOTH) {\n return (\n <Tabs\n centered\n destroyInactiveTabPane\n items={[\n {\n key: 'user',\n label: t.MemberPicker.users,\n children: userSelection,\n },\n {\n key: 'userGroup',\n label: t.MemberPicker.userGroups,\n children: userGroupSelection,\n },\n ]}\n className=\"ald-member-tabs\"\n ></Tabs>\n );\n }\n }, [\n t,\n dataList,\n panelwidth,\n selectedUsers,\n onSelectionChange,\n onSearchValueChange,\n searchValue,\n showSearch,\n lockedIds,\n props.loading,\n props.active,\n props.searchFailed,\n props.useProvidedGroupSearch,\n type,\n canEnterGroup,\n renderItem,\n filterItem,\n ]);\n\n // 单选 + 调用方未传 dropdownWidth 时让 wrapper 跟随父级(popupMatchSelectWidth=true 的浮窗 = 触发器宽度),\n // 否则按具体数字(多选 480 / 调用方自定义)固定宽度。\n const wrapperWidth: number | string =\n dropdownWidth ?? (multiple ? panelwidth : '100%');\n\n return (\n <div\n className={cn(className, 'ald-member-picker-wrapper', {\n ['ald-member-picker-multiple']: multiple,\n ['ald-member-picker-single']: !multiple,\n })}\n style={{ width: wrapperWidth }}\n >\n {props.searchFeedback}\n {multiple ? (\n <>\n <div className=\"ald-member-picker-inner\">\n <div className=\"ald-member-picker-member-selection-wrapper\">\n {renderDropdown()}\n </div>\n <SelectedMemberTags\n className={'ald-member-picker-selected-member-tags'}\n selectedUsers={selectedUsers}\n width={(panelwidth - 3) / 2}\n onRemove={onRemove}\n lockedIds={lockedIds}\n userList={dataList}\n renderSelectedTag={renderSelectedTag}\n ></SelectedMemberTags>\n </div>\n <SelectorFooter\n className={'ald-member-picker-selector-footer'}\n onCancel={onCancel}\n onOk={() => {\n onChange?.(selectedUsers);\n }}\n footer={footer}\n ></SelectorFooter>\n </>\n ) : (\n <>\n {type === EMemberPicker.USER && (\n <MemberSelection\n className={'ald-member-picker-member-selection-single'}\n userList={dataList.filter(isUser)}\n width={panelwidth - 2}\n onChange={onSelectionChange}\n selectedUsers={selectedUsers.filter(isUser)}\n onSearchValueChange={onSearchValueChange}\n searchValue={searchValue}\n showSearch={showSearch}\n multiple={false && multiple}\n lockedIds={lockedIds}\n loading={props.loading}\n renderItem={renderItem}\n ></MemberSelection>\n )}\n {type === EMemberPicker.GROUP && (\n <UserGroupSelection\n active={props.active}\n useProvidedSearch={\n props.useProvidedGroupSearch && !!searchValue.trim()\n }\n parentSearchFailed={props.searchFailed}\n className={'ald-member-picker-member-selection-multiple'}\n userGroupList={dataList.filter(isUserGroup)}\n width={(panelwidth - 3) / 2}\n selectedUsersGroup={selectedUsers.filter(isUserGroup)}\n onChange={onSelectionChange}\n onSearchValueChange={onSearchValueChange}\n searchValue={searchValue}\n showSearch={showSearch}\n multiple={false}\n lockedIds={lockedIds}\n loading={props.loading}\n canEnterGroup={canEnterGroup}\n renderItem={renderItem}\n ></UserGroupSelection>\n )}\n </>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { IBaseMemberSelectorProps, EMemberPicker, IUser, TMemberPickerValue } from '../interface';
|
|
1
2
|
import { ReactNode } from 'react';
|
|
2
3
|
import { IUserGroup, TUser, TUserGroupValue, TUserValue } from '../../ConfigProvider/getUserList';
|
|
3
|
-
import { EMemberPicker, IUser, TMemberPickerValue } from '../interface';
|
|
4
4
|
interface IProps {
|
|
5
5
|
type?: EMemberPicker;
|
|
6
6
|
multiple?: boolean;
|
|
@@ -12,6 +12,7 @@ interface IProps {
|
|
|
12
12
|
lockedIds?: Array<TUserValue | TUserGroupValue>;
|
|
13
13
|
showUserId?: boolean;
|
|
14
14
|
footer?: ReactNode;
|
|
15
|
+
canEnterGroup?: IBaseMemberSelectorProps['canEnterGroup'];
|
|
15
16
|
renderItem?: (item: IUser | IUserGroup, context: {
|
|
16
17
|
isSelected: boolean;
|
|
17
18
|
disabled: boolean;
|
|
@@ -22,5 +23,5 @@ interface IProps {
|
|
|
22
23
|
renderSelectedTag?: (user: IUser | IUserGroup, originNode: ReactNode) => ReactNode;
|
|
23
24
|
filterItem?: (item: IUser | IUserGroup) => boolean;
|
|
24
25
|
}
|
|
25
|
-
export declare const PanelWrapper: ({ type, value, multiple, dropdownWidth, onChange, onCancel, className, footer, lockedIds, renderItem, renderSelectedTag, filterItem, }: IProps) => import("react/jsx-runtime").JSX.Element;
|
|
26
|
+
export declare const PanelWrapper: ({ type, value, multiple, dropdownWidth, onChange, onCancel, className, footer, lockedIds, canEnterGroup, renderItem, renderSelectedTag, filterItem, }: IProps) => import("react/jsx-runtime").JSX.Element;
|
|
26
27
|
export default PanelWrapper;
|
|
@@ -10,7 +10,7 @@ import { useCallback, useContext, useEffect, useMemo, useState } from "react";
|
|
|
10
10
|
import { jsx } from "react/jsx-runtime";
|
|
11
11
|
import _ from "lodash";
|
|
12
12
|
//#region src/MemberPicker/components/PanelWrapper.tsx
|
|
13
|
-
var PanelWrapper = ({ type = EMemberPicker.USER, value, multiple, dropdownWidth, onChange, onCancel, className, footer, lockedIds = [], renderItem, renderSelectedTag, filterItem }) => {
|
|
13
|
+
var PanelWrapper = ({ type = EMemberPicker.USER, value, multiple, dropdownWidth, onChange, onCancel, className, footer, lockedIds = [], canEnterGroup, renderItem, renderSelectedTag, filterItem }) => {
|
|
14
14
|
const { locale } = useContext(LocaleContext);
|
|
15
15
|
const t = getTranslator(locale);
|
|
16
16
|
const { getUsersByIds, getUsersByKeywords, getUsersByKeywordsWithMeta, getNextLevelGroup, getNextLevelGroupWithMeta } = AldCustomConfigProvider.useGetUserList();
|
|
@@ -93,6 +93,7 @@ var PanelWrapper = ({ type = EMemberPicker.USER, value, multiple, dropdownWidth,
|
|
|
93
93
|
onCancel,
|
|
94
94
|
lockedIds,
|
|
95
95
|
footer,
|
|
96
|
+
canEnterGroup,
|
|
96
97
|
renderItem,
|
|
97
98
|
renderSelectedTag
|
|
98
99
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PanelWrapper.js","names":[],"sources":["../../../src/MemberPicker/components/PanelWrapper.tsx"],"sourcesContent":["import useMemberSearch from '../useMemberSearch';\nimport SearchFeedback from './SearchFeedback';\nimport _ from 'lodash';\nimport React, {\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport ConfigProvider from '../../ConfigProvider';\nimport {\n EUserType,\n IUserGroup,\n TUser,\n TUserGroupValue,\n TUserValue,\n} from '../../ConfigProvider/getUserList';\nimport { LocaleContext, getTranslator } from '../../locale/default';\nimport { EMemberPicker, IUser, TMemberPickerValue } from '../interface';\nimport { isUser, isUserGroup } from '../utils/getUsersWithUserId';\nimport Panel from './Panel';\n\ninterface IProps {\n type?: EMemberPicker;\n multiple?: boolean;\n onChange?(v: TUser | (IUser | IUserGroup)): void;\n dropdownWidth?: number;\n value?: TMemberPickerValue;\n className?: string;\n onCancel?: () => void;\n lockedIds?: Array<TUserValue | TUserGroupValue>;\n showUserId?: boolean;\n footer?: ReactNode;\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 filterItem?: (item: IUser | IUserGroup) => boolean;\n}\n\nexport const PanelWrapper = ({\n type = EMemberPicker.USER,\n value,\n multiple,\n dropdownWidth,\n onChange,\n onCancel,\n className,\n footer,\n lockedIds = [],\n renderItem,\n renderSelectedTag,\n filterItem,\n}: IProps) => {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n\n const {\n getUsersByIds,\n getUsersByKeywords,\n getUsersByKeywordsWithMeta,\n getNextLevelGroup,\n getNextLevelGroupWithMeta,\n } = ConfigProvider.useGetUserList();\n const usesGroupQuery =\n (type === EMemberPicker.GROUP ||\n (!getUsersByKeywords && !getUsersByKeywordsWithMeta)) &&\n !!(getNextLevelGroup || getNextLevelGroupWithMeta);\n const [selectedUserList, setSelectedUserList] = useState<TUser>([]);\n const [searchString, setSearchString] = useState<string>('');\n\n const onSearchValueChange = useCallback((v: string) => {\n setSearchString(v);\n }, []);\n\n const queryByKeywords = useMemo(() => {\n if (getUsersByKeywordsWithMeta) return getUsersByKeywordsWithMeta;\n if (getUsersByKeywords) {\n return getUsersByKeywords;\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 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 !usesGroupQuery,\n );\n const searchUserList = searchResult.items;\n\n const totalUserList: TUser = useMemo(() => {\n const totalUsers = searchUserList\n .concat(selectedUserList)\n .filter((item) => {\n if (filterItem) {\n return filterItem(item);\n }\n return true;\n });\n return _.uniqBy(totalUsers, (data: IUser | IUserGroup) => {\n if (data.type === EUserType.USER) return data.userId;\n return data.groupId;\n });\n }, [searchUserList, selectedUserList, filterItem]);\n\n useEffect(() => {\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 return;\n }\n if (!Array.isArray(value)) {\n param = [value];\n } else {\n param = value;\n }\n queryByIds(param).then((result) => {\n setSelectedUserList(result);\n });\n }\n }, [value, queryByIds]);\n\n const onSelectedChange = useCallback(\n (users: TUser) => {\n if (multiple) {\n onChange?.(users);\n } else {\n onChange?.(users[0]);\n }\n },\n [multiple, onChange],\n );\n\n return (\n <Panel\n searchFailed={failed}\n useProvidedGroupSearch={type === EMemberPicker.BOTH && !usesGroupQuery}\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 value={selectedUserList}\n dataList={totalUserList}\n multiple={multiple}\n loading={loading}\n dropdownWidth={dropdownWidth}\n onSearchValueChange={onSearchValueChange}\n searchValue={searchString}\n showSearch\n onChange={onSelectedChange}\n className={className}\n onCancel={onCancel}\n lockedIds={lockedIds}\n footer={footer}\n renderItem={renderItem}\n renderSelectedTag={renderSelectedTag}\n ></Panel>\n );\n};\n\nexport default PanelWrapper;\n"],"mappings":";;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"PanelWrapper.js","names":[],"sources":["../../../src/MemberPicker/components/PanelWrapper.tsx"],"sourcesContent":["import type { IBaseMemberSelectorProps } from '../interface';\nimport useMemberSearch from '../useMemberSearch';\nimport SearchFeedback from './SearchFeedback';\nimport _ from 'lodash';\nimport React, {\n ReactNode,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport ConfigProvider from '../../ConfigProvider';\nimport {\n EUserType,\n IUserGroup,\n TUser,\n TUserGroupValue,\n TUserValue,\n} from '../../ConfigProvider/getUserList';\nimport { LocaleContext, getTranslator } from '../../locale/default';\nimport { EMemberPicker, IUser, TMemberPickerValue } from '../interface';\nimport { isUser, isUserGroup } from '../utils/getUsersWithUserId';\nimport Panel from './Panel';\n\ninterface IProps {\n type?: EMemberPicker;\n multiple?: boolean;\n onChange?(v: TUser | (IUser | IUserGroup)): void;\n dropdownWidth?: number;\n value?: TMemberPickerValue;\n className?: string;\n onCancel?: () => void;\n lockedIds?: Array<TUserValue | TUserGroupValue>;\n showUserId?: boolean;\n footer?: ReactNode;\n canEnterGroup?: IBaseMemberSelectorProps['canEnterGroup'];\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 filterItem?: (item: IUser | IUserGroup) => boolean;\n}\n\nexport const PanelWrapper = ({\n type = EMemberPicker.USER,\n value,\n multiple,\n dropdownWidth,\n onChange,\n onCancel,\n className,\n footer,\n lockedIds = [],\n canEnterGroup,\n renderItem,\n renderSelectedTag,\n filterItem,\n}: IProps) => {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n\n const {\n getUsersByIds,\n getUsersByKeywords,\n getUsersByKeywordsWithMeta,\n getNextLevelGroup,\n getNextLevelGroupWithMeta,\n } = ConfigProvider.useGetUserList();\n const usesGroupQuery =\n (type === EMemberPicker.GROUP ||\n (!getUsersByKeywords && !getUsersByKeywordsWithMeta)) &&\n !!(getNextLevelGroup || getNextLevelGroupWithMeta);\n const [selectedUserList, setSelectedUserList] = useState<TUser>([]);\n const [searchString, setSearchString] = useState<string>('');\n\n const onSearchValueChange = useCallback((v: string) => {\n setSearchString(v);\n }, []);\n\n const queryByKeywords = useMemo(() => {\n if (getUsersByKeywordsWithMeta) return getUsersByKeywordsWithMeta;\n if (getUsersByKeywords) {\n return getUsersByKeywords;\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 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 !usesGroupQuery,\n );\n const searchUserList = searchResult.items;\n\n const totalUserList: TUser = useMemo(() => {\n const totalUsers = searchUserList\n .concat(selectedUserList)\n .filter((item) => {\n if (filterItem) {\n return filterItem(item);\n }\n return true;\n });\n return _.uniqBy(totalUsers, (data: IUser | IUserGroup) => {\n if (data.type === EUserType.USER) return data.userId;\n return data.groupId;\n });\n }, [searchUserList, selectedUserList, filterItem]);\n\n useEffect(() => {\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 return;\n }\n if (!Array.isArray(value)) {\n param = [value];\n } else {\n param = value;\n }\n queryByIds(param).then((result) => {\n setSelectedUserList(result);\n });\n }\n }, [value, queryByIds]);\n\n const onSelectedChange = useCallback(\n (users: TUser) => {\n if (multiple) {\n onChange?.(users);\n } else {\n onChange?.(users[0]);\n }\n },\n [multiple, onChange],\n );\n\n return (\n <Panel\n searchFailed={failed}\n useProvidedGroupSearch={type === EMemberPicker.BOTH && !usesGroupQuery}\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 value={selectedUserList}\n dataList={totalUserList}\n multiple={multiple}\n loading={loading}\n dropdownWidth={dropdownWidth}\n onSearchValueChange={onSearchValueChange}\n searchValue={searchString}\n showSearch\n onChange={onSelectedChange}\n className={className}\n onCancel={onCancel}\n lockedIds={lockedIds}\n footer={footer}\n canEnterGroup={canEnterGroup}\n renderItem={renderItem}\n renderSelectedTag={renderSelectedTag}\n ></Panel>\n );\n};\n\nexport default PanelWrapper;\n"],"mappings":";;;;;;;;;;;;AAsDA,IAAa,gBAAgB,EAC3B,OAAO,cAAc,MACrB,OACA,UACA,eACA,UACA,UACA,WACA,QACA,YAAY,EAAE,EACd,eACA,YACA,mBACA,iBACY;CACZ,MAAM,EAAE,WAAW,WAAW,cAAc;CAC5C,MAAM,IAAI,cAAc,OAAO;CAE/B,MAAM,EACJ,eACA,oBACA,4BACA,mBACA,8BACE,wBAAe,gBAAgB;CACnC,MAAM,kBACH,SAAS,cAAc,SACrB,CAAC,sBAAsB,CAAC,+BAC3B,CAAC,EAAE,qBAAqB;CAC1B,MAAM,CAAC,kBAAkB,uBAAuB,SAAgB,EAAE,CAAC;CACnE,MAAM,CAAC,cAAc,mBAAmB,SAAiB,GAAG;CAE5D,MAAM,sBAAsB,aAAa,MAAc;AACrD,kBAAgB,EAAE;IACjB,EAAE,CAAC;CAEN,MAAM,kBAAkB,cAAc;AACpC,MAAI,2BAA4B,QAAO;AACvC,MAAI,mBACF,QAAO;AAET,UAAQ,UAAU,EAAE,KAClB,QAAQ,OAAO,EACb,SAAS,EAAE,aAAa,qCACzB,CAAC;IACH;EACD;EACA;EACA,EAAE,aAAa;EAChB,CAAC;CACF,MAAM,aAAa,cAAc;AAC/B,MAAI,cACF,QAAO;AAET,UAAQ,UAAU,EAAE,KAClB,QAAQ,OAAO,EACb,SAAS,EAAE,aAAa,gCACzB,CAAC;IACH,CAAC,eAAe,EAAE,aAAa,+BAA+B,CAAC;CAClE,MAAM,EACJ,QAAQ,cACR,SACA,QACA,UACE,gBACF,iBACA,cACA,CAAC,eACF;CACD,MAAM,iBAAiB,aAAa;CAEpC,MAAM,gBAAuB,cAAc;EACzC,MAAM,aAAa,eAChB,OAAO,iBAAiB,CACxB,QAAQ,SAAS;AAChB,OAAI,WACF,QAAO,WAAW,KAAK;AAEzB,UAAO;IACP;AACJ,SAAO,EAAE,OAAO,aAAa,SAA6B;AACxD,OAAI,KAAK,SAAS,UAAU,KAAM,QAAO,KAAK;AAC9C,UAAO,KAAK;IACZ;IACD;EAAC;EAAgB;EAAkB;EAAW,CAAC;AAElD,iBAAgB;AACd,MAAI,MAAM,QAAQ,MAAM,KAAK,OAAO,MAAM,GAAG,IAAI,YAAY,MAAM,GAAG,EACpE,qBAAoB,MAAe;WAC1B,OAAO,MAAM,IAAI,YAAY,MAAM,CAC5C,qBAAoB,CAAC,MAAM,CAAC;OACvB;GACL,IAAI,QAA6C,EAAE;AACnD,OAAI,CAAC,MAAO;AACZ,OAAI,MAAM,QAAQ,MAAM,IAAI,MAAM,WAAW,GAAG;AAC9C,wBAAoB,EAAE,CAAC;AACvB;;AAEF,OAAI,CAAC,MAAM,QAAQ,MAAM,CACvB,SAAQ,CAAC,MAAM;OAEf,SAAQ;AAEV,cAAW,MAAM,CAAC,MAAM,WAAW;AACjC,wBAAoB,OAAO;KAC3B;;IAEH,CAAC,OAAO,WAAW,CAAC;CAEvB,MAAM,mBAAmB,aACtB,UAAiB;AAChB,MAAI,SACF,YAAW,MAAM;MAEjB,YAAW,MAAM,GAAG;IAGxB,CAAC,UAAU,SAAS,CACrB;AAED,QACE,oBAAC,OAAD;EACE,cAAc;EACd,wBAAwB,SAAS,cAAc,QAAQ,CAAC;EACxD,gBACE,CAAC,kBACC,oBAAC,gBAAD;GACU;GACR,SAAS,aAAa;GACtB,iBAAiB,aAAa;GACvB;GACP,CAAA;EAGA;EACN,OAAO;EACP,UAAU;EACA;EACD;EACM;EACM;EACrB,aAAa;EACb,YAAA;EACA,UAAU;EACC;EACD;EACC;EACH;EACO;EACH;EACO;EACZ,CAAA"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { IBaseMemberSelectorProps } from '../interface';
|
|
1
2
|
import { default as React } from 'react';
|
|
2
3
|
import { IUserGroup, TUserGroupValue, TUserValue } from '../../ConfigProvider/getUserList';
|
|
3
4
|
interface IProps {
|
|
@@ -16,6 +17,7 @@ interface IProps {
|
|
|
16
17
|
filterItem?: (item: IUserGroup) => boolean;
|
|
17
18
|
searchValue?: string;
|
|
18
19
|
showSearch?: boolean;
|
|
20
|
+
canEnterGroup?: IBaseMemberSelectorProps['canEnterGroup'];
|
|
19
21
|
renderItem?: (item: IUserGroup, context: {
|
|
20
22
|
isSelected: boolean;
|
|
21
23
|
disabled: boolean;
|
|
@@ -24,5 +26,5 @@ interface IProps {
|
|
|
24
26
|
originNode: React.ReactNode;
|
|
25
27
|
}) => React.ReactNode;
|
|
26
28
|
}
|
|
27
|
-
declare const UserGroupSelection: ({ active, useProvidedSearch, parentSearchFailed, className, userGroupList, multiple, onChange, selectedUsersGroup: selectedUsersGroups, loading, onSearchValueChange, width, lockedIds, filterItem, searchValue, showSearch, renderItem, }: IProps) => import("react/jsx-runtime").JSX.Element;
|
|
29
|
+
declare const UserGroupSelection: ({ active, useProvidedSearch, parentSearchFailed, className, userGroupList, multiple, onChange, selectedUsersGroup: selectedUsersGroups, loading, onSearchValueChange, width, lockedIds, filterItem, searchValue, showSearch, canEnterGroup, renderItem, }: IProps) => import("react/jsx-runtime").JSX.Element;
|
|
28
30
|
export default UserGroupSelection;
|
|
@@ -17,7 +17,7 @@ import { useCallback, useContext, useMemo, useState } from "react";
|
|
|
17
17
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
18
18
|
import _ from "lodash";
|
|
19
19
|
//#region src/MemberPicker/components/UserGroupSelection.tsx
|
|
20
|
-
var UserGroupSelection = ({ active = true, useProvidedSearch = false, parentSearchFailed = false, className, userGroupList, multiple, onChange, selectedUsersGroup: selectedUsersGroups, loading, onSearchValueChange, width, lockedIds, filterItem, searchValue = "", showSearch, renderItem }) => {
|
|
20
|
+
var UserGroupSelection = ({ active = true, useProvidedSearch = false, parentSearchFailed = false, className, userGroupList, multiple, onChange, selectedUsersGroup: selectedUsersGroups, loading, onSearchValueChange, width, lockedIds, filterItem, searchValue = "", showSearch, canEnterGroup, renderItem }) => {
|
|
21
21
|
const { locale } = useContext(LocaleContext);
|
|
22
22
|
const t = getTranslator(locale);
|
|
23
23
|
const { getNextLevelGroup, getNextLevelGroupWithMeta } = useContext(GetUserListContext);
|
|
@@ -139,7 +139,7 @@ var UserGroupSelection = ({ active = true, useProvidedSearch = false, parentSear
|
|
|
139
139
|
groupId: userGroup.groupId,
|
|
140
140
|
type: userGroup.type
|
|
141
141
|
}) !== -1;
|
|
142
|
-
const hasNextLevel = userGroupList.some((group) => group.parentId === userGroup.groupId) || isAsync;
|
|
142
|
+
const hasNextLevel = (userGroupList.some((group) => group.parentId === userGroup.groupId) || isAsync) && canEnterGroup?.(userGroup) !== false;
|
|
143
143
|
const onNextLevel = () => {
|
|
144
144
|
setGroupPath((prev) => [...prev, userGroup]);
|
|
145
145
|
onSearchValueChange?.("");
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserGroupSelection.js","names":[],"sources":["../../../src/MemberPicker/components/UserGroupSelection.tsx"],"sourcesContent":["import { useCallback } from 'react';\nimport useMemberSearch from '../useMemberSearch';\nimport SearchFeedback from './SearchFeedback';\nimport Breadcrumb from '../../Breadcrumb';\nimport { cn } from '../../lib/utils';\nimport _ from 'lodash';\nimport React, { useContext, useMemo, useState } from 'react';\nimport GetUserListContext, {\n IUserGroup,\n TUserGroupValue,\n TUserValue,\n} from '../../ConfigProvider/getUserList';\nimport Empty from '../../Empty';\nimport { ChevronLeftLine, SearchLine } from '../../Icon';\nimport Input from '../../Input';\nimport ScrollArea from '../../ScrollArea';\nimport Spin from '../../Spin';\nimport { LocaleContext, getTranslator } from '../../locale/default';\nimport { isUserGroup } from '../utils/getUsersWithUserId';\nimport MultipleOption from './MultipleOption';\nimport SingleOption from './SingleOption';\n\ninterface IProps {\n active?: boolean;\n useProvidedSearch?: boolean;\n parentSearchFailed?: boolean;\n className?: string;\n userGroupList: IUserGroup[];\n multiple?: boolean;\n onChange: (selected: boolean, userGroup: IUserGroup) => void;\n selectedUsersGroup: IUserGroup[];\n loading: boolean;\n onSearchValueChange?: (value: string) => void;\n width: number;\n lockedIds: Array<TUserValue | TUserGroupValue>;\n filterItem?: (item: IUserGroup) => boolean;\n searchValue?: string;\n showSearch?: boolean;\n renderItem?: (\n item: IUserGroup,\n context: {\n isSelected: boolean;\n disabled: boolean;\n onClick: () => void;\n onNextLevel?: () => void;\n originNode: React.ReactNode;\n },\n ) => React.ReactNode;\n}\n\nconst UserGroupSelection = ({\n active = true,\n useProvidedSearch = false,\n parentSearchFailed = false,\n className,\n userGroupList,\n multiple,\n onChange,\n selectedUsersGroup: selectedUsersGroups,\n loading,\n onSearchValueChange,\n width,\n lockedIds,\n filterItem,\n searchValue = '',\n showSearch,\n renderItem,\n}: IProps) => {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n\n const { getNextLevelGroup, getNextLevelGroupWithMeta } =\n useContext(GetUserListContext);\n\n const isAsync = !!(getNextLevelGroup || getNextLevelGroupWithMeta);\n\n const [groupPath, setGroupPath] = useState<IUserGroup[]>([]);\n const parentGroupId = _.last(groupPath)?.groupId;\n const queryGroups = useCallback(\n (keyword: string) => {\n const params = { parentGroupId, keyword };\n if (getNextLevelGroupWithMeta) return getNextLevelGroupWithMeta(params);\n return getNextLevelGroup\n ? getNextLevelGroup(params)\n : Promise.resolve([]);\n },\n [getNextLevelGroup, getNextLevelGroupWithMeta, parentGroupId],\n );\n const {\n result,\n loading: groupLoading,\n failed,\n retry,\n } = useMemberSearch<IUserGroup>(\n queryGroups,\n searchValue,\n isAsync && active && !useProvidedSearch,\n );\n const asyncUserGroupList = result.items;\n\n const filterUserList = useMemo(() => {\n let currentLevelGroups = asyncUserGroupList;\n\n if (!isAsync || useProvidedSearch) {\n currentLevelGroups = userGroupList.filter((userGroup) => {\n if (searchValue.trim()) return true;\n if (groupPath.length === 0) {\n return !userGroup.parentId;\n }\n\n return userGroup.parentId === parentGroupId;\n });\n\n const normalizedKeyword = searchValue.trim().toLowerCase();\n currentLevelGroups = currentLevelGroups.filter((group) => {\n if (!normalizedKeyword) {\n return true;\n }\n\n return group.name.toLowerCase().includes(normalizedKeyword);\n });\n }\n\n return currentLevelGroups.filter((userGroup) => {\n if (filterItem) {\n return filterItem(userGroup);\n }\n\n return true;\n });\n }, [\n asyncUserGroupList,\n filterItem,\n groupPath.length,\n isAsync,\n useProvidedSearch,\n parentGroupId,\n searchValue,\n userGroupList,\n ]);\n\n return (\n <div className={cn(className, 'ald-member-picker-member-list-wrap')}>\n {showSearch && (\n <Input\n prefix={<SearchLine size={16} />}\n className=\"ald-member-picker-search-input\"\n aria-label={t.InputSearch.search}\n autoFocus\n value={searchValue}\n onChange={(event) => onSearchValueChange?.(event.target.value)}\n />\n )}\n {filterUserList.length === 0 &&\n !loading &&\n !(useProvidedSearch ? parentSearchFailed : groupLoading || failed) && (\n <Empty\n title={t.MemberPicker.noData}\n size=\"small\"\n image={Empty.PRESENTED_IMAGE_SEARCH}\n className=\"ald-member-picker-member-list-empty\"\n />\n )}\n {groupPath.length !== 0 && (\n <ScrollArea className=\"ald-member-picker-breadcrumb-scroll\">\n <Breadcrumb className=\"ald-member-picker-breadcrumb\">\n <Breadcrumb.Item\n className=\"ald-member-picker-breadcrumb-item\"\n onClick={() => {\n setGroupPath([]);\n }}\n >\n <div className=\"ald-member-picker-breadcrumb-item-inner\">\n <ChevronLeftLine size={16} />\n {t.MemberPicker.userGroups}\n </div>\n </Breadcrumb.Item>\n {groupPath.map((group) => (\n <Breadcrumb.Item\n className=\"ald-member-picker-breadcrumb-item\"\n key={group.groupId}\n onClick={() => {\n setGroupPath((groups) => {\n const groupIndex = groups.findIndex(\n (tempGroup) => tempGroup.groupId === group.groupId,\n );\n return groups.filter(\n (tempGroup, index) => index <= groupIndex,\n );\n });\n }}\n >\n <div className=\"ald-member-picker-breadcrumb-item-inner\">\n {group.name}\n </div>\n </Breadcrumb.Item>\n ))}\n </Breadcrumb>\n </ScrollArea>\n )}\n {isAsync && !useProvidedSearch && (\n <SearchFeedback\n failed={failed}\n hasMore={result.hasMore}\n pathWarningCode={result.pathWarningCode}\n retry={retry}\n />\n )}\n <Spin\n tip=\"Loading\"\n spinning={loading || (!useProvidedSearch && groupLoading)}\n size=\"small\"\n className=\"ald-member-picker-user-list\"\n >\n <ScrollArea\n className={cn('ald-member-picker-member-list', {\n 'ald-member-picker-member-list-null':\n filterUserList.length === 0 && !loading && !groupLoading,\n })}\n innerClassName=\"ald-member-picker-member-scroll\"\n >\n <div\n role=\"listbox\"\n aria-label=\"Groups\"\n aria-multiselectable={multiple || undefined}\n className=\"ald-member-picker-member-list-inner\"\n style={{ width: multiple ? width : undefined, overflow: 'hidden' }}\n >\n {filterUserList.map((userGroup) => {\n const isSelected = selectedUsersGroups.some(\n (selectUserGroup) =>\n selectUserGroup.groupId === userGroup.groupId,\n );\n\n const index = _.findIndex(lockedIds, {\n groupId: userGroup.groupId,\n type: userGroup.type,\n });\n const disabled = index !== -1;\n\n const hasNextLevel =\n userGroupList.some(\n (group) => group.parentId === userGroup.groupId,\n ) || isAsync;\n const onNextLevel = () => {\n setGroupPath((prev) => [...prev, userGroup]);\n onSearchValueChange?.('');\n };\n\n const originNode = multiple ? (\n <MultipleOption\n key={userGroup.groupId}\n searchValue={searchValue}\n user={userGroup}\n disabled={disabled}\n selected={isSelected}\n onChange={(selected, userGroup) => {\n if (isUserGroup(userGroup)) {\n onChange(selected, userGroup);\n }\n }}\n hasNextLevel={hasNextLevel}\n onNextLevel={onNextLevel}\n ></MultipleOption>\n ) : (\n <SingleOption\n key={userGroup.groupId}\n searchValue={searchValue}\n user={userGroup}\n disabled={disabled}\n selected={isSelected}\n onChange={(selected, userGroup) => {\n if (isUserGroup(userGroup)) {\n onChange(selected, userGroup);\n }\n }}\n hasNextLevel={hasNextLevel}\n onNextLevel={onNextLevel}\n ></SingleOption>\n );\n\n if (renderItem) {\n return (\n <div\n key={userGroup.groupId}\n role=\"option\"\n id={`ald-member-picker-option-${userGroup.groupId}`}\n aria-selected={isSelected}\n aria-disabled={disabled || undefined}\n >\n {renderItem(userGroup, {\n isSelected,\n disabled,\n onClick: () => {\n if (isUserGroup(userGroup) && !disabled) {\n onChange(!isSelected, userGroup);\n }\n },\n onNextLevel: hasNextLevel ? onNextLevel : undefined,\n originNode,\n })}\n </div>\n );\n }\n\n return originNode;\n })}\n </div>\n </ScrollArea>\n </Spin>\n </div>\n );\n};\n\nexport default UserGroupSelection;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"UserGroupSelection.js","names":[],"sources":["../../../src/MemberPicker/components/UserGroupSelection.tsx"],"sourcesContent":["import type { IBaseMemberSelectorProps } from '../interface';\nimport { useCallback } from 'react';\nimport useMemberSearch from '../useMemberSearch';\nimport SearchFeedback from './SearchFeedback';\nimport Breadcrumb from '../../Breadcrumb';\nimport { cn } from '../../lib/utils';\nimport _ from 'lodash';\nimport React, { useContext, useMemo, useState } from 'react';\nimport GetUserListContext, {\n IUserGroup,\n TUserGroupValue,\n TUserValue,\n} from '../../ConfigProvider/getUserList';\nimport Empty from '../../Empty';\nimport { ChevronLeftLine, SearchLine } from '../../Icon';\nimport Input from '../../Input';\nimport ScrollArea from '../../ScrollArea';\nimport Spin from '../../Spin';\nimport { LocaleContext, getTranslator } from '../../locale/default';\nimport { isUserGroup } from '../utils/getUsersWithUserId';\nimport MultipleOption from './MultipleOption';\nimport SingleOption from './SingleOption';\n\ninterface IProps {\n active?: boolean;\n useProvidedSearch?: boolean;\n parentSearchFailed?: boolean;\n className?: string;\n userGroupList: IUserGroup[];\n multiple?: boolean;\n onChange: (selected: boolean, userGroup: IUserGroup) => void;\n selectedUsersGroup: IUserGroup[];\n loading: boolean;\n onSearchValueChange?: (value: string) => void;\n width: number;\n lockedIds: Array<TUserValue | TUserGroupValue>;\n filterItem?: (item: IUserGroup) => boolean;\n searchValue?: string;\n showSearch?: boolean;\n canEnterGroup?: IBaseMemberSelectorProps['canEnterGroup'];\n renderItem?: (\n item: IUserGroup,\n context: {\n isSelected: boolean;\n disabled: boolean;\n onClick: () => void;\n onNextLevel?: () => void;\n originNode: React.ReactNode;\n },\n ) => React.ReactNode;\n}\n\nconst UserGroupSelection = ({\n active = true,\n useProvidedSearch = false,\n parentSearchFailed = false,\n className,\n userGroupList,\n multiple,\n onChange,\n selectedUsersGroup: selectedUsersGroups,\n loading,\n onSearchValueChange,\n width,\n lockedIds,\n filterItem,\n searchValue = '',\n showSearch,\n canEnterGroup,\n renderItem,\n}: IProps) => {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n\n const { getNextLevelGroup, getNextLevelGroupWithMeta } =\n useContext(GetUserListContext);\n\n const isAsync = !!(getNextLevelGroup || getNextLevelGroupWithMeta);\n\n const [groupPath, setGroupPath] = useState<IUserGroup[]>([]);\n const parentGroupId = _.last(groupPath)?.groupId;\n const queryGroups = useCallback(\n (keyword: string) => {\n const params = { parentGroupId, keyword };\n if (getNextLevelGroupWithMeta) return getNextLevelGroupWithMeta(params);\n return getNextLevelGroup\n ? getNextLevelGroup(params)\n : Promise.resolve([]);\n },\n [getNextLevelGroup, getNextLevelGroupWithMeta, parentGroupId],\n );\n const {\n result,\n loading: groupLoading,\n failed,\n retry,\n } = useMemberSearch<IUserGroup>(\n queryGroups,\n searchValue,\n isAsync && active && !useProvidedSearch,\n );\n const asyncUserGroupList = result.items;\n\n const filterUserList = useMemo(() => {\n let currentLevelGroups = asyncUserGroupList;\n\n if (!isAsync || useProvidedSearch) {\n currentLevelGroups = userGroupList.filter((userGroup) => {\n if (searchValue.trim()) return true;\n if (groupPath.length === 0) {\n return !userGroup.parentId;\n }\n\n return userGroup.parentId === parentGroupId;\n });\n\n const normalizedKeyword = searchValue.trim().toLowerCase();\n currentLevelGroups = currentLevelGroups.filter((group) => {\n if (!normalizedKeyword) {\n return true;\n }\n\n return group.name.toLowerCase().includes(normalizedKeyword);\n });\n }\n\n return currentLevelGroups.filter((userGroup) => {\n if (filterItem) {\n return filterItem(userGroup);\n }\n\n return true;\n });\n }, [\n asyncUserGroupList,\n filterItem,\n groupPath.length,\n isAsync,\n useProvidedSearch,\n parentGroupId,\n searchValue,\n userGroupList,\n ]);\n\n return (\n <div className={cn(className, 'ald-member-picker-member-list-wrap')}>\n {showSearch && (\n <Input\n prefix={<SearchLine size={16} />}\n className=\"ald-member-picker-search-input\"\n aria-label={t.InputSearch.search}\n autoFocus\n value={searchValue}\n onChange={(event) => onSearchValueChange?.(event.target.value)}\n />\n )}\n {filterUserList.length === 0 &&\n !loading &&\n !(useProvidedSearch ? parentSearchFailed : groupLoading || failed) && (\n <Empty\n title={t.MemberPicker.noData}\n size=\"small\"\n image={Empty.PRESENTED_IMAGE_SEARCH}\n className=\"ald-member-picker-member-list-empty\"\n />\n )}\n {groupPath.length !== 0 && (\n <ScrollArea className=\"ald-member-picker-breadcrumb-scroll\">\n <Breadcrumb className=\"ald-member-picker-breadcrumb\">\n <Breadcrumb.Item\n className=\"ald-member-picker-breadcrumb-item\"\n onClick={() => {\n setGroupPath([]);\n }}\n >\n <div className=\"ald-member-picker-breadcrumb-item-inner\">\n <ChevronLeftLine size={16} />\n {t.MemberPicker.userGroups}\n </div>\n </Breadcrumb.Item>\n {groupPath.map((group) => (\n <Breadcrumb.Item\n className=\"ald-member-picker-breadcrumb-item\"\n key={group.groupId}\n onClick={() => {\n setGroupPath((groups) => {\n const groupIndex = groups.findIndex(\n (tempGroup) => tempGroup.groupId === group.groupId,\n );\n return groups.filter(\n (tempGroup, index) => index <= groupIndex,\n );\n });\n }}\n >\n <div className=\"ald-member-picker-breadcrumb-item-inner\">\n {group.name}\n </div>\n </Breadcrumb.Item>\n ))}\n </Breadcrumb>\n </ScrollArea>\n )}\n {isAsync && !useProvidedSearch && (\n <SearchFeedback\n failed={failed}\n hasMore={result.hasMore}\n pathWarningCode={result.pathWarningCode}\n retry={retry}\n />\n )}\n <Spin\n tip=\"Loading\"\n spinning={loading || (!useProvidedSearch && groupLoading)}\n size=\"small\"\n className=\"ald-member-picker-user-list\"\n >\n <ScrollArea\n className={cn('ald-member-picker-member-list', {\n 'ald-member-picker-member-list-null':\n filterUserList.length === 0 && !loading && !groupLoading,\n })}\n innerClassName=\"ald-member-picker-member-scroll\"\n >\n <div\n role=\"listbox\"\n aria-label=\"Groups\"\n aria-multiselectable={multiple || undefined}\n className=\"ald-member-picker-member-list-inner\"\n style={{ width: multiple ? width : undefined, overflow: 'hidden' }}\n >\n {filterUserList.map((userGroup) => {\n const isSelected = selectedUsersGroups.some(\n (selectUserGroup) =>\n selectUserGroup.groupId === userGroup.groupId,\n );\n\n const index = _.findIndex(lockedIds, {\n groupId: userGroup.groupId,\n type: userGroup.type,\n });\n const disabled = index !== -1;\n\n const hasNextLevel =\n (userGroupList.some(\n (group) => group.parentId === userGroup.groupId,\n ) ||\n isAsync) &&\n canEnterGroup?.(userGroup) !== false;\n const onNextLevel = () => {\n setGroupPath((prev) => [...prev, userGroup]);\n onSearchValueChange?.('');\n };\n\n const originNode = multiple ? (\n <MultipleOption\n key={userGroup.groupId}\n searchValue={searchValue}\n user={userGroup}\n disabled={disabled}\n selected={isSelected}\n onChange={(selected, userGroup) => {\n if (isUserGroup(userGroup)) {\n onChange(selected, userGroup);\n }\n }}\n hasNextLevel={hasNextLevel}\n onNextLevel={onNextLevel}\n ></MultipleOption>\n ) : (\n <SingleOption\n key={userGroup.groupId}\n searchValue={searchValue}\n user={userGroup}\n disabled={disabled}\n selected={isSelected}\n onChange={(selected, userGroup) => {\n if (isUserGroup(userGroup)) {\n onChange(selected, userGroup);\n }\n }}\n hasNextLevel={hasNextLevel}\n onNextLevel={onNextLevel}\n ></SingleOption>\n );\n\n if (renderItem) {\n return (\n <div\n key={userGroup.groupId}\n role=\"option\"\n id={`ald-member-picker-option-${userGroup.groupId}`}\n aria-selected={isSelected}\n aria-disabled={disabled || undefined}\n >\n {renderItem(userGroup, {\n isSelected,\n disabled,\n onClick: () => {\n if (isUserGroup(userGroup) && !disabled) {\n onChange(!isSelected, userGroup);\n }\n },\n onNextLevel: hasNextLevel ? onNextLevel : undefined,\n originNode,\n })}\n </div>\n );\n }\n\n return originNode;\n })}\n </div>\n </ScrollArea>\n </Spin>\n </div>\n );\n};\n\nexport default UserGroupSelection;\n"],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { MemberPickerDialogProps } from './MemberPickerDialog.js';
|
|
2
2
|
/** 打开期间拥有选择草稿;确认才通知业务,取消与卸载均释放请求和临时选择。 */
|
|
3
|
-
export default function DialogContent({ value, onChange, onClose, type, lockedIds, filterItem, renderItem, renderSelectedTag, zIndex, footer, onCancel, }: MemberPickerDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
3
|
+
export default function DialogContent({ value, onChange, onClose, type, lockedIds, filterItem, canEnterGroup, renderItem, renderSelectedTag, zIndex, footer, onCancel, }: MemberPickerDialogProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -14,7 +14,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
14
14
|
import { MaximizeLine, MinimizeLine } from "@aloudata/icons-react";
|
|
15
15
|
//#region src/MemberPicker/dialog/DialogContent.tsx
|
|
16
16
|
/** 打开期间拥有选择草稿;确认才通知业务,取消与卸载均释放请求和临时选择。 */
|
|
17
|
-
function DialogContent({ value, onChange, onClose, type = EMemberPicker.BOTH, lockedIds, filterItem, renderItem, renderSelectedTag, zIndex, footer, onCancel }) {
|
|
17
|
+
function DialogContent({ value, onChange, onClose, type = EMemberPicker.BOTH, lockedIds, filterItem, canEnterGroup, renderItem, renderSelectedTag, zIndex, footer, onCancel }) {
|
|
18
18
|
const t = useDialogLocale();
|
|
19
19
|
const [fullscreen, setFullscreen] = useState(false);
|
|
20
20
|
const draft = useMemberPickerDraft({
|
|
@@ -41,7 +41,10 @@ function DialogContent({ value, onChange, onClose, type = EMemberPicker.BOTH, lo
|
|
|
41
41
|
onClose();
|
|
42
42
|
};
|
|
43
43
|
const users = /* @__PURE__ */ jsx(UserCandidatePanel, { ...panelProps });
|
|
44
|
-
const groups = /* @__PURE__ */ jsx(UserGroupCandidatePanel, {
|
|
44
|
+
const groups = /* @__PURE__ */ jsx(UserGroupCandidatePanel, {
|
|
45
|
+
...panelProps,
|
|
46
|
+
canEnterGroup
|
|
47
|
+
});
|
|
45
48
|
return /* @__PURE__ */ jsx(Modal, {
|
|
46
49
|
open: true,
|
|
47
50
|
centered: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DialogContent.js","names":[],"sources":["../../../src/MemberPicker/dialog/DialogContent.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { MaximizeLine, MinimizeLine } from '@aloudata/icons-react';\nimport IconButton from '../../IconButton';\nimport Modal from '../../Modal';\nimport Tabs from '../../Tabs';\nimport SelectorFooter from '../components/SelectorFooter';\nimport { EMemberPicker } from '../interface';\nimport type { MemberPickerDialogProps } from './MemberPickerDialog';\nimport DialogColumns from './DialogColumns';\nimport SelectedMemberPanel from './SelectedMemberPanel';\nimport UserCandidatePanel from './UserCandidatePanel';\nimport UserGroupCandidatePanel from './UserGroupCandidatePanel';\nimport { useMemberPickerDraft } from './useMemberPickerDraft';\nimport useDialogLocale from './useDialogLocale';\n\n/** 打开期间拥有选择草稿;确认才通知业务,取消与卸载均释放请求和临时选择。 */\nexport default function DialogContent({\n value,\n onChange,\n onClose,\n type = EMemberPicker.BOTH,\n lockedIds,\n filterItem,\n renderItem,\n renderSelectedTag,\n zIndex,\n footer,\n onCancel,\n}: MemberPickerDialogProps) {\n const t = useDialogLocale();\n const [fullscreen, setFullscreen] = useState(false);\n const draft = useMemberPickerDraft({ value, onChange, type, lockedIds });\n const panelProps = {\n selectedByKey: draft.selectedByKey,\n onToggle: draft.toggleMember,\n onToggleAll: draft.toggleMembers,\n lockedIds,\n filterItem,\n renderItem,\n };\n const confirm = () => {\n if (draft.hydrating) return;\n draft.confirm();\n onClose();\n };\n const cancel = () => {\n onCancel?.();\n onClose();\n };\n const users = <UserCandidatePanel {...panelProps} />;\n const groups = <UserGroupCandidatePanel {...panelProps}
|
|
1
|
+
{"version":3,"file":"DialogContent.js","names":[],"sources":["../../../src/MemberPicker/dialog/DialogContent.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { MaximizeLine, MinimizeLine } from '@aloudata/icons-react';\nimport IconButton from '../../IconButton';\nimport Modal from '../../Modal';\nimport Tabs from '../../Tabs';\nimport SelectorFooter from '../components/SelectorFooter';\nimport { EMemberPicker } from '../interface';\nimport type { MemberPickerDialogProps } from './MemberPickerDialog';\nimport DialogColumns from './DialogColumns';\nimport SelectedMemberPanel from './SelectedMemberPanel';\nimport UserCandidatePanel from './UserCandidatePanel';\nimport UserGroupCandidatePanel from './UserGroupCandidatePanel';\nimport { useMemberPickerDraft } from './useMemberPickerDraft';\nimport useDialogLocale from './useDialogLocale';\n\n/** 打开期间拥有选择草稿;确认才通知业务,取消与卸载均释放请求和临时选择。 */\nexport default function DialogContent({\n value,\n onChange,\n onClose,\n type = EMemberPicker.BOTH,\n lockedIds,\n filterItem,\n canEnterGroup,\n renderItem,\n renderSelectedTag,\n zIndex,\n footer,\n onCancel,\n}: MemberPickerDialogProps) {\n const t = useDialogLocale();\n const [fullscreen, setFullscreen] = useState(false);\n const draft = useMemberPickerDraft({ value, onChange, type, lockedIds });\n const panelProps = {\n selectedByKey: draft.selectedByKey,\n onToggle: draft.toggleMember,\n onToggleAll: draft.toggleMembers,\n lockedIds,\n filterItem,\n renderItem,\n };\n const confirm = () => {\n if (draft.hydrating) return;\n draft.confirm();\n onClose();\n };\n const cancel = () => {\n onCancel?.();\n onClose();\n };\n const users = <UserCandidatePanel {...panelProps} />;\n const groups = (\n <UserGroupCandidatePanel {...panelProps} canEnterGroup={canEnterGroup} />\n );\n return (\n <Modal\n open\n centered\n paddingLess\n zIndex={zIndex}\n width={\n fullscreen ? 'calc(100vw - 24px)' : 'min(800px, calc(100vw - 32px))'\n }\n title={\n <div className=\"tw-flex tw-items-center tw-gap-sp-150\">\n <span>{t.MemberPickerDialog.title}</span>\n <IconButton\n size=\"small\"\n aria-label={\n fullscreen\n ? t.MemberPickerDialog.exitMaximize\n : t.MemberPickerDialog.maximize\n }\n tooltip={{\n title: fullscreen\n ? t.MemberPickerDialog.exitMaximize\n : t.MemberPickerDialog.maximize,\n }}\n icon={fullscreen ? <MinimizeLine /> : <MaximizeLine />}\n onClick={() => setFullscreen((current) => !current)}\n />\n </div>\n }\n okText={t.MemberPickerDialog.ok}\n cancelText={t.MemberPickerDialog.cancel}\n okButtonProps={{ disabled: draft.hydrating }}\n onOk={confirm}\n footer={\n footer ? (\n <SelectorFooter footer={footer} onOk={confirm} onCancel={cancel} />\n ) : undefined\n }\n onCancel={cancel}\n >\n <div\n className=\"ald-member-picker-dialog tw-min-h-0 tw-p-sp-200\"\n style={{\n height: fullscreen\n ? 'calc(100dvh - 150px)'\n : 'min(560px, calc(100dvh - 180px))',\n }}\n >\n <DialogColumns>\n <div className=\"tw-h-full tw-min-w-0 tw-overflow-hidden\">\n {type === EMemberPicker.BOTH ? (\n <Tabs\n compact\n adaptHeight\n className=\"tw-h-full\"\n activeKey={draft.activeTab}\n onChange={(key) => {\n if (key === EMemberPicker.USER || key === EMemberPicker.GROUP)\n draft.setActiveTab(key);\n }}\n items={[\n {\n key: EMemberPicker.USER,\n label: t.MemberPickerDialog.user,\n children: users,\n },\n {\n key: EMemberPicker.GROUP,\n label: t.MemberPickerDialog.userGroup,\n children: groups,\n },\n ]}\n />\n ) : type === EMemberPicker.GROUP ? (\n groups\n ) : (\n users\n )}\n </div>\n <SelectedMemberPanel\n members={draft.selectedMembers}\n lockedIds={lockedIds}\n onRemove={draft.removeMember}\n renderSelectedTag={renderSelectedTag}\n />\n </DialogColumns>\n </div>\n </Modal>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,SAAwB,cAAc,EACpC,OACA,UACA,SACA,OAAO,cAAc,MACrB,WACA,YACA,eACA,YACA,mBACA,QACA,QACA,YAC0B;CAC1B,MAAM,IAAI,iBAAiB;CAC3B,MAAM,CAAC,YAAY,iBAAiB,SAAS,MAAM;CACnD,MAAM,QAAQ,qBAAqB;EAAE;EAAO;EAAU;EAAM;EAAW,CAAC;CACxE,MAAM,aAAa;EACjB,eAAe,MAAM;EACrB,UAAU,MAAM;EAChB,aAAa,MAAM;EACnB;EACA;EACA;EACD;CACD,MAAM,gBAAgB;AACpB,MAAI,MAAM,UAAW;AACrB,QAAM,SAAS;AACf,WAAS;;CAEX,MAAM,eAAe;AACnB,cAAY;AACZ,WAAS;;CAEX,MAAM,QAAQ,oBAAC,oBAAD,EAAoB,GAAI,YAAc,CAAA;CACpD,MAAM,SACJ,oBAAC,yBAAD;EAAyB,GAAI;EAA2B;EAAiB,CAAA;AAE3E,QACE,oBAAC,OAAD;EACE,MAAA;EACA,UAAA;EACA,aAAA;EACQ;EACR,OACE,aAAa,uBAAuB;EAEtC,OACE,qBAAC,OAAD;GAAK,WAAU;aAAf,CACE,oBAAC,QAAD,EAAA,UAAO,EAAE,mBAAmB,OAAa,CAAA,EACzC,oBAAC,YAAD;IACE,MAAK;IACL,cACE,aACI,EAAE,mBAAmB,eACrB,EAAE,mBAAmB;IAE3B,SAAS,EACP,OAAO,aACH,EAAE,mBAAmB,eACrB,EAAE,mBAAmB,UAC1B;IACD,MAAM,aAAa,oBAAC,cAAD,EAAgB,CAAA,GAAG,oBAAC,cAAD,EAAgB,CAAA;IACtD,eAAe,eAAe,YAAY,CAAC,QAAQ;IACnD,CAAA,CACE;;EAER,QAAQ,EAAE,mBAAmB;EAC7B,YAAY,EAAE,mBAAmB;EACjC,eAAe,EAAE,UAAU,MAAM,WAAW;EAC5C,MAAM;EACN,QACE,SACE,oBAAC,gBAAD;GAAwB;GAAQ,MAAM;GAAS,UAAU;GAAU,CAAA,GACjE;EAEN,UAAU;YAEV,oBAAC,OAAD;GACE,WAAU;GACV,OAAO,EACL,QAAQ,aACJ,yBACA,oCACL;aAED,qBAAC,eAAD,EAAA,UAAA,CACE,oBAAC,OAAD;IAAK,WAAU;cACZ,SAAS,cAAc,OACtB,oBAAC,MAAD;KACE,SAAA;KACA,aAAA;KACA,WAAU;KACV,WAAW,MAAM;KACjB,WAAW,QAAQ;AACjB,UAAI,QAAQ,cAAc,QAAQ,QAAQ,cAAc,MACtD,OAAM,aAAa,IAAI;;KAE3B,OAAO,CACL;MACE,KAAK,cAAc;MACnB,OAAO,EAAE,mBAAmB;MAC5B,UAAU;MACX,EACD;MACE,KAAK,cAAc;MACnB,OAAO,EAAE,mBAAmB;MAC5B,UAAU;MACX,CACF;KACD,CAAA,GACA,SAAS,cAAc,QACzB,SAEA;IAEE,CAAA,EACN,oBAAC,qBAAD;IACE,SAAS,MAAM;IACJ;IACX,UAAU,MAAM;IACG;IACnB,CAAA,CACY,EAAA,CAAA;GACZ,CAAA;EACA,CAAA"}
|