macaron-css / macaron Goto Github PK
View Code? Open in Web Editor NEWCompiler-augmented typesafe CSS-in-JS with zero runtime, colocation, maximum safety and productivity
Home Page: https://macaron.js.org/
License: MIT License
Compiler-augmented typesafe CSS-in-JS with zero runtime, colocation, maximum safety and productivity
Home Page: https://macaron.js.org/
License: MIT License
In the app I'm using Macaron in, we have decorators, which I enable like this in Vite:
plugins: [
...
react({
babel: {
plugins: [
['@babel/plugin-proposal-decorators', { legacy: true }],
['@babel/plugin-proposal-class-properties', { loose: false }],
],
},
}),
macaronVitePlugin(),
],
This configuration doesn't extend to Macaron when I add it to the plugins, and I get this error
App.tsx: Support for the experimental syntax 'decorators' isn't currently enabled (39:1):
Would it be possible to extend the API of the Vite plugin to allow users to pass in additional plugins/presets to the babel config in @macaron-css/integration
?
https://github.com/macaron-css/macaron/blob/main/packages/integration/src/babel.ts#L11
Hi there!
I got some problems using macaron-css with Solid JS + Vite.
I only used the styled
function imported from @macaron-css/solid
and got the issue from the photo above.
I created a codesandbox with the problem to make available here. I will try to debug the problem myself to try to contribute with the solution (In case it really is something macaron-css related)
Codesandbox: https://codesandbox.io/p/sandbox/hungry-hooks-d44xwu
The current published version of macaron pushes all the bindings first and the styled nodes later, this means that all the nodes that reference a style declaration in the beginning of the new virtual file and the styled nodes are later.
This works fine if only the variables are being used inside declaration but becomes an issue when the declaration is used inside a another variable since babel considers both to be a "binding"
Consider this:
const color = 'red';
const red = style({ color });
const entireClass = `pt-2 ${red}`;
the expected compiled output would be
const color = 'red';
const red = 'red_HASH';
const entireClass = `pt-2 ${red}`;
but it is actually
const color = 'red';
const entireClass = `pt-2 ${red}`;
const red = 'red_HASH';
This would produce an error and shouldn't be that hard to fix. I think the fix would require checking the source location of binding and declaration and based on that decide which one should be pushed first
Is there a full esbuild example? The one linked in the documentation here emits an index.js
and an index.css
files. What's the suggested way to use these files in an html page? Should I just add a <link src="index.css" rel="stylesheet" />
tag in the html? Would this always be single a compiled stylesheet if I have several styled components in different files?
import * as macaronCore from '@macaron-css/core'
export const css = macaronCore.style;
Hi, I am trying to include/bundle some useful Macaron functions inside of a design system package. Specifically things like style functions in order to give users a "css" prop to use without having to install macaron/core or macaron/react itself. Also things like createTheme to make custom themes. This pattern works with other libraries, including VE. Currently when importing a function from my package in the consuming app the below error is thrown. This doesn't happen when importing any functions directly form Macaron or when importing {style as css} from @macaron-css/core in the app. This also doesn't work when importing directly to another file within in the same directory, before compiling.
Uncaught Error: Styles were unable to be assigned to a file. This is generally caused by one of the following:
Any suggestions on how to resolve this? thanks!
Versions
"@macaron-css/core": "1.2.0",
"@macaron-css/solid": "1.4.1",
"@macaron-css/vite": "1.4.3",
Error message,
Could not find a declaration file for module '@macaron-css/solid'. '/project/node_modules/@macaron-css/solid/dist/index.mjs' implicitly has an 'any' type.
There are types at '/project/node_modules/@macaron-css/solid/dist/index.d.ts', but this result could not be resolved when respecting package.json "exports". The '@macaron-css/solid' library may need to update its package.json or typings.ts(7016)
Emphasis on
this result could not be resolved when respecting package.json "exports". The '@macaron-css/solid' library may need to update its package.json or typings.ts
Hello, I'm trying yo use compoundVariants
option because it's very useful in my case. I guess it should work the similar as in stitches but I didn't find any examples in documentation. Could you add some?
As it stands right now, you can't style components that use a forwardRef
wrapper, which forced me to cast them to any.
Example
const MyForwardRefComponent = React.forwardRef((props, ref) => <h1 ref={ref}>Hello World</h1>);
// does not work
const StyledMyForwardRefComponent1 = styled(MyForwardRefComponent, {...});
// does work
const StyledMyForwardRefComponent2 = styled(MyForwardRefComponent as any, {...});
Would appreciate if this received a fix.
I am currently in the processes of porting over a design system from Vanilla Extract to Macaron.
I was compiling with Vite in Lib mode using vite-dts in Vanilla Extract and everything was working fine. When using Macaron, the builds are failing.
Here's the vite.config
import { defineConfig } from 'vite';
import dts from 'vite-plugin-dts';
import { peerDependencies } from './package.json';
import { macaronVitePlugin } from '@macaron-css/vite';
const externals = [...Object.keys(peerDependencies)];
export default defineConfig({
build: {
lib: {
entry: 'src/index.ts',
fileName: 'index',
formats: ['cjs', 'es'],
},
rollupOptions: {
external: externals,
},
},
plugins: [
macaronVitePlugin(),
dts({
beforeWriteFile: (filePath, content) => ({
content,
filePath: filePath.replace('src', ''),
}),
compilerOptions: {
baseUrl: './src/',
emitDeclarationOnly: true,
noEmit: false,
},
exclude: ['src/**/*.stories.tsx'],
outputDir: 'dist/types',
}),
],
});
FWIW, I was able to get builds working by removing vite-dts from the vite.config, building, and then running a separate build step with tsc and the following flags "tsc --emitDeclarationOnly --declaration --declarationDir dist/types".
In Stiches you can compose components from other elements, i.e. where MyCoolElement is another component.
Currently in Macaron it will throw a type error "... is not assignable to parameter of type 'string'"
The functionality still works and I have just been using //@ts-expect-error but thats not ideal.
const Button = styled(MyCoolElement, {
base: {
backgroundColor: 'gainsboro',
},
});
From my tests, you can pass a component successfully to as
(e.g. <StyledBtn as={WhateverComponent} />
), but a type error is shown if you don't pass a string:
Type 'WhateverComponent' is not assignable to type 'string'. ts(2322)
Types should be expanded to allow for more values here.
Made an example repo here:
https://github.com/broccolai/macaron-bug-example/blob/master/src/App.tsx#L6
Seems the types are not working for @macaron-css/solid
v1.5.1. I'm not getting any intellisense with v1.5.1. Is there something missing here?
[transferred to an issue from the vanilla extract discord]
Hello! I'm thinking of moving a codebase from emotionjs to macaron, but I've run into a sticking point: our component library often wraps a third-party component lib (ant design in this case) and we often need to restyle the underlying component lib in certain situations.
In emotion, we could select the classnames that the third-party library was exposing, so we could do something like this:
// styles for my current component
paddingLeft: 12,
// styles for the third party lib
'& .ant-table-thead': {
fontSize: 24
},
'& .ant-table-tbody': ...
// other styles
Since vanilla extract doesn't support complex selectors targeting elements other than the current one, the easiest way I could think of doing this with vanilla extract is something like this:
const wrapperCls = style({
paddingLeft: 12,
})
globalStyle(${wrapperCls} > .ant-table-thead
, {
fontSize: 24
})
globalStyle(${wrapperCls} > .ant-table-tbody
, ...)
// other calls to globalStyle
Which, while technically maybe the same number of lines, feels more clunky and forces a separation that I think makes the intention of the code less clear. I thought about possibly writing a utility function that would take the object style and make those multiple globalStyle calls for me, but it seems to throw "Maximum call stack size exceeded" errors, because I think the macro system doesn't know how to resolve the variable references.
Here's a stackblitz link: https://stackblitz.com/edit/macaron-css-macaron-rjwpfg?file=src/App.tsx
I was able to get it to work with Vanilla Extract (without macaron) if that's helpful: https://stackblitz.com/edit/vitejs-vite-63vac7?file=src/components/button/button.css.ts . Macaron would offer a cleaner upgrade path for me and closer to the DX that I'm looking for though
@Mokshit06 replied:
oh so i see what's happening, macaron is trying to extract the styled function inside sampleFn but it depends on a variable reference that is declared inside it so it is unable to extract
we should move this to a github issue
Is it Possible to Combine Kobalte or Ark with Macaron?
https://ark-ui.com/docs/solid/components/menu
#37 look like possible but I have the issue in above image
Is it possible to solve it?
Thanks!
use docusaurus and codehike
Macaron needs an update so that it can continue to work with the newest versions of Vite 5.x.
The error I'm getting is this:
vite v5.0.10 building for development...
โ 170 modules transformed.
[vite:react-babel] /Users/web/g/platform-clone/frontend-packages/design-system/src/web/extracted_1fmahrf.css.ts: Identifier 'globalStyle' has already been declared. (26:9)
24 | });
25 | var _$macaron$$unknown6 = _$macaron$$unknown5;
> 26 | import { globalStyle, globalFontFace } from '@macaron-css/core';
| ^
27 | export var _$macaron$$unknown7 = globalStyle('*, ::before, ::after', {
28 | boxSizing: 'border-box'
29 | });
file: /Users/web/g/platform-clone/frontend-packages/design-system/src/web/extracted_1fmahrf.css.ts:26:9
error during build:
SyntaxError: /Users/web/g/platform-clone/frontend-packages/design-system/src/web/extracted_1fmahrf.css.ts: Identifier 'globalStyle' has already been declared. (26:9)
24 | });
25 | var _$macaron$$unknown6 = _$macaron$$unknown5;
> 26 | import { globalStyle, globalFontFace } from '@macaron-css/core';
| ^
27 | export var _$macaron$$unknown7 = globalStyle('*, ::before, ::after', {
28 | boxSizing: 'border-box'
29 | });
at constructor (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:356:19)
at TypeScriptParserMixin.raise (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:3223:19)
at TypeScriptScopeHandler.declareName (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:7038:21)
at TypeScriptParserMixin.declareNameFromIdentifier (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:7484:16)
at TypeScriptParserMixin.checkIdentifier (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:7480:12)
at TypeScriptParserMixin.checkLVal (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:7419:12)
at TypeScriptParserMixin.finishImportSpecifier (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:14175:10)
at TypeScriptParserMixin.parseImportSpecifier (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:14352:17)
at TypeScriptParserMixin.parseImportSpecifier (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:10004:18)
at TypeScriptParserMixin.parseNamedImportSpecifiers (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:14330:36)
at TypeScriptParserMixin.parseImportSpecifiersAndAfter (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:14152:37)
at TypeScriptParserMixin.parseImport (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:14145:17)
at TypeScriptParserMixin.parseImport (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:9251:26)
at TypeScriptParserMixin.parseStatementContent (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:12710:27)
at TypeScriptParserMixin.parseStatementContent (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:9340:18)
at TypeScriptParserMixin.parseStatementLike (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:12588:17)
at TypeScriptParserMixin.parseModuleItem (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:12565:17)
at TypeScriptParserMixin.parseBlockOrModuleBlockBody (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:13189:36)
at TypeScriptParserMixin.parseBlockBody (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:13182:10)
at TypeScriptParserMixin.parseProgram (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:12464:10)
at TypeScriptParserMixin.parseTopLevel (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:12454:25)
at TypeScriptParserMixin.parse (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:14376:10)
at TypeScriptParserMixin.parse (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:9982:18)
at parse (/Users/web/g/platform-clone/node_modules/@babel/parser/lib/index.js:14417:38)
at parser (/Users/web/g/platform-clone/node_modules/@babel/core/lib/parser/index.js:41:34)
at parser.next (<anonymous>)
at normalizeFile (/Users/web/g/platform-clone/node_modules/@babel/core/lib/transformation/normalize-file.js:64:37)
at normalizeFile.next (<anonymous>)
at run (/Users/web/g/platform-clone/node_modules/@babel/core/lib/transformation/index.js:21:50)
at run.next (<anonymous>)
at transform (/Users/web/g/platform-clone/node_modules/@babel/core/lib/transform.js:22:33)
at transform.next (<anonymous>)
at step (/Users/web/g/platform-clone/node_modules/gensync/index.js:261:32)
at /Users/web/g/platform-clone/node_modules/gensync/index.js:273:13
at async.call.result.err.err (/Users/web/g/platform-clone/node_modules/gensync/index.js:223:11)
platform-clone/webapp 1 %
It would be greatly appreciated if an update came in sooner than later.
Can you please add documentation for how to create and use themes?
Talking about this page here: https://macaron.js.org/docs/dynamic-styling
It claims that colorVar
would produce a string like --my-var
, but instead it produces var(--my-var)
, which when passed as a style prop, would result in:
<span style={{ [colorVar]: '123px' }}></span>
<span style="var(--my-var): 123px"></span>
Which is obviously wrong and wont work.
To fix this, createVar
should return only the variable name without the var()
wrap, perhaps something like:
const { varDeclaration, varName } = createVar();
// varDeclaration: var(--my-var)
// varName: --my-var
I know that with vanilla-extract it is not possible to use child element selectors when defining the styles, e.g.:
export const myList = style({
position: 'relative',
display: 'block',
listStyle: 'none',
color: 'inherit',
'> li': {
padding: '1rem',
}
})
Is it possible to accomplish something like this in macaron or does it have the same limitation?
Having to write a separate style for each child selector is IMHO a lot of boilerplate and it defeats the purpose of cascade style sheets.
EDIT: moved to discussions #34
When you do:
const MyComponent = ({ customProp }: { customProp: Whatever }) => {...}
const StyledMyComponent = styled(MyComponent as any, {...});
<StyledMyComponent customProp={...} />
The prop customProp
will throw a type error saying:
Type '{ customProp: Whatever; }' is not assignable to type 'IntrinsicAttributes & ChildrenProp & RefAttributes'.
Macaron's Vite plugin seems to be using a deprected version of their API,
The CJS build of Vite's Node API is deprecated. See https://vitejs.dev/guide/troubleshooting.html#vite-cjs-node-api-deprecated for more details.
Macaron has an amazing macro engine! Can it be tweaked to insert the generated styles into a predefiend point in a source file?
This is desirable when developing web components (custom elements) since usually authors want/need the styles to be inlied within the shadow dom. Was thinking of something like,
function Root() {
return <>
<style>MACARON_INLINE_STYLES</style>
<div>{restOfTheComponent}</div>
</>
}
When building with Vite, the final step would be to insert the styles in the style tag above rather than generate a css file.
Solid.js provides a great experience building web components user their solid-element
package, all that's missing is a lib that can support injecting styles into the output, since css files aren't as easy to distribute as as self-contained custom element.
If macaron can pull this off, solid + macaron would be a killer combo for all things web components related. Could this be done?
Hey, I saw all these issues #52 #49 #36
Example doesn't work properly and show an error
Warning: Unsupported style property var(--_1dagh370). Did you mean var(-_1dagh370)?
The I tried to import assignInlineVars
but I couldn't
import { assignInlineVars } from "@macaron-css/core/dynamic";
Did I do something wrong?
"@macaron-css/core": "^1.2.0",
"@macaron-css/react": "^1.4.0",
"@macaron-css/vite": "^1.4.3",
I'm currently experimenting with macaron in my vite project and really like it so far ๐ช
I'm having sourcemaps enabled via build -> sourcemap -> "hidden" option in vite.config.ts. When building for production, I getting a couple of (warning) messages in my console:
Sourcemap is likely to be incorrect: a plugin (macaron-css-vite) was used to transform files, but didn't generate a sourcemap for the transformation. Consult the plugin documentation for help
This already fixed vanilla-extract issue is related I think: vanilla-extract-css/vanilla-extract#699
Can macaron suppress those warnings also?
To reproduce, see this Stackblitz example (modified react example from macarons homepage)
Hello,
It seems there is not way to create and use @keyframes
for animation. Could you take a look at this feature?
macaron extracts every style declaration out of the current file into a separate virtual file and adds imports for those declarations in the source file. It works like this:
// main.ts
const red = style({ color: 'red' })
and this gets compiled into
// main.ts
import { red } from 'extracted_HASH.css.ts'
// extracted_HASH.css.ts
const red = style({ color: 'red' });
module.exports = { red }
The issue that this currently has is that it doesn't check the scope of these variables and just moves them. This means that if there is a variable red
in the top scope and then another variable red
in a function scope, it wouldn't rename them in the virtual file to prevent conflict and consider them to be the same style declaration
I'm trying to run macaron inside Astro project within Solid component. So I placed it inside Astro's vite config, plugins array.
but getting an error:
[vite] Internal server error: ENOENT: no such file or directory, open 'astro:scripts/before-hydration.js'
Plugin: macaron-css-vite
File: astro:scripts/before-hydration.js
Hi! Sorry in advance if you find this confusing, my first ever issue on platform.
I came across your project from this dicussion and i love Stitches but sadly they're no longer maintained.
So, i don't find this issue #36 (this one to be specific) as a solved issue. Because you state that style={assignInlineVars({ [colorVar]: val })}
was exported in v1.2.0. But still can't find that in import option and so the dynamic docs is still broken to me.
Maybe you have some tutorial or example for the usage of createVar() in action? or updated docs for this case. That would be great! Thanks!
Using VE directly allows usage of Sprinkles which dramatically reduces friction of usage, is this planned or possible to use with macaron?
First of all, thank you so much for making this library, great stuff!
Is there currently a way to get Styled Component variant type definitions? Not sure if I am doing something wrong. Take a simple button using the traditional Vanilla Extract Recipe.
const ButtonWithRecipe = recipe({
base: {
backgroundColor: 'gainsboro',
borderRadius: '9999px',
},
variants: {
sm: { padding: '12px' },
md: { padding: '16px' },
},
});
//When using the RecipeVariants import the correct type is returned
export type ButtonRecipeVariants = RecipeVariants<typeof ButtonWithRecipe>;
When recreating that same thing as a Styled Component I am having trouble getting the correct type definitions.
const StyledButton = styled('button', {
base: {
backgroundColor: 'gainsboro',
borderRadius: '9999px',
fontSize: '13px',
border: '0',
},
variants: {
sm: { padding: '12px' },
md: { padding: '16px' },
},
});
//I am able to get type definitions for the _entire_ component including DOM props with the following,
export type WithDOMProps = React.ComponentProps<typeof StyledButton>;
//With the provided StyleVariants import the style always returns "type StyledButtonVariants = unknown"
export type StyledButtonVariants = StyleVariants<typeof ButtonWithRecipe>;
Hi want to make ui framework that supports react soild and qwik
When using vite build --watch
, the initial build works, but if you change the files to re-trigger a build, Macaron style generation will fail with the following error:
[commonjs] Could not load /home/projects/vitejs-vite-ggwk6m/src/extracted_1bkv64o.css.ts: ENOENT: no such file or directory, open '/home/projects/vitejs-vite-ggwk6m/src/extracted_1bkv64o.css.ts'
Repro repo:
Steps to test:
yarn build
We are working on a component library that uses Stitches, and analyzing alternatives we found this great library. I'm now making a POC to see if it covers all our use cases.
The particular case I want to cover now is using responsive variants, so for something like this:
const Box = styled("div", {
variants: { d: { flex: { display: "flex" }, grid: { display: "grid" } } },
});
We usually do:
<Box d={{ '@initial': 'flex', '@md': 'grid'}} />
Would it be possible to support this API? If not, what would be the best way to accomplish the same?
My understanding right now is that I would need to avoid using the styled
API with the variants inside and replace it by Sprinkles from VE, but I'm wondering if there is something I'm missing.
Thanks.
Starting from the example of the documentation, I was not able to use correctly the createVar
utility.
Here a small reproduction:
https://stackblitz.com/edit/macaron-css-macaron-ib7itb?file=vite.config.ts,index.html,src%2Findex.tsx,src%2FApp.tsx,src%2Fui%2Fbutton.tsx,package.json
In /ui/button.tsx
:
import { createVar, fallbackVar } from '@macaron-css/core';
import { styled } from '@macaron-css/solid';
const colorVar = createVar('debug');
const Button = styled('button', {
base: {
color: fallbackVar(colorVar, 'red'),
border: 'none',
},
});
export function MyButton(props: { color?: string }) {
// output: var(--debug__xxxxxx)
// should be only `--debug__xxxxxx`
console.log(colorVar);
return (
<Button
style={{
[colorVar]: props.color,
// ["--debug__xxxxxx"]: "blue" <-- this would work
}}
>
Click me
</Button>
);
}
colorVar
returns var(--debug__xxxxxx)
(invalid syntax) instead of var(--debug__xxxxxx)
. Did I misunderstand something?
Hey, thanks for making the library.
I've been using Macaron plugin with Vite in a medium size TS Monorepo project with a React Project. After introducing the plugin library to Vite project I've noticed my hot reload times have increased substantially to 30-60 secs.
These hot reload times are bigger than when I used library such as Chakra UI with Vite in the past. To be truthful, I'm no expert in debugging hot reload speed problem but from what I can see in my network tab, the lag in web-page rendering is when the macaron plugin transpiles code.
Packages
"vite": "^3.0.9"
"@vitejs/plugin-react": "1.3.2"
"@macaron-css/core": "^0.1.10"
"@macaron-css/react": "^0.1.10"
"@macaron-css/vite": "^0.1.12"
My current Vite config
import { defineConfig } from 'vite';
import { macaronVitePlugin } from '@macaron-css/vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [macaronVitePlugin(), react()],
server: {
port: 3000
},
build: {
target: 'esnext'
},
optimizeDeps: {
esbuildOptions: { preserveSymlinks: true }
}
});
Can you offer any tips or suggestions to get the hot reload times down?
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.