quickbase / babel-plugin-styled-components-css-namespace Goto Github PK
View Code? Open in Web Editor NEWA babel plugin to add css namespaces (and increase specificity) of styled-component classes.
License: MIT License
A babel plugin to add css namespaces (and increase specificity) of styled-component classes.
License: MIT License
January is going to be the month of closing out some issues in this project. Unfortunately, I was unable to dedicate enough time to improvements here. Thank you to everyone who has reported issues. Please continue to report them or open PRs with fixes. My goal is to better be aware of issues coming into the project and responding more quickly going forward.
Originally reported by @genedwards, moved from other repo.
Issue: the styled-components module exports a keyframe
function. https://www.styled-components.com/docs/basics#animations
Example usage:
const rotate360 = keyframes`
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
`;
const Rotate = styled.div`
animation: ${rotate360} 2s linear infinite;
`;
The generated CSS from the above example looks like the following:
@-webkit-keyframeskrrMtA{
.<cssNamespace> from{
-webkit-transform:rotate(0deg);
-ms-transform:rotate(0deg);
transform:rotate(0deg);
}
.<cssNamespace> to{
-webkit-transform:rotate(360deg);
-ms-transform:rotate(360deg);
transform:rotate(360deg);
}
}
@keyframes krrMtA{
.<cssNamespace> from{
-webkit-transform:rotate(0deg);
-ms-transform:rotate(0deg);
transform:rotate(0deg);
}
.<cssNamespace> to{
-webkit-transform:rotate(360deg);
-ms-transform:rotate(360deg);
transform:rotate(360deg);
}
}
If I write code like this
const SomeDiv = styled.div`
span {
color: blue;
}
&.is-span-red {
span {
color: red;
}
}
`;
It works good. But if I try to interpolate another styled-component inside the &.is-span-red
, it doesn't work.
const SomeSpan = styled.span``;
const SomeDiv = styled.div`
&.is-span-red {
${SomeSpan} {
color: red;
}
}
`;
Having an issue since upgrading to the new version. This plugin is failing with the following message:
There was a problem adding namespaces to this CSS. Error: <css input>:5:5: Unknown word
CSS:
&& {
fake-element-placeholder
fake-element-placeholder
transition: ease-in-out 50ms;
fake-element-placeholder
&:hover {
transition: ease-in-out 100ms;
}
}
It's failing with the repo here: https://github.com/zachhardesty7/semantic-styled-ui
I'm currently working on reducing the factors that could cause this and getting a minimal reproducible test case going but as of now, it should be reproducible with the above files!
Right now we have a very manual semver documentation and management system. If this plugin has many more additional fixes, we may want to investigate a better system. If anyone has suggestions, please comment or open a PR!
Hello!
That you for writing this awesome plugin! It's exactly what my team is looking for.
On adding it to my babel config I've received the following error. My guess is this is due to me using babel 7 in conjunction with webpack 4.
ERROR in ./src/index.js
Module build failed: TypeError: Cannot read property 'imports' of undefined
at importLocalName (/Users/danielkezerashvili/code/forms/node_modules/@quickbaseoss/babel-plugin-styled-components-css-namespace/node_modules/babel-plugin-styled-components/lib/utils/detectors.js:15:45)
at isCSSHelper (/Users/danielkezerashvili/code/forms/node_modules/@quickbaseoss/babel-plugin-styled-components-css-namespace/node_modules/babel-plugin-styled-components/lib/utils/detectors.js:41:46)
at isHelper (/Users/danielkezerashvili/code/forms/node_modules/@quickbaseoss/babel-plugin-styled-components-css-namespace/node_modules/babel-plugin-styled-components/lib/utils/detectors.js:53:10)
at exports.default (/Users/danielkezerashvili/code/forms/node_modules/@quickbaseoss/babel-plugin-styled-components-css-namespace/lib/visitors/cssNamespace.js:34:82)
at PluginPass.TaggedTemplateExpression (/Users/danielkezerashvili/code/forms/node_modules/@quickbaseoss/babel-plugin-styled-components-css-namespace/lib/index.js:13:36)
at newFn (/Users/danielkezerashvili/code/forms/node_modules/@babel/traverse/lib/visitors.js:223:21)
at NodePath._call (/Users/danielkezerashvili/code/forms/node_modules/@babel/traverse/lib/path/context.js:64:19)
at NodePath.call (/Users/danielkezerashvili/code/forms/node_modules/@babel/traverse/lib/path/context.js:38:17)
at NodePath.visit (/Users/danielkezerashvili/code/forms/node_modules/@babel/traverse/lib/path/context.js:99:12)
at TraversalContext.visitQueue (/Users/danielkezerashvili/code/forms/node_modules/@babel/traverse/lib/context.js:135:18)
@ multi (webpack)-dev-server/client?http://0.0.0.0:3000 ./src
my babel config:
"babel": {
"presets": [
[
"@babel/preset-env",
{
"shippedProposals": true,
"targets": {
"browsers": [
"last 2 versions"
]
}
}
],
"@babel/preset-react"
],
"plugins": [
"@quickbaseoss/babel-plugin-styled-components-css-namespace",
"lodash",
"transform-class-properties",
[
"styled-components",
{
"displayName": true
}
]
]
}
EDIT: The issue is shared with this issue styled-components/babel-plugin-styled-components#96
Hi,
I have a namespace #my-widget
.
Components looks schematically like this
const PolarityCell = styled.td`
color: ${({isNegative}) => isNegative ? 'red': 'green'};
`
<div id="my-widget">
<table>
{entries.map(({value, isNegative}) => (
<tr>
<td><PolarityCell isNegative={isNegative}>{value}</PolarityCell></td>
</tr>
)}
</table>
</div>
}
When entries: [{value: '1', isNegative: false}, {value: '-2', isNegative: true}]
all values are red
When entries: [{value: '-1', isNegative: true}, {value: '2', isNegative: false}]
all values are green
Just discovered what appears to be a bug with this library that causes media queries to be improperly parsed by placing the class name in the improper location. Unfortunately no error is produced so.
To reproduce
const mediaQuery = '@media only screen and (min-width: 426px) and (max-width: 767px)'
const Component = styled.div`
background-color: red;
${mediaQuery} {
background-color: blue;
}
`
Without interpolating the string, it works fine, but the above produces a rule like this:
/* sc-component-id: sc-14zearg-1 */
.jmWrIX.jmWrIX{background-color: red;}
.jmWrIX.jmWrIX @media only screen and (min-width: 426px) and (max-width: 767px){background-color: blue;}
while it should produce a rule like this:
/* sc-component-id: sc-14zearg-1 */
.jmWrIX.jmWrIX{background-color: red;}
@media only screen and (min-width: 426px) and (max-width: 767px){.jmWrIX.jmWrIX{background-color: blue;}}
The new strategy for namespacing adds the wrapper as sass notation. I have only released now that styled components are not really sass.
Given rawCssNamespace: ['body .theme-light', '.theme-dark']
and styles:
styled.div`
display: block;
min-width: 200px;
&.myClass {
/* some css */
}
`
When the plugin namespace styles
Then it should not add namespace as wrapper
Current behaviour:
styled.div`
body .theme-light, .theme-dark {
& {
display: block;
min-width: 200px;
&.myClass {
/* some css */
}
}
}
`
Expected behaviour:
Current behaviour:
styled.div`
body .theme-light &, .theme-dark & {
display: block;
min-width: 200px;
}
body .theme-light &.myClass, .theme-dark &.myClass {
/* some css */
}
`
I will have a look at this weekend. I see to possible solutions:
@nvanselow Sorry for that, it was good releasing as an alternative strategy. Let me know which solution you are up to, also, if you have a different solution. ;)
Thank you
Hi, I've got an issue with some components in a component library. The class names don't get doubled by this plugin when using the following Styled Components syntax:
Doesn't work
const ArrowButton = styled.button<ArrowButtonProps>(({ disabled = false }) => [
tw`text-white`,
disabled ? tw`bg-gray-50` : tw`hover:bg-secondary-700`
]);
Example output: .c0
Works
const PageCount = styled.div`
${tw`inline-flex justify-center items-center`};
`;
Example output: .c1.c1
Any ideas? Thank you!
Seems partially related to #33 or #46
Preamble: I migrated from old version 0.1.1
to 1.0.0-rc4
and a working application stopped working. I already read and performed migration procedure, converting class names and so on.
What I found: if my styled CSS contains comments in the form of // foo bar
now I can't complile my app.
The errors is something like this:
ERROR in ./components/mycomponent.js
Module build failed (from ../node_modules/babel-loader/lib/index.js):
Error: ..../xxx.js.js: There was a problem adding namespaces to this CSS in the file .../xxx.js. Error: <css input>:7:3: Unknown word
CSS:
If I go at line 7 of the CSS string I find a duble-slash.
I don't find any official reference, but I read that both of those kind of comments are legit:
// This is a comment
/* this is also a comment */
Unluckily now I have to convert my //
to /* */
.
Hi all!
Babel has updated to v7 and it would be great to update this package to follow suite with upgrading its dependencies.
@nvanselow What do you think of this? TrevorBurnham/babel-plugin-namespace-styled-components#5
Hi I'm using styled-components
in my current project and want to use this babel plugin as suggested by the official docs to prevent third-party styling of my components when embedded as a widget.
The styled components in this projects make quite some use of the & and sibling operator ~ which is not working and a known issue as stated in the docs. Is there any ambition to fix this in a future release as it seems to be fixed when using the rawCssNamepsace
option? Unfortunately the rawCssNamespace
option does not work in my project and my webpack dev server
is not starting, it seems to be stuck in an infinite loop. I tried to debug it but till now I had no luck. Any hints are highly appreciated.
Hello,
I have one Javascript project and one Typescript project, both with the plugin configured. In the Javascript project this work fine, but with Typescript doesn't work.
My question: This plugin is compatible with Typescript?
package.json:
{
"name": "react-typescript-starter",
"description": "Clean React + TypeScript starter, without usage of create-react-app โ",
"version": "1.0.0",
"main": "src/index.tsx",
"repository": "https://github.com/GR34SE/react-typescript-starter.git",
"license": "MIT",
"private": false,
"scripts": {
"dev": "webpack-dev-server --mode development --env.development",
"build": "webpack --mode production --env.production --progress",
"lint": "eslint './src/**/*.{ts,tsx}'",
"lint:fix": "eslint './src/**/*.{ts,tsx}' --fix"
},
"devDependencies": {
"@types/node": "13.13.33",
"@types/react": "16.14.2",
"@types/react-dom": "16.9.10",
"@types/styled-components": "^5.1.4",
"@types/webpack": "4.41.25",
"@types/webpack-dev-server": "3.11.1",
"@typescript-eslint/eslint-plugin": "4.8.2",
"@typescript-eslint/parser": "4.8.2",
"eslint": "7.14.0",
"eslint-config-prettier": "6.15.0",
"eslint-plugin-import": "2.22.1",
"eslint-plugin-prettier": "3.1.4",
"eslint-plugin-react": "7.21.5",
"eslint-plugin-react-hooks": "4.2.0",
"fork-ts-checker-webpack-plugin": "5.2.1",
"html-webpack-plugin": "4.5.0",
"prettier": "2.2.0",
"ts-loader": "8.0.11",
"ts-node": "9.0.0",
"tsconfig-paths-webpack-plugin": "3.3.0",
"typescript": "4.1.2",
"webpack": "4.44.2",
"webpack-cli": "3.3.12",
"webpack-dev-server": "3.11.0"
},
"dependencies": {
"@babel/cli": "^7.12.8",
"@babel/core": "^7.12.9",
"@babel/preset-env": "^7.12.7",
"@babel/preset-react": "^7.12.7",
"@quickbaseoss/babel-plugin-styled-components-css-namespace": "^1.0.1",
"babel-loader": "^8.2.1",
"babel-plugin-styled-components": "^1.12.0",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"styled-components": "^5.2.1"
}
}
webpack.config.ts
import path from "path";
import webpack, {Configuration} from "webpack";
import HtmlWebpackPlugin from "html-webpack-plugin";
import ForkTsCheckerWebpackPlugin from "fork-ts-checker-webpack-plugin";
import {TsconfigPathsPlugin} from "tsconfig-paths-webpack-plugin";
const webpackConfig = (env): Configuration => ({
entry: "./src/index.tsx",
...(env.production || !env.development ? {} : {devtool: "eval-source-map"}),
resolve: {
extensions: [".ts", ".tsx", ".js"],
plugins: [new TsconfigPathsPlugin()]
},
output: {
path: path.join(__dirname, "/dist"),
filename: "build.js"
},
module: {
rules: [
{
test: /\.ts$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
plugins: [
[
"@quickbaseoss/babel-plugin-styled-components-css-namespace",
{"cssNamespace": ".my-namespace"}
],
"styled-components"
]
}
},
{
test: /\.tsx?$/,
loader: "ts-loader",
options: {
transpileOnly: true
},
exclude: /dist/
}
]
},
plugins: [
new HtmlWebpackPlugin({
template: "./public/index.html"
}),
new webpack.DefinePlugin({
"process.env.PRODUCTION": env.production || !env.development,
"process.env.NAME": JSON.stringify(require("./package.json").name),
"process.env.VERSION": JSON.stringify(require("./package.json").version)
}),
new ForkTsCheckerWebpackPlugin({
eslint: {
files: "./src/**/*.{ts,tsx,js,jsx}" // required - same as command `eslint ./src/**/*.{ts,tsx,js,jsx} --ext .ts,.tsx,.js,.jsx`
}
})
]
});
export default webpackConfig;
index.tsx
<div className="my-namespace">
<h1>Hello World</h1>
<hr />
<h3>Environmental variables:</h3>
<Text>
process.env.PRODUCTION: <b>{process.env.PRODUCTION.toString()}</b>
</Text>
<Text>
process.env.NAME: <b>{process.env.NAME}</b>
</Text>
<Text>
process.env.VERSION: <b>{process.env.VERSION}</b>
</Text>
</div>
The component:
import styled from "styled-components/macro";
import { Segment } from "semantic-ui-react";
import semanticStyles from "../../../semantic/exports.module.less";
export const BlueSegment = styled(Segment)`
background-color: ${semanticStyles.mediumBlue} !important;
inverted: true;
`;
The config:
rule.options.plugins.push([
"@quickbaseoss/babel-plugin-styled-components-css-namespace",
{
"cssNamespace": "#root"
}
]);
rule.options.plugins.push("babel-plugin-styled-components");
Outputs:
<div class="ui blue inverted center aligned segment PortalStatsMainStyles__BlueSegment-ws1dxq-0 iaCJEB">
.iaCJEB {
background-color: #026fad !important;
inverted: true;
}
So I cant override semantic-ui styles :(
In the process of upgrading React to v18 we found that styled-components was throwing an error about breaking the rule of hooks. Upgrading styled-components to the latest version it appears that the babel-plugin-styled-components-css-namespace no longer works correctly.
Given the babel config
['@quickbaseoss/babel-plugin-styled-components-css-namespace', { cssNamespace: '.ssa-app' }],
and the code
const StyledIcon = styled(IcomoonReact)`
transform: ${(props) => (props.$flipx ? `scaleX(-1)` : 'none')};`
`
<StyledIcon $flipx={true} />
<StyledIcon $flipx={false} />
On version 5.1.1 the above would produce 2 styles and correctly assign the classnames to the elements in the DOM. (.ssa-app is the css prefix defined in babel-plugin-styled-components-css-namespace)
.ssa-app .lnugha {
transform: none;
}
.ssa-app .hHOYwd {
transform: scaleX(-1);
}
Since updating to 5.3.5 the CSS is as follows and both elements have the same class of sc-bczRLJ
and thus both look the same (flipped).
.ssa-app .sc-bczRLJ {
transform: scaleX(-1);
}
.ssa-app .sc-bczRLJ {
transform: none;
}
.ssa-app .sc-bczRLJ {
transform: none;
}
I'm completely stuck as to how to achieve the global css namespace in 5.3.5.
First all thank for this plugin, is solved a very annoying CSS override issue between our 2 projects.
My issue is that:
const InfoContainer = styled.div`
display: flex;
& + & {
margin-left: 0.5rem;
}
`;
now generate the style ('spa' is our namespace):
.sc-eHgmQL {}.spa .hVujAK{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;} .spa .hVujAK + .spa .hVujAK{margin-left:0.5rem;}
With that style the margin-left is never applied because the selector should be .spa .hVujAK + .hVujAK
instead of .spa .hVujAK + .spa .hVujAK
Is that fixable in babel-plugin-styled-components-css-namespace?
Hey!
When you have component like this:
const Button = styled.button`
background: green;
color: red;
padding: 1em;
`;
and .babelrc like:
["@quickbaseoss/babel-plugin-styled-components-css-namespace", {
"rawCssNamespace": ["#prefix"]
}]
The generated selector is wrong:
<style data-styled="" data-styled-version="4.1.3">
/* sc-component-id: sc-bdVaJa */
.gBOsWq #prefix{background:green;color:red;padding:1em;}</style>
The correct should be
<style data-styled="" data-styled-version="4.1.3">
/* sc-component-id: sc-bdVaJa */
#prefix .gBOsWq {background:green;color:red;padding:1em;}</style>
Using the cssNamespace seems to work, but I need to prefix the selectors with id rather than class.
Note
If I change
const Button = styled.button`
background: green;
color: red;
padding: 1em;
`;
to
const Button = styled.button`
.foo {
background: green;
color: red;
padding: 1em;
}
`;
It works.
Is this a desired behaviour?
I posted #50 to handle the shuffling of expressions that happens when the CSS is run through postcss
and the CSS contains nested pseudo-selectors e.g. &:hover
, &:active
etc.
That PR fixes one class of problems, but we've found another related problem that occurs when we include these sorts of pseudo-selectors inside the template expressions.
Example:
Here's the original styled component:
export default styled.div`
background: ${props => props.background};
border: 1px solid ${props => props.borderColor};
cursor: text;
&:hover {
border-color: ${props => props.hoverBorder};
}
&:active {
border-color: ${props => props.activeBorder};
}
${props =>
props.disabled &&
css`
border-color: ${props.disabledBorder};
cursor: not-allowed;
&:active,
&:hover {
border-color: ${props.disabledBorder};
}
* {
cursor: not-allowed;
}
`
};
`;
And here it is after processing with this plugin using cssNamespace: '.class-wrapper .other-wrapper'
:
export default styled.div`
.class-wrapper .other-wrapper & {
background: ${props => props.background};
border: 1px solid ${props => props.borderColor};
cursor: text;
${props =>
props.disabled &&
css`
border-color: ${props.disabledBorder};
cursor: not-allowed;
&:active,
&:hover {
border-color: ${props.disabledBorder};
}
* {
cursor: not-allowed;
}
`
};
}
.class-wrapper .other-wrapper &:hover {
border-color: ${props => props.hoverBorder};
}
.class-wrapper .other-wrapper &:active {
border-color: ${props => props.activeBorder};
}
`;
When styled-components renders this into the page and the component has the disabled
prop set, the resulting CSS will look like this:
.class-wrapper .other-wrapper .AAAAAA {
background: #bgcolor;
border: 1px solid #borderColor;
cursor: text;
border-color: #disabledBorder;
cursor: not-allowed;
}
.class-wrapper .other-wrapper .AAAAAA:active,
.class-wrapper .other-wrapper .AAAAAA:hover {
border-color: #disabledBorder;
}
.class-wrapper .other-wrapper .AAAAAA * {
cursor: not-allowed;
}
.class-wrapper .other-wrapper .AAAAAA:hover {
border-color: #hoverBorder;
}
.class-wrapper .other-wrapper .AAAAAA:active {
border-color: #activeBorder;
}
So, the problem is that this places the original (non-disabled) &:hover
and &:active
below the overrides that are intended to apply when the component gets the disabled
prop. Therefore the "disabled" overrides don't actually override the base styles, but rather they themselves get overridden by the base styles, since CSS uses code-order to determine precedence.
The reason: this plugin "unwraps" the source styles, which pulls the &:hover
and &:active
that are not in expressions below the main style block. But the &:hover
and &:active
that are in expressions don't get "unwrapped" until styled-components generates the final CSS, based on evaluating those expressions. At that time, the expression versions get placed just below the main style block, before the "main" versions that were pulled out by the plugin.
Hopefully this makes sense.
My question:
It seems to me that the inclusion of the postcss-nested
PostCSS processor is only to accommodate the postcss-parent-selector
, which will generate invalid results if provided nested CSS. I wonder though if, instead of using postcss-parent-selector
, instead a simplified version of that processor could be used, which only modifies the root element of the CSS it receives? Is there any reason for postcss-nested
other than to make postcss-parent-selector
happy? (*see below)
Such a simplified processor might look like this:
import postcss from 'postcss';
export default postcss.plugin('add-parent-selector', (opts = {}) => (root) => {
root.walkRules((rule) => {
if (rule.parent && rule.parent.type === 'root') {
rule.selectors = rule.selectors.map((selectors) =>
selectors.split(/,[\s]* /g).map((selector) => {
// don't add the parent class to a rule that is
// exactly equal to the one defined by the user
if (selector === opts.selector) {
return selector;
}
return `${opts.selector} ${selector}`;
}),
);
}
});
});
But I'm not sure if there are other reasons to include the postcss-nested
processor that I am not seeing. Any thoughts?
I'd be happy to post this proposal as a PR but don't want to do so if it's going to break other things.
*Without unnesting, the parent-selector processor would produce something like...
export default styled.div`
.class-wrapper .other-wrapper & {
background: ${props => props.background};
...
.class-wrapper .other-wrapper &:hover {
border-color: ${props => props.hoverBorder};
}
.class-wrapper .other-wrapper &:active {
border-color: ${props => props.activeBorder};
}
...
}
`;
...i.e. generating final selectors like .class-wrapper .other-wrapper .xxxxxx .class-wrapper .other-wrapper .xxxxx:hover { ... }
. Not good.
I guess this is a bit off topic but maybe someone can help.
The plugin works nicely when I use it in a fresh "create-react-app" setup. Really cool !
Now I want to create a bundle of my project to be used in another project by using the "microbundle" bundler.
I tried different Babel configs ".babelrc" and "babel.config.js" - but the css prefixes are not applied. Not sure if the plugin is even called. Maybe I should try another bundler?
Thanks,
Oliver
Hey, we're using create-react-app 2 which supports babel plugins without ejecting, using https://github.com/kentcdodds/babel-plugin-macros
Is this library compatible? I might look into creating a macro if not. Thanks!
Are style objects supported? They don't seem to work for me, and I can't find any examples in the issues or in the tests. I'm running the plugin using inside create-react-app
using customize-cra
, but I believe I have it (mostly) configured properly because when I change things into template literals, the namespace does get added correctly (both using styled
and the css prop).
Thank for the plugin;
Problem: no styled-component transformed when using cssNamespace option, work fine if not add cssNamespace option.
My project are using create-react-app, and install webpack to build a js file. it doesn't eject the create-react-app. Also the project use styled-component v3.
Also the compiler just hand if I add rawCssNamespace option
My .babelrc
{
"presets": ["@babel/env", "@babel/react"],
"plugins": [
"@babel/plugin-proposal-class-properties",
[
"@quickbaseoss/babel-plugin-styled-components-css-namespace",
{
"cssNamespace": ["moreSpecific", "reallySpecific", "extraSpecific"]
}
],
"babel-plugin-styled-components",
["@babel/plugin-transform-runtime", { "regenerator": true }]
]
}
My webpack.config.js
const webpack = require('webpack');
const path = require('path');
module.exports = {
entry: './src/build.jsx',
mode: 'production',
resolve: {
extensions: ['.js', '.jsx'],
},
output: {
filename: 'aaa.js',
libraryExport: 'default',
libraryTarget: 'var',
library: 'bbb',
path: path.resolve(__dirname, './dist/lib'),
},
node: {
fs: 'empty',
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
},
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
],
},
plugins: [
new webpack.DefinePlugin({
'process.browser': 'true',
}),
],
};
My package.json
{
"name": "",
"version": "0.1.0",
"private": true,
"dependencies": {
"@babel/plugin-proposal-class-properties": "^7.1.0",
"@babel/preset-react": "^7.0.0",
"@quickbaseoss/babel-plugin-styled-components-css-namespace": "^0.1.1",
"nprogress": "^0.2.0",
"prop-types": "^15.6.2",
"react": "^16.6.3",
"react-dom": "^16.6.3",
"react-scripts": "2.1.1",
"react-select": "^2.1.2",
"react-toastify": "^4.5.1",
"shortid": "^2.2.14",
"styled-components": "^3.1.6",
"webpack": "4.19.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"build:webpack": "webpack --config webpack.config.js"
},
"eslintConfig": {
"extends": "react-app"
},
"devDependencies": {
"babel-loader": "^8.0.4",
"babel-plugin-styled-components": "^1.10.0",
"babel-plugin-transform-runtime": "^6.23.0",
"eslint-config-airbnb": "^17.1.0",
"eslint-loader": "^2.1.1",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-jsx-a11y": "^6.1.2",
"eslint-plugin-react": "^7.11.1",
"webpack-cli": "^3.1.2"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"author": "",
"license": "ISC",
"description": "",
"proxy": "http://localhost:8888",
"main": "index.js"
}
Hi there,
This is exactly what I need for a pesky CSS problem ๐
Does this work with Emotion 11 (@emotion/styled
)? I am also using theme-ui
to make the compiling even more interesting ๐
I am not seeing any modifications to the CSS, though it could very well be user-error. Any thoughts?
{
test: /\.(js|jsx|ts|tsx)$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
presets: [
["@babel/preset-env", {}],
"@babel/preset-typescript",
[
"@babel/preset-react",
{
runtime: "automatic",
importSource: "react"
}
]
],
plugins: [
["@quickbaseoss/babel-plugin-styled-components-css-namespace", { cssNamespace: "&&&&" }],
"@babel/proposal-class-properties",
"@babel/proposal-object-rest-spread"
]
}
And the button
/** @jsxImportSource theme-ui */
import { Button as VendorButton, ButtonProps } from "@thirdpartyidontcontrol";
import styled from "@emotion/styled";
import { ReactNode } from "react";
export interface ButtonProps extends ButtonProps {
sx?: Record<string, string>;
variant?: string;
children?: ReactNode;
}
const StyledButton = styled(VendorButton)``;
export function Button(props: ButtonProps) {
const { sx: obj = {}, variant = "" } = props;
const sx = { variant, ...obj };
return <StyledButton {...props} />;
}
I am wondering if isStyled is evaluating to false, since it is Emotion
and not in the approved list?
This would be a big help if emotion
was supported, and I would be happy to help contribute to that end (if this is indeed the issue ๐คท )
Hey there,
I am not entirely sure if this is an issue for intended behaviour, so maybe someone can just explain?!
But I have the problem, that I have some styled components, which I am also extending and then using in a bigger application. That's why I wanted to use this plugin, to up the specificity of those components.
For example
export const Button = styled.button`
[...]
`;
export const ExtendedButton = Button.extend`
[...]
`;
The problem is that the extended styles don't seem to get the prefix like the main styles do:
Just for reference, this is the config for the plugin I am using: ["@quickbaseoss/babel-plugin-styled-components-css-namespace", { "cssNamespace": "folders" }]
Can anyone help?
Hi!
I use CRA and the development server NOT starting (without errors, only "Starting the development server..." in console displayed).
package.json:
"@quickbaseoss/babel-plugin-styled-components-css-namespace": "^1.0.0-rc4"
"react-app-rewired": "^2.1.5",
"customize-cra": "^0.9.1",
"react-scripts": "3.4.1"
But, if I change "react-scripts" to "3.2.0" - all work fine.
I tried to use the plugin together with webpack (babel-loader) and typescript, but wasn't successful.
With the following module.rules
part of my webpack.config.js I receive no error but the plugin shows no effect, i.e. the CSS of styled components is not transformed at all:
test: /\.tsx?$/,
exclude: path.resolve(__dirname, '../node_modules'),
loader: 'babel-loader',
options: {
plugins: ['@quickbaseoss/babel-plugin-styled-components-css-namespace']
}
When adding { cssNamespace: 'moreSpecific' }
, that is:
test: /\.tsx?$/,
exclude: path.resolve(__dirname, '../node_modules'),
loader: 'babel-loader',
options: {
plugins: [
'@quickbaseoss/babel-plugin-styled-components-css-namespace',
{ cssNamespace: 'moreSpecific' }
]
}
...I get the following error:
Module build failed: Error: Plugin 1 specified in "base" provided an invalid property of "cssNamespace"
Any ideas?
Versions of tools:
typescript: ^3.0.1
webpack: ^2.3.3
babel-loader: ^7.1.5
babel-plugin-styled-components-css-namespace: ^0.1.1
Hi there,
I have an app and some npm packages. I bundle these packages using rollup. I would like to use this plugin on my packages bundled with rollup
, however, I can't seem to get it to work. I'm using the rollup-babel
plugin. Do I need to include the packages in my app babel config? How could I make this work?
Thanks!
Example:
const foo = css`
width: 0px;
`;
const bar = styled`
color: green;
${foo}
`
Results in two classes:
.asdas.asdas.asdas.asdas {
width: 0px;
}
.asdas.asdas {
color: green;
}
expected behavior:
.asdas.asdas {
width: 0px;
color: green;
}
Note, that further nesting will add even more selectors.
Hey all, I was working with this plugin on the node version 12.15.0 and over there it wasn't working... by downgrading to 12.4.0 it did work. Met me post more details soon, but any suggestions where this is coming from?
The issue I encountered was that the webpack build kept spinning reaching some of the first encountered styled-components. repeatedly the same file. (implementation of the component made no difference). simple for example: styled.div with background color
also running the test directly in the repo seems to be broken?
after this test i downgraded to node 11.9.0 via nvm. result is that jest is run within seconds!
checking versions it seems like version 12.10 is correct, higher is broken. confirmed 12.11.0 is not working, (12.11.1 also broken )
locally I updated all packages (including jest, and styled components helpers for version 5) but didn't help me any further...
looks like postcss.process.then neither . catch is being triggered:
https://github.com/trevorburnham/babel-plugin-namespace-styled-components seems to be having the same issue
Hi! First of all, thanks for this plugin! I run into CSS parsing errors when trying to add it to my project.
Minimal reproducible example:
const a = '2px';
const MyStyledComponent = styled.div`
padding: ${a} ${a} ${a} ${a};
`;
Internally, this CSS snippet gets transpiled into:
padding: fake-element-placeholder fake-element-placeholder fake-element-placeholder fake-element-placeholder: fakevalue;
...which makes postcss
complain about the missing semicolon.
Another example that causes parser to fail:
const padding = 'padding: 2px 2px 2px 2px;';
const MyStyledComponent = styled.div`
${padding}
`;
This time it get transpiled to:
fake-element-placeholder
Which causes Error: <css input>:3:3: Unknown word
error.
I would be more than happy to help with fixing this issue, however, I might need some tips & guidance ๐
Cheers!
Hey man! This has been a super useful plugin for working with styled-components and 3rd party libraries but sometimes it would be super helpful to allow the className to be duplicated more than once. I tried running the plugin in Babel twice but that didn't work. Any thoughts?
Hi
I was wondering it possible to add the className as an additional class of the current element, and not as a parent selector ?
Requested:
"babel": { "plugins": [ ["@quickbaseoss/babel-plugin-styled-components-css-namespace", {"cssNamespace": "&.specific"}], "styled-components" ] }
// output:
.specific.c0 { background-color: blue; }
In order to add the same custom class on all styled components, so we can, for example use:
:not[class*='specific']
on existing legacy css selectors
https://codesandbox.io/s/festive-nobel-v7o9j?file=/config-overrides.js
<TestComponent className={
${classes.test} ${className}} />
In this case, $[classes.test}
take precedence over our styled components because of the order they're being passed in. But the plugin SHOULD be adding specificity to prevent that, no?
Hi,
First time trying this. Am I incorrect in assuming that I install this as instructed and it should automatically duplicate the styles as suggested here?
https://github.com/QuickBase/babel-plugin-styled-components-css-namespace#default
This is not the case for me. I added it, updated my babel files as instructed and nothing is duplicated. Everything is exactly the same as if I had not installed this plugin.
Thanks
Hi,
here an example of code
export const AnchorWrapper = styled.div<{ selected: boolean }>
box-sizing: border-box;
width: fit-content;
${({ selected, theme: { colors, mediaQueries } }) =>
mediaQueries?.isMobile
? cssdisplay: flex; flex-direction: row; align-items: center; padding: ${pxToRem(8)} 0 ${pxToRem(8)} ${pxToRem(16)}; border-left: ${pxToRem(3)} solid ${selected ? colors.lightAccentDefault : colors.neutral300};
: cssheight: ${pxToRem(56)}; display: flex; flex-direction: column; justify-content: space-between; align-items: center; padding: ${pxToRem(21)} 0 ${pxToRem(14)}; gap: ${pxToRem(4)};
}
;
and this is the error on returned
`ERROR in ../ui/build/src/atoms/Anchor/styles.js
Module build failed (from ../../node_modules/babel-loader/lib/index.js):
Error: prj/ui.frontend/packages/ui/build/src/atoms/Anchor/styles.js: There was a problem adding namespaces to this CSS in the file prj/ui.frontend/packages/ui/build/src/atoms/Anchor/styles.js. Error: :6:3: Unknown word
CSS:
box-sizing: border-box;
width: fit-content;
fake-element-placeholder-0
`
any known solution?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.