the problem I have is simply explained. I work on a project as a front-end developer and use react with styled-components to do so. My colleague uses TailwindCSS. Now I tried to merge things together but it seems like whenever I activate Tailwind and the components of my collage it messes up my styled-components just a slight bit so they look off, even though he did not work on these files and has never done anything Tailwindy inside of them. Is there something I'm missing out on or should look for?
Thank you in advance.
I don't know how you're working together but the right way to integrate styled components with tailwind is with the attr function to add the styles
const Card = styled.div.attrs({ className: "bg-white mx-auto max-w-sm shadow-lg rounded-lg" })` ["Your styles and props"]`;
//and even extend later
<Card className="overflow-hidden">Content</Card>
Otherwise, some tailwind global styles can affect your components where you don't want it to happen (this is probably what happened to you).
Related
For example, I have component like this:
const Button = ({borderColor, children}) => {
return (
<button style={{borderColor: borderColor ? `border: 1px solid ${borderColor}` : null}}>
{children}
</button>
)
}
Main goals of this component are:
pass children prop further
handle custom border color
With children - it's usual situation. But with css I don't know, should I test it, or not.
Some articles about RTL tell that we don't have to test css. But
in my opinion, in this case, our css prop is important for end user
(e.g. some other developer who will use this component) and this css
should be tested. What's the right way?
Testing a React Application should be about behaviors. That is, how the application behaves when controlled by an end user. That's one of the guiding principles of react-testing-library, and one I agree with.
Therefore, going by this statement you can do two different things:
Test the complete behavior that causes the border color to change. That is Integration Testing
Type check the component to guarantee that you cannot pass an incorrect value for borderColor. That is Unit Testing
In my opinion with this use case, testing anything else would be testing React itself or, as the other answer noted, you ability to write a correct css string. The later can be tested with your own eyes anyway and isn't likely to change
Type checking example
Giving you an example for integration testing is hard to do without knowing your complete use case. As for type checking you have two options:
Using PropTypes
Switching to Typescript
Note: These options aren't equivalent. Proptypes is a library that checks the props at runtime with a developement build. They are ignored with a production build. Typescript on the other hand is a complete compiler, that runs during the build. The correct solution depends on your setup
With PropTypes
You can use PropTypes.oneOf :
Button.propTypes = {
// Edit as needed
borderColor: PropTypes.oneOf(["red", ,blue"])
}
Typescript
interface ButtonProps {
borderColor: "blue" | "red";
}
const Button: React.FunctionComponent<ButtonProps> = ({borderColor, children}) => {...}
Potentially misreading your question, but maybe you're only asking because "is this string a valid CSS color" feels like a silly or annoying detail to test, even though you're aware of the problems that not writing tests will have on other developers who will use this component.
Is this a silly thing to test? I agree conditionally.
IMO this is far better solved using Typescript to enforce constraints on what form the string can take. Some ideas here: TypeScript - is it possible validate string types based on pattern matching or even length?
A better thing to test is probably a functionality question like "does this component genuinely create a button wrapping the children with the 1px solid borderColor that we asked for?
In that case, yes I'd write a test for that functionality.
I have a react component library implemented with styled components. Long story short, the company changed it's design system and they decided they need both styling, old and new, to be available for different projects(no runtime switching). So for now, we have two versions of the library, on two main branches of the same project, the difference being in the styled components files.
The problem is that new components or fixes need to be implemented in both versions, and what we are doing now is manually syncing the branches for the behavioral part of the components, but this task is becoming harder and harder to handle.
Some of the ideas were splitting the library in two, old and new, but doesn't solve the syncing problem; or splitting into three, behavioral, old style, and new style, and the behavioral library should somehow (don' know how) use one or the other; or let the app switch between the styled components at runtime, but that seems to add unnecessary complexity; or switching back to sass instead of styled components and let the user app choose which sass file will load (but I would be really sad to give up on the styled components).
Any ideas, advice, warnings, been-there-done-that-ers? :)
Perhaps you can try something like this: React Theme Management in Less with Javascript? Or perhaps even: Theming in React with Styled Components.
To me it seems like it isn't so much about splitting up the library into different components (which can get super messy over time). Rather it would be more about finding a way to make the styling abstract in such a way that you have different themes (Old Theme vs New Theme) and can choose either one as you use the library for other projects.
I really love theme management in styled-components. I believe this approach would make switching themes a breeze. Let me try to explain with a simple example.
Step 1 - Use a theme-file with e.g. theme_one.js and theme_two.js.
const theme_one = {
primary: "hsl(233, 26%, 24%)",
secondary: "hsl(136, 65%, 51%)",
};
const theme_two = {
primary: "hsl(024, 16%, 4%)",
secondary: "hsl(112, 25%, 81%)",
};
Step 2 - Import the relevant theme into your root App Component and then use the ThemeProvider
import { ThemeProvider } from "styled-components"
as a context provider in your App.js. The following code will make that theme available in every child-component.
<ThemeProvider theme={theme_one}>
<App />
</ThemeProvider>
Step 3 - Access the theme in any downstream component:
const StyledComponent = styled.div`
background-color: ${props => props.theme.primary}`
With this method, you would need to plug in either theme_one or theme_two in your context provider and watch the beauty unfold.
I am currently creating a React component library. This component needed a lightweight tooltip, and as I could not find anything as light as I wanted, I made another component library that I can use for the main or any other projects I want. This works very well.
However, what I'd like to do is offer users of my library a way to disable tooltips and not be penalized for doing so. From my tests it seem that, even if the tooltip is not used, it is still added to the bundle. Webpack apparently can't shake it out. It will also need to be installed as a dependency.
To give an idea of how it's used:
return (
<div>
{showTooltip ? (
<Tooltip>
//...children
</Tooltip>
) : (
//children
)}
</div>
);
showTooltip is just a destructured prop. I get why this doesn't work, as it's impossible for the bundler to know that showTooltip is never going to change value, but how do I do what I want here? How do I allow users to not install the tooltip lib and not be weighed down by a feature they've disabled?
I'm currently working on a project which has all of its styles declared in JSS. One of the "benefits" highlighted on many articles and the library docs is that it encapsulates styles. However I really am having a hard time customizing them, specially when it comes to styling that depends on the component's surrounding context (by context I mean parent elements, siblings, etc.).
Consider the following styles exported along a component called FieldDescriptor via the withStyles HOC:
info: {
fontFamily: theme.typography.fontFamily.light,
fontSize: "12px",
padding: "0 24px 8px 24px",
letterSpacing: 0.3,
},
This class will be found as FieldDescriptor-info-xxx on the element having that class. Now suppose that this component is child to another one that attempts to target the error class. You could target that class with something like [class*=FieldDescriptor-error] (personally I already consider this a very unclean approach) and it will work only on a development environment.
On production, classes will become unique (e.g. jss-xxx) and selectors like the one above will no longer be useful. My question is, what is the cleanest or "correct" approach to customizing component styles like this in JSS? I am either missing something really obvious or perhaps facing the limitations of JSS.
I am looking forward to solutions that do not require more tooling or code bloating, that would really miss the purpose of adopting JSS in the first place.
You can find an example using both withStyles and useStyles here
Try to think of a component as of a black box that intentionally hides implementation details from the outside world.
With this model, only component itself is responsible for it's presentation, so you need to ask that component to change something. In React world you do that most of the time by passing props to that component.
Inside of that component you can go multiple ways, combining the predefined classes depending on the props (preferred because static) or using function rules/values which let you access the props and define the styles per component instance.
I am using react material ui combined with storybook and storyshots. I am trying to understand how I can test responsive elements in material-ui with jest or storyshots via storybook
I have Hidden elements in my components like the following
<Hidden xsDown>
{displayText}
</Hidden>
and stories that look roughly like
storiesOf("Card", module)
.addDecorator(muiTheme(myTheme))
.add("options bar", () => (
<Card {...someProps}/>
));
I have tried modding the breakpoints in my theme, which has an effect when viewing through storybook. However no matter what I have tried, the Hidden element never renders in my snapshots.
I have also tried not using the Hidden element and tried className styles to set display: none if theme.breakpoints.down('xs') is true. This produces the element in my snapshot like
<h6
className="MuiTypography-root CardOptions-label-1170 MuiTypography-
subtitle2"
>
View Route
</h6>
but nothing in this block tells me that the element is being hidden on xs screens.
It seem like I should be able to somehow toggle xsDown in the Hidden element to be true or false in storybook to have storyshot render or not render the element in my snapshot, but I am having no luck figuring that out.
I guess in general I am just wondering how most people are testing responsive UIs with jest. It seems like I should be able to accomplish this with snapshots but maybe I am missing something.
Thanks for your help
At the moment Storybook does not provide a responsive UI testing library out of the box.
However, you can use an additional library such as Chroma (company behind Storybook) or React screenshot test.
Which one you choose really depends on other factors.
Read more on Chroma: https://blog.hichroma.com/responsive-ui-component-testing-6d38b7e89dd4