0

I have a Menu/Tabs React component I'm building that I've set up to receive a combination of both an SVG and a string of text as the title prop in order to display as the tab name.

The issue I'm having is that I have an active class that colors the active tab text blue, but not the SVG which remains black.

Desired Behavior: Have active class CSS stylings applied to both text and SVG elements so that they are both blue when active and both black when they are inactive

Current Behavior: Active class stylings are applied to the text but not the SVG. When tab is active text turns blue, while the SVG remains black

Here's a CodeSandbox demonstrating the problem:

Edit fervent-swanson-7sykc

My Current Tabs Component:

// @ts-nocheck
import React, { useState } from 'react';
import styled from '../../styles/styled';

type Props = {
  children: React.ReactNode;
};

export const Tabs = (props: Props) => {
  const { children } = props;
  const [tab, setTab] = useState(0);
  const childrenList = React.Children.toArray(children);

  const tabs = childrenList.map((child, idx) => {
    const title = (child as any).props.title ?? idx;
    return (
      <StyledTabs key={title} className={tab === idx ? 'activeTab' : ''} onClick={() => setTab(idx)}>
        {title}
      </StyledTabs>
    );
  });

  const current = childrenList[tab];

  return (
    <div>
      <div>{tabs}</div>
      <div>{current}</div>
    </div>
  );
};

const StyledTabs = styled.button`
  margin: 0 10px;
  padding: 0 10px;
  padding-bottom: 5px;
  border: none;
  background: transparent;
  display: inline-block;
  font-weight: 700;
  text-transform: uppercase;

  &.activeTab {
    color: #1471da;
    border-bottom: 1px solid #1471da;
    outline: none;
    padding-bottom: 5px;
  }
`;

Page where Tabs Component is used :

  const OverviewIcon = () => (
    <svg xmlns="http://www.w3.org/2000/svg" width="35" height="35">
      <path d="M0 0h16v16H0zM19 0h16v16H19zM0 19h16v16H0zM19 19h16v16H19z" />
    </svg>
  );

  const OverviewTab = () => (
    <>
      <OverviewIcon />
      <span>OVERVIEW</span>
    </>
  );

...

<Tabs>
 <div title={<OverviewTab />}>
  <ContentSection></ContentSection>    
 </div>
 <div title={'ADDITIONAL CONTACTS'}>
   <h1>CONTACTS</h1>
 </div>
</Tabs>
Josh
  • 1,165
  • 3
  • 24
  • 44
  • Changing color of a text inside of a button vs. changing color of an `SVG` element is different. Personally, I'd probably rewrite this differently so that you can pass some sort of `Boolean` that states whether something is `active` or not. Right now, a fix would be to add `fill: #1471da;` to your `&.activeTab` selector. `fill` will target the `SVG` and `color` will target text inside of the button. – goto May 09 '20 at 22:03
  • 1
    Does this answer your question? [How to change the color of an svg element?](https://stackoverflow.com/questions/22252472/how-to-change-the-color-of-an-svg-element) – goto May 09 '20 at 22:11
  • Yeup! Thank you! – Josh May 11 '20 at 17:32

1 Answers1

2

To change an svg color, use fill instead within your scss :

  &.activeTab {
    color: #1471da;
    fill: #1471da;
    border-bottom: 1px solid #1471da;
    outline: none;
    padding-bottom: 5px;
  }
Treycos
  • 7,373
  • 3
  • 24
  • 47
  • That's `styled-components`, not `scss`. – goto May 09 '20 at 22:05
  • Styled-components are internally using SCSS syntax: https://styled-components.com/docs/basics#pseudoelements-pseudoselectors-and-nesting – Treycos May 09 '20 at 22:19
  • There are some features of `scss` that have been ported to `styled-components`, but I can't find anywhere where it says that `styled-components` are internally using `scss` in their documentation or the blog post that you shared. – goto May 09 '20 at 22:24
  • "The preprocessor we use, stylis, supports scss-like syntax for automatically nesting styles.". Well, in the context of this answer I don't think it really matters anyway. It's not pure SCSS, but the basics are there – Treycos May 09 '20 at 22:26