@aloudata/aloudata-design 3.0.25 → 3.0.27
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/Button/index.js +4 -10
- package/dist/Button/index.js.map +1 -1
- package/dist/Checkbox/index.js +2 -8
- package/dist/Checkbox/index.js.map +1 -1
- package/dist/Collapse/index.js +22 -68
- package/dist/Collapse/index.js.map +1 -1
- package/dist/Dropdown/index.js +12 -2
- package/dist/Dropdown/index.js.map +1 -1
- package/dist/Input/components/Input/index.js +5 -11
- package/dist/Input/components/Input/index.js.map +1 -1
- package/dist/Input/components/TextArea/index.js +1 -7
- package/dist/Input/components/TextArea/index.js.map +1 -1
- package/dist/InputNumber/index.js +2 -8
- package/dist/InputNumber/index.js.map +1 -1
- package/dist/Modal/index.js +13 -0
- package/dist/Modal/index.js.map +1 -1
- package/dist/Pagination/PageSizeChanger.d.ts +0 -1
- package/dist/Pagination/PageSizeChanger.js +2 -3
- package/dist/Pagination/PageSizeChanger.js.map +1 -1
- package/dist/Pagination/index.js +19 -33
- package/dist/Pagination/index.js.map +1 -1
- package/dist/Pagination/types.d.ts +0 -3
- package/dist/Radio/components/Radio/index.js +1 -1
- package/dist/Radio/components/Radio/index.js.map +1 -1
- package/dist/Select/BaseSelect.js +12 -12
- package/dist/Select/BaseSelect.js.map +1 -1
- package/dist/Steps/index.js +14 -66
- package/dist/Steps/index.js.map +1 -1
- package/dist/Switch/index.js +1 -8
- package/dist/Switch/index.js.map +1 -1
- package/dist/Table/components/Cell.js +3 -8
- package/dist/Table/components/Cell.js.map +1 -1
- package/dist/Table/components/ExpandCell.js +2 -6
- package/dist/Table/components/ExpandCell.js.map +1 -1
- package/dist/Table/components/Footer/index.js +1 -2
- package/dist/Table/components/Footer/index.js.map +1 -1
- package/dist/Table/components/Header.js +18 -26
- package/dist/Table/components/Header.js.map +1 -1
- package/dist/Table/hooks/useFixed.js +5 -1
- package/dist/Table/hooks/useFixed.js.map +1 -1
- package/dist/Table/hooks/useRowSelection.js +7 -14
- package/dist/Table/hooks/useRowSelection.js.map +1 -1
- package/dist/Table/index.js +2 -8
- package/dist/Table/index.js.map +1 -1
- package/dist/Tabs/index.d.ts +1 -1
- package/dist/Tabs/index.js +11 -91
- package/dist/Tabs/index.js.map +1 -1
- package/dist/aloudata-design.css +1 -1
- package/dist/locale/default.d.ts +0 -6
- package/dist/locale/en_US.d.ts +0 -6
- package/dist/locale/en_US.js +0 -6
- package/dist/locale/en_US.js.map +1 -1
- package/dist/locale/zh_CN.d.ts +0 -6
- package/dist/locale/zh_CN.js +0 -6
- package/dist/locale/zh_CN.js.map +1 -1
- package/dist/theme/contract/tokenOutputContract.d.ts +1 -1
- package/dist/theme/contract/tokenOutputContract.js +0 -4
- package/dist/theme/contract/tokenOutputContract.js.map +1 -1
- package/dist/theme/runtime/colorValueMode/generated/darkBaselineDeclarations.d.ts +1 -1
- package/dist/theme/runtime/colorValueMode/generated/darkBaselineDeclarations.js +0 -3
- package/dist/theme/runtime/colorValueMode/generated/darkBaselineDeclarations.js.map +1 -1
- package/dist/theme/runtime/colorValueMode/generated/v3BaselineDeclarations.d.ts +1 -1
- package/dist/theme/runtime/colorValueMode/generated/v3BaselineDeclarations.js +0 -3
- package/dist/theme/runtime/colorValueMode/generated/v3BaselineDeclarations.js.map +1 -1
- package/dist/theme/runtime/themeToCssVars.js +0 -3
- package/dist/theme/runtime/themeToCssVars.js.map +1 -1
- package/package.json +1 -1
- package/dist/theme/contract/controlStateColorArtifact.d.ts +0 -73
- package/dist/theme/contract/controlStateColorArtifact.js +0 -2
- package/dist/theme/contract/focusRingArtifact.d.ts +0 -51
- package/dist/theme/contract/focusRingArtifact.js +0 -2
package/dist/Modal/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/Modal/index.tsx"],"sourcesContent":["import * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { hideOthers } from 'aria-hidden';\nimport React, {\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { createRoot } from 'react-dom/client';\nimport Button, { ButtonType, IButtonProps } from '../Button';\nimport {\n AttentionTriangleLightLine,\n CheckCircleLightLine,\n CloseLLine,\n InformationCircleLightLine,\n} from '../Icon';\nimport IconButton from '../IconButton';\nimport ScrollArea from '../ScrollArea';\nimport {\n FLOATING_LAYER_BASE_Z_INDEX,\n FLOATING_LAYER_STEP,\n FloatingLayerProvider,\n} from '../_utils/floatingLayer';\nimport {\n ModalLayerProvider,\n useModalLayer,\n} from '../_utils/overlayCoordinator';\nimport { LocaleContext, getTranslator } from '../locale/default';\nimport { cn } from '../lib/utils';\n\nexport const destroyFns: Array<() => void> = [];\n\nexport interface ModalProps {\n open?: boolean;\n onOk?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n onCancel?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n afterClose?: () => void;\n title?: React.ReactNode;\n subTitle?: React.ReactNode;\n icon?: React.ReactElement;\n width?: number | string;\n footer?: React.ReactNode | null;\n okText?: React.ReactNode;\n cancelText?: React.ReactNode;\n okButtonProps?: IButtonProps;\n cancelButtonProps?: IButtonProps;\n okType?: ButtonType;\n confirmLoading?: boolean;\n maskClosable?: boolean;\n closable?: boolean;\n closeIcon?: React.ReactNode;\n centered?: boolean;\n destroyOnClose?: boolean;\n className?: string;\n /** Pass through to the modal content root for automated testing. */\n 'data-testid'?: string;\n /** Pass through to the modal content root for accessibility and automated testing. */\n 'aria-label'?: string;\n /** Applied to the outer wrap layer (matches antd wrapClassName behavior) */\n wrapClassName?: string;\n style?: React.CSSProperties;\n bodyStyle?: React.CSSProperties;\n zIndex?: number;\n children?: React.ReactNode;\n paddingLess?: boolean;\n virtualScrollBar?: boolean;\n hideHeaderBottomBorder?: boolean;\n responsiveBounds?: boolean;\n fullscreen?: boolean;\n keyboard?: boolean;\n afterOpenChange?: (open: boolean) => void;\n getContainer?: (() => HTMLElement) | false;\n /** @internal used by static methods to pass modal type for icon styling */\n _modalType?: string;\n}\n\ninterface OriginModalProps extends ModalProps {\n onTopChange?: (isTop: boolean) => void;\n}\n\nexport interface ModalFuncProps {\n title?: React.ReactNode;\n subTitle?: React.ReactNode;\n content?: React.ReactNode;\n icon?: React.ReactElement;\n okText?: React.ReactNode;\n cancelText?: React.ReactNode;\n okButtonProps?: IButtonProps;\n cancelButtonProps?: IButtonProps;\n okType?: ButtonType;\n onOk?: (...args: any[]) => any;\n onCancel?: (...args: any[]) => any;\n width?: number | string;\n className?: string;\n /** @deprecated Use `className` instead. Preserved for antd v4 compat. */\n wrapClassName?: string;\n closable?: boolean;\n type?: 'info' | 'success' | 'error' | 'warn' | 'warning' | 'confirm';\n centered?: boolean;\n maskClosable?: boolean;\n}\n\nconst DEFAULT_WIDTH = 552;\nconst modalEscapeEvents = new WeakSet<KeyboardEvent>();\n\nfunction shouldCancelTopModal(event: KeyboardEvent) {\n return (\n !event.cancelBubble &&\n (!event.defaultPrevented || modalEscapeEvents.has(event))\n );\n}\n\nfunction ModalContentProviders({\n layerId,\n floatingLevel,\n children,\n}: {\n layerId: number;\n floatingLevel: number;\n children: React.ReactNode;\n}) {\n return (\n <ModalLayerProvider id={layerId}>\n <FloatingLayerProvider value={floatingLevel}>\n {children}\n </FloatingLayerProvider>\n </ModalLayerProvider>\n );\n}\n\nconst ModalTitle = (\n { icon, title, subTitle }: Pick<ModalProps, 'icon' | 'title' | 'subTitle'>,\n type?: string,\n) => (\n <div className=\"ald-modal-title-container tw-flex tw-items-center tw-gap-4\">\n {icon && (\n <div\n className={cn(\n 'ald-modal-icon-container tw-grid tw-size-10 tw-shrink-0 tw-place-items-center tw-rounded-[var(--global-grid-250)]',\n type === 'info' &&\n 'ald-modal-cion-info-container tw-bg-[var(--background-informative-muted)]',\n type === 'success' &&\n 'ald-modal-cion-success-container tw-bg-[var(--background-positive-muted)]',\n type === 'warning' &&\n 'ald-modal-cion-warning-container tw-bg-[var(--background-warning-muted)]',\n type === 'warn' &&\n 'ald-modal-cion-warning-container tw-bg-[var(--background-warning-muted)]',\n type === 'error' &&\n 'ald-modal-cion-error-container tw-bg-[var(--background-negative-muted)]',\n type === 'confirm' &&\n 'ald-modal-cion-confirm-container tw-bg-[var(--background-brand-muted)]',\n )}\n >\n {icon}\n </div>\n )}\n <div className=\"ald-modal-text-container\">\n {title && (\n <div\n className={cn(\n 'ald-modal-text-title tw-text-lg tw-font-semibold tw-leading-7 tw-text-[var(--content-primary)]',\n !subTitle && 'ald-modal-text-title-only tw-text-xl',\n )}\n >\n {title}\n </div>\n )}\n {subTitle && (\n <div className=\"ald-modal-text-sub-title tw-mt-1 tw-text-xs tw-leading-4 tw-text-[var(--content-secondary)]\">\n {subTitle}\n </div>\n )}\n </div>\n </div>\n);\n\nfunction getIcon(\n type: 'info' | 'success' | 'error' | 'warn' | 'warning' | 'confirm',\n) {\n if (type === 'success')\n return (\n <CheckCircleLightLine\n fill=\"var(--content-inverted-primary)\"\n color=\"var(--background-positive-strong)\"\n size={24}\n />\n );\n if (type === 'error')\n return (\n <AttentionTriangleLightLine\n color=\"var(--background-negative-strong)\"\n fill=\"var(--content-inverted-primary)\"\n size={24}\n />\n );\n if (type === 'warning' || type === 'warn')\n return (\n <AttentionTriangleLightLine\n color=\"var(--background-warning-strong)\"\n size={24}\n />\n );\n return (\n <InformationCircleLightLine\n size={24}\n color=\"var(--action-primary-normal)\"\n />\n );\n}\n\nfunction OriginModal(props: OriginModalProps) {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n const {\n className,\n 'data-testid': dataTestId,\n 'aria-label': ariaLabel,\n children,\n okType = 'primary',\n width,\n closeIcon,\n subTitle,\n okButtonProps = {},\n cancelButtonProps = {},\n okText = t.Modal.sure,\n cancelText = t.Modal.cancel,\n icon,\n title,\n paddingLess,\n responsiveBounds,\n hideHeaderBottomBorder,\n virtualScrollBar,\n style,\n maskClosable = false,\n fullscreen,\n open = false,\n onOk,\n onCancel,\n footer,\n confirmLoading,\n closable = true,\n zIndex = 1000,\n bodyStyle,\n keyboard = true,\n afterOpenChange,\n wrapClassName,\n _modalType,\n onTopChange,\n } = props;\n\n const prevOpenRef = useRef(open);\n const contentRef = useRef<HTMLDivElement>(null);\n const modalLayer = useModalLayer(open, zIndex);\n const { id: modalLayerId, maskZIndex, contentZIndex, isTop } = modalLayer;\n const nextFloatingLevel =\n (maskZIndex - FLOATING_LAYER_BASE_Z_INDEX) / FLOATING_LAYER_STEP + 1;\n\n useLayoutEffect(() => {\n onTopChange?.(isTop);\n }, [isTop, onTopChange]);\n\n useEffect(() => {\n if (prevOpenRef.current !== open) {\n prevOpenRef.current = open;\n afterOpenChange?.(open);\n }\n }, [open, afterOpenChange]);\n\n // ---- modal={false} 补偿:aria-hidden(屏幕阅读器只感知弹窗) ----\n useEffect(() => {\n if (!open || !isTop || !contentRef.current) return;\n return hideOthers(contentRef.current);\n }, [isTop, open]);\n\n // ---- modal={false} 补偿:Tab 焦点循环 ----\n useEffect(() => {\n if (!open || !isTop || !contentRef.current) return;\n const container = contentRef.current;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key !== 'Tab') return;\n const focusable = container.querySelectorAll<HTMLElement>(\n 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"]):not([disabled])',\n );\n if (focusable.length === 0) return;\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n\n if (e.shiftKey) {\n if (\n document.activeElement === first ||\n !container.contains(document.activeElement)\n ) {\n e.preventDefault();\n last.focus();\n }\n } else {\n if (\n document.activeElement === last ||\n !container.contains(document.activeElement)\n ) {\n e.preventDefault();\n first.focus();\n }\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [isTop, open]);\n\n useEffect(() => {\n if (!open || !isTop || !keyboard) return;\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key !== 'Escape') return;\n // Radix observes Escape during document capture, so child overlays can\n // only finish their own propagation handling later in the event cycle.\n queueMicrotask(() => {\n if (shouldCancelTopModal(event)) {\n onCancel?.({} as React.MouseEvent<HTMLButtonElement>);\n }\n });\n };\n\n window.addEventListener('keydown', handleEscape, true);\n return () => window.removeEventListener('keydown', handleEscape, true);\n }, [isTop, keyboard, onCancel, open]);\n\n const responsiveBoundsStyle = useMemo(() => {\n if (!responsiveBounds) return {};\n return {\n width: 'calc(100% - 160px)',\n maxWidth: '1680px',\n minWidth: '1280px',\n height: 'calc(100% - 48px)',\n maxHeight: '900px',\n minHeight: '640px',\n };\n }, [responsiveBounds]);\n\n const mergedOkProps = { loading: confirmLoading, ...okButtonProps };\n\n const renderFooter = () => {\n if (footer === null) return null;\n if (footer)\n return (\n // antd 兼容:antd .ant-modal-footer 使用 text-align:right 让 inline 按钮右对齐,\n // 即使消费方传入 width:100% 的子容器,内部 inline 元素仍能右对齐。\n // 此处同时使用 tw-flex tw-justify-end(flexbox 对齐)和 tw-text-right(继承式对齐)保持兼容。\n <div className=\"ald-modal-footer ant-modal-footer tw-flex tw-items-center tw-justify-end tw-gap-2 tw-border-t tw-border-solid tw-border-[var(--border-default)] tw-bg-[var(--background-default)] tw-px-6 tw-py-3 tw-text-right\">\n {footer}\n </div>\n );\n return (\n <div className=\"ald-modal-footer ant-modal-footer tw-flex tw-justify-end tw-gap-2 tw-border-t tw-border-solid tw-border-[var(--border-default)] tw-px-6 tw-py-4\">\n <Button\n type=\"secondary\"\n size=\"middle\"\n {...cancelButtonProps}\n onClick={onCancel}\n >\n {cancelText}\n </Button>\n <Button type={okType} size=\"middle\" {...mergedOkProps} onClick={onOk}>\n {okText}\n </Button>\n </div>\n );\n };\n\n return (\n <DialogPrimitive.Root open={open} modal={false}>\n <DialogPrimitive.Portal>\n {/* modal={false} 时 DialogPrimitive.Overlay 不渲染,用普通 div 替代 */}\n {isTop && (\n <div\n className=\"ald-modal-mask tw-animate-in tw-fade-in-0 tw-fixed tw-inset-0 tw-bg-[var(--background-inverted)] tw-opacity-45\"\n style={{ zIndex: maskZIndex }}\n onPointerDown={() => {\n if (maskClosable) {\n onCancel?.({} as React.MouseEvent<HTMLButtonElement>);\n }\n }}\n />\n )}\n {/* Centering wrapper — replaces transform centering so consumer CSS (top/left overrides) works */}\n <div\n ref={contentRef}\n {...(!isTop ? { inert: '' } : {})}\n aria-hidden={!isTop || undefined}\n className={cn(\n // antd 兼容:保留 ant-modal-wrap class,消费方 CSS 通过 wrapClassName + :global(.ant-modal) 控制弹窗宽高\n 'ald-modal-wrap ant-modal-wrap tw-pointer-events-none tw-fixed tw-inset-0 tw-flex tw-items-center tw-justify-center',\n wrapClassName,\n )}\n style={{ zIndex: contentZIndex }}\n >\n <DialogPrimitive.Content\n data-testid={dataTestId}\n aria-label={ariaLabel}\n className={cn(\n // antd 兼容:保留 ant-modal class,消费方 CSS 通过 .ant-modal 选择器控制弹窗宽高等样式\n // tw-outline-none:Radix 打开时会聚焦 Content,不抑制 outline 会渲染出蓝色焦点框\n 'ald-modal ant-modal tw-pointer-events-auto tw-box-border tw-flex tw-flex-col tw-overflow-hidden tw-bg-[var(--background-default)] tw-shadow-[var(--elevation-bottom-bottom-lg)] tw-outline-none',\n fullscreen\n ? 'ald-modal-fullscreen tw-fixed tw-inset-0 tw-size-full tw-rounded-none'\n : 'tw-rounded-r-75',\n !fullscreen &&\n 'tw-border tw-border-solid tw-border-[var(--border-default)]',\n paddingLess && 'ald-modal-padding-less',\n virtualScrollBar && 'ald-modal-virtual-scroll-bar',\n hideHeaderBottomBorder && 'ald-modal-hide-header-bottom-border',\n responsiveBounds && 'ald-modal-responsive-bounds',\n className,\n )}\n style={{\n ...(fullscreen\n ? {}\n : {\n width: responsiveBounds\n ? responsiveBoundsStyle.width\n : width || DEFAULT_WIDTH,\n ...responsiveBoundsStyle,\n }),\n ...style,\n }}\n onEscapeKeyDown={(event) => {\n if (!event.defaultPrevented) modalEscapeEvents.add(event);\n event.preventDefault();\n }}\n onPointerDownOutside={(e) => {\n if (maskClosable) {\n onCancel?.({} as React.MouseEvent<HTMLButtonElement>);\n } else {\n e.preventDefault();\n }\n }}\n onInteractOutside={(e) => {\n if (!maskClosable) {\n e.preventDefault();\n }\n }}\n >\n {/* ant-modal-content compat wrapper — matches antd DOM nesting for consumer CSS */}\n <div className=\"ant-modal-content tw-flex tw-h-full tw-flex-col\">\n <ModalContentProviders\n layerId={modalLayerId}\n floatingLevel={nextFloatingLevel}\n >\n {!fullscreen && (\n <div\n className={cn(\n 'ald-modal-header ant-modal-header tw-flex tw-items-start tw-justify-between tw-bg-[var(--background-default)] tw-px-6 tw-py-4',\n !hideHeaderBottomBorder &&\n 'tw-border-b tw-border-solid tw-border-[var(--border-default)]',\n )}\n >\n <DialogPrimitive.Title asChild>\n <div className=\"tw-flex-1\">\n {ModalTitle({ icon, title, subTitle }, _modalType)}\n </div>\n </DialogPrimitive.Title>\n {closable && (\n <DialogPrimitive.Close asChild>\n <span className=\"ant-modal-close\" onClick={onCancel}>\n {closeIcon || (\n <IconButton\n icon={<CloseLLine size={20} />}\n size=\"middle\"\n />\n )}\n </span>\n </DialogPrimitive.Close>\n )}\n </div>\n )}\n {/* Hidden title for accessibility when fullscreen hides the header */}\n {fullscreen && (\n <DialogPrimitive.Title className=\"tw-sr-only\">\n {title}\n </DialogPrimitive.Title>\n )}\n <div\n className={cn(\n 'ald-modal-body ant-modal-body tw-flex-1 tw-text-sm tw-leading-5',\n fullscreen\n ? 'tw-h-full tw-overflow-auto tw-p-0'\n : 'tw-min-h-[130px]',\n !fullscreen &&\n (virtualScrollBar\n ? 'tw-overflow-hidden tw-p-0'\n : 'tw-overflow-auto'),\n !fullscreen &&\n !responsiveBounds &&\n !virtualScrollBar &&\n 'tw-max-h-[68vh]',\n !fullscreen &&\n !paddingLess &&\n !virtualScrollBar &&\n 'tw-p-6',\n )}\n style={bodyStyle}\n >\n {virtualScrollBar ? (\n <ScrollArea\n className=\"ald-modal-body-wrap !tw-h-auto\"\n innerClassName={cn(\n 'ald-modal-body-wrap-inner tw-max-h-[68vh]',\n paddingLess ? 'tw-p-0' : 'tw-px-[23px] tw-py-0',\n )}\n >\n {children}\n </ScrollArea>\n ) : (\n children\n )}\n </div>\n {!fullscreen && renderFooter()}\n </ModalContentProviders>\n </div>\n </DialogPrimitive.Content>\n </div>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n}\n\n// Static method helper\nfunction createStaticModal(\n type: ModalFuncProps['type'],\n props: ModalFuncProps,\n) {\n const focusTarget = document.activeElement as HTMLElement | null;\n const container = document.createElement('div');\n document.body.appendChild(container);\n const root = createRoot(container);\n\n let currentProps = { ...props };\n let destroyed = false;\n let isTop = true;\n\n const destroy = () => {\n if (destroyed) return;\n destroyed = true;\n const shouldRestoreFocus = isTop;\n root.unmount();\n container.remove();\n const idx = destroyFns.indexOf(destroy);\n if (idx >= 0) destroyFns.splice(idx, 1);\n queueMicrotask(() => {\n if (shouldRestoreFocus && focusTarget?.isConnected) focusTarget.focus();\n });\n };\n\n const update = (newProps: Partial<ModalFuncProps>) => {\n currentProps = { ...currentProps, ...newProps };\n render(currentProps);\n };\n\n const isConfirm = type === 'confirm';\n\n const render = (p: ModalFuncProps) => {\n const handleOk = () => {\n p.onOk?.();\n destroy();\n };\n const handleCancel = () => {\n p.onCancel?.();\n destroy();\n };\n\n root.render(\n <OriginModal\n open={true}\n title={p.title}\n subTitle={p.subTitle}\n icon={p.icon || getIcon(type || 'info')}\n onOk={handleOk}\n onCancel={handleCancel}\n okText={p.okText}\n cancelText={p.cancelText}\n okButtonProps={p.okButtonProps}\n cancelButtonProps={p.cancelButtonProps}\n okType={p.okType || (isConfirm ? 'dangerous' : 'primary')}\n width={p.width || DEFAULT_WIDTH}\n className={cn('ald-modal', p.className)}\n closable={p.closable}\n maskClosable={p.maskClosable}\n _modalType={type}\n onTopChange={(nextIsTop) => {\n isTop = nextIsTop;\n }}\n footer={\n isConfirm ? undefined : (\n <Button\n type=\"primary\"\n size=\"middle\"\n {...(p.okButtonProps || {})}\n onClick={handleOk}\n >\n {p.okText || 'OK'}\n </Button>\n )\n }\n >\n {p.content}\n </OriginModal>,\n );\n };\n\n destroyFns.push(destroy);\n render(currentProps);\n\n return { destroy, update };\n}\n\n// Attach static methods\ntype ModalFunc = (props: ModalFuncProps) => {\n destroy: () => void;\n update: (props: Partial<ModalFuncProps>) => void;\n};\n\n// ---------- useModal hook ----------\n\ninterface ModalInstance {\n id: number;\n type: ModalFuncProps['type'];\n props: ModalFuncProps;\n open: boolean;\n}\n\nexport interface ModalApiInstance {\n destroy: () => void;\n update: (newProps: Partial<ModalFuncProps>) => void;\n}\n\nexport interface ModalStaticFunctions {\n info: (props: ModalFuncProps) => ModalApiInstance;\n success: (props: ModalFuncProps) => ModalApiInstance;\n error: (props: ModalFuncProps) => ModalApiInstance;\n warning: (props: ModalFuncProps) => ModalApiInstance;\n confirm: (props: ModalFuncProps) => ModalApiInstance;\n}\n\nfunction useModal(): [ModalStaticFunctions, React.ReactElement] {\n const [modals, setModals] = useState<ModalInstance[]>([]);\n const idCounter = useRef(0);\n\n const removeModal = useCallback((id: number) => {\n setModals((prev) =>\n prev.map((m) => (m.id === id ? { ...m, open: false } : m)),\n );\n // Remove from DOM after animation\n setTimeout(() => {\n setModals((prev) => prev.filter((m) => m.id !== id));\n }, 300);\n }, []);\n\n const updateModal = useCallback(\n (id: number, newProps: Partial<ModalFuncProps>) => {\n setModals((prev) =>\n prev.map((m) =>\n m.id === id ? { ...m, props: { ...m.props, ...newProps } } : m,\n ),\n );\n },\n [],\n );\n\n const openModal = useCallback(\n (type: ModalFuncProps['type'], props: ModalFuncProps): ModalApiInstance => {\n const id = ++idCounter.current;\n const instance: ModalInstance = { id, type, props, open: true };\n setModals((prev) => [...prev, instance]);\n\n return {\n destroy: () => removeModal(id),\n update: (newProps: Partial<ModalFuncProps>) =>\n updateModal(id, newProps),\n };\n },\n [removeModal, updateModal],\n );\n\n const api = useMemo<ModalStaticFunctions>(\n () => ({\n info: (props) => openModal('info', props),\n success: (props) => openModal('success', props),\n error: (props) => openModal('error', props),\n warning: (props) => openModal('warning', props),\n confirm: (props) =>\n openModal('confirm', { ...props, type: props.type || 'confirm' }),\n }),\n [openModal],\n );\n\n const contextHolder = (\n <>\n {modals.map((m) => {\n const isConfirmType = m.type === 'confirm';\n const handleOk = () => {\n m.props.onOk?.();\n removeModal(m.id);\n };\n const handleCancel = () => {\n m.props.onCancel?.();\n removeModal(m.id);\n };\n return (\n <OriginModal\n key={m.id}\n open={m.open}\n title={m.props.title}\n subTitle={m.props.subTitle}\n icon={m.props.icon || getIcon(m.type || 'info')}\n onOk={handleOk}\n onCancel={handleCancel}\n okText={m.props.okText}\n cancelText={m.props.cancelText}\n okButtonProps={m.props.okButtonProps}\n cancelButtonProps={m.props.cancelButtonProps}\n okType={m.props.okType || (isConfirmType ? 'dangerous' : 'primary')}\n width={m.props.width || DEFAULT_WIDTH}\n className={cn('ald-modal', m.props.className)}\n closable={m.props.closable}\n maskClosable={m.props.maskClosable}\n _modalType={m.type}\n footer={\n isConfirmType ? undefined : (\n <Button\n type=\"primary\"\n size=\"middle\"\n {...(m.props.okButtonProps || {})}\n onClick={handleOk}\n >\n {m.props.okText || 'OK'}\n </Button>\n )\n }\n >\n {m.props.content}\n </OriginModal>\n );\n })}\n </>\n );\n\n return [api, contextHolder];\n}\n\n// ---------- end useModal ----------\n\nconst Modal = OriginModal as typeof OriginModal & {\n info: ModalFunc;\n success: ModalFunc;\n error: ModalFunc;\n warning: ModalFunc;\n confirm: ModalFunc;\n destroyAll: () => void;\n useModal: typeof useModal;\n config: (config: any) => void;\n};\n\nModal.info = (props) => createStaticModal('info', props);\nModal.success = (props) => createStaticModal('success', props);\nModal.error = (props) => createStaticModal('error', props);\nModal.warning = (props) => createStaticModal('warning', props);\nModal.confirm = (props) =>\n createStaticModal('confirm', { ...props, type: props.type || 'confirm' });\n\nModal.destroyAll = () => {\n while (destroyFns.length) {\n const close = destroyFns.pop();\n if (close) close();\n }\n};\n\nModal.useModal = useModal;\nModal.config = () => {};\n\nexport default Modal;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/Modal/index.tsx"],"sourcesContent":["import * as DialogPrimitive from '@radix-ui/react-dialog';\nimport { hideOthers } from 'aria-hidden';\nimport React, {\n useCallback,\n useContext,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport { createRoot } from 'react-dom/client';\nimport Button, { ButtonType, IButtonProps } from '../Button';\nimport {\n AttentionTriangleLightLine,\n CheckCircleLightLine,\n CloseLLine,\n InformationCircleLightLine,\n} from '../Icon';\nimport IconButton from '../IconButton';\nimport ScrollArea from '../ScrollArea';\nimport {\n FLOATING_LAYER_BASE_Z_INDEX,\n FLOATING_LAYER_STEP,\n FloatingLayerProvider,\n} from '../_utils/floatingLayer';\nimport {\n ModalLayerProvider,\n useModalLayer,\n} from '../_utils/overlayCoordinator';\nimport { LocaleContext, getTranslator } from '../locale/default';\nimport { cn } from '../lib/utils';\n\nexport const destroyFns: Array<() => void> = [];\n\nexport interface ModalProps {\n open?: boolean;\n onOk?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n onCancel?: (e: React.MouseEvent<HTMLButtonElement>) => void;\n afterClose?: () => void;\n title?: React.ReactNode;\n subTitle?: React.ReactNode;\n icon?: React.ReactElement;\n width?: number | string;\n footer?: React.ReactNode | null;\n okText?: React.ReactNode;\n cancelText?: React.ReactNode;\n okButtonProps?: IButtonProps;\n cancelButtonProps?: IButtonProps;\n okType?: ButtonType;\n confirmLoading?: boolean;\n maskClosable?: boolean;\n closable?: boolean;\n closeIcon?: React.ReactNode;\n centered?: boolean;\n destroyOnClose?: boolean;\n className?: string;\n /** Pass through to the modal content root for automated testing. */\n 'data-testid'?: string;\n /** Pass through to the modal content root for accessibility and automated testing. */\n 'aria-label'?: string;\n /** Applied to the outer wrap layer (matches antd wrapClassName behavior) */\n wrapClassName?: string;\n style?: React.CSSProperties;\n bodyStyle?: React.CSSProperties;\n zIndex?: number;\n children?: React.ReactNode;\n paddingLess?: boolean;\n virtualScrollBar?: boolean;\n hideHeaderBottomBorder?: boolean;\n responsiveBounds?: boolean;\n fullscreen?: boolean;\n keyboard?: boolean;\n afterOpenChange?: (open: boolean) => void;\n getContainer?: (() => HTMLElement) | false;\n /** @internal used by static methods to pass modal type for icon styling */\n _modalType?: string;\n}\n\ninterface OriginModalProps extends ModalProps {\n onTopChange?: (isTop: boolean) => void;\n}\n\nexport interface ModalFuncProps {\n title?: React.ReactNode;\n subTitle?: React.ReactNode;\n content?: React.ReactNode;\n icon?: React.ReactElement;\n okText?: React.ReactNode;\n cancelText?: React.ReactNode;\n okButtonProps?: IButtonProps;\n cancelButtonProps?: IButtonProps;\n okType?: ButtonType;\n onOk?: (...args: any[]) => any;\n onCancel?: (...args: any[]) => any;\n width?: number | string;\n className?: string;\n /** @deprecated Use `className` instead. Preserved for antd v4 compat. */\n wrapClassName?: string;\n closable?: boolean;\n type?: 'info' | 'success' | 'error' | 'warn' | 'warning' | 'confirm';\n centered?: boolean;\n maskClosable?: boolean;\n}\n\nconst DEFAULT_WIDTH = 552;\nconst modalEscapeEvents = new WeakSet<KeyboardEvent>();\n\nfunction shouldCancelTopModal(event: KeyboardEvent) {\n return (\n !event.cancelBubble &&\n (!event.defaultPrevented || modalEscapeEvents.has(event))\n );\n}\n\nfunction ModalContentProviders({\n layerId,\n floatingLevel,\n children,\n}: {\n layerId: number;\n floatingLevel: number;\n children: React.ReactNode;\n}) {\n return (\n <ModalLayerProvider id={layerId}>\n <FloatingLayerProvider value={floatingLevel}>\n {children}\n </FloatingLayerProvider>\n </ModalLayerProvider>\n );\n}\n\nconst ModalTitle = (\n { icon, title, subTitle }: Pick<ModalProps, 'icon' | 'title' | 'subTitle'>,\n type?: string,\n) => (\n <div className=\"ald-modal-title-container tw-flex tw-items-center tw-gap-4\">\n {icon && (\n <div\n className={cn(\n 'ald-modal-icon-container tw-grid tw-size-10 tw-shrink-0 tw-place-items-center tw-rounded-[var(--global-grid-250)]',\n type === 'info' &&\n 'ald-modal-cion-info-container tw-bg-[var(--background-informative-muted)]',\n type === 'success' &&\n 'ald-modal-cion-success-container tw-bg-[var(--background-positive-muted)]',\n type === 'warning' &&\n 'ald-modal-cion-warning-container tw-bg-[var(--background-warning-muted)]',\n type === 'warn' &&\n 'ald-modal-cion-warning-container tw-bg-[var(--background-warning-muted)]',\n type === 'error' &&\n 'ald-modal-cion-error-container tw-bg-[var(--background-negative-muted)]',\n type === 'confirm' &&\n 'ald-modal-cion-confirm-container tw-bg-[var(--background-brand-muted)]',\n )}\n >\n {icon}\n </div>\n )}\n <div className=\"ald-modal-text-container\">\n {title && (\n <div\n className={cn(\n 'ald-modal-text-title tw-text-lg tw-font-semibold tw-leading-7 tw-text-[var(--content-primary)]',\n !subTitle && 'ald-modal-text-title-only tw-text-xl',\n )}\n >\n {title}\n </div>\n )}\n {subTitle && (\n <div className=\"ald-modal-text-sub-title tw-mt-1 tw-text-xs tw-leading-4 tw-text-[var(--content-secondary)]\">\n {subTitle}\n </div>\n )}\n </div>\n </div>\n);\n\nfunction getIcon(\n type: 'info' | 'success' | 'error' | 'warn' | 'warning' | 'confirm',\n) {\n if (type === 'success')\n return (\n <CheckCircleLightLine\n fill=\"var(--content-inverted-primary)\"\n color=\"var(--background-positive-strong)\"\n size={24}\n />\n );\n if (type === 'error')\n return (\n <AttentionTriangleLightLine\n color=\"var(--background-negative-strong)\"\n fill=\"var(--content-inverted-primary)\"\n size={24}\n />\n );\n if (type === 'warning' || type === 'warn')\n return (\n <AttentionTriangleLightLine\n color=\"var(--background-warning-strong)\"\n size={24}\n />\n );\n return (\n <InformationCircleLightLine\n size={24}\n color=\"var(--action-primary-normal)\"\n />\n );\n}\n\nfunction OriginModal(props: OriginModalProps) {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n const {\n className,\n 'data-testid': dataTestId,\n 'aria-label': ariaLabel,\n children,\n okType = 'primary',\n width,\n closeIcon,\n subTitle,\n okButtonProps = {},\n cancelButtonProps = {},\n okText = t.Modal.sure,\n cancelText = t.Modal.cancel,\n icon,\n title,\n paddingLess,\n responsiveBounds,\n hideHeaderBottomBorder,\n virtualScrollBar,\n style,\n maskClosable = false,\n fullscreen,\n open = false,\n onOk,\n onCancel,\n footer,\n confirmLoading,\n closable = true,\n zIndex = 1000,\n bodyStyle,\n keyboard = true,\n afterOpenChange,\n wrapClassName,\n _modalType,\n onTopChange,\n } = props;\n\n const prevOpenRef = useRef(open);\n const contentRef = useRef<HTMLDivElement>(null);\n const modalRef = useRef<HTMLDivElement>(null);\n const modalLayer = useModalLayer(open, zIndex);\n const { id: modalLayerId, maskZIndex, contentZIndex, isTop } = modalLayer;\n const nextFloatingLevel =\n (maskZIndex - FLOATING_LAYER_BASE_Z_INDEX) / FLOATING_LAYER_STEP + 1;\n\n useLayoutEffect(() => {\n onTopChange?.(isTop);\n }, [isTop, onTopChange]);\n\n useEffect(() => {\n if (prevOpenRef.current !== open) {\n prevOpenRef.current = open;\n afterOpenChange?.(open);\n }\n }, [open, afterOpenChange]);\n\n // ---- modal={false} 补偿:aria-hidden(屏幕阅读器只感知弹窗) ----\n useEffect(() => {\n if (!open || !isTop || !contentRef.current) return;\n return hideOthers(contentRef.current);\n }, [isTop, open]);\n\n // ---- modal={false} 补偿:Tab 焦点循环 ----\n useEffect(() => {\n if (!open || !isTop || !contentRef.current) return;\n const container = contentRef.current;\n\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.key !== 'Tab') return;\n const focusable = container.querySelectorAll<HTMLElement>(\n 'a[href], button:not([disabled]), input:not([disabled]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"]):not([disabled])',\n );\n if (focusable.length === 0) return;\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n\n if (e.shiftKey) {\n if (\n document.activeElement === first ||\n !container.contains(document.activeElement)\n ) {\n e.preventDefault();\n last.focus();\n }\n } else {\n if (\n document.activeElement === last ||\n !container.contains(document.activeElement)\n ) {\n e.preventDefault();\n first.focus();\n }\n }\n };\n\n document.addEventListener('keydown', handleKeyDown);\n return () => document.removeEventListener('keydown', handleKeyDown);\n }, [isTop, open]);\n\n useEffect(() => {\n if (!open || !isTop || !keyboard) return;\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key !== 'Escape') return;\n // Radix observes Escape during document capture, so child overlays can\n // only finish their own propagation handling later in the event cycle.\n queueMicrotask(() => {\n if (shouldCancelTopModal(event)) {\n onCancel?.({} as React.MouseEvent<HTMLButtonElement>);\n }\n });\n };\n\n window.addEventListener('keydown', handleEscape, true);\n return () => window.removeEventListener('keydown', handleEscape, true);\n }, [isTop, keyboard, onCancel, open]);\n\n const responsiveBoundsStyle = useMemo(() => {\n if (!responsiveBounds) return {};\n return {\n width: 'calc(100% - 160px)',\n maxWidth: '1680px',\n minWidth: '1280px',\n height: 'calc(100% - 48px)',\n maxHeight: '900px',\n minHeight: '640px',\n };\n }, [responsiveBounds]);\n\n const mergedOkProps = { loading: confirmLoading, ...okButtonProps };\n\n const renderFooter = () => {\n if (footer === null) return null;\n if (footer)\n return (\n // antd 兼容:antd .ant-modal-footer 使用 text-align:right 让 inline 按钮右对齐,\n // 即使消费方传入 width:100% 的子容器,内部 inline 元素仍能右对齐。\n // 此处同时使用 tw-flex tw-justify-end(flexbox 对齐)和 tw-text-right(继承式对齐)保持兼容。\n <div className=\"ald-modal-footer ant-modal-footer tw-flex tw-items-center tw-justify-end tw-gap-2 tw-border-t tw-border-solid tw-border-[var(--border-default)] tw-bg-[var(--background-default)] tw-px-6 tw-py-3 tw-text-right\">\n {footer}\n </div>\n );\n return (\n <div className=\"ald-modal-footer ant-modal-footer tw-flex tw-justify-end tw-gap-2 tw-border-t tw-border-solid tw-border-[var(--border-default)] tw-px-6 tw-py-4\">\n <Button\n type=\"secondary\"\n size=\"middle\"\n {...cancelButtonProps}\n onClick={onCancel}\n >\n {cancelText}\n </Button>\n <Button type={okType} size=\"middle\" {...mergedOkProps} onClick={onOk}>\n {okText}\n </Button>\n </div>\n );\n };\n\n return (\n <DialogPrimitive.Root open={open} modal={false}>\n <DialogPrimitive.Portal>\n {/* modal={false} 时 DialogPrimitive.Overlay 不渲染,用普通 div 替代 */}\n {isTop && (\n <div\n className=\"ald-modal-mask tw-animate-in tw-fade-in-0 tw-fixed tw-inset-0 tw-bg-[var(--background-inverted)] tw-opacity-45\"\n style={{ zIndex: maskZIndex }}\n onPointerDown={() => {\n if (maskClosable) {\n onCancel?.({} as React.MouseEvent<HTMLButtonElement>);\n }\n }}\n />\n )}\n {/* Centering wrapper — replaces transform centering so consumer CSS (top/left overrides) works */}\n <div\n ref={contentRef}\n {...(!isTop ? { inert: '' } : {})}\n aria-hidden={!isTop || undefined}\n className={cn(\n // antd 兼容:保留 ant-modal-wrap class,消费方 CSS 通过 wrapClassName + :global(.ant-modal) 控制弹窗宽高\n 'ald-modal-wrap ant-modal-wrap tw-pointer-events-none tw-fixed tw-inset-0 tw-flex tw-items-center tw-justify-center',\n wrapClassName,\n )}\n style={{ zIndex: contentZIndex }}\n >\n <DialogPrimitive.Content\n ref={modalRef}\n tabIndex={-1}\n data-testid={dataTestId}\n aria-label={ariaLabel}\n className={cn(\n // antd 兼容:保留 ant-modal class,消费方 CSS 通过 .ant-modal 选择器控制弹窗宽高等样式\n // tw-outline-none:Radix 打开时会聚焦 Content,不抑制 outline 会渲染出蓝色焦点框\n 'ald-modal ant-modal tw-pointer-events-auto tw-box-border tw-flex tw-flex-col tw-overflow-hidden tw-bg-[var(--background-default)] tw-shadow-[var(--elevation-bottom-bottom-lg)] tw-outline-none',\n fullscreen\n ? 'ald-modal-fullscreen tw-fixed tw-inset-0 tw-size-full tw-rounded-none'\n : 'tw-rounded-r-75',\n !fullscreen &&\n 'tw-border tw-border-solid tw-border-[var(--border-default)]',\n paddingLess && 'ald-modal-padding-less',\n virtualScrollBar && 'ald-modal-virtual-scroll-bar',\n hideHeaderBottomBorder && 'ald-modal-hide-header-bottom-border',\n responsiveBounds && 'ald-modal-responsive-bounds',\n className,\n )}\n style={{\n ...(fullscreen\n ? {}\n : {\n width: responsiveBounds\n ? responsiveBoundsStyle.width\n : width || DEFAULT_WIDTH,\n ...responsiveBoundsStyle,\n }),\n ...style,\n }}\n onOpenAutoFocus={(event) => {\n event.preventDefault();\n requestAnimationFrame(() => {\n const modal = modalRef.current;\n const activeElement = document.activeElement;\n const activeOverlay =\n activeElement instanceof HTMLElement\n ? activeElement.closest(\n '[role=\"dialog\"], [role=\"menu\"], [role=\"listbox\"]',\n )\n : null;\n\n // A nested overlay may open together with the modal and owns\n // focus already. Do not steal focus back from that overlay.\n if (\n !modal ||\n (activeOverlay &&\n !activeOverlay.classList.contains('ald-modal') &&\n activeOverlay !== modal &&\n !modal.contains(activeOverlay))\n ) {\n return;\n }\n modal.focus({ preventScroll: true });\n });\n }}\n onEscapeKeyDown={(event) => {\n if (!event.defaultPrevented) modalEscapeEvents.add(event);\n event.preventDefault();\n }}\n onPointerDownOutside={(e) => {\n if (maskClosable) {\n onCancel?.({} as React.MouseEvent<HTMLButtonElement>);\n } else {\n e.preventDefault();\n }\n }}\n onInteractOutside={(e) => {\n if (!maskClosable) {\n e.preventDefault();\n }\n }}\n >\n {/* ant-modal-content compat wrapper — matches antd DOM nesting for consumer CSS */}\n <div className=\"ant-modal-content tw-flex tw-h-full tw-flex-col\">\n <ModalContentProviders\n layerId={modalLayerId}\n floatingLevel={nextFloatingLevel}\n >\n {!fullscreen && (\n <div\n className={cn(\n 'ald-modal-header ant-modal-header tw-flex tw-items-start tw-justify-between tw-bg-[var(--background-default)] tw-px-6 tw-py-4',\n !hideHeaderBottomBorder &&\n 'tw-border-b tw-border-solid tw-border-[var(--border-default)]',\n )}\n >\n <DialogPrimitive.Title asChild>\n <div className=\"tw-flex-1\">\n {ModalTitle({ icon, title, subTitle }, _modalType)}\n </div>\n </DialogPrimitive.Title>\n {closable && (\n <DialogPrimitive.Close asChild>\n <span className=\"ant-modal-close\" onClick={onCancel}>\n {closeIcon || (\n <IconButton\n icon={<CloseLLine size={20} />}\n size=\"middle\"\n />\n )}\n </span>\n </DialogPrimitive.Close>\n )}\n </div>\n )}\n {/* Hidden title for accessibility when fullscreen hides the header */}\n {fullscreen && (\n <DialogPrimitive.Title className=\"tw-sr-only\">\n {title}\n </DialogPrimitive.Title>\n )}\n <div\n className={cn(\n 'ald-modal-body ant-modal-body tw-flex-1 tw-text-sm tw-leading-5',\n fullscreen\n ? 'tw-h-full tw-overflow-auto tw-p-0'\n : 'tw-min-h-[130px]',\n !fullscreen &&\n (virtualScrollBar\n ? 'tw-overflow-hidden tw-p-0'\n : 'tw-overflow-auto'),\n !fullscreen &&\n !responsiveBounds &&\n !virtualScrollBar &&\n 'tw-max-h-[68vh]',\n !fullscreen &&\n !paddingLess &&\n !virtualScrollBar &&\n 'tw-p-6',\n )}\n style={bodyStyle}\n >\n {virtualScrollBar ? (\n <ScrollArea\n className=\"ald-modal-body-wrap !tw-h-auto\"\n innerClassName={cn(\n 'ald-modal-body-wrap-inner tw-max-h-[68vh]',\n paddingLess ? 'tw-p-0' : 'tw-px-[23px] tw-py-0',\n )}\n >\n {children}\n </ScrollArea>\n ) : (\n children\n )}\n </div>\n {!fullscreen && renderFooter()}\n </ModalContentProviders>\n </div>\n </DialogPrimitive.Content>\n </div>\n </DialogPrimitive.Portal>\n </DialogPrimitive.Root>\n );\n}\n\n// Static method helper\nfunction createStaticModal(\n type: ModalFuncProps['type'],\n props: ModalFuncProps,\n) {\n const focusTarget = document.activeElement as HTMLElement | null;\n const container = document.createElement('div');\n document.body.appendChild(container);\n const root = createRoot(container);\n\n let currentProps = { ...props };\n let destroyed = false;\n let isTop = true;\n\n const destroy = () => {\n if (destroyed) return;\n destroyed = true;\n const shouldRestoreFocus = isTop;\n root.unmount();\n container.remove();\n const idx = destroyFns.indexOf(destroy);\n if (idx >= 0) destroyFns.splice(idx, 1);\n queueMicrotask(() => {\n if (shouldRestoreFocus && focusTarget?.isConnected) focusTarget.focus();\n });\n };\n\n const update = (newProps: Partial<ModalFuncProps>) => {\n currentProps = { ...currentProps, ...newProps };\n render(currentProps);\n };\n\n const isConfirm = type === 'confirm';\n\n const render = (p: ModalFuncProps) => {\n const handleOk = () => {\n p.onOk?.();\n destroy();\n };\n const handleCancel = () => {\n p.onCancel?.();\n destroy();\n };\n\n root.render(\n <OriginModal\n open={true}\n title={p.title}\n subTitle={p.subTitle}\n icon={p.icon || getIcon(type || 'info')}\n onOk={handleOk}\n onCancel={handleCancel}\n okText={p.okText}\n cancelText={p.cancelText}\n okButtonProps={p.okButtonProps}\n cancelButtonProps={p.cancelButtonProps}\n okType={p.okType || (isConfirm ? 'dangerous' : 'primary')}\n width={p.width || DEFAULT_WIDTH}\n className={cn('ald-modal', p.className)}\n closable={p.closable}\n maskClosable={p.maskClosable}\n _modalType={type}\n onTopChange={(nextIsTop) => {\n isTop = nextIsTop;\n }}\n footer={\n isConfirm ? undefined : (\n <Button\n type=\"primary\"\n size=\"middle\"\n {...(p.okButtonProps || {})}\n onClick={handleOk}\n >\n {p.okText || 'OK'}\n </Button>\n )\n }\n >\n {p.content}\n </OriginModal>,\n );\n };\n\n destroyFns.push(destroy);\n render(currentProps);\n\n return { destroy, update };\n}\n\n// Attach static methods\ntype ModalFunc = (props: ModalFuncProps) => {\n destroy: () => void;\n update: (props: Partial<ModalFuncProps>) => void;\n};\n\n// ---------- useModal hook ----------\n\ninterface ModalInstance {\n id: number;\n type: ModalFuncProps['type'];\n props: ModalFuncProps;\n open: boolean;\n}\n\nexport interface ModalApiInstance {\n destroy: () => void;\n update: (newProps: Partial<ModalFuncProps>) => void;\n}\n\nexport interface ModalStaticFunctions {\n info: (props: ModalFuncProps) => ModalApiInstance;\n success: (props: ModalFuncProps) => ModalApiInstance;\n error: (props: ModalFuncProps) => ModalApiInstance;\n warning: (props: ModalFuncProps) => ModalApiInstance;\n confirm: (props: ModalFuncProps) => ModalApiInstance;\n}\n\nfunction useModal(): [ModalStaticFunctions, React.ReactElement] {\n const [modals, setModals] = useState<ModalInstance[]>([]);\n const idCounter = useRef(0);\n\n const removeModal = useCallback((id: number) => {\n setModals((prev) =>\n prev.map((m) => (m.id === id ? { ...m, open: false } : m)),\n );\n // Remove from DOM after animation\n setTimeout(() => {\n setModals((prev) => prev.filter((m) => m.id !== id));\n }, 300);\n }, []);\n\n const updateModal = useCallback(\n (id: number, newProps: Partial<ModalFuncProps>) => {\n setModals((prev) =>\n prev.map((m) =>\n m.id === id ? { ...m, props: { ...m.props, ...newProps } } : m,\n ),\n );\n },\n [],\n );\n\n const openModal = useCallback(\n (type: ModalFuncProps['type'], props: ModalFuncProps): ModalApiInstance => {\n const id = ++idCounter.current;\n const instance: ModalInstance = { id, type, props, open: true };\n setModals((prev) => [...prev, instance]);\n\n return {\n destroy: () => removeModal(id),\n update: (newProps: Partial<ModalFuncProps>) =>\n updateModal(id, newProps),\n };\n },\n [removeModal, updateModal],\n );\n\n const api = useMemo<ModalStaticFunctions>(\n () => ({\n info: (props) => openModal('info', props),\n success: (props) => openModal('success', props),\n error: (props) => openModal('error', props),\n warning: (props) => openModal('warning', props),\n confirm: (props) =>\n openModal('confirm', { ...props, type: props.type || 'confirm' }),\n }),\n [openModal],\n );\n\n const contextHolder = (\n <>\n {modals.map((m) => {\n const isConfirmType = m.type === 'confirm';\n const handleOk = () => {\n m.props.onOk?.();\n removeModal(m.id);\n };\n const handleCancel = () => {\n m.props.onCancel?.();\n removeModal(m.id);\n };\n return (\n <OriginModal\n key={m.id}\n open={m.open}\n title={m.props.title}\n subTitle={m.props.subTitle}\n icon={m.props.icon || getIcon(m.type || 'info')}\n onOk={handleOk}\n onCancel={handleCancel}\n okText={m.props.okText}\n cancelText={m.props.cancelText}\n okButtonProps={m.props.okButtonProps}\n cancelButtonProps={m.props.cancelButtonProps}\n okType={m.props.okType || (isConfirmType ? 'dangerous' : 'primary')}\n width={m.props.width || DEFAULT_WIDTH}\n className={cn('ald-modal', m.props.className)}\n closable={m.props.closable}\n maskClosable={m.props.maskClosable}\n _modalType={m.type}\n footer={\n isConfirmType ? undefined : (\n <Button\n type=\"primary\"\n size=\"middle\"\n {...(m.props.okButtonProps || {})}\n onClick={handleOk}\n >\n {m.props.okText || 'OK'}\n </Button>\n )\n }\n >\n {m.props.content}\n </OriginModal>\n );\n })}\n </>\n );\n\n return [api, contextHolder];\n}\n\n// ---------- end useModal ----------\n\nconst Modal = OriginModal as typeof OriginModal & {\n info: ModalFunc;\n success: ModalFunc;\n error: ModalFunc;\n warning: ModalFunc;\n confirm: ModalFunc;\n destroyAll: () => void;\n useModal: typeof useModal;\n config: (config: any) => void;\n};\n\nModal.info = (props) => createStaticModal('info', props);\nModal.success = (props) => createStaticModal('success', props);\nModal.error = (props) => createStaticModal('error', props);\nModal.warning = (props) => createStaticModal('warning', props);\nModal.confirm = (props) =>\n createStaticModal('confirm', { ...props, type: props.type || 'confirm' });\n\nModal.destroyAll = () => {\n while (destroyFns.length) {\n const close = destroyFns.pop();\n if (close) close();\n }\n};\n\nModal.useModal = useModal;\nModal.config = () => {};\n\nexport default Modal;\n"],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ import { useContext } from "react";
|
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
|
5
5
|
//#region src/Pagination/PageSizeChanger.tsx
|
|
6
6
|
var PAGE_SIZE_CHANGER_POPUP_WIDTH = 128;
|
|
7
|
-
var PageSizeChanger = ({ pageSize, pageSizeOptions, onChange, className, disabled = false
|
|
7
|
+
var PageSizeChanger = ({ pageSize, pageSizeOptions, onChange, className, disabled = false }) => {
|
|
8
8
|
const { locale } = useContext(LocaleContext);
|
|
9
9
|
const t = getTranslator(locale);
|
|
10
10
|
const optionSet = new Set([...pageSizeOptions, pageSize]);
|
|
@@ -24,8 +24,7 @@ var PageSizeChanger = ({ pageSize, pageSizeOptions, onChange, className, disable
|
|
|
24
24
|
disabled,
|
|
25
25
|
className: `ald-pagination-page-size-changer ${className || ""}`.trim(),
|
|
26
26
|
placeholder: t.Pagination.selectPageSize,
|
|
27
|
-
popupMatchSelectWidth: PAGE_SIZE_CHANGER_POPUP_WIDTH
|
|
28
|
-
"aria-label": ariaLabel
|
|
27
|
+
popupMatchSelectWidth: PAGE_SIZE_CHANGER_POPUP_WIDTH
|
|
29
28
|
});
|
|
30
29
|
};
|
|
31
30
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PageSizeChanger.js","names":[],"sources":["../../src/Pagination/PageSizeChanger.tsx"],"sourcesContent":["import React, { useContext } from 'react';\nimport Select from '../Select';\nimport { ISelectProps } from '../Select/interface';\nimport { LocaleContext, getTranslator } from '../locale/default';\n\nconst PAGE_SIZE_CHANGER_POPUP_WIDTH = 128;\n\ninterface IPageSizeChangerProps {\n // 当前 pageSize\n pageSize: number;\n // pageSize 选项\n pageSizeOptions: (string | number)[];\n // pageSize 变化的回调\n onChange: (size: number) => void;\n // 自定义样式类名\n className?: string;\n // 是否禁用\n disabled?: boolean;\n
|
|
1
|
+
{"version":3,"file":"PageSizeChanger.js","names":[],"sources":["../../src/Pagination/PageSizeChanger.tsx"],"sourcesContent":["import React, { useContext } from 'react';\nimport Select from '../Select';\nimport { ISelectProps } from '../Select/interface';\nimport { LocaleContext, getTranslator } from '../locale/default';\n\nconst PAGE_SIZE_CHANGER_POPUP_WIDTH = 128;\n\ninterface IPageSizeChangerProps {\n // 当前 pageSize\n pageSize: number;\n // pageSize 选项\n pageSizeOptions: (string | number)[];\n // pageSize 变化的回调\n onChange: (size: number) => void;\n // 自定义样式类名\n className?: string;\n // 是否禁用\n disabled?: boolean;\n}\n\nconst PageSizeChanger: React.FC<IPageSizeChangerProps> = ({\n pageSize,\n pageSizeOptions,\n onChange,\n className,\n disabled = false,\n}) => {\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n\n // 将 pageSizeOptions 转换为 Select 可用的选项格式\n // 确保当前 pageSize 值在选项中存在\n const optionSet = new Set([...pageSizeOptions, pageSize]);\n const allOptions = Array.from(optionSet).sort(\n (a, b) => Number(a) - Number(b),\n );\n const selectOptions = allOptions.map((option) => ({\n label: `${option} ${t.Pagination.itemsPerPage}`,\n value: String(option),\n }));\n\n const handleChange = (value: string) => {\n const newSize = parseInt(value, 10);\n if (!isNaN(newSize) && newSize !== pageSize) {\n onChange(newSize);\n }\n };\n\n const selectProps: ISelectProps = {\n value: String(pageSize),\n onChange: handleChange,\n options: selectOptions,\n width: 112,\n disabled,\n className: `ald-pagination-page-size-changer ${className || ''}`.trim(),\n placeholder: t.Pagination.selectPageSize,\n popupMatchSelectWidth: PAGE_SIZE_CHANGER_POPUP_WIDTH,\n };\n\n return <Select {...selectProps} />;\n};\n\nexport default PageSizeChanger;\n"],"mappings":";;;;;AAKA,IAAM,gCAAgC;AAetC,IAAM,mBAAoD,EACxD,UACA,iBACA,UACA,WACA,WAAW,YACP;CACJ,MAAM,EAAE,WAAW,WAAW,cAAc;CAC5C,MAAM,IAAI,cAAc,OAAO;CAI/B,MAAM,YAAY,IAAI,IAAI,CAAC,GAAG,iBAAiB,SAAS,CAAC;CAIzD,MAAM,gBAHa,MAAM,KAAK,UAAU,CAAC,MACtC,GAAG,MAAM,OAAO,EAAE,GAAG,OAAO,EAAE,CAChC,CACgC,KAAK,YAAY;EAChD,OAAO,GAAG,OAAO,GAAG,EAAE,WAAW;EACjC,OAAO,OAAO,OAAO;EACtB,EAAE;CAEH,MAAM,gBAAgB,UAAkB;EACtC,MAAM,UAAU,SAAS,OAAO,GAAG;AACnC,MAAI,CAAC,MAAM,QAAQ,IAAI,YAAY,SACjC,UAAS,QAAQ;;AAerB,QAAO,oBAAC,gBAAD;EAVL,OAAO,OAAO,SAAS;EACvB,UAAU;EACV,SAAS;EACT,OAAO;EACP;EACA,WAAW,oCAAoC,aAAa,KAAK,MAAM;EACvE,aAAa,EAAE,WAAW;EAC1B,uBAAuB;EAGS,CAAA"}
|
package/dist/Pagination/index.js
CHANGED
|
@@ -6,52 +6,46 @@ import Button_default from "../Button/index.js";
|
|
|
6
6
|
import { LocaleContext, getTranslator } from "../locale/default.js";
|
|
7
7
|
import PageSizeChanger from "./PageSizeChanger.js";
|
|
8
8
|
/* empty css */
|
|
9
|
-
import { useCallback, useContext, useState } from "react";
|
|
9
|
+
import { useCallback, useContext, useEffect, useState } from "react";
|
|
10
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
11
|
import _ from "lodash";
|
|
12
12
|
//#region src/Pagination/index.tsx
|
|
13
13
|
function Pagination(props) {
|
|
14
|
-
const { current:
|
|
14
|
+
const { current: currPage = 1, pageSize, total, onChange, hideOnSinglePage, showSizeChanger = false, pageSizeOptions = [
|
|
15
15
|
10,
|
|
16
16
|
20,
|
|
17
17
|
30,
|
|
18
18
|
50
|
|
19
|
-
], onShowSizeChange, showTotal = false
|
|
19
|
+
], onShowSizeChange, showTotal = false } = props;
|
|
20
20
|
const { locale } = useContext(LocaleContext);
|
|
21
21
|
const t = getTranslator(locale);
|
|
22
|
-
const a11y = t.Pagination;
|
|
23
|
-
const [uncontrolledCurrent, setUncontrolledCurrent] = useState(defaultCurrent);
|
|
24
|
-
if (pageSize <= 0) throw new Error("pageSize must be greater than 0");
|
|
25
22
|
const totalPage = getTotalPage(total, pageSize);
|
|
26
|
-
const current = getSafeCurrent(totalPage,
|
|
23
|
+
const [current, setCurrent] = useState(getSafeCurrent(totalPage, currPage));
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
setCurrent(getSafeCurrent(totalPage, currPage));
|
|
26
|
+
}, [currPage, totalPage]);
|
|
27
|
+
if (pageSize === 0) throw new Error("pageSize must be greater than 0");
|
|
27
28
|
const onChangePage = useCallback((page) => {
|
|
28
29
|
return () => {
|
|
29
|
-
if (
|
|
30
|
-
|
|
30
|
+
if (page === current) return;
|
|
31
|
+
setCurrent(page);
|
|
31
32
|
onChange(page, pageSize);
|
|
32
33
|
};
|
|
33
34
|
}, [
|
|
34
|
-
controlledCurrent,
|
|
35
|
-
disabled,
|
|
36
35
|
onChange,
|
|
37
36
|
current,
|
|
38
|
-
pageSize
|
|
39
|
-
totalPage
|
|
37
|
+
pageSize
|
|
40
38
|
]);
|
|
41
39
|
const handlePageSizeChange = useCallback((newPageSize) => {
|
|
42
|
-
if (disabled || newPageSize <= 0 || newPageSize === pageSize) return;
|
|
43
40
|
const safeCurrent = getSafeCurrent(getTotalPage(total, newPageSize), current);
|
|
44
|
-
|
|
41
|
+
setCurrent(safeCurrent);
|
|
45
42
|
if (onShowSizeChange) onShowSizeChange(safeCurrent, newPageSize);
|
|
46
43
|
onChange(safeCurrent, newPageSize);
|
|
47
44
|
}, [
|
|
48
|
-
|
|
45
|
+
total,
|
|
49
46
|
current,
|
|
50
|
-
disabled,
|
|
51
|
-
onChange,
|
|
52
47
|
onShowSizeChange,
|
|
53
|
-
|
|
54
|
-
total
|
|
48
|
+
onChange
|
|
55
49
|
]);
|
|
56
50
|
const pageRange = getPaginationRange(totalPage, current);
|
|
57
51
|
if (hideOnSinglePage) {
|
|
@@ -64,9 +58,8 @@ function Pagination(props) {
|
|
|
64
58
|
if (showTotal === true) return t.Pagination.totalItems(total, range);
|
|
65
59
|
return null;
|
|
66
60
|
};
|
|
67
|
-
return /* @__PURE__ */ jsxs("
|
|
61
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
68
62
|
className: containerClassName,
|
|
69
|
-
"aria-label": ariaLabel ?? a11y.navigationLabel,
|
|
70
63
|
children: [
|
|
71
64
|
showTotal && /* @__PURE__ */ jsx("div", {
|
|
72
65
|
className: prefixCls("total"),
|
|
@@ -78,8 +71,7 @@ function Pagination(props) {
|
|
|
78
71
|
/* @__PURE__ */ jsx(Button_default, {
|
|
79
72
|
icon: /* @__PURE__ */ jsx(Memo, { size: 16 }),
|
|
80
73
|
onClick: onChangePage(current - 1),
|
|
81
|
-
disabled:
|
|
82
|
-
"aria-label": a11y.previousPage
|
|
74
|
+
disabled: current === 1
|
|
83
75
|
}),
|
|
84
76
|
_.map(pageRange, (page, index) => {
|
|
85
77
|
if (page === "...") return /* @__PURE__ */ jsx("span", {
|
|
@@ -89,26 +81,20 @@ function Pagination(props) {
|
|
|
89
81
|
return /* @__PURE__ */ jsx(Button_default, {
|
|
90
82
|
icon: /* @__PURE__ */ jsx("span", { children: page }),
|
|
91
83
|
className: cn(prefixCls("button"), { [prefixCls("active")]: page === current }),
|
|
92
|
-
onClick: onChangePage(page)
|
|
93
|
-
disabled,
|
|
94
|
-
"aria-label": page === current ? a11y.currentPage(page) : a11y.page(page),
|
|
95
|
-
...page === current ? { "aria-current": "page" } : {}
|
|
84
|
+
onClick: onChangePage(page)
|
|
96
85
|
}, index);
|
|
97
86
|
}),
|
|
98
87
|
/* @__PURE__ */ jsx(Button_default, {
|
|
99
88
|
icon: /* @__PURE__ */ jsx(Memo$1, { size: 16 }),
|
|
100
89
|
onClick: onChangePage(current + 1),
|
|
101
|
-
disabled:
|
|
102
|
-
"aria-label": a11y.nextPage
|
|
90
|
+
disabled: current >= totalPage
|
|
103
91
|
})
|
|
104
92
|
]
|
|
105
93
|
}),
|
|
106
94
|
showSizeChanger && /* @__PURE__ */ jsx(PageSizeChanger, {
|
|
107
95
|
pageSize,
|
|
108
96
|
pageSizeOptions,
|
|
109
|
-
onChange: handlePageSizeChange
|
|
110
|
-
disabled,
|
|
111
|
-
ariaLabel: a11y.pageSize
|
|
97
|
+
onChange: handlePageSizeChange
|
|
112
98
|
})
|
|
113
99
|
]
|
|
114
100
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/Pagination/index.tsx"],"sourcesContent":["import { cn } from '../lib/utils';\nimport _ from 'lodash';\nimport React, { useCallback, useContext, useState } from 'react';\nimport Button from '../Button';\nimport { ChevronLeftLine, ChevronRightLine, Ellipsis } from '../Icon';\nimport { LocaleContext, getTranslator } from '../locale/default';\nimport { IPaginationProps } from './types';\nimport PageSizeChanger from './PageSizeChanger';\nimport './pagination.css';\n\nfunction Pagination(props: IPaginationProps) {\n const {\n current: controlledCurrent,\n defaultCurrent = 1,\n pageSize,\n total,\n onChange,\n hideOnSinglePage,\n showSizeChanger = false,\n pageSizeOptions = [10, 20, 30, 50],\n onShowSizeChange,\n showTotal = false,\n disabled = false,\n 'aria-label': ariaLabel,\n } = props;\n\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n const a11y = t.Pagination;\n const [uncontrolledCurrent, setUncontrolledCurrent] =\n useState(defaultCurrent);\n\n if (pageSize <= 0) {\n throw new Error('pageSize must be greater than 0');\n }\n\n const totalPage = getTotalPage(total, pageSize);\n const current = getSafeCurrent(\n totalPage,\n controlledCurrent ?? uncontrolledCurrent,\n );\n\n const onChangePage = useCallback(\n (page: number) => {\n return () => {\n if (disabled || page === current || page < 1 || page > totalPage) {\n return;\n }\n if (controlledCurrent === undefined) {\n setUncontrolledCurrent(page);\n }\n onChange(page, pageSize);\n };\n },\n [controlledCurrent, disabled, onChange, current, pageSize, totalPage],\n );\n\n const handlePageSizeChange = useCallback(\n (newPageSize: number) => {\n if (disabled || newPageSize <= 0 || newPageSize === pageSize) {\n return;\n }\n const newTotalPage = getTotalPage(total, newPageSize);\n const safeCurrent = getSafeCurrent(newTotalPage, current);\n\n if (controlledCurrent === undefined) {\n setUncontrolledCurrent(safeCurrent);\n }\n if (onShowSizeChange) {\n onShowSizeChange(safeCurrent, newPageSize);\n }\n\n onChange(safeCurrent, newPageSize);\n },\n [\n controlledCurrent,\n current,\n disabled,\n onChange,\n onShowSizeChange,\n pageSize,\n total,\n ],\n );\n\n const pageRange = getPaginationRange(totalPage, current);\n\n if (hideOnSinglePage) {\n if (totalPage <= 1 && !showSizeChanger && !showTotal) {\n return null;\n }\n }\n\n // 计算当前显示的数据范围\n const startIndex = (current - 1) * pageSize + 1;\n const endIndex = Math.min(current * pageSize, total);\n const range: [number, number] = [startIndex, endIndex];\n\n const containerClassName = prefixCls('container');\n\n // 获取显示总数的函数\n const getShowTotalContent = () => {\n if (typeof showTotal === 'function') {\n return showTotal(total, range);\n }\n if (showTotal === true) {\n return t.Pagination.totalItems(total, range);\n }\n return null;\n };\n\n return (\n <nav\n className={containerClassName}\n aria-label={ariaLabel ?? a11y.navigationLabel}\n >\n {/* 显示总数和当前范围 */}\n {showTotal && (\n <div className={prefixCls('total')}>{getShowTotalContent()}</div>\n )}\n\n {/* 主要的分页控件 */}\n <div className={prefixCls('main')}>\n <Button\n icon={<ChevronLeftLine size={16} />}\n onClick={onChangePage(current - 1)}\n disabled={disabled || current === 1}\n aria-label={a11y.previousPage}\n />\n {_.map(pageRange, (page, index: number) => {\n if (page === ELLIPSIS) {\n return (\n <span key={index} className={prefixCls('ellipsis')}>\n <Ellipsis size={20} />\n </span>\n );\n }\n return (\n <Button\n key={index}\n icon={<span>{page}</span>}\n className={cn(prefixCls('button'), {\n [prefixCls('active')]: page === current,\n })}\n onClick={onChangePage(page)}\n disabled={disabled}\n aria-label={\n page === current ? a11y.currentPage(page) : a11y.page(page)\n }\n {...(page === current\n ? ({ 'aria-current': 'page' } as React.AriaAttributes)\n : {})}\n />\n );\n })}\n <Button\n icon={<ChevronRightLine size={16} />}\n onClick={onChangePage(current + 1)}\n disabled={disabled || current >= totalPage}\n aria-label={a11y.nextPage}\n />\n </div>\n\n {/* 页面大小选择器 */}\n {showSizeChanger && (\n <PageSizeChanger\n pageSize={pageSize}\n pageSizeOptions={pageSizeOptions}\n onChange={handlePageSizeChange}\n disabled={disabled}\n ariaLabel={a11y.pageSize}\n />\n )}\n </nav>\n );\n}\n\nexport default Pagination;\n\n/**\n * 获取在安全范围内的当前页数\n */\nexport function getSafeCurrent(totalPage: number, current?: number) {\n if (current === undefined) {\n return 1;\n }\n return Math.max(1, Math.min(current, totalPage));\n}\n\nfunction getTotalPage(total: number, pageSize: number) {\n return Math.max(1, Math.ceil(total / pageSize));\n}\n\nexport const ELLIPSIS = '...';\n\nexport type PaginationItemType = number | typeof ELLIPSIS;\n\n/**\n * 获取分页组件需要显示的页码范围。\n *\n * @param totalPage 最大页码。\n * @param currentPage 当前所在的页码。\n *\n * 如果总页数不超过5页,直接返回所有页码。\n * 否则,在生成页码时,除了第一页和最后一页,还会显示以当前页为中心的连续页码,数量为 `surroundCount`*2 个,\n * 当当前页码距离边界过近时,会在页码前后添加省略号。\n * 当前页码 `currentPage` 的值必须介于 1 和总页数之间,如果超出这个范围,会自动修正。\n *\n * @returns 一个包含了所有要显示的页码和省略号的数组。\n */\nexport function getPaginationRange(\n totalPage: number,\n currentPage: number,\n): PaginationItemType[] {\n // 如果总页数不超过5页,直接返回所有页码\n if (totalPage <= 5) {\n return Array.from({ length: totalPage }, (_, i) => i + 1);\n }\n\n const surroundCount = 2;\n\n const current = Math.max(1, Math.min(currentPage, totalPage));\n\n let start = Math.max(2, current - surroundCount);\n let end = Math.min(totalPage - 1, current + surroundCount);\n\n // Adjust start and end based on current page\n if (current - start < surroundCount) {\n end = Math.min(end + (surroundCount - (current - start)), totalPage - 1);\n }\n if (end - current < surroundCount) {\n start = Math.max(start - (surroundCount - (end - current)), 2);\n }\n\n // Check if current page is out of range\n if (current < start || current > end) {\n start = Math.max(2, current - surroundCount);\n end = Math.min(totalPage - 1, current + surroundCount);\n }\n\n const range: PaginationItemType[] = [];\n for (let i = start; i <= end; i++) {\n range.push(i);\n }\n\n range.unshift(1);\n if (start > 2 && range[1] !== ELLIPSIS) {\n range.splice(1, 0, ELLIPSIS);\n }\n\n if (totalPage !== range[range.length - 1]) {\n if (end < totalPage - 1 && range[range.length - 1] !== ELLIPSIS) {\n range.splice(range.length, 0, ELLIPSIS);\n }\n range.push(totalPage);\n }\n\n return range;\n}\n\nfunction prefixCls(name: string) {\n return `ald-pagination-${name}`;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/Pagination/index.tsx"],"sourcesContent":["import { cn } from '../lib/utils';\nimport _ from 'lodash';\nimport React, { useCallback, useContext, useEffect, useState } from 'react';\nimport Button from '../Button';\nimport { ChevronLeftLine, ChevronRightLine, Ellipsis } from '../Icon';\nimport { LocaleContext, getTranslator } from '../locale/default';\nimport { IPaginationProps } from './types';\nimport PageSizeChanger from './PageSizeChanger';\nimport './pagination.css';\n\nfunction Pagination(props: IPaginationProps) {\n const {\n current: currPage = 1,\n pageSize,\n total,\n onChange,\n hideOnSinglePage,\n showSizeChanger = false,\n pageSizeOptions = [10, 20, 30, 50],\n onShowSizeChange,\n showTotal = false,\n } = props;\n\n const { locale } = useContext(LocaleContext);\n const t = getTranslator(locale);\n const totalPage = getTotalPage(total, pageSize);\n\n const [current, setCurrent] = useState(getSafeCurrent(totalPage, currPage));\n\n useEffect(() => {\n const safeCurrent = getSafeCurrent(totalPage, currPage);\n setCurrent(safeCurrent);\n }, [currPage, totalPage]);\n\n if (pageSize === 0) {\n throw new Error('pageSize must be greater than 0');\n }\n\n const onChangePage = useCallback(\n (page: number) => {\n return () => {\n if (page === current) {\n return;\n }\n setCurrent(page);\n onChange(page, pageSize);\n };\n },\n [onChange, current, pageSize],\n );\n\n const handlePageSizeChange = useCallback(\n (newPageSize: number) => {\n const newTotalPage = getTotalPage(total, newPageSize);\n // 确保当前页在有效范围内\n const safeCurrent = getSafeCurrent(newTotalPage, current);\n\n setCurrent(safeCurrent);\n\n // 调用回调函数\n if (onShowSizeChange) {\n onShowSizeChange(safeCurrent, newPageSize);\n }\n\n // 也调用 onChange 以保持一致性\n onChange(safeCurrent, newPageSize);\n },\n [total, current, onShowSizeChange, onChange],\n );\n\n const pageRange = getPaginationRange(totalPage, current);\n\n if (hideOnSinglePage) {\n if (totalPage <= 1 && !showSizeChanger && !showTotal) {\n return null;\n }\n }\n\n // 计算当前显示的数据范围\n const startIndex = (current - 1) * pageSize + 1;\n const endIndex = Math.min(current * pageSize, total);\n const range: [number, number] = [startIndex, endIndex];\n\n const containerClassName = prefixCls('container');\n\n // 获取显示总数的函数\n const getShowTotalContent = () => {\n if (typeof showTotal === 'function') {\n return showTotal(total, range);\n }\n if (showTotal === true) {\n return t.Pagination.totalItems(total, range);\n }\n return null;\n };\n\n return (\n <div className={containerClassName}>\n {/* 显示总数和当前范围 */}\n {showTotal && (\n <div className={prefixCls('total')}>{getShowTotalContent()}</div>\n )}\n\n {/* 主要的分页控件 */}\n <div className={prefixCls('main')}>\n <Button\n icon={<ChevronLeftLine size={16} />}\n onClick={onChangePage(current - 1)}\n disabled={current === 1}\n />\n {_.map(pageRange, (page, index: number) => {\n if (page === ELLIPSIS) {\n return (\n <span key={index} className={prefixCls('ellipsis')}>\n <Ellipsis size={20} />\n </span>\n );\n }\n return (\n <Button\n key={index}\n icon={<span>{page}</span>}\n className={cn(prefixCls('button'), {\n [prefixCls('active')]: page === current,\n })}\n onClick={onChangePage(page)}\n />\n );\n })}\n <Button\n icon={<ChevronRightLine size={16} />}\n onClick={onChangePage(current + 1)}\n disabled={current >= totalPage}\n />\n </div>\n\n {/* 页面大小选择器 */}\n {showSizeChanger && (\n <PageSizeChanger\n pageSize={pageSize}\n pageSizeOptions={pageSizeOptions}\n onChange={handlePageSizeChange}\n />\n )}\n </div>\n );\n}\n\nexport default Pagination;\n\n/**\n * 获取在安全范围内的当前页数\n */\nexport function getSafeCurrent(totalPage: number, current?: number) {\n if (current === undefined) {\n return 1;\n }\n return Math.max(1, Math.min(current, totalPage));\n}\n\nfunction getTotalPage(total: number, pageSize: number) {\n return Math.max(1, Math.ceil(total / pageSize));\n}\n\nexport const ELLIPSIS = '...';\n\nexport type PaginationItemType = number | typeof ELLIPSIS;\n\n/**\n * 获取分页组件需要显示的页码范围。\n *\n * @param totalPage 最大页码。\n * @param currentPage 当前所在的页码。\n *\n * 如果总页数不超过5页,直接返回所有页码。\n * 否则,在生成页码时,除了第一页和最后一页,还会显示以当前页为中心的连续页码,数量为 `surroundCount`*2 个,\n * 当当前页码距离边界过近时,会在页码前后添加省略号。\n * 当前页码 `currentPage` 的值必须介于 1 和总页数之间,如果超出这个范围,会自动修正。\n *\n * @returns 一个包含了所有要显示的页码和省略号的数组。\n */\nexport function getPaginationRange(\n totalPage: number,\n currentPage: number,\n): PaginationItemType[] {\n // 如果总页数不超过5页,直接返回所有页码\n if (totalPage <= 5) {\n return Array.from({ length: totalPage }, (_, i) => i + 1);\n }\n\n const surroundCount = 2;\n\n const current = Math.max(1, Math.min(currentPage, totalPage));\n\n let start = Math.max(2, current - surroundCount);\n let end = Math.min(totalPage - 1, current + surroundCount);\n\n // Adjust start and end based on current page\n if (current - start < surroundCount) {\n end = Math.min(end + (surroundCount - (current - start)), totalPage - 1);\n }\n if (end - current < surroundCount) {\n start = Math.max(start - (surroundCount - (end - current)), 2);\n }\n\n // Check if current page is out of range\n if (current < start || current > end) {\n start = Math.max(2, current - surroundCount);\n end = Math.min(totalPage - 1, current + surroundCount);\n }\n\n const range: PaginationItemType[] = [];\n for (let i = start; i <= end; i++) {\n range.push(i);\n }\n\n range.unshift(1);\n if (start > 2 && range[1] !== ELLIPSIS) {\n range.splice(1, 0, ELLIPSIS);\n }\n\n if (totalPage !== range[range.length - 1]) {\n if (end < totalPage - 1 && range[range.length - 1] !== ELLIPSIS) {\n range.splice(range.length, 0, ELLIPSIS);\n }\n range.push(totalPage);\n }\n\n return range;\n}\n\nfunction prefixCls(name: string) {\n return `ald-pagination-${name}`;\n}\n"],"mappings":"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"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
export interface IPaginationProps {
|
|
3
3
|
current?: number;
|
|
4
|
-
defaultCurrent?: number;
|
|
5
4
|
pageSize: number;
|
|
6
5
|
total: number;
|
|
7
6
|
onChange: (current: number, pageSize?: number) => void;
|
|
@@ -10,6 +9,4 @@ export interface IPaginationProps {
|
|
|
10
9
|
pageSizeOptions?: (string | number)[];
|
|
11
10
|
onShowSizeChange?: (current: number, size: number) => void;
|
|
12
11
|
showTotal?: boolean | ((total: number, range: [number, number]) => React.ReactNode);
|
|
13
|
-
disabled?: boolean;
|
|
14
|
-
'aria-label'?: string;
|
|
15
12
|
}
|
|
@@ -68,7 +68,7 @@ function Radio(props) {
|
|
|
68
68
|
}
|
|
69
69
|
}), /* @__PURE__ */ jsx("span", { className: "ald-radio-inner" })]
|
|
70
70
|
}), props.children && /* @__PURE__ */ jsx("span", {
|
|
71
|
-
className: "ald-radio-desc
|
|
71
|
+
className: "ald-radio-desc",
|
|
72
72
|
children: props.children
|
|
73
73
|
})]
|
|
74
74
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/Radio/components/Radio/index.tsx"],"sourcesContent":["import { cn } from '../../../lib/utils';\nimport _ from 'lodash';\nimport React, { useContext, useRef, useState } from 'react';\n\nimport { getUUID } from '../../../_utils/hooks/useId';\nimport { IRadioProps } from '../../interface/radio';\nimport { RadioGroupContext } from '../Group';\n\nexport default function Radio(props: IRadioProps) {\n const groupContext = useContext(RadioGroupContext);\n const labelRef = useRef<HTMLLabelElement>(null);\n const [id] = useState(() => getUUID().toString());\n\n const radioProps = { ...props };\n const inGroup = !_.isEmpty(groupContext);\n const isControlled = 'checked' in props;\n const [innerChecked, setInnerChecked] = useState(\n props.defaultChecked ?? false,\n );\n\n if (inGroup) {\n radioProps.disabled = groupContext.disabled || props.disabled;\n }\n\n // checked 直接从 groupContext 或 props 派生,不使用 useState + useEffect,\n // 避免双重渲染导致切换时视觉抖动。\n const checked = inGroup\n ? groupContext.value === props.value\n : !isControlled\n ? innerChecked\n : radioProps.checked;\n\n // 设置input外层盒子的class\n const aldRadioClass = cn('ald-radio', {\n 'ald-radio-checked': checked,\n 'ald-radio-disabled': radioProps.disabled,\n });\n\n // 根据属性设置最外层的class\n const getWrapperClass = () => {\n let otherClass = '';\n if (groupContext.type === 'button') {\n if (groupContext.radioGroupStyle === 'filled') {\n otherClass = 'ald-radio-button-wrapper-filled';\n } else if (groupContext.radioGroupStyle === 'border') {\n otherClass = 'ald-radio-button-wrapper-border';\n } else if (groupContext.radioGroupStyle === 'filter') {\n otherClass = 'ald-radio-button-wrapper-filter';\n } else {\n otherClass = 'ald-radio-button-wrapper-border-primary';\n }\n } else if (groupContext.type === 'iconButton') {\n if (groupContext.radioGroupStyle === 'filled') {\n otherClass = 'ald-radio-icon-button-wrapper-filled';\n } else if (groupContext.radioGroupStyle === 'border') {\n otherClass = 'ald-radio-icon-button-wrapper-border';\n } else if (groupContext.radioGroupStyle === 'filter') {\n otherClass = 'ald-radio-icon-button-wrapper-filter';\n } else {\n otherClass = 'ald-radio-icon-button-wrapper-border-primary';\n }\n } else {\n // 当type未设置或者是radio时\n otherClass = 'ald-radio-wrapper';\n if (props.indeterminate) {\n otherClass = otherClass + ' ald-radio-wrapper-indeterminate';\n }\n }\n return cn('ald-radio-label', otherClass, props.className, {\n 'ald-radio-wrapper-checked': checked,\n 'ald-radio-wrapper-disabled': radioProps.disabled,\n });\n };\n\n // button / iconButton 模式下,radio 圆圈需要完全隐藏\n const isButtonMode =\n groupContext.type === 'button' || groupContext.type === 'iconButton';\n const radioHideStyle: React.CSSProperties | undefined = isButtonMode\n ? { width: 0, height: 0, overflow: 'hidden' }\n : undefined;\n\n return (\n <label className={getWrapperClass()} htmlFor={id} ref={labelRef}>\n <span className={aldRadioClass} style={radioHideStyle}>\n <input\n id={id}\n type=\"radio\"\n className=\"ald-radio-input\"\n // 同步派生的 checked 到原生 input,对齐 v2/antd 行为(仅有 class 不更新 input.checked)\n checked={!!checked}\n disabled={radioProps.disabled}\n value={props.value}\n onChange={(e) => {\n if (radioProps.disabled) return;\n if (!inGroup && !isControlled) {\n setInnerChecked(e.target.checked);\n }\n props.onChange?.(e);\n }}\n onClick={(e) => {\n props.onClick?.(e);\n\n if (inGroup && groupContext?.onChange) {\n // input事件的value会被toString,所以此处进行一个覆盖\n groupContext.onChange(props.value);\n }\n }}\n />\n <span className=\"ald-radio-inner\" />\n </span>\n {props.children && (\n <span className=\"ald-radio-desc
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/Radio/components/Radio/index.tsx"],"sourcesContent":["import { cn } from '../../../lib/utils';\nimport _ from 'lodash';\nimport React, { useContext, useRef, useState } from 'react';\n\nimport { getUUID } from '../../../_utils/hooks/useId';\nimport { IRadioProps } from '../../interface/radio';\nimport { RadioGroupContext } from '../Group';\n\nexport default function Radio(props: IRadioProps) {\n const groupContext = useContext(RadioGroupContext);\n const labelRef = useRef<HTMLLabelElement>(null);\n const [id] = useState(() => getUUID().toString());\n\n const radioProps = { ...props };\n const inGroup = !_.isEmpty(groupContext);\n const isControlled = 'checked' in props;\n const [innerChecked, setInnerChecked] = useState(\n props.defaultChecked ?? false,\n );\n\n if (inGroup) {\n radioProps.disabled = groupContext.disabled || props.disabled;\n }\n\n // checked 直接从 groupContext 或 props 派生,不使用 useState + useEffect,\n // 避免双重渲染导致切换时视觉抖动。\n const checked = inGroup\n ? groupContext.value === props.value\n : !isControlled\n ? innerChecked\n : radioProps.checked;\n\n // 设置input外层盒子的class\n const aldRadioClass = cn('ald-radio', {\n 'ald-radio-checked': checked,\n 'ald-radio-disabled': radioProps.disabled,\n });\n\n // 根据属性设置最外层的class\n const getWrapperClass = () => {\n let otherClass = '';\n if (groupContext.type === 'button') {\n if (groupContext.radioGroupStyle === 'filled') {\n otherClass = 'ald-radio-button-wrapper-filled';\n } else if (groupContext.radioGroupStyle === 'border') {\n otherClass = 'ald-radio-button-wrapper-border';\n } else if (groupContext.radioGroupStyle === 'filter') {\n otherClass = 'ald-radio-button-wrapper-filter';\n } else {\n otherClass = 'ald-radio-button-wrapper-border-primary';\n }\n } else if (groupContext.type === 'iconButton') {\n if (groupContext.radioGroupStyle === 'filled') {\n otherClass = 'ald-radio-icon-button-wrapper-filled';\n } else if (groupContext.radioGroupStyle === 'border') {\n otherClass = 'ald-radio-icon-button-wrapper-border';\n } else if (groupContext.radioGroupStyle === 'filter') {\n otherClass = 'ald-radio-icon-button-wrapper-filter';\n } else {\n otherClass = 'ald-radio-icon-button-wrapper-border-primary';\n }\n } else {\n // 当type未设置或者是radio时\n otherClass = 'ald-radio-wrapper';\n if (props.indeterminate) {\n otherClass = otherClass + ' ald-radio-wrapper-indeterminate';\n }\n }\n return cn('ald-radio-label', otherClass, props.className, {\n 'ald-radio-wrapper-checked': checked,\n 'ald-radio-wrapper-disabled': radioProps.disabled,\n });\n };\n\n // button / iconButton 模式下,radio 圆圈需要完全隐藏\n const isButtonMode =\n groupContext.type === 'button' || groupContext.type === 'iconButton';\n const radioHideStyle: React.CSSProperties | undefined = isButtonMode\n ? { width: 0, height: 0, overflow: 'hidden' }\n : undefined;\n\n return (\n <label className={getWrapperClass()} htmlFor={id} ref={labelRef}>\n <span className={aldRadioClass} style={radioHideStyle}>\n <input\n id={id}\n type=\"radio\"\n className=\"ald-radio-input\"\n // 同步派生的 checked 到原生 input,对齐 v2/antd 行为(仅有 class 不更新 input.checked)\n checked={!!checked}\n disabled={radioProps.disabled}\n value={props.value}\n onChange={(e) => {\n if (radioProps.disabled) return;\n if (!inGroup && !isControlled) {\n setInnerChecked(e.target.checked);\n }\n props.onChange?.(e);\n }}\n onClick={(e) => {\n props.onClick?.(e);\n\n if (inGroup && groupContext?.onChange) {\n // input事件的value会被toString,所以此处进行一个覆盖\n groupContext.onChange(props.value);\n }\n }}\n />\n <span className=\"ald-radio-inner\" />\n </span>\n {props.children && (\n <span className=\"ald-radio-desc\">{props.children}</span>\n )}\n </label>\n );\n}\n"],"mappings":";;;;;;;AAQA,SAAwB,MAAM,OAAoB;CAChD,MAAM,eAAe,WAAW,kBAAkB;CAClD,MAAM,WAAW,OAAyB,KAAK;CAC/C,MAAM,CAAC,MAAM,eAAe,SAAS,CAAC,UAAU,CAAC;CAEjD,MAAM,aAAa,EAAE,GAAG,OAAO;CAC/B,MAAM,UAAU,CAAC,EAAE,QAAQ,aAAa;CACxC,MAAM,eAAe,aAAa;CAClC,MAAM,CAAC,cAAc,mBAAmB,SACtC,MAAM,kBAAkB,MACzB;AAED,KAAI,QACF,YAAW,WAAW,aAAa,YAAY,MAAM;CAKvD,MAAM,UAAU,UACZ,aAAa,UAAU,MAAM,QAC7B,CAAC,eACD,eACA,WAAW;CAGf,MAAM,gBAAgB,GAAG,aAAa;EACpC,qBAAqB;EACrB,sBAAsB,WAAW;EAClC,CAAC;CAGF,MAAM,wBAAwB;EAC5B,IAAI,aAAa;AACjB,MAAI,aAAa,SAAS,SACxB,KAAI,aAAa,oBAAoB,SACnC,cAAa;WACJ,aAAa,oBAAoB,SAC1C,cAAa;WACJ,aAAa,oBAAoB,SAC1C,cAAa;MAEb,cAAa;WAEN,aAAa,SAAS,aAC/B,KAAI,aAAa,oBAAoB,SACnC,cAAa;WACJ,aAAa,oBAAoB,SAC1C,cAAa;WACJ,aAAa,oBAAoB,SAC1C,cAAa;MAEb,cAAa;OAEV;AAEL,gBAAa;AACb,OAAI,MAAM,cACR,cAAa,aAAa;;AAG9B,SAAO,GAAG,mBAAmB,YAAY,MAAM,WAAW;GACxD,6BAA6B;GAC7B,8BAA8B,WAAW;GAC1C,CAAC;;CAMJ,MAAM,iBADJ,aAAa,SAAS,YAAY,aAAa,SAAS,eAEtD;EAAE,OAAO;EAAG,QAAQ;EAAG,UAAU;EAAU,GAC3C;AAEJ,QACE,qBAAC,SAAD;EAAO,WAAW,iBAAiB;EAAE,SAAS;EAAI,KAAK;YAAvD,CACE,qBAAC,QAAD;GAAM,WAAW;GAAe,OAAO;aAAvC,CACE,oBAAC,SAAD;IACM;IACJ,MAAK;IACL,WAAU;IAEV,SAAS,CAAC,CAAC;IACX,UAAU,WAAW;IACrB,OAAO,MAAM;IACb,WAAW,MAAM;AACf,SAAI,WAAW,SAAU;AACzB,SAAI,CAAC,WAAW,CAAC,aACf,iBAAgB,EAAE,OAAO,QAAQ;AAEnC,WAAM,WAAW,EAAE;;IAErB,UAAU,MAAM;AACd,WAAM,UAAU,EAAE;AAElB,SAAI,WAAW,cAAc,SAE3B,cAAa,SAAS,MAAM,MAAM;;IAGtC,CAAA,EACF,oBAAC,QAAD,EAAM,WAAU,mBAAoB,CAAA,CAC/B;MACN,MAAM,YACL,oBAAC,QAAD;GAAM,WAAU;aAAkB,MAAM;GAAgB,CAAA,CAEpD"}
|
|
@@ -30,7 +30,6 @@ var BaseSelect = React$1.forwardRef((props, ref) => {
|
|
|
30
30
|
const { id, className, displayValues, onDisplayValuesChange, displayMenu, notFoundContent, onClear, width, mode, status: customStatus, onOptionSelect, onClick, size: customSize, borderLess = false, disabled, placeholder, loading = false, open, defaultOpen, onOpenChange, showSearch, innerSearchValue, setInnerSearchValue, allowClear, showArrow = true, prefix, suffixIcon, dropdownRender, overlayStyle, dropdownStyle, popupMatchSelectWidth = true, placement, popupClassName, allowOverlap, style, "data-testid": dataTestid, "aria-label": ariaLabel, ...restProps } = props;
|
|
31
31
|
const setClassNames = prefixCls("select");
|
|
32
32
|
const selectRef = useRef(null);
|
|
33
|
-
const triggerRef = useRef(null);
|
|
34
33
|
const widthStyle = getWidthStyle(width);
|
|
35
34
|
const dropdownRef = useRef(null);
|
|
36
35
|
const [matchedPopupWidth, setMatchedPopupWidth] = useState();
|
|
@@ -44,14 +43,15 @@ var BaseSelect = React$1.forwardRef((props, ref) => {
|
|
|
44
43
|
const { status: contextStatus } = useContext(FormItemInputContext);
|
|
45
44
|
const mergedStatus = customStatus === null ? void 0 : customStatus || contextStatus;
|
|
46
45
|
React$1.useImperativeHandle(ref, () => ({
|
|
47
|
-
focus: () =>
|
|
48
|
-
blur: () =>
|
|
46
|
+
focus: () => setFocus(true),
|
|
47
|
+
blur: () => setFocus(false),
|
|
49
48
|
open: () => onToggleOpen(true),
|
|
50
49
|
close: () => {
|
|
51
50
|
console.log("ref close");
|
|
52
51
|
onToggleOpen(false);
|
|
53
52
|
}
|
|
54
53
|
}));
|
|
54
|
+
const [focus, setFocus] = useState(false);
|
|
55
55
|
const [isHover, setIsHover] = useState(false);
|
|
56
56
|
const [innerOpen, setInnerOpen] = useMergedState(false, {
|
|
57
57
|
defaultValue: defaultOpen,
|
|
@@ -67,7 +67,10 @@ var BaseSelect = React$1.forwardRef((props, ref) => {
|
|
|
67
67
|
const onToggleOpen = React$1.useCallback((newOpen) => {
|
|
68
68
|
const nextOpen = newOpen !== void 0 ? newOpen : !mergedOpen;
|
|
69
69
|
if (nextOpen) updateMatchedPopupWidth();
|
|
70
|
-
if (!nextOpen)
|
|
70
|
+
if (!nextOpen) {
|
|
71
|
+
setShowResponsiveSelectedSection(false);
|
|
72
|
+
setFocus(false);
|
|
73
|
+
}
|
|
71
74
|
if (mergedOpen !== nextOpen && !disabled) {
|
|
72
75
|
setInnerOpen(nextOpen);
|
|
73
76
|
onOpenChange?.(nextOpen);
|
|
@@ -118,8 +121,7 @@ var BaseSelect = React$1.forwardRef((props, ref) => {
|
|
|
118
121
|
});
|
|
119
122
|
};
|
|
120
123
|
const mergedClassName = cn(setClassNames("beta-ald-select", size, {
|
|
121
|
-
|
|
122
|
-
active: mergedOpen,
|
|
124
|
+
active: mergedOpen || focus,
|
|
123
125
|
borderless: borderLess,
|
|
124
126
|
disabled,
|
|
125
127
|
loading,
|
|
@@ -135,7 +137,10 @@ var BaseSelect = React$1.forwardRef((props, ref) => {
|
|
|
135
137
|
onClick: (info) => {
|
|
136
138
|
displayMenu?.onClick?.(info);
|
|
137
139
|
if (isMultipleMode) info.keepOpen = info.keepOpen ?? true;
|
|
138
|
-
else if (displayMenu)
|
|
140
|
+
else if (displayMenu) {
|
|
141
|
+
onToggleOpen(false);
|
|
142
|
+
setFocus(false);
|
|
143
|
+
}
|
|
139
144
|
setIsHover(false);
|
|
140
145
|
onOptionSelect?.(info.key);
|
|
141
146
|
}
|
|
@@ -197,11 +202,6 @@ var BaseSelect = React$1.forwardRef((props, ref) => {
|
|
|
197
202
|
else onToggleOpen(open);
|
|
198
203
|
},
|
|
199
204
|
children: /* @__PURE__ */ jsxs("div", {
|
|
200
|
-
ref: triggerRef,
|
|
201
|
-
tabIndex: disabled ? void 0 : 0,
|
|
202
|
-
role: "combobox",
|
|
203
|
-
"aria-disabled": disabled || void 0,
|
|
204
|
-
"aria-expanded": mergedOpen,
|
|
205
205
|
className: cn(setClassNames("trigger"), "ant-select-selector"),
|
|
206
206
|
children: [
|
|
207
207
|
prefix && /* @__PURE__ */ jsx("div", {
|