What is the trick to displaying the horizontal scrollbar without having to scroll downwards?

Currently, I am utilizing react-split, but I am encountering an issue where the first pane requires scrolling down to display the horizontal scrollbar.

I would like both the vertical and horizontal scrollbars to be visible simultaneously.

Below is the code snippet:

https://codesandbox.io/s/vibrant-flower-ueywiu

App

function App() {
  return (
    <Split
      className="split"
      direction="vertical"
      minSize={0}
      snapOffset={10}
      dragInterval={5}
      sizes={[30, 70]}
    >
      <Market />

      <chakra.div bg="blue">
        <Center h="100%" p="16" textAlign="center">
          <Heading color="white">
            How to show the horizontal scrollbar without needing to scroll down?
          </Heading>
        </Center>
      </chakra.div>
    </Split>
  );
}

Market

const Market = (props) => {
  return (
    <chakra.div {...props} overflow="auto">
      <Tabs isLazy>
        <TabList>
          <Tab>Stocks</Tab>
          <Tab>FTSE 100</Tab>
        </TabList>

        <TabPanels>
          <TabPanel padding={0}>
            <MarketTable />
          </TabPanel>

          <TabPanel padding={0}>
            <p>Empty</p>
          </TabPanel>
        </TabPanels>
      </Tabs>
    </chakra.div>
  );
};

MarketTable

const MarketTable = () => {
  return (
    <TableContainer>
      <Table size="sm">
        <Thead>
          <Tr>
            <Th>Title</Th>
            <Th>Quote</Th>
            <Th>Date/Time</Th>
            <Th>Place</Th>
            <Th>Variation</Th>
            <Th>CMP</Th>
            <Th>VND</Th>
            <Th>Min</Th>
            <Th>Max</Th>
            <Th>Volume</Th>
          </Tr>
        </Thead>

        <Tbody>
          {data.map((each) => (
            <Tr key={each.name}>
              <Td title={String(each.name ?? EMPTY_CHAR)}>
                {each.name ?? EMPTY_CHAR}
              </Td>
              <Td title={String(each.quote ?? EMPTY_CHAR)}>
                {each.quote ?? EMPTY_CHAR}
              </Td>
              <Td title={String(each.dateTime ?? EMPTY_CHAR)}>
                {each.dateTime ?? EMPTY_CHAR}
              </Td>
              <Td title={String(each.place.name ?? EMPTY_CHAR)}>
                {each.place.name ?? EMPTY_CHAR}
              </Td>
              <Td title={String(each.variationPercent ?? EMPTY_CHAR)}>
                {each.variationPercent ?? EMPTY_CHAR}
              </Td>
              <Td title={String(each.cmp ?? EMPTY_CHAR)}>
                {each.cmp ?? EMPTY_CHAR}
              </Td>
              <Td title={String(each.vnd ?? EMPTY_CHAR)}>
                {each.vnd ?? EMPTY_CHAR}
              </Td>
              <Td title={String(each.min ?? EMPTY_CHAR)}>
                {each.min ?? EMPTY_CHAR}
              </Td>
              <Td title={String(each.max ?? EMPTY_CHAR)}>
                {each.max ?? EMPTY_CHAR}
              </Td>
              <Td title={String(each.volume ?? EMPTY_CHAR)}>
                {each.volume ?? EMPTY_CHAR}
              </Td>
            </Tr>
          ))}
        </Tbody>
      </Table>
    </TableContainer>
  );
};

Answer №1

Although I have not had any experience working with these libraries or using Typescript, my solution remains effective and easy to understand. The key approach involves tracking the largest container size and table size, calculating their respective percentages in relation to each other, and passing them to <Split />.

In order to properly set the sizes prop on <Split />, we need to include two refs. One is obtained from the <TableContainer /> within MarketTable.tsx, while the other is placed on a <div> wrapper added in the index file. The wrapper serves as the top-level container, ensuring access to the current screen size.

If you are unfamiliar with refs, they provide a quick way to interact with specific DOM elements and manipulate their properties. In this case, we aim to retrieve the current heights of the <TableContainer /> (the table) and the div wrapper.

The <TableContainer /> section looks like this:

<TableContainer ref={tableHeight}>

While the structure in index.tsx appears as follows:

<div ref={containerHeightRef}>

Both <MarketTable /> and index utilize useEffect() to dynamically adjust the table height as data changes. Within useEffect() in index.tsx, we continually monitor the two refs to adapt to their heights and trigger re-renders for the involved components. Here is an example:

  useEffect(() => {
    if (containerHeightRef && tableHeight) {
      let containerHeight = containerHeightRef.current.clientHeight;
      setSizePercents([
        (tableHeight / containerHeight) * 100,
        ((containerHeight - tableHeight) / containerHeight) * 100
      ]);
    }
  }, [containerHeightRef, tableHeight]);

Whenever data is added or removed from data.tsx, the <Split /> automatically adjusts to fit the table size accordingly.

Having acquired both the table height and wrapper height values in index.tsx, we convert these pixels into percentages for the sizes prop in <Split />. The first value represents the final table height percent, calculated by dividing tableHeight by containerHeight (wrapper height in

index.tsx</code) and then multiplying by 100. Subsequently, the split height, constituting the second percent value for the <code>sizes
prop, is determined by
((containerHeight - tableHeight) / containerHeight) * 100
.

Eventually, the completed sizes prop takes the following form:

      <Split
        className="split"
        direction="vertical"
        minSize={0}
        snapOffset={10}
        dragInterval={5}
        sizes={sizePercents ? [sizePercents[0] + 8.5, sizePercents[1]] : ""}
      >

The additional 8.5 offset accounts for the scrollbar height, ensuring the accurate sizing of the table. Without it, the table height may slightly deviate from the intended measurement.

To transfer the tableHeight value to index.tsx, we must relay it from <MarketTable /> up the component hierarchy to its grandparent (index.tsx). This is achieved by passing settableheight through the chain:

index.tsx --> <Market /> --> <MarketTable />
. Subsequently, setting the tableHeight allows us to access it in index.tsx. Although there is an error concerning the transmission of settableheight, it does not impact functionality and can be resolved separately.

While there may exist more streamlined approaches in Typescript, this solution establishes a solid foundation for refactoring and creating a more permanent resolution.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The page remains static even after selecting a child route using routerLink in Angular 2

Hello, I am facing an issue that I need help with. I am using a routerLink to navigate to a child route in my Angular application. Although the URL changes as expected, the view does not update to display the component associated with the active child rout ...

CSS layout: The full-width header should align its left margin with the centered content-div

Can someone help me out with a solution to my problem? My page has a 1040px centered div for content, menu, and footer. I want the header image to align with the left margin of the content div and expand towards the right side for higher screen resolutio ...

Error: Attempting to access the 'name' property of a null object

Having an issue with my Node.js server connected to MongoDB. This is the primary code for app.js: var express = require("express") var app = express(); var bodyParser = require("body-parser"); var mongoose = require("mongoose") mongoose.connect("mongodb: ...

What could be the reason for the ineffective functioning of Jquery's remove and fadeout?

Here are the links to index.html and main.css files: index.html, main.css Unfortunately, there seems to be an issue with the code in line 28-30 of index.html: $(".todo-liste").click(function(){ $(this).parent(".todo-listeEleman" ...

CSS sliding element moving horizontally

This code is currently set up to slide from right to left. #panel { position: absolute; right: 0; width: 180px; top: 0; bottom: 0; box-shadow: 0px 0px 15px black; background: white; padding: 10px; -webkit-transform-origin: 100% 50%; ...

Maximizing the power of Webpack alongside Google Maps API

I have been using Webpack along with the html-webpack-plugin to compile all my static files. However, I am facing an issue when integrating it with the Google Maps API. Here is the code snippet: var map; function initMap() { map = new google.maps.Map(d ...

Adjust the vertical positioning according to the percentage of the width

Currently, I am attempting to modify the position of my navigation bar on the screen in relation to the screen width rather than the height. I previously attempted using top: 10% in CSS, but realized this is based on the screen's height instead of its ...

What sets SVG and CSS3 animations apart and where do they overlap?

Sencha Animator relies on CSS3 animations as its primary animation tool. RaphaelJS, on the other hand, favors SVG animations for its visual effects. I'm curious about the parallels and distinctions between SVG and CSS3 animations. Is either one a s ...

Encountering an ENOTEMPTY error with babel-loader during npm installation process

I am encountering an error while attempting to install a new dependency. Any suggestions on how to resolve this issue? Thank you! https://i.sstatic.net/1hasv.png ==> EDIT : After deleting the folder and running npm install emailjs again, I continued t ...

Having difficulty extracting information from an HTML page using Swift

I'm attempting to convert data retrieved from an HTML page into a readable format, but the string urlContent is showing as nil even though the data received from the NSURLSession is not null. This is my approach: var city = "London" var url = NSURL ...

How to temporarily disable CSS hover effects

I have a menu with some links <ul id="nav"> <li> <a href="#">Project</a> <div class="subs"> <div> <ul> <li> <h3>Save</h3> <ul> <li> <a i ...

Reduce the size of a webpage by 10%

Have you ever noticed that when you press Ctrl+- on any browser, the page scales down to 90% of its original size? It actually looks nicer at 90%, so I want my webpage to default to opening at 90% instead of 100%. I've tried following common approach ...

Struggling with updating an object in Express and Mongoose

Is there a way to update an object by adding a new field defined in the schema? Here's what I have: const updatePlotObject = async (request, response) => { let modifications = {}; modifications = Object.assign(modifications, request.body.p ...

"Experiencing Issues with jQuery as Thumbnails Caption is Not Functioning Proper

I am currently working on creating interactive thumbnails using jQuery. However, I have encountered an issue where the caption only displays on the last thumbnail. It doesn't show up individually for each one as intended. How can I modify my code to ...

(no longer supported) We are unsure about the usage of /deep/, >>>, and ::ng-deep, ::v-deep

Since /deep/ has been deprecated, I have found that using global styles instead is the only viable solution. Does anyone know of an alternative solution where we can still maintain encapsulation or scoped styling? ...

How to modify a nested object in MongoDB based on the JSON data provided

In my possession, there exists a structured form of JSON data as displayed below: [ {"size":100,"year":2015,"geography":"London","age":"21","gender":"Female"}, {"size":80,"year":2015,"geography":"Cardiff","age":"38","gender":"Male"}, {"size":80,"year":201 ...

Sending a form from an iPhone device to a PHP backend server

It seems like I'm overlooking a simple aspect... Here is a basic form that I want to submit to a PHP script. It works perfectly on PC and Mac, but it doesn't function properly in Safari on iPad, iPhone, etc. Do you think there's some mobile ...

Troubleshooting: Next.js Axios Get Request Fails to Execute on Host

One of the challenges I'm facing is with an API that retrieves records from Mongodb. While retrieving records directly from the database works fine, it encounters issues when attempting to do so from the hosting platform. An error message is displayed ...

Examining the potential of a promise within a dynamic import feature in Angular

Here's a code snippet that I'm working with: The component file (component.ts) looks like this: async ngOnInit() { import('dom-to-image').then(module => { const domToImage = module.default; const node = document.getEl ...

What is the most effective method for live-updating a field every 5 seconds in Laravel?

I want to monitor the database to see if a new row is created for each user and display a popup message to notify them. I'm debating between using pusher/socket or making an Ajax call every 5 seconds to achieve this live update without page refresh. I ...