@yoka-ui/ui 1.1.1 → 1.1.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.
Files changed (84) hide show
  1. package/@Docs-yoka/exports.generated.md +53 -4
  2. package/dist/es/assets/image/skills.zip +0 -0
  3. package/dist/es/business/AiChat/index.js +15 -13
  4. package/dist/es/business/AiChat/index.js.map +2 -2
  5. package/dist/es/business/AiChat/useAiChat.js +41 -24
  6. package/dist/es/business/AiChat/useAiChat.js.map +2 -2
  7. package/dist/es/business/Editor/index.d.ts +2 -2
  8. package/dist/es/business/Editor/index.js.map +2 -2
  9. package/dist/es/business/Empty/index.d.ts +1 -1
  10. package/dist/es/business/Empty/index.js.map +1 -1
  11. package/dist/es/business/ModCommonFilter/index.d.ts +1 -0
  12. package/dist/es/business/ModCommonFilter/index.js.map +2 -2
  13. package/dist/es/business/YkLoginModule/index.d.ts +1 -0
  14. package/dist/es/business/YkLoginModule/index.js.map +2 -2
  15. package/dist/es/business/YkPorjectSelect/index.d.ts +3 -3
  16. package/dist/es/business/YkPorjectSelect/index.js +37 -51
  17. package/dist/es/business/YkPorjectSelect/index.js.map +2 -2
  18. package/dist/es/business/YkSqlEdit/index.d.ts +1 -0
  19. package/dist/es/business/YkSqlEdit/index.js.map +2 -2
  20. package/dist/es/components/Clock/index.d.ts +2 -2
  21. package/dist/es/components/Clock/index.js.map +2 -2
  22. package/dist/es/components/DebounceInput/index.d.ts +2 -2
  23. package/dist/es/components/DebounceInput/index.js.map +2 -2
  24. package/dist/es/components/MultipleSelect/index.d.ts +2 -2
  25. package/dist/es/components/MultipleSelect/index.js.map +2 -2
  26. package/dist/es/components/RefreshButton/index.d.ts +2 -2
  27. package/dist/es/components/RefreshButton/index.js.map +2 -2
  28. package/dist/es/components/SearchWithHistory/index.d.ts +1 -1
  29. package/dist/es/components/SearchWithHistory/index.js.map +1 -1
  30. package/dist/es/components/TextWithInput/index.d.ts +2 -5
  31. package/dist/es/components/TextWithInput/index.js.map +2 -2
  32. package/dist/es/components/TextWithToolTip/index.d.ts +2 -2
  33. package/dist/es/components/TextWithToolTip/index.js.map +2 -2
  34. package/dist/es/components/TreeTransfer/index.d.ts +1 -0
  35. package/dist/es/components/TreeTransfer/index.js.map +2 -2
  36. package/dist/es/index.d.ts +29 -0
  37. package/dist/es/index.js.map +2 -2
  38. package/dist/es/index.less +1 -0
  39. package/dist/es/layout/YkContainer/index.d.ts +24 -14
  40. package/dist/es/layout/YkContainer/index.js +7 -41
  41. package/dist/es/layout/YkContainer/index.js.map +2 -2
  42. package/dist/es/layout/YkContainer/index.module.less +73 -0
  43. package/dist/lib/assets/image/skills.zip +0 -0
  44. package/dist/lib/business/AiChat/index.js +15 -13
  45. package/dist/lib/business/AiChat/index.js.map +2 -2
  46. package/dist/lib/business/AiChat/useAiChat.js +40 -22
  47. package/dist/lib/business/AiChat/useAiChat.js.map +2 -2
  48. package/dist/lib/business/Editor/index.d.ts +2 -2
  49. package/dist/lib/business/Editor/index.js.map +2 -2
  50. package/dist/lib/business/Empty/index.d.ts +1 -1
  51. package/dist/lib/business/Empty/index.js.map +1 -1
  52. package/dist/lib/business/ModCommonFilter/index.d.ts +1 -0
  53. package/dist/lib/business/ModCommonFilter/index.js.map +2 -2
  54. package/dist/lib/business/YkLoginModule/index.d.ts +1 -0
  55. package/dist/lib/business/YkLoginModule/index.js.map +2 -2
  56. package/dist/lib/business/YkPorjectSelect/index.d.ts +3 -3
  57. package/dist/lib/business/YkPorjectSelect/index.js +33 -27
  58. package/dist/lib/business/YkPorjectSelect/index.js.map +2 -2
  59. package/dist/lib/business/YkSqlEdit/index.d.ts +1 -0
  60. package/dist/lib/business/YkSqlEdit/index.js.map +2 -2
  61. package/dist/lib/components/Clock/index.d.ts +2 -2
  62. package/dist/lib/components/Clock/index.js.map +2 -2
  63. package/dist/lib/components/DebounceInput/index.d.ts +2 -2
  64. package/dist/lib/components/DebounceInput/index.js.map +2 -2
  65. package/dist/lib/components/MultipleSelect/index.d.ts +2 -2
  66. package/dist/lib/components/MultipleSelect/index.js.map +2 -2
  67. package/dist/lib/components/RefreshButton/index.d.ts +2 -2
  68. package/dist/lib/components/RefreshButton/index.js.map +2 -2
  69. package/dist/lib/components/SearchWithHistory/index.d.ts +1 -1
  70. package/dist/lib/components/SearchWithHistory/index.js.map +1 -1
  71. package/dist/lib/components/TextWithInput/index.d.ts +2 -5
  72. package/dist/lib/components/TextWithInput/index.js.map +2 -2
  73. package/dist/lib/components/TextWithToolTip/index.d.ts +2 -2
  74. package/dist/lib/components/TextWithToolTip/index.js.map +2 -2
  75. package/dist/lib/components/TreeTransfer/index.d.ts +1 -0
  76. package/dist/lib/components/TreeTransfer/index.js.map +2 -2
  77. package/dist/lib/index.d.ts +29 -0
  78. package/dist/lib/index.js.map +2 -2
  79. package/dist/lib/index.less +1 -0
  80. package/dist/lib/layout/YkContainer/index.d.ts +24 -14
  81. package/dist/lib/layout/YkContainer/index.js +6 -39
  82. package/dist/lib/layout/YkContainer/index.js.map +3 -3
  83. package/dist/lib/layout/YkContainer/index.module.less +73 -0
  84. package/package.json +6 -5
@@ -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';\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;",
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\nexport type DebounceInputProps = {\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<DebounceInputProps> = ({\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,iBAA+C,CAAC;AAAA,EACpD,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
  }
@@ -14,7 +14,7 @@
14
14
  */
15
15
  import type { FC } from 'react';
16
16
  import React from 'react';
17
- type PageTypes = {
17
+ export type MultipleSelectProps = {
18
18
  name?: string;
19
19
  value: (string | number)[];
20
20
  onChange: (value: (string | number)[]) => void;
@@ -33,5 +33,5 @@ type PageTypes = {
33
33
  noAllSelect?: boolean;
34
34
  autoConfirm?: boolean;
35
35
  };
36
- declare const MultipleSelect: FC<PageTypes>;
36
+ declare const MultipleSelect: FC<MultipleSelectProps>;
37
37
  export default MultipleSelect;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/MultipleSelect/index.tsx"],
4
- "sourcesContent": ["/**\n * 组件名称:MultipleSelect\n * 组件描述:一个用于多选的组件,支持搜索和选择\n * 组件使用场景:在需要选择多个值的场景中使用,如筛选、排序等\n * 组件参数说明:\n * - name: 组件名称\n * - value: 选中的值\n * - onChange: 值改变时的回调\n * - options: 选项列表\n * - style: 组件样式\n * - popoverStyle: 弹窗样式\n * - icon: 组件图标\n * - autoConfirm: 是否自动确认,默认为true。如果为false,则显示确定和取消按钮,点击确定后触发onChange\n */\n\nimport { Button, Checkbox, ConfigProvider, Flex, message, Popover, Tooltip } from 'antd';\nimport classNames from 'classnames';\nimport type { FC } from 'react';\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport { AutoSizer, List } from 'react-virtualized';\nimport TextWithTooltip from '@/components/TextWithToolTip';\nimport DebounceInput from '../DebounceInput';\nimport styles from './index.module.less';\n\ntype PageTypes = {\n name?: string;\n value: (string | number)[];\n onChange: (value: (string | number)[]) => void;\n options: { label: string; value: string | number; isSelectAll?: boolean }[];\n style?: React.CSSProperties;\n popoverStyle?: React.CSSProperties;\n icon?: React.ReactNode;\n noXiala?: boolean;\n minCount?: number;\n disabledItems?: (string | number)[] | undefined; // 禁用选项\n disabledMessages?: string; // 禁用提示\n noAllSelect?: boolean; // 是否不显示全选选项\n autoConfirm?: boolean; // 是否自动确认,默认为true,如果为false则显示确定和取消按钮\n};\n\nconst MultipleSelect: FC<PageTypes> = ({\n name,\n value = [],\n onChange,\n options = [],\n style,\n popoverStyle,\n icon,\n noXiala = false,\n minCount = 0,\n disabledItems,\n disabledMessages,\n noAllSelect = false,\n autoConfirm = true,\n}) => {\n const [searchKey, setSearchKey] = useState('');\n const [open, setOpen] = useState(false);\n const [tempValue, setTempValue] = useState<(string | number)[]>([]); // 临时存储选中的值\n const listRef = useRef(null);\n\n useEffect(() => {\n setTimeout(() => {\n setSearchKey('');\n }, 200);\n }, [open]);\n\n // 当弹窗打开时,初始化临时值\n useEffect(() => {\n if (open) {\n setTempValue(value);\n }\n }, [open, value]);\n\n const handlePopOpen = (visible: boolean) => {\n setOpen(visible);\n };\n\n const itemClick = (v: string | number, checked: boolean) => {\n const currentValue = autoConfirm ? value : tempValue;\n\n if (checked && currentValue.filter((f) => f !== v).length < minCount) {\n message.warning(`至少选择${minCount}个`);\n return;\n }\n\n const newValue = checked ? currentValue?.filter((f) => f !== v) : [...currentValue, v];\n\n if (autoConfirm) {\n // 自动确认模式,直接触发onChange\n onChange(newValue);\n } else {\n // 非自动确认模式,更新临时值\n setTempValue(newValue);\n }\n };\n\n const filterOptions = useMemo(() => {\n const key = searchKey.trim().toUpperCase();\n const filtered = options.filter((m) => {\n if (key) {\n return m.label.toUpperCase().includes(key);\n }\n return true;\n });\n // 添加全选选项到列表开头\n return noAllSelect ? filtered : [{ label: '全选', value: '__selectAll__', isSelectAll: true }, ...filtered];\n }, [searchKey, options]);\n\n const rowRenderer = ({ index, key, style }: { index: number; key: string; style: React.CSSProperties }) => {\n const m = filterOptions[index];\n const currentValue = autoConfirm ? value : tempValue;\n\n // 处理全选选项\n if (m.isSelectAll) {\n return (\n <div key={key} style={style} className={styles.checkAll}>\n <ConfigProvider\n theme={{\n token: {\n controlInteractiveSize: 14,\n },\n }}\n >\n <Checkbox\n checked={currentValue.length === options.length}\n indeterminate={currentValue.length > 0 && currentValue.length < options.length}\n onChange={(e) => {\n const newValue = e.target.checked ? options.map((m) => m.value) : [];\n if (autoConfirm) {\n onChange(newValue);\n } else {\n setTempValue(newValue);\n }\n }}\n >\n 全选\n </Checkbox>\n </ConfigProvider>\n </div>\n );\n }\n\n // 处理普通选项\n return (\n <Tooltip\n title={disabledItems?.includes(m.value) ? disabledMessages || '该选项不能改变状态' : ''}\n color='#fff'\n styles={{ body: { color: '#333', fontSize: 12 } }}\n key={key}\n style={style}\n >\n <div\n style={style}\n className={classNames(styles.optionItem, currentValue?.includes(m.value) ? styles.active : null)}\n // 可以保留整行点击\n onClick={() => {\n if (disabledItems?.includes(m.value)) {\n return;\n }\n itemClick(m.value, currentValue?.includes(m.value));\n }}\n >\n <ConfigProvider\n theme={{\n token: {\n controlInteractiveSize: 14,\n },\n }}\n >\n <Checkbox\n disabled={disabledItems?.includes(m.value)}\n checked={currentValue?.includes(m.value)}\n onChange={() => {\n itemClick(m.value, currentValue?.includes(m.value));\n }}\n // 阻止点击Checkbox时冒泡到整行\n onClick={(e) => e.stopPropagation()}\n style={{ marginRight: 8 }}\n />\n </ConfigProvider>\n <TextWithTooltip\n text={m.label}\n style={{ color: disabledItems?.includes(m.value) ? '#999' : '#333' }}\n width='100%'\n maxWidth='100%'\n className={styles.label}\n highlight={searchKey}\n />\n </div>\n </Tooltip>\n );\n };\n\n const PopoverContent = (\n <div className={styles.popoverContent} style={popoverStyle}>\n <DebounceInput\n allowClear={true}\n inputClass={styles.searchInput}\n placeholder='搜索'\n currentValue={searchKey}\n onChange={(value) => {\n setSearchKey(value);\n }}\n ></DebounceInput>\n <div className={styles.popoverContentList}>\n {filterOptions.length === 0 ? (\n <div className={styles.emptyItem}>当前搜索条件无数据</div>\n ) : (\n <AutoSizer\n style={{\n background: '#fff',\n width: '100%',\n // maxHeight: 400,\n minHeight: 35,\n height: 'auto',\n }}\n >\n {({ width }: { width: number }) => {\n let height = 35;\n if (filterOptions.length <= 10) {\n height = 35 * filterOptions.length || 35;\n } else {\n height = 35 * 10;\n }\n return (\n <List\n ref={listRef}\n overscanRowCount={5}\n width={width}\n height={height}\n rowCount={filterOptions.length}\n rowHeight={35}\n rowRenderer={rowRenderer}\n />\n );\n }}\n </AutoSizer>\n )}\n </div>\n {!autoConfirm && (\n <div className={styles.popoverFooter}>\n <Button\n size='small'\n type='primary'\n onClick={() => {\n onChange(tempValue);\n setOpen(false);\n }}\n >\n 确定\n </Button>\n <Button\n size='small'\n // className={styles.cancelButton}\n onClick={() => {\n setTempValue(value);\n setOpen(false);\n }}\n >\n 取消\n </Button>\n </div>\n )}\n </div>\n );\n\n return (\n <Popover\n open={open}\n onOpenChange={handlePopOpen}\n fresh={true}\n title={false}\n arrow={false}\n content={PopoverContent}\n trigger='click'\n placement='bottomLeft'\n styles={{ body: { borderRadius: 2, padding: 0 } }}\n >\n <Button\n className={styles.button}\n style={style}\n icon={\n noXiala ? null : <i className='iconfont icon-xiala1' style={open ? { transform: 'rotate(180deg)' } : {}} />\n }\n iconPosition='end'\n onClick={() => {\n setOpen(!open);\n }}\n >\n <Flex justify='space-between' style={{ flex: 1, overflow: 'hidden' }}>\n {icon && icon}\n {name && <span className={styles.nameText}>{name}:</span>}\n <span className={styles.valueText} style={{ flex: 1 }}>\n {value?.length === 1 && options?.length === 1\n ? options?.find((m) => m.value === value?.[0])?.label\n : (value?.length || 0) + '/' + options?.length}\n </span>\n </Flex>\n </Button>\n </Popover>\n );\n};\n\nexport default MultipleSelect;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * 组件名称:MultipleSelect\n * 组件描述:一个用于多选的组件,支持搜索和选择\n * 组件使用场景:在需要选择多个值的场景中使用,如筛选、排序等\n * 组件参数说明:\n * - name: 组件名称\n * - value: 选中的值\n * - onChange: 值改变时的回调\n * - options: 选项列表\n * - style: 组件样式\n * - popoverStyle: 弹窗样式\n * - icon: 组件图标\n * - autoConfirm: 是否自动确认,默认为true。如果为false,则显示确定和取消按钮,点击确定后触发onChange\n */\n\nimport { Button, Checkbox, ConfigProvider, Flex, message, Popover, Tooltip } from 'antd';\nimport classNames from 'classnames';\nimport type { FC } from 'react';\nimport React, { useEffect, useMemo, useRef, useState } from 'react';\nimport { AutoSizer, List } from 'react-virtualized';\nimport TextWithTooltip from '@/components/TextWithToolTip';\nimport DebounceInput from '../DebounceInput';\nimport styles from './index.module.less';\n\nexport type MultipleSelectProps = {\n name?: string;\n value: (string | number)[];\n onChange: (value: (string | number)[]) => void;\n options: { label: string; value: string | number; isSelectAll?: boolean }[];\n style?: React.CSSProperties;\n popoverStyle?: React.CSSProperties;\n icon?: React.ReactNode;\n noXiala?: boolean;\n minCount?: number;\n disabledItems?: (string | number)[] | undefined; // 禁用选项\n disabledMessages?: string; // 禁用提示\n noAllSelect?: boolean; // 是否不显示全选选项\n autoConfirm?: boolean; // 是否自动确认,默认为true,如果为false则显示确定和取消按钮\n};\n\nconst MultipleSelect: FC<MultipleSelectProps> = ({\n name,\n value = [],\n onChange,\n options = [],\n style,\n popoverStyle,\n icon,\n noXiala = false,\n minCount = 0,\n disabledItems,\n disabledMessages,\n noAllSelect = false,\n autoConfirm = true,\n}) => {\n const [searchKey, setSearchKey] = useState('');\n const [open, setOpen] = useState(false);\n const [tempValue, setTempValue] = useState<(string | number)[]>([]); // 临时存储选中的值\n const listRef = useRef(null);\n\n useEffect(() => {\n setTimeout(() => {\n setSearchKey('');\n }, 200);\n }, [open]);\n\n // 当弹窗打开时,初始化临时值\n useEffect(() => {\n if (open) {\n setTempValue(value);\n }\n }, [open, value]);\n\n const handlePopOpen = (visible: boolean) => {\n setOpen(visible);\n };\n\n const itemClick = (v: string | number, checked: boolean) => {\n const currentValue = autoConfirm ? value : tempValue;\n\n if (checked && currentValue.filter((f) => f !== v).length < minCount) {\n message.warning(`至少选择${minCount}个`);\n return;\n }\n\n const newValue = checked ? currentValue?.filter((f) => f !== v) : [...currentValue, v];\n\n if (autoConfirm) {\n // 自动确认模式,直接触发onChange\n onChange(newValue);\n } else {\n // 非自动确认模式,更新临时值\n setTempValue(newValue);\n }\n };\n\n const filterOptions = useMemo(() => {\n const key = searchKey.trim().toUpperCase();\n const filtered = options.filter((m) => {\n if (key) {\n return m.label.toUpperCase().includes(key);\n }\n return true;\n });\n // 添加全选选项到列表开头\n return noAllSelect ? filtered : [{ label: '全选', value: '__selectAll__', isSelectAll: true }, ...filtered];\n }, [searchKey, options]);\n\n const rowRenderer = ({ index, key, style }: { index: number; key: string; style: React.CSSProperties }) => {\n const m = filterOptions[index];\n const currentValue = autoConfirm ? value : tempValue;\n\n // 处理全选选项\n if (m.isSelectAll) {\n return (\n <div key={key} style={style} className={styles.checkAll}>\n <ConfigProvider\n theme={{\n token: {\n controlInteractiveSize: 14,\n },\n }}\n >\n <Checkbox\n checked={currentValue.length === options.length}\n indeterminate={currentValue.length > 0 && currentValue.length < options.length}\n onChange={(e) => {\n const newValue = e.target.checked ? options.map((m) => m.value) : [];\n if (autoConfirm) {\n onChange(newValue);\n } else {\n setTempValue(newValue);\n }\n }}\n >\n 全选\n </Checkbox>\n </ConfigProvider>\n </div>\n );\n }\n\n // 处理普通选项\n return (\n <Tooltip\n title={disabledItems?.includes(m.value) ? disabledMessages || '该选项不能改变状态' : ''}\n color='#fff'\n styles={{ body: { color: '#333', fontSize: 12 } }}\n key={key}\n style={style}\n >\n <div\n style={style}\n className={classNames(styles.optionItem, currentValue?.includes(m.value) ? styles.active : null)}\n // 可以保留整行点击\n onClick={() => {\n if (disabledItems?.includes(m.value)) {\n return;\n }\n itemClick(m.value, currentValue?.includes(m.value));\n }}\n >\n <ConfigProvider\n theme={{\n token: {\n controlInteractiveSize: 14,\n },\n }}\n >\n <Checkbox\n disabled={disabledItems?.includes(m.value)}\n checked={currentValue?.includes(m.value)}\n onChange={() => {\n itemClick(m.value, currentValue?.includes(m.value));\n }}\n // 阻止点击Checkbox时冒泡到整行\n onClick={(e) => e.stopPropagation()}\n style={{ marginRight: 8 }}\n />\n </ConfigProvider>\n <TextWithTooltip\n text={m.label}\n style={{ color: disabledItems?.includes(m.value) ? '#999' : '#333' }}\n width='100%'\n maxWidth='100%'\n className={styles.label}\n highlight={searchKey}\n />\n </div>\n </Tooltip>\n );\n };\n\n const PopoverContent = (\n <div className={styles.popoverContent} style={popoverStyle}>\n <DebounceInput\n allowClear={true}\n inputClass={styles.searchInput}\n placeholder='搜索'\n currentValue={searchKey}\n onChange={(value) => {\n setSearchKey(value);\n }}\n ></DebounceInput>\n <div className={styles.popoverContentList}>\n {filterOptions.length === 0 ? (\n <div className={styles.emptyItem}>当前搜索条件无数据</div>\n ) : (\n <AutoSizer\n style={{\n background: '#fff',\n width: '100%',\n // maxHeight: 400,\n minHeight: 35,\n height: 'auto',\n }}\n >\n {({ width }: { width: number }) => {\n let height = 35;\n if (filterOptions.length <= 10) {\n height = 35 * filterOptions.length || 35;\n } else {\n height = 35 * 10;\n }\n return (\n <List\n ref={listRef}\n overscanRowCount={5}\n width={width}\n height={height}\n rowCount={filterOptions.length}\n rowHeight={35}\n rowRenderer={rowRenderer}\n />\n );\n }}\n </AutoSizer>\n )}\n </div>\n {!autoConfirm && (\n <div className={styles.popoverFooter}>\n <Button\n size='small'\n type='primary'\n onClick={() => {\n onChange(tempValue);\n setOpen(false);\n }}\n >\n 确定\n </Button>\n <Button\n size='small'\n // className={styles.cancelButton}\n onClick={() => {\n setTempValue(value);\n setOpen(false);\n }}\n >\n 取消\n </Button>\n </div>\n )}\n </div>\n );\n\n return (\n <Popover\n open={open}\n onOpenChange={handlePopOpen}\n fresh={true}\n title={false}\n arrow={false}\n content={PopoverContent}\n trigger='click'\n placement='bottomLeft'\n styles={{ body: { borderRadius: 2, padding: 0 } }}\n >\n <Button\n className={styles.button}\n style={style}\n icon={\n noXiala ? null : <i className='iconfont icon-xiala1' style={open ? { transform: 'rotate(180deg)' } : {}} />\n }\n iconPosition='end'\n onClick={() => {\n setOpen(!open);\n }}\n >\n <Flex justify='space-between' style={{ flex: 1, overflow: 'hidden' }}>\n {icon && icon}\n {name && <span className={styles.nameText}>{name}:</span>}\n <span className={styles.valueText} style={{ flex: 1 }}>\n {value?.length === 1 && options?.length === 1\n ? options?.find((m) => m.value === value?.[0])?.label\n : (value?.length || 0) + '/' + options?.length}\n </span>\n </Flex>\n </Button>\n </Popover>\n );\n};\n\nexport default MultipleSelect;\n"],
5
+ "mappings": "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",
6
6
  "names": ["style", "m", "value"]
7
7
  }
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
- type Props = {
2
+ export type RefreshButtonProps = {
3
3
  handleRefresh: () => void;
4
4
  text?: string;
5
5
  style?: React.CSSProperties;
6
6
  };
7
- declare const RefreshButton: React.FC<Props>;
7
+ declare const RefreshButton: React.FC<RefreshButtonProps>;
8
8
  export default RefreshButton;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/RefreshButton/index.tsx"],
4
- "sourcesContent": ["import { Button } from 'antd';\nimport React from 'react';\n\ntype Props = {\n handleRefresh: () => void;\n text?: string;\n style?: React.CSSProperties;\n};\n\nconst RefreshButton: React.FC<Props> = ({ handleRefresh, text = '刷新', style }) => {\n return (\n <Button\n style={style}\n onClick={() => {\n handleRefresh();\n }}\n icon={<i className='iconfont icon-refresh' style={{ color: '#3B86F9', fontSize: 14 }} />}\n >\n {text}\n </Button>\n );\n};\n\nexport default RefreshButton;\n"],
5
- "mappings": ";AAAA,SAAS,cAAc;AACvB,OAAO,WAAW;AAQlB,IAAM,gBAAiC,CAAC,EAAE,eAAe,OAAO,MAAM,MAAM,MAAM;AAChF,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,SAAS,MAAM;AACb,sBAAc;AAAA,MAChB;AAAA,MACA,MAAM,oCAAC,OAAE,WAAU,yBAAwB,OAAO,EAAE,OAAO,WAAW,UAAU,GAAG,GAAG;AAAA;AAAA,IAErF;AAAA,EACH;AAEJ;AAEA,IAAO,wBAAQ;",
4
+ "sourcesContent": ["import { Button } from 'antd';\nimport React from 'react';\n\nexport type RefreshButtonProps = {\n handleRefresh: () => void;\n text?: string;\n style?: React.CSSProperties;\n};\n\nconst RefreshButton: React.FC<RefreshButtonProps> = ({ handleRefresh, text = '刷新', style }) => {\n return (\n <Button\n style={style}\n onClick={() => {\n handleRefresh();\n }}\n icon={<i className='iconfont icon-refresh' style={{ color: '#3B86F9', fontSize: 14 }} />}\n >\n {text}\n </Button>\n );\n};\n\nexport default RefreshButton;\n"],
5
+ "mappings": ";AAAA,SAAS,cAAc;AACvB,OAAO,WAAW;AAQlB,IAAM,gBAA8C,CAAC,EAAE,eAAe,OAAO,MAAM,MAAM,MAAM;AAC7F,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,SAAS,MAAM;AACb,sBAAc;AAAA,MAChB;AAAA,MACA,MAAM,oCAAC,OAAE,WAAU,yBAAwB,OAAO,EAAE,OAAO,WAAW,UAAU,GAAG,GAAG;AAAA;AAAA,IAErF;AAAA,EACH;AAEJ;AAEA,IAAO,wBAAQ;",
6
6
  "names": []
7
7
  }
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- type SearchWithHistoryProps = {
2
+ export type SearchWithHistoryProps = {
3
3
  /** localStorage 存储 key */
4
4
  localstorageKey: string;
5
5
  /** 可搜索的选项列表(含菜单路由、看板等) */
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/SearchWithHistory/index.tsx"],
4
- "sourcesContent": ["import { ClockCircleOutlined, SearchOutlined } from '@ant-design/icons';\nimport { useLocalStorageState } from 'ahooks';\nimport { ConfigProvider, Input, Popover } from 'antd';\nimport React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport TextWithTooltip from '@/components/TextWithToolTip';\nimport styles from './index.module.less';\n\ntype SearchWithHistoryProps = {\n /** localStorage 存储 key */\n localstorageKey: string;\n /** 可搜索的选项列表(含菜单路由、看板等) */\n list: { label: string; value: string; tag?: string }[];\n placeholder?: string;\n /** 选中项回调,value 为路由 path 或看板 id 等 */\n onClick: (value: string) => void;\n};\n\nconst INPUT_THEME = {\n token: { colorText: 'rgba(191, 199, 209, 1)' },\n components: {\n Input: {\n colorBgContainer: 'rgba(45, 56, 86, 1)',\n colorBorder: '#2D3856',\n borderRadius: 18,\n boxShadow: 'inset 0px -0.5px 0px 0px rgba(20, 31, 62, 0.5)',\n hoverBorderColor: 'rgba(0, 85, 255, 1)',\n paddingBlock: 6,\n },\n },\n};\n\n/**\n * 带历史记录的搜索弹层\n * - 无输入时展示最近搜索(localStorage 持久化)\n * - 有输入时展示匹配的菜单/看板列表\n */\nconst SearchWithHistory: React.FC<SearchWithHistoryProps> = ({\n localstorageKey = 'yk_search_history',\n list,\n placeholder = '搜索',\n onClick,\n}) => {\n const [open, setOpen] = useState(false);\n const [searchValue, setSearchValue] = useState('');\n const [historyList, setHistoryList] = useLocalStorageState<{ label: string; value: string; tag?: string }[]>(\n localstorageKey,\n { defaultValue: [] },\n );\n\n /** 选中项:执行回调并更新历史(同 value 则置顶) */\n const menuItemClick = useCallback(\n (item: { label: string; value: string; tag?: string }) => {\n onClick(item.value);\n setOpen(false);\n setHistoryList((prev = []) => [item, ...prev.filter((h) => h.value !== item.value)]);\n },\n [onClick, setHistoryList],\n );\n\n /** 清空历史 */\n const clearHistory = useCallback(() => {\n setOpen(false);\n setTimeout(() => setHistoryList([]), 100);\n }, [setHistoryList]);\n\n /** 匹配的选项列表(按 label 包含搜索词过滤) */\n const menuList = useMemo(() => list.filter((item) => item.label.includes(searchValue)), [list, searchValue]);\n\n /** 最近搜索列表 DOM */\n const historyContent = useMemo(\n () => (\n <div>\n <div className={styles.historyHeader}>\n <ClockCircleOutlined style={{ marginRight: 10, transform: 'translateY(-1px)' }} />\n <span>最近搜索</span>\n <i className='iconfont icon-lajitong' onClick={clearHistory} />\n </div>\n <div className={styles.historyList}>\n {historyList.map((item) => (\n <div className={styles.item} key={item.value} onClick={() => menuItemClick(item)}>\n <TextWithTooltip width={160} text={item.label} />\n {item.tag && <div className={styles.tag}>{item.tag}</div>}\n </div>\n ))}\n </div>\n </div>\n ),\n [historyList, clearHistory, menuItemClick],\n );\n\n /** 搜索结果列表 DOM */\n const listContent = useMemo(\n () => (\n <div>\n {menuList.map((item) => (\n <div key={item.value} className={styles.item} onClick={() => menuItemClick(item)}>\n <TextWithTooltip width={160} text={item.label} highlight={searchValue} />\n {item.tag && <div className={styles.tag}>{item.tag}</div>}\n </div>\n ))}\n </div>\n ),\n [menuList, searchValue, menuItemClick],\n );\n\n /**\n * 弹层内容:根据输入与历史决定\n * 1. 无历史 → null(不展示弹层)\n * 2. 有历史且无输入 → 最近搜索\n * 3. 有输入且无匹配 → 暂无搜索结果\n * 4. 有输入且匹配 → 菜单列表\n */\n const content = useMemo(() => {\n if (!searchValue) {\n if (historyList.length === 0) return null;\n return <div>{historyContent}</div>;\n }\n if (menuList.length === 0) return <div style={{ color: '#999' }}>暂无搜索结果</div>;\n return listContent;\n }, [searchValue, historyList, historyContent, menuList, listContent]);\n\n /** 内容为空时关闭弹层(如清空输入且无历史) */\n useEffect(() => {\n if (!content) setOpen(false);\n }, [content]);\n\n /** 有输入或有历史时显示弹层 */\n const shouldOpen = (value: string) => {\n if (value) return true;\n return historyList.length > 0;\n };\n\n return (\n <Popover\n open={open}\n onOpenChange={(nextOpen) => {\n if (nextOpen && !content) return; // 无内容时不打开,避免空白弹层\n setOpen(nextOpen);\n }}\n className={styles.popover}\n styles={{ body: { borderRadius: 4, width: 250, paddingRight: 0 } }}\n fresh\n title={false}\n trigger='click'\n placement='bottomLeft'\n arrow={false}\n content={content}\n getPopupContainer={(triggerNode: HTMLElement) => triggerNode.parentNode as HTMLElement}\n autoAdjustOverflow={false}\n >\n <ConfigProvider theme={INPUT_THEME}>\n <Input\n className={styles.inputContainer}\n classNames={{ input: styles.input }}\n placeholder={placeholder}\n prefix={<SearchOutlined />}\n value={searchValue}\n onFocus={() => historyList.length > 0 && setOpen(true)}\n onChange={(e) => {\n const val = e.target.value;\n setSearchValue(val);\n setOpen(shouldOpen(val));\n }}\n />\n </ConfigProvider>\n </Popover>\n );\n};\n\nexport default SearchWithHistory;\n"],
4
+ "sourcesContent": ["import { ClockCircleOutlined, SearchOutlined } from '@ant-design/icons';\nimport { useLocalStorageState } from 'ahooks';\nimport { ConfigProvider, Input, Popover } from 'antd';\nimport React, { useCallback, useEffect, useMemo, useState } from 'react';\nimport TextWithTooltip from '@/components/TextWithToolTip';\nimport styles from './index.module.less';\n\nexport type SearchWithHistoryProps = {\n /** localStorage 存储 key */\n localstorageKey: string;\n /** 可搜索的选项列表(含菜单路由、看板等) */\n list: { label: string; value: string; tag?: string }[];\n placeholder?: string;\n /** 选中项回调,value 为路由 path 或看板 id 等 */\n onClick: (value: string) => void;\n};\n\nconst INPUT_THEME = {\n token: { colorText: 'rgba(191, 199, 209, 1)' },\n components: {\n Input: {\n colorBgContainer: 'rgba(45, 56, 86, 1)',\n colorBorder: '#2D3856',\n borderRadius: 18,\n boxShadow: 'inset 0px -0.5px 0px 0px rgba(20, 31, 62, 0.5)',\n hoverBorderColor: 'rgba(0, 85, 255, 1)',\n paddingBlock: 6,\n },\n },\n};\n\n/**\n * 带历史记录的搜索弹层\n * - 无输入时展示最近搜索(localStorage 持久化)\n * - 有输入时展示匹配的菜单/看板列表\n */\nconst SearchWithHistory: React.FC<SearchWithHistoryProps> = ({\n localstorageKey = 'yk_search_history',\n list,\n placeholder = '搜索',\n onClick,\n}) => {\n const [open, setOpen] = useState(false);\n const [searchValue, setSearchValue] = useState('');\n const [historyList, setHistoryList] = useLocalStorageState<{ label: string; value: string; tag?: string }[]>(\n localstorageKey,\n { defaultValue: [] },\n );\n\n /** 选中项:执行回调并更新历史(同 value 则置顶) */\n const menuItemClick = useCallback(\n (item: { label: string; value: string; tag?: string }) => {\n onClick(item.value);\n setOpen(false);\n setHistoryList((prev = []) => [item, ...prev.filter((h) => h.value !== item.value)]);\n },\n [onClick, setHistoryList],\n );\n\n /** 清空历史 */\n const clearHistory = useCallback(() => {\n setOpen(false);\n setTimeout(() => setHistoryList([]), 100);\n }, [setHistoryList]);\n\n /** 匹配的选项列表(按 label 包含搜索词过滤) */\n const menuList = useMemo(() => list.filter((item) => item.label.includes(searchValue)), [list, searchValue]);\n\n /** 最近搜索列表 DOM */\n const historyContent = useMemo(\n () => (\n <div>\n <div className={styles.historyHeader}>\n <ClockCircleOutlined style={{ marginRight: 10, transform: 'translateY(-1px)' }} />\n <span>最近搜索</span>\n <i className='iconfont icon-lajitong' onClick={clearHistory} />\n </div>\n <div className={styles.historyList}>\n {historyList.map((item) => (\n <div className={styles.item} key={item.value} onClick={() => menuItemClick(item)}>\n <TextWithTooltip width={160} text={item.label} />\n {item.tag && <div className={styles.tag}>{item.tag}</div>}\n </div>\n ))}\n </div>\n </div>\n ),\n [historyList, clearHistory, menuItemClick],\n );\n\n /** 搜索结果列表 DOM */\n const listContent = useMemo(\n () => (\n <div>\n {menuList.map((item) => (\n <div key={item.value} className={styles.item} onClick={() => menuItemClick(item)}>\n <TextWithTooltip width={160} text={item.label} highlight={searchValue} />\n {item.tag && <div className={styles.tag}>{item.tag}</div>}\n </div>\n ))}\n </div>\n ),\n [menuList, searchValue, menuItemClick],\n );\n\n /**\n * 弹层内容:根据输入与历史决定\n * 1. 无历史 → null(不展示弹层)\n * 2. 有历史且无输入 → 最近搜索\n * 3. 有输入且无匹配 → 暂无搜索结果\n * 4. 有输入且匹配 → 菜单列表\n */\n const content = useMemo(() => {\n if (!searchValue) {\n if (historyList.length === 0) return null;\n return <div>{historyContent}</div>;\n }\n if (menuList.length === 0) return <div style={{ color: '#999' }}>暂无搜索结果</div>;\n return listContent;\n }, [searchValue, historyList, historyContent, menuList, listContent]);\n\n /** 内容为空时关闭弹层(如清空输入且无历史) */\n useEffect(() => {\n if (!content) setOpen(false);\n }, [content]);\n\n /** 有输入或有历史时显示弹层 */\n const shouldOpen = (value: string) => {\n if (value) return true;\n return historyList.length > 0;\n };\n\n return (\n <Popover\n open={open}\n onOpenChange={(nextOpen) => {\n if (nextOpen && !content) return; // 无内容时不打开,避免空白弹层\n setOpen(nextOpen);\n }}\n className={styles.popover}\n styles={{ body: { borderRadius: 4, width: 250, paddingRight: 0 } }}\n fresh\n title={false}\n trigger='click'\n placement='bottomLeft'\n arrow={false}\n content={content}\n getPopupContainer={(triggerNode: HTMLElement) => triggerNode.parentNode as HTMLElement}\n autoAdjustOverflow={false}\n >\n <ConfigProvider theme={INPUT_THEME}>\n <Input\n className={styles.inputContainer}\n classNames={{ input: styles.input }}\n placeholder={placeholder}\n prefix={<SearchOutlined />}\n value={searchValue}\n onFocus={() => historyList.length > 0 && setOpen(true)}\n onChange={(e) => {\n const val = e.target.value;\n setSearchValue(val);\n setOpen(shouldOpen(val));\n }}\n />\n </ConfigProvider>\n </Popover>\n );\n};\n\nexport default SearchWithHistory;\n"],
5
5
  "mappings": ";AAAA,SAAS,qBAAqB,sBAAsB;AACpD,SAAS,4BAA4B;AACrC,SAAS,gBAAgB,OAAO,eAAe;AAC/C,OAAO,SAAS,aAAa,WAAW,SAAS,gBAAgB;AACjE,OAAO,qBAAqB;AAC5B,OAAO,YAAY;AAYnB,IAAM,cAAc;AAAA,EAClB,OAAO,EAAE,WAAW,yBAAyB;AAAA,EAC7C,YAAY;AAAA,IACV,OAAO;AAAA,MACL,kBAAkB;AAAA,MAClB,aAAa;AAAA,MACb,cAAc;AAAA,MACd,WAAW;AAAA,MACX,kBAAkB;AAAA,MAClB,cAAc;AAAA,IAChB;AAAA,EACF;AACF;AAOA,IAAM,oBAAsD,CAAC;AAAA,EAC3D,kBAAkB;AAAA,EAClB;AAAA,EACA,cAAc;AAAA,EACd;AACF,MAAM;AACJ,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,EAAE;AACjD,QAAM,CAAC,aAAa,cAAc,IAAI;AAAA,IACpC;AAAA,IACA,EAAE,cAAc,CAAC,EAAE;AAAA,EACrB;AAGA,QAAM,gBAAgB;AAAA,IACpB,CAAC,SAAyD;AACxD,cAAQ,KAAK,KAAK;AAClB,cAAQ,KAAK;AACb,qBAAe,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,KAAK,OAAO,CAAC,MAAM,EAAE,UAAU,KAAK,KAAK,CAAC,CAAC;AAAA,IACrF;AAAA,IACA,CAAC,SAAS,cAAc;AAAA,EAC1B;AAGA,QAAM,eAAe,YAAY,MAAM;AACrC,YAAQ,KAAK;AACb,eAAW,MAAM,eAAe,CAAC,CAAC,GAAG,GAAG;AAAA,EAC1C,GAAG,CAAC,cAAc,CAAC;AAGnB,QAAM,WAAW,QAAQ,MAAM,KAAK,OAAO,CAAC,SAAS,KAAK,MAAM,SAAS,WAAW,CAAC,GAAG,CAAC,MAAM,WAAW,CAAC;AAG3G,QAAM,iBAAiB;AAAA,IACrB,MACE,oCAAC,aACC,oCAAC,SAAI,WAAW,OAAO,iBACrB,oCAAC,uBAAoB,OAAO,EAAE,aAAa,IAAI,WAAW,mBAAmB,GAAG,GAChF,oCAAC,cAAK,MAAI,GACV,oCAAC,OAAE,WAAU,0BAAyB,SAAS,cAAc,CAC/D,GACA,oCAAC,SAAI,WAAW,OAAO,eACpB,YAAY,IAAI,CAAC,SAChB,oCAAC,SAAI,WAAW,OAAO,MAAM,KAAK,KAAK,OAAO,SAAS,MAAM,cAAc,IAAI,KAC7E,oCAAC,mBAAgB,OAAO,KAAK,MAAM,KAAK,OAAO,GAC9C,KAAK,OAAO,oCAAC,SAAI,WAAW,OAAO,OAAM,KAAK,GAAI,CACrD,CACD,CACH,CACF;AAAA,IAEF,CAAC,aAAa,cAAc,aAAa;AAAA,EAC3C;AAGA,QAAM,cAAc;AAAA,IAClB,MACE,oCAAC,aACE,SAAS,IAAI,CAAC,SACb,oCAAC,SAAI,KAAK,KAAK,OAAO,WAAW,OAAO,MAAM,SAAS,MAAM,cAAc,IAAI,KAC7E,oCAAC,mBAAgB,OAAO,KAAK,MAAM,KAAK,OAAO,WAAW,aAAa,GACtE,KAAK,OAAO,oCAAC,SAAI,WAAW,OAAO,OAAM,KAAK,GAAI,CACrD,CACD,CACH;AAAA,IAEF,CAAC,UAAU,aAAa,aAAa;AAAA,EACvC;AASA,QAAM,UAAU,QAAQ,MAAM;AAC5B,QAAI,CAAC,aAAa;AAChB,UAAI,YAAY,WAAW;AAAG,eAAO;AACrC,aAAO,oCAAC,aAAK,cAAe;AAAA,IAC9B;AACA,QAAI,SAAS,WAAW;AAAG,aAAO,oCAAC,SAAI,OAAO,EAAE,OAAO,OAAO,KAAG,QAAM;AACvE,WAAO;AAAA,EACT,GAAG,CAAC,aAAa,aAAa,gBAAgB,UAAU,WAAW,CAAC;AAGpE,YAAU,MAAM;AACd,QAAI,CAAC;AAAS,cAAQ,KAAK;AAAA,EAC7B,GAAG,CAAC,OAAO,CAAC;AAGZ,QAAM,aAAa,CAAC,UAAkB;AACpC,QAAI;AAAO,aAAO;AAClB,WAAO,YAAY,SAAS;AAAA,EAC9B;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,cAAc,CAAC,aAAa;AAC1B,YAAI,YAAY,CAAC;AAAS;AAC1B,gBAAQ,QAAQ;AAAA,MAClB;AAAA,MACA,WAAW,OAAO;AAAA,MAClB,QAAQ,EAAE,MAAM,EAAE,cAAc,GAAG,OAAO,KAAK,cAAc,EAAE,EAAE;AAAA,MACjE,OAAK;AAAA,MACL,OAAO;AAAA,MACP,SAAQ;AAAA,MACR,WAAU;AAAA,MACV,OAAO;AAAA,MACP;AAAA,MACA,mBAAmB,CAAC,gBAA6B,YAAY;AAAA,MAC7D,oBAAoB;AAAA;AAAA,IAEpB,oCAAC,kBAAe,OAAO,eACrB;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,OAAO;AAAA,QAClB,YAAY,EAAE,OAAO,OAAO,MAAM;AAAA,QAClC;AAAA,QACA,QAAQ,oCAAC,oBAAe;AAAA,QACxB,OAAO;AAAA,QACP,SAAS,MAAM,YAAY,SAAS,KAAK,QAAQ,IAAI;AAAA,QACrD,UAAU,CAAC,MAAM;AACf,gBAAM,MAAM,EAAE,OAAO;AACrB,yBAAe,GAAG;AAClB,kBAAQ,WAAW,GAAG,CAAC;AAAA,QACzB;AAAA;AAAA,IACF,CACF;AAAA,EACF;AAEJ;AAEA,IAAO,4BAAQ;",
6
6
  "names": []
7
7
  }
@@ -1,8 +1,5 @@
1
1
  import React from 'react';
2
- /**
3
- * 文本可编辑组件的 Props
4
- */
5
- type PropsType = {
2
+ export type TextWithInputProps = {
6
3
  /** 当前展示/提交的文本值,受控 */
7
4
  value: string;
8
5
  /** 确认编辑后的回调,参数为输入框内的新值 */
@@ -11,5 +8,5 @@ type PropsType = {
11
8
  /**
12
9
  * 文本 + 内联编辑:默认展示文案与编辑图标,点击图标切为输入框+确认/取消,确认时调用 callback。
13
10
  */
14
- declare const TextWithInput: React.FC<PropsType>;
11
+ declare const TextWithInput: React.FC<TextWithInputProps>;
15
12
  export default TextWithInput;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/TextWithInput/index.tsx"],
4
- "sourcesContent": ["import { CheckOutlined, CloseOutlined, EditOutlined } from '@ant-design/icons';\nimport { Button, Input } from 'antd';\nimport React, { useState } from 'react';\n\n/**\n * 文本可编辑组件的 Props\n */\ntype PropsType = {\n /** 当前展示/提交的文本值,受控 */\n value: string;\n /** 确认编辑后的回调,参数为输入框内的新值 */\n callback: (value: string) => void;\n};\n\n/**\n * 文本 + 内联编辑:默认展示文案与编辑图标,点击图标切为输入框+确认/取消,确认时调用 callback。\n */\nconst TextWithInput: React.FC<PropsType> = ({ value, callback }) => {\n /** 是否处于编辑态(显示输入框与确认/取消按钮) */\n const [isEdit, setIsEdit] = useState(false);\n /** 编辑态下的输入内容,进入编辑时从 value 同步 */\n const [localValue, setLocalValue] = useState(value);\n\n return (\n <div style={{ display: 'flex', alignItems: 'center', gap: 5 }}>\n {isEdit ? (\n <>\n <Input value={localValue} style={{ borderRadius: 2 }} onChange={(e) => setLocalValue(e.target.value)} />\n <Button\n size='small'\n type='primary'\n style={{ width: 30, height: 30 }}\n onClick={() => {\n callback(localValue);\n setIsEdit(false);\n }}\n >\n <CheckOutlined />\n </Button>\n <Button size='small' style={{ width: 30, height: 30 }} onClick={() => setIsEdit(false)}>\n <CloseOutlined />\n </Button>\n </>\n ) : (\n <span>\n {value}\n <EditOutlined\n style={{ marginLeft: 10, cursor: 'pointer', color: '#333' }}\n onClick={() => {\n setLocalValue(value);\n setIsEdit(true);\n }}\n />\n </span>\n )}\n </div>\n );\n};\n\nexport default TextWithInput;\n"],
5
- "mappings": ";AAAA,SAAS,eAAe,eAAe,oBAAoB;AAC3D,SAAS,QAAQ,aAAa;AAC9B,OAAO,SAAS,gBAAgB;AAehC,IAAM,gBAAqC,CAAC,EAAE,OAAO,SAAS,MAAM;AAElE,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAE1C,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAElD,SACE,oCAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,EAAE,KACzD,SACC,0DACE,oCAAC,SAAM,OAAO,YAAY,OAAO,EAAE,cAAc,EAAE,GAAG,UAAU,CAAC,MAAM,cAAc,EAAE,OAAO,KAAK,GAAG,GACtG;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,MAAK;AAAA,MACL,OAAO,EAAE,OAAO,IAAI,QAAQ,GAAG;AAAA,MAC/B,SAAS,MAAM;AACb,iBAAS,UAAU;AACnB,kBAAU,KAAK;AAAA,MACjB;AAAA;AAAA,IAEA,oCAAC,mBAAc;AAAA,EACjB,GACA,oCAAC,UAAO,MAAK,SAAQ,OAAO,EAAE,OAAO,IAAI,QAAQ,GAAG,GAAG,SAAS,MAAM,UAAU,KAAK,KACnF,oCAAC,mBAAc,CACjB,CACF,IAEA,oCAAC,cACE,OACD;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,YAAY,IAAI,QAAQ,WAAW,OAAO,OAAO;AAAA,MAC1D,SAAS,MAAM;AACb,sBAAc,KAAK;AACnB,kBAAU,IAAI;AAAA,MAChB;AAAA;AAAA,EACF,CACF,CAEJ;AAEJ;AAEA,IAAO,wBAAQ;",
4
+ "sourcesContent": ["import { CheckOutlined, CloseOutlined, EditOutlined } from '@ant-design/icons';\nimport { Button, Input } from 'antd';\nimport React, { useState } from 'react';\n\nexport type TextWithInputProps = {\n /** 当前展示/提交的文本值,受控 */\n value: string;\n /** 确认编辑后的回调,参数为输入框内的新值 */\n callback: (value: string) => void;\n};\n\n/**\n * 文本 + 内联编辑:默认展示文案与编辑图标,点击图标切为输入框+确认/取消,确认时调用 callback。\n */\nconst TextWithInput: React.FC<TextWithInputProps> = ({ value, callback }) => {\n /** 是否处于编辑态(显示输入框与确认/取消按钮) */\n const [isEdit, setIsEdit] = useState(false);\n /** 编辑态下的输入内容,进入编辑时从 value 同步 */\n const [localValue, setLocalValue] = useState(value);\n\n return (\n <div style={{ display: 'flex', alignItems: 'center', gap: 5 }}>\n {isEdit ? (\n <>\n <Input value={localValue} style={{ borderRadius: 2 }} onChange={(e) => setLocalValue(e.target.value)} />\n <Button\n size='small'\n type='primary'\n style={{ width: 30, height: 30 }}\n onClick={() => {\n callback(localValue);\n setIsEdit(false);\n }}\n >\n <CheckOutlined />\n </Button>\n <Button size='small' style={{ width: 30, height: 30 }} onClick={() => setIsEdit(false)}>\n <CloseOutlined />\n </Button>\n </>\n ) : (\n <span>\n {value}\n <EditOutlined\n style={{ marginLeft: 10, cursor: 'pointer', color: '#333' }}\n onClick={() => {\n setLocalValue(value);\n setIsEdit(true);\n }}\n />\n </span>\n )}\n </div>\n );\n};\n\nexport default TextWithInput;\n"],
5
+ "mappings": ";AAAA,SAAS,eAAe,eAAe,oBAAoB;AAC3D,SAAS,QAAQ,aAAa;AAC9B,OAAO,SAAS,gBAAgB;AAYhC,IAAM,gBAA8C,CAAC,EAAE,OAAO,SAAS,MAAM;AAE3E,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAE1C,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAElD,SACE,oCAAC,SAAI,OAAO,EAAE,SAAS,QAAQ,YAAY,UAAU,KAAK,EAAE,KACzD,SACC,0DACE,oCAAC,SAAM,OAAO,YAAY,OAAO,EAAE,cAAc,EAAE,GAAG,UAAU,CAAC,MAAM,cAAc,EAAE,OAAO,KAAK,GAAG,GACtG;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,MAAK;AAAA,MACL,OAAO,EAAE,OAAO,IAAI,QAAQ,GAAG;AAAA,MAC/B,SAAS,MAAM;AACb,iBAAS,UAAU;AACnB,kBAAU,KAAK;AAAA,MACjB;AAAA;AAAA,IAEA,oCAAC,mBAAc;AAAA,EACjB,GACA,oCAAC,UAAO,MAAK,SAAQ,OAAO,EAAE,OAAO,IAAI,QAAQ,GAAG,GAAG,SAAS,MAAM,UAAU,KAAK,KACnF,oCAAC,mBAAc,CACjB,CACF,IAEA,oCAAC,cACE,OACD;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,EAAE,YAAY,IAAI,QAAQ,WAAW,OAAO,OAAO;AAAA,MAC1D,SAAS,MAAM;AACb,sBAAc,KAAK;AACnB,kBAAU,IAAI;AAAA,MAChB;AAAA;AAAA,EACF,CACF,CAEJ;AAEJ;AAEA,IAAO,wBAAQ;",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,6 @@
1
1
  import { type TooltipProps } from 'antd';
2
2
  import React from 'react';
3
- type PropsType = {
3
+ export type TextWithTooltipProps = {
4
4
  text: number | string | React.ReactNode;
5
5
  placement?: 'top' | 'left' | 'right' | 'bottom';
6
6
  zIndex?: number;
@@ -13,5 +13,5 @@ type PropsType = {
13
13
  highlight?: string;
14
14
  arrow?: boolean;
15
15
  };
16
- declare const TextWithTooltip: React.FC<PropsType>;
16
+ declare const TextWithTooltip: React.FC<TextWithTooltipProps>;
17
17
  export default TextWithTooltip;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/TextWithToolTip/index.tsx"],
4
- "sourcesContent": ["import { Tooltip, type TooltipProps } from 'antd';\nimport React, { useRef, useState } from 'react';\n\ntype PropsType = {\n text: number | string | React.ReactNode;\n placement?: 'top' | 'left' | 'right' | 'bottom';\n zIndex?: number;\n color?: string;\n styles?: TooltipProps['styles'];\n width: number | string;\n maxWidth?: number | string;\n className?: string;\n style?: React.CSSProperties;\n highlight?: string; // 高亮的关键字\n arrow?: boolean;\n};\n\nconst TextWithTooltip: React.FC<PropsType> = ({\n text,\n placement = 'top',\n zIndex,\n width,\n maxWidth,\n className,\n style = {},\n color,\n styles,\n highlight = '',\n arrow = false,\n}) => {\n const [showTooltip, setShowTooltip] = useState(false);\n const textRef = useRef(null);\n\n const handleMouseEnter = () => {\n if (textRef.current) {\n const range = document.createRange();\n range.selectNodeContents(textRef.current);\n const rangeWidth = range.getBoundingClientRect().width;\n const actualWidth = (textRef.current as HTMLElement).getBoundingClientRect().width;\n setShowTooltip(rangeWidth > actualWidth);\n }\n };\n\n // 将text按照高亮关键字拆分成数组\n function splitString(str: string, delimiter: string) {\n const result = [];\n let match;\n const escapedDelimiter = delimiter.replace(/[-/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n const regex = new RegExp(`(${escapedDelimiter})`, 'gi');\n let remaining = str; // 新建变量存储剩余字符串\n\n while ((match = regex.exec(remaining)) !== null) {\n const index = match.index;\n if (index !== 0) {\n result.push(remaining.slice(0, index));\n }\n result.push(match[1]);\n remaining = remaining.slice(index + match[1].length);\n regex.lastIndex = 0;\n }\n if (remaining.length > 0) {\n result.push(remaining);\n }\n return result;\n }\n\n // text是ReactNode时,不处理高亮\n const highlightedText = (text: number | string | React.ReactNode): React.ReactNode => {\n if (highlight && (typeof text === 'string' || typeof text === 'number')) {\n return splitString(text.toString(), highlight).map((part, index) => {\n if (part.toUpperCase() === highlight.toUpperCase()) {\n return (\n <span key={index} style={{ color: '#ffb401' }}>\n {part}\n </span>\n );\n } else {\n return <span key={index}>{part}</span>;\n }\n });\n } else {\n return text;\n }\n };\n\n // 处理宽度值,确保字符串数字能正确转换为带单位的 CSS 值\n const formatWidth = (value: number | string): number | string => {\n if (typeof value === 'string' && /^\\d+$/.test(value)) {\n // 如果是纯数字字符串,添加 px 单位\n return `${value}px`;\n }\n return value;\n };\n\n return (\n <Tooltip\n open={showTooltip}\n title={text}\n placement={placement}\n arrow={arrow}\n destroyOnHidden={true}\n color={color ? color : '#fff'}\n styles={styles ? styles : { body: { color: '#333', fontSize: 12 } }}\n {...(zIndex ? { zIndex } : {})}\n >\n <span\n ref={textRef}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={() => setShowTooltip(false)}\n className={className}\n style={{\n display: 'inline-block',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n verticalAlign: 'bottom',\n ...style,\n ...(maxWidth ? { maxWidth: formatWidth(maxWidth) } : { width: formatWidth(width) }),\n }}\n >\n {highlightedText(text)}\n </span>\n </Tooltip>\n );\n};\n\nexport default TextWithTooltip;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { Tooltip, type TooltipProps } from 'antd';\nimport React, { useRef, useState } from 'react';\n\nexport type TextWithTooltipProps = {\n text: number | string | React.ReactNode;\n placement?: 'top' | 'left' | 'right' | 'bottom';\n zIndex?: number;\n color?: string;\n styles?: TooltipProps['styles'];\n width: number | string;\n maxWidth?: number | string;\n className?: string;\n style?: React.CSSProperties;\n highlight?: string; // 高亮的关键字\n arrow?: boolean;\n};\n\nconst TextWithTooltip: React.FC<TextWithTooltipProps> = ({\n text,\n placement = 'top',\n zIndex,\n width,\n maxWidth,\n className,\n style = {},\n color,\n styles,\n highlight = '',\n arrow = false,\n}) => {\n const [showTooltip, setShowTooltip] = useState(false);\n const textRef = useRef(null);\n\n const handleMouseEnter = () => {\n if (textRef.current) {\n const range = document.createRange();\n range.selectNodeContents(textRef.current);\n const rangeWidth = range.getBoundingClientRect().width;\n const actualWidth = (textRef.current as HTMLElement).getBoundingClientRect().width;\n setShowTooltip(rangeWidth > actualWidth);\n }\n };\n\n // 将text按照高亮关键字拆分成数组\n function splitString(str: string, delimiter: string) {\n const result = [];\n let match;\n const escapedDelimiter = delimiter.replace(/[-/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n const regex = new RegExp(`(${escapedDelimiter})`, 'gi');\n let remaining = str; // 新建变量存储剩余字符串\n\n while ((match = regex.exec(remaining)) !== null) {\n const index = match.index;\n if (index !== 0) {\n result.push(remaining.slice(0, index));\n }\n result.push(match[1]);\n remaining = remaining.slice(index + match[1].length);\n regex.lastIndex = 0;\n }\n if (remaining.length > 0) {\n result.push(remaining);\n }\n return result;\n }\n\n // text是ReactNode时,不处理高亮\n const highlightedText = (text: number | string | React.ReactNode): React.ReactNode => {\n if (highlight && (typeof text === 'string' || typeof text === 'number')) {\n return splitString(text.toString(), highlight).map((part, index) => {\n if (part.toUpperCase() === highlight.toUpperCase()) {\n return (\n <span key={index} style={{ color: '#ffb401' }}>\n {part}\n </span>\n );\n } else {\n return <span key={index}>{part}</span>;\n }\n });\n } else {\n return text;\n }\n };\n\n // 处理宽度值,确保字符串数字能正确转换为带单位的 CSS 值\n const formatWidth = (value: number | string): number | string => {\n if (typeof value === 'string' && /^\\d+$/.test(value)) {\n // 如果是纯数字字符串,添加 px 单位\n return `${value}px`;\n }\n return value;\n };\n\n return (\n <Tooltip\n open={showTooltip}\n title={text}\n placement={placement}\n arrow={arrow}\n destroyOnHidden={true}\n color={color ? color : '#fff'}\n styles={styles ? styles : { body: { color: '#333', fontSize: 12 } }}\n {...(zIndex ? { zIndex } : {})}\n >\n <span\n ref={textRef}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={() => setShowTooltip(false)}\n className={className}\n style={{\n display: 'inline-block',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n verticalAlign: 'bottom',\n ...style,\n ...(maxWidth ? { maxWidth: formatWidth(maxWidth) } : { width: formatWidth(width) }),\n }}\n >\n {highlightedText(text)}\n </span>\n </Tooltip>\n );\n};\n\nexport default TextWithTooltip;\n"],
5
+ "mappings": "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",
6
6
  "names": ["text"]
7
7
  }
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { type TreeTransferProps } from './types';
3
+ export type { TreeTransferProps } from './types';
3
4
  import './index.less';
4
5
  declare function TreeTransfer<T>({ leftDataSource, rightDataSource, loading, leftTitle, rightTitle, pageSize, columns, customRender, searchFields, searchPlaceholder, onChange, }: TreeTransferProps<T>): React.JSX.Element;
5
6
  export default TreeTransfer;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/components/TreeTransfer/index.tsx"],
4
- "sourcesContent": ["/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements. See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\n/**\n * TreeTransfer\n *\n * 树形表格穿梭框组件。支持:\n * - 树形结构展示,父子联动选择(checkStrictly: false)\n * - 前端分页 + 防抖搜索\n * - 左右穿梭操作(含多级树正确迁移)\n * - 自定义列配置和渲染\n * - 完整的 TypeScript 泛型支持\n *\n * @template T - 行数据的自定义业务类型\n *\n * @example\n * ```tsx\n * <TreeTransfer\n * leftDataSource={leftData}\n * rightDataSource={rightData}\n * leftTitle=\"待分配\"\n * rightTitle=\"已分配\"\n * onChange={({ leftData, rightData }) => { ... }}\n * />\n * ```\n */\n\nimport { LeftOutlined, RightOutlined } from '@ant-design/icons';\nimport { Button, Space, Spin } from 'antd';\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport TreeTransferPanel from './components/TreeTransferPanel';\nimport { DEFAULT_PAGE_SIZE, type TreeTransferProps } from './types';\nimport {\n addNodesToTree,\n countParentNodes,\n extractTopLevelSelectedNodes,\n filterData,\n getAllDescendantKeys,\n removeNodesFromTree,\n sliceDataByPage,\n} from './utils';\nimport './index.less';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// useDebounce\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * 防抖 Hook\n *\n * 修复说明:\n * 原实现将 `callback` 放入 `useCallback` 的 deps,导致每次渲染(callback 为\n * 新引用)都重新创建防抖函数,使 timeout 重置,防抖完全失效。\n * 修复方案:将最新 callback 存入 ref,useCallback 仅依赖 delay,保证\n * 防抖函数引用稳定,timeout 不被意外清除。\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction useDebounce<T extends (...args: any[]) => any>(callback: T, delay: number): T {\n // 存储最新 callback,避免 stale closure\n const callbackRef = useRef(callback);\n callbackRef.current = callback;\n\n const timeoutRef = useRef<NodeJS.Timeout>();\n\n return useCallback(\n (...args: Parameters<T>) => {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = setTimeout(() => callbackRef.current(...args), delay);\n },\n [delay], // callback 通过 ref 读取,不需要放入 deps\n ) as T;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// TreeTransfer\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * 面板选择/分页状态(不含 dataSource,数据源来自 props + memo 计算)\n */\ninterface PanelState {\n selectedRowKeys: React.Key[];\n searchValue: string;\n currentPage: number;\n totalCount: number;\n}\n\nfunction TreeTransfer<T>({\n leftDataSource,\n rightDataSource,\n loading = false,\n leftTitle = '待分配项',\n rightTitle = '已分配项',\n pageSize = DEFAULT_PAGE_SIZE,\n columns,\n customRender,\n searchFields,\n searchPlaceholder,\n onChange,\n}: TreeTransferProps<T>) {\n // ── 面板状态(选择、搜索、分页) ─────────────────────────────────────────────\n // 注意:dataSource 不存储在 state 中;显示数据通过 memo 从 props 实时计算,\n // 避免 state 与 props 不同步的问题。\n const [leftPanel, setLeftPanel] = useState<PanelState>({\n selectedRowKeys: [],\n searchValue: '',\n currentPage: 1,\n totalCount: 0,\n });\n\n const [rightPanel, setRightPanel] = useState<PanelState>({\n selectedRowKeys: [],\n searchValue: '',\n currentPage: 1,\n totalCount: 0,\n });\n\n // ── 过滤后的完整数据(先 filter,再由 slice 分页) ──────────────────────────\n // 合并 filter + count,避免对同一搜索词调用两次 filterData(原来的问题)。\n\n const filteredLeft = useMemo(\n () => filterData<T>(leftDataSource, leftPanel.searchValue, searchFields),\n [leftDataSource, leftPanel.searchValue, searchFields],\n );\n\n const filteredRight = useMemo(\n () => filterData<T>(rightDataSource, rightPanel.searchValue, searchFields),\n [rightDataSource, rightPanel.searchValue, searchFields],\n );\n\n /** 当前页展示数据(供左侧面板渲染) */\n const filteredLeftData = useMemo(\n () => sliceDataByPage<T>(filteredLeft, leftPanel.currentPage, pageSize),\n [filteredLeft, leftPanel.currentPage, pageSize],\n );\n\n /** 当前页展示数据(供右侧面板渲染) */\n const filteredRightData = useMemo(\n () => sliceDataByPage<T>(filteredRight, rightPanel.currentPage, pageSize),\n [filteredRight, rightPanel.currentPage, pageSize],\n );\n\n /** 搜索后的顶层节点数(用于分页器 total) */\n const filteredLeftTotalCount = useMemo(() => countParentNodes(filteredLeft), [filteredLeft]);\n const filteredRightTotalCount = useMemo(() => countParentNodes(filteredRight), [filteredRight]);\n\n // ── 数据源变化时更新 totalCount,同时重置到第 1 页 ──────────────────────────\n useEffect(() => {\n setLeftPanel((prev) => ({\n ...prev,\n currentPage: 1,\n totalCount: countParentNodes(leftDataSource),\n }));\n }, [leftDataSource]);\n\n useEffect(() => {\n setRightPanel((prev) => ({\n ...prev,\n currentPage: 1,\n totalCount: countParentNodes(rightDataSource),\n }));\n }, [rightDataSource]);\n\n // ── 防抖搜索 ─────────────────────────────────────────────────────────────────\n\n const handleLeftSearchChange = useDebounce((value: string) => {\n setLeftPanel((prev) => ({ ...prev, searchValue: value, currentPage: 1 }));\n }, 300);\n\n const handleRightSearchChange = useDebounce((value: string) => {\n setRightPanel((prev) => ({ ...prev, searchValue: value, currentPage: 1 }));\n }, 300);\n\n // ── 分页 ─────────────────────────────────────────────────────────────────────\n\n const handleLeftPageChange = useCallback((page: number) => {\n setLeftPanel((prev) => ({ ...prev, currentPage: page }));\n }, []);\n\n const handleRightPageChange = useCallback((page: number) => {\n setRightPanel((prev) => ({ ...prev, currentPage: page }));\n }, []);\n\n // ── 穿梭操作 ─────────────────────────────────────────────────────────────────\n\n /**\n * 右移:将左侧选中项移到右侧\n *\n * 修复说明:\n * 原实现通过 `dataSource.filter(item => item.key === key)` 只查根节点,\n * 导致仅选中子节点时 nodesToAdd 为空,数据静默丢失。\n * 修复:使用 `extractTopLevelSelectedNodes` 递归提取选中的顶层节点(含 children)。\n */\n const handleMoveRight = useCallback(() => {\n if (leftPanel.selectedRowKeys.length === 0) return;\n\n const selectedSet = new Set(leftPanel.selectedRowKeys.map(String));\n // 提取选中的顶层节点(子节点随父一起携带)\n const nodesToAdd = extractTopLevelSelectedNodes<T>(selectedSet, leftDataSource);\n // 删除所有相关 key(含后代)\n const keysToRemove = new Set(getAllDescendantKeys(leftPanel.selectedRowKeys, leftDataSource));\n const newLeftData = removeNodesFromTree(leftDataSource, keysToRemove);\n const newRightData = addNodesToTree(rightDataSource, null, nodesToAdd);\n\n setLeftPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n setRightPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n\n onChange?.({\n leftSelected: [],\n rightSelected: [],\n leftData: newLeftData,\n rightData: newRightData,\n });\n }, [leftPanel.selectedRowKeys, leftDataSource, rightDataSource, onChange]);\n\n /**\n * 左移:将右侧选中项移到左侧\n */\n const handleMoveLeft = useCallback(() => {\n if (rightPanel.selectedRowKeys.length === 0) return;\n\n const selectedSet = new Set(rightPanel.selectedRowKeys.map(String));\n const nodesToAdd = extractTopLevelSelectedNodes<T>(selectedSet, rightDataSource);\n const keysToRemove = new Set(getAllDescendantKeys(rightPanel.selectedRowKeys, rightDataSource));\n const newRightData = removeNodesFromTree(rightDataSource, keysToRemove);\n const newLeftData = addNodesToTree(leftDataSource, null, nodesToAdd);\n\n setLeftPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n setRightPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n\n onChange?.({\n leftSelected: [],\n rightSelected: [],\n leftData: newLeftData,\n rightData: newRightData,\n });\n }, [rightPanel.selectedRowKeys, rightDataSource, leftDataSource, onChange]);\n\n // ── 渲染 ─────────────────────────────────────────────────────────────────────\n\n return (\n <div className='tree-transfer-wrapper'>\n <Spin spinning={loading}>\n <div className='tree-transfer-content'>\n {/* 左侧面板 */}\n <TreeTransferPanel<T>\n dataSource={filteredLeftData}\n selectedRowKeys={leftPanel.selectedRowKeys}\n onRowSelect={(_, keys) => setLeftPanel((prev) => ({ ...prev, selectedRowKeys: keys }))}\n searchValue={leftPanel.searchValue}\n setSearchValue={handleLeftSearchChange}\n totalCount={leftPanel.searchValue ? filteredLeftTotalCount : leftPanel.totalCount}\n title={leftTitle}\n showPagination={true}\n currentPage={leftPanel.currentPage}\n pageSize={pageSize}\n onPageChange={handleLeftPageChange}\n columns={columns}\n customRender={customRender}\n searchPlaceholder={searchPlaceholder}\n />\n\n {/* 中间操作按钮 */}\n <div className='tree-transfer-operations'>\n <Space direction='vertical' size={8}>\n <Button\n className='tree-transfer-operation-btn'\n type={leftPanel.selectedRowKeys.length > 0 ? 'primary' : 'default'}\n icon={<RightOutlined />}\n onClick={handleMoveRight}\n disabled={leftPanel.selectedRowKeys.length === 0}\n />\n <Button\n className='tree-transfer-operation-btn'\n type={rightPanel.selectedRowKeys.length > 0 ? 'primary' : 'default'}\n icon={<LeftOutlined />}\n onClick={handleMoveLeft}\n disabled={rightPanel.selectedRowKeys.length === 0}\n />\n </Space>\n </div>\n\n {/* 右侧面板 */}\n <TreeTransferPanel<T>\n dataSource={filteredRightData}\n selectedRowKeys={rightPanel.selectedRowKeys}\n onRowSelect={(_, keys) => setRightPanel((prev) => ({ ...prev, selectedRowKeys: keys }))}\n searchValue={rightPanel.searchValue}\n setSearchValue={handleRightSearchChange}\n totalCount={rightPanel.searchValue ? filteredRightTotalCount : rightPanel.totalCount}\n title={rightTitle}\n showPagination={true}\n currentPage={rightPanel.currentPage}\n pageSize={pageSize}\n onPageChange={handleRightPageChange}\n columns={columns}\n customRender={customRender}\n />\n </div>\n </Spin>\n </div>\n );\n}\n\nexport default TreeTransfer;\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/*\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements. See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License. You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n *\n */\n\n/**\n * TreeTransfer\n *\n * 树形表格穿梭框组件。支持:\n * - 树形结构展示,父子联动选择(checkStrictly: false)\n * - 前端分页 + 防抖搜索\n * - 左右穿梭操作(含多级树正确迁移)\n * - 自定义列配置和渲染\n * - 完整的 TypeScript 泛型支持\n *\n * @template T - 行数据的自定义业务类型\n *\n * @example\n * ```tsx\n * <TreeTransfer\n * leftDataSource={leftData}\n * rightDataSource={rightData}\n * leftTitle=\"待分配\"\n * rightTitle=\"已分配\"\n * onChange={({ leftData, rightData }) => { ... }}\n * />\n * ```\n */\n\nimport { LeftOutlined, RightOutlined } from '@ant-design/icons';\nimport { Button, Space, Spin } from 'antd';\nimport React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport TreeTransferPanel from './components/TreeTransferPanel';\nimport { DEFAULT_PAGE_SIZE, type TreeTransferProps } from './types';\n\nexport type { TreeTransferProps } from './types';\nimport {\n addNodesToTree,\n countParentNodes,\n extractTopLevelSelectedNodes,\n filterData,\n getAllDescendantKeys,\n removeNodesFromTree,\n sliceDataByPage,\n} from './utils';\nimport './index.less';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// useDebounce\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * 防抖 Hook\n *\n * 修复说明:\n * 原实现将 `callback` 放入 `useCallback` 的 deps,导致每次渲染(callback 为\n * 新引用)都重新创建防抖函数,使 timeout 重置,防抖完全失效。\n * 修复方案:将最新 callback 存入 ref,useCallback 仅依赖 delay,保证\n * 防抖函数引用稳定,timeout 不被意外清除。\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction useDebounce<T extends (...args: any[]) => any>(callback: T, delay: number): T {\n // 存储最新 callback,避免 stale closure\n const callbackRef = useRef(callback);\n callbackRef.current = callback;\n\n const timeoutRef = useRef<NodeJS.Timeout>();\n\n return useCallback(\n (...args: Parameters<T>) => {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = setTimeout(() => callbackRef.current(...args), delay);\n },\n [delay], // callback 通过 ref 读取,不需要放入 deps\n ) as T;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// TreeTransfer\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * 面板选择/分页状态(不含 dataSource,数据源来自 props + memo 计算)\n */\ninterface PanelState {\n selectedRowKeys: React.Key[];\n searchValue: string;\n currentPage: number;\n totalCount: number;\n}\n\nfunction TreeTransfer<T>({\n leftDataSource,\n rightDataSource,\n loading = false,\n leftTitle = '待分配项',\n rightTitle = '已分配项',\n pageSize = DEFAULT_PAGE_SIZE,\n columns,\n customRender,\n searchFields,\n searchPlaceholder,\n onChange,\n}: TreeTransferProps<T>) {\n // ── 面板状态(选择、搜索、分页) ─────────────────────────────────────────────\n // 注意:dataSource 不存储在 state 中;显示数据通过 memo 从 props 实时计算,\n // 避免 state 与 props 不同步的问题。\n const [leftPanel, setLeftPanel] = useState<PanelState>({\n selectedRowKeys: [],\n searchValue: '',\n currentPage: 1,\n totalCount: 0,\n });\n\n const [rightPanel, setRightPanel] = useState<PanelState>({\n selectedRowKeys: [],\n searchValue: '',\n currentPage: 1,\n totalCount: 0,\n });\n\n // ── 过滤后的完整数据(先 filter,再由 slice 分页) ──────────────────────────\n // 合并 filter + count,避免对同一搜索词调用两次 filterData(原来的问题)。\n\n const filteredLeft = useMemo(\n () => filterData<T>(leftDataSource, leftPanel.searchValue, searchFields),\n [leftDataSource, leftPanel.searchValue, searchFields],\n );\n\n const filteredRight = useMemo(\n () => filterData<T>(rightDataSource, rightPanel.searchValue, searchFields),\n [rightDataSource, rightPanel.searchValue, searchFields],\n );\n\n /** 当前页展示数据(供左侧面板渲染) */\n const filteredLeftData = useMemo(\n () => sliceDataByPage<T>(filteredLeft, leftPanel.currentPage, pageSize),\n [filteredLeft, leftPanel.currentPage, pageSize],\n );\n\n /** 当前页展示数据(供右侧面板渲染) */\n const filteredRightData = useMemo(\n () => sliceDataByPage<T>(filteredRight, rightPanel.currentPage, pageSize),\n [filteredRight, rightPanel.currentPage, pageSize],\n );\n\n /** 搜索后的顶层节点数(用于分页器 total) */\n const filteredLeftTotalCount = useMemo(() => countParentNodes(filteredLeft), [filteredLeft]);\n const filteredRightTotalCount = useMemo(() => countParentNodes(filteredRight), [filteredRight]);\n\n // ── 数据源变化时更新 totalCount,同时重置到第 1 页 ──────────────────────────\n useEffect(() => {\n setLeftPanel((prev) => ({\n ...prev,\n currentPage: 1,\n totalCount: countParentNodes(leftDataSource),\n }));\n }, [leftDataSource]);\n\n useEffect(() => {\n setRightPanel((prev) => ({\n ...prev,\n currentPage: 1,\n totalCount: countParentNodes(rightDataSource),\n }));\n }, [rightDataSource]);\n\n // ── 防抖搜索 ─────────────────────────────────────────────────────────────────\n\n const handleLeftSearchChange = useDebounce((value: string) => {\n setLeftPanel((prev) => ({ ...prev, searchValue: value, currentPage: 1 }));\n }, 300);\n\n const handleRightSearchChange = useDebounce((value: string) => {\n setRightPanel((prev) => ({ ...prev, searchValue: value, currentPage: 1 }));\n }, 300);\n\n // ── 分页 ─────────────────────────────────────────────────────────────────────\n\n const handleLeftPageChange = useCallback((page: number) => {\n setLeftPanel((prev) => ({ ...prev, currentPage: page }));\n }, []);\n\n const handleRightPageChange = useCallback((page: number) => {\n setRightPanel((prev) => ({ ...prev, currentPage: page }));\n }, []);\n\n // ── 穿梭操作 ─────────────────────────────────────────────────────────────────\n\n /**\n * 右移:将左侧选中项移到右侧\n *\n * 修复说明:\n * 原实现通过 `dataSource.filter(item => item.key === key)` 只查根节点,\n * 导致仅选中子节点时 nodesToAdd 为空,数据静默丢失。\n * 修复:使用 `extractTopLevelSelectedNodes` 递归提取选中的顶层节点(含 children)。\n */\n const handleMoveRight = useCallback(() => {\n if (leftPanel.selectedRowKeys.length === 0) return;\n\n const selectedSet = new Set(leftPanel.selectedRowKeys.map(String));\n // 提取选中的顶层节点(子节点随父一起携带)\n const nodesToAdd = extractTopLevelSelectedNodes<T>(selectedSet, leftDataSource);\n // 删除所有相关 key(含后代)\n const keysToRemove = new Set(getAllDescendantKeys(leftPanel.selectedRowKeys, leftDataSource));\n const newLeftData = removeNodesFromTree(leftDataSource, keysToRemove);\n const newRightData = addNodesToTree(rightDataSource, null, nodesToAdd);\n\n setLeftPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n setRightPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n\n onChange?.({\n leftSelected: [],\n rightSelected: [],\n leftData: newLeftData,\n rightData: newRightData,\n });\n }, [leftPanel.selectedRowKeys, leftDataSource, rightDataSource, onChange]);\n\n /**\n * 左移:将右侧选中项移到左侧\n */\n const handleMoveLeft = useCallback(() => {\n if (rightPanel.selectedRowKeys.length === 0) return;\n\n const selectedSet = new Set(rightPanel.selectedRowKeys.map(String));\n const nodesToAdd = extractTopLevelSelectedNodes<T>(selectedSet, rightDataSource);\n const keysToRemove = new Set(getAllDescendantKeys(rightPanel.selectedRowKeys, rightDataSource));\n const newRightData = removeNodesFromTree(rightDataSource, keysToRemove);\n const newLeftData = addNodesToTree(leftDataSource, null, nodesToAdd);\n\n setLeftPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n setRightPanel((prev) => ({ ...prev, currentPage: 1, selectedRowKeys: [] }));\n\n onChange?.({\n leftSelected: [],\n rightSelected: [],\n leftData: newLeftData,\n rightData: newRightData,\n });\n }, [rightPanel.selectedRowKeys, rightDataSource, leftDataSource, onChange]);\n\n // ── 渲染 ─────────────────────────────────────────────────────────────────────\n\n return (\n <div className='tree-transfer-wrapper'>\n <Spin spinning={loading}>\n <div className='tree-transfer-content'>\n {/* 左侧面板 */}\n <TreeTransferPanel<T>\n dataSource={filteredLeftData}\n selectedRowKeys={leftPanel.selectedRowKeys}\n onRowSelect={(_, keys) => setLeftPanel((prev) => ({ ...prev, selectedRowKeys: keys }))}\n searchValue={leftPanel.searchValue}\n setSearchValue={handleLeftSearchChange}\n totalCount={leftPanel.searchValue ? filteredLeftTotalCount : leftPanel.totalCount}\n title={leftTitle}\n showPagination={true}\n currentPage={leftPanel.currentPage}\n pageSize={pageSize}\n onPageChange={handleLeftPageChange}\n columns={columns}\n customRender={customRender}\n searchPlaceholder={searchPlaceholder}\n />\n\n {/* 中间操作按钮 */}\n <div className='tree-transfer-operations'>\n <Space direction='vertical' size={8}>\n <Button\n className='tree-transfer-operation-btn'\n type={leftPanel.selectedRowKeys.length > 0 ? 'primary' : 'default'}\n icon={<RightOutlined />}\n onClick={handleMoveRight}\n disabled={leftPanel.selectedRowKeys.length === 0}\n />\n <Button\n className='tree-transfer-operation-btn'\n type={rightPanel.selectedRowKeys.length > 0 ? 'primary' : 'default'}\n icon={<LeftOutlined />}\n onClick={handleMoveLeft}\n disabled={rightPanel.selectedRowKeys.length === 0}\n />\n </Space>\n </div>\n\n {/* 右侧面板 */}\n <TreeTransferPanel<T>\n dataSource={filteredRightData}\n selectedRowKeys={rightPanel.selectedRowKeys}\n onRowSelect={(_, keys) => setRightPanel((prev) => ({ ...prev, selectedRowKeys: keys }))}\n searchValue={rightPanel.searchValue}\n setSearchValue={handleRightSearchChange}\n totalCount={rightPanel.searchValue ? filteredRightTotalCount : rightPanel.totalCount}\n title={rightTitle}\n showPagination={true}\n currentPage={rightPanel.currentPage}\n pageSize={pageSize}\n onPageChange={handleRightPageChange}\n columns={columns}\n customRender={customRender}\n />\n </div>\n </Spin>\n </div>\n );\n}\n\nexport default TreeTransfer;\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,49 +1,78 @@
1
1
  import 'antd/dist/reset.css';
2
2
  export { default as AiChat } from './business/AiChat';
3
+ export type { AiChatProps } from './business/AiChat';
3
4
  export { default as DrawerPageInfo } from './business/DrawerPageInfo';
5
+ export type { TipContentData, FeedbackParams, PropsType as DrawerPageInfoProps } from './business/DrawerPageInfo';
4
6
  export { default as Editor } from './business/Editor';
7
+ export type { EditorProps } from './business/Editor';
5
8
  export { default as Empty } from './business/Empty';
9
+ export type { EmptyProps } from './business/Empty';
6
10
  export { default as ModCommonFilter } from './business/ModCommonFilter';
11
+ export type { ModCommonFilterProps, ListItem, CategoryItem, TerminalItem } from './business/ModCommonFilter';
7
12
  export { default as YkLoginModule } from './business/YkLoginModule';
13
+ export type { LoginModuleProps, LoginType, LoginTabItem, QrcodeApi, SmsLoginFormApi } from './business/YkLoginModule';
14
+ export type { OptionItem, YkPorjectSelectProps } from './business/YkPorjectSelect';
8
15
  export { default as YkPorjectSelect } from './business/YkPorjectSelect';
9
16
  export { default as YkSqlEdit } from './business/YkSqlEdit';
17
+ export type { YkSqlEditProps, SqlDialectType } from './business/YkSqlEdit';
10
18
  export { default as Clock } from './components/Clock';
19
+ export type { ClockProps } from './components/Clock';
11
20
  export { default as DebounceInput } from './components/DebounceInput';
21
+ export type { DebounceInputProps } from './components/DebounceInput';
12
22
  export { default as MultipleSelect } from './components/MultipleSelect';
23
+ export type { MultipleSelectProps } from './components/MultipleSelect';
13
24
  export { default as NumericInput } from './components/NumericInput';
25
+ export type { NumericInputProps } from './components/NumericInput';
14
26
  export { default as RefreshButton } from './components/RefreshButton';
27
+ export type { RefreshButtonProps } from './components/RefreshButton';
15
28
  export { default as SearchWithHistory } from './components/SearchWithHistory';
29
+ export type { SearchWithHistoryProps } from './components/SearchWithHistory';
16
30
  export { default as TextWithInput } from './components/TextWithInput';
31
+ export type { TextWithInputProps } from './components/TextWithInput';
17
32
  export { default as TextWithToolTip } from './components/TextWithToolTip';
33
+ export type { TextWithTooltipProps } from './components/TextWithToolTip';
18
34
  export { default as TreeTransfer } from './components/TreeTransfer';
35
+ export type { TreeTransferProps } from './components/TreeTransfer';
19
36
  export type { DateRangeValue, YkDateRangePickerProps, YkDateRangePickerRef, } from './components/YkDateRangePicker';
20
37
  export { default as YkDateRangePicker } from './components/YkDateRangePicker';
21
38
  export { default as YkRangeDateWithVS } from './components/YkRangeDateWithVS';
39
+ export type { YkRangeDateWithVSProps, YkRangeDateWithVSValue, YkRangeDateWithVSChange } from './components/YkRangeDateWithVS';
22
40
  export { default as YkRangeTimeWithRecent } from './components/YkRangeTimeWithRecent';
41
+ export type { YkRangeTimeWithRecentProps, YkRangeTimeWithRecentTimeType } from './components/YkRangeTimeWithRecent';
23
42
  export type { ArcCheckboxProps } from './creative/ArcCheckbox';
24
43
  export { default as ArcCheckbox } from './creative/ArcCheckbox';
25
44
  export { default as ButtonRadioWithInfo } from './creative/ButtonRadioWithInfo';
45
+ export type { ButtonRadioWithInfoProps, ButtonRadioWithInfoOption } from './creative/ButtonRadioWithInfo';
26
46
  export { default as ButtonWithProgress } from './creative/ButtonWithProgress';
47
+ export type { ButtonWithProgressProps } from './creative/ButtonWithProgress';
27
48
  export type { GlassSegmentedRadioProps, GlassSegmentOption, } from './creative/GlassSegmentedRadio';
28
49
  export { default as GlassSegmentedRadio } from './creative/GlassSegmentedRadio';
29
50
  export { default as FlexGrid } from './layout/FlexGrid';
51
+ export type { FlexGridProps, FlexGridColSpan } from './layout/FlexGrid';
30
52
  export { default as YkContainer } from './layout/YkContainer';
53
+ export type { YkContainerProps } from './layout/YkContainer';
31
54
  export { default as YkDrawer } from './layout/YkDrawer';
55
+ export type { YkDrawerProps, YkDrawerSize, YkDrawerPlacement } from './layout/YkDrawer';
32
56
  export { default as InputTheme } from './Themes/InputTheme';
33
57
  export { default as TableTheme } from './Themes/TableTheme';
34
58
  export { default as LabelSelect } from './ui/LabelSelect';
59
+ export type { LabelSelectProps, CustomOption } from './ui/LabelSelect';
35
60
  export { default as LogicOperator } from './ui/LogicOperator';
61
+ export type { LogicOperatorProps } from './ui/LogicOperator';
36
62
  export { default as YkButton } from './ui/YkButton';
63
+ export type { YkButtonProps } from './ui/YkButton';
37
64
  export { default as YkCard } from './ui/YkCard';
38
65
  export { default as YkCheckbox } from './ui/YkCheckbox';
39
66
  export { default as YkDescriptions } from './ui/YkDescriptions';
40
67
  export { default as YkPagination } from './ui/YkPagination';
41
68
  export { default as YkRadio } from './ui/YkRadio';
42
69
  export { default as YkRadioBtnSpecial } from './ui/YkRadioBtnSpecial';
70
+ export type { RadioBtnProps } from './ui/YkRadioBtnSpecial';
43
71
  export { default as YkSegmented } from './ui/YkSegmented';
44
72
  export { default as YkSelect } from './ui/YkSelect';
45
73
  export { default as YkSpin } from './ui/YkSpin';
46
74
  export { default as YkStatistic } from './ui/YkStatistic';
47
75
  export { default as YkSwitch } from './ui/YkSwitch';
48
76
  export { default as YkTabs } from './ui/YkTabs';
77
+ export type { YkTabsProps, YkTabItem } from './ui/YkTabs';
49
78
  export { default as YkTooltip } from './ui/YkTooltip';
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/index.tsx"],
4
- "sourcesContent": ["// Auto-inject Ant Design styles per project_specification_memory #6eafc28d\nimport 'antd/dist/reset.css';\n\n// Export business components\nexport { default as AiChat } from './business/AiChat';\nexport { default as DrawerPageInfo } from './business/DrawerPageInfo';\nexport { default as Editor } from './business/Editor';\nexport { default as Empty } from './business/Empty';\nexport { default as ModCommonFilter } from './business/ModCommonFilter';\nexport { default as YkLoginModule } from './business/YkLoginModule';\nexport { default as YkPorjectSelect } from './business/YkPorjectSelect';\nexport { default as YkSqlEdit } from './business/YkSqlEdit';\n// Export common components\nexport { default as Clock } from './components/Clock';\nexport { default as DebounceInput } from './components/DebounceInput';\nexport { default as MultipleSelect } from './components/MultipleSelect';\nexport { default as NumericInput } from './components/NumericInput';\nexport { default as RefreshButton } from './components/RefreshButton';\nexport { default as SearchWithHistory } from './components/SearchWithHistory';\nexport { default as TextWithInput } from './components/TextWithInput';\nexport { default as TextWithToolTip } from './components/TextWithToolTip';\nexport { default as TreeTransfer } from './components/TreeTransfer';\nexport type {\n DateRangeValue,\n YkDateRangePickerProps,\n YkDateRangePickerRef,\n} from './components/YkDateRangePicker';\nexport { default as YkDateRangePicker } from './components/YkDateRangePicker';\nexport { default as YkRangeDateWithVS } from './components/YkRangeDateWithVS';\nexport { default as YkRangeTimeWithRecent } from './components/YkRangeTimeWithRecent';\n// Export creative components\nexport type { ArcCheckboxProps } from './creative/ArcCheckbox';\nexport { default as ArcCheckbox } from './creative/ArcCheckbox';\nexport { default as ButtonRadioWithInfo } from './creative/ButtonRadioWithInfo';\nexport { default as ButtonWithProgress } from './creative/ButtonWithProgress';\nexport type {\n GlassSegmentedRadioProps,\n GlassSegmentOption,\n} from './creative/GlassSegmentedRadio';\nexport { default as GlassSegmentedRadio } from './creative/GlassSegmentedRadio';\n// Export layout\nexport { default as FlexGrid } from './layout/FlexGrid';\nexport { default as YkContainer } from './layout/YkContainer';\nexport { default as YkDrawer } from './layout/YkDrawer';\n// Export theme components\nexport { default as InputTheme } from './Themes/InputTheme';\nexport { default as TableTheme } from './Themes/TableTheme';\n// Export all UI components\nexport { default as LabelSelect } from './ui/LabelSelect';\nexport { default as LogicOperator } from './ui/LogicOperator';\nexport { default as YkButton } from './ui/YkButton';\nexport { default as YkCard } from './ui/YkCard';\nexport { default as YkCheckbox } from './ui/YkCheckbox';\nexport { default as YkDescriptions } from './ui/YkDescriptions';\nexport { default as YkPagination } from './ui/YkPagination';\nexport { default as YkRadio } from './ui/YkRadio';\nexport { default as YkRadioBtnSpecial } from './ui/YkRadioBtnSpecial';\nexport { default as YkSegmented } from './ui/YkSegmented';\nexport { default as YkSelect } from './ui/YkSelect';\nexport { default as YkSpin } from './ui/YkSpin';\nexport { default as YkStatistic } from './ui/YkStatistic';\nexport { default as YkSwitch } from './ui/YkSwitch';\nexport { default as YkTabs } from './ui/YkTabs';\nexport { default as YkTooltip } from './ui/YkTooltip';\n"],
5
- "mappings": ";AACA,OAAO;AAGP,SAAoB,WAAXA,gBAAyB;AAClC,SAAoB,WAAXA,gBAAiC;AAC1C,SAAoB,WAAXA,gBAAyB;AAClC,SAAoB,WAAXA,gBAAwB;AACjC,SAAoB,WAAXA,gBAAkC;AAC3C,SAAoB,WAAXA,gBAAgC;AACzC,SAAoB,WAAXA,gBAAkC;AAC3C,SAAoB,WAAXA,gBAA4B;AAErC,SAAoB,WAAXA,iBAAwB;AACjC,SAAoB,WAAXA,iBAAgC;AACzC,SAAoB,WAAXA,iBAAiC;AAC1C,SAAoB,WAAXA,iBAA+B;AACxC,SAAoB,WAAXA,iBAAgC;AACzC,SAAoB,WAAXA,iBAAoC;AAC7C,SAAoB,WAAXA,iBAAgC;AACzC,SAAoB,WAAXA,iBAAkC;AAC3C,SAAoB,WAAXA,iBAA+B;AAMxC,SAAoB,WAAXA,iBAAoC;AAC7C,SAAoB,WAAXA,iBAAoC;AAC7C,SAAoB,WAAXA,iBAAwC;AAGjD,SAAoB,WAAXA,iBAA8B;AACvC,SAAoB,WAAXA,iBAAsC;AAC/C,SAAoB,WAAXA,iBAAqC;AAK9C,SAAoB,WAAXA,iBAAsC;AAE/C,SAAoB,WAAXA,iBAA2B;AACpC,SAAoB,WAAXA,iBAA8B;AACvC,SAAoB,WAAXA,iBAA2B;AAEpC,SAAoB,WAAXA,iBAA6B;AACtC,SAAoB,WAAXA,iBAA6B;AAEtC,SAAoB,WAAXA,iBAA8B;AACvC,SAAoB,WAAXA,iBAAgC;AACzC,SAAoB,WAAXA,iBAA2B;AACpC,SAAoB,WAAXA,iBAAyB;AAClC,SAAoB,WAAXA,iBAA6B;AACtC,SAAoB,WAAXA,iBAAiC;AAC1C,SAAoB,WAAXA,iBAA+B;AACxC,SAAoB,WAAXA,iBAA0B;AACnC,SAAoB,WAAXA,iBAAoC;AAC7C,SAAoB,WAAXA,iBAA8B;AACvC,SAAoB,WAAXA,iBAA2B;AACpC,SAAoB,WAAXA,iBAAyB;AAClC,SAAoB,WAAXA,iBAA8B;AACvC,SAAoB,WAAXA,iBAA2B;AACpC,SAAoB,WAAXA,iBAAyB;AAClC,SAAoB,WAAXA,iBAA4B;",
4
+ "sourcesContent": ["// Auto-inject Ant Design styles per project_specification_memory #6eafc28d\nimport 'antd/dist/reset.css';\n\n// Export business components\nexport { default as AiChat } from './business/AiChat';\nexport type { AiChatProps } from './business/AiChat';\nexport { default as DrawerPageInfo } from './business/DrawerPageInfo';\nexport type { TipContentData, FeedbackParams, PropsType as DrawerPageInfoProps } from './business/DrawerPageInfo';\nexport { default as Editor } from './business/Editor';\nexport type { EditorProps } from './business/Editor';\nexport { default as Empty } from './business/Empty';\nexport type { EmptyProps } from './business/Empty';\nexport { default as ModCommonFilter } from './business/ModCommonFilter';\nexport type { ModCommonFilterProps, ListItem, CategoryItem, TerminalItem } from './business/ModCommonFilter';\nexport { default as YkLoginModule } from './business/YkLoginModule';\nexport type { LoginModuleProps, LoginType, LoginTabItem, QrcodeApi, SmsLoginFormApi } from './business/YkLoginModule';\nexport type { OptionItem, YkPorjectSelectProps } from './business/YkPorjectSelect';\nexport { default as YkPorjectSelect } from './business/YkPorjectSelect';\nexport { default as YkSqlEdit } from './business/YkSqlEdit';\nexport type { YkSqlEditProps, SqlDialectType } from './business/YkSqlEdit';\n// Export common components\nexport { default as Clock } from './components/Clock';\nexport type { ClockProps } from './components/Clock';\nexport { default as DebounceInput } from './components/DebounceInput';\nexport type { DebounceInputProps } from './components/DebounceInput';\nexport { default as MultipleSelect } from './components/MultipleSelect';\nexport type { MultipleSelectProps } from './components/MultipleSelect';\nexport { default as NumericInput } from './components/NumericInput';\nexport type { NumericInputProps } from './components/NumericInput';\nexport { default as RefreshButton } from './components/RefreshButton';\nexport type { RefreshButtonProps } from './components/RefreshButton';\nexport { default as SearchWithHistory } from './components/SearchWithHistory';\nexport type { SearchWithHistoryProps } from './components/SearchWithHistory';\nexport { default as TextWithInput } from './components/TextWithInput';\nexport type { TextWithInputProps } from './components/TextWithInput';\nexport { default as TextWithToolTip } from './components/TextWithToolTip';\nexport type { TextWithTooltipProps } from './components/TextWithToolTip';\nexport { default as TreeTransfer } from './components/TreeTransfer';\nexport type { TreeTransferProps } from './components/TreeTransfer';\nexport type {\n DateRangeValue,\n YkDateRangePickerProps,\n YkDateRangePickerRef,\n} from './components/YkDateRangePicker';\nexport { default as YkDateRangePicker } from './components/YkDateRangePicker';\nexport { default as YkRangeDateWithVS } from './components/YkRangeDateWithVS';\nexport type { YkRangeDateWithVSProps, YkRangeDateWithVSValue, YkRangeDateWithVSChange } from './components/YkRangeDateWithVS';\nexport { default as YkRangeTimeWithRecent } from './components/YkRangeTimeWithRecent';\nexport type { YkRangeTimeWithRecentProps, YkRangeTimeWithRecentTimeType } from './components/YkRangeTimeWithRecent';\n// Export creative components\nexport type { ArcCheckboxProps } from './creative/ArcCheckbox';\nexport { default as ArcCheckbox } from './creative/ArcCheckbox';\nexport { default as ButtonRadioWithInfo } from './creative/ButtonRadioWithInfo';\nexport type { ButtonRadioWithInfoProps, ButtonRadioWithInfoOption } from './creative/ButtonRadioWithInfo';\nexport { default as ButtonWithProgress } from './creative/ButtonWithProgress';\nexport type { ButtonWithProgressProps } from './creative/ButtonWithProgress';\nexport type {\n GlassSegmentedRadioProps,\n GlassSegmentOption,\n} from './creative/GlassSegmentedRadio';\nexport { default as GlassSegmentedRadio } from './creative/GlassSegmentedRadio';\n// Export layout\nexport { default as FlexGrid } from './layout/FlexGrid';\nexport type { FlexGridProps, FlexGridColSpan } from './layout/FlexGrid';\nexport { default as YkContainer } from './layout/YkContainer';\nexport type { YkContainerProps } from './layout/YkContainer';\nexport { default as YkDrawer } from './layout/YkDrawer';\nexport type { YkDrawerProps, YkDrawerSize, YkDrawerPlacement } from './layout/YkDrawer';\n// Export theme components\nexport { default as InputTheme } from './Themes/InputTheme';\nexport { default as TableTheme } from './Themes/TableTheme';\n// Export all UI components\nexport { default as LabelSelect } from './ui/LabelSelect';\nexport type { LabelSelectProps, CustomOption } from './ui/LabelSelect';\nexport { default as LogicOperator } from './ui/LogicOperator';\nexport type { LogicOperatorProps } from './ui/LogicOperator';\nexport { default as YkButton } from './ui/YkButton';\nexport type { YkButtonProps } from './ui/YkButton';\nexport { default as YkCard } from './ui/YkCard';\nexport { default as YkCheckbox } from './ui/YkCheckbox';\nexport { default as YkDescriptions } from './ui/YkDescriptions';\nexport { default as YkPagination } from './ui/YkPagination';\nexport { default as YkRadio } from './ui/YkRadio';\nexport { default as YkRadioBtnSpecial } from './ui/YkRadioBtnSpecial';\nexport type { RadioBtnProps } from './ui/YkRadioBtnSpecial';\nexport { default as YkSegmented } from './ui/YkSegmented';\nexport { default as YkSelect } from './ui/YkSelect';\nexport { default as YkSpin } from './ui/YkSpin';\nexport { default as YkStatistic } from './ui/YkStatistic';\nexport { default as YkSwitch } from './ui/YkSwitch';\nexport { default as YkTabs } from './ui/YkTabs';\nexport type { YkTabsProps, YkTabItem } from './ui/YkTabs';\nexport { default as YkTooltip } from './ui/YkTooltip';\n"],
5
+ "mappings": ";AACA,OAAO;AAGP,SAAoB,WAAXA,gBAAyB;AAElC,SAAoB,WAAXA,gBAAiC;AAE1C,SAAoB,WAAXA,gBAAyB;AAElC,SAAoB,WAAXA,gBAAwB;AAEjC,SAAoB,WAAXA,gBAAkC;AAE3C,SAAoB,WAAXA,gBAAgC;AAGzC,SAAoB,WAAXA,gBAAkC;AAC3C,SAAoB,WAAXA,gBAA4B;AAGrC,SAAoB,WAAXA,iBAAwB;AAEjC,SAAoB,WAAXA,iBAAgC;AAEzC,SAAoB,WAAXA,iBAAiC;AAE1C,SAAoB,WAAXA,iBAA+B;AAExC,SAAoB,WAAXA,iBAAgC;AAEzC,SAAoB,WAAXA,iBAAoC;AAE7C,SAAoB,WAAXA,iBAAgC;AAEzC,SAAoB,WAAXA,iBAAkC;AAE3C,SAAoB,WAAXA,iBAA+B;AAOxC,SAAoB,WAAXA,iBAAoC;AAC7C,SAAoB,WAAXA,iBAAoC;AAE7C,SAAoB,WAAXA,iBAAwC;AAIjD,SAAoB,WAAXA,iBAA8B;AACvC,SAAoB,WAAXA,iBAAsC;AAE/C,SAAoB,WAAXA,iBAAqC;AAM9C,SAAoB,WAAXA,iBAAsC;AAE/C,SAAoB,WAAXA,iBAA2B;AAEpC,SAAoB,WAAXA,iBAA8B;AAEvC,SAAoB,WAAXA,iBAA2B;AAGpC,SAAoB,WAAXA,iBAA6B;AACtC,SAAoB,WAAXA,iBAA6B;AAEtC,SAAoB,WAAXA,iBAA8B;AAEvC,SAAoB,WAAXA,iBAAgC;AAEzC,SAAoB,WAAXA,iBAA2B;AAEpC,SAAoB,WAAXA,iBAAyB;AAClC,SAAoB,WAAXA,iBAA6B;AACtC,SAAoB,WAAXA,iBAAiC;AAC1C,SAAoB,WAAXA,iBAA+B;AACxC,SAAoB,WAAXA,iBAA0B;AACnC,SAAoB,WAAXA,iBAAoC;AAE7C,SAAoB,WAAXA,iBAA8B;AACvC,SAAoB,WAAXA,iBAA2B;AACpC,SAAoB,WAAXA,iBAAyB;AAClC,SAAoB,WAAXA,iBAA8B;AACvC,SAAoB,WAAXA,iBAA2B;AACpC,SAAoB,WAAXA,iBAAyB;AAElC,SAAoB,WAAXA,iBAA4B;",
6
6
  "names": ["default"]
7
7
  }
@@ -34,6 +34,7 @@
34
34
  @import "../../src/creative/ButtonWithProgress/index.less";
35
35
  @import "../../src/creative/GlassSegmentedRadio/index.module.less";
36
36
  @import "../../src/creative/SkillsWriter/index.module.less";
37
+ @import "../../src/layout/YkContainer/index.module.less";
37
38
  @import "../../src/layout/YkDrawer/index.module.less";
38
39
  @import "../../src/Themes/TableTheme/index.less";
39
40
  @import "../../src/ui/LogicOperator/index.module.less";
@@ -1,27 +1,37 @@
1
- import React from 'react';
1
+ import React, { ReactNode } from 'react';
2
2
  export type YkContainerProps = Omit<React.HTMLAttributes<HTMLDivElement>, 'title'> & {
3
- /** 页头左侧标题,字号 18px、颜色 #3b82fe;存在 `headerLeft` 时不展示 */
3
+ /** 页头左侧主标题,字号18px、#3b82feheaderLeft存在时不展示title与subTitle */
4
4
  title?: React.ReactNode;
5
- /** 自定义页头左侧,优先级高于 `title` */
5
+ /** 页头左侧二级副标题,与title同行、下边线对齐;headerLeft优先级更高 */
6
+ subTitle?: React.ReactNode;
7
+ /** 自定义左侧整区域,优先级 > title+subTitle */
6
8
  headerLeft?: React.ReactNode;
7
- /** 页头右侧插槽 */
9
+ /** 右侧操作插槽:元素过多自动换行展示为两行及以上 */
8
10
  headerRight?: React.ReactNode;
9
- /** 是否展示页头,默认 true */
11
+ /** 是否渲染顶部固定页头,默认true */
10
12
  showHeader?: boolean;
11
13
  };
12
14
  /**
13
- * 页面内容区布局容器(语义上类似 Pro PageContainer 的内容包裹层):
14
- * 顶部可选固定(sticky)页头,左右插槽;下方区域左右与底部留白 10px、顶部与页头间距 10px;
15
- * 子元素纵向排列,间距 10px
15
+ * Yoka页面全局容器组件
16
+ * 1. 顶部sticky吸顶页头:左侧主/副标题同行下边线对齐、右侧自适应操作区(按钮过多自动换行两行)
17
+ * 2. 容器内部上下左右留白,子内容纵向间距10px,适配BI报表页面布局
18
+ * 3. 遵循项目antd/yoka-ui规范,样式使用CSS Modules Less
19
+ * @param title 主标题
20
+ * @param subTitle 二级副标题,与title同行
21
+ * @param headerLeft 自定义左侧全量插槽
22
+ * @param headerRight 右侧操作区域,内容自动换行
23
+ * @param showHeader 是否显示头部
16
24
  */
17
- declare const YkContainer: React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLDivElement>, "title"> & {
18
- /** 页头左侧标题,字号 18px、颜色 #3b82fe;存在 `headerLeft` 时不展示 */
25
+ declare const YkContainer: React.MemoExoticComponent<React.ForwardRefExoticComponent<Omit<React.HTMLAttributes<HTMLDivElement>, "title"> & {
26
+ /** 页头左侧主标题,字号18px、#3b82feheaderLeft存在时不展示title与subTitle */
19
27
  title?: React.ReactNode;
20
- /** 自定义页头左侧,优先级高于 `title` */
28
+ /** 页头左侧二级副标题,与title同行、下边线对齐;headerLeft优先级更高 */
29
+ subTitle?: React.ReactNode;
30
+ /** 自定义左侧整区域,优先级 > title+subTitle */
21
31
  headerLeft?: React.ReactNode;
22
- /** 页头右侧插槽 */
32
+ /** 右侧操作插槽:元素过多自动换行展示为两行及以上 */
23
33
  headerRight?: React.ReactNode;
24
- /** 是否展示页头,默认 true */
34
+ /** 是否渲染顶部固定页头,默认true */
25
35
  showHeader?: boolean;
26
- } & React.RefAttributes<HTMLDivElement>>;
36
+ } & React.RefAttributes<HTMLDivElement>>>;
27
37
  export default YkContainer;