Styled-is Flag Utility for styled-components
styled-is is a utility library designed to simplify conditional styling within `styled-components` by providing declarative functions for checking component props. It offers functions like `is`, `isNot`, `isOr`, and `isSomeNot` for boolean prop checks, as well as `match` for value-based prop comparisons. The current stable version, 1.3.0, indicates a mature and stable project focused on a specific use case within the `styled-components` ecosystem. The library aims to enable cleaner and more readable style definitions, reducing the need for verbose ternary operators or complex prop destructuring directly within styled templates. It ships with TypeScript types, enhancing the developer experience in TypeScript projects by providing strong type checking and IDE autocompletion.
Common errors
-
TypeError: (0 , styled_is__WEBPACK_IMPORTED_MODULE_0__.is) is not a function
cause The default export `is` was imported as a named export in a CommonJS or bundled environment (e.g., `import { is } from 'styled-is';`).fixCorrect the import statement to use the default import syntax: `import is from 'styled-is';` -
Warning: Prop `[your-prop-name]` did not match. Server: `[value1]`. Client: `[value2]`.
cause A mismatch in prop values or dynamic styling evaluation between server-side rendering (SSR) and client-side hydration, often due to non-deterministic logic or environment differences when `styled-is` functions are used with dynamic props.fixEnsure that any prop values affecting `styled-is` logic are consistent between server and client. For dynamic values that differ, consider using a `useState` hook with `useEffect` for client-side only effects, or use `suppressHydrationWarning` on the element if the mismatch is benign. -
ReferenceError: styled is not defined
cause The `styled` object from `styled-components` was not imported or correctly configured before attempting to use it to create a styled component.fixEnsure `import styled from 'styled-components';` is present at the top of your file. If using `styled-components` v6+, ensure you are using named imports: `import { styled } from 'styled-components';`.
Warnings
- gotcha Ensure strict compatibility with your `styled-components` version. `styled-is` relies on `styled-components`' underlying API. Mismatches, especially between major `styled-components` versions (e.g., v4/v5 vs. v6+ which introduced breaking changes in module exports and prop handling), can lead to runtime errors or unexpected styling behavior. Always check the peer dependency range.
- gotcha When using `is('propName')`, `styled-is` checks for the *truthiness* of the `propName`. If you intend to match a specific boolean value (`true` or `false`) or a non-truthy value other than `false`/`null`/`undefined`/`0`/`''`, you might need to pass a function or use `match` for explicit value checking.
- gotcha In `styled-components` v6 and above, props not starting with `$` (transient props) that are passed to a styled component might be forwarded to the underlying DOM element, causing React warnings about unknown HTML attributes. While `styled-is` simplifies conditional logic, it doesn't automatically convert prop names to transient ones.
- gotcha Defining `styled-components` within a React render function can lead to performance issues and unexpected behavior (like losing DOM state) because React remounts the component on every render. This principle also applies to the usage of `styled-is` helpers within such dynamically created styled components.
Install
-
npm install styled-is -
yarn add styled-is -
pnpm add styled-is
Imports
- is
import { is } from 'styled-is';import is from 'styled-is';
- isNot
import isNot from 'styled-is';
import { isNot } from 'styled-is'; - match
import match from 'styled-is';
import { match } from 'styled-is'; - isOr
import isOr from 'styled-is';
import { isOr } from 'styled-is';
Quickstart
import is, { isNot, isOr, match } from 'styled-is';
import styled from 'styled-components';
import React from 'react';
import { createRoot } from 'react-dom/client';
const ThemedButton = styled.button`
padding: 10px 20px;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
background-color: #eee;
color: #333;
${is('primary')`
background-color: #007bff;
color: white;
`};
${is('large')`
padding: 15px 30px;
font-size: 20px;
`};
${isNot('disabled')`
&:hover {
opacity: 0.9;
}
`};
${isOr('primary', 'secondary')`
font-weight: bold;
`};
${match('variant', 'outline')`
border: 2px solid currentColor;
background-color: transparent;
`};
${match('variant', 'text')`
background-color: transparent;
color: #007bff;
padding: 5px 10px;
`};
${(props) =>
is('compact')(props) &&
`
padding: 5px 10px;
font-size: 14px;
`}
`;
function App() {
return (
<div>
<ThemedButton>Default Button</ThemedButton>
<ThemedButton primary>Primary Button</ThemedButton>
<ThemedButton primary large>Primary Large Button</ThemedButton>
<ThemedButton large disabled>Large Disabled Button</ThemedButton>
<ThemedButton variant="outline" primary>Outline Primary</ThemedButton>
<ThemedButton variant="text">Text Button</ThemedButton>
<ThemedButton compact>Compact Button</ThemedButton>
<ThemedButton primary compact>Primary Compact</ThemedButton>
</div>
);
}
const container = document.getElementById('root');
if (container) {
const root = createRoot(container);
root.render(<App />);
} else {
console.error("Root element not found. Please ensure your HTML has a <div id='root'>.");
}