TestUser
TestUser

Reputation: 213

React: how to align icons with text?

I am displaying treeview. tree nodes are showing with icons plus and minus. These icons are showing above the text? how to align node icon and node text in the same line? please find my sandbox: https://codesandbox.io/s/shy-snow-nfce4i

thanks

Upvotes: 4

Views: 321

Answers (3)

George Chond
George Chond

Reputation: 997

Replace ::marker with ::before, remove list-style-type and adjust padding from ul. ::marker can not be modified with as many properties as pseudo-elements, therefore in order to style it you need to switch to a pseudo-element.

//ProductsTreeView.js  - line 177
const StyledLI = styled.li`
  list-style-type: none;
  ::before {
    content: "";
    display: inline-flex;
    width: 16px;
    height: 16px;
    ${({ expanded }) =>
      `background: url(${expanded ? minus : plus})};`};
  }
`;
//ProductsTreeView.js  - line 294
<ul style={{paddingLeft: '1.8rem'}}>

Update for Paper Icons

First initialize an Icon property on Node class:

//ProductsTreeView.js - line 209
class Node {
  description = "n/a";
  id = -1;
  key_id = -1;
  linkpagename = "";
  icon = "";
  isActive = false;
  nodes = [];

  constructor(description, id, key_id, icon, linkpagename) {
    this.description = description;
    this.id = id;
    this.key_id = key_id;
    this.icon = icon;
    this.linkpagename = linkpagename;
  }

// the rest of the code...

Then assign a value to Icon property from your XML's "imageOpen" field:

//ProductsTreeView.js - line 236
const icon =
  entity.children[
    entity.children.findIndex((child) => child.name === "imageOpen")
  ].value;

//ProductsTreeView.js - line 250
const node = new Node(descriptionText, id, key_id, icon, linkPageName);

Then on your StyledLI assign this Icon prop as "isPaper":

//ProductsTreeView.js - line 387
<StyledLI
  id={node.id}
  expanded={node.isActive}
  isPaper={node.icon}
  isLeaf={!node.nodes.length}
  to={node.linkpagename}
  key={node.key_id}
  onClick={(event) => {
    event.stopPropagation();
    onToggle(node);
  }}
>

Then readjust your CSS-in-JS:

//ProductTreeView.js - line 177
const StyledLI = styled.li`
  list-style-type: none;
  ::before {
    content: "";
    display: inline-flex;
    width: 16px;
    height: 16px;
    ${({ expanded, isPaper }) => `background: url(${isPaper === "paper.gif" ? paper : (expanded ? minus : plus)})};`};
  }
`;

enter image description here

Upvotes: 3

Moldovan Andrei
Moldovan Andrei

Reputation: 315

I tried modifying your StyledLi component and working with ::marker exclusively, to no avail. However, I managed to align them as such:

   const StyledLI = styled.li`
      list-style-type: none;
    `;

And in the TreeNode:

class TreeNode extends React.Component {
  render() {
    const { node, onToggle } = this.props;

    const activeChildren =
      node.isActive && node.nodes.length ? (
        <ul>
          {node.nodes.map((node) => (
            <TreeNode
              id={node.id}
              key={node.key_id}
              node={node}
              onToggle={onToggle}
            />
          ))}
        </ul>
      ) : null;

    return (
      <StyledLI
        id={node.id}
        expanded={node.isActive}
        isLeaf={!node.nodes.length}
        to={node.linkpagename}
        key={node.key_id}
        onClick={(event) => {
          event.stopPropagation();
          onToggle(node);
        }}
      >
        <div style={{
          display: 'flex',
          alignItems: 'center'
        }}>
          <img src={node.isActive ? minus : plus} />

          <Link
            to={node.linkpagename}
            style={{ textDecoration: "none", color: "#000000" }}
          >
            {node.description}
          </Link>{" "}
          - {node.key_id} - {node.linkpagename}
        </div>

        {activeChildren}
      </StyledLI>
    );
  }
}

You can copy-paste this into your code.

Upvotes: 1

Dmitriy Zhiganov
Dmitriy Zhiganov

Reputation: 1128

You can use before pseudo-element instead of markers. This is more flexible way.

// css
.list {
  list-style: none;
}

.item {
   position: relative;
   padding-left: 20px;
}

.item::before {
  top: 0;
  left: 0;
  position: absolute;
  content: url(https://uploads.codesandbox.io/uploads/user/25a43e4c-a00e-4028-8cde-b4bc9a9987f9/pkCB-plus.gif);
}

// render
<ul className="list">
  <li className="item">Some text 1</li>
  <li className="item">Some text 2</li>
  <li className="item">Some text 3</li>
</ul>

Upvotes: 0

Related Questions