What is the most effective method for incorporating multi-line breadcrumb links in a React application?

I am currently working on implementing a multiline breadcrumb link feature for mobile and tablet devices. As users navigate through multiple folders, I need to handle scenarios where the number of links exceeds the maximum allowed in the breadcrumb container. In such cases, I want to prioritize displaying the path from the current location onward. Despite my efforts, I have not been able to find a CSS solution that fits this requirement. Below is an example with max lines = 2:

current path = 
path1 / path2 
/ path3 / path4
/path5

In the above scenario, the path exceeds max lines at 'path5' and requires modification as follows:

updated path = 
.../ path2 
/ path3 / path4

If the user navigates back, the displayed path should update accordingly without ellipses. I've attempted various methods but none have met my expectations:

  1. An attempt at clamping to max lines using CSS - unsuccessful due to difficulties in determining which links to trim.
  2. The use of white-space: no wrap and text-overflow: ellipse was considered, but multiline support remains a challenge.
  3. An exploration into calculating maximum characters per line based on width and font size yielded some results, yet determining the font constant has proven elusive.

I have managed to dynamically adjust width and font size, but the elusive font constant continues to pose a challenge. Any assistance in resolving these issues would be greatly appreciated.

Answer №1

I have implemented a demo component showcasing a unique strategy that I believe will be beneficial.
The approach taken includes:

  1. Calculating the number of lines by dividing the wrapper's height by the line height
  2. Removing items from the beginning until the total number of lines meets the maximum allowed limit

Breadcrumbs.js

import { createRef, useEffect, useState } from "react";
import "./Breadcrumbs.css";

function Breadcrumbs() {

    const wrapper = createRef();
    const ellipsis = createRef();
    const [items, setItems] = useState([]);
    const [dropped, setDropped] = useState(false);

    const countLines = (element, lineHeight) => {
        let height = element.offsetHeight;
        let lines = height / lineHeight;
        return Math.round(lines);
    }

    useEffect(() => {
        setItems(window.location.pathname.split("/").filter((e) => e.length > 0))
    }, [window.location.pathname])

    useEffect(() => {
        const lines = countLines(wrapper.current, ellipsis.current.clientHeight);
        const maxLines = 2;

        if (lines > maxLines) {
            setItems(items.slice(1));
            setDropped(true);
        }
    }, [items])

    return <nav className="breadcrumbs-wrapper" ref={wrapper}>
        <span ref={ellipsis}>
            {dropped ? "..." : ""}
        </span>
        {items.map((item, index) => {
            return <span key={index.toString()}>
                <span>&nbsp;/&nbsp;</span>
                <a href="#">{item}</a>
            </span>
        })}
    </nav>
}

export default Breadcrumbs;

Breadcrumbs.css

.breadcrumbs-wrapper {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
}

View screenshots of the live example below

https://i.sstatic.net/oa5wf.png

https://i.sstatic.net/mfzNg.png

https://i.sstatic.net/splfX.png

Answer №2

import React from 'react'; import { Link, useLocation } from 'react-router-dom';

const Breadcrumb = ({ handleDrawerOpen, open }) => {
   const { pathname } = useLocation();

   const pathString = (paths, index) => {
      return paths.filter((pathItem, pathIndex) => pathIndex !== 0 && pathIndex <= index).join('/');
   };
   
   const generateBreadcrumbs = () => {
      const pathsArray = pathname.split('/');
      return pathsArray.map(
         (pathItem, index) =>
            index !== 0 && (
               <Link
                  style={{
                     textDecoration: 'none',
                     color: index === pathsArray.length - 1 ? '#49C5B6' : 'white',
                  }}
                  to={`/${pathString(pathsArray, index)}`}>{`${
                  pathItem?.charAt(0)?.toUpperCase() + pathItem.slice(1).toLowerCase()
               } ${index !== pathsArray.length - 1 ? '>' : ''} `}</Link>
            )
      );
   };
   return (
      <Box>
         {!open && (
            <IconButton onClick={handleDrawerOpen}>
               <MenuIcon />
            </IconButton>
         )}

         <Profile />
      </Box>
   );
};

export default Breadcrumb;

Answer №3

To display the last 5 items as links, you can slice the breadcrumbs array and then map through them:

breadcrumbs.slice(-5).map((breadcrumb, index) => (
<React.Fragment key={index}>
  {index !== 0 && breadcrumbs.length > 1 ? ' / ' : ''}
  {index === 0 && breadcrumb.path !== breadcrumbs[0].path ? (
    '...'
  ) : (
    <a href={breadcrumb.link}>{breadcrumb.path}</a>
  )}
  {index % 2 ? <br /> : ''}
</React.Fragment>

For a visual representation of this solution, check out this demo.

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

Transmit information to a specific route through Express JS while simultaneously serving a static file for React-Router

My Objective: I want to create Express JS routes that can fetch data (for example, from: ), send it via React Router to the correct route, and make React wait until the data is fetched so I can use it on the client-side. Attempts Made: server.js ' ...

What is the significance of h being undefined?

I have successfully set up a new Vue project using vue create and added Storybook with no issues. However, after installing storybook-addon-designs and following the instructions in the readme to add it to my story, I encountered an error in my console sa ...

Background of jQuery-UI Slider

Can the background color of a jQuery-UI Slider widget be set using JavaScript? This is the default setting: What I am trying to accomplish is the following: The green range should be determined based on historical data. I want to visually show the user ...

callback triggering state change

This particular member function is responsible for populating a folder_structure object with fabricated data asynchronously: fake(folders_: number, progress_callback_: (progress_: number) => void = (progress_: number) => null): Promise<boolean ...

Having trouble getting $.ajax to function properly in conjunction with fullcalendar js?

Currently in the process of utilizing the Smart Admin Theme, specifically focusing on the functionality within the calendar page. The calendar's core features are operational, allowing for the creation and placement of new events on the map. My curr ...

Replicating a row in a table without disrupting a button within the row

As a novice in the world of coding, I am currently embarking on a project to revamp an existing website. The task at hand involves creating a table with a built-in save/edit feature, which I have successfully implemented. However, I am facing a roadblock w ...

Issues with IE9's CSS hover functionality are causing problems

This particular css style functions well on most browsers, but seems to have compatibility issues with Explorer 9 specifically when it comes to the :hover effect. There are instances where it works perfectly fine and other times when it doesn't work a ...

Is there a way to reach the redux store from an action creator?

I am currently exploring the concept of chaining actions together within my application. When the SET_CURRENT_USER action is triggered, I want it to not only modify the state by setting the current user, but also initiate a series of other side-effect task ...

Is JavaScript responsible for creating threads for non-blocking AJAX requests?

It is widely believed that JavaScript operates on a single-threaded model, but it has the ability to run asynchronously. One intriguing aspect is how this single-threaded model manages non-blocking AJAX requests. Consider a scenario where a non-blocking A ...

The code for the bouncing image isn't functioning properly outside of the JSFiddle environment

I'm having issues with this jQuery snippet in my web application. It works fine on jsfiddle, but not when I add it to my project. Here's the code: $('.myimage').mouseenter(function() { $(this).effect('bounce',500); }); Her ...

Persist in the face of a mishap in javascript

Two scripts are present on the page. If the first script encounters an error, the second script will not function properly as a result. Is there a way to make the second script ignore any errors from the first one and still work? Please note that I am str ...

Encountering the issue of "Unknown provider" while injecting Angular modules

After following a tutorial on organizing an Angular project, I came up with a structure where I have a ng directory containing all my controllers, services, and the routes.js file. These are then bundled together into an app.js through my configuration in ...

Show divs in identical position when clicking

There are 4 section divs that need to be displayed in the center of the page when clicked, but the last one appears further down. This is likely due to the flex box nature. What is the best way to ensure all sections appear at the exact same location? Ano ...

Check for my variable in the redux state before proceeding

Currently, I am creating connection and registration screens, with a profile button on the bottom tab bar. The objective is for the user to be directed to their profile page if they are logged in (user data stored in Redux), or to a landing screen with log ...

What is the best way to test a route using nock and request-promise when the URL includes single quotes?

Trying to test an API call using nock + request-promise is resulting in an error due to mismatched routes caused by single quotes in the API's url. The problem arises from request-promise url encoding the quotes while Nock does not. You can view the ...

The React MUI Tree only shows updates when the user clicks on a child item

I have encountered an issue with my React MUI tree implementation. When I click on the "add" buttons to add a tree item, it gets added successfully to the ROMItems variable, but doesn't display immediately in the tree structure. The newly added item o ...

What might be the reason for jQuery not functioning in Internet Explorer 11?

Working on developing a slideout menu for my website using jQuery. It functions perfectly in Chrome, but encountering issues in Internet Explorer (IE11). Extensive search hasn't provided a solution yet. Seeking assistance and any help would be highly ...

Generating a highchart by retrieving JSON data using AJAX

I'm currently working on generating a basic chart on a webpage using data from a MySQL database that is fetched via a MySQL script. My main challenge lies in understanding how to combine the ajax call with the necessary data for the chart. I'm n ...

What are some techniques for transforming text into JSON format?

Beginner inquiry: I'm struggling with manipulating text using JavaScript. Here is the text I want to transform: "5555 55:55: John: New York 6666 66:66: Jack: Los Angeles" My desired output after manipulation: [{ name:"John", address:"New York", n ...

When attempting to push `content[i]` into an array in AngularJS, it is flagged

In my JSON data, I have the following structure: var data = [{ id: 1, name: 'mobile', parentid: 0, limit:3 }, { id: 2, name: 'samsung', parentid: 1 }, { id: 3, name: 'moto', parenti ...