Choosing a root element in a hierarchy without affecting the chosen style of a child

I am working on a MUI TreeView component that includes Categories as parents and Articles as children. Whenever I select a child item, it gets styled with a "selected" status. However, when I click on a parent item, the previously selected child loses its "selected" styling.

Is there a way to differentiate between a "child selected" state and a "parent clicked (selected)" state? I would like to achieve this using only CSS if possible. The project is built using Next.js.

Here is the CSS for CategoryItem:

const StyledCategoryItemRoot = styled(TreeItem)(({ theme }) => ({
  [`& .${treeItemClasses.content}`]: {
    fontWeight: theme.typography.fontWeightBold,
    marginBottom: 5,
    paddingLeft: 0,
    borderRadius: theme.shape.borderRadius,
    '&.Mui-selected.Mui-focused, &:hover, &.Mui-selected:hover': {
      backgroundColor:
        theme.palette.mode === 'light'
          ? alpha('#ff9aff', 0.16)
          : alpha('#2f506f', 0.24),
    },
    '&.Mui-selected, &.Mui-focused': {
      backgroundColor: 'transparent',
    },
  },
}));

And here is the CSS for ArticleItem:

const StyledArticleItemRoot = styled(TreeItem)(({ theme, router, post }) => ({
  color:
    theme.palette.mode === 'light'
      ? theme.palette.grey[900]
      : theme.palette.grey[500],
  [`& .${treeItemClasses.content}`]: {
    fontWeight: theme.typography.fontWeightBold,
    paddingLeft: 0,
    borderRadius: theme.shape.borderRadius,
    transition: '.2s',
    '&.Mui-selected:hover, &.Mui-selected.Mui-focused:hover, &:hover': {
      color: theme.palette.mode === 'light' ? theme.palette.grey[800] : 'white',
    },
    '&.Mui-focused, &.Mui-selected, &.Mui-selected.Mui-focused': {
      backgroundColor:
        theme.palette.mode === 'light'
          ? alpha('#ff9aff', 0.16)
          : alpha('#2f506f', 0.16),
      color:
        post.attributes.slug !== router.query.slug
          ? theme.palette.grey[500]
          : theme.palette.mode === 'light'
          ? theme.palette.primary.main
          : theme.palette.secondary.main,
    },
  },
}));

Answer №1

When using the MUI tree view component with multiselect turned off (multiSelect={false}), only one node (parent or child) can be selected at a time. It is not possible to select both parent and child nodes simultaneously.

If a child node is selected first and then the parent node is selected, the child will lose its selected style as it is no longer considered selected.

Regarding the question in the comments:

The desire is to click on the Categories dropdown without losing the "selected" styling on Article.

This can be achieved by manually handling the selection of nodes:

<TreeView
   aria-label="file system navigator"
   key="treeView"
   defaultCollapseIcon={<ExpandMoreIcon />}
   defaultExpandIcon={<ChevronRightIcon />}
   multiSelect={false}
   selected={selectedNodes}
   onNodeSelect={(e, node_ids) => {
     handleClick(e, node_ids);
   }}> //add tree nodes here 
</TreeView>

In the handleClick function, set the selected nodes:

setSelectedNodes(nodes_ids);

To ensure that only the node label is selected (and not the dropdown or collapsible icon), update the handleClick function as follows:

function handleClick(e, nodes_ids) {
  if (e.target.className == "MuiTreeItem-label") 
   setSelectedNodes(nodes_ids);
}

Note: Remember to add selectedNodes to your state:

[selectedNodes, setSelectedNodes]=useState([]);

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 configuration of the Braintree API client is incorrect: the clientApiUrl found in the clientToken is not valid

Error Found: Braintree API Client Misconfiguration - The clientApiUrl provided in the clientToken is invalid. Upon checking my browser log, I noticed this error. I am using a Node backend with an Angular front end and integrating Braintree javascript SDK ...

JavaScript - Toggling checkboxes to either be checked or unchecked with a "check all" option

To create a toggle checkboxes functionality, I am attempting the following: HTML Code: <!-- "Check all" box --> <input type="checkbox" name="check" id="cbx_00_00" onclick="selectbox( this.getAttribute( 'id' ));" /> <!-- the other ...

Is it feasible to display Material components inside a material-table?

Currently, I am in the process of developing a data display feature for my application and have been exploring various data table components that are constructed using Material UI. One question that has arisen is whether it is feasible to incorporate Mater ...

Sharing information between React components involves passing data as props. By sending data from

Brand new to React and still figuring things out. Here's the scenario: <div> <DropDown> </DropDown> <Panel> </Panel> </div> After selecting a value in the dropdown and storing it as currentL ...

Guide to redirecting data from an external POST request to a customer through a GET request

Within my Express application, I am currently dealing with both incoming POST requests containing a payload from an external source and GET requests sent by my client: router.post('/liveReleaseStore', (req, res) => { let data = req.body.m ...

Is there a way to automatically disable other options in a MUI Select once one option has been selected?

Can the options in the select menu be dynamically changed based on the value selected in another menu? For example: if option A is selected show options C and D in the other menu but if option B is selected show options E and F Here is a visual represent ...

When hovering over it, an element within an li tag appears larger than its parent element

I'm currently working on a project for my school classes and running into an issue with CSS. I'm trying to enclose everything in boxes, but it's proving to be quite challenging. The main problem I'm facing is that when I hover over the ...

Guide to integrating various HTML files into a single HTML file with the help of Vue.js

Although I am familiar with using require_once() in PHP, unfortunately, I am unable to use PHP in my current project. I attempted to use w3-include from W3Schools as an alternative, but encountered issues with loading my scripts. Even utilizing JavaScript ...

What is the best way to verify the input of a TextField element?

When I visited the Material UI Components documentation for TextField, I was hoping to find an example of validation in action. Unfortunately, all they showed was the appearance of the invalid TextField without any insight into the actual validation code i ...

Choosing an element with JavaScript

var displayedImage = document.querySelector('.displayed-img'); var thumbBar = document.querySelector('.thumb-bar'); btn = document.querySelector('button'); var overlay = document.querySelector('.overlay'); /* Itera ...

What is the best way to utilize *ngFor for looping in Angular 6 in order to display three images simultaneously?

I have successfully added 3 images on a single slide. How can I implement *ngFor to dynamically load data? <carousel> <slide> <img src="../../assets/wts1.png" alt="first slide" style="display: inline-blo ...

Is there a way to confirm whether the current date and time, based on a specific timezone and hour, is before or equal to a particular date?

I am working on a project that involves a timezone map with publishing hour in the local zone and news articles that need to be scheduled using a date picker. This particular article is set up as follows: { timeZoneId: 'Europe/Paris, releaseHour: 9 ...

Vercel's nodemailer failing to send emails in production environment

Recently, I encountered an issue with sending emails using Nodemailer in my serverless Next.js project deployed on Vercel. Surprisingly, it works flawlessly in development mode, but fails to send any emails in production mode without giving any error feedb ...

I am looking to utilize next/image to occupy half of the width within a div container

Currently, I am delving into the world of Next.js and Tailwind CSS. I have a challenge where I want to fill half width using the next/image component. However, it seems to be occupying the full width instead. function Slider() { return ( <div cl ...

Unable to trigger jQuery onclick event on nested div elements

I'm experiencing an issue with my web-page where two buttons at the top are not responding to a sorting function on the nested #byFilter. Despite trying to apply the onclick(function()) method, it doesn't seem to work. Javascript $(document).re ...

Sending information from a rails controller to a react component

Wondering how to pass the example @post = Post.all from the controller to React component props while integrating Rails with React via Webpacker. Is it necessary to do this through an API or is there another way? ...

Issue with displaying nested React Elements from Component

I am currently facing an issue with my Collection component, which is utilizing a sub-component called RenderCollectionPieces to display UI elements. Strangely, I am able to see the data for image.name in the console but for some reason, the UI elements ar ...

Generate an array of objects by combining three separate arrays of objects

There are 3 private methods in my Angular component that return arrays of objects. I want to combine these arrays into one array containing all the objects, as they all have the same class. Here is the object structure: export class TimelineItemDto { ...

What steps should I take to insert a divider in a dropdown menu?

I am attempting to enhance my dropdown menu by incorporating a separator using the following code: <li class='divider'></li> Below is my HTML code with the separator included: <ul class="dropdown-menu dropdown-menu-right" id="ul ...

Customize the CSS styling of third-party components in different pages using NextJS

When working with third-party components, you can include their styles by importing their stylesheet into your component or _app.tsx file. For detailed instructions on how to do this, you can refer to Next.js documentation. Another option is to add the sty ...