searchBox.tsx 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. import useNewToken from "@/Hook/useNewToken";
  2. import { useSize } from "ahooks";
  3. import { Button, Card, InputProps, Space, SelectProps, Input, Select } from "antd"
  4. import { Key, useCallback, useEffect, useMemo, useRef, useState } from "react";
  5. import { DownOutlined, UpOutlined } from '@ant-design/icons';
  6. import React from "react";
  7. import GlobalHeader from "./header";
  8. interface IpnutType extends InputProps {
  9. label: 'Input',
  10. name: string
  11. }
  12. interface SelectType extends SelectProps {
  13. label: 'Select',
  14. name: string
  15. }
  16. export interface SearchBoxConfigPorps {
  17. config?: Array<IpnutType | SelectType>,
  18. }
  19. interface SearchBoxProps extends SearchBoxConfigPorps {
  20. children?: JSX.Element,
  21. buttons?: JSX.Element,
  22. bodyPadding?: string | number,//自定义bodyPadding
  23. isCustom?: boolean//是否自义定搜索条件
  24. }
  25. /**
  26. *@param buttons 按钮组件 <>...<Button/></>
  27. *@param config Array<IpnutType | SelectType> 搜索条件配置
  28. * */
  29. function SearchBox(props: SearchBoxProps) {
  30. const { buttons, config, children, bodyPadding, isCustom = false } = props
  31. const [data, setData] = useState<any>(null)
  32. const ref: any = useRef(null);
  33. const refBtns: any = useRef(null);
  34. const refBox: any = useRef(null);
  35. const [show, setShow] = useState(false)
  36. const [setHeight, set_setHeight] = useState(false)
  37. const { token } = useNewToken()
  38. const size = useSize(ref);
  39. const sizeBtn = useSize(refBtns);
  40. const sizeBox = useSize(refBox);
  41. const [btnMinWidth, setBtnMinWindth] = useState(-1)
  42. const [chiMinWidth, setChiMinWindth] = useState(-1)
  43. const showDiv = useCallback(() => {
  44. set_setHeight(!setHeight)
  45. }, [setHeight])
  46. useEffect(() => {
  47. if (ref?.current && size.height) {
  48. let divH: any = size.height
  49. let childrenH = ref?.current?.children[0]?.offsetHeight
  50. console.log(ref?.current?.children[0])
  51. if (divH > childrenH || !childrenH) {
  52. setShow(false)
  53. } else {
  54. setShow(true)
  55. }
  56. // console.log(divH, childrenH)
  57. }
  58. }, [size, ref])
  59. useEffect(() => {
  60. if (refBtns?.current && ref.current && sizeBtn.width && sizeBox.width && size.width) {
  61. // console.log(sizeBox.width, size.width, sizeBtn.width)
  62. let btns = refBtns?.current?.children[0]?.children[0]?.children
  63. let chis = ref?.current?.children[0]?.children
  64. let wArr: any = []
  65. let cArr: any = []
  66. Array(chis?.length)?.fill('')?.forEach((a, b) => {
  67. if (b) {
  68. cArr[b] = chis[b]?.offsetWidth + 8
  69. }
  70. })
  71. Array(btns?.length)?.fill('')?.forEach((a, b) => {
  72. let n = wArr[wArr.length - 1] || 0
  73. if (b % 2 === 1) {
  74. // console.log('1=====>', b, n, wArr)
  75. wArr[wArr.length - 1] = btns[b]?.offsetWidth + n
  76. } else {
  77. wArr.push(btns[b].offsetWidth + 8)
  78. }
  79. })
  80. let maxBtnW = Math.max(...wArr)
  81. if (maxBtnW + 75 > sizeBtn.width && sizeBox.width - size.width < maxBtnW + 75) {
  82. let cW = sizeBox.width - 20 - maxBtnW - 75
  83. let newCw = 0
  84. for (let cw of cArr) {
  85. if (newCw + cw < cW) {
  86. newCw += cw
  87. }
  88. }
  89. setChiMinWindth(newCw)
  90. setBtnMinWindth(maxBtnW)
  91. }
  92. }
  93. }, [refBtns, sizeBtn, sizeBox, refBox, size, ref])
  94. return <Card
  95. style={{ background: token.colortRansparency, borderRadius: 0, borderTop: 0, borderRight: 0, borderLeft: 0 }}
  96. styles={{
  97. body: { display: 'flex', justifyContent: !show ? 'flex-start' : 'flex-start', padding: bodyPadding ? bodyPadding : 'auto' }
  98. }}
  99. ref={refBox}
  100. >
  101. {children && <div style={{ flexShrink: 1, marginRight: !show ? 20 : 0 }} >
  102. <div ref={ref} style={{ height: setHeight ? 'auto' : '30px', overflow: 'hidden', width: chiMinWidth !== -1 ? chiMinWidth : 'auto' }}>
  103. {
  104. isCustom ? children: <Space wrap >
  105. {children}
  106. {/* {config?.map((item, index) => {
  107. if (item.label === 'Input') {
  108. let { label, name, ...props } = item
  109. return <Input
  110. {...props}
  111. key={index}
  112. allowClear
  113. onChange={(e) => {
  114. let v = e.target.value
  115. setData({ ...data, [name]: v })
  116. }} />
  117. }
  118. if (item.label === 'Select') {
  119. let { label, options, name, ...props } = item
  120. return <Select {...props}
  121. options={options?.map(item => ({ ...item }))}
  122. key={index}
  123. allowClear
  124. onChange={(v) => {
  125. setData({ ...data, [name]: v })
  126. }}
  127. />
  128. }
  129. })} */}
  130. </Space>
  131. }
  132. </div>
  133. </div>}
  134. <div style={{ height: setHeight ? 'auto' : '30px', overflow: 'hidden', flexShrink: 1, display: 'flex', justifyContent: !show ? 'flex-start' : 'space-between', alignItems: 'flex-start', width: btnMinWidth === -1 ? 'auto' : btnMinWidth + 75 }} ref={refBtns}>
  135. <div style={{ width: btnMinWidth === -1 ? 'auto' : btnMinWidth }}>
  136. <Space wrap >
  137. {buttons}
  138. {/* {buttons?.props?.children?.map((item: any) => {
  139. if (item.props.name === 'submit') {
  140. return <Button {...item.props} key='item.props.name' onClick={() => {
  141. item.props.onClick && item.props.onClick(data)
  142. }} />
  143. }
  144. return item
  145. })} */}
  146. </Space></div>
  147. {show && <Space><div style={{ flexShrink: 1, width: '75px' }}><Button type="link" onClick={showDiv}>{!setHeight ? <> 展开 <DownOutlined /> </> : <>收起 <UpOutlined /></>}</Button></div></Space>}
  148. </div>
  149. </Card >
  150. }
  151. export default React.memo(SearchBox, (prevProps, nextProps) => {
  152. return false
  153. })