@aloudata/aloudata-design 3.0.26 → 3.1.0

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.
@@ -35,7 +35,7 @@ function InternalItem(props) {
35
35
  var ITEM_WIDTH = 10;
36
36
  var REST_KEY = "__OVERFLOW_REST__";
37
37
  function OverflowInner(props, ref) {
38
- const { prefixCls = "rc-overflow", data, renderItem, itemKey, renderRest, className, onVisibleChange } = props;
38
+ const { prefixCls = "rc-overflow", data, renderItem, itemKey, renderRest, gap = 0, className, onVisibleChange } = props;
39
39
  const [containerWidth, setContainerWidth] = useState(null);
40
40
  const mergedContainerWidth = containerWidth || 0;
41
41
  const [itemWidths, setItemWidths] = useState(() => /* @__PURE__ */ new Map());
@@ -97,11 +97,11 @@ function OverflowInner(props, ref) {
97
97
  return;
98
98
  }
99
99
  totalWidth += currentItemWidth;
100
- if (lastIndex === 0 && totalWidth <= mergedContainerWidth || i === lastIndex - 1 && totalWidth + (getItemWidth(lastIndex) ?? 0) <= mergedContainerWidth) {
100
+ if (lastIndex === 0 && totalWidth <= mergedContainerWidth || i === lastIndex - 1 && totalWidth + (getItemWidth(lastIndex) ?? 0) + lastIndex * gap <= mergedContainerWidth) {
101
101
  updateDisplayCount(lastIndex);
102
102
  return;
103
103
  }
104
- if (totalWidth + mergedRestWidth > mergedContainerWidth) {
104
+ if (totalWidth + mergedRestWidth + (i + 1) * gap > mergedContainerWidth) {
105
105
  updateDisplayCount(i - 1);
106
106
  return;
107
107
  }
@@ -1 +1 @@
1
- {"version":3,"file":"FixedOverflow.js","names":[],"sources":["../../../src/Select/Selector/FixedOverflow.tsx"],"sourcesContent":["// 修复 rc-overflow 的 restReady 卡 false bug。\n//\n// 根因(rc-overflow@1.5 es/Overflow.js updateDisplayCount):\n// if (displayCount === count && ...) return; // <-- 这一行\n// setDisplayCount(count);\n// if (!notReady) { setRestReady(count < data.length - 1); onVisibleChange?.(count); }\n//\n// 触发条件:modal 首开等首屏渲染时,半测量阶段(部分 itemWidth 还没注册)\n// 会先以 notReady=true 把 displayCount 推到「最终值 N」(比如 9 个 tag 都已\n// 测过,第 10 个还没到时调用 updateDisplayCount(9, undefined, true),\n// 而最终稳定态恰好也是 displayCount=9)。后续 ready 路径 displayCount===count\n// 早返回,setRestReady 永远没被调用 → restReady 始终是 false →\n// rest 节点 opacity:0, position:absolute, height:0 不可见。\n//\n// 修复:把 setRestReady 和 onVisibleChange 移到 early-return 之前。只要本次\n// 是 ready 路径,无论 displayCount 是否变化,都把 rest 状态推到位。\n//\n// 其它逻辑 1:1 复刻 rc-overflow 的 responsive 分支(ald 只用 maxCount='responsive'\n// 一种模式,prefix/suffix/raw render 等都没用),删掉用不到的代码以降复杂度。\n// 用 React 18 自动批处理,不再重写 channelUpdate / unstable_batchedUpdates。\n\nimport React, {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport ResizeObserver from 'rc-resize-observer';\nimport useLayoutEffect from 'rc-util/es/hooks/useLayoutEffect';\nimport cn from 'classnames';\n\ninterface ResizeInfo {\n width: number;\n height: number;\n offsetWidth: number;\n offsetHeight: number;\n}\n\ninterface InternalItemProps {\n prefixCls: string;\n display: boolean;\n order: number;\n itemKey: React.Key;\n registerSize: (key: React.Key, width: number | null) => void;\n className?: string;\n children?: React.ReactNode;\n}\n\nfunction InternalItem(props: InternalItemProps) {\n const {\n prefixCls,\n display,\n order,\n itemKey,\n registerSize,\n className,\n children,\n } = props;\n const mergedHidden = !display;\n // 卸载时把本 item 的 width 从 Map 里删掉。registerSize/itemKey 用 ref 抓最新,\n // 这样 effect 自身依赖只有 [],不需要 eslint-disable。\n const registerSizeRef = useRef(registerSize);\n const itemKeyRef = useRef(itemKey);\n registerSizeRef.current = registerSize;\n itemKeyRef.current = itemKey;\n useEffect(\n () => () => {\n registerSizeRef.current(itemKeyRef.current, null);\n },\n [],\n );\n const overflowStyle: React.CSSProperties = {\n opacity: mergedHidden ? 0 : 1,\n height: mergedHidden ? 0 : undefined,\n overflowY: mergedHidden ? 'hidden' : undefined,\n order,\n pointerEvents: mergedHidden ? 'none' : undefined,\n position: mergedHidden ? 'absolute' : undefined,\n };\n return (\n <ResizeObserver\n onResize={({ offsetWidth }: ResizeInfo) =>\n registerSize(itemKey, offsetWidth)\n }\n >\n <div\n className={cn(prefixCls, className)}\n style={overflowStyle}\n aria-hidden={mergedHidden || undefined}\n >\n {children}\n </div>\n </ResizeObserver>\n );\n}\n\nexport interface FixedOverflowProps<T> {\n prefixCls?: string;\n data: T[];\n renderItem: (item: T, info: { index: number }) => React.ReactNode;\n itemKey: (item: T) => React.Key;\n renderRest: (omittedItems: T[]) => React.ReactNode;\n className?: string;\n onVisibleChange?: (count: number) => void;\n}\n\nconst ITEM_WIDTH = 10;\n// rest 节点的固定 React key。假设调用方传入的 itemKey 不会返回此常量\n// (ald 内部 Select 的 itemKey 取 value/key 字段,不会等于这个字符串)。\nconst REST_KEY: React.Key = '__OVERFLOW_REST__';\n\nfunction OverflowInner<T>(\n props: FixedOverflowProps<T>,\n ref: React.ForwardedRef<HTMLDivElement>,\n) {\n const {\n prefixCls = 'rc-overflow',\n data,\n renderItem,\n itemKey,\n renderRest,\n className,\n onVisibleChange,\n } = props;\n\n const [containerWidth, setContainerWidth] = useState<number | null>(null);\n const mergedContainerWidth = containerWidth || 0;\n const [itemWidths, setItemWidths] = useState<Map<React.Key, number>>(\n () => new Map(),\n );\n const [prevRestWidth, setPrevRestWidth] = useState(0);\n const [restWidth, setRestWidth] = useState(0);\n const [displayCount, setDisplayCount] = useState<number | null>(null);\n const [restReady, setRestReady] = useState(false);\n\n const mergedDisplayCount = displayCount || 0;\n const itemPrefixCls = `${prefixCls}-item`;\n const mergedRestWidth = Math.max(prevRestWidth, restWidth);\n\n const getKey = useCallback(\n (item: T, index: number): React.Key => {\n if (item == null) return index;\n return itemKey(item) ?? index;\n },\n [itemKey],\n );\n\n const mergedData = useMemo(() => {\n if (!data.length) return data;\n return data.slice(\n 0,\n Math.min(data.length, mergedContainerWidth / ITEM_WIDTH),\n );\n }, [data, mergedContainerWidth]);\n\n const omittedItems = useMemo(\n () => data.slice(mergedDisplayCount + 1),\n [data, mergedDisplayCount],\n );\n\n const updateDisplayCount = (count: number, notReady?: boolean) => {\n // === BUG FIX ===\n // 不论 displayCount 是否变化,只要本次是 ready 路径,立即把 restReady /\n // onVisibleChange 推到位。原版在 displayCount===count 时早返回,会跳过\n // 这两步,造成 restReady 卡死在 false。\n if (!notReady) {\n setRestReady(count < data.length - 1);\n onVisibleChange?.(count);\n }\n if (displayCount !== count) {\n setDisplayCount(count);\n }\n };\n\n const registerSize = useCallback((key: React.Key, width: number | null) => {\n setItemWidths((origin) => {\n const clone = new Map(origin);\n if (width === null) clone.delete(key);\n else clone.set(key, width);\n return clone;\n });\n }, []);\n\n const registerRestSize = useCallback(\n (_key: React.Key, width: number | null) => {\n if (width === null) return;\n setRestWidth((prev) => {\n setPrevRestWidth(prev);\n return width;\n });\n },\n [],\n );\n\n const onOverflowResize = (_: ResizeInfo, element: HTMLElement) => {\n setContainerWidth(element.clientWidth);\n };\n\n // 故意不加依赖数组:测量回路依赖每次渲染都重跑——itemWidths 变 → 重算 displayCount\n // → 触发再渲染 → 再测量。加 deps 会破坏 rc-overflow 原版的测量-更新循环。\n useLayoutEffect(() => {\n if (!mergedContainerWidth || !mergedData) return;\n const len = mergedData.length;\n const lastIndex = len - 1;\n if (!len) {\n updateDisplayCount(0);\n return;\n }\n let totalWidth = 0;\n const getItemWidth = (index: number): number | undefined =>\n itemWidths.get(getKey(mergedData[index], index));\n for (let i = 0; i < len; i += 1) {\n const currentItemWidth = getItemWidth(i);\n if (currentItemWidth === undefined) {\n // 半测量:先把 displayCount 推到 i-1,但不动 restReady(notReady=true)。\n updateDisplayCount(i - 1, true);\n return;\n }\n totalWidth += currentItemWidth;\n if (\n (lastIndex === 0 && totalWidth <= mergedContainerWidth) ||\n (i === lastIndex - 1 &&\n totalWidth + (getItemWidth(lastIndex) ?? 0) <= mergedContainerWidth)\n ) {\n // 全部塞得下\n updateDisplayCount(lastIndex);\n return;\n }\n if (totalWidth + mergedRestWidth > mergedContainerWidth) {\n // 当前这个塞不下了,需要展示 \"+N\"\n updateDisplayCount(i - 1);\n return;\n }\n }\n });\n\n const displayRest = restReady && !!omittedItems.length;\n\n return (\n <ResizeObserver onResize={onOverflowResize} disabled={!data.length}>\n <div className={cn(prefixCls, className)} ref={ref}>\n {mergedData.map((item, index) => {\n const key = getKey(item, index);\n return (\n <InternalItem\n key={key}\n prefixCls={itemPrefixCls}\n display={index <= mergedDisplayCount}\n order={index}\n itemKey={key}\n registerSize={registerSize}\n >\n {renderItem(item, { index })}\n </InternalItem>\n );\n })}\n <InternalItem\n prefixCls={itemPrefixCls}\n display={displayRest}\n order={displayRest ? mergedDisplayCount : Number.MAX_SAFE_INTEGER}\n itemKey={REST_KEY}\n registerSize={registerRestSize}\n className={`${itemPrefixCls}-rest`}\n >\n {renderRest(omittedItems)}\n </InternalItem>\n </div>\n </ResizeObserver>\n );\n}\n\nconst FixedOverflow = forwardRef(OverflowInner) as <T>(\n props: FixedOverflowProps<T> & { ref?: React.Ref<HTMLDivElement> },\n) => React.ReactElement;\n\nexport default FixedOverflow;\n"],"mappings":"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"}
1
+ {"version":3,"file":"FixedOverflow.js","names":[],"sources":["../../../src/Select/Selector/FixedOverflow.tsx"],"sourcesContent":["// 修复 rc-overflow 的 restReady 卡 false bug。\n//\n// 根因(rc-overflow@1.5 es/Overflow.js updateDisplayCount):\n// if (displayCount === count && ...) return; // <-- 这一行\n// setDisplayCount(count);\n// if (!notReady) { setRestReady(count < data.length - 1); onVisibleChange?.(count); }\n//\n// 触发条件:modal 首开等首屏渲染时,半测量阶段(部分 itemWidth 还没注册)\n// 会先以 notReady=true 把 displayCount 推到「最终值 N」(比如 9 个 tag 都已\n// 测过,第 10 个还没到时调用 updateDisplayCount(9, undefined, true),\n// 而最终稳定态恰好也是 displayCount=9)。后续 ready 路径 displayCount===count\n// 早返回,setRestReady 永远没被调用 → restReady 始终是 false →\n// rest 节点 opacity:0, position:absolute, height:0 不可见。\n//\n// 修复:把 setRestReady 和 onVisibleChange 移到 early-return 之前。只要本次\n// 是 ready 路径,无论 displayCount 是否变化,都把 rest 状态推到位。\n//\n// 其它逻辑 1:1 复刻 rc-overflow 的 responsive 分支(ald 只用 maxCount='responsive'\n// 一种模式,prefix/suffix/raw render 等都没用),删掉用不到的代码以降复杂度。\n// 用 React 18 自动批处理,不再重写 channelUpdate / unstable_batchedUpdates。\n\nimport React, {\n forwardRef,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport ResizeObserver from 'rc-resize-observer';\nimport useLayoutEffect from 'rc-util/es/hooks/useLayoutEffect';\nimport cn from 'classnames';\n\ninterface ResizeInfo {\n width: number;\n height: number;\n offsetWidth: number;\n offsetHeight: number;\n}\n\ninterface InternalItemProps {\n prefixCls: string;\n display: boolean;\n order: number;\n itemKey: React.Key;\n registerSize: (key: React.Key, width: number | null) => void;\n className?: string;\n children?: React.ReactNode;\n}\n\nfunction InternalItem(props: InternalItemProps) {\n const {\n prefixCls,\n display,\n order,\n itemKey,\n registerSize,\n className,\n children,\n } = props;\n const mergedHidden = !display;\n // 卸载时把本 item 的 width 从 Map 里删掉。registerSize/itemKey 用 ref 抓最新,\n // 这样 effect 自身依赖只有 [],不需要 eslint-disable。\n const registerSizeRef = useRef(registerSize);\n const itemKeyRef = useRef(itemKey);\n registerSizeRef.current = registerSize;\n itemKeyRef.current = itemKey;\n useEffect(\n () => () => {\n registerSizeRef.current(itemKeyRef.current, null);\n },\n [],\n );\n const overflowStyle: React.CSSProperties = {\n opacity: mergedHidden ? 0 : 1,\n height: mergedHidden ? 0 : undefined,\n overflowY: mergedHidden ? 'hidden' : undefined,\n order,\n pointerEvents: mergedHidden ? 'none' : undefined,\n position: mergedHidden ? 'absolute' : undefined,\n };\n return (\n <ResizeObserver\n onResize={({ offsetWidth }: ResizeInfo) =>\n registerSize(itemKey, offsetWidth)\n }\n >\n <div\n className={cn(prefixCls, className)}\n style={overflowStyle}\n aria-hidden={mergedHidden || undefined}\n >\n {children}\n </div>\n </ResizeObserver>\n );\n}\n\nexport interface FixedOverflowProps<T> {\n prefixCls?: string;\n data: T[];\n renderItem: (item: T, info: { index: number }) => React.ReactNode;\n itemKey: (item: T) => React.Key;\n renderRest: (omittedItems: T[]) => React.ReactNode;\n gap?: number;\n className?: string;\n onVisibleChange?: (count: number) => void;\n}\n\nconst ITEM_WIDTH = 10;\n// rest 节点的固定 React key。假设调用方传入的 itemKey 不会返回此常量\n// (ald 内部 Select 的 itemKey 取 value/key 字段,不会等于这个字符串)。\nconst REST_KEY: React.Key = '__OVERFLOW_REST__';\n\nfunction OverflowInner<T>(\n props: FixedOverflowProps<T>,\n ref: React.ForwardedRef<HTMLDivElement>,\n) {\n const {\n prefixCls = 'rc-overflow',\n data,\n renderItem,\n itemKey,\n renderRest,\n gap = 0,\n className,\n onVisibleChange,\n } = props;\n\n const [containerWidth, setContainerWidth] = useState<number | null>(null);\n const mergedContainerWidth = containerWidth || 0;\n const [itemWidths, setItemWidths] = useState<Map<React.Key, number>>(\n () => new Map(),\n );\n const [prevRestWidth, setPrevRestWidth] = useState(0);\n const [restWidth, setRestWidth] = useState(0);\n const [displayCount, setDisplayCount] = useState<number | null>(null);\n const [restReady, setRestReady] = useState(false);\n\n const mergedDisplayCount = displayCount || 0;\n const itemPrefixCls = `${prefixCls}-item`;\n const mergedRestWidth = Math.max(prevRestWidth, restWidth);\n\n const getKey = useCallback(\n (item: T, index: number): React.Key => {\n if (item == null) return index;\n return itemKey(item) ?? index;\n },\n [itemKey],\n );\n\n const mergedData = useMemo(() => {\n if (!data.length) return data;\n return data.slice(\n 0,\n Math.min(data.length, mergedContainerWidth / ITEM_WIDTH),\n );\n }, [data, mergedContainerWidth]);\n\n const omittedItems = useMemo(\n () => data.slice(mergedDisplayCount + 1),\n [data, mergedDisplayCount],\n );\n\n const updateDisplayCount = (count: number, notReady?: boolean) => {\n // === BUG FIX ===\n // 不论 displayCount 是否变化,只要本次是 ready 路径,立即把 restReady /\n // onVisibleChange 推到位。原版在 displayCount===count 时早返回,会跳过\n // 这两步,造成 restReady 卡死在 false。\n if (!notReady) {\n setRestReady(count < data.length - 1);\n onVisibleChange?.(count);\n }\n if (displayCount !== count) {\n setDisplayCount(count);\n }\n };\n\n const registerSize = useCallback((key: React.Key, width: number | null) => {\n setItemWidths((origin) => {\n const clone = new Map(origin);\n if (width === null) clone.delete(key);\n else clone.set(key, width);\n return clone;\n });\n }, []);\n\n const registerRestSize = useCallback(\n (_key: React.Key, width: number | null) => {\n if (width === null) return;\n setRestWidth((prev) => {\n setPrevRestWidth(prev);\n return width;\n });\n },\n [],\n );\n\n const onOverflowResize = (_: ResizeInfo, element: HTMLElement) => {\n setContainerWidth(element.clientWidth);\n };\n\n // 故意不加依赖数组:测量回路依赖每次渲染都重跑——itemWidths 变 → 重算 displayCount\n // → 触发再渲染 → 再测量。加 deps 会破坏 rc-overflow 原版的测量-更新循环。\n useLayoutEffect(() => {\n if (!mergedContainerWidth || !mergedData) return;\n const len = mergedData.length;\n const lastIndex = len - 1;\n if (!len) {\n updateDisplayCount(0);\n return;\n }\n let totalWidth = 0;\n const getItemWidth = (index: number): number | undefined =>\n itemWidths.get(getKey(mergedData[index], index));\n for (let i = 0; i < len; i += 1) {\n const currentItemWidth = getItemWidth(i);\n if (currentItemWidth === undefined) {\n // 半测量:先把 displayCount 推到 i-1,但不动 restReady(notReady=true)。\n updateDisplayCount(i - 1, true);\n return;\n }\n totalWidth += currentItemWidth;\n if (\n (lastIndex === 0 && totalWidth <= mergedContainerWidth) ||\n (i === lastIndex - 1 &&\n totalWidth + (getItemWidth(lastIndex) ?? 0) + lastIndex * gap <=\n mergedContainerWidth)\n ) {\n // 全部塞得下\n updateDisplayCount(lastIndex);\n return;\n }\n if (totalWidth + mergedRestWidth + (i + 1) * gap > mergedContainerWidth) {\n // 当前这个塞不下了,需要展示 \"+N\"\n updateDisplayCount(i - 1);\n return;\n }\n }\n });\n\n const displayRest = restReady && !!omittedItems.length;\n\n return (\n <ResizeObserver onResize={onOverflowResize} disabled={!data.length}>\n <div className={cn(prefixCls, className)} ref={ref}>\n {mergedData.map((item, index) => {\n const key = getKey(item, index);\n return (\n <InternalItem\n key={key}\n prefixCls={itemPrefixCls}\n display={index <= mergedDisplayCount}\n order={index}\n itemKey={key}\n registerSize={registerSize}\n >\n {renderItem(item, { index })}\n </InternalItem>\n );\n })}\n <InternalItem\n prefixCls={itemPrefixCls}\n display={displayRest}\n order={displayRest ? mergedDisplayCount : Number.MAX_SAFE_INTEGER}\n itemKey={REST_KEY}\n registerSize={registerRestSize}\n className={`${itemPrefixCls}-rest`}\n >\n {renderRest(omittedItems)}\n </InternalItem>\n </div>\n </ResizeObserver>\n );\n}\n\nconst FixedOverflow = forwardRef(OverflowInner) as <T>(\n props: FixedOverflowProps<T> & { ref?: React.Ref<HTMLDivElement> },\n) => React.ReactElement;\n\nexport default FixedOverflow;\n"],"mappings":"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"}
@@ -102,6 +102,7 @@ function MultipleSelector(props) {
102
102
  className: cn({ "beta-ald-select-selector-overflow-hidden": showItemIndex === -1 && displayValues.length === 1 }),
103
103
  renderRest,
104
104
  itemKey,
105
+ gap,
105
106
  onVisibleChange
106
107
  }),
107
108
  showResponsiveSelectedSection && /* @__PURE__ */ jsx(MultipleResponsiveSelectedSection, {
@@ -1 +1 @@
1
- {"version":3,"file":"MultipleSelector.js","names":[],"sources":["../../../src/Select/Selector/MultipleSelector.tsx"],"sourcesContent":["import React, { RefObject, useEffect, useMemo, useState } from 'react';\nimport { SelectorProps } from './index';\nimport Tag from '../../Tag';\nimport { DisplayValueType, RawValueType } from '../interface';\nimport {\n CustomTagProps,\n isMultiple,\n isResponsive,\n isShowSelectedSection,\n} from '../BaseSelect';\nimport ScrollArea from '../../ScrollArea';\nimport { cn } from '../../lib/utils';\nimport _ from 'lodash';\n// 用 ald 内部 fork 的 FixedOverflow 替代 rc-overflow。\n// 原因:rc-overflow 1.5 的 updateDisplayCount 在 displayCount===count 时早返回,\n// 会跳过 setRestReady,导致 modal 首开等场景下半测量阶段把 displayCount 提前\n// 推到「最终值 N」后,restReady 卡在 false → \"+N\" 节点 opacity:0 不可见。\n// FixedOverflow 把 setRestReady/onVisibleChange 上移到 early-return 之前,\n// 其它逻辑 1:1 复刻 rc-overflow 的 responsive 分支。\nimport Overflow from './FixedOverflow';\nimport MultipleResponsiveSelectedSection from './MultipleResponsiveSelectedSection';\nimport { RefTriggerProps } from '../SelectTrigger';\nconst overflowPrefixCls = 'beta-ald-select-selector-overflow';\nconst tagHeight = 20;\nconst gap = 4;\ninterface MultipleSelectorProps extends SelectorProps {\n // Event\n onRemove: (value: DisplayValueType) => void;\n onToggleOpen: (open?: boolean) => void;\n tagRender?: (props: CustomTagProps, isPreview?: boolean) => React.ReactNode;\n maxTagPlaceholder?:\n | React.ReactNode\n | ((omittedValues: DisplayValueType[]) => React.ReactNode);\n dropdownRef: RefObject<RefTriggerProps>;\n}\nconst onPreventMouseDown = (event: React.MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n};\n\nfunction itemKey(value: DisplayValueType): React.Key {\n return (value.key ?? value.value) || '';\n}\n\nexport default function MultipleSelector(props: MultipleSelectorProps) {\n const {\n displayValues,\n tagRender,\n onRemove,\n onToggleOpen,\n mode,\n disabled,\n maxTagPlaceholder,\n showResponsiveSelectedSection,\n dropdownRef,\n suffixIcon,\n onOverflowCollapsedChange,\n } = props;\n const innerMaxTagPlaceholder = (omittedValues: DisplayValueType[]) => {\n return `+ ${\n omittedValues.length === displayValues.length\n ? omittedValues.length - 1\n : omittedValues.length\n }`;\n };\n const [showItemIndex, setShowItemIndex] = useState(0);\n const isCollapsed = showItemIndex === -1 && displayValues.length > 0;\n useEffect(() => {\n onOverflowCollapsedChange?.(isCollapsed);\n }, [isCollapsed, onOverflowCollapsedChange]);\n const customizeRenderSelector = (\n value: RawValueType | undefined,\n content: React.ReactNode,\n itemDisabled: boolean,\n closable?: boolean,\n onClose?: (event?: React.MouseEvent) => void,\n isPreview?: boolean,\n uniqueKey?: React.Key,\n ) => {\n const onMouseDown = (e: React.MouseEvent) => {\n onPreventMouseDown(e);\n };\n\n return (\n <span\n className=\"beta-ald-select-custom-tag-render-wrapper\"\n onMouseDown={onMouseDown}\n key={uniqueKey ?? value}\n >\n {tagRender?.(\n {\n label: content,\n value,\n disabled: itemDisabled,\n closable: isPreview ? false : closable ?? false,\n onClose: onClose ?? (() => {}),\n },\n isPreview,\n )}\n </span>\n );\n };\n const defaultRenderSelector = (\n item: DisplayValueType | undefined,\n content: React.ReactNode,\n itemDisabled: boolean,\n closable?: boolean,\n onClose?: React.MouseEventHandler,\n isPreview?: boolean,\n uniqueKey?: React.Key,\n ) => (\n <Tag\n disabled={itemDisabled}\n key={uniqueKey ?? item?.value}\n size=\"small\"\n closable={isPreview ? false : closable}\n onClose={(e) => {\n onPreventMouseDown(e);\n onClose?.(e);\n }}\n >\n {content}\n </Tag>\n );\n const isResponsiveMode = isResponsive(mode);\n const showSelectedSection = isShowSelectedSection(mode);\n const renderItem = (valueItem: DisplayValueType, index?: number) => {\n const { disabled: itemDisabled, label, value } = valueItem;\n const closable = !disabled && !itemDisabled;\n let isPreview = !showResponsiveSelectedSection;\n if (!isResponsiveMode) {\n isPreview = false;\n }\n if (!showSelectedSection) {\n isPreview = false;\n }\n if (disabled) {\n isPreview = true;\n }\n const displayLabel: React.ReactNode = label;\n\n const onClose = (event?: React.MouseEvent) => {\n if (event) {\n event.stopPropagation();\n }\n onRemove(valueItem);\n };\n if (_.isNil(value)) {\n return null;\n }\n\n // 生成唯一的 key,如果 value 可能重复,使用 value + index 组合\n const uniqueKey =\n valueItem.key ??\n (value !== undefined && value !== null\n ? `${value}-${index ?? ''}`\n : `item-${index ?? ''}`);\n\n return typeof tagRender === 'function'\n ? customizeRenderSelector(\n value,\n displayLabel,\n !!itemDisabled,\n closable,\n onClose,\n isPreview,\n uniqueKey,\n )\n : defaultRenderSelector(\n valueItem,\n displayLabel,\n !!itemDisabled,\n closable,\n onClose,\n isPreview,\n uniqueKey,\n );\n };\n\n const renderRest = (omittedValues: DisplayValueType[]) => {\n if (displayValues.length === 1) {\n return null;\n }\n\n const content =\n typeof maxTagPlaceholder === 'function'\n ? maxTagPlaceholder(\n omittedValues.length === displayValues.length\n ? omittedValues.slice(1, omittedValues.length)\n : omittedValues,\n )\n : innerMaxTagPlaceholder(\n omittedValues.length === displayValues.length\n ? omittedValues.slice(1, omittedValues.length)\n : omittedValues,\n );\n\n return typeof maxTagPlaceholder === 'function'\n ? content\n : defaultRenderSelector({ title: content }, content, false);\n };\n const onVisibleChange = (visibleCount: number) => {\n setShowItemIndex(visibleCount);\n };\n const maxHeight = useMemo(() => {\n if (isMultiple(mode)) {\n let maxRows: number | undefined;\n if (typeof mode === 'object') {\n maxRows = mode.maxRows;\n }\n if (!maxRows) {\n // 2.5行高+2行间距\n return 2.5 * tagHeight + 2 * gap;\n } else {\n // 总行高+总行间距\n return maxRows * tagHeight + (maxRows - 1) * gap;\n }\n }\n\n return undefined;\n }, [mode]);\n if (isResponsiveMode) {\n return (\n <div className=\"beta-ald-select-selector beta-ald-select-selector-multiple-responsive\">\n {showItemIndex === -1 && displayValues.length > 0 && (\n <div className=\"beta-ald-select-selector-overflow-item-first\">\n {renderItem(displayValues[0], 0)}\n </div>\n )}\n <Overflow\n prefixCls={overflowPrefixCls}\n data={displayValues}\n renderItem={(item, info) => renderItem(item, info?.index)}\n className={cn({\n 'beta-ald-select-selector-overflow-hidden':\n showItemIndex === -1 && displayValues.length === 1,\n })}\n renderRest={renderRest}\n itemKey={itemKey}\n onVisibleChange={onVisibleChange}\n />\n {showResponsiveSelectedSection && (\n <MultipleResponsiveSelectedSection\n displayValues={displayValues}\n renderItem={renderItem}\n maxHeight={maxHeight}\n suffixIcon={suffixIcon}\n onToggleOpen={onToggleOpen}\n dropdownRef={dropdownRef}\n />\n )}\n </div>\n );\n }\n\n return (\n <ScrollArea\n innerClassName=\"beta-ald-select-selector-multiple-default-inner\"\n className=\"beta-ald-select-selector beta-ald-select-selector-multiple-default\"\n innerStyle={{\n maxHeight: maxHeight,\n }}\n >\n <div className=\"beta-ald-select-selector-multiple-default-tags\">\n {displayValues.map((item, index) => renderItem(item, index))}\n </div>\n </ScrollArea>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"MultipleSelector.js","names":[],"sources":["../../../src/Select/Selector/MultipleSelector.tsx"],"sourcesContent":["import React, { RefObject, useEffect, useMemo, useState } from 'react';\nimport { SelectorProps } from './index';\nimport Tag from '../../Tag';\nimport { DisplayValueType, RawValueType } from '../interface';\nimport {\n CustomTagProps,\n isMultiple,\n isResponsive,\n isShowSelectedSection,\n} from '../BaseSelect';\nimport ScrollArea from '../../ScrollArea';\nimport { cn } from '../../lib/utils';\nimport _ from 'lodash';\n// 用 ald 内部 fork 的 FixedOverflow 替代 rc-overflow。\n// 原因:rc-overflow 1.5 的 updateDisplayCount 在 displayCount===count 时早返回,\n// 会跳过 setRestReady,导致 modal 首开等场景下半测量阶段把 displayCount 提前\n// 推到「最终值 N」后,restReady 卡在 false → \"+N\" 节点 opacity:0 不可见。\n// FixedOverflow 把 setRestReady/onVisibleChange 上移到 early-return 之前,\n// 其它逻辑 1:1 复刻 rc-overflow 的 responsive 分支。\nimport Overflow from './FixedOverflow';\nimport MultipleResponsiveSelectedSection from './MultipleResponsiveSelectedSection';\nimport { RefTriggerProps } from '../SelectTrigger';\nconst overflowPrefixCls = 'beta-ald-select-selector-overflow';\nconst tagHeight = 20;\nconst gap = 4;\ninterface MultipleSelectorProps extends SelectorProps {\n // Event\n onRemove: (value: DisplayValueType) => void;\n onToggleOpen: (open?: boolean) => void;\n tagRender?: (props: CustomTagProps, isPreview?: boolean) => React.ReactNode;\n maxTagPlaceholder?:\n | React.ReactNode\n | ((omittedValues: DisplayValueType[]) => React.ReactNode);\n dropdownRef: RefObject<RefTriggerProps>;\n}\nconst onPreventMouseDown = (event: React.MouseEvent) => {\n event.preventDefault();\n event.stopPropagation();\n};\n\nfunction itemKey(value: DisplayValueType): React.Key {\n return (value.key ?? value.value) || '';\n}\n\nexport default function MultipleSelector(props: MultipleSelectorProps) {\n const {\n displayValues,\n tagRender,\n onRemove,\n onToggleOpen,\n mode,\n disabled,\n maxTagPlaceholder,\n showResponsiveSelectedSection,\n dropdownRef,\n suffixIcon,\n onOverflowCollapsedChange,\n } = props;\n const innerMaxTagPlaceholder = (omittedValues: DisplayValueType[]) => {\n return `+ ${\n omittedValues.length === displayValues.length\n ? omittedValues.length - 1\n : omittedValues.length\n }`;\n };\n const [showItemIndex, setShowItemIndex] = useState(0);\n const isCollapsed = showItemIndex === -1 && displayValues.length > 0;\n useEffect(() => {\n onOverflowCollapsedChange?.(isCollapsed);\n }, [isCollapsed, onOverflowCollapsedChange]);\n const customizeRenderSelector = (\n value: RawValueType | undefined,\n content: React.ReactNode,\n itemDisabled: boolean,\n closable?: boolean,\n onClose?: (event?: React.MouseEvent) => void,\n isPreview?: boolean,\n uniqueKey?: React.Key,\n ) => {\n const onMouseDown = (e: React.MouseEvent) => {\n onPreventMouseDown(e);\n };\n\n return (\n <span\n className=\"beta-ald-select-custom-tag-render-wrapper\"\n onMouseDown={onMouseDown}\n key={uniqueKey ?? value}\n >\n {tagRender?.(\n {\n label: content,\n value,\n disabled: itemDisabled,\n closable: isPreview ? false : closable ?? false,\n onClose: onClose ?? (() => {}),\n },\n isPreview,\n )}\n </span>\n );\n };\n const defaultRenderSelector = (\n item: DisplayValueType | undefined,\n content: React.ReactNode,\n itemDisabled: boolean,\n closable?: boolean,\n onClose?: React.MouseEventHandler,\n isPreview?: boolean,\n uniqueKey?: React.Key,\n ) => (\n <Tag\n disabled={itemDisabled}\n key={uniqueKey ?? item?.value}\n size=\"small\"\n closable={isPreview ? false : closable}\n onClose={(e) => {\n onPreventMouseDown(e);\n onClose?.(e);\n }}\n >\n {content}\n </Tag>\n );\n const isResponsiveMode = isResponsive(mode);\n const showSelectedSection = isShowSelectedSection(mode);\n const renderItem = (valueItem: DisplayValueType, index?: number) => {\n const { disabled: itemDisabled, label, value } = valueItem;\n const closable = !disabled && !itemDisabled;\n let isPreview = !showResponsiveSelectedSection;\n if (!isResponsiveMode) {\n isPreview = false;\n }\n if (!showSelectedSection) {\n isPreview = false;\n }\n if (disabled) {\n isPreview = true;\n }\n const displayLabel: React.ReactNode = label;\n\n const onClose = (event?: React.MouseEvent) => {\n if (event) {\n event.stopPropagation();\n }\n onRemove(valueItem);\n };\n if (_.isNil(value)) {\n return null;\n }\n\n // 生成唯一的 key,如果 value 可能重复,使用 value + index 组合\n const uniqueKey =\n valueItem.key ??\n (value !== undefined && value !== null\n ? `${value}-${index ?? ''}`\n : `item-${index ?? ''}`);\n\n return typeof tagRender === 'function'\n ? customizeRenderSelector(\n value,\n displayLabel,\n !!itemDisabled,\n closable,\n onClose,\n isPreview,\n uniqueKey,\n )\n : defaultRenderSelector(\n valueItem,\n displayLabel,\n !!itemDisabled,\n closable,\n onClose,\n isPreview,\n uniqueKey,\n );\n };\n\n const renderRest = (omittedValues: DisplayValueType[]) => {\n if (displayValues.length === 1) {\n return null;\n }\n\n const content =\n typeof maxTagPlaceholder === 'function'\n ? maxTagPlaceholder(\n omittedValues.length === displayValues.length\n ? omittedValues.slice(1, omittedValues.length)\n : omittedValues,\n )\n : innerMaxTagPlaceholder(\n omittedValues.length === displayValues.length\n ? omittedValues.slice(1, omittedValues.length)\n : omittedValues,\n );\n\n return typeof maxTagPlaceholder === 'function'\n ? content\n : defaultRenderSelector({ title: content }, content, false);\n };\n const onVisibleChange = (visibleCount: number) => {\n setShowItemIndex(visibleCount);\n };\n const maxHeight = useMemo(() => {\n if (isMultiple(mode)) {\n let maxRows: number | undefined;\n if (typeof mode === 'object') {\n maxRows = mode.maxRows;\n }\n if (!maxRows) {\n // 2.5行高+2行间距\n return 2.5 * tagHeight + 2 * gap;\n } else {\n // 总行高+总行间距\n return maxRows * tagHeight + (maxRows - 1) * gap;\n }\n }\n\n return undefined;\n }, [mode]);\n if (isResponsiveMode) {\n return (\n <div className=\"beta-ald-select-selector beta-ald-select-selector-multiple-responsive\">\n {showItemIndex === -1 && displayValues.length > 0 && (\n <div className=\"beta-ald-select-selector-overflow-item-first\">\n {renderItem(displayValues[0], 0)}\n </div>\n )}\n <Overflow\n prefixCls={overflowPrefixCls}\n data={displayValues}\n renderItem={(item, info) => renderItem(item, info?.index)}\n className={cn({\n 'beta-ald-select-selector-overflow-hidden':\n showItemIndex === -1 && displayValues.length === 1,\n })}\n renderRest={renderRest}\n itemKey={itemKey}\n gap={gap}\n onVisibleChange={onVisibleChange}\n />\n {showResponsiveSelectedSection && (\n <MultipleResponsiveSelectedSection\n displayValues={displayValues}\n renderItem={renderItem}\n maxHeight={maxHeight}\n suffixIcon={suffixIcon}\n onToggleOpen={onToggleOpen}\n dropdownRef={dropdownRef}\n />\n )}\n </div>\n );\n }\n\n return (\n <ScrollArea\n innerClassName=\"beta-ald-select-selector-multiple-default-inner\"\n className=\"beta-ald-select-selector beta-ald-select-selector-multiple-default\"\n innerStyle={{\n maxHeight: maxHeight,\n }}\n >\n <div className=\"beta-ald-select-selector-multiple-default-tags\">\n {displayValues.map((item, index) => renderItem(item, index))}\n </div>\n </ScrollArea>\n );\n}\n"],"mappings":"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"}