{"id":13723246,"url":"https://github.com/wmertens/styled-vanilla-extract","last_synced_at":"2025-04-07T13:06:17.829Z","repository":{"id":63573034,"uuid":"562604625","full_name":"wmertens/styled-vanilla-extract","owner":"wmertens","description":"A 0-runtime styled-components-like API for Qwik using vanilla-extract.","archived":false,"fork":false,"pushed_at":"2024-07-15T09:35:31.000Z","size":1580,"stargazers_count":127,"open_issues_count":4,"forks_count":9,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-04-06T06:34:21.944Z","etag":null,"topics":["css-in-js","hacktoberfest","qwik","styled-components","vanilla-extract"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wmertens.png","metadata":{"files":{"readme":"README.md","changelog":"Changelog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-06T21:02:13.000Z","updated_at":"2025-04-02T14:46:51.000Z","dependencies_parsed_at":"2023-07-16T00:02:37.066Z","dependency_job_id":"bc4d73a7-303e-4fd3-9863-cccdb0fafda5","html_url":"https://github.com/wmertens/styled-vanilla-extract","commit_stats":{"total_commits":48,"total_committers":2,"mean_commits":24.0,"dds":0.02083333333333337,"last_synced_commit":"efa92bb39276ddab51de6b792dee051b5abe6664"},"previous_names":["wmertens/qwik-styled-ve"],"tags_count":27,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wmertens%2Fstyled-vanilla-extract","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wmertens%2Fstyled-vanilla-extract/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wmertens%2Fstyled-vanilla-extract/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wmertens%2Fstyled-vanilla-extract/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wmertens","download_url":"https://codeload.github.com/wmertens/styled-vanilla-extract/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247445691,"owners_count":20939953,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["css-in-js","hacktoberfest","qwik","styled-components","vanilla-extract"],"created_at":"2024-08-03T01:01:37.746Z","updated_at":"2025-04-07T13:06:17.804Z","avatar_url":"https://github.com/wmertens.png","language":"TypeScript","funding_links":[],"categories":["Made for Vanilla Extract","TypeScript"],"sub_categories":[],"readme":"# Styled Vanilla-Extract ⚡️💅\n\nThis provides a [Styled-Components](https://styled-components.com/)-like (SC) API for Qwik, using [vanilla-extract](https://vanilla-extract.style/) (VE) and [stylis](https://stylis.js.org/).\nThis combination yields a type-checked 0-runtime CSS-in-TS project.\n\n**Try it out now on 👉 [StackBlitz](https://stackblitz.com/edit/styled-vanilla-extract-playground) 👈.**\n\nExample:\n\n- styles.css.ts:\n\n  ```tsx\n  import {styled} from 'styled-vanilla-extract/qwik'\n\n  export const RedText = styled.span`\n    color: red;\n  `\n  ```\n\ngets converted at build time to\n\n- styles.css.ts.vanilla.css:\n\n  ```css\n  .werasf1 {\n    color: red;\n  }\n  ```\n\n- styles.css.ts.vanilla.js:\n\n  ```js\n  import './styles.css.ts.vanilla.css'\n  import {styled as _spofw} from 'styled-vanilla-extract/qwik-styled'\n\n  export var RedText = _spofw('span', 'werasf1')\n  ```\n\n`RedText` is a Qwik Lite component ready for use, and the CSS will be included by Qwik automatically.\n\nType-checking happens automatically thanks to the fact that the source file is a `.ts` file (you can use plain js too) and all helpers have proper typing.\n\n## Installation\n\n### Automatically\n\nRun `npx @builder.io/qwik add styled-vanilla-extract`.\n\n### Manually\n\nInstall the needed NPM modules; they can be dev dependencies because Qwik will bundle them correctly for client and server.\n\n```sh\nnpm i -D styled-vanilla-extract @vanilla-extract/css\n```\n\nThen, add the Vite plugin to your `vite.config.ts`, for example:\n\n```js\nimport {defineConfig} from 'vite'\nimport {qwikVite} from '@builder.io/qwik/optimizer'\nimport {qwikCity} from '@builder.io/qwik-city/vite'\nimport tsconfigPaths from 'vite-tsconfig-paths'\n// ---------------- ADD THIS ----------------\nimport {vanillaExtractPlugin} from 'styled-vanilla-extract/vite'\n\nexport default defineConfig(() =\u003e {\n  const cfg = {\n    build: {sourcemap: true},\n    plugins: [\n      qwikCity(),\n      qwikVite(),\n      tsconfigPaths(),\n      // ---------------- ADD THIS ----------------\n      // This has to come somewhere after qwikVite, or the exports break\n      vanillaExtractPlugin(),\n    ],\n  }\n  return cfg\n})\n```\n\nThen, check if your editor has styled-components support. For example, VS Code has [vscode-styled-components](https://marketplace.visualstudio.com/items?itemName=styled-components.vscode-styled-components).\n\n## Usage\n\nThis library is complementary to vanilla-extract, so head over to the [vanilla-extract docs](https://vanilla-extract.style/documentation/getting-started#create-a-style) to learn the basics.\n\n### styled\n\nYou use `styled` to create Qwik components that you can import. This uses the same configuration objects as the vanilla-extract `style()` function:\n\nheader.css.ts:\n\n```ts\nimport {style, styled} from 'styled-vanilla-extract/qwik'\n\n// Local classname that makes things fancy\nexport const fancy = style({})\n\n// Header: a Qwik Lite Component\nexport const Header = styled.header({\n  padding: '0.5em',\n  border: 'thin solid var(--color-hint)',\n  borderBottom: 'none',\n  selectors: {\n    [`${fancy} \u0026, ${fancy}\u0026`]: {\n      background: 'gold',\n    },\n  },\n})\n```\n\nheader.tsx:\n\n```tsx\nimport {Header, fancy} from './header.css'\n\nexport default component$(() =\u003e {\n  // do header stuff\n  return (\n    \u003cHeader class={isFancy \u0026\u0026 fancy}\u003e\n      Header, possibly fancy.\n      \u003cbr /\u003e\n      The classname it uses is {Header.class}.\n    \u003c/Header\u003e\n  )\n})\n```\n\n### css\n\nThere's also `css` template string helper to convert CSS syntax to vanilla-extract syntax. You can use it anywhere that accepts vanilla-extract style objects:\n\nheader.css.ts:\n\n```ts\nimport {style, styled, css} from 'styled-vanilla-extract/qwik'\n\n// Local classname\nexport const fancy = style({})\n\n// Header: a Qwik Lite Component\nexport const Header = styled.h1(css`\n  padding: 0.5em;\n  border: thin solid var(--color-hint);\n  border-bottom: none;\n  ${fancy} \u0026, ${fancy}\u0026: {\n    background: gold;\n  }\n`)\n```\n\n### combined\n\nBoth `style` and `styled` can be used as tagged template functions, so the above can also be written as\n\nheader.css.ts:\n\n```ts\nimport {style, styled} from 'styled-vanilla-extract/qwik'\n\nexport const Fancy = style``\n\n// Header: a Qwik Lite Component\nexport const Header = styled.h1`\n  padding: 0.5em;\n  border: thin solid var(--color-hint);\n  border-bottom: none;\n  ${fancy} \u0026, ${fancy}\u0026: {\n    background: gold;\n  }\n`\n```\n\n## Only emitting styles you use\n\nBy default, the CSS you create will be emitted in a .css file that your html will load.\n\nYou can instead get the CSS as a string that you then give to Qwik's `useStyles$()`. To do this, you must have a default export in your definition:\n\nheader.css.ts:\n\n```ts\nimport {styled} from 'styled-vanilla-extract/qwik'\n\n// This will be replaced with the CSS\nexport default ''\n\n// Header: a Qwik Lite Component\nexport const Header = styled.h1`\n  padding: 0.5em;\n  border: thin solid var(--color-hint);\n  border-bottom: none;\n`\n```\n\nHeader.tsx:\n\n```tsx\nimport {component$, useStyles$} from '@builder.io/qwik'\nimport style, {Header} from './header.css'\n\nexport default component$(() =\u003e {\n  useStyles$(style)\n\n  return \u003cHeader\u003eI'm styled!\u003c/Header\u003e\n})\n```\n\nThis has the advantage that your initial HTML includes only the styles you actually use, and they are inline, which reduces lag.\nIf you are building a Single Page Application, this is most likely what you want.\n\n## Notes\n\n- All styles you create in a css.ts file are included in the CSS output. They do not get tree-shaken, unlike the exported identifiers. This is vanilla-extract behavior.\n- Qwik doesn't do hot reloading at the moment. It also has problems with changing .css files. You might have to reload the page manually sometimes to get styles to apply.\n\n## Migrating from Styled Components\n\nSeveral features are not supported because they are impossible as 0-runtime, or don't make sense in Qwik.\n\n### Replacing function interpolation\n\nInstead of embedding a function in your CSS like `` `color: ${p =\u003e p.error ? 'red':'black'}` ``, you should use extra classes, inline styles, CSS variables, or a combination thereof. Any option is easy to implement with Qwik.\n\n```tsx\nimport {Text, showError} from './component.css'\n\n// ... hasError is a boolean\n// Object of classnames and booleans\n\u003cText class={{[showError]: hasError}}\u003etext\u003c/Text\u003e\n// Class string\n\u003cText class={hasError \u0026\u0026 showError}\u003etext\u003c/Text\u003e\n// Style object\n\u003cText style={{color: hasError ? 'red' : 'black'}}\u003etext\u003c/Text\u003e\n// CSS variable that you use in your CSS\n\u003cText style={{\"--color-hint\": hasError ? 'red' : 'black'}}\u003etext\u003c/Text\u003e\n```\n\n### Replacing themes\n\nUse CSS variables instead. They are supported in all relevant browsers.\n\nYou can also import any code you like to create the CSS at build time, there are no restrictions, go wild!\n\nVanilla-extract also has nice helper projects for this purpose, [Sprinkles](https://vanilla-extract.style/documentation/packages/sprinkles/) and [Recipes](https://vanilla-extract.style/documentation/packages/recipes/).\n\n### Extending a component\n\nA QwikStyledComponent can be passed to `style` and `styled` to\nInstead of using an existing component to build on, compose the styles that vanilla-extract generates:\n\n```ts\nimport {styled, css} from 'styled-vanilla-extract'\n\nconst Button = styled.button`\n  text-size: 3em;\n`\n\nexport const RedButton = styled.button([\n  Button,\n  css`\n    background-color: red;\n  `,\n])\n```\n\n### Use `as` another tag, extending another component, adding props\n\nThings like `const Foo = styled(Bar).as('ul').props(...)` make the API more complex and are not (yet) supported.\n\nThis library aims to stay lean, but if DX can be improved new features will be considered.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwmertens%2Fstyled-vanilla-extract","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwmertens%2Fstyled-vanilla-extract","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwmertens%2Fstyled-vanilla-extract/lists"}