ahooks#useSize TypeScript Examples

The following examples show how to use ahooks#useSize. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Gantt.tsx    From react-gantt-component with MIT License 6 votes vote down vote up
Body: React.FC = ({ children }) => {
  const { store } = useContext(Context);
  const ref = useRef<HTMLDivElement>(null);
  const size = useSize(ref);
  useEffect(() => {
    store.syncSize(size);
  }, [size, store]);
  return (
    <div className={`${prefixCls}-body`} ref={ref}>
      {children}
    </div>
  );
}
Example #2
Source File: index.tsx    From scorpio-h5-design with MIT License 6 votes vote down vote up
export default function(props:IProps) {
  const ref = useRef<HTMLDivElement>(null);
  const size = useSize(ref);
  const { setStateByObjectKeys } = useModel('bridge');
  useEffect(()=>{
    if(history.location.pathname === '/manage/component/detail' && !props.loading){
      setStateByObjectKeys({
        showSelectComponentBorder: false,
      });
    }
  }, [props.loading]);

  return (
    <div className="mobile-simulator-container">
      {(history.location.pathname !== '/manage/component/detail' && !props.loading) && <SelectArea size={size} loading={props.loading}/>}
      <div className="mobile-simulator">
        <div className="mobile-head-bar"></div>
        <div className="mobile-content" id="mobile-content" ref={ref} />
      </div>
    </div>
  );
}
Example #3
Source File: AppWrapper.tsx    From airtable-app-mind-flow with MIT License 5 votes vote down vote up
AppWrapper: FC = () => {
  const { isShowSettings, setShowSettings } = useShowSettings();
  const { settings, isValid } = useSettingsStore();
  const { locale, messages } = useI18n();

  const graph = useRef(null);
  const canvas = useRef(null);

  const size = useSize(canvas);

  useEffect(() => {
    if (!isValid && !isShowSettings) {
      setShowSettings(true);
    }
  }, [setShowSettings, isValid, isShowSettings]);

  return (
    <IntlProvider
      locale={locale}
      defaultLocale={'en-US'}
      // @ts-ignore
      messages={messages ? messages : {}}
    >
      <Box
        position="absolute"
        top={0}
        left={0}
        right={0}
        bottom={0}
        display="flex"
        backgroundColor="#f5f5f5"
        overflow="hidden"
      >
        <Box
          ref={canvas}
          style={{
            width: isShowSettings ? 'calc(100% - 300px)' : '100%',
          }}
        >
          <MindFlow width={size.width} height={size.height} />
        </Box>
        {isShowSettings && (
          <Settings graph={graph} settings={settings} isValid={isValid} />
        )}
      </Box>
    </IntlProvider>
  );
}
Example #4
Source File: index.tsx    From fe-v5 with Apache License 2.0 5 votes vote down vote up
Hexbin: FunctionComponent<HoneyCombProps> = (props) => {
  const { values, series } = props;
  const { custom = {}, options } = values;
  const { calc, colorRange = [], reverseColorOrder = false, colorDomainAuto, colorDomain } = custom as IHexbinStyles;
  const groupEl = useRef<SVGGElement>(null);
  const svgEl = useRef<HTMLDivElement>(null);
  const svgSize = useSize(svgEl);

  useEffect(() => {
    const calculatedValues = getCalculatedValuesBySeries(
      series,
      calc,
      {
        util: options?.standardOptions?.util,
        decimals: options?.standardOptions?.decimals,
      },
      options?.valueMappings,
    );
    const colorScales = d3
      .scaleLinear()
      .domain(getColorScaleLinearDomain(calculatedValues, colorDomainAuto, colorDomain))
      .range(reverseColorOrder ? _.reverse(_.slice(colorRange)) : colorRange);

    if (svgSize?.width && svgSize?.height) {
      const renderProps = {
        width: svgSize?.width,
        height: svgSize?.height,
        parentGroupEl: groupEl.current,
      };
      const data = _.map(calculatedValues, (item) => {
        return {
          ...item,
          value: item.text,
          color: item.color || colorScales(item.stat) || '#3399CC',
        };
      });
      d3.select(groupEl.current).selectAll('*').remove();
      if (data.length) {
        renderFn(data, renderProps);
      }
    }
  }, [JSON.stringify(series), JSON.stringify(options), svgSize?.width, svgSize?.height, calc, colorRange, reverseColorOrder, colorDomainAuto, colorDomain]);
  return (
    <div ref={svgEl} style={{ width: '100%', height: '100%' }}>
      <svg style={{ width: '100%', height: '100%' }}>
        <g ref={groupEl} />
      </svg>
    </div>
  );
}
Example #5
Source File: index.tsx    From fe-v5 with Apache License 2.0 5 votes vote down vote up
function StatItem(props) {
  const ele = useRef(null);
  const eleSize = useSize(ele);
  const { item, idx, colSpan, textMode, colorMode, textSize } = props;
  const headerFontSize = textSize?.title ? textSize?.title : eleSize?.width! / _.toString(item.name).length || 12;
  let statFontSize = textSize?.value ? textSize?.value : eleSize?.width! / _.toString(item.text).length || 12;
  const color = item.color ? item.color : hexPalette[idx % hexPalette.length];

  if (statFontSize > eleSize?.height! - 20) {
    statFontSize = eleSize?.height! - 20;
  }

  return (
    <div
      key={item.name}
      className='renderer-stat-item'
      ref={ele}
      style={{
        width: `${100 / colSpan}%`,
        flexBasis: `${100 / colSpan}%`,
        backgroundColor: colorMode === 'background' ? color : 'transparent',
      }}
    >
      <div className='renderer-stat-item-content'>
        {textMode === 'valueAndName' && (
          <div
            className='renderer-stat-header'
            style={{
              fontSize: headerFontSize > 100 ? 100 : headerFontSize,
            }}
          >
            {item.name}
          </div>
        )}
        <div
          className='renderer-stat-value'
          style={{
            color: colorMode === 'value' ? color : '#fff',
            fontSize: statFontSize > 100 ? 100 : statFontSize,
          }}
        >
          {item.text}
        </div>
      </div>
    </div>
  );
}
Example #6
Source File: index.tsx    From web-pdm with Apache License 2.0 4 votes vote down vote up
useLocal = () => {
    const mst = useMst()
    // window.kkk = mst

    const containerRef = useRef(null)
    const erdGraphRef = useRef<Graph>(null)
    const miniMapRef = useRef<any>(null)
    useEffect(() => {
        register(mst)
    }, [])
    const checkRef = useRef(+new Date())
    const size = useSize(containerRef);
    useEffect(() => {
        // alert()
        // const { Nodes , edges } = mst
        if (!erdGraphRef.current) {
            //  alert(mst.Nodes.length)
            // alert(mst === window.kkk)
            //alert('erdGraphRef.current = render')
            const Obj = render(containerRef.current, mst.Nodes, mst.edges, mst)
            erdGraphRef.current = Obj.graph
            miniMapRef.current = Obj.miniMap
            //alert('erdGraphRef.current')
            //  alert(mst.graph.$modelId)
            async(() => {
                mst.graph.setG6Graph(erdGraphRef.current)
                // layout(erdGraphRef.current,  Nodes , edges, mst)
            })

            //  window.kkk1 = mst
        } else {
            //alert('  layout(erdGraphRef.current,  mst.Nodes ' + mst.Nodes.length)
            layout(erdGraphRef.current, mst.Nodes, mst.edges, mst)
            // erdGraphRef.current.fitView(0)
        }
    }, [JSON.stringify(mst.sys.checkedKeys), mst])

    useEffect(() => {
        if (erdGraphRef.current && size.width && size.height) {
            // alert(erdGraphRef.current['isLayouting'])
            if (!erdGraphRef.current['isLayouting']) {
                const documentHeight =
                    window.innerHeight ||
                    document.documentElement.clientHeight ||
                    document.body.clientHeight
                const height =
                    mst.sys.height === '100%'
                        ? documentHeight - 45
                        : (mst.sys.height as number) - 45
                erdGraphRef.current.changeSize(size.width, height)
                erdGraphRef.current.fitView(0)

            }

        }

    }, [size.height, size.width])
    const setRef = useCallback(
        ref => {
            containerRef.current = ref
        },
        [containerRef]
    )
    useEffect(() => {
        // debounce(()=> {
        const graph = erdGraphRef.current
        if (graph) {
            const gwidth = graph.get('width')
            const gheight = graph.get('height')
            const point = graph.getCanvasByPoint(gwidth / 2, gheight / 2)

            graph.zoomTo(mst.graph.zoom, point)
        }
        // }
        //  }, 100)()
    }, [mst.graph.zoom])
    const reloadRef = useRef(false)
    useEffect(() => {
        // debounce(()=> {
        const graph = erdGraphRef.current
        if (graph) {
            if (!reloadRef.current) {
                reloadRef.current = true
                return
            }
            // alert()
            // graph.clear()
            // graph.data({ nodes: mst.Nodes, edges: mst.edges })
            // graph.render()
            const isLargar = graph.getNodes().length > 50
            graph.updateLayout({
                type: mst.sys.dagreLayout ? 'dagre' : 'fruchterman',
                // condense: true,
                // cols: 3,
                workerEnabled: true,
                linkDistance: 0,
                pixelRatio: 2,
                // alphaDecay: isLargar ? 0.3 : 0.15,
                // preventOverlap: true,
                // clustering: true,
                clusterGravity: 100,
                speed: 2,
                gravity: 100,
                gpuEnabled: true,
                // collideStrength: 0.5,
                //   type: 'dagre',
                //   // controlPoints: true,
                //   // nodeSize: [40, 20],
                // nodesep: 1,
                // ranksep: 1,
                // align: 'DL',
                // nodesep: 100, // 节点水平间距(px)
                // ranksep: 200, // 每一层节点之间间距

                // nodeSpacing: isLargar ? -100 : -180,
                onLayoutEnd: () => {
                    async(() => {
                        // alert()
                        graph['isLayouting'] = false
                        // graph['isLayouting'] = false
                        // alert('endlayout')
                        graph.fitView(0)

                        withoutUndo(() => {
                            mst.graph.setZoom(graph.getZoom())
                        })

                        // alert('onLayoutEnd')
                    }, 1000)
                }
            })
            if (mst.sys.dagreLayout) {
                async(() => {
                    // alert()
                    graph.fitView(0)
                }, 1000)
            }
        }
    }, [mst.sys.dagreLayout])

    //  alert('useUpdateItem' + mst.graph.zoom)
    useUpdateItem({
        currentModel: mst.sys.currentModel,
        graph: erdGraphRef.current as any,
        showNameOrLabel: mst.sys.showNameOrLabel,
        zoom: mst.graph.zoom,
        checkNum: checkRef.current,
        themeColor: mst.Ui.themeColor,
        darkness: mst.Ui.darkness
    })

    useEffect(() => {
        if (erdGraphRef.current && miniMapRef.current) {
            // alert()
            if (!mst.sys.disableMiniMap) {
                erdGraphRef.current?.removePlugin(miniMapRef.current)
            } else {
                const miniMap = new G6.Minimap({
                    type: 'delegate',
                    viewportClassName: 'g6-minimap-viewport-erd',
                    delegateStyle: {
                        fill: 'rgba(0,0,0,0.10)'
                    }
                })
                miniMapRef.current = miniMap
                erdGraphRef.current?.addPlugin(miniMap)
            }
        }
    }, [mst.sys.disableMiniMap])

    return {
        containerRef,
        setRef,
        erdGraph: erdGraphRef.current
    }
}
Example #7
Source File: index.tsx    From fe-v5 with Apache License 2.0 4 votes vote down vote up
export default function Stat(props: IProps) {
  const eleRef = useRef<HTMLDivElement>(null);
  const size = useSize(eleRef);
  const { dispatch } = useContext(Context);
  const { values, series } = props;
  const { custom, options, overrides } = values;
  const { showHeader, calc, aggrDimension, displayMode, columns, sortColumn, sortOrder } = custom;
  const [calculatedValues, setCalculatedValues] = React.useState([]);
  const [sortObj, setSortObj] = React.useState({
    sortColumn,
    sortOrder,
  });

  useEffect(() => {
    setSortObj({
      sortColumn,
      sortOrder,
    });
  }, [sortColumn, sortOrder]);

  useEffect(() => {
    const data = getCalculatedValuesBySeries(
      series,
      calc,
      {
        util: options?.standardOptions?.util,
        decimals: options?.standardOptions?.decimals,
      },
      options?.valueMappings,
    );
    if (dispatch) {
      dispatch({
        type: 'updateMetric',
        payload: getColumnsKeys(data),
      });
    }
    setCalculatedValues(data);
  }, [JSON.stringify(series), calc, JSON.stringify(options)]);

  let tableDataSource = calculatedValues;
  let tableColumns: any[] = [
    {
      title: 'name',
      dataIndex: 'name',
      key: 'name',
      sorter: (a, b) => {
        return localeCompare(a.name, b.name);
      },
      sortOrder: getSortOrder('name', sortObj),
      render: (text) => <div className='renderer-table-td-content'>{text}</div>,
    },
    {
      title: 'value',
      dataIndex: 'text',
      key: 'text',
      sorter: (a, b) => {
        return a.stat - b.stat;
      },
      sortOrder: getSortOrder('value', sortObj),
      render: (text, record) => {
        let textObj = {
          text,
          color: record.color,
        };
        const overrideProps = getOverridePropertiesByName(overrides, record.fields.refId);
        if (!_.isEmpty(overrideProps)) {
          textObj = getSerieTextObj(record?.stat, overrideProps?.standardOptions, overrideProps?.valueMappings);
        }
        return (
          <div className='renderer-table-td-content' style={{ color: textObj.color }}>
            {textObj.text}
          </div>
        );
      },
    },
  ];

  if (displayMode === 'labelsOfSeriesToRows') {
    const columnsKeys = _.isEmpty(columns) ? _.concat(getColumnsKeys(calculatedValues), 'value') : columns;
    tableColumns = _.map(columnsKeys, (key) => {
      return {
        title: key,
        dataIndex: key,
        key: key,
        sorter: (a, b) => {
          if (key === 'value') {
            return a.stat - b.stat;
          }
          return localeCompare(a.name, b.name);
        },
        sortOrder: getSortOrder(key, sortObj),
        render: (_text, record) => {
          if (key === 'value') {
            return _.get(record, 'text');
          }
          return _.get(record.metric, key);
        },
      };
    });
  }

  if (displayMode === 'labelValuesToRows' && aggrDimension) {
    tableDataSource = formatToTable(calculatedValues, aggrDimension, 'refId');
    const groupNames = _.reduce(
      tableDataSource,
      (pre, item) => {
        return _.union(_.concat(pre, item.groupNames));
      },
      [],
    );
    tableColumns = [
      {
        title: aggrDimension,
        dataIndex: aggrDimension,
        key: aggrDimension,
        sorter: (a, b) => {
          return localeCompare(a[aggrDimension], b[aggrDimension]);
        },
        sortOrder: getSortOrder(aggrDimension, sortObj),
        render: (text) => <div className='renderer-table-td-content'>{text}</div>,
      },
    ];
    _.map(groupNames, (name) => {
      const result = _.find(tableDataSource, (item) => {
        return item[name];
      });
      tableColumns.push({
        title: result[name]?.name,
        dataIndex: name,
        key: name,
        sorter: (a, b) => {
          return _.get(a[name], 'stat') - _.get(b[name], 'stat');
        },
        sortOrder: getSortOrder('value', sortObj),
        render: (text) => {
          let textObj = {
            text: text?.text,
            color: text?.color,
          };
          const overrideProps = getOverridePropertiesByName(overrides, name);
          if (!_.isEmpty(overrideProps)) {
            textObj = getSerieTextObj(text?.stat, overrideProps?.standardOptions, overrideProps?.valueMappings);
          }
          return (
            <div className='renderer-table-td-content' style={{ color: textObj?.color }}>
              {textObj?.text}
            </div>
          );
        },
      });
    });
  }

  const headerHeight = showHeader ? 40 : 0;
  const height = _.get(size, 'height') - headerHeight;
  const realHeight = isNaN(height) ? 0 : height;

  return (
    <div className='renderer-table-container' ref={eleRef}>
      <div className='renderer-table-container-box'>
        <Table
          rowKey='id'
          getPopupContainer={() => document.body}
          showSorterTooltip={false}
          showHeader={showHeader}
          dataSource={tableDataSource}
          columns={tableColumns}
          scroll={{ y: realHeight }}
          bordered={false}
          pagination={false}
          onChange={(pagination, filters, sorter: any) => {
            setSortObj({
              sortColumn: sorter.columnKey,
              sortOrder: sorter.order,
            });
          }}
        />
      </div>
    </div>
  );
}
Example #8
Source File: index.tsx    From fe-v5 with Apache License 2.0 4 votes vote down vote up
export default function index(props: IProps) {
  const { values, series, inDashboard = true, chartHeight = '200px', tableHeight = '200px' } = props;
  const { custom, options = {} } = values;
  const chartEleRef = useRef<HTMLDivElement>(null);
  const chartRef = useRef<TsGraph>(null);
  const legendEleRef = useRef<HTMLDivElement>(null);
  const legendEleSize = useSize(legendEleRef);
  const hasLegend = options.legend?.displayMode !== 'hidden';
  const [legendData, setLegendData] = useState([]);
  let _chartHeight = hasLegend ? '70%' : '100%';
  let _tableHeight = hasLegend ? '30%' : '0px';

  if (!inDashboard) {
    _chartHeight = chartHeight;
    _tableHeight = tableHeight;
  }

  useEffect(() => {
    if (chartEleRef.current) {
      if (chartRef.current) {
        chartRef.current.destroy();
      }
      chartRef.current = new TsGraph({
        colors: hexPalette,
        timestamp: 'X',
        xkey: 0,
        ykey: 1,
        ykeyFormatter: (value) => Number(value),
        chart: {
          renderTo: chartEleRef.current,
          height: chartEleRef.current.clientHeight,
        },
        series: [],
        line: {
          width: 1,
        },
      });
    }
    if (hasLegend) {
      setLegendData(
        getLegendValues(
          series,
          {
            util: options?.standardOptions?.util,
            decimals: options?.standardOptions?.decimals,
          },
          hexPalette,
        ),
      );
    } else {
      setLegendData([]);
    }
    return () => {
      if (chartRef.current && typeof chartRef.current.destroy === 'function') {
        chartRef.current.destroy();
      }
    };
  }, [hasLegend]);

  useEffect(() => {
    if (chartRef.current) {
      chartRef.current.update({
        type: custom.drawStyle === 'lines' ? 'line' : 'bar',
        series,
        area: {
          opacity: custom.fillOpacity,
        },
        stack: {
          enabled: custom.stack === 'noraml',
        },
        curve: {
          enabled: true,
          mode: custom.lineInterpolation,
        },
        tooltip: {
          ...chartRef.current.options.tooltip,
          shared: options.tooltip?.mode === 'all',
          sharedSortDirection: options.tooltip?.sort !== 'none' ? options.tooltip?.sort : undefined,
          pointValueformatter: (val) => {
            return valueFormatter(
              {
                util: options?.standardOptions?.util,
                decimals: options?.standardOptions?.decimals,
              },
              val,
            );
          },
        },
        yAxis: {
          ...chartRef.current.options.yAxis,
          min: options?.standardOptions?.min,
          max: options?.standardOptions?.max,
          plotLines: options?.thresholds?.steps,
          tickValueFormatter: (val) => {
            return valueFormatter(
              {
                util: options?.standardOptions?.util,
                decimals: options?.standardOptions?.decimals,
              },
              val,
            );
          },
        },
      });
    }
    if (hasLegend) {
      setLegendData(
        getLegendValues(
          series,
          {
            util: options?.standardOptions?.util,
            decimals: options?.standardOptions?.decimals,
          },
          hexPalette,
        ),
      );
    } else {
      setLegendData([]);
    }
  }, [JSON.stringify(series), JSON.stringify(custom), JSON.stringify(options)]);

  return (
    <div className='renderer-timeseries-container'>
      <div ref={chartEleRef} style={{ height: _chartHeight }} />
      <div className='renderer-timeseries-legend' style={{ [inDashboard ? 'height' : 'maxHeight']: _tableHeight, overflow: 'hidden' }} ref={legendEleRef}>
        <Table
          rowKey='id'
          size='small'
          scroll={{ x: 650, y: legendEleSize?.height || 100 - 46 }}
          columns={[
            {
              title: `Series (${series.length})`,
              dataIndex: 'name',
              width: 150,
              ellipsis: {
                showTitle: false,
              },
              render: (_text, record: any) => {
                return (
                  <Tooltip
                    placement='topLeft'
                    title={
                      <div>
                        <div>{_.get(record, 'metric.__name__')}</div>
                        <div>{record.offset && record.offset !== 'current' ? `offfset ${record.offset}` : ''}</div>
                        {_.map(_.omit(record.metric, '__name__'), (val, key) => {
                          return (
                            <div key={key}>
                              {key}={val}
                            </div>
                          );
                        })}
                      </div>
                    }
                    getTooltipContainer={() => document.body}
                  >
                    <span style={{ color: record.color, fontSize: 14, paddingRight: 5, position: 'relative', top: 2 }}>ꔷ</span>
                    {record.offset && record.offset !== 'current' ? <span style={{ paddingRight: 5 }}>offfset {record.offset}</span> : ''}
                    <span>{JSON.stringify(record.metric)}</span>
                  </Tooltip>
                );
              },
            },
            {
              title: 'Max',
              dataIndex: 'max',
            },
            {
              title: 'Min',
              dataIndex: 'min',
            },
            {
              title: 'Avg',
              dataIndex: 'avg',
            },
            {
              title: 'Sum',
              dataIndex: 'sum',
            },
            {
              title: 'Last',
              dataIndex: 'last',
            },
          ]}
          dataSource={legendData}
          locale={{
            emptyText: '暂无数据',
          }}
          pagination={false}
        />
      </div>
    </div>
  );
}
Example #9
Source File: index.tsx    From fe-v5 with Apache License 2.0 4 votes vote down vote up
export default function Stat(props: IProps) {
  const eleRef = useRef<HTMLDivElement>(null);
  const size = useSize(eleRef);
  const { values, series } = props;
  const { custom, options, overrides } = values;
  const { showHeader, calc, aggrDimension } = custom;
  const calculatedValues = getCalculatedValuesBySeries(
    series,
    calc,
    {
      util: options?.standardOptions?.util,
      decimals: options?.standardOptions?.decimals,
    },
    options?.valueMappings,
  );
  let tableDataSource = calculatedValues;
  let columns: any[] = [
    {
      title: 'name',
      dataIndex: 'name',
      key: 'name',
      render: (text) => <div className='renderer-table-td-content'>{text}</div>,
    },
    {
      title: 'value',
      dataIndex: 'text',
      key: 'text',
      render: (text, record) => {
        let textObj = {
          text,
          color: record.color,
        };
        const overrideProps = getOverridePropertiesByName(overrides, record.fields.refId);
        if (!_.isEmpty(overrideProps)) {
          textObj = getSerieTextObj(record?.stat, overrideProps?.standardOptions, overrideProps?.valueMappings);
        }
        return (
          <div className='renderer-table-td-content' style={{ color: textObj.color }}>
            {textObj.text}
          </div>
        );
      },
    },
  ];

  if (aggrDimension) {
    tableDataSource = formatToTable(calculatedValues, aggrDimension, 'refId');
    const groupNames = _.reduce(
      tableDataSource,
      (pre, item) => {
        return _.union(_.concat(pre, item.groupNames));
      },
      [],
    );
    columns = [
      {
        title: aggrDimension,
        dataIndex: aggrDimension,
        key: aggrDimension,
        render: (text) => <div className='renderer-table-td-content'>{text}</div>,
      },
    ];
    _.map(groupNames, (name) => {
      const result = _.find(tableDataSource, (item) => {
        return item[name];
      });
      columns.push({
        title: result[name]?.name,
        dataIndex: name,
        key: name,
        render: (text) => {
          let textObj = {
            text: text?.text,
            color: text?.color,
          };
          const overrideProps = getOverridePropertiesByName(overrides, name);
          if (!_.isEmpty(overrideProps)) {
            textObj = getSerieTextObj(text?.stat, overrideProps?.standardOptions, overrideProps?.valueMappings);
          }
          return (
            <div className='renderer-table-td-content' style={{ color: textObj?.color }}>
              {textObj?.text}
            </div>
          );
        },
      });
    });
  }

  const headerHeight = showHeader ? 40 : 0;
  const height = _.get(size, 'height') - headerHeight;
  const realHeight = isNaN(height) ? 0 : height;

  return (
    <div className='renderer-table-container' ref={eleRef}>
      <div className='renderer-table-container-box'>
        <Table rowKey='id' showHeader={showHeader} dataSource={tableDataSource} columns={columns} scroll={{ y: realHeight }} bordered={false} pagination={false} />
      </div>
    </div>
  );
}