@yoka-ui/ui 1.0.4 → 1.0.5
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/@Docs-yoka/exports.generated.md +71 -63
- package/README.md +6 -4
- package/dist/es/business/AiChat/index.js.map +1 -1
- package/dist/es/business/AiChat/intentRecognizer.js.map +1 -1
- package/dist/es/business/AiChat/navigationManager.js +6 -6
- package/dist/es/business/AiChat/navigationManager.js.map +2 -2
- package/dist/es/business/DrawerPageInfo/index.js +2 -2
- package/dist/es/business/DrawerPageInfo/index.js.map +2 -2
- package/dist/es/business/Editor/index.d.ts +1 -1
- package/dist/es/business/Editor/index.js.map +2 -2
- package/dist/es/business/Empty/index.js +1 -1
- package/dist/es/business/Empty/index.js.map +1 -1
- package/dist/es/business/ModCommonFilter/components/PopoverContent/Category.js +2 -2
- package/dist/es/business/ModCommonFilter/components/PopoverContent/Category.js.map +2 -2
- package/dist/es/business/ModCommonFilter/components/PopoverContent/Content.js +3 -3
- package/dist/es/business/ModCommonFilter/components/PopoverContent/Content.js.map +2 -2
- package/dist/es/business/ModCommonFilter/components/PopoverContent/Selected.js +2 -2
- package/dist/es/business/ModCommonFilter/components/PopoverContent/Selected.js.map +2 -2
- package/dist/es/business/ModCommonFilter/index.d.ts +1 -1
- package/dist/es/business/ModCommonFilter/index.js.map +2 -2
- package/dist/es/business/YkPorjectSelect/index.d.ts +1 -1
- package/dist/es/business/YkPorjectSelect/index.js +2 -2
- package/dist/es/business/YkPorjectSelect/index.js.map +2 -2
- package/dist/es/components/DebounceInput/index.js.map +2 -2
- package/dist/es/components/MultipleSelect/index.d.ts +14 -0
- package/dist/es/components/MultipleSelect/index.js +1 -1
- package/dist/es/components/MultipleSelect/index.js.map +2 -2
- package/dist/es/components/RefreshButton/index.js.map +2 -2
- package/dist/es/components/SearchWithHistory/index.js +1 -1
- package/dist/es/components/SearchWithHistory/index.js.map +2 -2
- package/dist/es/components/TextWithToolTip/index.d.ts +1 -1
- package/dist/es/components/TextWithToolTip/index.js.map +2 -2
- package/dist/es/components/TreeTransfer/components/TreeTransferPanel/index.d.ts +1 -24
- package/dist/es/components/TreeTransfer/components/TreeTransferPanel/index.js +2 -2
- package/dist/es/components/TreeTransfer/components/TreeTransferPanel/index.js.map +2 -2
- package/dist/es/components/TreeTransfer/index.d.ts +1 -24
- package/dist/es/components/TreeTransfer/index.js +8 -8
- package/dist/es/components/TreeTransfer/index.js.map +2 -2
- package/dist/es/components/TreeTransfer/utils/index.d.ts +1 -1
- package/dist/es/components/TreeTransfer/utils/index.js.map +2 -2
- package/dist/es/components/YkDateRangePicker/index.d.ts +1 -1
- package/dist/es/components/YkDateRangePicker/index.js +1 -1
- package/dist/es/components/YkDateRangePicker/index.js.map +2 -2
- package/dist/es/components/YkDateRangePicker/index.module.less +2 -1
- package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSCompare.d.ts +1 -1
- package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSCompare.js +3 -2
- package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSCompare.js.map +2 -2
- package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSRange.d.ts +1 -1
- package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSRange.js +60 -9
- package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSRange.js.map +3 -3
- package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSSelect.d.ts +1 -1
- package/dist/es/components/YkRangeDateWithVS/YkRangeDateWithVSSelect.js.map +2 -2
- package/dist/es/components/YkRangeDateWithVS/index.d.ts +4 -4
- package/dist/es/components/YkRangeDateWithVS/index.js +2 -3
- package/dist/es/components/YkRangeDateWithVS/index.js.map +2 -2
- package/dist/es/components/YkRangeDateWithVS/index.module.less +23 -4
- package/dist/es/components/YkRangeTimeWithRecent/index.d.ts +1 -18
- package/dist/es/components/YkRangeTimeWithRecent/index.js +27 -7
- package/dist/es/components/YkRangeTimeWithRecent/index.js.map +2 -2
- package/dist/es/creative/ArcCheckbox/index.d.ts +12 -0
- package/dist/es/creative/ArcCheckbox/index.js +49 -0
- package/dist/es/creative/ArcCheckbox/index.js.map +7 -0
- package/dist/es/creative/ArcCheckbox/index.module.less +102 -0
- package/dist/es/creative/ButtonRadioWithInfo/index.js.map +1 -1
- package/dist/es/creative/ButtonWithProgress/index.d.ts +1 -1
- package/dist/es/creative/ButtonWithProgress/index.js.map +2 -2
- package/dist/es/creative/GlassSegmentedRadio/index.d.ts +24 -0
- package/dist/es/creative/GlassSegmentedRadio/index.js +75 -0
- package/dist/es/creative/GlassSegmentedRadio/index.js.map +7 -0
- package/dist/es/creative/GlassSegmentedRadio/index.module.less +241 -0
- package/dist/es/index.d.ts +30 -26
- package/dist/es/index.js +86 -82
- package/dist/es/index.js.map +2 -2
- package/dist/es/index.less +3 -1
- package/dist/es/layout/FlexGrid/index.d.ts +1 -1
- package/dist/es/layout/FlexGrid/index.js.map +2 -2
- package/dist/es/layout/YkContainer/index.js.map +1 -1
- package/dist/es/layout/YkDrawer/index.d.ts +1 -1
- package/dist/es/layout/YkDrawer/index.js +2 -1
- package/dist/es/layout/YkDrawer/index.js.map +2 -2
- package/dist/es/ui/LabelSelect/demo.js +1 -1
- package/dist/es/ui/LabelSelect/demo.js.map +2 -2
- package/dist/es/ui/LabelSelect/index.d.ts +1 -1
- package/dist/es/ui/LabelSelect/index.js +1 -1
- package/dist/es/ui/LabelSelect/index.js.map +2 -2
- package/dist/es/ui/LogicOperator/index.d.ts +1 -1
- package/dist/es/ui/LogicOperator/index.js.map +2 -2
- package/dist/es/ui/YkButton/index.d.ts +1 -1
- package/dist/es/ui/YkButton/index.js.map +2 -2
- package/dist/es/ui/YkCard/index.d.ts +1 -1
- package/dist/es/ui/YkCard/index.js +1 -1
- package/dist/es/ui/YkCard/index.js.map +2 -2
- package/dist/es/ui/YkCheckbox/index.d.ts +1 -1
- package/dist/es/ui/YkCheckbox/index.js.map +2 -2
- package/dist/es/ui/YkDescriptions/index.d.ts +1 -1
- package/dist/es/ui/YkDescriptions/index.js.map +2 -2
- package/dist/es/ui/YkPagination/index.d.ts +1 -1
- package/dist/es/ui/YkPagination/index.js.map +2 -2
- package/dist/es/ui/YkRadio/index.d.ts +1 -1
- package/dist/es/ui/YkRadio/index.js.map +2 -2
- package/dist/es/ui/YkSegmented/index.d.ts +1 -1
- package/dist/es/ui/YkSegmented/index.js.map +2 -2
- package/dist/es/ui/YkSelect/index.d.ts +1 -1
- package/dist/es/ui/YkSelect/index.js.map +2 -2
- package/dist/es/ui/YkSpin/index.d.ts +1 -1
- package/dist/es/ui/YkSpin/index.js.map +2 -2
- package/dist/es/ui/YkStatistic/index.d.ts +1 -1
- package/dist/es/ui/YkStatistic/index.js.map +2 -2
- package/dist/es/ui/YkSwitch/index.d.ts +1 -1
- package/dist/es/ui/YkSwitch/index.js.map +2 -2
- package/dist/es/ui/YkTabs/index.d.ts +1 -1
- package/dist/es/ui/YkTabs/index.js.map +2 -2
- package/dist/es/ui/YkTooltip/index.d.ts +1 -1
- package/dist/es/ui/YkTooltip/index.js.map +2 -2
- package/dist/es/utils/styleUtils.js.map +2 -2
- package/dist/es/utils/ykStorybookDoc.js +1 -1
- package/dist/es/utils/ykStorybookDoc.js.map +1 -1
- package/dist/lib/business/AiChat/index.js.map +1 -1
- package/dist/lib/business/AiChat/intentRecognizer.js.map +1 -1
- package/dist/lib/business/AiChat/navigationManager.js +6 -6
- package/dist/lib/business/AiChat/navigationManager.js.map +2 -2
- package/dist/lib/business/DrawerPageInfo/index.js +1 -1
- package/dist/lib/business/DrawerPageInfo/index.js.map +2 -2
- package/dist/lib/business/Editor/index.d.ts +1 -1
- package/dist/lib/business/Editor/index.js.map +2 -2
- package/dist/lib/business/Empty/index.js +1 -1
- package/dist/lib/business/Empty/index.js.map +1 -1
- package/dist/lib/business/ModCommonFilter/components/PopoverContent/Category.js +3 -3
- package/dist/lib/business/ModCommonFilter/components/PopoverContent/Category.js.map +2 -2
- package/dist/lib/business/ModCommonFilter/components/PopoverContent/Content.js +4 -4
- package/dist/lib/business/ModCommonFilter/components/PopoverContent/Content.js.map +2 -2
- package/dist/lib/business/ModCommonFilter/components/PopoverContent/Selected.js +3 -3
- package/dist/lib/business/ModCommonFilter/components/PopoverContent/Selected.js.map +2 -2
- package/dist/lib/business/ModCommonFilter/index.d.ts +1 -1
- package/dist/lib/business/ModCommonFilter/index.js.map +2 -2
- package/dist/lib/business/YkPorjectSelect/index.d.ts +1 -1
- package/dist/lib/business/YkPorjectSelect/index.js +3 -3
- package/dist/lib/business/YkPorjectSelect/index.js.map +2 -2
- package/dist/lib/components/DebounceInput/index.js.map +2 -2
- package/dist/lib/components/MultipleSelect/index.d.ts +14 -0
- package/dist/lib/components/MultipleSelect/index.js +1 -1
- package/dist/lib/components/MultipleSelect/index.js.map +2 -2
- package/dist/lib/components/RefreshButton/index.js.map +2 -2
- package/dist/lib/components/SearchWithHistory/index.js +1 -1
- package/dist/lib/components/SearchWithHistory/index.js.map +2 -2
- package/dist/lib/components/TextWithToolTip/index.d.ts +1 -1
- package/dist/lib/components/TextWithToolTip/index.js.map +2 -2
- package/dist/lib/components/TreeTransfer/components/TreeTransferPanel/index.d.ts +1 -24
- package/dist/lib/components/TreeTransfer/components/TreeTransferPanel/index.js +2 -2
- package/dist/lib/components/TreeTransfer/components/TreeTransferPanel/index.js.map +2 -2
- package/dist/lib/components/TreeTransfer/index.d.ts +1 -24
- package/dist/lib/components/TreeTransfer/index.js +3 -3
- package/dist/lib/components/TreeTransfer/index.js.map +2 -2
- package/dist/lib/components/TreeTransfer/utils/index.d.ts +1 -1
- package/dist/lib/components/TreeTransfer/utils/index.js.map +2 -2
- package/dist/lib/components/YkDateRangePicker/index.d.ts +1 -1
- package/dist/lib/components/YkDateRangePicker/index.js +1 -1
- package/dist/lib/components/YkDateRangePicker/index.js.map +2 -2
- package/dist/lib/components/YkDateRangePicker/index.module.less +2 -1
- package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSCompare.d.ts +1 -1
- package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSCompare.js +3 -2
- package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSCompare.js.map +2 -2
- package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSRange.d.ts +1 -1
- package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSRange.js +59 -8
- package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSRange.js.map +3 -3
- package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSSelect.d.ts +1 -1
- package/dist/lib/components/YkRangeDateWithVS/YkRangeDateWithVSSelect.js.map +2 -2
- package/dist/lib/components/YkRangeDateWithVS/index.d.ts +4 -4
- package/dist/lib/components/YkRangeDateWithVS/index.js +4 -5
- package/dist/lib/components/YkRangeDateWithVS/index.js.map +3 -3
- package/dist/lib/components/YkRangeDateWithVS/index.module.less +23 -4
- package/dist/lib/components/YkRangeTimeWithRecent/index.d.ts +1 -18
- package/dist/lib/components/YkRangeTimeWithRecent/index.js +27 -7
- package/dist/lib/components/YkRangeTimeWithRecent/index.js.map +2 -2
- package/dist/lib/creative/ArcCheckbox/index.d.ts +12 -0
- package/dist/lib/creative/ArcCheckbox/index.js +50 -0
- package/dist/lib/creative/ArcCheckbox/index.js.map +7 -0
- package/dist/lib/creative/ArcCheckbox/index.module.less +102 -0
- package/dist/lib/creative/ButtonRadioWithInfo/index.js.map +1 -1
- package/dist/lib/creative/ButtonWithProgress/index.d.ts +1 -1
- package/dist/lib/creative/ButtonWithProgress/index.js.map +2 -2
- package/dist/lib/creative/GlassSegmentedRadio/index.d.ts +24 -0
- package/dist/lib/creative/GlassSegmentedRadio/index.js +78 -0
- package/dist/lib/creative/GlassSegmentedRadio/index.js.map +7 -0
- package/dist/lib/creative/GlassSegmentedRadio/index.module.less +241 -0
- package/dist/lib/index.d.ts +30 -26
- package/dist/lib/index.js +31 -25
- package/dist/lib/index.js.map +2 -2
- package/dist/lib/index.less +3 -1
- package/dist/lib/layout/FlexGrid/index.d.ts +1 -1
- package/dist/lib/layout/FlexGrid/index.js.map +2 -2
- package/dist/lib/layout/YkContainer/index.js.map +1 -1
- package/dist/lib/layout/YkDrawer/index.d.ts +1 -1
- package/dist/lib/layout/YkDrawer/index.js +2 -1
- package/dist/lib/layout/YkDrawer/index.js.map +2 -2
- package/dist/lib/ui/LabelSelect/demo.js +1 -1
- package/dist/lib/ui/LabelSelect/demo.js.map +2 -2
- package/dist/lib/ui/LabelSelect/index.d.ts +1 -1
- package/dist/lib/ui/LabelSelect/index.js +1 -1
- package/dist/lib/ui/LabelSelect/index.js.map +2 -2
- package/dist/lib/ui/LogicOperator/index.d.ts +1 -1
- package/dist/lib/ui/LogicOperator/index.js.map +2 -2
- package/dist/lib/ui/YkButton/index.d.ts +1 -1
- package/dist/lib/ui/YkButton/index.js.map +2 -2
- package/dist/lib/ui/YkCard/index.d.ts +1 -1
- package/dist/lib/ui/YkCard/index.js.map +2 -2
- package/dist/lib/ui/YkCheckbox/index.d.ts +1 -1
- package/dist/lib/ui/YkCheckbox/index.js.map +2 -2
- package/dist/lib/ui/YkDescriptions/index.d.ts +1 -1
- package/dist/lib/ui/YkDescriptions/index.js.map +2 -2
- package/dist/lib/ui/YkPagination/index.d.ts +1 -1
- package/dist/lib/ui/YkPagination/index.js.map +2 -2
- package/dist/lib/ui/YkRadio/index.d.ts +1 -1
- package/dist/lib/ui/YkRadio/index.js.map +2 -2
- package/dist/lib/ui/YkSegmented/index.d.ts +1 -1
- package/dist/lib/ui/YkSegmented/index.js.map +2 -2
- package/dist/lib/ui/YkSelect/index.d.ts +1 -1
- package/dist/lib/ui/YkSelect/index.js.map +2 -2
- package/dist/lib/ui/YkSpin/index.d.ts +1 -1
- package/dist/lib/ui/YkSpin/index.js.map +2 -2
- package/dist/lib/ui/YkStatistic/index.d.ts +1 -1
- package/dist/lib/ui/YkStatistic/index.js.map +2 -2
- package/dist/lib/ui/YkSwitch/index.d.ts +1 -1
- package/dist/lib/ui/YkSwitch/index.js.map +2 -2
- package/dist/lib/ui/YkTabs/index.d.ts +1 -1
- package/dist/lib/ui/YkTabs/index.js.map +2 -2
- package/dist/lib/ui/YkTooltip/index.d.ts +1 -1
- package/dist/lib/ui/YkTooltip/index.js.map +2 -2
- package/dist/lib/utils/styleUtils.js.map +2 -2
- package/dist/lib/utils/ykStorybookDoc.js +1 -1
- package/dist/lib/utils/ykStorybookDoc.js.map +1 -1
- package/package.json +137 -144
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/business/DrawerPageInfo/index.tsx"],
|
|
4
|
-
"sourcesContent": ["import { DislikeOutlined, LikeOutlined } from '@ant-design/icons';\nimport { Button, Divider, Drawer, Modal, Skeleton } from 'antd';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\nimport styles from './index.module.less';\n\n/** 提示内容数据结构,与 loadData 返回一致 */\nexport interface TipContentData {\n tip_id: number;\n tip_name: string;\n content: string;\n stared: boolean;\n unstared: boolean;\n}\n\n/** 反馈接口参数 */\nexport interface FeedbackParams {\n stared?: boolean;\n unstared?: boolean;\n}\n\n/**\n * DrawerPageInfo 组件的 Props\n * 数据与请求通过 loadData / onFeedback 由父组件负责,组件仅负责展示与交互。\n */\nexport type PropsType = {\n /** 当前提示页 id,用于 loadData / onFeedback 入参 */\n id: number | string;\n /** 抽屉是否打开 */\n open: boolean;\n /** 抽屉打开状态变化回调(关闭时由组件调用) */\n onOpenChange?: (open: boolean) => void;\n /** 加载内容:抽屉打开且 id 有效时由组件调用,父组件请求后返回数据 */\n loadData: (id: number) => Promise<TipContentData>;\n /** 提交反馈(点赞/点踩):父组件请求接口,组件在成功后更新本地状态 */\n onFeedback: (id: number, params: FeedbackParams) => Promise<void>;\n};\n\nconst FEEDBACK_RESET_DELAY = 200;\n\n/**\n * 抽屉式提示页:展示富文本内容与点赞/点踩反馈,内容与反馈请求通过 props 回调解耦。\n */\nconst DrawerPageInfo: React.FC<PropsType> = ({ id, open, onOpenChange, loadData, onFeedback }) => {\n const numericId = Number(id);\n const onOpenChangeFn = onOpenChange ?? (() => {});\n const [title, setTitle] = useState('');\n const [content, setContent] = useState('');\n const [stared, setStared] = useState(false);\n const [unstared, setUnstared] = useState(false);\n const [loading, setLoading] = useState(false);\n const [feedbackLoading, setFeedbackLoading] = useState(false);\n\n const [previewOpen, setPreviewOpen] = useState(false);\n const [previewSrc, setPreviewSrc] = useState('');\n const richTextRef = useRef<HTMLDivElement>(null);\n\n /** 打开时根据 id 拉取内容 */\n useEffect(() => {\n if (!open || !numericId || Number.isNaN(numericId)) return;\n setLoading(true);\n loadData(numericId)\n .then((data) => {\n setTitle(data.tip_name);\n setContent(data.content);\n setStared(data.stared);\n setUnstared(data.unstared);\n })\n .finally(() => setLoading(false));\n }, [open, numericId, loadData]);\n\n const onClose = useCallback(() => {\n setContent('');\n onOpenChangeFn(false);\n }, [onOpenChangeFn]);\n\n /** 点赞:若已点踩则先取消点踩再点赞,否则直接点赞 */\n const handleLike = useCallback(() => {\n setFeedbackLoading(true);\n const nextStared = !stared;\n const run = unstared\n ? onFeedback(numericId, { unstared: false }).then(() => onFeedback(numericId, { stared: nextStared }))\n : onFeedback(numericId, { stared: nextStared });\n\n run\n .then(() => {\n setStared(nextStared);\n if (unstared) setUnstared(false);\n })\n .finally(() => {\n setTimeout(() => setFeedbackLoading(false), FEEDBACK_RESET_DELAY);\n });\n }, [numericId, stared, unstared, onFeedback]);\n\n /** 点踩:若已点赞则先取消点赞再点踩,否则直接点踩 */\n const handleDislike = useCallback(() => {\n setFeedbackLoading(true);\n const nextUnstared = !unstared;\n const run = stared\n ? onFeedback(numericId, { stared: false }).then(() => onFeedback(numericId, { unstared: nextUnstared }))\n : onFeedback(numericId, { unstared: nextUnstared });\n\n run\n .then(() => {\n setUnstared(nextUnstared);\n if (stared) setStared(false);\n })\n .finally(() => {\n setTimeout(() => setFeedbackLoading(false), FEEDBACK_RESET_DELAY);\n });\n }, [numericId, stared, unstared, onFeedback]);\n\n /** 富文本内图片点击放大:content 变化后重新绑定 */\n useEffect(() => {\n const el = richTextRef.current;\n if (!el || !content) return;\n const images = el.querySelectorAll<HTMLImageElement>('img');\n const handler = (e: Event) => {\n const img = e.currentTarget as HTMLImageElement;\n if (img?.src) {\n setPreviewSrc(img.src);\n setPreviewOpen(true);\n }\n };\n images.forEach((img) => {\n img.style.cursor = 'pointer';\n img.addEventListener('click', handler);\n });\n return () => images.forEach((img) => img.removeEventListener('click', handler));\n }, [content]);\n\n const showThanks = (stared || unstared) && !feedbackLoading;\n\n if (!numericId || Number.isNaN(numericId)) return null;\n\n return (\n <Drawer\n title={title}\n width={600}\n open={open}\n onClose={onClose}\n extra={\n <div className={styles.pageInfoDrawerExtraClose} onClick={onClose} role='button' tabIndex={0}>\n <
|
|
5
|
-
"mappings": ";AAAA,SAAS,iBAAiB,oBAAoB;
|
|
4
|
+
"sourcesContent": ["import { CloseOutlined, DislikeOutlined, LikeOutlined } from '@ant-design/icons';\nimport { Button, Divider, Drawer, Modal, Skeleton } from 'antd';\nimport React, { useCallback, useEffect, useRef, useState } from 'react';\nimport styles from './index.module.less';\n\n/** 提示内容数据结构,与 loadData 返回一致 */\nexport interface TipContentData {\n tip_id: number;\n tip_name: string;\n content: string;\n stared: boolean;\n unstared: boolean;\n}\n\n/** 反馈接口参数 */\nexport interface FeedbackParams {\n stared?: boolean;\n unstared?: boolean;\n}\n\n/**\n * DrawerPageInfo 组件的 Props\n * 数据与请求通过 loadData / onFeedback 由父组件负责,组件仅负责展示与交互。\n */\nexport type PropsType = {\n /** 当前提示页 id,用于 loadData / onFeedback 入参 */\n id: number | string;\n /** 抽屉是否打开 */\n open: boolean;\n /** 抽屉打开状态变化回调(关闭时由组件调用) */\n onOpenChange?: (open: boolean) => void;\n /** 加载内容:抽屉打开且 id 有效时由组件调用,父组件请求后返回数据 */\n loadData: (id: number) => Promise<TipContentData>;\n /** 提交反馈(点赞/点踩):父组件请求接口,组件在成功后更新本地状态 */\n onFeedback: (id: number, params: FeedbackParams) => Promise<void>;\n};\n\nconst FEEDBACK_RESET_DELAY = 200;\n\n/**\n * 抽屉式提示页:展示富文本内容与点赞/点踩反馈,内容与反馈请求通过 props 回调解耦。\n */\nconst DrawerPageInfo: React.FC<PropsType> = ({ id, open, onOpenChange, loadData, onFeedback }) => {\n const numericId = Number(id);\n const onOpenChangeFn = onOpenChange ?? (() => {});\n const [title, setTitle] = useState('');\n const [content, setContent] = useState('');\n const [stared, setStared] = useState(false);\n const [unstared, setUnstared] = useState(false);\n const [loading, setLoading] = useState(false);\n const [feedbackLoading, setFeedbackLoading] = useState(false);\n\n const [previewOpen, setPreviewOpen] = useState(false);\n const [previewSrc, setPreviewSrc] = useState('');\n const richTextRef = useRef<HTMLDivElement>(null);\n\n /** 打开时根据 id 拉取内容 */\n useEffect(() => {\n if (!open || !numericId || Number.isNaN(numericId)) return;\n setLoading(true);\n loadData(numericId)\n .then((data) => {\n setTitle(data.tip_name);\n setContent(data.content);\n setStared(data.stared);\n setUnstared(data.unstared);\n })\n .finally(() => setLoading(false));\n }, [open, numericId, loadData]);\n\n const onClose = useCallback(() => {\n setContent('');\n onOpenChangeFn(false);\n }, [onOpenChangeFn]);\n\n /** 点赞:若已点踩则先取消点踩再点赞,否则直接点赞 */\n const handleLike = useCallback(() => {\n setFeedbackLoading(true);\n const nextStared = !stared;\n const run = unstared\n ? onFeedback(numericId, { unstared: false }).then(() => onFeedback(numericId, { stared: nextStared }))\n : onFeedback(numericId, { stared: nextStared });\n\n run\n .then(() => {\n setStared(nextStared);\n if (unstared) setUnstared(false);\n })\n .finally(() => {\n setTimeout(() => setFeedbackLoading(false), FEEDBACK_RESET_DELAY);\n });\n }, [numericId, stared, unstared, onFeedback]);\n\n /** 点踩:若已点赞则先取消点赞再点踩,否则直接点踩 */\n const handleDislike = useCallback(() => {\n setFeedbackLoading(true);\n const nextUnstared = !unstared;\n const run = stared\n ? onFeedback(numericId, { stared: false }).then(() => onFeedback(numericId, { unstared: nextUnstared }))\n : onFeedback(numericId, { unstared: nextUnstared });\n\n run\n .then(() => {\n setUnstared(nextUnstared);\n if (stared) setStared(false);\n })\n .finally(() => {\n setTimeout(() => setFeedbackLoading(false), FEEDBACK_RESET_DELAY);\n });\n }, [numericId, stared, unstared, onFeedback]);\n\n /** 富文本内图片点击放大:content 变化后重新绑定 */\n useEffect(() => {\n const el = richTextRef.current;\n if (!el || !content) return;\n const images = el.querySelectorAll<HTMLImageElement>('img');\n const handler = (e: Event) => {\n const img = e.currentTarget as HTMLImageElement;\n if (img?.src) {\n setPreviewSrc(img.src);\n setPreviewOpen(true);\n }\n };\n images.forEach((img) => {\n img.style.cursor = 'pointer';\n img.addEventListener('click', handler);\n });\n return () => images.forEach((img) => img.removeEventListener('click', handler));\n }, [content]);\n\n const showThanks = (stared || unstared) && !feedbackLoading;\n\n if (!numericId || Number.isNaN(numericId)) return null;\n\n return (\n <Drawer\n title={title}\n width={600}\n open={open}\n onClose={onClose}\n extra={\n <div className={styles.pageInfoDrawerExtraClose} onClick={onClose} role='button' tabIndex={0}>\n <CloseOutlined />\n </div>\n }\n maskClosable={false}\n className={styles.drawerTipInfo}\n >\n {loading ? (\n <Skeleton active />\n ) : (\n <>\n <div ref={richTextRef} className={styles.boxTipHtml} dangerouslySetInnerHTML={{ __html: content }} />\n <div className={styles.boxStared}>\n <Divider plain style={{ margin: '10px 0' }}>\n 此内容是否有帮助\n </Divider>\n <div className={styles.btnsStared}>\n <Button\n type={stared ? 'primary' : 'default'}\n shape='circle'\n loading={feedbackLoading}\n disabled={feedbackLoading}\n icon={<LikeOutlined />}\n onClick={handleLike}\n />\n <Button\n type={unstared ? 'primary' : 'default'}\n shape='circle'\n loading={feedbackLoading}\n disabled={feedbackLoading}\n icon={<DislikeOutlined />}\n onClick={handleDislike}\n />\n </div>\n <div className={styles.thanksTip} style={{ cursor: 'default', opacity: showThanks ? 1 : 0 }}>\n 感谢您的反馈\n </div>\n </div>\n </>\n )}\n <Modal\n title='图片'\n style={{ top: 20 }}\n open={previewOpen}\n onCancel={() => {\n setPreviewOpen(false);\n setPreviewSrc('');\n }}\n footer={null}\n width='80%'\n >\n <img src={previewSrc} alt='预览' style={{ width: '100%' }} />\n </Modal>\n </Drawer>\n );\n};\n\nexport default DrawerPageInfo;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/business/Editor/index.tsx"],
|
|
4
|
-
"sourcesContent": ["import { IDomEditor, IEditorConfig } from '@wangeditor/editor';\nimport { Editor } from '@wangeditor/editor-for-react';\nimport '@wangeditor/editor/dist/css/style.css'; // 引入 css\nimport React, { FC, useEffect, useState } from 'react';\nimport './index.less';\n\ntype PageTypes = {\n value: string;\n onChange?: (value: string) => void;\n style?: React.CSSProperties;\n readOnly?: boolean;\n};\n\nconst NoteEditor: FC<PageTypes> = ({ value, onChange, style, readOnly = false }) => {\n // editor 实例\n const [editor, setEditor] = useState<IDomEditor | null>(null);\n\n // 编辑器配置\n const editorConfig: Partial<IEditorConfig> = {\n placeholder: '请输入内容...',\n readOnly: readOnly,\n // 配置 hoverbar 菜单项\n hoverbarKeys: {\n text: {\n menuKeys: [\n 'headerSelect', // N级标题\n 'justifyLeft', // 左对齐按钮\n 'justifyCenter', // 居中按钮\n 'justifyRight', // 右对齐按钮\n 'bulletedList', // 无序列表\n 'numberedList', // 有序列表\n '|', // 分隔符\n 'color', // 字色\n 'bgColor', // 字背景\n 'bold', // 加粗按钮\n 'through', // 删除按钮(删除线)\n 'italic', // 斜体按钮\n 'underline', // 下划线按钮\n ],\n },\n },\n };\n\n // 及时销毁 editor ,重要!\n useEffect(() => {\n return () => {\n if (editor === null) return;\n editor.destroy();\n setEditor(null);\n };\n }, [editor]);\n\n return (\n <Editor\n defaultConfig={editorConfig}\n value={value}\n onCreated={setEditor}\n onChange={(editor) => onChange?.(editor.getHtml())}\n mode='default'\n style={{ ...style }}\n />\n );\n};\n\nexport default NoteEditor;\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AACA,SAAS,cAAc;AACvB,OAAO;AACP,OAAO,
|
|
4
|
+
"sourcesContent": ["import type { IDomEditor, IEditorConfig } from '@wangeditor/editor';\nimport { Editor } from '@wangeditor/editor-for-react';\nimport '@wangeditor/editor/dist/css/style.css'; // 引入 css\nimport React, { type FC, useEffect, useState } from 'react';\nimport './index.less';\n\ntype PageTypes = {\n value: string;\n onChange?: (value: string) => void;\n style?: React.CSSProperties;\n readOnly?: boolean;\n};\n\nconst NoteEditor: FC<PageTypes> = ({ value, onChange, style, readOnly = false }) => {\n // editor 实例\n const [editor, setEditor] = useState<IDomEditor | null>(null);\n\n // 编辑器配置\n const editorConfig: Partial<IEditorConfig> = {\n placeholder: '请输入内容...',\n readOnly: readOnly,\n // 配置 hoverbar 菜单项\n hoverbarKeys: {\n text: {\n menuKeys: [\n 'headerSelect', // N级标题\n 'justifyLeft', // 左对齐按钮\n 'justifyCenter', // 居中按钮\n 'justifyRight', // 右对齐按钮\n 'bulletedList', // 无序列表\n 'numberedList', // 有序列表\n '|', // 分隔符\n 'color', // 字色\n 'bgColor', // 字背景\n 'bold', // 加粗按钮\n 'through', // 删除按钮(删除线)\n 'italic', // 斜体按钮\n 'underline', // 下划线按钮\n ],\n },\n },\n };\n\n // 及时销毁 editor ,重要!\n useEffect(() => {\n return () => {\n if (editor === null) return;\n editor.destroy();\n setEditor(null);\n };\n }, [editor]);\n\n return (\n <Editor\n defaultConfig={editorConfig}\n value={value}\n onCreated={setEditor}\n onChange={(editor) => onChange?.(editor.getHtml())}\n mode='default'\n style={{ ...style }}\n />\n );\n};\n\nexport default NoteEditor;\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AACA,SAAS,cAAc;AACvB,OAAO;AACP,OAAO,SAAkB,WAAW,gBAAgB;AACpD,OAAO;AASP,IAAM,aAA4B,CAAC,EAAE,OAAO,UAAU,OAAO,WAAW,MAAM,MAAM;AAElF,QAAM,CAAC,QAAQ,SAAS,IAAI,SAA4B,IAAI;AAG5D,QAAM,eAAuC;AAAA,IAC3C,aAAa;AAAA,IACb;AAAA;AAAA,IAEA,cAAc;AAAA,MACZ,MAAM;AAAA,QACJ,UAAU;AAAA,UACR;AAAA;AAAA,UACA;AAAA;AAAA,UACA;AAAA;AAAA,UACA;AAAA;AAAA,UACA;AAAA;AAAA,UACA;AAAA;AAAA,UACA;AAAA;AAAA,UACA;AAAA;AAAA,UACA;AAAA;AAAA,UACA;AAAA;AAAA,UACA;AAAA;AAAA,UACA;AAAA;AAAA,UACA;AAAA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,YAAU,MAAM;AACd,WAAO,MAAM;AACX,UAAI,WAAW;AAAM;AACrB,aAAO,QAAQ;AACf,gBAAU,IAAI;AAAA,IAChB;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAe;AAAA,MACf;AAAA,MACA,WAAW;AAAA,MACX,UAAU,CAACA,YAAW,qCAAWA,QAAO,QAAQ;AAAA,MAChD,MAAK;AAAA,MACL,OAAO,mBAAK;AAAA;AAAA,EACd;AAEJ;AAEA,IAAO,iBAAQ;",
|
|
6
6
|
"names": ["editor"]
|
|
7
7
|
}
|
|
@@ -43,7 +43,7 @@ var ForwardedEmptyPlaceholder = React.forwardRef(
|
|
|
43
43
|
));
|
|
44
44
|
}
|
|
45
45
|
);
|
|
46
|
-
ForwardedEmptyPlaceholder.displayName = "
|
|
46
|
+
ForwardedEmptyPlaceholder.displayName = "Empty";
|
|
47
47
|
var Empty_default = ForwardedEmptyPlaceholder;
|
|
48
48
|
export {
|
|
49
49
|
Empty_default as default
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/business/Empty/index.tsx"],
|
|
4
|
-
"sourcesContent": ["import { Empty, Flex } from 'antd';\nimport type { ForwardedRef } from 'react';\nimport React from 'react';\nimport EmptyImg from './empty.png';\n\n/**\n * 空状态占位组件的 Props(ref 由 forwardRef 注入,无需在 props 中声明)\n */\ntype EmptyProps = {\n /** 空状态插图,不传则使用默认 empty.png */\n image?: React.ReactNode | string;\n /** 描述文案或自定义节点,默认「暂无数据」 */\n description?: string | React.ReactNode;\n /** 图片容器样式,会与默认宽高合并 */\n imageStyle?: React.CSSProperties;\n /** 根节点 Flex 的样式 */\n style?: React.CSSProperties;\n};\n\n/** 描述文字统一样式 */\nconst descriptionStyle: React.CSSProperties = {\n color: '#999',\n fontSize: 14,\n height: 20,\n lineHeight: '20px',\n};\n\n/**\n * 空状态占位:居中展示默认图 + 描述,支持自定义图片与文案,支持 ref 透传。\n */\nconst ForwardedEmptyPlaceholder = React.forwardRef(\n ({ image, description, imageStyle = {}, style = {} }: EmptyProps, ref: ForwardedRef<HTMLDivElement>) => {\n return (\n <Flex ref={ref} style={{ padding: '80px 0', ...style }} align
|
|
4
|
+
"sourcesContent": ["import { Empty, Flex } from 'antd';\nimport type { ForwardedRef } from 'react';\nimport React from 'react';\nimport EmptyImg from './empty.png';\n\n/**\n * 空状态占位组件的 Props(ref 由 forwardRef 注入,无需在 props 中声明)\n */\ntype EmptyProps = {\n /** 空状态插图,不传则使用默认 empty.png */\n image?: React.ReactNode | string;\n /** 描述文案或自定义节点,默认「暂无数据」 */\n description?: string | React.ReactNode;\n /** 图片容器样式,会与默认宽高合并 */\n imageStyle?: React.CSSProperties;\n /** 根节点 Flex 的样式 */\n style?: React.CSSProperties;\n};\n\n/** 描述文字统一样式 */\nconst descriptionStyle: React.CSSProperties = {\n color: '#999',\n fontSize: 14,\n height: 20,\n lineHeight: '20px',\n};\n\n/**\n * 空状态占位:居中展示默认图 + 描述,支持自定义图片与文案,支持 ref 透传。\n */\nconst ForwardedEmptyPlaceholder = React.forwardRef(\n ({ image, description, imageStyle = {}, style = {} }: EmptyProps, ref: ForwardedRef<HTMLDivElement>) => {\n return (\n <Flex ref={ref} style={{ padding: '80px 0', ...style }} align=\"center\" justify=\"center\">\n <Empty\n image={image || EmptyImg}\n styles={{\n image: {\n height: 60,\n width: 150,\n display: 'inline-block',\n ...imageStyle,\n },\n }}\n description={\n description == null || description === '' ? (\n <span style={descriptionStyle}>暂无数据</span>\n ) : typeof description === 'string' ? (\n <span style={descriptionStyle}>{description}</span>\n ) : (\n description\n )\n }\n />\n </Flex>\n );\n },\n);\n\nForwardedEmptyPlaceholder.displayName = 'Empty';\n\nexport default ForwardedEmptyPlaceholder;\n"],
|
|
5
5
|
"mappings": ";;;;;;;;;;;;;;;;;;AAAA,SAAS,OAAO,YAAY;AAE5B,OAAO,WAAW;AAClB,OAAO,cAAc;AAiBrB,IAAM,mBAAwC;AAAA,EAC5C,OAAO;AAAA,EACP,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,YAAY;AACd;AAKA,IAAM,4BAA4B,MAAM;AAAA,EACtC,CAAC,EAAE,OAAO,aAAa,aAAa,CAAC,GAAG,QAAQ,CAAC,EAAE,GAAe,QAAsC;AACtG,WACE,oCAAC,QAAK,KAAU,OAAO,iBAAE,SAAS,YAAa,QAAS,OAAM,UAAS,SAAQ,YAC7E;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,SAAS;AAAA,QAChB,QAAQ;AAAA,UACN,OAAO;AAAA,YACL,QAAQ;AAAA,YACR,OAAO;AAAA,YACP,SAAS;AAAA,aACN;AAAA,QAEP;AAAA,QACA,aACE,eAAe,QAAQ,gBAAgB,KACrC,oCAAC,UAAK,OAAO,oBAAkB,MAAI,IACjC,OAAO,gBAAgB,WACzB,oCAAC,UAAK,OAAO,oBAAmB,WAAY,IAE5C;AAAA;AAAA,IAGN,CACF;AAAA,EAEJ;AACF;AAEA,0BAA0B,cAAc;AAExC,IAAO,gBAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -31,10 +31,10 @@ var __objRest = (source, exclude) => {
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
// src/business/ModCommonFilter/components/PopoverContent/Category.tsx
|
|
34
|
-
import TextWithTooltip from "../../../../components/TextWithToolTip";
|
|
35
34
|
import classNames from "classnames";
|
|
36
35
|
import React, { useRef } from "react";
|
|
37
|
-
import { Scrollbars } from "react-custom-scrollbars";
|
|
36
|
+
import { Scrollbars } from "react-custom-scrollbars-2";
|
|
37
|
+
import TextWithTooltip from "../../../../components/TextWithToolTip";
|
|
38
38
|
import IconXiala from "../FilterButton/IconXiala";
|
|
39
39
|
import styles from "./index.module.less";
|
|
40
40
|
var Category = ({ category, categorySelected, setCategorySelected }) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/business/ModCommonFilter/components/PopoverContent/Category.tsx"],
|
|
4
|
-
"sourcesContent": ["import
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,
|
|
4
|
+
"sourcesContent": ["import classNames from 'classnames';\nimport React, { useRef } from 'react';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\nimport TextWithTooltip from '@/components/TextWithToolTip';\nimport type { CategoryItem } from '../../typing';\nimport IconXiala from '../FilterButton/IconXiala';\nimport styles from './index.module.less';\n\n/**\n * 分类组件的 Props\n */\ninterface PropsType {\n /** 分类项列表(code/name) */\n category?: CategoryItem[];\n /** 当前选中的分类 code */\n categorySelected: string;\n /** 设置选中的分类 */\n setCategorySelected: (categorySelected: string) => void;\n}\n\n/**\n * 筛选弹层左侧分类列表:垂直滚动,点击项切换分类并高亮当前项。\n */\nconst Category: React.FC<PropsType> = ({ category, categorySelected, setCategorySelected }) => {\n const scrollLeftRef = useRef<React.ComponentRef<typeof Scrollbars>>(null);\n\n return (\n <div className={styles.category}>\n <Scrollbars\n ref={scrollLeftRef}\n style={{ height: 365 }}\n renderThumbVertical={({ style, ...props }) => (\n <div {...props} style={{ ...style, background: '#EFEFEF', borderRadius: 3 }} />\n )}\n >\n {category?.map((item) => {\n return (\n <div\n onClick={() => {\n setCategorySelected(item.code);\n // setSelfKind(item.isSelf ? item.code : '');\n }}\n key={item.code}\n className={classNames(styles.categoryItem, {\n [styles.categoryItemActive]: categorySelected === item.code,\n })}\n >\n <TextWithTooltip text={item.name} width={100}></TextWithTooltip>\n <IconXiala size={16} className={styles.categoryItemIcon} />\n </div>\n );\n })}\n </Scrollbars>\n </div>\n );\n};\n\nexport default Category;\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,gBAAgB;AACvB,OAAO,SAAS,cAAc;AAC9B,SAAS,kBAAkB;AAC3B,OAAO,qBAAqB;AAE5B,OAAO,eAAe;AACtB,OAAO,YAAY;AAiBnB,IAAM,WAAgC,CAAC,EAAE,UAAU,kBAAkB,oBAAoB,MAAM;AAC7F,QAAM,gBAAgB,OAA8C,IAAI;AAExE,SACE,oCAAC,SAAI,WAAW,OAAO,YACrB;AAAA,IAAC;AAAA;AAAA,MACC,KAAK;AAAA,MACL,OAAO,EAAE,QAAQ,IAAI;AAAA,MACrB,qBAAqB,CAAC,OAAqB;AAArB,qBAAE,QA/BhC,IA+B8B,IAAY,kBAAZ,IAAY,CAAV;AACtB,mDAAC,wCAAQ,QAAR,EAAe,OAAO,iCAAK,QAAL,EAAY,YAAY,WAAW,cAAc,EAAE,KAAG;AAAA;AAAA;AAAA,IAG9E,qCAAU,IAAI,CAAC,SAAS;AACvB,aACE;AAAA,QAAC;AAAA;AAAA,UACC,SAAS,MAAM;AACb,gCAAoB,KAAK,IAAI;AAAA,UAE/B;AAAA,UACA,KAAK,KAAK;AAAA,UACV,WAAW,WAAW,OAAO,cAAc;AAAA,YACzC,CAAC,OAAO,kBAAkB,GAAG,qBAAqB,KAAK;AAAA,UACzD,CAAC;AAAA;AAAA,QAED,oCAAC,mBAAgB,MAAM,KAAK,MAAM,OAAO,KAAK;AAAA,QAC9C,oCAAC,aAAU,MAAM,IAAI,WAAW,OAAO,kBAAkB;AAAA,MAC3D;AAAA,IAEJ;AAAA,EACF,CACF;AAEJ;AAEA,IAAO,mBAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -31,12 +31,12 @@ var __objRest = (source, exclude) => {
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
// src/business/ModCommonFilter/components/PopoverContent/Content.tsx
|
|
34
|
-
import DebouncedInput from "../../../../components/DebounceInput";
|
|
35
|
-
import TextWithTooltip from "../../../../components/TextWithToolTip";
|
|
36
34
|
import { Checkbox, Divider, Tabs } from "antd";
|
|
37
35
|
import React, { useEffect, useMemo, useRef, useState } from "react";
|
|
38
|
-
import { Scrollbars } from "react-custom-scrollbars";
|
|
36
|
+
import { Scrollbars } from "react-custom-scrollbars-2";
|
|
39
37
|
import { Grid } from "react-virtualized";
|
|
38
|
+
import DebouncedInput from "../../../../components/DebounceInput";
|
|
39
|
+
import TextWithTooltip from "../../../../components/TextWithToolTip";
|
|
40
40
|
import emptyImg from "../../assets/images/empty.png";
|
|
41
41
|
import styles from "./index.module.less";
|
|
42
42
|
var Content = ({
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/business/ModCommonFilter/components/PopoverContent/Content.tsx"],
|
|
4
|
-
"sourcesContent": ["import
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,
|
|
4
|
+
"sourcesContent": ["import { Checkbox, Divider, Tabs } from 'antd';\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\nimport { Grid } from 'react-virtualized';\nimport DebouncedInput from '@/components/DebounceInput';\nimport TextWithTooltip from '@/components/TextWithToolTip';\nimport emptyImg from '../../assets/images/empty.png';\nimport type { ListItem, TerminalItem } from '../../typing';\nimport styles from './index.module.less';\n\n/**\n * 可选列表内容区的 Props\n */\ninterface PropsType {\n /** 终端 Tab 数据(如 全部/PC/APP),无则不展示终端 Tab */\n terminal?: TerminalItem[];\n /** 当前分类下的可选列表 */\n list: ListItem[];\n /** 当前已选中的 code 列表 */\n selected: string[];\n /** 更新已选中列表 */\n setSelected: (selected: string[]) => void;\n /** 搜索框占位文案 */\n placeholder: string;\n /** 当前选中的分类 code,用于过滤 list */\n categorySelected: string;\n /** 网格列数 */\n columnCount?: number;\n /** 内容区宽度 */\n contentWidth?: number;\n /** 每行高度 */\n rowHeight?: number;\n /** 每格自定义渲染 */\n cellRender?: (item: ListItem) => React.ReactNode;\n /** 是否在名称后展示 code */\n showCode?: boolean;\n /** 通知父组件「用户是否有过勾选操作」 */\n setHasOperation: (hasOperation: boolean) => void;\n}\n\n/**\n * 筛选弹层中间区域:终端 Tab(可选)+ 搜索 + 全选 + 虚拟列表勾选。\n * 内部维护 modalChecked 与外部 selected 同步,并用 isInternalUpdate 区分内外更新避免循环。\n */\nconst Content: React.FC<PropsType> = ({\n terminal,\n list,\n selected,\n setSelected,\n placeholder,\n categorySelected,\n columnCount = 1,\n contentWidth = 510,\n rowHeight = 32,\n cellRender,\n showCode = false,\n setHasOperation,\n}) => {\n const [searchKey, setSearchKey] = useState<string>('');\n /** 当前选中的终端 Tab(code),空字符串表示「全部」 */\n const [terminalSelected, setTerminalSelected] = useState<string>('');\n /** 弹层内勾选状态(与 selected 同步,用于避免直接改 selected 导致父组件重渲染影响虚拟列表) */\n const [modalChecked, setModalChecked] = useState<string[]>(selected);\n\n /** 已选 code -> true 的 Map,用于 O(1) 判断是否选中 */\n const modalCheckMap = useMemo(() => {\n return new Map(modalChecked.map((item) => [item, true]));\n }, [modalChecked]);\n\n const scrollbarsRef = useRef(null);\n const gridRef = useRef(null);\n /** 标记本次 selected 变更是否由本组件内部更新引起,避免 useEffect 把外部重置误同步进 modalChecked */\n const isInternalUpdate = useRef(false);\n\n /** 外部 selected 变化时同步到 modalChecked;若为内部更新触发的 effect 则跳过避免覆盖 */\n useEffect(() => {\n if (isInternalUpdate.current) {\n isInternalUpdate.current = false;\n return;\n }\n setModalChecked(selected);\n }, [selected]);\n\n /** 根据搜索关键词、终端、分类过滤后的列表,供虚拟列表与全选使用 */\n const filterList = useMemo(() => {\n const key = searchKey.trim().toUpperCase();\n return list\n .filter((v) => v.name.toUpperCase().includes(key) || (showCode && v.code.toUpperCase().includes(key)))\n .filter((f) => terminalSelected === '' || f.terminal === terminalSelected)\n .filter((f) => categorySelected === '' || f.category === categorySelected);\n }, [list, searchKey, terminalSelected, categorySelected]);\n\n /** 全选勾选状态与半选状态(基于当前 filterList 与 modalChecked) */\n const { allChecked, isIndeterminate } = useMemo(() => {\n if (filterList.length === 0) {\n return { allChecked: false, isIndeterminate: false };\n }\n const checkedCount = filterList.filter((item) => modalCheckMap.get(item.code)).length;\n const allChecked = checkedCount === filterList.length;\n const isIndeterminate = checkedCount > 0 && checkedCount < filterList.length;\n return { allChecked, isIndeterminate };\n }, [filterList, modalChecked]);\n\n /** 终端选项列表,头部插入「全部」(code: '') */\n const useTerminal = useMemo(() => {\n const newTerminal: TerminalItem[] = terminal ? [...terminal] : [];\n newTerminal.unshift({\n code: '',\n name: '全部',\n });\n return newTerminal;\n }, [terminal]);\n\n /** 更新弹层内勾选状态并同步到父组件 selected,并标记有过操作 */\n function updateModalChecked(checked: string[]) {\n isInternalUpdate.current = true;\n setModalChecked(checked);\n setSelected(checked);\n setHasOperation(true);\n }\n\n /** 全选/取消全选:仅针对当前 filterList 中的项 */\n const handleAllChecked = (checked: boolean) => {\n const filterCodes = filterList.map((item) => item.code);\n if (checked) {\n // 全选:将过滤列表中的所有项添加到已选列表(去重)\n const newChecked = Array.from(new Set([...modalChecked, ...filterCodes]));\n updateModalChecked(newChecked);\n } else {\n // 取消全选:从已选列表中移除过滤列表中的所有项\n const newChecked = modalChecked.filter((code) => !filterCodes.includes(code));\n updateModalChecked(newChecked);\n }\n };\n\n /** 将 Scrollbars 的滚动事件转发给 Grid,保证虚拟列表滚动一致 */\n const handleScrollbarScroll = (event: React.UIEvent<HTMLDivElement>) => {\n const { scrollTop, scrollLeft } = event.target as HTMLElement;\n if (gridRef.current) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (gridRef.current as any).handleScrollEvent({ scrollTop, scrollLeft });\n }\n };\n\n /** 根据 code 判断该项是否已选中 */\n function isItemChecked(value: string) {\n return modalCheckMap.get(value);\n }\n\n /** 切换单项勾选状态 */\n function checkItem(value: string) {\n if (isItemChecked(value)) {\n updateModalChecked(modalChecked.filter((item) => item !== value));\n } else {\n updateModalChecked([...modalChecked, value]);\n }\n }\n\n return (\n <div className={styles.content}>\n <div className={styles.contentHeader}>\n {terminal && terminal.length > 0 && (\n <>\n <Tabs\n activeKey={terminalSelected}\n items={useTerminal.map((v) => ({\n key: v.code,\n label: v.name,\n }))}\n onChange={(value) => {\n setTerminalSelected(value);\n }}\n />\n <Divider type='vertical' style={{ margin: '0 0 0 20px' }} />\n </>\n )}\n <DebouncedInput\n allowClear={false}\n placeholder={placeholder}\n currentValue={searchKey}\n onChange={(value) => {\n setSearchKey(value);\n }}\n inputClass={styles.search}\n ></DebouncedInput>\n </div>\n <div className={styles.contentList}>\n <div className={styles.checkAll}>\n <Checkbox\n checked={allChecked}\n indeterminate={isIndeterminate}\n onChange={() => {\n handleAllChecked(!allChecked);\n }}\n >\n 全选\n </Checkbox>\n </div>\n <Scrollbars\n style={{ height: 285, width: contentWidth }}\n renderThumbVertical={({ style, ...props }) => (\n <div {...props} style={{ ...style, background: '#EFEFEF', borderRadius: 3 }} />\n )}\n ref={scrollbarsRef}\n onScroll={handleScrollbarScroll}\n >\n <div className={styles.contentListInner}>\n <Grid\n style={{ overflowX: 'visible', overflowY: 'visible' }}\n overscanRowCount={5}\n ref={gridRef}\n columnCount={columnCount}\n rowCount={Math.ceil(filterList.length / columnCount)}\n height={285}\n width={contentWidth - 40}\n columnWidth={(contentWidth - 40) / columnCount}\n rowHeight={rowHeight}\n cellRenderer={({\n columnIndex,\n key,\n rowIndex,\n style,\n }: {\n columnIndex: number;\n key: string;\n rowIndex: number;\n style: React.CSSProperties;\n }) => {\n const item = filterList[rowIndex * columnCount + columnIndex];\n if (!item) return;\n return (\n <div key={key} style={style}>\n <Checkbox\n checked={isItemChecked(item.code)}\n onChange={() => {\n checkItem(item.code);\n }}\n >\n {cellRender ? (\n cellRender(item)\n ) : (\n <TextWithTooltip\n text={item?.name + (showCode ? '(' + item?.code + ')' : '')}\n width={(contentWidth - 40 * columnCount) / columnCount}\n ></TextWithTooltip>\n )}\n </Checkbox>\n </div>\n );\n }}\n noContentRenderer={() => (\n <div className={styles.empty}>\n <img src={emptyImg} alt='' />\n <p>当前搜索条件无数据</p>\n </div>\n )}\n />\n </div>\n </Scrollbars>\n </div>\n </div>\n );\n};\n\nexport default Content;\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,SAAS,UAAU,SAAS,YAAY;AACxC,OAAO,SAAS,WAAW,SAAS,QAAQ,gBAAgB;AAC5D,SAAS,kBAAkB;AAC3B,SAAS,YAAY;AACrB,OAAO,oBAAoB;AAC3B,OAAO,qBAAqB;AAC5B,OAAO,cAAc;AAErB,OAAO,YAAY;AAoCnB,IAAM,UAA+B,CAAC;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,eAAe;AAAA,EACf,YAAY;AAAA,EACZ;AAAA,EACA,WAAW;AAAA,EACX;AACF,MAAM;AACJ,QAAM,CAAC,WAAW,YAAY,IAAI,SAAiB,EAAE;AAErD,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAiB,EAAE;AAEnE,QAAM,CAAC,cAAc,eAAe,IAAI,SAAmB,QAAQ;AAGnE,QAAM,gBAAgB,QAAQ,MAAM;AAClC,WAAO,IAAI,IAAI,aAAa,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,CAAC,CAAC;AAAA,EACzD,GAAG,CAAC,YAAY,CAAC;AAEjB,QAAM,gBAAgB,OAAO,IAAI;AACjC,QAAM,UAAU,OAAO,IAAI;AAE3B,QAAM,mBAAmB,OAAO,KAAK;AAGrC,YAAU,MAAM;AACd,QAAI,iBAAiB,SAAS;AAC5B,uBAAiB,UAAU;AAC3B;AAAA,IACF;AACA,oBAAgB,QAAQ;AAAA,EAC1B,GAAG,CAAC,QAAQ,CAAC;AAGb,QAAM,aAAa,QAAQ,MAAM;AAC/B,UAAM,MAAM,UAAU,KAAK,EAAE,YAAY;AACzC,WAAO,KACJ,OAAO,CAAC,MAAM,EAAE,KAAK,YAAY,EAAE,SAAS,GAAG,KAAM,YAAY,EAAE,KAAK,YAAY,EAAE,SAAS,GAAG,CAAE,EACpG,OAAO,CAAC,MAAM,qBAAqB,MAAM,EAAE,aAAa,gBAAgB,EACxE,OAAO,CAAC,MAAM,qBAAqB,MAAM,EAAE,aAAa,gBAAgB;AAAA,EAC7E,GAAG,CAAC,MAAM,WAAW,kBAAkB,gBAAgB,CAAC;AAGxD,QAAM,EAAE,YAAY,gBAAgB,IAAI,QAAQ,MAAM;AACpD,QAAI,WAAW,WAAW,GAAG;AAC3B,aAAO,EAAE,YAAY,OAAO,iBAAiB,MAAM;AAAA,IACrD;AACA,UAAM,eAAe,WAAW,OAAO,CAAC,SAAS,cAAc,IAAI,KAAK,IAAI,CAAC,EAAE;AAC/E,UAAMA,cAAa,iBAAiB,WAAW;AAC/C,UAAMC,mBAAkB,eAAe,KAAK,eAAe,WAAW;AACtE,WAAO,EAAE,YAAAD,aAAY,iBAAAC,iBAAgB;AAAA,EACvC,GAAG,CAAC,YAAY,YAAY,CAAC;AAG7B,QAAM,cAAc,QAAQ,MAAM;AAChC,UAAM,cAA8B,WAAW,CAAC,GAAG,QAAQ,IAAI,CAAC;AAChE,gBAAY,QAAQ;AAAA,MAClB,MAAM;AAAA,MACN,MAAM;AAAA,IACR,CAAC;AACD,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,CAAC;AAGb,WAAS,mBAAmB,SAAmB;AAC7C,qBAAiB,UAAU;AAC3B,oBAAgB,OAAO;AACvB,gBAAY,OAAO;AACnB,oBAAgB,IAAI;AAAA,EACtB;AAGA,QAAM,mBAAmB,CAAC,YAAqB;AAC7C,UAAM,cAAc,WAAW,IAAI,CAAC,SAAS,KAAK,IAAI;AACtD,QAAI,SAAS;AAEX,YAAM,aAAa,MAAM,KAAK,oBAAI,IAAI,CAAC,GAAG,cAAc,GAAG,WAAW,CAAC,CAAC;AACxE,yBAAmB,UAAU;AAAA,IAC/B,OAAO;AAEL,YAAM,aAAa,aAAa,OAAO,CAAC,SAAS,CAAC,YAAY,SAAS,IAAI,CAAC;AAC5E,yBAAmB,UAAU;AAAA,IAC/B;AAAA,EACF;AAGA,QAAM,wBAAwB,CAAC,UAAyC;AACtE,UAAM,EAAE,WAAW,WAAW,IAAI,MAAM;AACxC,QAAI,QAAQ,SAAS;AAEnB,MAAC,QAAQ,QAAgB,kBAAkB,EAAE,WAAW,WAAW,CAAC;AAAA,IACtE;AAAA,EACF;AAGA,WAAS,cAAc,OAAe;AACpC,WAAO,cAAc,IAAI,KAAK;AAAA,EAChC;AAGA,WAAS,UAAU,OAAe;AAChC,QAAI,cAAc,KAAK,GAAG;AACxB,yBAAmB,aAAa,OAAO,CAAC,SAAS,SAAS,KAAK,CAAC;AAAA,IAClE,OAAO;AACL,yBAAmB,CAAC,GAAG,cAAc,KAAK,CAAC;AAAA,IAC7C;AAAA,EACF;AAEA,SACE,oCAAC,SAAI,WAAW,OAAO,WACrB,oCAAC,SAAI,WAAW,OAAO,iBACpB,YAAY,SAAS,SAAS,KAC7B,0DACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,MACX,OAAO,YAAY,IAAI,CAAC,OAAO;AAAA,QAC7B,KAAK,EAAE;AAAA,QACP,OAAO,EAAE;AAAA,MACX,EAAE;AAAA,MACF,UAAU,CAAC,UAAU;AACnB,4BAAoB,KAAK;AAAA,MAC3B;AAAA;AAAA,EACF,GACA,oCAAC,WAAQ,MAAK,YAAW,OAAO,EAAE,QAAQ,aAAa,GAAG,CAC5D,GAEF;AAAA,IAAC;AAAA;AAAA,MACC,YAAY;AAAA,MACZ;AAAA,MACA,cAAc;AAAA,MACd,UAAU,CAAC,UAAU;AACnB,qBAAa,KAAK;AAAA,MACpB;AAAA,MACA,YAAY,OAAO;AAAA;AAAA,EACpB,CACH,GACA,oCAAC,SAAI,WAAW,OAAO,eACrB,oCAAC,SAAI,WAAW,OAAO,YACrB;AAAA,IAAC;AAAA;AAAA,MACC,SAAS;AAAA,MACT,eAAe;AAAA,MACf,UAAU,MAAM;AACd,yBAAiB,CAAC,UAAU;AAAA,MAC9B;AAAA;AAAA,IACD;AAAA,EAED,CACF,GACA;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,QAAQ,KAAK,OAAO,aAAa;AAAA,MAC1C,qBAAqB,CAAC,OAAqB;AAArB,qBAAE,QAxMlC,IAwMgC,IAAY,kBAAZ,IAAY,CAAV;AACtB,mDAAC,wCAAQ,QAAR,EAAe,OAAO,iCAAK,QAAL,EAAY,YAAY,WAAW,cAAc,EAAE,KAAG;AAAA;AAAA,MAE/E,KAAK;AAAA,MACL,UAAU;AAAA;AAAA,IAEV,oCAAC,SAAI,WAAW,OAAO,oBACrB;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,EAAE,WAAW,WAAW,WAAW,UAAU;AAAA,QACpD,kBAAkB;AAAA,QAClB,KAAK;AAAA,QACL;AAAA,QACA,UAAU,KAAK,KAAK,WAAW,SAAS,WAAW;AAAA,QACnD,QAAQ;AAAA,QACR,OAAO,eAAe;AAAA,QACtB,cAAc,eAAe,MAAM;AAAA,QACnC;AAAA,QACA,cAAc,CAAC;AAAA,UACb;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF,MAKM;AACJ,gBAAM,OAAO,WAAW,WAAW,cAAc,WAAW;AAC5D,cAAI,CAAC;AAAM;AACX,iBACE,oCAAC,SAAI,KAAU,SACb;AAAA,YAAC;AAAA;AAAA,cACC,SAAS,cAAc,KAAK,IAAI;AAAA,cAChC,UAAU,MAAM;AACd,0BAAU,KAAK,IAAI;AAAA,cACrB;AAAA;AAAA,YAEC,aACC,WAAW,IAAI,IAEf;AAAA,cAAC;AAAA;AAAA,gBACC,OAAM,6BAAM,SAAQ,WAAW,OAAM,6BAAM,QAAO,MAAM;AAAA,gBACxD,QAAQ,eAAe,KAAK,eAAe;AAAA;AAAA,YAC5C;AAAA,UAEL,CACF;AAAA,QAEJ;AAAA,QACA,mBAAmB,MACjB,oCAAC,SAAI,WAAW,OAAO,SACrB,oCAAC,SAAI,KAAK,UAAU,KAAI,IAAG,GAC3B,oCAAC,WAAE,WAAS,CACd;AAAA;AAAA,IAEJ,CACF;AAAA,EACF,CACF,CACF;AAEJ;AAEA,IAAO,kBAAQ;",
|
|
6
6
|
"names": ["allChecked", "isIndeterminate"]
|
|
7
7
|
}
|
|
@@ -31,11 +31,11 @@ var __objRest = (source, exclude) => {
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
// src/business/ModCommonFilter/components/PopoverContent/Selected.tsx
|
|
34
|
-
import TextWithTooltip from "../../../../components/TextWithToolTip";
|
|
35
34
|
import classNames from "classnames";
|
|
36
35
|
import React, { useRef } from "react";
|
|
37
|
-
import { Scrollbars } from "react-custom-scrollbars";
|
|
36
|
+
import { Scrollbars } from "react-custom-scrollbars-2";
|
|
38
37
|
import { AutoSizer, List } from "react-virtualized";
|
|
38
|
+
import TextWithTooltip from "../../../../components/TextWithToolTip";
|
|
39
39
|
import styles from "./index.module.less";
|
|
40
40
|
var Selected = ({
|
|
41
41
|
list,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../../../src/business/ModCommonFilter/components/PopoverContent/Selected.tsx"],
|
|
4
|
-
"sourcesContent": ["import
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,
|
|
4
|
+
"sourcesContent": ["import classNames from 'classnames';\nimport React, { useRef } from 'react';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\nimport { AutoSizer, List } from 'react-virtualized';\nimport TextWithTooltip from '@/components/TextWithToolTip';\nimport type { ListItem } from '../../typing';\nimport styles from './index.module.less';\n\n/**\n * 已选列表组件的 Props\n */\ninterface PropsType {\n /** 完整列表数据,用于根据 selected 中的 code 取 name 等信息 */\n list: ListItem[];\n /** 已选中的 code 数组(顺序即展示顺序) */\n selected: string[];\n /** 更新已选列表 */\n setSelected: (selected: string[]) => void;\n /** 内容宽度(当前未在 Selected 内使用,可做预留) */\n contentWidth?: number;\n /** 每行高度 */\n rowHeight?: number;\n /** 是否在名称后展示 code */\n showCode?: boolean;\n /** 已选列表中每行的自定义渲染 */\n checkedCellRender?: (item: ListItem) => React.ReactNode;\n}\n\n/**\n * 筛选弹层右侧已选列表:展示已选数量、清空、虚拟列表逐项展示并可删除。\n */\nconst Selected: React.FC<PropsType> = ({\n list,\n selected,\n setSelected,\n rowHeight = 32,\n showCode,\n checkedCellRender,\n}) => {\n const listScrollbarsRef = useRef<React.ComponentRef<typeof Scrollbars>>(null);\n const listRef = useRef(null);\n\n /** 将 Scrollbars 滚动同步到 List,保证虚拟列表与滚动条一致 */\n const handleListScrollbarScroll = (event: React.UIEvent<HTMLDivElement>) => {\n const { scrollTop, scrollLeft } = event.target as HTMLElement;\n if (listRef.current) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n (listRef.current as any).Grid.handleScrollEvent({ scrollTop, scrollLeft });\n }\n };\n\n return (\n <div className={styles.selected}>\n <div className={styles.selectedHeader}>\n <span>已选{selected.length}个</span>\n <span className={styles.clear} onClick={() => setSelected([])}>\n 清空\n </span>\n </div>\n\n <Scrollbars\n style={{ height: 325 }}\n renderThumbVertical={({ style, ...props }) => (\n <div {...props} style={{ ...style, background: '#EFEFEF', borderRadius: 3 }} />\n )}\n ref={listScrollbarsRef}\n onScroll={handleListScrollbarScroll}\n >\n <div className={styles.selectedContent}>\n <AutoSizer disableHeight>\n {({ width }: { width: number }) => (\n <List\n ref={listRef}\n style={{ overflowX: 'visible', overflowY: 'visible' }}\n rowCount={selected.length}\n height={325}\n width={width}\n rowHeight={rowHeight}\n rowRenderer={({ index, key, style }: { index: number; key: string; style: React.CSSProperties }) => {\n const option = list.find((option) => option.code === selected[index]);\n return (\n <div className={styles.selectedItem} key={key} style={style}>\n {option && checkedCellRender ? (\n checkedCellRender(option)\n ) : (\n <TextWithTooltip\n text={option?.name + (showCode ? '(' + option?.code + ')' : '')}\n width='100%'\n ></TextWithTooltip>\n )}\n\n <i\n className={classNames('iconfont icon-lajitong', styles.close)}\n onClick={() => {\n setSelected(selected.filter((item) => item !== selected[index]));\n }}\n ></i>\n </div>\n );\n }}\n ></List>\n )}\n </AutoSizer>\n </div>\n </Scrollbars>\n </div>\n );\n};\n\nexport default Selected;\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,gBAAgB;AACvB,OAAO,SAAS,cAAc;AAC9B,SAAS,kBAAkB;AAC3B,SAAS,WAAW,YAAY;AAChC,OAAO,qBAAqB;AAE5B,OAAO,YAAY;AAyBnB,IAAM,WAAgC,CAAC;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA,YAAY;AAAA,EACZ;AAAA,EACA;AACF,MAAM;AACJ,QAAM,oBAAoB,OAA8C,IAAI;AAC5E,QAAM,UAAU,OAAO,IAAI;AAG3B,QAAM,4BAA4B,CAAC,UAAyC;AAC1E,UAAM,EAAE,WAAW,WAAW,IAAI,MAAM;AACxC,QAAI,QAAQ,SAAS;AAEnB,MAAC,QAAQ,QAAgB,KAAK,kBAAkB,EAAE,WAAW,WAAW,CAAC;AAAA,IAC3E;AAAA,EACF;AAEA,SACE,oCAAC,SAAI,WAAW,OAAO,YACrB,oCAAC,SAAI,WAAW,OAAO,kBACrB,oCAAC,cAAK,MAAG,SAAS,QAAO,GAAC,GAC1B,oCAAC,UAAK,WAAW,OAAO,OAAO,SAAS,MAAM,YAAY,CAAC,CAAC,KAAG,IAE/D,CACF,GAEA;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,QAAQ,IAAI;AAAA,MACrB,qBAAqB,CAAC,OAAqB;AAArB,qBAAE,QA9DhC,IA8D8B,IAAY,kBAAZ,IAAY,CAAV;AACtB,mDAAC,wCAAQ,QAAR,EAAe,OAAO,iCAAK,QAAL,EAAY,YAAY,WAAW,cAAc,EAAE,KAAG;AAAA;AAAA,MAE/E,KAAK;AAAA,MACL,UAAU;AAAA;AAAA,IAEV,oCAAC,SAAI,WAAW,OAAO,mBACrB,oCAAC,aAAU,eAAa,QACrB,CAAC,EAAE,MAAM,MACR;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,OAAO,EAAE,WAAW,WAAW,WAAW,UAAU;AAAA,QACpD,UAAU,SAAS;AAAA,QACnB,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA,aAAa,CAAC,EAAE,OAAO,KAAK,MAAM,MAAkE;AAClG,gBAAM,SAAS,KAAK,KAAK,CAACA,YAAWA,QAAO,SAAS,SAAS,KAAK,CAAC;AACpE,iBACE,oCAAC,SAAI,WAAW,OAAO,cAAc,KAAU,SAC5C,UAAU,oBACT,kBAAkB,MAAM,IAExB;AAAA,YAAC;AAAA;AAAA,cACC,OAAM,iCAAQ,SAAQ,WAAW,OAAM,iCAAQ,QAAO,MAAM;AAAA,cAC5D,OAAM;AAAA;AAAA,UACP,GAGH;AAAA,YAAC;AAAA;AAAA,cACC,WAAW,WAAW,0BAA0B,OAAO,KAAK;AAAA,cAC5D,SAAS,MAAM;AACb,4BAAY,SAAS,OAAO,CAAC,SAAS,SAAS,SAAS,KAAK,CAAC,CAAC;AAAA,cACjE;AAAA;AAAA,UACD,CACH;AAAA,QAEJ;AAAA;AAAA,IACD,CAEL,CACF;AAAA,EACF,CACF;AAEJ;AAEA,IAAO,mBAAQ;",
|
|
6
6
|
"names": ["option"]
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/business/ModCommonFilter/index.tsx"],
|
|
4
|
-
"sourcesContent": ["import { Popover, PopoverProps } from 'antd';\nimport React, { useEffect, useMemo, useState } from 'react';\nimport FilterButton from './components/FilterButton';\nimport PopoverContent from './components/PopoverContent';\nimport styles from './index.module.less';\nimport type { CategoryItem, ListItem, TerminalItem } from './typing';\n\n/**\n * 通用筛选器组件的 Props\n */\nexport interface ModCommonFilterProps {\n /** 当前选中的值(code 数组),受控 */\n value: string[];\n /** 选中项变化回调 */\n onChange: (value: string[]) => void;\n /** 可选列表数据 */\n list: ListItem[];\n /** 筛选维度名称,如「品类」「品牌」 */\n title: string;\n /** 按钮/标题前缀文案,如「筛选」 */\n prefixTitle?: string;\n /** 按钮左侧图标 */\n iconPrefix?: React.ReactNode;\n /** 分类列表,有则弹层左侧展示分类 Tab */\n category?: CategoryItem[];\n /** 终端列表,有则弹层内展示终端 Tab(如全部/PC/APP) */\n terminal?: TerminalItem[];\n /** 搜索框占位文案 */\n placeholder?: string;\n /** Popover 层级 */\n zIndex?: number;\n /** Popover 弹出方向 */\n placement?: PopoverProps['placement'];\n /** 透传给 antd Popover 的额外属性 */\n popoverProps?: PopoverProps;\n /** 可选列表列数(多列网格) */\n columnCount?: number;\n /** 内容区宽度 */\n contentWidth?: number;\n /** 列表行高 */\n rowHeight?: number;\n /** 是否在名称后展示 code */\n showCode?: boolean;\n /** 可选列表中每项的自定义渲染 */\n cellRender?: (item: ListItem) => React.ReactNode;\n /** 已选列表中每项的自定义渲染 */\n checkedCellRender?: (item: ListItem) => React.ReactNode;\n /** 弹层底部备注文案或节点 */\n remark?: string | React.ReactNode;\n /** 自定义触发区域,不传则使用默认 FilterButton */\n filterChildren?: React.ReactNode;\n}\n\n/**\n * 通用筛选器:点击按钮打开 Popover,内为分类 + 可选列表 + 已选列表,确认后回调 onChange。\n */\nconst ModCommonFilter: React.FC<ModCommonFilterProps> = ({\n value,\n onChange,\n list,\n title,\n prefixTitle,\n iconPrefix,\n category,\n terminal,\n placeholder = '搜索',\n zIndex = 100,\n placement = 'bottomRight',\n columnCount = 1,\n contentWidth,\n rowHeight,\n showCode = false,\n popoverProps = {},\n cellRender,\n checkedCellRender,\n remark,\n filterChildren,\n}) => {\n const [popOpen, setPopOpen] = useState(false);\n /** 弹层内当前选中的 code 列表,打开时与 value 同步 */\n const [selected, setSelected] = useState<string[]>([]);\n /** 当前选中的分类 code,空字符串表示「全部」 */\n const [categorySelected, setCategorySelected] = useState<string>('');\n\n /** 弹层打开时用外部 value 同步 selected,保证每次打开初始为当前已选 */\n useEffect(() => {\n if (popOpen) {\n setSelected(value || []);\n }\n }, [popOpen, value]);\n\n /** 分类选项列表,头部插入「全部{title}」 */\n const useCateGory = useMemo(() => {\n const newCategory: CategoryItem[] = category ? [...category] : [];\n newCategory.unshift({\n code: '',\n name: '全部' + title,\n });\n return newCategory;\n }, [category]);\n\n /** 确认:把当前选中回传并关闭弹层 */\n const handleVerify = () => {\n onChange(selected);\n setPopOpen(false);\n };\n\n /** 取消:恢复为打开前的 value 并关闭弹层 */\n const handleClear = () => {\n setSelected(value || []);\n setPopOpen(false);\n };\n\n return (\n <Popover\n className={styles.modCommonFilter}\n open={popOpen}\n onOpenChange={(open) => setPopOpen(open)}\n title={false}\n fresh={true}\n arrow={false}\n zIndex={zIndex}\n placement={placement}\n trigger='click'\n classNames={{\n body: styles.popoverBody,\n }}\n getPopupContainer={(triggerNode) => triggerNode.parentNode as HTMLElement}\n content={\n <PopoverContent\n popOpen={popOpen}\n selected={selected}\n setSelected={setSelected}\n category={useCateGory}\n terminal={terminal}\n list={list}\n placeholder={placeholder}\n title={title}\n categorySelected={categorySelected}\n setCategorySelected={setCategorySelected}\n columnCount={columnCount}\n showCode={showCode}\n contentWidth={contentWidth}\n rowHeight={rowHeight}\n cellRender={cellRender}\n checkedCellRender={checkedCellRender}\n handleVerify={handleVerify}\n handleClear={handleClear}\n remark={remark}\n />\n }\n {...popoverProps}\n >\n {filterChildren || (\n <FilterButton\n iconPrefix={iconPrefix}\n title={title}\n prefixTitle={prefixTitle}\n value={value}\n popOpen={popOpen}\n handlePopOpen={() => setPopOpen(!popOpen)}\n handleClear={() => onChange([])}\n />\n )}\n </Popover>\n );\n};\n\nexport default ModCommonFilter;\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;AAAA,SAAS,
|
|
4
|
+
"sourcesContent": ["import { Popover, type PopoverProps } from 'antd';\nimport React, { useEffect, useMemo, useState } from 'react';\nimport FilterButton from './components/FilterButton';\nimport PopoverContent from './components/PopoverContent';\nimport styles from './index.module.less';\nimport type { CategoryItem, ListItem, TerminalItem } from './typing';\n\n/**\n * 通用筛选器组件的 Props\n */\nexport interface ModCommonFilterProps {\n /** 当前选中的值(code 数组),受控 */\n value: string[];\n /** 选中项变化回调 */\n onChange: (value: string[]) => void;\n /** 可选列表数据 */\n list: ListItem[];\n /** 筛选维度名称,如「品类」「品牌」 */\n title: string;\n /** 按钮/标题前缀文案,如「筛选」 */\n prefixTitle?: string;\n /** 按钮左侧图标 */\n iconPrefix?: React.ReactNode;\n /** 分类列表,有则弹层左侧展示分类 Tab */\n category?: CategoryItem[];\n /** 终端列表,有则弹层内展示终端 Tab(如全部/PC/APP) */\n terminal?: TerminalItem[];\n /** 搜索框占位文案 */\n placeholder?: string;\n /** Popover 层级 */\n zIndex?: number;\n /** Popover 弹出方向 */\n placement?: PopoverProps['placement'];\n /** 透传给 antd Popover 的额外属性 */\n popoverProps?: PopoverProps;\n /** 可选列表列数(多列网格) */\n columnCount?: number;\n /** 内容区宽度 */\n contentWidth?: number;\n /** 列表行高 */\n rowHeight?: number;\n /** 是否在名称后展示 code */\n showCode?: boolean;\n /** 可选列表中每项的自定义渲染 */\n cellRender?: (item: ListItem) => React.ReactNode;\n /** 已选列表中每项的自定义渲染 */\n checkedCellRender?: (item: ListItem) => React.ReactNode;\n /** 弹层底部备注文案或节点 */\n remark?: string | React.ReactNode;\n /** 自定义触发区域,不传则使用默认 FilterButton */\n filterChildren?: React.ReactNode;\n}\n\n/**\n * 通用筛选器:点击按钮打开 Popover,内为分类 + 可选列表 + 已选列表,确认后回调 onChange。\n */\nconst ModCommonFilter: React.FC<ModCommonFilterProps> = ({\n value,\n onChange,\n list,\n title,\n prefixTitle,\n iconPrefix,\n category,\n terminal,\n placeholder = '搜索',\n zIndex = 100,\n placement = 'bottomRight',\n columnCount = 1,\n contentWidth,\n rowHeight,\n showCode = false,\n popoverProps = {},\n cellRender,\n checkedCellRender,\n remark,\n filterChildren,\n}) => {\n const [popOpen, setPopOpen] = useState(false);\n /** 弹层内当前选中的 code 列表,打开时与 value 同步 */\n const [selected, setSelected] = useState<string[]>([]);\n /** 当前选中的分类 code,空字符串表示「全部」 */\n const [categorySelected, setCategorySelected] = useState<string>('');\n\n /** 弹层打开时用外部 value 同步 selected,保证每次打开初始为当前已选 */\n useEffect(() => {\n if (popOpen) {\n setSelected(value || []);\n }\n }, [popOpen, value]);\n\n /** 分类选项列表,头部插入「全部{title}」 */\n const useCateGory = useMemo(() => {\n const newCategory: CategoryItem[] = category ? [...category] : [];\n newCategory.unshift({\n code: '',\n name: '全部' + title,\n });\n return newCategory;\n }, [category]);\n\n /** 确认:把当前选中回传并关闭弹层 */\n const handleVerify = () => {\n onChange(selected);\n setPopOpen(false);\n };\n\n /** 取消:恢复为打开前的 value 并关闭弹层 */\n const handleClear = () => {\n setSelected(value || []);\n setPopOpen(false);\n };\n\n return (\n <Popover\n className={styles.modCommonFilter}\n open={popOpen}\n onOpenChange={(open) => setPopOpen(open)}\n title={false}\n fresh={true}\n arrow={false}\n zIndex={zIndex}\n placement={placement}\n trigger='click'\n classNames={{\n body: styles.popoverBody,\n }}\n getPopupContainer={(triggerNode) => triggerNode.parentNode as HTMLElement}\n content={\n <PopoverContent\n popOpen={popOpen}\n selected={selected}\n setSelected={setSelected}\n category={useCateGory}\n terminal={terminal}\n list={list}\n placeholder={placeholder}\n title={title}\n categorySelected={categorySelected}\n setCategorySelected={setCategorySelected}\n columnCount={columnCount}\n showCode={showCode}\n contentWidth={contentWidth}\n rowHeight={rowHeight}\n cellRender={cellRender}\n checkedCellRender={checkedCellRender}\n handleVerify={handleVerify}\n handleClear={handleClear}\n remark={remark}\n />\n }\n {...popoverProps}\n >\n {filterChildren || (\n <FilterButton\n iconPrefix={iconPrefix}\n title={title}\n prefixTitle={prefixTitle}\n value={value}\n popOpen={popOpen}\n handlePopOpen={() => setPopOpen(!popOpen)}\n handleClear={() => onChange([])}\n />\n )}\n </Popover>\n );\n};\n\nexport default ModCommonFilter;\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA,SAAS,eAAkC;AAC3C,OAAO,SAAS,WAAW,SAAS,gBAAgB;AACpD,OAAO,kBAAkB;AACzB,OAAO,oBAAoB;AAC3B,OAAO,YAAY;AAoDnB,IAAM,kBAAkD,CAAC;AAAA,EACvD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,eAAe,CAAC;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAE5C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAmB,CAAC,CAAC;AAErD,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAiB,EAAE;AAGnE,YAAU,MAAM;AACd,QAAI,SAAS;AACX,kBAAY,SAAS,CAAC,CAAC;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,SAAS,KAAK,CAAC;AAGnB,QAAM,cAAc,QAAQ,MAAM;AAChC,UAAM,cAA8B,WAAW,CAAC,GAAG,QAAQ,IAAI,CAAC;AAChE,gBAAY,QAAQ;AAAA,MAClB,MAAM;AAAA,MACN,MAAM,OAAO;AAAA,IACf,CAAC;AACD,WAAO;AAAA,EACT,GAAG,CAAC,QAAQ,CAAC;AAGb,QAAM,eAAe,MAAM;AACzB,aAAS,QAAQ;AACjB,eAAW,KAAK;AAAA,EAClB;AAGA,QAAM,cAAc,MAAM;AACxB,gBAAY,SAAS,CAAC,CAAC;AACvB,eAAW,KAAK;AAAA,EAClB;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,OAAO;AAAA,MAClB,MAAM;AAAA,MACN,cAAc,CAAC,SAAS,WAAW,IAAI;AAAA,MACvC,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,SAAQ;AAAA,MACR,YAAY;AAAA,QACV,MAAM,OAAO;AAAA,MACf;AAAA,MACA,mBAAmB,CAAC,gBAAgB,YAAY;AAAA,MAChD,SACE;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA;AAAA,UACA,UAAU;AAAA,UACV;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA;AAAA,MACF;AAAA,OAEE;AAAA,IAEH,kBACC;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,eAAe,MAAM,WAAW,CAAC,OAAO;AAAA,QACxC,aAAa,MAAM,SAAS,CAAC,CAAC;AAAA;AAAA,IAChC;AAAA,EAEJ;AAEJ;AAEA,IAAO,0BAAQ;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -51,12 +51,12 @@ var __async = (__this, __arguments, generator) => {
|
|
|
51
51
|
};
|
|
52
52
|
|
|
53
53
|
// src/business/YkPorjectSelect/index.tsx
|
|
54
|
-
import TextWithTooltip from "../../components/TextWithToolTip";
|
|
55
54
|
import { SearchOutlined } from "@ant-design/icons";
|
|
56
55
|
import { ConfigProvider, Empty, Flex, Input, Popover, Rate, Tabs, Tooltip } from "antd";
|
|
57
56
|
import classNames from "classnames";
|
|
58
57
|
import React, { useEffect, useMemo, useRef, useState } from "react";
|
|
59
|
-
import { Scrollbars } from "react-custom-scrollbars";
|
|
58
|
+
import { Scrollbars } from "react-custom-scrollbars-2";
|
|
59
|
+
import TextWithTooltip from "../../components/TextWithToolTip";
|
|
60
60
|
import iconProductDefault from "./icon-product.png";
|
|
61
61
|
import styles from "./index.module.less";
|
|
62
62
|
var YkPorjectSelect = ({ value, options, onChange, followedCallback, slot, customShow }) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/business/YkPorjectSelect/index.tsx"],
|
|
4
|
-
"sourcesContent": ["import TextWithTooltip from '@/components/TextWithToolTip';\nimport { SearchOutlined } from '@ant-design/icons';\nimport type { InputRef } from 'antd';\nimport { ConfigProvider, Empty, Flex, Input, Popover, Rate, Tabs, Tooltip } from 'antd';\nimport classNames from 'classnames';\nimport React, { FC, useEffect, useMemo, useRef, useState } from 'react';\nimport { Scrollbars } from 'react-custom-scrollbars';\nimport iconProductDefault from './icon-product.png';\nimport styles from './index.module.less';\n\n/** 项目选项项 */\ntype OptionItem = {\n /** 项目名称 */\n label: string;\n /** 项目 ID */\n value: string | number;\n /** 项目图标 URL */\n icon: string;\n /** 是否已关注 */\n followed?: boolean;\n /** 关注排序索引 */\n follow_index?: number;\n /** 是否最近访问 */\n recent_visit?: boolean;\n /** 是否已关服 */\n closed?: boolean;\n};\n\n/** 项目选择器 Props */\ntype PageTypes = {\n /** 当前选中的项目 ID */\n value: string | number;\n /** 项目选项列表 */\n options: OptionItem[];\n /** 选中项目变化时的回调 */\n onChange: (value: string | number) => void;\n /** 关注/取消关注时的回调 */\n followedCallback?: (item: OptionItem, bool: boolean) => void;\n /** 弹层内自定义插槽,渲染在搜索框下方、关注项目上方 */\n slot?: React.ReactNode;\n /** 自定义触发元素,替代默认的「图标+名称+下拉箭头」展示 */\n customShow?: React.ReactNode;\n};\n\n/**\n * 项目选择器\n *\n * 支持搜索、关注/取消关注(最多6个)、在营/关服切换。\n * 弹层展开时自动聚焦搜索框,使用 preventScroll 避免页面滚动。\n *\n * @example\n * ```tsx\n * <YkPorjectSelect\n * value={projectId}\n * options={options}\n * onChange={setProjectId}\n * followedCallback={(item, followed) => api.follow(item.value, followed)}\n * />\n * ```\n */\nconst YkPorjectSelect: FC<PageTypes> = ({ value, options, onChange, followedCallback, slot, customShow }) => {\n const [open, setOpen] = useState(false);\n const [status, setStatus] = useState<string>('1');\n const [searchKey, setSearchKey] = useState('');\n const [pageHeight, setPageHeight] = useState<number>(1000);\n const [localOptions, setLocalOptions] = useState<OptionItem[]>(options);\n const searchInputRef = useRef<InputRef>(null);\n\n useEffect(() => {\n setLocalOptions(options);\n }, [options]);\n\n /** 弹层展开时聚焦搜索框,使用 preventScroll 避免浏览器滚动到顶部;延迟等待 Popover 内容挂载 */\n useEffect(() => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n if (open) {\n timer = setTimeout(() => {\n searchInputRef.current?.input?.focus({ preventScroll: true });\n }, 0);\n }\n return () => {\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n };\n }, [open]);\n\n /** 在营/关服数量统计 */\n const stateCount = useMemo(() => {\n return localOptions.reduce(\n (acc, item) => {\n const statusClosed = item.closed ? 2 : 1;\n if (!acc[statusClosed]) {\n acc[statusClosed] = 0;\n }\n acc[statusClosed] += 1;\n return acc;\n },\n {} as { [key: string]: number },\n );\n }, [localOptions]);\n\n /** 在营/关服 Tab 配置 */\n const tabs = [\n { key: '1', label: `在营(${stateCount['1'] || 0})` },\n { key: '2', label: `关服(${stateCount['2'] || 0})` },\n ];\n\n /** 当前选中的项目(用于展示图标与名称) */\n const activeItem = useMemo(() => {\n return localOptions.find((item) => item.value === value);\n }, [localOptions, value]);\n\n /** 已关注的项目列表(顶部展示、用于计算关注数限制) */\n const followedOptions = useMemo(() => {\n return localOptions.filter((item) => item.followed);\n }, [localOptions]);\n\n // 切换在营/关服\n const handleTabChange = (tabKey: string) => {\n setStatus(tabKey);\n };\n\n // 点击关注或取消关注\n const handleStarChange = async (item: OptionItem, val: number) => {\n void followedCallback?.(item, val === 1);\n setLocalOptions((prev) =>\n prev.map((p) => {\n if (p.value === item.value) {\n return { ...p, followed: val === 1 };\n }\n return p;\n }),\n );\n };\n\n const handleResize = () => {\n const height = window.innerHeight;\n setPageHeight(height);\n };\n\n useEffect(() => {\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, []);\n\n /** 渲染单个项目行(名称、ID、关注星标) */\n const renderItem = (item: OptionItem) => {\n const isDisabled = !item.followed && followedOptions.length >= 6;\n return (\n <Flex justify='space-between' align='center'>\n <span className={styles.contentItemSpan} onClick={() => onChange(item.value)}>\n <img className={styles.contentItemSpanIcon} src={item?.icon ? item.icon : iconProductDefault} />\n <div className={styles.contentItemSpanDev}>\n <div className={styles.contentItemSpanProName}>\n <TextWithTooltip\n text={item.label}\n width='100%'\n maxWidth={175}\n arrow={true}\n color='#fff'\n styles={{ body: { color: '#333' } }}\n ></TextWithTooltip>\n {item.recent_visit ? <span className={styles.recentVisit}>最近访问</span> : null}\n </div>\n <div className={styles.contentItemSpanProId}>ID: {item.value}</div>\n </div>\n </span>\n <Tooltip\n title={isDisabled ? '最多关注6个项目' : item.followed ? '取消关注' : '关注'}\n color='#fff'\n placement='right'\n styles={{ body: { color: '#333' } }}\n >\n <label\n className={classNames(styles.contentItemStar, isDisabled && styles.contentItemStarDisabled)}\n onClick={() => {\n if (isDisabled) {\n return;\n }\n void handleStarChange(item, item.followed ? 0 : 1);\n }}\n >\n <ConfigProvider\n theme={{\n components: {\n Rate: {\n starBg: '#dcdbdb',\n },\n },\n }}\n >\n <Rate\n style={{\n fontSize: 14,\n color: isDisabled ? 'rgba(0, 0, 0, 0.06)' : '#FFB401',\n opacity: item.followed || followedOptions.length === 0 ? 1 : 0,\n }}\n value={item.followed ? 1 : 0}\n count={1}\n />\n </ConfigProvider>\n </label>\n </Tooltip>\n </Flex>\n );\n };\n\n /** 弹层内容:搜索、slot、关注区、Tab、项目列表 */\n const content = (\n <div className={styles.ykPorjectSelectContent}>\n <div className={styles.ykPorjectSelectHeader}>\n <Input\n ref={searchInputRef}\n className={styles.ykPorjectSelectSearchInput}\n prefix={<SearchOutlined style={{ color: '#999', marginRight: '10px' }} />}\n value={searchKey}\n onChange={(e) => setSearchKey(e.target.value)}\n allowClear\n placeholder='请输入项目ID/名称'\n />\n </div>\n {slot && <div className={styles.ykPorjectSelectSoltContainer}>{slot}</div>}\n <div className={styles.ykPorjectSelectFollowed}>\n <div className={styles.contentHeader}>关注项目</div>\n <div className={styles.ykPorjectSelectFollowedList}>\n {followedOptions.map((item) => (\n <Tooltip\n key={item.value}\n title={\n <>\n <div style={{ fontSize: 14, color: '#555555' }}>{item.label}</div>\n <div style={{ fontSize: 12, color: '#999' }}>ID: {item.value}</div>\n </>\n }\n color='#fff'\n placement='bottomLeft'\n styles={{ body: { color: '#333' } }}\n >\n <div key={item.value} className={styles.ykPorjectSelectFollowedItem}>\n <img className={styles.ykPorjectSelectFollowedItemIcon} src={item.icon} alt={item.label} />\n <div className={styles.closeIcon} onClick={() => void handleStarChange(item, 0)} />\n </div>\n </Tooltip>\n ))}\n </div>\n </div>\n <Tabs\n className={styles.ykPorjectSelectProductPanelTabs}\n centered\n onChange={handleTabChange}\n activeKey={status}\n items={tabs}\n ></Tabs>\n {localOptions.length === 0 ? (\n <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />\n ) : (\n <div className={styles.ykPorjectSelectListSection}>\n <div className={styles.contentHeader}>全部项目</div>\n <Scrollbars\n className={styles.ykPorjectSelectScrollBarsBox}\n autoHeight\n autoHide\n autoHeightMax={Math.min(450, pageHeight - 310)}\n renderThumbVertical={({ style, ...props }) => (\n <div {...props} style={{ ...style, background: '#EEEEEE', borderRadius: 3, width: 6 }} />\n )}\n >\n {localOptions\n .sort((a, b) => (b.recent_visit ? 1 : 0) - (a.recent_visit ? 1 : 0))\n .map((item) => (\n <div\n key={item.value}\n className={classNames(styles.contentItem, item.value === value ? styles.contentItemActive : '')}\n >\n {renderItem(item)}\n </div>\n ))}\n </Scrollbars>\n </div>\n )}\n </div>\n );\n\n return (\n <Popover\n className={styles.ykPorjectSelect}\n styles={{ body: { borderRadius: 4, padding: 0 } }}\n content={content}\n placement='bottom'\n trigger='click'\n open={open}\n onOpenChange={setOpen}\n getPopupContainer={(triggerNode: HTMLElement) => triggerNode.parentNode as HTMLElement}\n autoAdjustOverflow={false}\n >\n {customShow ? (\n customShow\n ) : (\n <div className={styles.ykPorjectSelectShow}>\n <img className={styles.ykPorjectSelectShowIcon} src={activeItem?.icon} alt={activeItem?.label} />\n <span className={styles.ykPorjectSelectShowText}>{activeItem?.label}</span>\n <i className='iconfont icon-xiala' />\n </div>\n )}\n </Popover>\n );\n};\n\nexport default YkPorjectSelect;\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,
|
|
4
|
+
"sourcesContent": ["import { SearchOutlined } from '@ant-design/icons';\nimport type { InputRef } from 'antd';\nimport { ConfigProvider, Empty, Flex, Input, Popover, Rate, Tabs, Tooltip } from 'antd';\nimport classNames from 'classnames';\nimport React, { type FC, useEffect, useMemo, useRef, useState } from 'react';\nimport { Scrollbars } from 'react-custom-scrollbars-2';\nimport TextWithTooltip from '@/components/TextWithToolTip';\nimport iconProductDefault from './icon-product.png';\nimport styles from './index.module.less';\n\n/** 项目选项项 */\ntype OptionItem = {\n /** 项目名称 */\n label: string;\n /** 项目 ID */\n value: string | number;\n /** 项目图标 URL */\n icon: string;\n /** 是否已关注 */\n followed?: boolean;\n /** 关注排序索引 */\n follow_index?: number;\n /** 是否最近访问 */\n recent_visit?: boolean;\n /** 是否已关服 */\n closed?: boolean;\n};\n\n/** 项目选择器 Props */\ntype PageTypes = {\n /** 当前选中的项目 ID */\n value: string | number;\n /** 项目选项列表 */\n options: OptionItem[];\n /** 选中项目变化时的回调 */\n onChange: (value: string | number) => void;\n /** 关注/取消关注时的回调 */\n followedCallback?: (item: OptionItem, bool: boolean) => void;\n /** 弹层内自定义插槽,渲染在搜索框下方、关注项目上方 */\n slot?: React.ReactNode;\n /** 自定义触发元素,替代默认的「图标+名称+下拉箭头」展示 */\n customShow?: React.ReactNode;\n};\n\n/**\n * 项目选择器\n *\n * 支持搜索、关注/取消关注(最多6个)、在营/关服切换。\n * 弹层展开时自动聚焦搜索框,使用 preventScroll 避免页面滚动。\n *\n * @example\n * ```tsx\n * <YkPorjectSelect\n * value={projectId}\n * options={options}\n * onChange={setProjectId}\n * followedCallback={(item, followed) => api.follow(item.value, followed)}\n * />\n * ```\n */\nconst YkPorjectSelect: FC<PageTypes> = ({ value, options, onChange, followedCallback, slot, customShow }) => {\n const [open, setOpen] = useState(false);\n const [status, setStatus] = useState<string>('1');\n const [searchKey, setSearchKey] = useState('');\n const [pageHeight, setPageHeight] = useState<number>(1000);\n const [localOptions, setLocalOptions] = useState<OptionItem[]>(options);\n const searchInputRef = useRef<InputRef>(null);\n\n useEffect(() => {\n setLocalOptions(options);\n }, [options]);\n\n /** 弹层展开时聚焦搜索框,使用 preventScroll 避免浏览器滚动到顶部;延迟等待 Popover 内容挂载 */\n useEffect(() => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n if (open) {\n timer = setTimeout(() => {\n searchInputRef.current?.input?.focus({ preventScroll: true });\n }, 0);\n }\n return () => {\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n };\n }, [open]);\n\n /** 在营/关服数量统计 */\n const stateCount = useMemo(() => {\n return localOptions.reduce(\n (acc, item) => {\n const statusClosed = item.closed ? 2 : 1;\n if (!acc[statusClosed]) {\n acc[statusClosed] = 0;\n }\n acc[statusClosed] += 1;\n return acc;\n },\n {} as { [key: string]: number },\n );\n }, [localOptions]);\n\n /** 在营/关服 Tab 配置 */\n const tabs = [\n { key: '1', label: `在营(${stateCount['1'] || 0})` },\n { key: '2', label: `关服(${stateCount['2'] || 0})` },\n ];\n\n /** 当前选中的项目(用于展示图标与名称) */\n const activeItem = useMemo(() => {\n return localOptions.find((item) => item.value === value);\n }, [localOptions, value]);\n\n /** 已关注的项目列表(顶部展示、用于计算关注数限制) */\n const followedOptions = useMemo(() => {\n return localOptions.filter((item) => item.followed);\n }, [localOptions]);\n\n // 切换在营/关服\n const handleTabChange = (tabKey: string) => {\n setStatus(tabKey);\n };\n\n // 点击关注或取消关注\n const handleStarChange = async (item: OptionItem, val: number) => {\n void followedCallback?.(item, val === 1);\n setLocalOptions((prev) =>\n prev.map((p) => {\n if (p.value === item.value) {\n return { ...p, followed: val === 1 };\n }\n return p;\n }),\n );\n };\n\n const handleResize = () => {\n const height = window.innerHeight;\n setPageHeight(height);\n };\n\n useEffect(() => {\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, []);\n\n /** 渲染单个项目行(名称、ID、关注星标) */\n const renderItem = (item: OptionItem) => {\n const isDisabled = !item.followed && followedOptions.length >= 6;\n return (\n <Flex justify='space-between' align='center'>\n <span className={styles.contentItemSpan} onClick={() => onChange(item.value)}>\n <img className={styles.contentItemSpanIcon} src={item?.icon ? item.icon : iconProductDefault} />\n <div className={styles.contentItemSpanDev}>\n <div className={styles.contentItemSpanProName}>\n <TextWithTooltip\n text={item.label}\n width='100%'\n maxWidth={175}\n arrow={true}\n color='#fff'\n styles={{ body: { color: '#333' } }}\n ></TextWithTooltip>\n {item.recent_visit ? <span className={styles.recentVisit}>最近访问</span> : null}\n </div>\n <div className={styles.contentItemSpanProId}>ID: {item.value}</div>\n </div>\n </span>\n <Tooltip\n title={isDisabled ? '最多关注6个项目' : item.followed ? '取消关注' : '关注'}\n color='#fff'\n placement='right'\n styles={{ body: { color: '#333' } }}\n >\n <label\n className={classNames(styles.contentItemStar, isDisabled && styles.contentItemStarDisabled)}\n onClick={() => {\n if (isDisabled) {\n return;\n }\n void handleStarChange(item, item.followed ? 0 : 1);\n }}\n >\n <ConfigProvider\n theme={{\n components: {\n Rate: {\n starBg: '#dcdbdb',\n },\n },\n }}\n >\n <Rate\n style={{\n fontSize: 14,\n color: isDisabled ? 'rgba(0, 0, 0, 0.06)' : '#FFB401',\n opacity: item.followed || followedOptions.length === 0 ? 1 : 0,\n }}\n value={item.followed ? 1 : 0}\n count={1}\n />\n </ConfigProvider>\n </label>\n </Tooltip>\n </Flex>\n );\n };\n\n /** 弹层内容:搜索、slot、关注区、Tab、项目列表 */\n const content = (\n <div className={styles.ykPorjectSelectContent}>\n <div className={styles.ykPorjectSelectHeader}>\n <Input\n ref={searchInputRef}\n className={styles.ykPorjectSelectSearchInput}\n prefix={<SearchOutlined style={{ color: '#999', marginRight: '10px' }} />}\n value={searchKey}\n onChange={(e) => setSearchKey(e.target.value)}\n allowClear\n placeholder='请输入项目ID/名称'\n />\n </div>\n {slot && <div className={styles.ykPorjectSelectSoltContainer}>{slot}</div>}\n <div className={styles.ykPorjectSelectFollowed}>\n <div className={styles.contentHeader}>关注项目</div>\n <div className={styles.ykPorjectSelectFollowedList}>\n {followedOptions.map((item) => (\n <Tooltip\n key={item.value}\n title={\n <>\n <div style={{ fontSize: 14, color: '#555555' }}>{item.label}</div>\n <div style={{ fontSize: 12, color: '#999' }}>ID: {item.value}</div>\n </>\n }\n color='#fff'\n placement='bottomLeft'\n styles={{ body: { color: '#333' } }}\n >\n <div key={item.value} className={styles.ykPorjectSelectFollowedItem}>\n <img className={styles.ykPorjectSelectFollowedItemIcon} src={item.icon} alt={item.label} />\n <div className={styles.closeIcon} onClick={() => void handleStarChange(item, 0)} />\n </div>\n </Tooltip>\n ))}\n </div>\n </div>\n <Tabs\n className={styles.ykPorjectSelectProductPanelTabs}\n centered\n onChange={handleTabChange}\n activeKey={status}\n items={tabs}\n ></Tabs>\n {localOptions.length === 0 ? (\n <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />\n ) : (\n <div className={styles.ykPorjectSelectListSection}>\n <div className={styles.contentHeader}>全部项目</div>\n <Scrollbars\n className={styles.ykPorjectSelectScrollBarsBox}\n autoHeight\n autoHide\n autoHeightMax={Math.min(450, pageHeight - 310)}\n renderThumbVertical={({ style, ...props }) => (\n <div {...props} style={{ ...style, background: '#EEEEEE', borderRadius: 3, width: 6 }} />\n )}\n >\n {localOptions\n .sort((a, b) => (b.recent_visit ? 1 : 0) - (a.recent_visit ? 1 : 0))\n .map((item) => (\n <div\n key={item.value}\n className={classNames(styles.contentItem, item.value === value ? styles.contentItemActive : '')}\n >\n {renderItem(item)}\n </div>\n ))}\n </Scrollbars>\n </div>\n )}\n </div>\n );\n\n return (\n <Popover\n className={styles.ykPorjectSelect}\n styles={{ body: { borderRadius: 4, padding: 0 } }}\n content={content}\n placement='bottom'\n trigger='click'\n open={open}\n onOpenChange={setOpen}\n getPopupContainer={(triggerNode: HTMLElement) => triggerNode.parentNode as HTMLElement}\n autoAdjustOverflow={false}\n >\n {customShow ? (\n customShow\n ) : (\n <div className={styles.ykPorjectSelectShow}>\n <img className={styles.ykPorjectSelectShowIcon} src={activeItem?.icon} alt={activeItem?.label} />\n <span className={styles.ykPorjectSelectShowText}>{activeItem?.label}</span>\n <i className='iconfont icon-xiala' />\n </div>\n )}\n </Popover>\n );\n};\n\nexport default YkPorjectSelect;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/components/DebounceInput/index.tsx"],
|
|
4
|
-
"sourcesContent": ["/**\n * 组件名称:DebouncedInput\n * 组件描述:一个用于搜索的输入框组件,支持防抖\n * 组件使用场景:在需要搜索的场景中使用,如筛选、排序等\n * 组件参数说明:\n * - noDebounced: 是否不使用防抖\n * - currentValue: 当前值\n * - placeholder: 输入框提示文字\n * - onChange: 值改变时的回调\n * - delay: 防抖时间\n * - inputClass: 输入框样式类名\n * - allowClear: 是否允许清空\n * - style: 组件样式\n */\nimport { useDebounceFn } from 'ahooks';\nimport { Input } from 'antd';\nimport classNames from 'classnames';\nimport React, { useEffect, useRef, useState } from 'react';\nimport styles from './index.module.less';\ntype PropsType = {\n noDebounced?: boolean;\n currentValue: string | undefined;\n placeholder?: string;\n onChange: (value: string) => void;\n delay?: number;\n inputClass?: any;\n allowClear?: boolean;\n style?: React.CSSProperties;\n noPrefixIcon?: boolean;\n disabled?: boolean;\n icon?: React.ReactNode;\n};\nconst DebouncedInput: React.FC<PropsType> = ({\n noDebounced = false,\n currentValue = '',\n placeholder = '搜索',\n onChange = (value: string) => {},\n delay = 150,\n inputClass,\n allowClear = true,\n style = {},\n noPrefixIcon = false,\n disabled = false,\n icon,\n}) => {\n const [value, setValue] = useState(currentValue);\n const lock = useRef(false);\n const changeFlag = useRef(false);\n useEffect(() => {\n if (changeFlag.current) {\n changeFlag.current = false;\n return;\n }\n setValue(currentValue);\n }, [currentValue]);\n\n const { run } = useDebounceFn(\n () => {\n onChange(value);\n },\n { wait: delay },\n );\n function handleChange(e: any) {\n const type = e.type;\n if (type === 'compositionstart') {\n lock.current = true;\n return;\n }\n const value = e.target.value;\n setValue(value);\n if (e.type === 'compositionend') {\n lock.current = false;\n }\n if (!lock.current) {\n changeFlag.current = true;\n if (noDebounced) {\n onChange(value);\n } else {\n run();\n }\n }\n }\n return (\n <Input\n allowClear={allowClear}\n style={style}\n className={classNames(styles.search, inputClass)}\n placeholder={placeholder}\n prefix={\n !noPrefixIcon &&\n (icon || <i className='iconfont icon-sousuo' style={{ fontSize: 14, lineHeight: '28px', color: '#999' }} />)\n }\n value={value}\n onChange={handleChange}\n onCompositionStart={handleChange}\n onCompositionEnd={handleChange}\n disabled={disabled}\n />\n );\n};\n\nexport default DebouncedInput;\n"],
|
|
5
|
-
"mappings": ";AAcA,SAAS,qBAAqB;AAC9B,SAAS,aAAa;AACtB,OAAO,gBAAgB;AACvB,OAAO,SAAS,WAAW,QAAQ,gBAAgB;AACnD,OAAO,YAAY;
|
|
4
|
+
"sourcesContent": ["/**\n * 组件名称:DebouncedInput\n * 组件描述:一个用于搜索的输入框组件,支持防抖\n * 组件使用场景:在需要搜索的场景中使用,如筛选、排序等\n * 组件参数说明:\n * - noDebounced: 是否不使用防抖\n * - currentValue: 当前值\n * - placeholder: 输入框提示文字\n * - onChange: 值改变时的回调\n * - delay: 防抖时间\n * - inputClass: 输入框样式类名\n * - allowClear: 是否允许清空\n * - style: 组件样式\n */\nimport { useDebounceFn } from 'ahooks';\nimport { Input } from 'antd';\nimport classNames from 'classnames';\nimport React, { useEffect, useRef, useState } from 'react';\nimport styles from './index.module.less';\n\ntype PropsType = {\n noDebounced?: boolean;\n currentValue: string | undefined;\n placeholder?: string;\n onChange: (value: string) => void;\n delay?: number;\n inputClass?: any;\n allowClear?: boolean;\n style?: React.CSSProperties;\n noPrefixIcon?: boolean;\n disabled?: boolean;\n icon?: React.ReactNode;\n};\nconst DebouncedInput: React.FC<PropsType> = ({\n noDebounced = false,\n currentValue = '',\n placeholder = '搜索',\n onChange = (value: string) => {},\n delay = 150,\n inputClass,\n allowClear = true,\n style = {},\n noPrefixIcon = false,\n disabled = false,\n icon,\n}) => {\n const [value, setValue] = useState(currentValue);\n const lock = useRef(false);\n const changeFlag = useRef(false);\n useEffect(() => {\n if (changeFlag.current) {\n changeFlag.current = false;\n return;\n }\n setValue(currentValue);\n }, [currentValue]);\n\n const { run } = useDebounceFn(\n () => {\n onChange(value);\n },\n { wait: delay },\n );\n function handleChange(e: any) {\n const type = e.type;\n if (type === 'compositionstart') {\n lock.current = true;\n return;\n }\n const value = e.target.value;\n setValue(value);\n if (e.type === 'compositionend') {\n lock.current = false;\n }\n if (!lock.current) {\n changeFlag.current = true;\n if (noDebounced) {\n onChange(value);\n } else {\n run();\n }\n }\n }\n return (\n <Input\n allowClear={allowClear}\n style={style}\n className={classNames(styles.search, inputClass)}\n placeholder={placeholder}\n prefix={\n !noPrefixIcon &&\n (icon || <i className='iconfont icon-sousuo' style={{ fontSize: 14, lineHeight: '28px', color: '#999' }} />)\n }\n value={value}\n onChange={handleChange}\n onCompositionStart={handleChange}\n onCompositionEnd={handleChange}\n disabled={disabled}\n />\n );\n};\n\nexport default DebouncedInput;\n"],
|
|
5
|
+
"mappings": ";AAcA,SAAS,qBAAqB;AAC9B,SAAS,aAAa;AACtB,OAAO,gBAAgB;AACvB,OAAO,SAAS,WAAW,QAAQ,gBAAgB;AACnD,OAAO,YAAY;AAenB,IAAM,iBAAsC,CAAC;AAAA,EAC3C,cAAc;AAAA,EACd,eAAe;AAAA,EACf,cAAc;AAAA,EACd,WAAW,CAAC,UAAkB;AAAA,EAAC;AAAA,EAC/B,QAAQ;AAAA,EACR;AAAA,EACA,aAAa;AAAA,EACb,QAAQ,CAAC;AAAA,EACT,eAAe;AAAA,EACf,WAAW;AAAA,EACX;AACF,MAAM;AACJ,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,YAAY;AAC/C,QAAM,OAAO,OAAO,KAAK;AACzB,QAAM,aAAa,OAAO,KAAK;AAC/B,YAAU,MAAM;AACd,QAAI,WAAW,SAAS;AACtB,iBAAW,UAAU;AACrB;AAAA,IACF;AACA,aAAS,YAAY;AAAA,EACvB,GAAG,CAAC,YAAY,CAAC;AAEjB,QAAM,EAAE,IAAI,IAAI;AAAA,IACd,MAAM;AACJ,eAAS,KAAK;AAAA,IAChB;AAAA,IACA,EAAE,MAAM,MAAM;AAAA,EAChB;AACA,WAAS,aAAa,GAAQ;AAC5B,UAAM,OAAO,EAAE;AACf,QAAI,SAAS,oBAAoB;AAC/B,WAAK,UAAU;AACf;AAAA,IACF;AACA,UAAMA,SAAQ,EAAE,OAAO;AACvB,aAASA,MAAK;AACd,QAAI,EAAE,SAAS,kBAAkB;AAC/B,WAAK,UAAU;AAAA,IACjB;AACA,QAAI,CAAC,KAAK,SAAS;AACjB,iBAAW,UAAU;AACrB,UAAI,aAAa;AACf,iBAASA,MAAK;AAAA,MAChB,OAAO;AACL,YAAI;AAAA,MACN;AAAA,IACF;AAAA,EACF;AACA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,WAAW,WAAW,OAAO,QAAQ,UAAU;AAAA,MAC/C;AAAA,MACA,QACE,CAAC,iBACA,QAAQ,oCAAC,OAAE,WAAU,wBAAuB,OAAO,EAAE,UAAU,IAAI,YAAY,QAAQ,OAAO,OAAO,GAAG;AAAA,MAE3G;AAAA,MACA,UAAU;AAAA,MACV,oBAAoB;AAAA,MACpB,kBAAkB;AAAA,MAClB;AAAA;AAAA,EACF;AAEJ;AAEA,IAAO,wBAAQ;",
|
|
6
6
|
"names": ["value"]
|
|
7
7
|
}
|
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 组件名称:MultipleSelect
|
|
3
|
+
* 组件描述:一个用于多选的组件,支持搜索和选择
|
|
4
|
+
* 组件使用场景:在需要选择多个值的场景中使用,如筛选、排序等
|
|
5
|
+
* 组件参数说明:
|
|
6
|
+
* - name: 组件名称
|
|
7
|
+
* - value: 选中的值
|
|
8
|
+
* - onChange: 值改变时的回调
|
|
9
|
+
* - options: 选项列表
|
|
10
|
+
* - style: 组件样式
|
|
11
|
+
* - popoverStyle: 弹窗样式
|
|
12
|
+
* - icon: 组件图标
|
|
13
|
+
* - autoConfirm: 是否自动确认,默认为true。如果为false,则显示确定和取消按钮,点击确定后触发onChange
|
|
14
|
+
*/
|
|
1
15
|
import type { FC } from 'react';
|
|
2
16
|
import React from 'react';
|
|
3
17
|
type PageTypes = {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// src/components/MultipleSelect/index.tsx
|
|
2
|
-
import TextWithTooltip from "../TextWithToolTip";
|
|
3
2
|
import { Button, Checkbox, ConfigProvider, Flex, message, Popover, Tooltip } from "antd";
|
|
4
3
|
import classNames from "classnames";
|
|
5
4
|
import React, { useEffect, useMemo, useRef, useState } from "react";
|
|
6
5
|
import { AutoSizer, List } from "react-virtualized";
|
|
6
|
+
import TextWithTooltip from "../TextWithToolTip";
|
|
7
7
|
import DebounceInput from "../DebounceInput";
|
|
8
8
|
import styles from "./index.module.less";
|
|
9
9
|
var MultipleSelect = ({
|