├── website ├── docs │ ├── tailwind.md │ ├── under-the-hood.md │ ├── style-any-component.md │ ├── install.md │ ├── media-queries.md │ ├── global.md │ ├── styled-components.md │ ├── theming.md │ ├── pseudo-elements.md │ ├── with-props.md │ ├── keyframes.md │ ├── component-selector.md │ ├── override-component-style.md │ ├── auto-prefixing.md │ ├── using-as-prop.md │ ├── labels.md │ ├── nested-selectors.md │ ├── preact.md │ ├── create-react-app.md │ ├── docs.yaml │ ├── todo.md │ ├── CSS.md │ ├── gatsby.md │ ├── nextjs.md │ └── server-side-rendering.md ├── gatsby-browser.js ├── .babelrc.json ├── plugins │ └── gatsby-remark-live-code │ │ ├── package.json │ │ └── index.js ├── src │ ├── pages │ │ ├── 404.js │ │ └── index.js │ ├── images │ │ └── icons │ │ │ ├── close.svg │ │ │ ├── hamburger.svg │ │ │ ├── theme.svg │ │ │ ├── github.svg │ │ │ └── twitter.svg │ ├── components │ │ ├── StaticCode.jsx │ │ ├── Code.jsx │ │ ├── markdown-overrides.js │ │ ├── Header.jsx │ │ ├── Playground.jsx │ │ ├── Editor.jsx │ │ ├── Sidebar.jsx │ │ └── Layout.jsx │ ├── themes │ │ ├── utils.js │ │ └── hook.js │ ├── html.js │ └── templates │ │ ├── package.js │ │ └── doc.js ├── docs-yaml.js ├── LICENSE ├── .gitignore ├── package.json ├── gatsby-config.js └── CHANGELOG.md ├── benchmarks ├── size │ ├── emotion │ │ ├── .env │ │ ├── public │ │ │ ├── robots.txt │ │ │ ├── favicon.ico │ │ │ ├── logo192.png │ │ │ ├── logo512.png │ │ │ ├── manifest.json │ │ │ └── index.html │ │ ├── src │ │ │ ├── setupTests.js │ │ │ ├── App.test.js │ │ │ ├── css-in-js.js │ │ │ ├── index.js │ │ │ ├── App.js │ │ │ └── logo.svg │ │ ├── .gitignore │ │ ├── package.json │ │ └── README.md │ ├── filbert │ │ ├── .env │ │ ├── public │ │ │ ├── robots.txt │ │ │ ├── favicon.ico │ │ │ ├── logo192.png │ │ │ ├── logo512.png │ │ │ ├── manifest.json │ │ │ └── index.html │ │ ├── src │ │ │ ├── setupTests.js │ │ │ ├── App.test.js │ │ │ ├── css-in-js.js │ │ │ ├── index.js │ │ │ ├── App.js │ │ │ └── logo.svg │ │ ├── .gitignore │ │ ├── package.json │ │ ├── CHANGELOG.md │ │ └── README.md │ ├── vanilla-css │ │ ├── .env │ │ ├── public │ │ │ ├── robots.txt │ │ │ ├── favicon.ico │ │ │ ├── logo192.png │ │ │ ├── logo512.png │ │ │ ├── manifest.json │ │ │ └── index.html │ │ ├── src │ │ │ ├── setupTests.js │ │ │ ├── App.test.js │ │ │ ├── index.js │ │ │ ├── App.js │ │ │ ├── App.css │ │ │ └── logo.svg │ │ ├── .gitignore │ │ ├── package.json │ │ └── README.md │ ├── styled-components │ │ ├── .env │ │ ├── public │ │ │ ├── robots.txt │ │ │ ├── favicon.ico │ │ │ ├── logo192.png │ │ │ ├── logo512.png │ │ │ ├── manifest.json │ │ │ └── index.html │ │ ├── src │ │ │ ├── setupTests.js │ │ │ ├── App.test.js │ │ │ ├── css-in-js.js │ │ │ ├── index.js │ │ │ ├── App.js │ │ │ └── logo.svg │ │ ├── .gitignore │ │ ├── package.json │ │ └── README.md │ └── bundle-size │ │ ├── package.json │ │ ├── capture-sizes.js │ │ └── delta.js └── performance │ ├── package.json │ ├── CHANGELOG.md │ └── index.js ├── packages ├── gatsby-plugin-filbert │ ├── index.js │ ├── gatsby-node.js │ ├── README.md │ ├── gatsby-browser.js │ ├── gatsby-ssr.js │ ├── package.json │ └── CHANGELOG.md ├── core │ ├── index.js │ ├── src │ │ ├── Global.js │ │ ├── hash.js │ │ ├── factory.js │ │ ├── core.js │ │ ├── interpolate.js │ │ ├── hooks.js │ │ └── styled.js │ ├── README.md │ ├── package.json │ └── CHANGELOG.md ├── css-ast │ ├── constants.js │ ├── index.js │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ └── ast.js ├── types │ ├── README.md │ ├── CHANGELOG.md │ ├── index.js │ └── package.json ├── css-parser │ ├── README.md │ ├── CHANGELOG.md │ ├── package.json │ └── index.js ├── autoprefixer │ ├── README.md │ ├── CHANGELOG.md │ ├── package.json │ └── index.js ├── theming │ ├── index.js │ ├── CHANGELOG.md │ ├── README.md │ └── package.json ├── macro │ ├── CHANGELOG.md │ ├── README.md │ ├── index.js │ └── package.json ├── style-sheet-context │ ├── README.md │ ├── index.js │ ├── CHANGELOG.md │ └── package.json ├── babel-plugin-filbert │ ├── CHANGELOG.md │ ├── README.md │ └── package.json ├── stylesheet │ ├── CHANGELOG.md │ ├── README.md │ ├── package.json │ └── index.js ├── browser-stylesheet │ ├── README.md │ ├── CHANGELOG.md │ ├── package.json │ └── index.js └── server-stylesheet │ ├── README.md │ ├── CHANGELOG.md │ └── package.json ├── filbert.png ├── filbert-arch.png ├── .prettierignore ├── filbert-benchmark-ssr.png ├── filbert-benchmark-deep-tree.png ├── filbert-benchmark-wide-tree.png ├── filbert-benchmark-dynamic-styles.png ├── .travis.yml ├── lerna.json ├── .vscode ├── extensions.json ├── launch.json └── settings.json ├── .prettierrc.yaml ├── .changeset ├── config.json └── README.md ├── .github ├── workflows │ ├── pr_build.yml │ ├── benchmark.yml │ ├── size.yml │ └── release.yml ├── FUNDING.yml ├── dependabot.yml └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── SECURITY.md ├── .codesandbox └── ci.json ├── LICENSE ├── .gitignore ├── CONTRIBUTING.md ├── .all-contributorsrc ├── package.json └── filbert.svg /website/docs/tailwind.md: -------------------------------------------------------------------------------- 1 | WIP 2 | -------------------------------------------------------------------------------- /benchmarks/size/emotion/.env: -------------------------------------------------------------------------------- 1 | SKIP_PREFLIGHT_CHECK=true -------------------------------------------------------------------------------- /benchmarks/size/filbert/.env: -------------------------------------------------------------------------------- 1 | SKIP_PREFLIGHT_CHECK=true -------------------------------------------------------------------------------- /packages/gatsby-plugin-filbert/index.js: -------------------------------------------------------------------------------- 1 | //no-op 2 | -------------------------------------------------------------------------------- /benchmarks/size/vanilla-css/.env: -------------------------------------------------------------------------------- 1 | SKIP_PREFLIGHT_CHECK=true -------------------------------------------------------------------------------- /benchmarks/size/styled-components/.env: -------------------------------------------------------------------------------- 1 | SKIP_PREFLIGHT_CHECK=true -------------------------------------------------------------------------------- /website/gatsby-browser.js: -------------------------------------------------------------------------------- 1 | import './src/themes/theme.css'; 2 | -------------------------------------------------------------------------------- /filbert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuldeepkeshwar/filbert-js/HEAD/filbert.png -------------------------------------------------------------------------------- /filbert-arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuldeepkeshwar/filbert-js/HEAD/filbert-arch.png -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | .cache 2 | package.json 3 | package-lock.json 4 | public 5 | dist 6 | node_modules 7 | *.log -------------------------------------------------------------------------------- /filbert-benchmark-ssr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuldeepkeshwar/filbert-js/HEAD/filbert-benchmark-ssr.png -------------------------------------------------------------------------------- /benchmarks/size/emotion/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /benchmarks/size/filbert/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /filbert-benchmark-deep-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuldeepkeshwar/filbert-js/HEAD/filbert-benchmark-deep-tree.png -------------------------------------------------------------------------------- /filbert-benchmark-wide-tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuldeepkeshwar/filbert-js/HEAD/filbert-benchmark-wide-tree.png -------------------------------------------------------------------------------- /benchmarks/size/vanilla-css/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /benchmarks/size/styled-components/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /filbert-benchmark-dynamic-styles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuldeepkeshwar/filbert-js/HEAD/filbert-benchmark-dynamic-styles.png -------------------------------------------------------------------------------- /website/.babelrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-react"], 3 | "plugins": ["@babel/plugin-proposal-class-properties"] 4 | } 5 | -------------------------------------------------------------------------------- /benchmarks/size/emotion/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuldeepkeshwar/filbert-js/HEAD/benchmarks/size/emotion/public/favicon.ico -------------------------------------------------------------------------------- /benchmarks/size/emotion/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuldeepkeshwar/filbert-js/HEAD/benchmarks/size/emotion/public/logo192.png -------------------------------------------------------------------------------- /benchmarks/size/emotion/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuldeepkeshwar/filbert-js/HEAD/benchmarks/size/emotion/public/logo512.png -------------------------------------------------------------------------------- /benchmarks/size/filbert/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuldeepkeshwar/filbert-js/HEAD/benchmarks/size/filbert/public/favicon.ico -------------------------------------------------------------------------------- /benchmarks/size/filbert/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuldeepkeshwar/filbert-js/HEAD/benchmarks/size/filbert/public/logo192.png -------------------------------------------------------------------------------- /benchmarks/size/filbert/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuldeepkeshwar/filbert-js/HEAD/benchmarks/size/filbert/public/logo512.png -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '10' 4 | cache: 5 | directories: 6 | - node_modules 7 | notifications: 8 | email: false 9 | -------------------------------------------------------------------------------- /benchmarks/size/vanilla-css/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuldeepkeshwar/filbert-js/HEAD/benchmarks/size/vanilla-css/public/favicon.ico -------------------------------------------------------------------------------- /benchmarks/size/vanilla-css/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuldeepkeshwar/filbert-js/HEAD/benchmarks/size/vanilla-css/public/logo192.png -------------------------------------------------------------------------------- /benchmarks/size/vanilla-css/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuldeepkeshwar/filbert-js/HEAD/benchmarks/size/vanilla-css/public/logo512.png -------------------------------------------------------------------------------- /benchmarks/size/styled-components/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuldeepkeshwar/filbert-js/HEAD/benchmarks/size/styled-components/public/favicon.ico -------------------------------------------------------------------------------- /benchmarks/size/styled-components/public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuldeepkeshwar/filbert-js/HEAD/benchmarks/size/styled-components/public/logo192.png -------------------------------------------------------------------------------- /benchmarks/size/styled-components/public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kuldeepkeshwar/filbert-js/HEAD/benchmarks/size/styled-components/public/logo512.png -------------------------------------------------------------------------------- /packages/core/index.js: -------------------------------------------------------------------------------- 1 | export { Global } from './src/Global'; 2 | export { styled } from './src/styled'; 3 | 4 | export { keyframes, css, jsx } from './src/core'; 5 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "npmClient": "yarn", 3 | "useWorkspaces": true, 4 | "version": "independent", 5 | "repository": "https://github.com/kuldeepkeshwar/filbert-js" 6 | } 7 | -------------------------------------------------------------------------------- /packages/css-ast/constants.js: -------------------------------------------------------------------------------- 1 | export const RULE_END = ';'; 2 | export const RULE_SEPARATOR = ':'; 3 | export const OPEN_BRACKET = `{`; 4 | export const CLOSE_BRACKET = `}`; 5 | -------------------------------------------------------------------------------- /packages/css-ast/index.js: -------------------------------------------------------------------------------- 1 | export { 2 | CLOSE_BRACKET, 3 | OPEN_BRACKET, 4 | RULE_END, 5 | RULE_SEPARATOR, 6 | } from './constants'; 7 | export { toAST } from './ast'; 8 | -------------------------------------------------------------------------------- /website/docs/under-the-hood.md: -------------------------------------------------------------------------------- 1 |

2 | filbert 3 |

4 | -------------------------------------------------------------------------------- /packages/gatsby-plugin-filbert/gatsby-node.js: -------------------------------------------------------------------------------- 1 | exports.onCreateBabelConfig = ({ actions }) => { 2 | actions.setBabelPlugin({ 3 | name: `babel-plugin-filbert`, 4 | }); 5 | }; 6 | -------------------------------------------------------------------------------- /website/plugins/gatsby-remark-live-code/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-remark-live-code", 3 | "version": "0.0.1", 4 | "repository": "https://github.com/kuldeepkeshwar/filbert-js" 5 | } 6 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "editorconfig.editorconfig", 4 | "dbaeumer.vscode-eslint", 5 | "esbenp.prettier-vscode", 6 | "amatiasq.sort-imports" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /.prettierrc.yaml: -------------------------------------------------------------------------------- 1 | tabWidth: 2 2 | semi: true 3 | singleQuote: true 4 | trailingComma: all 5 | arrowParens: always 6 | overrides: 7 | - files: website/docs/*.md 8 | options: 9 | printWidth: 100 10 | -------------------------------------------------------------------------------- /packages/types/README.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/types 2 | 3 | > types for filbert-js. 4 | 5 | ## Install 6 | 7 | ```bash 8 | yarn add @filbert-js/types 9 | ``` 10 | 11 | More documentation is available at https://filbert-js.vercel.app. 12 | -------------------------------------------------------------------------------- /packages/css-parser/README.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/css-parser 2 | 3 | > css parser for filbert-js. 4 | 5 | ## Install 6 | 7 | ```bash 8 | yarn add @filbert-js/css-parser 9 | ``` 10 | 11 | More documentation is available at https://filbert-js.vercel.app. 12 | -------------------------------------------------------------------------------- /packages/autoprefixer/README.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/autoprefixer 2 | 3 | > autoprefixer for filbert-js. 4 | 5 | ## Install 6 | 7 | ```bash 8 | yarn add @filbert-js/autoprefixer 9 | ``` 10 | 11 | More documentation is available at https://filbert-js.vercel.app. 12 | -------------------------------------------------------------------------------- /website/src/pages/404.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const NotFoundPage = () => ( 4 | <> 5 |

NOT FOUND

6 |

You just hit a route that doesn't exist... the sadness.

7 | 8 | ); 9 | 10 | export default NotFoundPage; 11 | -------------------------------------------------------------------------------- /packages/types/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/types 2 | 3 | ## 0.0.6 4 | 5 | ### Patch Changes 6 | 7 | - 985f0e3: reuse filbert-types/merge type+label 8 | 9 | ## 0.0.5 10 | 11 | ### Patch Changes 12 | 13 | - 0ef9584: - Add `as` Prop 14 | - Add `forward ref` 15 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "node", 6 | "request": "attach", 7 | "name": "Launch Program", 8 | "skipFiles": ["/**"], 9 | "port": 9229 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /packages/autoprefixer/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/autoprefixer 2 | 3 | ## 0.0.6 4 | 5 | ### Patch Changes 6 | 7 | - e4ecedd: replace tiny-css-prefixer with style-vendorizer 8 | 9 | ## 0.0.5 10 | 11 | ### Patch Changes 12 | 13 | - 0ef9584: - Add `as` Prop 14 | - Add `forward ref` 15 | -------------------------------------------------------------------------------- /packages/theming/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export const ThemeContext = React.createContext(); 4 | 5 | export const ThemeProvider = ({ theme, children }) => { 6 | return ( 7 | {children} 8 | ); 9 | }; 10 | -------------------------------------------------------------------------------- /benchmarks/size/bundle-size/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "benchmarks-bundle-size", 3 | "version": "0.0.4", 4 | "private": true, 5 | "dependencies": { 6 | "react-scripts": "4.0.1" 7 | }, 8 | "scripts": { 9 | "print-delta": "node ./delta.js" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /benchmarks/size/emotion/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom/extend-expect'; 6 | -------------------------------------------------------------------------------- /benchmarks/size/filbert/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom/extend-expect'; 6 | -------------------------------------------------------------------------------- /website/src/images/icons/close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /benchmarks/size/vanilla-css/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom/extend-expect'; 6 | -------------------------------------------------------------------------------- /website/src/images/icons/hamburger.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /benchmarks/size/styled-components/src/setupTests.js: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import '@testing-library/jest-dom/extend-expect'; 6 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@1.3.0/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "linked": [], 6 | "access": "restricted", 7 | "baseBranch": "master", 8 | "updateInternalDependencies": "patch", 9 | "ignore": [] 10 | } -------------------------------------------------------------------------------- /website/docs/style-any-component.md: -------------------------------------------------------------------------------- 1 | ```jsx editor=live 2 | import React from 'react'; 3 | import { styled } from '@filbert-js/core'; 4 | 5 | const Text = ({ className }) =>

Some text

; 6 | 7 | const PinkText = styled(Text)` 8 | color: hotpink; 9 | `; 10 | render(); 11 | ``` 12 | -------------------------------------------------------------------------------- /website/src/components/StaticCode.jsx: -------------------------------------------------------------------------------- 1 | import { Editor } from './Editor'; 2 | import React from 'react'; 3 | import { Stack } from 'layout-ui'; 4 | 5 | export default ({ code, compiled }) => { 6 | return ( 7 | 8 | 9 | 10 | ); 11 | }; 12 | -------------------------------------------------------------------------------- /website/src/images/icons/theme.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /website/docs/install.md: -------------------------------------------------------------------------------- 1 | Installation 2 | 3 | You can install `@filbert-js` from npm or yarn 4 | 5 | ```sh 6 | npm install @filbert-js/core 7 | ``` 8 | 9 | Or 10 | 11 | ```sh 12 | yarn add @filbert-js/core 13 | ``` 14 | 15 | Usage 16 | 17 | ```js editor=static 18 | import { styled, Global, keyframes } from '@filbert-js/core'; 19 | ``` 20 | -------------------------------------------------------------------------------- /website/src/pages/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default () => { 4 | React.useEffect(() => { 5 | window.location = '/docs/introduction'; 6 | }, []); 7 | return ( 8 |
9 |
loading..
10 |
redirecting you to https://filbert-js.vercel.app
11 |
12 | ); 13 | }; 14 | -------------------------------------------------------------------------------- /website/docs-yaml.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const yaml = require('js-yaml'); 4 | const packageYamlPath = path.resolve(__dirname, 'docs/docs.yaml'); 5 | 6 | module.exports = () => { 7 | const yamlString = fs.readFileSync(packageYamlPath).toString(); 8 | 9 | return yaml.safeLoad(yamlString); 10 | }; 11 | -------------------------------------------------------------------------------- /website/docs/media-queries.md: -------------------------------------------------------------------------------- 1 | ```jsx editor=live 2 | import React from 'react'; 3 | import { styled } from '@filbert-js/core'; 4 | 5 | const Paragraph = styled('p')` 6 | color: red; 7 | font-size: 1rem; 8 | @media (min-width: 420px) { 9 | font-size: 3rem; 10 | } 11 | `; 12 | 13 | render(I'm red !!); 14 | ``` 15 | -------------------------------------------------------------------------------- /benchmarks/size/emotion/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders learn react link', () => { 6 | const { getByText } = render(); 7 | const linkElement = getByText(/learn react/i); 8 | expect(linkElement).toBeInTheDocument(); 9 | }); 10 | -------------------------------------------------------------------------------- /benchmarks/size/filbert/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders learn react link', () => { 6 | const { getByText } = render(); 7 | const linkElement = getByText(/learn react/i); 8 | expect(linkElement).toBeInTheDocument(); 9 | }); 10 | -------------------------------------------------------------------------------- /benchmarks/size/vanilla-css/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders learn react link', () => { 6 | const { getByText } = render(); 7 | const linkElement = getByText(/learn react/i); 8 | expect(linkElement).toBeInTheDocument(); 9 | }); 10 | -------------------------------------------------------------------------------- /benchmarks/size/styled-components/src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render } from '@testing-library/react'; 3 | import App from './App'; 4 | 5 | test('renders learn react link', () => { 6 | const { getByText } = render(); 7 | const linkElement = getByText(/learn react/i); 8 | expect(linkElement).toBeInTheDocument(); 9 | }); 10 | -------------------------------------------------------------------------------- /.github/workflows/pr_build.yml: -------------------------------------------------------------------------------- 1 | name: Build Check 2 | 3 | on: [pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v2-beta 11 | with: 12 | fetch-depth: 1 13 | - name: Installing packages 14 | run: yarn 15 | - name: Run build 16 | run: yarn build 17 | -------------------------------------------------------------------------------- /packages/theming/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/theming 2 | 3 | ## 0.0.7 4 | 5 | ### Patch Changes 6 | 7 | - 5ba6c20: fix stylesheet ordering 8 | 9 | ## 0.0.6 10 | 11 | ### Patch Changes 12 | 13 | - b3e80f1: Remove react from dependencies list in core 14 | 15 | ## 0.0.5 16 | 17 | ### Patch Changes 18 | 19 | - 0ef9584: - Add `as` Prop 20 | - Add `forward ref` 21 | -------------------------------------------------------------------------------- /benchmarks/size/filbert/src/css-in-js.js: -------------------------------------------------------------------------------- 1 | export { Global, keyframes, styled } from '@filbert-js/core'; 2 | export { ThemeProvider } from '@filbert-js/theming'; 3 | /** 4 | benchmarks-filbert: 39.86 KB build/static/js/2.af4fabaf.chunk.js 5 | benchmarks-filbert: 3.44 KB build/static/js/main.126bde6f.chunk.js 6 | benchmarks-filbert: 782 B build/static/js/runtime-main.d3cee8d4.js 7 | */ 8 | -------------------------------------------------------------------------------- /.github/workflows/benchmark.yml: -------------------------------------------------------------------------------- 1 | name: Benchmarks(Bundle Size|Performance) 2 | 3 | on: [pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v2-beta 11 | with: 12 | fetch-depth: 1 13 | - name: Installing packages 14 | run: yarn 15 | - name: Run benchmarks 16 | run: yarn benchmarks 17 | -------------------------------------------------------------------------------- /website/docs/global.md: -------------------------------------------------------------------------------- 1 | ```jsx editor=live 2 | import React from 'react'; 3 | import { Global } from '@filbert-js/core'; 4 | 5 | render( 6 | 7 | 15 |
I'm pink
16 |
, 17 | ); 18 | ``` 19 | -------------------------------------------------------------------------------- /packages/core/src/Global.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { TYPES_GLOBAL } from '@filbert-js/types'; 3 | import { useGlobalStylesheet } from './hooks'; 4 | let counter = 0; 5 | export const Global = React.memo(function ({ styles }) { 6 | const [id] = React.useState(() => { 7 | counter++; 8 | return `${TYPES_GLOBAL}-${counter}`; 9 | }); 10 | useGlobalStylesheet(id, styles); 11 | return null; 12 | }); 13 | -------------------------------------------------------------------------------- /packages/types/index.js: -------------------------------------------------------------------------------- 1 | const key = '__styled'; 2 | export const TYPE = Symbol.for(`${key}_type`); 3 | export const TYPES_KEYFRAMES = 'k'; 4 | export const TYPES_GLOBAL = 'g'; 5 | export const TYPES_CSS = 'c'; 6 | 7 | export const RAW = Symbol.for(`${key}_raw`); 8 | 9 | export const IS_STYLED_COMPONENT = Symbol.for(`${key}_is`); 10 | export const SOURCE_ORDER = `${key}_source_order`; 11 | export const LABEL_PREFIX = `fj-`; 12 | -------------------------------------------------------------------------------- /packages/gatsby-plugin-filbert/README.md: -------------------------------------------------------------------------------- 1 | # gatsby-plugin-filbert 2 | 3 | > A Gatsby Plugin for filbert-js. 4 | 5 | ## Install 6 | 7 | ```bash 8 | yarn add gatsby-plugin-filbert 9 | ``` 10 | 11 | ## Usage 12 | 13 | Edit `gatsby-config.js` 14 | 15 | ```js editor=static 16 | module.exports = { 17 | plugins: [`gatsby-plugin-filbert`], 18 | }; 19 | ``` 20 | 21 | More documentation is available at https://filbert-js.vercel.app. 22 | -------------------------------------------------------------------------------- /packages/macro/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/macro 2 | 3 | ## 0.0.3 4 | 5 | ### Patch Changes 6 | 7 | - Updated dependencies [001085a] 8 | - babel-plugin-filbert@0.0.8 9 | 10 | ## 0.0.2 11 | 12 | ### Patch Changes 13 | 14 | - 4affc53: remove pragma annotation dependency 15 | - Updated dependencies [4affc53] 16 | - babel-plugin-filbert@0.0.7 17 | 18 | ## 0.0.1 19 | 20 | ### Patch Changes 21 | 22 | - bdfb060: add @filbert-js/macro 23 | -------------------------------------------------------------------------------- /benchmarks/size/emotion/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /benchmarks/size/filbert/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /packages/style-sheet-context/README.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/style-sheet-context 2 | 3 | > StyleSheet Context for filbert-js 4 | 5 | ## Install 6 | 7 | ```bash 8 | yarn add @filbert-js/style-sheet-context 9 | ``` 10 | 11 | ## Usage 12 | 13 | ```jsx 14 | import { 15 | StyleSheetProvider, 16 | StyleSheetContext, 17 | } from '@filbert-js/style-sheet-context'; 18 | ``` 19 | 20 | More documentation is available at https://filbert-js.vercel.app. 21 | -------------------------------------------------------------------------------- /benchmarks/size/vanilla-css/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /website/docs/styled-components.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 'Styled Components' 3 | --- 4 | 5 | `styled` is a way to create React components that have styles attached to them 6 | 7 | ```jsx editor=live 8 | import React from 'react'; 9 | import { styled } from '@filbert-js/core'; 10 | 11 | const Button = styled('button')` 12 | background: pink; 13 | border: solid 1px gray; 14 | `; 15 | 16 | render(); 17 | ``` 18 | -------------------------------------------------------------------------------- /benchmarks/size/styled-components/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: filbert-js # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | custom: https://www.paypal.me/kuldeepkeshwar 9 | -------------------------------------------------------------------------------- /packages/core/src/hash.js: -------------------------------------------------------------------------------- 1 | //https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript 2 | 3 | const cache = {}; 4 | export function hash(str) { 5 | let hash = cache[str] || 0; 6 | if (!hash) { 7 | for (let i = 0; i < str.length; i++) { 8 | const chr = str.charCodeAt(i); 9 | hash = (hash << 5) - hash + chr; 10 | hash |= 0; // Convert to 32bit integer 11 | } 12 | cache[str] = hash; 13 | } 14 | return hash; 15 | } 16 | -------------------------------------------------------------------------------- /packages/macro/README.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/macro 2 | 3 | A [Babel](https://babeljs.io/) macro for filbert, converts `styled.div` syntax to `styled('div')` calls. 4 | 5 | ## Install 6 | 7 | `npm install --save @filbert-js/macro` 8 | 9 | ## How to use 10 | 11 | ```jsx editor=static 12 | import React from 'react'; 13 | import { styled } from '@filbert-js/macro'; 14 | 15 | const Button = styled.button` 16 | margin: 0; 17 | padding: 1rem; 18 | font-size: 1rem; 19 | background-color: tomato; 20 | `; 21 | ``` 22 | -------------------------------------------------------------------------------- /packages/core/src/factory.js: -------------------------------------------------------------------------------- 1 | import { RAW, TYPE, TYPES_CSS } from '@filbert-js/types'; 2 | 3 | import { hash } from './hash'; 4 | import { interpolate } from './interpolate'; 5 | 6 | export function factory(type = TYPES_CSS, context) { 7 | return function () { 8 | const [css, keyframes] = interpolate.apply(context, arguments); 9 | const selector = `${type}-${hash(css)}`; 10 | return { 11 | [TYPE]: type, 12 | [RAW]: [css, keyframes], 13 | toString: () => selector, 14 | }; 15 | }; 16 | } 17 | -------------------------------------------------------------------------------- /packages/style-sheet-context/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { createStylesheet } from '@filbert-js/browser-stylesheet'; 3 | 4 | // for css API 5 | export let __sheet = createStylesheet(); 6 | 7 | export const StyleSheetContext = React.createContext(__sheet); 8 | 9 | export const StyleSheetProvider = ({ stylesheet, children }) => { 10 | __sheet = stylesheet; 11 | return ( 12 | 13 | {children} 14 | 15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /website/docs/theming.md: -------------------------------------------------------------------------------- 1 | ```jsx editor=live 2 | import React from 'react'; 3 | import { styled } from '@filbert-js/core'; 4 | import { ThemeProvider } from '@filbert-js/theming'; 5 | const Button = styled('button')` 6 | background: ${({ theme }) => theme.colors.brand}; 7 | border: solid 1px gray; 8 | `; 9 | const theme = { 10 | colors: { 11 | brand: 'hotpink', 12 | }, 13 | }; 14 | render( 15 | 16 | 17 | , 18 | ); 19 | ``` 20 | -------------------------------------------------------------------------------- /benchmarks/size/emotion/src/css-in-js.js: -------------------------------------------------------------------------------- 1 | import { Global, keyframes } from '@emotion/core'; 2 | 3 | import { ThemeProvider } from 'emotion-theming'; 4 | import styled from '@emotion/styled'; 5 | 6 | export { Global, keyframes, styled, ThemeProvider }; 7 | /** 8 | benchmarks-emotion: File sizes after gzip: 9 | benchmarks-emotion: 49.15 KB build/static/js/2.a3d99853.chunk.js 10 | benchmarks-emotion: 1.22 KB build/static/js/main.aa8a0bd6.chunk.js 11 | benchmarks-emotion: 780 B build/static/js/runtime-main.8b548c26.js 12 | */ 13 | -------------------------------------------------------------------------------- /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/master/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: 'npm' # See documentation for possible values 9 | directory: '/' # Location of package manifests 10 | schedule: 11 | interval: 'daily' 12 | -------------------------------------------------------------------------------- /benchmarks/size/styled-components/src/css-in-js.js: -------------------------------------------------------------------------------- 1 | import styled, { 2 | ThemeProvider, 3 | createGlobalStyle, 4 | keyframes, 5 | } from 'styled-components'; 6 | 7 | export { createGlobalStyle, keyframes, styled, ThemeProvider }; 8 | /** 9 | benchmarks-styled-components: File sizes after gzip: 10 | benchmarks-styled-components: 51.58 KB build/static/js/2.ab9b68a8.chunk.js 11 | benchmarks-styled-components: 1.23 KB build/static/js/main.1bd05e39.chunk.js 12 | benchmarks-styled-components: 792 B build/static/js/runtime-main.0cd2f5d2.js 13 | */ 14 | -------------------------------------------------------------------------------- /benchmarks/performance/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "benchmarks-performance", 3 | "version": "0.0.14", 4 | "private": true, 5 | "dependencies": { 6 | "@emotion/cache": "^10.0.29", 7 | "@emotion/core": "^10.0.28", 8 | "@filbert-js/core": "^0.0.14", 9 | "@filbert-js/server-stylesheet": "^0.0.10", 10 | "benchmark": "^2.1.4", 11 | "create-emotion-server": "^10.0.27", 12 | "react": "^16.13.1", 13 | "react-dom": "^16.13.1", 14 | "styled-components": "^5.1.1" 15 | }, 16 | "scripts": { 17 | "performance": "node ./index.js" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /benchmarks/size/emotion/src/index.js: -------------------------------------------------------------------------------- 1 | import * as serviceWorker from './serviceWorker'; 2 | 3 | import App from './App'; 4 | import React from 'react'; 5 | import ReactDOM from 'react-dom'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root'), 12 | ); 13 | 14 | // If you want your app to work offline and load faster, you can change 15 | // unregister() to register() below. Note this comes with some pitfalls. 16 | // Learn more about service workers: https://bit.ly/CRA-PWA 17 | serviceWorker.unregister(); 18 | -------------------------------------------------------------------------------- /benchmarks/size/filbert/src/index.js: -------------------------------------------------------------------------------- 1 | import * as serviceWorker from './serviceWorker'; 2 | 3 | import App from './App'; 4 | import React from 'react'; 5 | import ReactDOM from 'react-dom'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root'), 12 | ); 13 | 14 | // If you want your app to work offline and load faster, you can change 15 | // unregister() to register() below. Note this comes with some pitfalls. 16 | // Learn more about service workers: https://bit.ly/CRA-PWA 17 | serviceWorker.unregister(); 18 | -------------------------------------------------------------------------------- /benchmarks/size/vanilla-css/src/index.js: -------------------------------------------------------------------------------- 1 | import * as serviceWorker from './serviceWorker'; 2 | 3 | import App from './App'; 4 | import React from 'react'; 5 | import ReactDOM from 'react-dom'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root'), 12 | ); 13 | 14 | // If you want your app to work offline and load faster, you can change 15 | // unregister() to register() below. Note this comes with some pitfalls. 16 | // Learn more about service workers: https://bit.ly/CRA-PWA 17 | serviceWorker.unregister(); 18 | -------------------------------------------------------------------------------- /packages/css-ast/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/css-ast 2 | 3 | ## 0.0.8 4 | 5 | ### Patch Changes 6 | 7 | - 5ba6c20: fix stylesheet ordering 8 | 9 | ## 0.0.7 10 | 11 | ### Patch Changes 12 | 13 | - a30ad13: special handling for css property's value of types url /string with quotes 14 | 15 | ## 0.0.6 16 | 17 | ### Patch Changes 18 | 19 | - dc6e795: - (Website): add examples using `filbert-js` with `preact`/`cra`/`nextjs`/`gatsby` 20 | - (CSS-AST): handle `url` as css value 21 | 22 | ## 0.0.5 23 | 24 | ### Patch Changes 25 | 26 | - 0ef9584: - Add `as` Prop 27 | - Add `forward ref` 28 | -------------------------------------------------------------------------------- /benchmarks/size/styled-components/src/index.js: -------------------------------------------------------------------------------- 1 | import * as serviceWorker from './serviceWorker'; 2 | 3 | import App from './App'; 4 | import React from 'react'; 5 | import ReactDOM from 'react-dom'; 6 | 7 | ReactDOM.render( 8 | 9 | 10 | , 11 | document.getElementById('root'), 12 | ); 13 | 14 | // If you want your app to work offline and load faster, you can change 15 | // unregister() to register() below. Note this comes with some pitfalls. 16 | // Learn more about service workers: https://bit.ly/CRA-PWA 17 | serviceWorker.unregister(); 18 | -------------------------------------------------------------------------------- /.github/workflows/size.yml: -------------------------------------------------------------------------------- 1 | name: Compressed Size 2 | 3 | on: [pull_request] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v2 11 | - uses: preactjs/compressed-size-action@v2 12 | with: 13 | repo-token: '${{ secrets.GITHUB_TOKEN }}' 14 | build-script: 'build-packages' 15 | # Any JS files anywhere within a dist directory: 16 | pattern: 'packages/**/dist/**/*.js' 17 | 18 | # Always ignore SourceMaps and node_modules: 19 | exclude: '{**/*.map,**/node_modules/**}' 20 | -------------------------------------------------------------------------------- /packages/babel-plugin-filbert/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # babel-plugin-filbert 2 | 3 | ## 0.0.8 4 | 5 | ### Patch Changes 6 | 7 | - 001085a: bug: add missing dependencies 8 | 9 | ## 0.0.7 10 | 11 | ### Patch Changes 12 | 13 | - 4affc53: remove pragma annotation dependency 14 | 15 | ## 0.0.6 16 | 17 | ### Patch Changes 18 | 19 | - 002e3f5: - Prepend #**PURE** comment to help minifiers with dead code elimination (=DCE) 20 | - Remove `StyleSheetContext` from `styled` api 21 | - Refactored website(sidebar) 22 | 23 | ## 0.0.5 24 | 25 | ### Patch Changes 26 | 27 | - 0ef9584: - Add `as` Prop 28 | - Add `forward ref` 29 | -------------------------------------------------------------------------------- /packages/stylesheet/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/stylesheet 2 | 3 | ## 0.0.8 4 | 5 | ### Patch Changes 6 | 7 | - 5ba6c20: fix stylesheet ordering 8 | 9 | ## 0.0.7 10 | 11 | ### Patch Changes 12 | 13 | - b3e80f1: Remove react from dependencies list in core 14 | 15 | ## 0.0.6 16 | 17 | ### Patch Changes 18 | 19 | - 985f0e3: reuse filbert-types/merge type+label 20 | - Updated dependencies [985f0e3] 21 | - @filbert-js/types@0.0.6 22 | 23 | ## 0.0.5 24 | 25 | ### Patch Changes 26 | 27 | - 0ef9584: - Add `as` Prop 28 | - Add `forward ref` 29 | - Updated dependencies [0ef9584] 30 | - @filbert-js/types@0.0.5 31 | -------------------------------------------------------------------------------- /website/docs/pseudo-elements.md: -------------------------------------------------------------------------------- 1 | ```jsx editor=live 2 | import React from 'react'; 3 | import { styled } from '@filbert-js/core'; 4 | 5 | const Card = styled('div')` 6 | border: solid 2px gray; 7 | display: flex; 8 | flex-direction: column; 9 | align-items: center; 10 | min-height: 2.5rem; 11 | padding: 0.5rem; 12 | &:hover { 13 | background: gray; 14 | } 15 | &::before { 16 | content: ''; 17 | display: block; 18 | height: 1rem; 19 | width: 1rem; 20 | border-radius: 50%; 21 | background: hotpink; 22 | } 23 | `; 24 | 25 | render(Hover over me!!); 26 | ``` 27 | -------------------------------------------------------------------------------- /website/src/components/Code.jsx: -------------------------------------------------------------------------------- 1 | import Playground from './Playground'; 2 | import React from 'react'; 3 | import StaticCode from './StaticCode'; 4 | 5 | export function Code({ children, editor, metastring }) { 6 | if (editor === 'live') { 7 | const compiled = metastring.replace('editor=live compiled=', '').trim(); 8 | return ; 9 | } else if (editor === 'static') { 10 | const code = children.replace('editor=static', '').trim(); 11 | return ; 12 | } else { 13 | return children; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /benchmarks/size/emotion/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /benchmarks/size/filbert/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /benchmarks/size/vanilla-css/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /website/docs/with-props.md: -------------------------------------------------------------------------------- 1 | ```jsx editor=live 2 | import React from 'react'; 3 | import { styled } from '@filbert-js/core'; 4 | 5 | const Button = styled('button')` 6 | background: ${({ primary }) => (primary ? '#1f368f' : 'white')}; 7 | color: ${({ primary }) => (primary ? 'white' : '#1f368f')}; 8 | border: solid 1px gray; 9 | `; 10 | const Container = styled('div')` 11 | display: flex; 12 | > * + * { 13 | margin-left: 1rem; 14 | } 15 | `; 16 | 17 | render( 18 | 19 | 20 | 21 | , 22 | ); 23 | ``` 24 | -------------------------------------------------------------------------------- /benchmarks/size/styled-components/public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /packages/browser-stylesheet/README.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/browser-stylesheet 2 | 3 | > Browser StyleSheet for filbert-js 4 | 5 | ## Install 6 | 7 | ```bash 8 | yarn add @filbert-js/browser-stylesheet 9 | ``` 10 | 11 | ## Usage 12 | 13 | ```jsx editor=static 14 | import { createStylesheet } from '@filbert-js/browser-stylesheet'; 15 | import { StyleSheetProvider } from '@filbert-js/style-sheet-context'; 16 | import App from './App'; 17 | 18 | const stylesheet = createStylesheet(); 19 | 20 | 21 | 22 | ; 23 | ``` 24 | 25 | More documentation is available at https://filbert-js.vercel.app. 26 | -------------------------------------------------------------------------------- /website/docs/keyframes.md: -------------------------------------------------------------------------------- 1 | ```jsx editor=live 2 | import React from 'react'; 3 | import { styled, Global, keyframes } from '@filbert-js/core'; 4 | 5 | // Create the keyframes 6 | const rotate = keyframes` 7 | from { 8 | transform: rotate(0deg); 9 | } 10 | to { 11 | transform: rotate(360deg); 12 | } 13 | `; 14 | /** Will rotate everything we pass in over one seconds */ 15 | const Rotate = styled('span')` 16 | display: flex; 17 | justify-content: center; 18 | font-size: 1.5rem; 19 | animation: ${rotate} 1s linear infinite; 20 | `; 21 | 22 | render( 23 | 24 | ⭐ 25 | , 26 | ); 27 | ``` 28 | -------------------------------------------------------------------------------- /website/docs/component-selector.md: -------------------------------------------------------------------------------- 1 | ```jsx editor=live 2 | import React from 'react'; 3 | import { styled } from '@filbert-js/core'; 4 | 5 | const Button = styled('button')` 6 | margin: 0 1rem; 7 | background: #1f368f; 8 | color: white; 9 | border: none; 10 | outline: none; 11 | `; 12 | const Paragraph = styled('p')` 13 | color: gray; 14 | ${Button} { 15 | color: #1f368f; 16 | background: white; 17 | } 18 | `; 19 | 20 | render( 21 | 22 | 23 | 24 | I'm gray!! 25 | 26 | 27 | , 28 | ); 29 | ``` 30 | -------------------------------------------------------------------------------- /benchmarks/size/vanilla-css/src/App.js: -------------------------------------------------------------------------------- 1 | import './App.css'; 2 | 3 | import React from 'react'; 4 | import logo from './logo.svg'; 5 | 6 | function App() { 7 | return ( 8 |
9 |
10 | logo 11 |

12 | Edit src/App.js and save to reload. 13 |

14 | 20 | Learn React 21 | 22 |
23 |
24 | ); 25 | } 26 | 27 | export default App; 28 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Use this section to tell people about which versions of your project are 6 | currently being supported with security updates. 7 | 8 | | Version | Supported | 9 | | ------- | ------------------ | 10 | | 5.1.x | :white_check_mark: | 11 | | 5.0.x | :x: | 12 | | 4.0.x | :white_check_mark: | 13 | | < 4.0 | :x: | 14 | 15 | ## Reporting a Vulnerability 16 | 17 | Use this section to tell people how to report a vulnerability. 18 | 19 | Tell them where to go, how often they can expect to get an update on a 20 | reported vulnerability, what to expect if the vulnerability is accepted or 21 | declined, etc. 22 | -------------------------------------------------------------------------------- /packages/css-parser/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/css-parser 2 | 3 | ## 0.0.9 4 | 5 | ### Patch Changes 6 | 7 | - Updated dependencies [5ba6c20] 8 | - @filbert-js/css-ast@0.0.8 9 | 10 | ## 0.0.8 11 | 12 | ### Patch Changes 13 | 14 | - b3e80f1: Remove react from dependencies list in core 15 | 16 | ## 0.0.7 17 | 18 | ### Patch Changes 19 | 20 | - Updated dependencies [a30ad13] 21 | - @filbert-js/css-ast@0.0.7 22 | 23 | ## 0.0.6 24 | 25 | ### Patch Changes 26 | 27 | - Updated dependencies [dc6e795] 28 | - @filbert-js/css-ast@0.0.6 29 | 30 | ## 0.0.5 31 | 32 | ### Patch Changes 33 | 34 | - 0ef9584: - Add `as` Prop 35 | - Add `forward ref` 36 | - Updated dependencies [0ef9584] 37 | - @filbert-js/css-ast@0.0.5 38 | -------------------------------------------------------------------------------- /website/docs/override-component-style.md: -------------------------------------------------------------------------------- 1 | ```jsx editor=live 2 | import React from 'react'; 3 | import { styled } from '@filbert-js/core'; 4 | 5 | const Box = styled('div')` 6 | background: gray; 7 | color: white; 8 | border: solid 1px gray; 9 | padding: 0.5rem; 10 | `; 11 | 12 | const BlueBox = styled(Box)` 13 | background: #1f368f; 14 | `; 15 | 16 | const RedBox = styled(Box)` 17 | background: red; 18 | `; 19 | 20 | const Container = styled('div')` 21 | display: flex; 22 | > * + * { 23 | margin-left: 1rem; 24 | } 25 | `; 26 | 27 | render( 28 | 29 | I'm red!! 30 | I'm blue!! 31 | I'm gray!! 32 | , 33 | ); 34 | ``` 35 | -------------------------------------------------------------------------------- /packages/stylesheet/README.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/stylesheet 2 | 3 | > A StyleSheet for css-in-js libraries 4 | 5 | ## Install 6 | 7 | ```bash 8 | yarn add @filbert-js/stylesheet 9 | ``` 10 | 11 | ## Usage 12 | 13 | ```jsx editor=static 14 | import React from 'react'; 15 | import { StyleSheet } from '@filbert-js/stylesheet'; 16 | import { StyleSheetProvider } from '@filbert-js/style-sheet-context'; 17 | 18 | const stylesheet = new StyleSheet({ 19 | getRoot, 20 | createElement, 21 | findElementByStyleId, 22 | cssParser, 23 | }); 24 | render( 25 | 26 | 27 | , 28 | ); 29 | ``` 30 | 31 | More documentation is available at https://filbert-js.vercel.app. 32 | -------------------------------------------------------------------------------- /packages/babel-plugin-filbert/README.md: -------------------------------------------------------------------------------- 1 | # babel-plugin-filbert 2 | 3 | A [Babel](https://babeljs.io/) plugin for filbert, converts `styled.div` syntax to `styled('div')` calls. 4 | 5 | ## Install 6 | 7 | `npm install --save babel-plugin-filbert` 8 | 9 | ## How to use 10 | 11 | Edit `.babelrc.json` 12 | 13 | ```js editor=static 14 | { 15 | "presets": [...], 16 | "plugins": ["babel-plugin-filbert"] 17 | } 18 | ``` 19 | 20 | And now you can create your components using `styled.*` syntax: 21 | 22 | ```jsx editor=static 23 | import React from 'react'; 24 | import { styled } from 'filbert'; 25 | 26 | const Button = styled.button` 27 | margin: 0; 28 | padding: 1rem; 29 | font-size: 1rem; 30 | background-color: tomato; 31 | `; 32 | ``` 33 | -------------------------------------------------------------------------------- /benchmarks/size/vanilla-css/src/App.css: -------------------------------------------------------------------------------- 1 | .App { 2 | text-align: center; 3 | } 4 | 5 | .App-logo { 6 | height: 40vmin; 7 | pointer-events: none; 8 | } 9 | 10 | @media (prefers-reduced-motion: no-preference) { 11 | .App-logo { 12 | animation: App-logo-spin infinite 20s linear; 13 | } 14 | } 15 | 16 | .App-header { 17 | background-color: #282c34; 18 | min-height: 100vh; 19 | display: flex; 20 | flex-direction: column; 21 | align-items: center; 22 | justify-content: center; 23 | font-size: calc(10px + 2vmin); 24 | color: white; 25 | } 26 | 27 | .App-link { 28 | color: #61dafb; 29 | } 30 | 31 | @keyframes App-logo-spin { 32 | from { 33 | transform: rotate(0deg); 34 | } 35 | to { 36 | transform: rotate(360deg); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/theming/README.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/theming 2 | 3 | > theming for filbert-js 4 | 5 | ## Install 6 | 7 | ```bash 8 | yarn add @filbert-js/theming 9 | ``` 10 | 11 | ## Usage 12 | 13 | ```jsx editor=static 14 | import React from 'react'; 15 | import { styled } from '@filbert-js/core'; 16 | import { ThemeProvider } from '@filbert-js/theming'; 17 | const Button = styled('button')` 18 | background: ${({ theme }) => theme.colors.brand}; 19 | border: solid 1px gray; 20 | `; 21 | const theme = { 22 | colors: { 23 | brand: 'hotpink', 24 | }, 25 | }; 26 | render( 27 | 28 | 29 | , 30 | ); 31 | ``` 32 | 33 | More documentation is available at https://filbert-js.vercel.app. 34 | -------------------------------------------------------------------------------- /website/docs/auto-prefixing.md: -------------------------------------------------------------------------------- 1 | ```js editor=static 2 | import React from 'react'; 3 | import ReactDOM from 'react-dom'; 4 | import { StyleSheetProvider } from '@filbert-js/style-sheet-context'; 5 | import { createParser } from '@filbert-js/css-parser'; 6 | import { createStylesheet } from '@filbert-js/browser-stylesheet'; 7 | import { prefix } from '@filbert-js/autoprefixer'; 8 | import { App } from './App'; 9 | import ReactDOM from 'react-dom'; 10 | 11 | const cssParser = createParser({ prefix }); 12 | const stylesheet = createStylesheet({ cssParser }); 13 | 14 | ReactDOM.render( 15 | 16 | 17 | 18 | 19 | , 20 | document.getElementById('root'), 21 | ); 22 | ``` 23 | -------------------------------------------------------------------------------- /website/src/images/icons/github.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/gatsby-plugin-filbert/gatsby-browser.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Implement Gatsby's Browser APIs in this file. 3 | * 4 | * See: https://www.gatsbyjs.org/docs/browser-apis/ 5 | */ 6 | 7 | // You can delete this file if you're not using it 8 | import React from 'react'; 9 | import { StyleSheetProvider } from '@filbert-js/style-sheet-context'; 10 | import { createParser } from '@filbert-js/css-parser'; 11 | import { createStylesheet } from '@filbert-js/browser-stylesheet'; 12 | import { prefix } from '@filbert-js/autoprefixer'; 13 | const cssParser = createParser({ prefix }); 14 | const stylesheet = createStylesheet({ cssParser }); 15 | 16 | export const wrapRootElement = ({ element }) => { 17 | return ( 18 | {element} 19 | ); 20 | }; 21 | -------------------------------------------------------------------------------- /.codesandbox/ci.json: -------------------------------------------------------------------------------- 1 | { 2 | "packages": [ 3 | "packages/core", 4 | "packages/theming", 5 | "packages/server-stylesheet", 6 | "packages/browser-stylesheet", 7 | "packages/autoprefixer", 8 | "packages/css-ast", 9 | "packages/style-sheet-context", 10 | "packages/css-parser", 11 | "packages/stylesheet", 12 | "packages/types", 13 | "packages/macro", 14 | "packages/babel-plugin-filbert", 15 | "packages/gatsby-plugin-filbert" 16 | ], 17 | "buildCommand": "build", 18 | "sandboxes": [ 19 | "github/kuldeepkeshwar/filbert-js-examples-with-cra", 20 | "github/kuldeepkeshwar/filbert-js-examples-with-preact", 21 | "github/kuldeepkeshwar/filbert-js-examples-with-nextjs", 22 | "github/kuldeepkeshwar/filbert-js-examples-with-gatsby" 23 | ] 24 | } 25 | -------------------------------------------------------------------------------- /website/plugins/gatsby-remark-live-code/index.js: -------------------------------------------------------------------------------- 1 | const visit = require('unist-util-visit'); 2 | const escapeGoat = require('escape-goat'); 3 | const Babel = require('babel-standalone'); 4 | const livePattern = /editor=live/; 5 | 6 | module.exports = (options) => { 7 | function transformer(tree) { 8 | visit(tree, `code`, (node, index, parent) => { 9 | if (node.lang === 'jsx' || node.lang === 'js') { 10 | if (livePattern.test(node.meta)) { 11 | const code = node.value; 12 | const compiled = Babel.transform(code, { 13 | presets: ['es2015', 'react', 'stage-1'], 14 | }).code; 15 | node.meta = `${node.meta} compiled=${compiled}`; 16 | node.value = code; 17 | } 18 | } 19 | }); 20 | } 21 | return transformer; 22 | }; 23 | -------------------------------------------------------------------------------- /packages/core/README.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/core 2 | 3 | > A light weight(~1KB) css-in-js solution(framework)🎨. 4 | 5 | ## Install 6 | 7 | ```bash 8 | yarn add @filbert-js/core 9 | ``` 10 | 11 | ## Usage 12 | 13 | ```jsx editor=static 14 | import React from 'react'; 15 | import { styled, Global } from '@filbert-js/core'; 16 | 17 | const Button = styled('button')` 18 | background: pink; 19 | border: solid 1px gray; 20 | `; 21 | 22 | render( 23 | <> 24 | 25 | 33 |
I'm pink
34 | , 35 | ); 36 | ``` 37 | 38 | More documentation is available at https://filbert-js.vercel.app. 39 | -------------------------------------------------------------------------------- /packages/core/src/core.js: -------------------------------------------------------------------------------- 1 | import { RAW, TYPE, TYPES_CSS, TYPES_KEYFRAMES } from '@filbert-js/types'; 2 | 3 | import React from 'react'; 4 | import { __sheet } from '@filbert-js/style-sheet-context'; 5 | import { factory } from './factory'; 6 | 7 | export const css = factory(TYPES_CSS); 8 | export const keyframes = factory(TYPES_KEYFRAMES); 9 | export function jsx() { 10 | const { css, className = '', ...props } = arguments[1] || {}; 11 | const sheet = __sheet; 12 | if (css) { 13 | const [styleBlock, keyframes] = css[RAW]; 14 | keyframes.forEach((frame) => sheet.createKeyframes(frame)); 15 | sheet.createStyles(css.toString(), styleBlock, undefined, css[TYPE]); 16 | props.className = `${css} ${className}`.trim(); 17 | arguments[1] = props; 18 | } 19 | return React.createElement.apply(null, arguments); 20 | } 21 | -------------------------------------------------------------------------------- /website/docs/using-as-prop.md: -------------------------------------------------------------------------------- 1 | ```jsx editor=live 2 | import React from 'react'; 3 | import { styled } from '@filbert-js/core'; 4 | 5 | const Button = styled('button')` 6 | display: inline-block; 7 | outline: none; 8 | text-decoration: none; 9 | font-weight: 300; 10 | letter-spacing: 1px; 11 | border: 1px solid; 12 | transition: all 0.2s ease; 13 | box-sizing: border-box; 14 | text-shadow: 0 1px 0 rgba(0, 0, 0, 0.01); 15 | border-radius: 3px; 16 | font-size: 0.8125em; 17 | padding: 0.4125em 1.25em; 18 | color: #4682b4; 19 | border-color: #4682b4; 20 | &:hover { 21 | background: #4682b4; 22 | color: #fff; 23 | border-color: #4682b4; 24 | } 25 | `; 26 | 27 | render( 28 | , 31 | ); 32 | ``` 33 | -------------------------------------------------------------------------------- /packages/server-stylesheet/README.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/server-stylesheet 2 | 3 | > A StyleSheet for server-side rendering 4 | 5 | ## Install 6 | 7 | ```bash 8 | yarn add @filbert-js/server-stylesheet 9 | ``` 10 | 11 | ## Usage 12 | 13 | ```jsx editor=static 14 | import { renderToString } from 'react-dom/server'; 15 | import { createStylesheet } from '@filbert-js/server-stylesheet'; 16 | import App from './App'; 17 | 18 | const sheet = createStylesheet(); 19 | const app = renderToString(sheet.collectStyles()); 20 | const styleHTML = sheet.getStyles(); 21 | // Or 22 | // const styleTags = sheet.getReactElements(); // give React elements 23 | 24 | const html = ` 25 | 26 | ${styleHTML} 27 | 28 |
${app}
29 | 30 | 31 | `; 32 | ``` 33 | 34 | More documentation is available at https://filbert-js.vercel.app. 35 | -------------------------------------------------------------------------------- /website/src/themes/utils.js: -------------------------------------------------------------------------------- 1 | const themes = ['theme-light', 'theme-dark']; 2 | export function getThemeName() { 3 | if (typeof window === 'undefined') { 4 | return themes[0]; 5 | } 6 | const localTheme = window.localStorage.getItem('theme'); 7 | return window.matchMedia && 8 | window.matchMedia('(prefers-color-scheme: dark)').matches && 9 | !localTheme 10 | ? themes[1] 11 | : localTheme 12 | ? localTheme 13 | : themes[0]; 14 | } 15 | export function toggleTheme() { 16 | const themeRoot = document.body; 17 | const currentTheme = themeRoot.classList.toString(); 18 | let result; 19 | if (themes[0] === currentTheme) { 20 | result = themes[1]; 21 | } else { 22 | result = themes[0]; 23 | } 24 | themeRoot.classList.add(result); 25 | themeRoot.classList.remove(currentTheme); 26 | window.localStorage.setItem('theme', result); 27 | } 28 | -------------------------------------------------------------------------------- /packages/macro/index.js: -------------------------------------------------------------------------------- 1 | const { createMacro } = require('babel-plugin-macros'); 2 | const { addNamed } = require('@babel/helper-module-imports'); 3 | 4 | const babelPlugin = require('babel-plugin-filbert'); 5 | 6 | const source = '@filbert-js/core'; 7 | 8 | function filbertMacro({ references, babel, state }) { 9 | const program = state.file.path; 10 | 11 | const imports = {}; 12 | 13 | Object.keys(references).forEach((refName) => { 14 | const id = addNamed(program, refName, source, { nameHint: refName }); 15 | 16 | imports[refName] = id.name; 17 | references[refName].forEach((referencePath) => { 18 | referencePath.node.name = id.name; 19 | }); 20 | }); 21 | 22 | babel.traverse( 23 | program.parent, 24 | babelPlugin(babel, { imports }).visitor, 25 | undefined, 26 | state, 27 | ); 28 | } 29 | module.exports = createMacro(filbertMacro); 30 | -------------------------------------------------------------------------------- /packages/core/src/interpolate.js: -------------------------------------------------------------------------------- 1 | import { IS_STYLED_COMPONENT, TYPE, TYPES_KEYFRAMES } from '@filbert-js/types'; 2 | 3 | export function interpolate(styleTemplates, ...variables) { 4 | const keyframes = []; 5 | 6 | const styleStr = styleTemplates.reduce((previous, current, index) => { 7 | const variable = variables[index - 1]; 8 | const value = resolveValue(keyframes, this, variable); 9 | return `${previous}${value}${current}`; 10 | }); 11 | return [styleStr, keyframes]; 12 | } 13 | function resolveValue(keyframes, context, variable) { 14 | let value = variable; 15 | if (variable[TYPE] === TYPES_KEYFRAMES) { 16 | keyframes.push(variable); 17 | value = variable; 18 | } else if (variable[IS_STYLED_COMPONENT]) { 19 | value = `.${variable.label}`; 20 | } else if (typeof variable === 'function') { 21 | value = variable(context); 22 | } 23 | return value; 24 | } 25 | -------------------------------------------------------------------------------- /website/docs/labels.md: -------------------------------------------------------------------------------- 1 | `@filbert-js` generates dynamic class name for the styling. Sometimes, we may want more readable class name. 2 | 3 | `@filbert-js` allows labeling components 4 | 5 | ```jsx editor=live 6 | import React from 'react'; 7 | import { styled } from '@filbert-js/core'; 8 | 9 | const Base = ({ className }) =>
{className}
; 10 | 11 | const Box = styled(Base)` 12 | background: gray; 13 | color: white; 14 | border: solid 1px gray; 15 | padding: 0.5rem; 16 | `; 17 | const BlueBox = styled(Base, { label: 'BlueBox' })` 18 | background: #1f368f; 19 | color: white; 20 | border: solid 1px gray; 21 | padding: 0.5rem; 22 | `; 23 | 24 | const Container = styled('div')` 25 | display: flex; 26 | > * + * { 27 | margin-left: 1rem; 28 | } 29 | `; 30 | 31 | render( 32 | 33 | 34 | 35 | , 36 | ); 37 | ``` 38 | -------------------------------------------------------------------------------- /packages/macro/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@filbert-js/macro", 3 | "version": "0.0.3", 4 | "repository": "https://github.com/kuldeepkeshwar/filbert-js", 5 | "description": "babel plugin macro for filbert-js", 6 | "sideEffects": false, 7 | "source": "index.js", 8 | "main": "index.js", 9 | "publishConfig": { 10 | "access": "public" 11 | }, 12 | "author": "Kuldeep Keshwar ", 13 | "keywords": [ 14 | "babel-plugin-macros", 15 | "babel-plugin", 16 | "javascript", 17 | "react", 18 | "preact", 19 | "css", 20 | "css-in-js", 21 | "filbert-js", 22 | "1kb", 23 | "light-weight", 24 | "styling", 25 | "styled", 26 | "emotion", 27 | "styled-components" 28 | ], 29 | "license": "MIT", 30 | "dependencies": { 31 | "babel-plugin-filbert": "0.0.8", 32 | "@babel/helper-module-imports": "7.12.5", 33 | "babel-plugin-macros": "3.0.0" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /packages/style-sheet-context/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/style-sheet-context 2 | 3 | ## 0.0.10 4 | 5 | ### Patch Changes 6 | 7 | - Updated dependencies [5ba6c20] 8 | - @filbert-js/browser-stylesheet@0.0.10 9 | 10 | ## 0.0.9 11 | 12 | ### Patch Changes 13 | 14 | - b3e80f1: Remove react from dependencies list in core 15 | - Updated dependencies [b3e80f1] 16 | - @filbert-js/browser-stylesheet@0.0.9 17 | 18 | ## 0.0.8 19 | 20 | ### Patch Changes 21 | 22 | - Updated dependencies [67bbe4a] 23 | - Updated dependencies [985f0e3] 24 | - @filbert-js/browser-stylesheet@0.0.8 25 | 26 | ## 0.0.7 27 | 28 | ### Patch Changes 29 | 30 | - @filbert-js/browser-stylesheet@0.0.7 31 | 32 | ## 0.0.6 33 | 34 | ### Patch Changes 35 | 36 | - @filbert-js/browser-stylesheet@0.0.6 37 | 38 | ## 0.0.5 39 | 40 | ### Patch Changes 41 | 42 | - 0ef9584: - Add `as` Prop 43 | - Add `forward ref` 44 | - Updated dependencies [0ef9584] 45 | - @filbert-js/browser-stylesheet@0.0.5 46 | -------------------------------------------------------------------------------- /packages/babel-plugin-filbert/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel-plugin-filbert", 3 | "version": "0.0.8", 4 | "repository": "https://github.com/kuldeepkeshwar/filbert-js", 5 | "description": "babel plugin for filbert-js", 6 | "sideEffects": false, 7 | "source": "index.js", 8 | "main": "index.js", 9 | "publishConfig": { 10 | "access": "public" 11 | }, 12 | "author": "Kuldeep Keshwar ", 13 | "keywords": [ 14 | "babel-plugin", 15 | "javascript", 16 | "react", 17 | "preact", 18 | "css", 19 | "css-in-js", 20 | "filbert-js", 21 | "1kb", 22 | "light-weight", 23 | "styling", 24 | "styled", 25 | "emotion", 26 | "styled-components" 27 | ], 28 | "license": "MIT", 29 | "dependencies": { 30 | "@babel/plugin-transform-react-jsx": "^7.10.4", 31 | "@babel/core": "^7.0.0-0" 32 | }, 33 | "peerDependencies": { 34 | "@babel/plugin-transform-react-jsx": "^7.10.4", 35 | "@babel/core": "^7.0.0-0" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /benchmarks/size/vanilla-css/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "benchmarks-vanilla-css", 3 | "version": "0.0.4", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.11.2", 7 | "@testing-library/react": "^11.0.2", 8 | "@testing-library/user-event": "^7.1.2", 9 | "react": "^16.13.1", 10 | "react-dom": "^16.13.1", 11 | "react-scripts": "4.0.1" 12 | }, 13 | "scripts": { 14 | "start": "react-scripts start", 15 | "build": "react-scripts build", 16 | "capture-stats": "node ../bundle-size/build.js", 17 | "clean": "rm -rf ./build", 18 | "test": "react-scripts test", 19 | "eject": "react-scripts eject" 20 | }, 21 | "eslintConfig": { 22 | "extends": "react-app" 23 | }, 24 | "browserslist": { 25 | "production": [ 26 | ">0.2%", 27 | "not dead", 28 | "not op_mini all" 29 | ], 30 | "development": [ 31 | "last 1 chrome version", 32 | "last 1 firefox version", 33 | "last 1 safari version" 34 | ] 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /website/docs/nested-selectors.md: -------------------------------------------------------------------------------- 1 | Use nested selectors to target elements inside the current class or React component. An example with an element selector is shown below. 2 | 3 | ```jsx editor=live 4 | import React from 'react'; 5 | import { styled } from '@filbert-js/core'; 6 | 7 | const Paragraph = styled('p')` 8 | color: gray; 9 | button { 10 | margin: 0 1rem; 11 | background: #1f368f; 12 | color: white; 13 | } 14 | `; 15 | 16 | render( 17 | 18 | I'm gray!! 19 | 20 | , 21 | ); 22 | ``` 23 | 24 | Use `&` to select the current class nested in another element: 25 | 26 | ```jsx editor=live 27 | import React from 'react'; 28 | import { styled } from '@filbert-js/core'; 29 | 30 | const Paragraph = styled('p')` 31 | color: gray; 32 | header & { 33 | color: red; 34 | } 35 | `; 36 | 37 | render( 38 |
39 |
40 | I'm red !! 41 |
42 | I'm gray !! 43 |
, 44 | ); 45 | ``` 46 | -------------------------------------------------------------------------------- /packages/css-ast/README.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/css-ast 2 | 3 | > CSS to AST transformer for filbert-js. 4 | 5 | ## Install 6 | 7 | ```bash 8 | yarn add @filbert-js/css-ast 9 | ``` 10 | 11 | ```js editor=static 12 | import { toAST } from '@filbert-js/css-ast'; 13 | 14 | const css = ` 15 | color: gray; 16 | button { 17 | margin: 0 1rem; 18 | background: #1f368f; 19 | color: white; 20 | span { 21 | color: red; 22 | } 23 | } 24 | button,span { 25 | color: pink; 26 | } 27 | `; 28 | const ast = toAST(css); 29 | console.log(ast); 30 | /** 31 | children: Array[2] 32 | 0: Node 33 | 1: Node 34 | rules: Array[1] 35 | 0: Object 36 | name: "color" 37 | value: "gray" 38 | start: 0 39 | end: 168 40 | raw: " 41 | color: gray; 42 | button { 43 | margin: 0 1rem; 44 | background: #1f368f; 45 | color: white; 46 | span { 47 | color: red; 48 | } 49 | } 50 | button, 51 | span { 52 | color: pink; 53 | } 54 | " 55 | * */ 56 | ``` 57 | 58 | More documentation is available at https://filbert-js.vercel.app. 59 | -------------------------------------------------------------------------------- /website/src/components/markdown-overrides.js: -------------------------------------------------------------------------------- 1 | import { styled } from '@filbert-js/core'; 2 | export const Title = styled.h1` 3 | font-size: 2rem; 4 | `; 5 | export const H3 = styled.h3` 6 | margin: 1rem 0; 7 | `; 8 | export const Paragraph = styled.p` 9 | margin: 1rem 0; 10 | .language-text { 11 | background: rgba(27, 31, 35, 0.05); 12 | border-radius: 6px; 13 | padding: 0.2em 0.4em; 14 | } 15 | `; 16 | export const Pre = styled.pre` 17 | padding: 10px 20px; 18 | background: var(--colors-app-background); 19 | border-radius: 6px; 20 | color: var(--colors-text-body); 21 | `; 22 | export const Blockquote = styled.div` 23 | background: var(--colors-app-background); 24 | border-left: 10px solid #ccc; 25 | margin: 1.5em 0; 26 | padding: 1em 10px 1em 10px; 27 | p { 28 | margin: 0; 29 | } 30 | `; 31 | export const Anchor = styled.a` 32 | display: inline; 33 | cursor: pointer; 34 | text-decoration: none; 35 | color: var(--colors-text-link); 36 | 37 | :hover { 38 | color: var(--colors-text-link-hover); 39 | } 40 | `; 41 | -------------------------------------------------------------------------------- /website/docs/preact.md: -------------------------------------------------------------------------------- 1 | To use `filbert-js` with `preact`, all you need is `@filbert-js/macro` 2 | 3 | ```jsx editor=static 4 | // app.js 5 | import { styled } from '@filbert-js/macro'; 6 | 7 | import { h } from 'preact'; 8 | 9 | const Box = styled.div` 10 | color: red; 11 | `; 12 | export default function App() { 13 | return Preact is awesome; 14 | } 15 | ``` 16 | 17 | 23 | 24 | 👉 Checkout [starter kit](https://github.com/kuldeepkeshwar/filbert-js-examples-with-preact) 25 | -------------------------------------------------------------------------------- /benchmarks/size/styled-components/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "benchmarks-styled-components", 3 | "version": "0.0.4", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.11.2", 7 | "@testing-library/react": "^11.0.2", 8 | "@testing-library/user-event": "^7.1.2", 9 | "react": "^16.13.1", 10 | "react-dom": "^16.13.1", 11 | "react-scripts": "4.0.1", 12 | "styled-components": "^5.1.1" 13 | }, 14 | "scripts": { 15 | "start": "react-scripts start", 16 | "build": "react-scripts build", 17 | "capture-stats": "node ../bundle-size/build.js", 18 | "clean": "rm -rf ./build", 19 | "test": "react-scripts test", 20 | "eject": "react-scripts eject" 21 | }, 22 | "eslintConfig": { 23 | "extends": "react-app" 24 | }, 25 | "browserslist": { 26 | "production": [ 27 | ">0.2%", 28 | "not dead", 29 | "not op_mini all" 30 | ], 31 | "development": [ 32 | "last 1 chrome version", 33 | "last 1 firefox version", 34 | "last 1 safari version" 35 | ] 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /website/docs/create-react-app.md: -------------------------------------------------------------------------------- 1 | To use `filbert-js` with `Create React App(CRA)`, all you need is `@filbert-js/macro` 2 | 3 | ```jsx editor=static 4 | // app.js 5 | import { styled } from '@filbert-js/macro'; 6 | 7 | import React from 'react'; 8 | 9 | const Box = styled.div` 10 | color: red; 11 | `; 12 | export default function App() { 13 | return React JS is awesome; 14 | } 15 | ``` 16 | 17 | 23 | 24 | 👉 Checkout [starter kit](https://github.com/kuldeepkeshwar/filbert-js-examples-with-cra) 25 | -------------------------------------------------------------------------------- /benchmarks/size/filbert/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "benchmarks-filbert", 3 | "version": "0.0.14", 4 | "private": true, 5 | "dependencies": { 6 | "@filbert-js/core": "^0.0.14", 7 | "@filbert-js/theming": "^0.0.7", 8 | "@testing-library/jest-dom": "^5.11.2", 9 | "@testing-library/react": "^11.0.2", 10 | "@testing-library/user-event": "^7.1.2", 11 | "react": "^16.13.1", 12 | "react-dom": "^16.13.1", 13 | "react-scripts": "4.0.1" 14 | }, 15 | "scripts": { 16 | "start": "react-scripts start", 17 | "build": "react-scripts build", 18 | "capture-stats": "node ../bundle-size/build.js", 19 | "clean": "rm -rf ./build", 20 | "test": "react-scripts test", 21 | "eject": "react-scripts eject" 22 | }, 23 | "eslintConfig": { 24 | "extends": "react-app" 25 | }, 26 | "browserslist": { 27 | "production": [ 28 | ">0.2%", 29 | "not dead", 30 | "not op_mini all" 31 | ], 32 | "development": [ 33 | "last 1 chrome version", 34 | "last 1 firefox version", 35 | "last 1 safari version" 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /packages/css-ast/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@filbert-js/css-ast", 3 | "version": "0.0.8", 4 | "repository": "https://github.com/kuldeepkeshwar/filbert-js", 5 | "description": "", 6 | "sideEffects": false, 7 | "source": "index.js", 8 | "main": "dist/index.js", 9 | "umd:main": "dist/index.umd.js", 10 | "module": "dist/index.es.js", 11 | "scripts": { 12 | "prepare": "npm run build", 13 | "clean": "rm -rf ./dist", 14 | "develop": "microbundle watch", 15 | "build": "microbundle --no-sourcemap", 16 | "test": "echo \"Error: no test specified\" && exit 1" 17 | }, 18 | "devDependencies": { 19 | "microbundle": "^0.11.0" 20 | }, 21 | "publishConfig": { 22 | "access": "public" 23 | }, 24 | "author": "Kuldeep Keshwar ", 25 | "keywords": [ 26 | "ast", 27 | "css-ast", 28 | "javascript", 29 | "react", 30 | "preact", 31 | "css", 32 | "css-in-js", 33 | "filbert-js", 34 | "1kb", 35 | "light-weight", 36 | "styling", 37 | "styled", 38 | "emotion", 39 | "styled-components" 40 | ], 41 | "license": "MIT" 42 | } 43 | -------------------------------------------------------------------------------- /benchmarks/size/emotion/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "benchmarks-emotion", 3 | "version": "0.0.4", 4 | "private": true, 5 | "dependencies": { 6 | "@emotion/core": "^10.0.28", 7 | "@emotion/styled": "^10.0.27", 8 | "@testing-library/jest-dom": "^5.11.2", 9 | "@testing-library/react": "^11.0.2", 10 | "@testing-library/user-event": "^7.1.2", 11 | "emotion-theming": "^10.0.27", 12 | "react": "^16.13.1", 13 | "react-dom": "^16.13.1", 14 | "react-scripts": "4.0.1" 15 | }, 16 | "scripts": { 17 | "start": "react-scripts start", 18 | "build": "react-scripts build", 19 | "capture-stats": "node ../bundle-size/build.js", 20 | "clean": "rm -rf ./build", 21 | "test": "react-scripts test", 22 | "eject": "react-scripts eject" 23 | }, 24 | "eslintConfig": { 25 | "extends": "react-app" 26 | }, 27 | "browserslist": { 28 | "production": [ 29 | ">0.2%", 30 | "not dead", 31 | "not op_mini all" 32 | ], 33 | "development": [ 34 | "last 1 chrome version", 35 | "last 1 firefox version", 36 | "last 1 safari version" 37 | ] 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 kuldeepkeshwar 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@filbert-js/types", 3 | "version": "0.0.6", 4 | "repository": "https://github.com/kuldeepkeshwar/filbert-js", 5 | "description": "", 6 | "sideEffects": false, 7 | "source": "index.js", 8 | "main": "dist/index.js", 9 | "umd:main": "dist/index.umd.js", 10 | "module": "dist/index.es.js", 11 | "scripts": { 12 | "prepare": "npm run build", 13 | "clean": "rm -rf ./dist", 14 | "develop": "microbundle watch", 15 | "build": "microbundle --no-sourcemap", 16 | "test": "echo \"Error: no test specified\" && exit 1" 17 | }, 18 | "devDependencies": { 19 | "microbundle": "^0.11.0" 20 | }, 21 | "publishConfig": { 22 | "access": "public" 23 | }, 24 | "author": "Kuldeep Keshwar ", 25 | "keywords": [ 26 | "javascript", 27 | "react", 28 | "preact", 29 | "css", 30 | "css-in-js", 31 | "filbert-js", 32 | "1kb", 33 | "light-weight", 34 | "styling", 35 | "styled", 36 | "emotion", 37 | "styled-components" 38 | ], 39 | "license": "MIT", 40 | "gitHead": "00460640ba9373828e11101ea4429c46e9ef07a7" 41 | } 42 | -------------------------------------------------------------------------------- /packages/browser-stylesheet/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/browser-stylesheet 2 | 3 | ## 0.0.10 4 | 5 | ### Patch Changes 6 | 7 | - 5ba6c20: fix stylesheet ordering 8 | - Updated dependencies [5ba6c20] 9 | - @filbert-js/stylesheet@0.0.8 10 | - @filbert-js/css-parser@0.0.9 11 | 12 | ## 0.0.9 13 | 14 | ### Patch Changes 15 | 16 | - b3e80f1: Remove react from dependencies list in core 17 | - Updated dependencies [b3e80f1] 18 | - @filbert-js/css-parser@0.0.8 19 | - @filbert-js/stylesheet@0.0.7 20 | 21 | ## 0.0.8 22 | 23 | ### Patch Changes 24 | 25 | - 67bbe4a: add @filbert-js/types to deps 26 | - 985f0e3: reuse filbert-types/merge type+label 27 | - Updated dependencies [985f0e3] 28 | - @filbert-js/stylesheet@0.0.6 29 | - @filbert-js/types@0.0.6 30 | 31 | ## 0.0.7 32 | 33 | ### Patch Changes 34 | 35 | - @filbert-js/css-parser@0.0.7 36 | 37 | ## 0.0.6 38 | 39 | ### Patch Changes 40 | 41 | - @filbert-js/css-parser@0.0.6 42 | 43 | ## 0.0.5 44 | 45 | ### Patch Changes 46 | 47 | - 0ef9584: - Add `as` Prop 48 | - Add `forward ref` 49 | - Updated dependencies [0ef9584] 50 | - @filbert-js/css-parser@0.0.5 51 | - @filbert-js/stylesheet@0.0.5 52 | -------------------------------------------------------------------------------- /website/src/components/Header.jsx: -------------------------------------------------------------------------------- 1 | import LogoIcon from './../images/icons/github.svg'; 2 | import React from 'react'; 3 | import { Stack } from 'layout-ui'; 4 | import ThemeIcon from './../images/icons/theme.svg'; 5 | import TwitterIcon from './../images/icons/twitter.svg'; 6 | import { styled } from '@filbert-js/core'; 7 | import { toggleTheme } from '../themes/utils'; 8 | 9 | const Link = styled.a` 10 | display: inline-flex; 11 | align-items: center; 12 | color: var(--colors-app-color); 13 | `; 14 | export function Header(props) { 15 | return ( 16 | 17 | 22 | 23 | 24 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | ); 36 | } 37 | -------------------------------------------------------------------------------- /website/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 gatsbyjs 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | release: 10 | name: Release 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: Checkout Repo 14 | uses: actions/checkout@master 15 | with: 16 | # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits 17 | fetch-depth: 0 18 | 19 | - name: Setup Node.js 12.x 20 | uses: actions/setup-node@master 21 | with: 22 | node-version: 12.x 23 | 24 | - name: Install Dependencies 25 | run: yarn 26 | - name: Build Packages 27 | run: yarn build-packages 28 | - name: Create Release Pull Request or Publish to npm 29 | id: changesets 30 | uses: changesets/action@master 31 | with: 32 | # This expects you to have a script called release which does a build for your packages and calls changeset publish 33 | publish: yarn release 34 | env: 35 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 36 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} 37 | -------------------------------------------------------------------------------- /packages/theming/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@filbert-js/theming", 3 | "version": "0.0.7", 4 | "repository": "https://github.com/kuldeepkeshwar/filbert-js", 5 | "description": "", 6 | "sideEffects": false, 7 | "source": "index.js", 8 | "main": "dist/index.js", 9 | "module": "dist/index.es.js", 10 | "scripts": { 11 | "prepare": "npm run build", 12 | "clean": "rm -rf ./dist", 13 | "develop": "microbundle watch --jsx React.createElement", 14 | "build": "microbundle --no-sourcemap --jsx React.createElement", 15 | "test": "echo \"Error: no test specified\" && exit 1" 16 | }, 17 | "peerDependencies": { 18 | "react": "^16.8.6" 19 | }, 20 | "devDependencies": { 21 | "microbundle": "^0.11.0" 22 | }, 23 | "publishConfig": { 24 | "access": "public" 25 | }, 26 | "author": "Kuldeep Keshwar ", 27 | "keywords": [ 28 | "javascript", 29 | "react", 30 | "preact", 31 | "css", 32 | "css-in-js", 33 | "filbert-js", 34 | "1kb", 35 | "light-weight", 36 | "styling", 37 | "styled", 38 | "emotion", 39 | "styled-components" 40 | ], 41 | "license": "MIT" 42 | } 43 | -------------------------------------------------------------------------------- /website/src/html.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import React from 'react'; 3 | import { getThemeName } from './themes/utils'; 4 | export default function HTML(props) { 5 | return ( 6 | 7 | 8 | 9 | 10 | 14 | {props.headComponents} 15 | 16 | 17 | {props.preBodyComponents} 18 |
23 | {props.postBodyComponents} 24 | 25 | 26 | ); 27 | } 28 | 29 | HTML.propTypes = { 30 | htmlAttributes: PropTypes.object, 31 | headComponents: PropTypes.array, 32 | bodyAttributes: PropTypes.object, 33 | preBodyComponents: PropTypes.array, 34 | body: PropTypes.string, 35 | postBodyComponents: PropTypes.array, 36 | }; 37 | -------------------------------------------------------------------------------- /packages/css-parser/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@filbert-js/css-parser", 3 | "version": "0.0.9", 4 | "repository": "https://github.com/kuldeepkeshwar/filbert-js", 5 | "description": "", 6 | "sideEffects": false, 7 | "source": "index.js", 8 | "main": "dist/index.js", 9 | "umd:main": "dist/index.umd.js", 10 | "module": "dist/index.es.js", 11 | "scripts": { 12 | "prepare": "npm run build", 13 | "clean": "rm -rf ./dist", 14 | "develop": "microbundle watch", 15 | "build": "microbundle --no-sourcemap", 16 | "test": "echo \"Error: no test specified\" && exit 1" 17 | }, 18 | "peerDependencies": { 19 | "@filbert-js/css-ast": "^0.0.8" 20 | }, 21 | "devDependencies": { 22 | "microbundle": "^0.11.0" 23 | }, 24 | "publishConfig": { 25 | "access": "public" 26 | }, 27 | "author": "Kuldeep Keshwar ", 28 | "keywords": [ 29 | "javascript", 30 | "react", 31 | "preact", 32 | "css", 33 | "css-in-js", 34 | "filbert-js", 35 | "1kb", 36 | "light-weight", 37 | "styling", 38 | "styled", 39 | "emotion", 40 | "styled-components" 41 | ], 42 | "license": "MIT" 43 | } 44 | -------------------------------------------------------------------------------- /website/src/themes/hook.js: -------------------------------------------------------------------------------- 1 | import { useCallback, useEffect, useState } from 'react'; 2 | 3 | import { tokens as darkTheme } from './dark'; 4 | import { tokens as lightTheme } from './light'; 5 | 6 | const themes = { light: lightTheme, dark: darkTheme }; 7 | function getThemeName() { 8 | if (typeof window === 'object') { 9 | const localTheme = window.localStorage.getItem('theme'); 10 | return window.matchMedia && 11 | window.matchMedia('(prefers-color-scheme: dark)').matches && 12 | !localTheme 13 | ? 'dark' 14 | : localTheme 15 | ? localTheme 16 | : 'light'; 17 | } else { 18 | return 'light'; 19 | } 20 | } 21 | export const useTheme = () => { 22 | const [theme, setTheme] = useState(getThemeName()); 23 | 24 | const setMode = useCallback((mode) => { 25 | window.localStorage.setItem('theme', mode); 26 | setTheme(mode); 27 | }, []); 28 | 29 | const toggleTheme = () => { 30 | if (theme === 'light') { 31 | setMode('dark'); 32 | } else { 33 | setMode('light'); 34 | } 35 | }; 36 | 37 | useEffect(() => { 38 | setMode(getThemeName()); 39 | }, [setMode]); 40 | 41 | return [themes[theme], toggleTheme]; 42 | }; 43 | -------------------------------------------------------------------------------- /packages/stylesheet/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@filbert-js/stylesheet", 3 | "version": "0.0.8", 4 | "repository": "https://github.com/kuldeepkeshwar/filbert-js", 5 | "description": "", 6 | "sideEffects": false, 7 | "source": "index.js", 8 | "main": "dist/index.js", 9 | "umd:main": "dist/index.umd.js", 10 | "module": "dist/index.es.js", 11 | "scripts": { 12 | "prepare": "npm run build", 13 | "clean": "rm -rf ./dist", 14 | "develop": "microbundle watch", 15 | "build": "microbundle --no-sourcemap", 16 | "test": "echo \"Error: no test specified\" && exit 1" 17 | }, 18 | "peerDependencies": { 19 | "@filbert-js/types": "^0.0.6" 20 | }, 21 | "devDependencies": { 22 | "microbundle": "^0.11.0" 23 | }, 24 | "publishConfig": { 25 | "access": "public" 26 | }, 27 | "author": "Kuldeep Keshwar ", 28 | "keywords": [ 29 | "javascript", 30 | "react", 31 | "preact", 32 | "css", 33 | "css-in-js", 34 | "filbert-js", 35 | "1kb", 36 | "light-weight", 37 | "styling", 38 | "styled", 39 | "emotion", 40 | "styled-components" 41 | ], 42 | "license": "MIT", 43 | "gitHead": "00460640ba9373828e11101ea4429c46e9ef07a7" 44 | } 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | 55 | 56 | # gatsby files 57 | .cache 58 | 59 | # Mac files 60 | .DS_Store 61 | 62 | # Yarn 63 | yarn-error.log 64 | .pnp/ 65 | .pnp.js 66 | # Yarn Integrity file 67 | .yarn-integrity 68 | 69 | dist -------------------------------------------------------------------------------- /packages/gatsby-plugin-filbert/gatsby-ssr.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Implement Gatsby's SSR (Server Side Rendering) APIs in this file. 3 | * 4 | * See: https://www.gatsbyjs.org/docs/ssr-apis/ 5 | */ 6 | 7 | // You can delete this file if you're not using it 8 | /** 9 | * Implement Gatsby's SSR (Server Side Rendering) APIs in this file. 10 | * 11 | * See: https://www.gatsbyjs.org/docs/ssr-apis/ 12 | */ 13 | 14 | // You can delete this file if you're not using it 15 | 16 | import { createParser } from '@filbert-js/css-parser'; 17 | import { createStylesheet } from '@filbert-js/server-stylesheet'; 18 | import { prefix } from '@filbert-js/autoprefixer'; 19 | 20 | const cssParser = createParser({ prefix }); 21 | const sheetByPathname = new Map(); 22 | 23 | export const wrapRootElement = ({ element, pathname }) => { 24 | const sheet = createStylesheet({ cssParser }); 25 | sheetByPathname.set(pathname, sheet); 26 | return sheet.collectStyles(element); 27 | }; 28 | 29 | export const onRenderBody = ({ setHeadComponents, pathname }) => { 30 | const sheet = sheetByPathname.get(pathname); 31 | if (sheet) { 32 | const styleTags = sheet.getReactElements(); 33 | setHeadComponents(styleTags); 34 | sheetByPathname.delete(pathname); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /packages/style-sheet-context/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@filbert-js/style-sheet-context", 3 | "version": "0.0.10", 4 | "repository": "https://github.com/kuldeepkeshwar/filbert-js", 5 | "description": "", 6 | "sideEffects": false, 7 | "source": "index.js", 8 | "main": "dist/index.js", 9 | "module": "dist/index.es.js", 10 | "scripts": { 11 | "prepare": "npm run build", 12 | "clean": "rm -rf ./dist", 13 | "develop": "microbundle watch --jsx React.createElement", 14 | "build": "microbundle --no-sourcemap --jsx React.createElement", 15 | "test": "echo \"Error: no test specified\" && exit 1" 16 | }, 17 | "peerDependencies": { 18 | "@filbert-js/browser-stylesheet": "^0.0.10", 19 | "react": "^16.8.6" 20 | }, 21 | "devDependencies": { 22 | "microbundle": "^0.11.0" 23 | }, 24 | "publishConfig": { 25 | "access": "public" 26 | }, 27 | "author": "Kuldeep Keshwar ", 28 | "keywords": [ 29 | "javascript", 30 | "react", 31 | "preact", 32 | "css", 33 | "css-in-js", 34 | "filbert-js", 35 | "1kb", 36 | "light-weight", 37 | "styling", 38 | "styled", 39 | "emotion", 40 | "styled-components" 41 | ], 42 | "license": "MIT" 43 | } 44 | -------------------------------------------------------------------------------- /website/docs/docs.yaml: -------------------------------------------------------------------------------- 1 | - title: Getting Started 2 | items: 3 | - Introduction 4 | - Install 5 | - Styled Components 6 | - CSS 7 | - Nested Selectors 8 | - With Props 9 | - Override Component Style 10 | - Pseudo Elements 11 | - Style Any Component 12 | - Global 13 | - Media Queries 14 | - Keyframes 15 | - Theming 16 | - Component Selector 17 | - Labels 18 | - Server Side Rendering 19 | - Auto Prefixing 20 | - Using As Prop 21 | - Todo 22 | - title: Integrations 23 | items: 24 | - create react app 25 | - preact 26 | - nextjs 27 | - gatsby 28 | - tailwind 29 | - title: Miscellaneous 30 | items: 31 | - Under The Hood 32 | # This loads the READMEs instead of files in docs/ 33 | - title: Packages 34 | items: 35 | - '@filbert-js/core' 36 | - '@filbert-js/theming' 37 | - '@filbert-js/server-stylesheet' 38 | - '@filbert-js/browser-stylesheet' 39 | - '@filbert-js/autoprefixer' 40 | - '@filbert-js/css-ast' 41 | - '@filbert-js/style-sheet-context' 42 | - '@filbert-js/css-parser' 43 | - '@filbert-js/stylesheet' 44 | - '@filbert-js/types' 45 | - '@filbert-js/macro' 46 | - 'babel-plugin-filbert' 47 | - 'gatsby-plugin-filbert' 48 | -------------------------------------------------------------------------------- /packages/autoprefixer/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@filbert-js/autoprefixer", 3 | "version": "0.0.6", 4 | "repository": "https://github.com/kuldeepkeshwar/filbert-js", 5 | "description": "", 6 | "sideEffects": false, 7 | "source": "index.js", 8 | "main": "dist/index.js", 9 | "umd:main": "dist/index.umd.js", 10 | "module": "dist/index.es.js", 11 | "scripts": { 12 | "prepare": "npm run build", 13 | "clean": "rm -rf ./dist", 14 | "develop": "microbundle watch", 15 | "build": "microbundle --no-sourcemap", 16 | "test": "echo \"Error: no test specified\" && exit 1" 17 | }, 18 | "dependencies": { 19 | "style-vendorizer": "^1.0.1" 20 | }, 21 | "devDependencies": { 22 | "microbundle": "^0.11.0" 23 | }, 24 | "publishConfig": { 25 | "access": "public" 26 | }, 27 | "author": "Kuldeep Keshwar ", 28 | "keywords": [ 29 | "autoprefixer", 30 | "postcss", 31 | "javascript", 32 | "react", 33 | "preact", 34 | "css", 35 | "css-in-js", 36 | "filbert-js", 37 | "1kb", 38 | "light-weight", 39 | "styling", 40 | "styled", 41 | "emotion", 42 | "styled-components" 43 | ], 44 | "license": "MIT", 45 | "gitHead": "00460640ba9373828e11101ea4429c46e9ef07a7" 46 | } 47 | -------------------------------------------------------------------------------- /packages/browser-stylesheet/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@filbert-js/browser-stylesheet", 3 | "version": "0.0.10", 4 | "repository": "https://github.com/kuldeepkeshwar/filbert-js", 5 | "description": "", 6 | "sideEffects": false, 7 | "source": "index.js", 8 | "main": "dist/index.js", 9 | "umd:main": "dist/index.umd.js", 10 | "module": "dist/index.es.js", 11 | "scripts": { 12 | "prepare": "npm run build", 13 | "clean": "rm -rf ./dist", 14 | "develop": "microbundle watch", 15 | "build": "microbundle --no-sourcemap", 16 | "test": "echo \"Error: no test specified\" && exit 1" 17 | }, 18 | "peerDependencies": { 19 | "@filbert-js/css-parser": "^0.0.9", 20 | "@filbert-js/types": "^0.0.6", 21 | "@filbert-js/stylesheet": "^0.0.8" 22 | }, 23 | "devDependencies": { 24 | "microbundle": "^0.11.0" 25 | }, 26 | "author": "Kuldeep Keshwar ", 27 | "keywords": [ 28 | "javascript", 29 | "react", 30 | "preact", 31 | "css", 32 | "css-in-js", 33 | "filbert-js", 34 | "1kb", 35 | "light-weight", 36 | "styling", 37 | "styled", 38 | "emotion", 39 | "styled-components" 40 | ], 41 | "license": "MIT", 42 | "publishConfig": { 43 | "access": "public" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /packages/server-stylesheet/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/server-stylesheet 2 | 3 | ## 0.0.10 4 | 5 | ### Patch Changes 6 | 7 | - 5ba6c20: fix stylesheet ordering 8 | - Updated dependencies [5ba6c20] 9 | - @filbert-js/stylesheet@0.0.8 10 | - @filbert-js/style-sheet-context@0.0.10 11 | - @filbert-js/css-parser@0.0.9 12 | 13 | ## 0.0.9 14 | 15 | ### Patch Changes 16 | 17 | - b3e80f1: Remove react from dependencies list in core 18 | - Updated dependencies [b3e80f1] 19 | - @filbert-js/css-parser@0.0.8 20 | - @filbert-js/style-sheet-context@0.0.9 21 | - @filbert-js/stylesheet@0.0.7 22 | 23 | ## 0.0.8 24 | 25 | ### Patch Changes 26 | 27 | - Updated dependencies [985f0e3] 28 | - @filbert-js/stylesheet@0.0.6 29 | - @filbert-js/style-sheet-context@0.0.8 30 | 31 | ## 0.0.7 32 | 33 | ### Patch Changes 34 | 35 | - @filbert-js/css-parser@0.0.7 36 | - @filbert-js/style-sheet-context@0.0.7 37 | 38 | ## 0.0.6 39 | 40 | ### Patch Changes 41 | 42 | - @filbert-js/css-parser@0.0.6 43 | - @filbert-js/style-sheet-context@0.0.6 44 | 45 | ## 0.0.5 46 | 47 | ### Patch Changes 48 | 49 | - 0ef9584: - Add `as` Prop 50 | - Add `forward ref` 51 | - Updated dependencies [0ef9584] 52 | - @filbert-js/css-parser@0.0.5 53 | - @filbert-js/style-sheet-context@0.0.5 54 | - @filbert-js/stylesheet@0.0.5 55 | -------------------------------------------------------------------------------- /website/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (http://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # Typescript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # dotenv environment variable files 55 | .env* 56 | 57 | # gatsby files 58 | .cache/ 59 | public 60 | 61 | # Mac files 62 | .DS_Store 63 | 64 | # Yarn 65 | yarn-error.log 66 | .pnp/ 67 | .pnp.js 68 | # Yarn Integrity file 69 | .yarn-integrity 70 | -------------------------------------------------------------------------------- /website/src/images/icons/twitter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 13 | 14 | -------------------------------------------------------------------------------- /packages/server-stylesheet/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@filbert-js/server-stylesheet", 3 | "version": "0.0.10", 4 | "repository": "https://github.com/kuldeepkeshwar/filbert-js", 5 | "description": "", 6 | "sideEffects": false, 7 | "source": "index.js", 8 | "main": "dist/index.js", 9 | "module": "dist/index.es.js", 10 | "scripts": { 11 | "prepare": "npm run build", 12 | "clean": "rm -rf ./dist", 13 | "develop": "microbundle watch --jsx React.createElement", 14 | "build": "microbundle --no-sourcemap --jsx React.createElement", 15 | "test": "echo \"Error: no test specified\" && exit 1" 16 | }, 17 | "peerDependencies": { 18 | "@filbert-js/css-parser": "^0.0.9", 19 | "@filbert-js/style-sheet-context": "^0.0.10", 20 | "@filbert-js/stylesheet": "^0.0.8", 21 | "react": "^16.8.6" 22 | }, 23 | "devDependencies": { 24 | "microbundle": "^0.11.0" 25 | }, 26 | "publishConfig": { 27 | "access": "public" 28 | }, 29 | "author": "Kuldeep Keshwar ", 30 | "keywords": [ 31 | "javascript", 32 | "react", 33 | "preact", 34 | "css", 35 | "css-in-js", 36 | "filbert-js", 37 | "1kb", 38 | "light-weight", 39 | "styling", 40 | "styled", 41 | "emotion", 42 | "styled-components" 43 | ], 44 | "license": "MIT" 45 | } 46 | -------------------------------------------------------------------------------- /website/src/components/Playground.jsx: -------------------------------------------------------------------------------- 1 | import { LiveError, LivePreview, LiveProvider } from 'react-live'; 2 | 3 | import { Editor } from './Editor'; 4 | import React from 'react'; 5 | import { Stack } from 'layout-ui'; 6 | import { styled } from '@filbert-js/core'; 7 | 8 | export const scope = { 9 | process: { 10 | env: { 11 | NODE_ENV: process.env.NODE_ENV, 12 | }, 13 | }, 14 | require(moduleName) { 15 | switch (moduleName) { 16 | case 'react': 17 | return React; 18 | case '@filbert-js/core': 19 | return require('@filbert-js/core'); 20 | case '@filbert-js/theming': 21 | return require('@filbert-js/theming'); 22 | 23 | default: 24 | // eslint-disable-next-line no-throw-literal 25 | throw `Module "${moduleName}" not found`; 26 | } 27 | }, 28 | }; 29 | 30 | const Preview = styled.div` 31 | display: flex; 32 | justify-content: center; 33 | align-items: center; 34 | `; 35 | export default ({ code, compiled }) => { 36 | return ( 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | ); 47 | }; 48 | -------------------------------------------------------------------------------- /packages/core/src/hooks.js: -------------------------------------------------------------------------------- 1 | import { TYPES_CSS, TYPES_GLOBAL } from '@filbert-js/types'; 2 | 3 | import React from 'react'; 4 | import { __sheet } from '@filbert-js/style-sheet-context'; 5 | 6 | // invoke callback if value changes b/w render cycles 7 | 8 | export function useGlobalStylesheet(id, styles) { 9 | __sheet.createGlobalStyles(id, styles); 10 | 11 | React.useEffect(() => { 12 | __sheet.createGlobalStyles(id, styles); 13 | }, [styles, id]); 14 | 15 | React.useEffect(() => { 16 | return () => __sheet.removeStyles(id, TYPES_GLOBAL); 17 | }, [id]); 18 | } 19 | 20 | export function useStylesheet( 21 | keyframes, 22 | className, 23 | styles, 24 | sourceOrder, 25 | label, 26 | ) { 27 | const latestRef = React.useRef(); 28 | 29 | keyframes.forEach((frame) => __sheet.createKeyframes(frame)); 30 | __sheet.createStyles(className, styles, sourceOrder, label); 31 | 32 | latestRef.current = className; 33 | 34 | React.useEffect(() => { 35 | const previous = className; 36 | return () => { 37 | const latest = latestRef.current; 38 | if (previous !== latest) { 39 | __sheet.removeStyles(previous, TYPES_CSS); 40 | } 41 | }; 42 | }, [className]); 43 | 44 | React.useEffect(() => { 45 | return () => __sheet.removeStyles(latestRef.current, TYPES_CSS); 46 | }, []); 47 | } 48 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | If you want to start fresh, We have a [todo list](https://filbert-js.vercel.app/docs/todo). 4 | 5 | ## Issues 6 | 7 | Issues are very valuable to this project. 8 | 9 | * Ideas are a valuable source of contributions others can make 10 | * Problems show where this project is lacking 11 | * With a question you show where contributors can improve the user experience 12 | 13 | Thank you for creating them. 14 | 15 | ## Pull Requests 16 | 17 | Pull requests are, a great way to get your ideas into this repository. 18 | 19 | When deciding if I merge in a pull request I look at the following things: 20 | 21 | ### Does it state intent 22 | 23 | You should be clear which problem you're trying to solve with your contribution. 24 | 25 | For example: 26 | 27 | > Add link to code of conduct in README.md 28 | 29 | Doesn't tell anything about why you're doing that 30 | 31 | > Add link to code of conduct in README.md because users don't always look in the CONTRIBUTING.md 32 | 33 | Tells me the problem that you have found, and the pull request shows me the action you have taken to solve it. 34 | 35 | 36 | ### Is it of good quality 37 | 38 | * There are no spelling mistakes 39 | * It reads well 40 | * For english language contributions: Has a good score on [Grammarly](grammarly.com) or [Hemingway App](http://www.hemingwayapp.com/) 41 | -------------------------------------------------------------------------------- /benchmarks/size/bundle-size/capture-sizes.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const filesize = require('filesize'); 4 | 5 | const gzipSize = require('gzip-size').sync; 6 | function canReadAsset(asset) { 7 | return ( 8 | /\.(js|css)$/.test(asset) && 9 | !/service-worker\.js/.test(asset) && 10 | !/precache-manifest\.[0-9a-f]+\.js/.test(asset) 11 | ); 12 | } 13 | module.exports = function capture(stats, buildFolder) { 14 | let total = 0; 15 | const assets = stats 16 | .toJson({ all: false, assets: true }) 17 | .assets.filter((asset) => canReadAsset(asset.name)) 18 | .map((asset) => { 19 | const fileContents = fs.readFileSync(path.join(buildFolder, asset.name)); 20 | const size = gzipSize(fileContents); 21 | total = size + total; 22 | return { 23 | name: path.join( 24 | path.basename(buildFolder), 25 | path.dirname(asset.name), 26 | path.basename(asset.name), 27 | ), 28 | size: size, 29 | sizeLabel: filesize(size), 30 | }; 31 | }); 32 | 33 | const data = { 34 | total, 35 | totalLabel: filesize(total), 36 | assets, 37 | }; 38 | 39 | fs.writeFileSync( 40 | path.join(path.basename(buildFolder), 'build-stats.json'), 41 | JSON.stringify(data, null, 2), 42 | ); 43 | console.log('save build-stats.json'); 44 | }; 45 | -------------------------------------------------------------------------------- /benchmarks/size/filbert/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # benchmarks-filbert 2 | 3 | ## 0.0.14 4 | 5 | ### Patch Changes 6 | 7 | - Updated dependencies [5ba6c20] 8 | - @filbert-js/core@0.0.14 9 | - @filbert-js/theming@0.0.7 10 | 11 | ## 0.0.13 12 | 13 | ### Patch Changes 14 | 15 | - Updated dependencies [fcf4d50] 16 | - @filbert-js/core@0.0.13 17 | 18 | ## 0.0.12 19 | 20 | ### Patch Changes 21 | 22 | - Updated dependencies [b3e80f1] 23 | - @filbert-js/core@0.0.12 24 | - @filbert-js/theming@0.0.6 25 | 26 | ## 0.0.11 27 | 28 | ### Patch Changes 29 | 30 | - Updated dependencies [67bbe4a] 31 | - Updated dependencies [985f0e3] 32 | - @filbert-js/core@0.0.11 33 | 34 | ## 0.0.10 35 | 36 | ### Patch Changes 37 | 38 | - @filbert-js/core@0.0.10 39 | 40 | ## 0.0.9 41 | 42 | ### Patch Changes 43 | 44 | - Updated dependencies [dc6e795] 45 | - @filbert-js/core@0.0.9 46 | 47 | ## 0.0.8 48 | 49 | ### Patch Changes 50 | 51 | - Updated dependencies [002e3f5] 52 | - @filbert-js/core@0.0.8 53 | 54 | ## 0.0.7 55 | 56 | ### Patch Changes 57 | 58 | - Updated dependencies [28ecee8] 59 | - @filbert-js/core@0.0.7 60 | 61 | ## 0.0.6 62 | 63 | ### Patch Changes 64 | 65 | - Updated dependencies [fa304df] 66 | - @filbert-js/core@0.0.6 67 | 68 | ## 0.0.5 69 | 70 | ### Patch Changes 71 | 72 | - Updated dependencies [0ef9584] 73 | - @filbert-js/core@0.0.5 74 | - @filbert-js/theming@0.0.5 75 | -------------------------------------------------------------------------------- /website/src/components/Editor.jsx: -------------------------------------------------------------------------------- 1 | import Highlight, { defaultProps } from 'prism-react-renderer'; 2 | 3 | import React from 'react'; 4 | import { styled } from '@filbert-js/core'; 5 | import theme from 'prism-react-renderer/themes/nightOwl'; 6 | 7 | const Pre = styled.pre` 8 | text-align: left; 9 | margin: 1em 0; 10 | padding: 0.5em; 11 | overflow: scroll; 12 | `; 13 | 14 | const Line = styled.div` 15 | display: table-row; 16 | `; 17 | 18 | const LineNo = styled.span` 19 | display: table-cell; 20 | text-align: right; 21 | padding-right: 1em; 22 | user-select: none; 23 | opacity: 0.5; 24 | `; 25 | 26 | const LineContent = styled.span` 27 | display: table-cell; 28 | `; 29 | 30 | export const Editor = ({ code = '' }) => ( 31 | 32 | {({ className, style, tokens, getLineProps, getTokenProps }) => ( 33 |
34 |         {tokens.map((line, i) => (
35 |           
36 |             {i + 1}
37 |             
38 |               {line.map((token, key) => (
39 |                 
40 |               ))}
41 |             
42 |           
43 |         ))}
44 |       
45 | )} 46 |
47 | ); 48 | -------------------------------------------------------------------------------- /packages/autoprefixer/index.js: -------------------------------------------------------------------------------- 1 | import { 2 | cssPropertyAlias, 3 | cssPropertyPrefixFlags, 4 | cssValuePrefixFlags, 5 | } from 'style-vendorizer'; 6 | 7 | export function prefix(property, value) { 8 | let cssText = ''; 9 | 10 | /* Resolve aliases, e.g. `gap` -> `grid-gap` */ 11 | const propertyAlias = cssPropertyAlias(property); 12 | if (propertyAlias) cssText += `${propertyAlias}:${value};`; 13 | 14 | /* Prefix properties, e.g. `backdrop-filter` -> `-webkit-backdrop-filter` */ 15 | const propertyFlags = cssPropertyPrefixFlags(property); 16 | if (propertyFlags & 0b001) cssText += `-webkit-${property}:${value};`; 17 | if (propertyFlags & 0b010) cssText += `-moz-${property}:${value};`; 18 | if (propertyFlags & 0b100) cssText += `-ms-${property}:${value};`; 19 | 20 | /* Prefix values, e.g. `position: "sticky"` -> `position: "-webkit-sticky"` */ 21 | /* Notice that flags don't overlap and property prefixing isn't needed here */ 22 | const valueFlags = cssValuePrefixFlags(property, value); 23 | if (valueFlags & 0b001) cssText += `${property}:-webkit-${value};`; 24 | else if (valueFlags & 0b010) cssText += `${property}:-moz-${value};`; 25 | else if (valueFlags & 0b100) cssText += `${property}:-ms-${value};`; 26 | 27 | /* Include the standardized declaration last */ 28 | /* https://css-tricks.com/ordering-css3-properties/ */ 29 | cssText += `${property}:${value};`; 30 | 31 | return cssText; 32 | } 33 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.minimap.enabled": false, 3 | "editor.wordWrap": "off", 4 | "sort-imports.suppress-warnings": true, 5 | "search.exclude": { 6 | "**/node_modules*": true 7 | }, 8 | // Turns on auto format on save for all files types. 9 | // This is also required to allow Prettier to auto format files on save. 10 | // Turns it off for JavaScript since we use Prettier to auto format on save. 11 | "javascript.format.enable": false, 12 | "javascript.validate.enable": true, 13 | "json.format.enable": false, 14 | // Required to allow auto format on save with Prettier + ESLint + Vetur. 15 | "eslint.alwaysShowStatus": true, 16 | "editor.codeActionsOnSave": { 17 | "source.fixAll.eslint": true 18 | }, 19 | // eslint extension options 20 | "eslint.enable": true, 21 | "eslint.validate": [ 22 | "javascript", 23 | "javascriptreact", 24 | "typescript", 25 | "typescriptreact" 26 | ], 27 | // prettier extension setting 28 | "editor.formatOnSave": true, 29 | "[javascript]": { 30 | "editor.defaultFormatter": "esbenp.prettier-vscode" 31 | }, 32 | "[javascriptreact]": { 33 | "editor.defaultFormatter": "esbenp.prettier-vscode" 34 | }, 35 | "[typescript]": { 36 | "editor.defaultFormatter": "esbenp.prettier-vscode" 37 | }, 38 | "[typescriptreact]": { 39 | "editor.defaultFormatter": "esbenp.prettier-vscode" 40 | }, 41 | "prettier.configPath": ".prettierrc.yaml" 42 | } 43 | -------------------------------------------------------------------------------- /packages/gatsby-plugin-filbert/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gatsby-plugin-filbert", 3 | "version": "0.0.16", 4 | "repository": "https://github.com/kuldeepkeshwar/filbert-js", 5 | "description": "", 6 | "sideEffects": false, 7 | "main": "index.js", 8 | "keywords": [ 9 | "javascript", 10 | "react", 11 | "preact", 12 | "css", 13 | "css-in-js", 14 | "filbert-js", 15 | "1kb", 16 | "light-weight", 17 | "styling", 18 | "styled", 19 | "emotion", 20 | "styled-components", 21 | "gatsby", 22 | "gatsby-plugin" 23 | ], 24 | "scripts": { 25 | "test": "echo \"Error: no test specified\" && exit 1" 26 | }, 27 | "author": "Kuldeep Keshwar ", 28 | "license": "MIT", 29 | "publishConfig": { 30 | "access": "public" 31 | }, 32 | "dependencies": { 33 | "@filbert-js/browser-stylesheet": "^0.0.10", 34 | "babel-plugin-filbert": "0.0.8", 35 | "@filbert-js/autoprefixer": "^0.0.6", 36 | "@filbert-js/style-sheet-context": "^0.0.10", 37 | "@filbert-js/server-stylesheet": "^0.0.10", 38 | "@filbert-js/css-parser": "^0.0.9" 39 | }, 40 | "peerDependencies": { 41 | "@filbert-js/css-parser": "^0.0.9", 42 | "@filbert-js/browser-stylesheet": "^0.0.10", 43 | "@filbert-js/style-sheet-context": "^0.0.10", 44 | "babel-plugin-filbert": "0.0.8", 45 | "@filbert-js/autoprefixer": "^0.0.6", 46 | "@filbert-js/server-stylesheet": "^0.0.10" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /website/src/templates/package.js: -------------------------------------------------------------------------------- 1 | import { 2 | Anchor, 3 | Blockquote, 4 | H3, 5 | Paragraph, 6 | Pre, 7 | } from '../components/markdown-overrides'; 8 | 9 | import { Code } from '../components/Code'; 10 | import { Layout } from '../components/Layout'; 11 | import { MDXProvider } from '@mdx-js/react'; 12 | import { MDXRenderer } from 'gatsby-plugin-mdx'; 13 | import React from 'react'; 14 | import { SEO } from '../components/SEO'; 15 | import { graphql } from 'gatsby'; 16 | 17 | export default ({ data: { doc } }) => { 18 | const { 19 | fields: { slug, title }, 20 | frontmatter: { title: _title }, 21 | body, 22 | } = doc; 23 | 24 | const __title = _title || title || slug; 25 | return ( 26 | <> 27 | 28 | 29 | 39 | 40 | 41 | 42 | 43 | ); 44 | }; 45 | 46 | export const pageQuery = graphql` 47 | query PackageBySlug($slug: String!) { 48 | doc: mdx(fields: { slug: { eq: $slug } }) { 49 | body 50 | fields { 51 | slug 52 | title 53 | } 54 | frontmatter { 55 | title 56 | } 57 | } 58 | } 59 | `; 60 | -------------------------------------------------------------------------------- /website/docs/todo.md: -------------------------------------------------------------------------------- 1 | - filbert-js 2 | 3 | - [ ] Use CSSStyleSheet API 4 | - [ ] Add Typescript support 5 | - [ ] Alternate execution path for static styles(using babel plugin) 6 | - [ ] Support `object` syntax for styling 7 | - [ ] Bring size below 1kb 8 | - [ ] Write test cases 9 | - [x] Make `gatsby-plugin-filbert` working 10 | - [x] Enable Ref forwarding 11 | - [x] Support `as` prop 12 | - [x] Remove `html-tags` dependency 13 | - [x] Babel plugin for transformation `styled.div` -> `styled('div')` 14 | - [x] Separate packages for Context 15 | - [x] Separate packages for Theming 16 | - [x] Add `css` API 17 | - [x] Support Media Query 18 | - [x] CSS AST 19 | - [x] Auto prefixing 20 | - [x] Component Selector 21 | 22 | - Website 23 | - [ ] Themes for website 24 | - [ ] Add more description in documentation 25 | - [ ] Document trade offs 26 | - [x] Add Meta tags for website 27 | - [x] Add Mobile layout 28 | - [x] List `README.md` from `packages` 29 | - Other 30 | - [ ] Add a example for vanilla(using `express.js`) Server-Side Rendering 31 | - [ ] Show benchmark stats in pull request. 32 | - [ ] Add Integration examples/links with `CRA`/`Gatsby`/`Nextjs`/`Preact`/`twin.macro` 33 | - [x] Add a official example for [next.js](https://github.com/vercel/next.js) 34 | - [x] Add benchmark for bundle-size (filbert vs emotion vs styled-components) 35 | - [x] Add benchmark for runtime performance (filbert vs emotion vs styled-components) 36 | -------------------------------------------------------------------------------- /website/docs/CSS.md: -------------------------------------------------------------------------------- 1 | ```jsx editor=live 2 | /* This comment tells babel to convert jsx to calls 3 | to a function called jsx instead of React.createElement*/ 4 | /** @jsx jsx */ 5 | import React from 'react'; 6 | import { css, jsx } from '@filbert-js/core'; 7 | 8 | const styles = css` 9 | background: pink; 10 | border: solid 1px gray; 11 | `; 12 | 13 | render(); 14 | ``` 15 | 16 | Or you can use `@filbert-js/macro` 17 | 18 | ```jsx editor=static 19 | import React from 'react'; 20 | import { css } from '@filbert-js/macro'; 21 | 22 | const styles = css` 23 | background: pink; 24 | border: solid 1px gray; 25 | `; 26 | 27 | render(); 28 | ``` 29 | 30 | Or you can use `@filbert-js/core` along with `babel-plugin-filbert` 31 | 32 | ```jsx editor=static 33 | import React from 'react'; 34 | import { css } from '@filbert-js/core'; 35 | 36 | const styles = css` 37 | background: pink; 38 | border: solid 1px gray; 39 | `; 40 | 41 | render(); 42 | ``` 43 | 44 | > Pragma annotation (`/*@jsx jsx*/`) is not required when using `babel-plugin-filbert` or `@filbert-js/macro` 45 | 46 | Check out example 47 | 48 | [![Edit kuldeepkeshwar/filbert-js-examples-with-cra](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/kuldeepkeshwar/filbert-js-examples-with-cra/tree/master/?fontsize=14&hidenavigation=1&theme=dark) 49 | -------------------------------------------------------------------------------- /website/src/templates/doc.js: -------------------------------------------------------------------------------- 1 | import { 2 | Anchor, 3 | Blockquote, 4 | H3, 5 | Paragraph, 6 | Pre, 7 | Title, 8 | } from '../components/markdown-overrides'; 9 | 10 | import { Code } from '../components/Code'; 11 | import { Layout } from '../components/Layout'; 12 | import { MDXProvider } from '@mdx-js/react'; 13 | import { MDXRenderer } from 'gatsby-plugin-mdx'; 14 | import React from 'react'; 15 | import { SEO } from '../components/SEO'; 16 | import { graphql } from 'gatsby'; 17 | 18 | export default ({ data: { doc } }) => { 19 | const { 20 | fields: { slug, title }, 21 | frontmatter: { title: _title }, 22 | body, 23 | } = doc; 24 | 25 | const __title = _title || title || slug; 26 | return ( 27 | <> 28 | 29 | 30 | {__title} 31 | 41 | 42 | 43 | 44 | 45 | ); 46 | }; 47 | 48 | export const pageQuery = graphql` 49 | query DocBySlug($slug: String!) { 50 | doc: mdx(fields: { slug: { eq: $slug } }) { 51 | body 52 | fields { 53 | slug 54 | title 55 | } 56 | frontmatter { 57 | title 58 | } 59 | } 60 | } 61 | `; 62 | -------------------------------------------------------------------------------- /benchmarks/performance/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # benchmarks-performance 2 | 3 | ## 0.0.14 4 | 5 | ### Patch Changes 6 | 7 | - Updated dependencies [5ba6c20] 8 | - @filbert-js/core@0.0.14 9 | - @filbert-js/server-stylesheet@0.0.10 10 | 11 | ## 0.0.13 12 | 13 | ### Patch Changes 14 | 15 | - Updated dependencies [fcf4d50] 16 | - @filbert-js/core@0.0.13 17 | 18 | ## 0.0.12 19 | 20 | ### Patch Changes 21 | 22 | - Updated dependencies [b3e80f1] 23 | - @filbert-js/core@0.0.12 24 | - @filbert-js/server-stylesheet@0.0.9 25 | 26 | ## 0.0.11 27 | 28 | ### Patch Changes 29 | 30 | - Updated dependencies [67bbe4a] 31 | - Updated dependencies [985f0e3] 32 | - @filbert-js/core@0.0.11 33 | - @filbert-js/server-stylesheet@0.0.8 34 | 35 | ## 0.0.10 36 | 37 | ### Patch Changes 38 | 39 | - @filbert-js/server-stylesheet@0.0.7 40 | - @filbert-js/core@0.0.10 41 | 42 | ## 0.0.9 43 | 44 | ### Patch Changes 45 | 46 | - Updated dependencies [dc6e795] 47 | - @filbert-js/core@0.0.9 48 | - @filbert-js/server-stylesheet@0.0.6 49 | 50 | ## 0.0.8 51 | 52 | ### Patch Changes 53 | 54 | - Updated dependencies [002e3f5] 55 | - @filbert-js/core@0.0.8 56 | 57 | ## 0.0.7 58 | 59 | ### Patch Changes 60 | 61 | - Updated dependencies [28ecee8] 62 | - @filbert-js/core@0.0.7 63 | 64 | ## 0.0.6 65 | 66 | ### Patch Changes 67 | 68 | - Updated dependencies [fa304df] 69 | - @filbert-js/core@0.0.6 70 | 71 | ## 0.0.5 72 | 73 | ### Patch Changes 74 | 75 | - Updated dependencies [0ef9584] 76 | - @filbert-js/core@0.0.5 77 | - @filbert-js/server-stylesheet@0.0.5 78 | -------------------------------------------------------------------------------- /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "README.md" 4 | ], 5 | "imageSize": 100, 6 | "commit": false, 7 | "contributors": [ 8 | { 9 | "login": "Darth-koder007", 10 | "name": "Vijay Singh", 11 | "avatar_url": "https://avatars2.githubusercontent.com/u/9719845?v=4", 12 | "profile": "https://github.com/Darth-koder007", 13 | "contributions": [ 14 | "content" 15 | ] 16 | }, 17 | { 18 | "login": "kuldeepkeshwar", 19 | "name": "anotherjsguy", 20 | "avatar_url": "https://avatars1.githubusercontent.com/u/10448534?v=4", 21 | "profile": "https://in.linkedin.com/in/kuldeepkeshwar", 22 | "contributions": [ 23 | "code" 24 | ] 25 | }, 26 | { 27 | "login": "vivek32ta", 28 | "name": "Vivek T A", 29 | "avatar_url": "https://avatars1.githubusercontent.com/u/32357540?v=4", 30 | "profile": "https://github.com/vivek32ta", 31 | "contributions": [ 32 | "code" 33 | ] 34 | }, 35 | { 36 | "login": "danedavid", 37 | "name": "Dane David", 38 | "avatar_url": "https://avatars3.githubusercontent.com/u/19928280?v=4", 39 | "profile": "https://github.com/danedavid", 40 | "contributions": [ 41 | "code" 42 | ] 43 | }, 44 | { 45 | "login": "devevignesh", 46 | "name": "Vignesh Elangovan", 47 | "avatar_url": "https://avatars1.githubusercontent.com/u/31436276?v=4", 48 | "profile": "http://vigneshwaran.dev", 49 | "contributions": [ 50 | "code" 51 | ] 52 | } 53 | ], 54 | "contributorsPerLine": 7, 55 | "projectName": "filbert-js", 56 | "projectOwner": "kuldeepkeshwar", 57 | "repoType": "github", 58 | "repoHost": "https://github.com", 59 | "skipCi": true 60 | } 61 | -------------------------------------------------------------------------------- /packages/core/src/styled.js: -------------------------------------------------------------------------------- 1 | import { 2 | IS_STYLED_COMPONENT, 3 | LABEL_PREFIX, 4 | RAW, 5 | SOURCE_ORDER, 6 | } from '@filbert-js/types'; 7 | 8 | import React from 'react'; 9 | import { ThemeContext } from '@filbert-js/theming'; 10 | import { factory } from './factory'; 11 | import { useStylesheet } from './hooks'; 12 | 13 | let id = 1; 14 | export function styled(Component, options = {}) { 15 | return function f() { 16 | const args = arguments; 17 | function S(props, ref) { 18 | const theme = React.useContext(ThemeContext); 19 | const obj = factory(options.label, { 20 | ...props, 21 | theme, 22 | }).apply(null, args); 23 | 24 | const [styles, keyframes] = obj[RAW]; 25 | 26 | const className = obj.toString(); 27 | 28 | useStylesheet( 29 | keyframes, 30 | className, 31 | styles, 32 | props[SOURCE_ORDER], 33 | ForwardRef.label, 34 | ); 35 | const { 36 | className: passedClassName = '', 37 | [SOURCE_ORDER]: sourceOrder, 38 | as, 39 | children, 40 | ..._props 41 | } = props; 42 | 43 | const finalProps = Object.assign( 44 | { 45 | className: [ForwardRef.label, className, passedClassName] 46 | .join(' ') 47 | .trim(), 48 | [SOURCE_ORDER]: Component[IS_STYLED_COMPONENT] 49 | ? className 50 | : undefined, 51 | ref, 52 | }, 53 | _props, 54 | ); 55 | 56 | return React.createElement(as || Component, finalProps, children); 57 | } 58 | const ForwardRef = React.forwardRef(S); 59 | ForwardRef[IS_STYLED_COMPONENT] = true; 60 | ForwardRef.label = options.label ? options.label : `${LABEL_PREFIX}${id}`; 61 | 62 | id++; 63 | return ForwardRef; 64 | }; 65 | } 66 | -------------------------------------------------------------------------------- /benchmarks/size/bundle-size/delta.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const filesize = require('filesize'); 4 | const chalk = require('chalk'); 5 | const filbertVersion = require('@filbert-js/core/package.json').version; 6 | const styledVersion = require('styled-components/package.json').version; 7 | const emotionVersion = require('@emotion/styled/package.json').version; 8 | 9 | const baseFramework = 'vanilla-css'; 10 | const frameworks = [ 11 | { name: 'filbert', version: filbertVersion }, 12 | { name: 'emotion', version: emotionVersion }, 13 | { name: 'styled-components', version: styledVersion }, 14 | ]; 15 | const statsFilePath = 'build/build-stats.json'; 16 | 17 | function readJSON(dir) { 18 | return JSON.parse( 19 | fs.readFileSync(path.join(__dirname, dir, statsFilePath), { 20 | encoding: 'utf-8', 21 | }), 22 | ); 23 | } 24 | const baseStats = readJSON(path.join(`../${baseFramework}`)); 25 | chalk.cyan( 26 | `Base Application(vanilla CSS) size after gzip :${filesize( 27 | baseStats.total, 28 | )}`, 29 | ); 30 | const deltas = frameworks.map((framework) => { 31 | const stats = readJSON(path.join(`../${framework.name}`)); 32 | const delta = stats.total - baseStats.total; 33 | return { 34 | ...framework, 35 | total: stats.total, 36 | delta, 37 | deltaLabel: filesize(delta), 38 | }; 39 | }); 40 | let message = chalk.cyan(`Framework sizes after gzip \n`); 41 | message = deltas.reduce((previous, item) => { 42 | return `${previous}${chalk.green( 43 | `${item.name}@${item.version}`, 44 | )} ${chalk.yellow(item.deltaLabel)}\n`; 45 | }, message); 46 | const lightest = deltas.reduce((previous, item) => { 47 | if (previous.total < item.total) { 48 | return previous; 49 | } 50 | return item; 51 | }); 52 | console.log(message); 53 | console.log(chalk.cyan(`Lightest is: ${lightest.name}@${lightest.version}`)); 54 | -------------------------------------------------------------------------------- /benchmarks/size/emotion/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /benchmarks/size/filbert/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /benchmarks/size/vanilla-css/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /benchmarks/size/styled-components/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /website/src/components/Sidebar.jsx: -------------------------------------------------------------------------------- 1 | import { Link, graphql, useStaticQuery } from 'gatsby'; 2 | 3 | import React from 'react'; 4 | import { Stack } from 'layout-ui'; 5 | import { styled } from '@filbert-js/core'; 6 | 7 | const MenuItem = styled.span` 8 | a { 9 | display: block; 10 | cursor: pointer; 11 | text-decoration: none; 12 | color: var(--colors-text-link); 13 | 14 | font-size: 14px; 15 | font-weight: 600; 16 | transition: 0.2s ease-out; 17 | border-radius: 3px; 18 | padding: 10px 8px; 19 | width: 100%; 20 | } 21 | a:hover { 22 | background : var(--colors-text-hightlight); 23 | } 24 | `; 25 | const MenuHeading = styled.div` 26 | margin-bottom: 1rem; 27 | font-weight: bold; 28 | `; 29 | export const Sidebar = () => { 30 | const { allDocMap } = useStaticQuery(graphql` 31 | query Sidebar { 32 | allDocMap { 33 | nodes { 34 | items { 35 | group 36 | name 37 | slug 38 | } 39 | } 40 | } 41 | } 42 | `); 43 | 44 | const links = allDocMap.nodes.reduce((agg, { items }) => { 45 | items.forEach((item) => { 46 | if (item.name !== 'Todo') { 47 | if (agg[item.group]) { 48 | agg[item.group].push(item); 49 | } else { 50 | agg[item.group] = [item]; 51 | } 52 | } 53 | }); 54 | return agg; 55 | }, {}); 56 | 57 | return ( 58 | 59 | {Object.keys(links).map((group) => { 60 | return ( 61 |
62 | {group} 63 | 64 | {links[group].map((item) => ( 65 | 66 | {item.name} 67 | 68 | ))} 69 | 70 |
71 | ); 72 | })} 73 |
74 | ); 75 | }; 76 | -------------------------------------------------------------------------------- /website/docs/gatsby.md: -------------------------------------------------------------------------------- 1 | To use `filbert-js` with `gatsbyjs`, follow below steps 2 | 3 | 1. use `@filbert-js/macro` in pages 4 | 2. use `@filbert-js/server-stylesheet` to support SSR/Client Hydration 5 | 6 | ```jsx editor=static 7 | // pages/app.js 8 | import { styled } from '@filbert-js/macro'; 9 | 10 | import React from 'react'; 11 | 12 | const Box = styled.div` 13 | color: red; 14 | `; 15 | export default function App() { 16 | return Gatsby.js is awesome; 17 | } 18 | ``` 19 | 20 | ```js editor=static 21 | // gatsby-ssr.js 22 | import { createStylesheet } from '@filbert-js/server-stylesheet'; 23 | 24 | const sheetByPathname = new Map(); 25 | 26 | export const wrapRootElement = ({ element, pathname }) => { 27 | const sheet = createStylesheet(); 28 | sheetByPathname.set(pathname, sheet); 29 | return sheet.collectStyles(element); 30 | }; 31 | 32 | export const onRenderBody = ({ setHeadComponents, pathname }) => { 33 | const sheet = sheetByPathname.get(pathname); 34 | if (sheet) { 35 | const styleTags = sheet.getReactElements(); 36 | setHeadComponents(styleTags); 37 | sheetByPathname.delete(pathname); 38 | } 39 | }; 40 | ``` 41 | 42 | Or 43 | 44 | Directly use [gatsby-plugin-filbert](https://github.com/kuldeepkeshwar/filbert-js/tree/master/packages/gatsby-plugin-filbert) 45 | 46 | 52 | 53 | 👉 Checkout [starter kit](https://github.com/kuldeepkeshwar/filbert-js-examples-with-gatsby) 54 | -------------------------------------------------------------------------------- /benchmarks/size/filbert/src/App.js: -------------------------------------------------------------------------------- 1 | import { Global, ThemeProvider, keyframes, styled } from './css-in-js'; 2 | 3 | import React from 'react'; 4 | import logo from './logo.svg'; 5 | 6 | // Create the keyframes 7 | const rotate = keyframes` 8 | from {transform: rotate(0deg);} 9 | to {transform: rotate(360deg);} 10 | `; 11 | 12 | const AppLogo = styled('img')` 13 | height: 40vmin; 14 | pointer-events: none; 15 | @media (prefers-reduced-motion: no-preference) { 16 | animation: ${rotate} infinite 20s linear; 17 | } 18 | `; 19 | const AppHeader = styled('div')` 20 | background-color: #282c34; 21 | min-height: 100vh; 22 | display: flex; 23 | flex-direction: column; 24 | align-items: center; 25 | justify-content: center; 26 | font-size: calc(10px + 2vmin); 27 | color: white; 28 | `; 29 | const AppLink = styled('a')` 30 | color: #61dafb; 31 | `; 32 | const App = styled('span')` 33 | text-align: center; 34 | `; 35 | const globalCSS = ` 36 | body { 37 | margin: 0; 38 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 39 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 40 | sans-serif; 41 | -webkit-font-smoothing: antialiased; 42 | -moz-osx-font-smoothing: grayscale; 43 | } 44 | code { 45 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 46 | monospace; 47 | } 48 | `; 49 | 50 | const theme = { font: '16px' }; 51 | 52 | function Root() { 53 | return ( 54 | 55 | 56 | 57 | 58 | 59 |

60 | Edit src/App.js and save to reload. 61 |

62 | 67 | Learn React 68 | 69 |
70 |
71 |
72 | ); 73 | } 74 | 75 | export default Root; 76 | -------------------------------------------------------------------------------- /packages/core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@filbert-js/core", 3 | "version": "0.0.14", 4 | "repository": "https://github.com/kuldeepkeshwar/filbert-js", 5 | "description": "A light weight(~1KB) css-in-js solution(framework)🎨", 6 | "sideEffects": false, 7 | "homepage": "https://filbert-js.vercel.app", 8 | "source": "index.js", 9 | "main": "dist/index.js", 10 | "umd:main": "dist/index.umd.js", 11 | "module": "dist/index.es.js", 12 | "scripts": { 13 | "prepare": "npm run build", 14 | "clean": "rm -rf ./dist", 15 | "develop": "microbundle watch --jsx React.createElement", 16 | "build": "microbundle --no-sourcemap --jsx React.createElement", 17 | "test": "echo \"Error: no test specified\" && exit 1" 18 | }, 19 | "dependencies": { 20 | "@filbert-js/browser-stylesheet": "^0.0.10", 21 | "@filbert-js/style-sheet-context": "^0.0.10", 22 | "@filbert-js/stylesheet": "^0.0.8", 23 | "@filbert-js/css-ast": "^0.0.8", 24 | "@filbert-js/css-parser": "^0.0.9", 25 | "@filbert-js/types": "^0.0.6", 26 | "@filbert-js/theming": "^0.0.7" 27 | }, 28 | "peerDependencies": { 29 | "@filbert-js/browser-stylesheet": "^0.0.10", 30 | "@filbert-js/style-sheet-context": "^0.0.10", 31 | "@filbert-js/css-ast": "^0.0.8", 32 | "@filbert-js/stylesheet": "^0.0.8", 33 | "@filbert-js/css-parser": "^0.0.9", 34 | "@filbert-js/types": "^0.0.6", 35 | "@filbert-js/theming": "^0.0.7", 36 | "react": "^16.8.6" 37 | }, 38 | "devDependencies": { 39 | "microbundle": "^0.11.0" 40 | }, 41 | "publishConfig": { 42 | "access": "public" 43 | }, 44 | "author": "Kuldeep Keshwar ", 45 | "keywords": [ 46 | "javascript", 47 | "react", 48 | "preact", 49 | "css", 50 | "css-in-js", 51 | "filbert-js", 52 | "1kb", 53 | "light-weight", 54 | "styling", 55 | "styled", 56 | "emotion", 57 | "styled-components" 58 | ], 59 | "license": "MIT", 60 | "collective": { 61 | "type": "opencollective", 62 | "url": "https://opencollective.com/filbert-js" 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /benchmarks/size/emotion/src/App.js: -------------------------------------------------------------------------------- 1 | import { Global, ThemeProvider, keyframes, styled } from './css-in-js'; 2 | 3 | import React from 'react'; 4 | import logo from './logo.svg'; 5 | 6 | // Create the keyframes 7 | const rotate = keyframes` 8 | from { 9 | transform: rotate(0deg); 10 | } 11 | to { 12 | transform: rotate(360deg); 13 | } 14 | `; 15 | 16 | const AppLogo = styled('img')` 17 | height: 40vmin; 18 | pointer-events: none; 19 | @media (prefers-reduced-motion: no-preference) { 20 | animation: ${rotate} infinite 20s linear; 21 | } 22 | `; 23 | const AppHeader = styled('div')` 24 | background-color: #282c34; 25 | min-height: 100vh; 26 | display: flex; 27 | flex-direction: column; 28 | align-items: center; 29 | justify-content: center; 30 | font-size: calc(10px + 2vmin); 31 | color: white; 32 | `; 33 | const AppLink = styled('a')` 34 | color: #61dafb; 35 | `; 36 | const App = styled('span')` 37 | text-align: center; 38 | `; 39 | const globalCSS = ` 40 | body { 41 | margin: 0; 42 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 43 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 44 | sans-serif; 45 | -webkit-font-smoothing: antialiased; 46 | -moz-osx-font-smoothing: grayscale; 47 | } 48 | 49 | code { 50 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 51 | monospace; 52 | } 53 | `; 54 | 55 | const theme = { font: '16px' }; 56 | 57 | function Root() { 58 | return ( 59 | 60 | 61 | 62 | 63 | 64 |

65 | Edit src/App.js and save to reload. 66 |

67 | 72 | Learn React 73 | 74 |
75 |
76 |
77 | ); 78 | } 79 | 80 | export default Root; 81 | -------------------------------------------------------------------------------- /benchmarks/size/styled-components/src/App.js: -------------------------------------------------------------------------------- 1 | import { 2 | ThemeProvider, 3 | createGlobalStyle, 4 | keyframes, 5 | styled, 6 | } from './css-in-js'; 7 | 8 | import React from 'react'; 9 | import logo from './logo.svg'; 10 | 11 | // Create the keyframes 12 | const rotate = keyframes` 13 | from { 14 | transform: rotate(0deg); 15 | } 16 | to { 17 | transform: rotate(360deg); 18 | } 19 | `; 20 | 21 | const AppLogo = styled('img')` 22 | height: 40vmin; 23 | pointer-events: none; 24 | @media (prefers-reduced-motion: no-preference) { 25 | animation: ${rotate} infinite 20s linear; 26 | } 27 | `; 28 | const AppHeader = styled('div')` 29 | background-color: #282c34; 30 | min-height: 100vh; 31 | display: flex; 32 | flex-direction: column; 33 | align-items: center; 34 | justify-content: center; 35 | font-size: calc(10px + 2vmin); 36 | color: white; 37 | `; 38 | const AppLink = styled('a')` 39 | color: #61dafb; 40 | `; 41 | const App = styled('span')` 42 | text-align: center; 43 | `; 44 | const globalCSS = ` 45 | body { 46 | margin: 0; 47 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 48 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', 49 | sans-serif; 50 | -webkit-font-smoothing: antialiased; 51 | -moz-osx-font-smoothing: grayscale; 52 | } 53 | 54 | code { 55 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', 56 | monospace; 57 | } 58 | `; 59 | const Global = createGlobalStyle(globalCSS); 60 | const theme = { font: '16px' }; 61 | 62 | function Root() { 63 | return ( 64 | 65 | 66 | 67 | 68 | 69 |

70 | Edit src/App.js and save to reload. 71 |

72 | 77 | Learn React 78 | 79 |
80 |
81 |
82 | ); 83 | } 84 | 85 | export default Root; 86 | -------------------------------------------------------------------------------- /website/docs/nextjs.md: -------------------------------------------------------------------------------- 1 | To use `filbert-js` with `next.js`, follow below steps 2 | 3 | 1. use `@filbert-js/macro` in pages 4 | 2. use `@filbert-js/server-stylesheet` to support SSR/Client Hydration 5 | 6 | ```jsx editor=static 7 | // app.js 8 | import { styled } from '@filbert-js/macro'; 9 | 10 | import React from 'react'; 11 | 12 | const Box = styled.div` 13 | color: red; 14 | `; 15 | export default function App() { 16 | return Next.js is awesome; 17 | } 18 | ``` 19 | 20 | ```js editor=static 21 | // pages/_document.js 22 | 23 | import Document from 'next/document'; 24 | import { createStylesheet } from '@filbert-js/server-stylesheet'; 25 | 26 | class MyDocument extends Document { 27 | static async getInitialProps(ctx) { 28 | const sheet = createStylesheet(); 29 | const originalRenderPage = ctx.renderPage; 30 | try { 31 | ctx.renderPage = () => 32 | originalRenderPage({ 33 | enhanceApp: (App) => { 34 | return (props) => { 35 | return sheet.collectStyles(); 36 | }; 37 | }, 38 | }); 39 | const initialProps = await Document.getInitialProps(ctx); 40 | 41 | const styleTags = sheet.getReactElements(); 42 | return { 43 | ...initialProps, 44 | styles: ( 45 | <> 46 | {styleTags} 47 | {initialProps.styles} 48 | 49 | ), 50 | }; 51 | } finally { 52 | } 53 | } 54 | } 55 | 56 | export default MyDocument; 57 | ``` 58 | 59 | 65 | 66 | 👉 Checkout [starter kit](https://github.com/kuldeepkeshwar/filbert-js-examples-with-nextjs) 67 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "root", 3 | "private": true, 4 | "keywords": [ 5 | "styles", 6 | "filbert", 7 | "react", 8 | "css", 9 | "css-in-js" 10 | ], 11 | "resolutions": { 12 | "**/react": "16.12.0", 13 | "**/react-dom": "16.12.0", 14 | "**/@filbert-js/core": "^0.0.14", 15 | "**/@filbert-js/browser-stylesheet": "^0.0.10", 16 | "**/@filbert-js/style-sheet-context": "^0.0.10", 17 | "**/@filbert-js/css-ast":"^0.0.8", 18 | "**/@filbert-js/css-parser":"^0.0.9", 19 | "**/@filbert-js/types":"^0.0.6" 20 | }, 21 | "scripts": { 22 | "develop": "lerna run --stream --parallel --ignore @filbert-js/examples-* --ignore benchmarks-* develop", 23 | "postinstall": "yarn build-packages", 24 | "build": "lerna run build", 25 | "build-packages": "lerna run --ignore @filbert-js/website --ignore benchmarks-* --ignore @filbert-js/examples-* build", 26 | "develop-packages": "lerna run --parallel --stream --ignore @filbert-js/website --ignore benchmarks-* --ignore @filbert-js/examples-* develop", 27 | "benchmarks": "yarn build-packages && yarn benchmarks-size && yarn benchmarks-performance", 28 | "benchmarks-size": "lerna run capture-stats && lerna run print-delta --stream", 29 | "benchmarks-performance": "lerna run performance --stream", 30 | "release": "changeset publish" 31 | }, 32 | "devDependencies": { 33 | "husky": "^4.2.5", 34 | "lerna": "^3.16.4", 35 | "prettier": "2.0.5" 36 | }, 37 | "eslintConfig": { 38 | "extends": "react-app" 39 | }, 40 | "workspaces": { 41 | "packages": [ 42 | "packages/*", 43 | "website", 44 | "examples/*", 45 | "benchmarks/size/*", 46 | "benchmarks/performance" 47 | ], 48 | "nohoist": [ 49 | "**/dtslint" 50 | ] 51 | }, 52 | "lint-staged": { 53 | "*.{js,ts,tsx,md}": [ 54 | "prettier --write", 55 | "git add" 56 | ] 57 | }, 58 | "husky": { 59 | "hooks": { 60 | "post-commit": "git update-index --again", 61 | "pre-commit": "lint-staged" 62 | } 63 | }, 64 | "dependencies": { 65 | "@changesets/cli": "^2.9.2", 66 | "lint-staged": "^10.2.11" 67 | }, 68 | "collective": { 69 | "type": "opencollective", 70 | "url": "https://opencollective.com/filbert-js" 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /packages/gatsby-plugin-filbert/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # gatsby-plugin-filbert 2 | 3 | ## 0.0.16 4 | 5 | ### Patch Changes 6 | 7 | - Updated dependencies [5ba6c20] 8 | - @filbert-js/browser-stylesheet@0.0.10 9 | - @filbert-js/server-stylesheet@0.0.10 10 | - @filbert-js/style-sheet-context@0.0.10 11 | - @filbert-js/css-parser@0.0.9 12 | 13 | ## 0.0.15 14 | 15 | ### Patch Changes 16 | 17 | - Updated dependencies [001085a] 18 | - babel-plugin-filbert@0.0.8 19 | 20 | ## 0.0.14 21 | 22 | ### Patch Changes 23 | 24 | - b3e80f1: Remove react from dependencies list in core 25 | - Updated dependencies [b3e80f1] 26 | - @filbert-js/browser-stylesheet@0.0.9 27 | - @filbert-js/css-parser@0.0.8 28 | - @filbert-js/server-stylesheet@0.0.9 29 | - @filbert-js/style-sheet-context@0.0.9 30 | 31 | ## 0.0.13 32 | 33 | ### Patch Changes 34 | 35 | - 67bbe4a: add @filbert-js/types to deps 36 | - Updated dependencies [67bbe4a] 37 | - Updated dependencies [985f0e3] 38 | - @filbert-js/browser-stylesheet@0.0.8 39 | - @filbert-js/style-sheet-context@0.0.8 40 | - @filbert-js/server-stylesheet@0.0.8 41 | 42 | ## 0.0.12 43 | 44 | ### Patch Changes 45 | 46 | - Updated dependencies [e4ecedd] 47 | - @filbert-js/autoprefixer@0.0.6 48 | 49 | ## 0.0.11 50 | 51 | ### Patch Changes 52 | 53 | - @filbert-js/server-stylesheet@0.0.7 54 | 55 | ## 0.0.10 56 | 57 | ### Patch Changes 58 | 59 | - @filbert-js/server-stylesheet@0.0.6 60 | 61 | ## 0.0.9 62 | 63 | ### Patch Changes 64 | 65 | - Updated dependencies [4affc53] 66 | - babel-plugin-filbert@0.0.7 67 | 68 | ## 0.0.8 69 | 70 | ### Patch Changes 71 | 72 | - Updated dependencies [002e3f5] 73 | - babel-plugin-filbert@0.0.6 74 | 75 | ## 0.0.7 76 | 77 | ### Patch Changes 78 | 79 | - 28ecee8: - Add `babel-plugin-filbert`/ `gatsby-browser.js` to `gatsby-plugin-filbert` 80 | - remove `babel-plugin-filbert`/ `gatsby-browser.js` from `website` 81 | - Fix `jsx` API: handle null `props` case & `children` 82 | 83 | ## 0.0.6 84 | 85 | ### Patch Changes 86 | 87 | - 9965e28: Make Gatsby plugin filbert work. 88 | - move `packages/gatsby-plugin-filbert/src/gatsby-ssr.js` to `packages/gatsby-plugin-filbert/gatsby-ssr.js` for gatsby to resolve plugin. 89 | 90 | ## 0.0.5 91 | 92 | ### Patch Changes 93 | 94 | - 0ef9584: - Add `as` Prop 95 | - Add `forward ref` 96 | - Updated dependencies [0ef9584] 97 | - @filbert-js/server-stylesheet@0.0.5 98 | -------------------------------------------------------------------------------- /packages/css-parser/index.js: -------------------------------------------------------------------------------- 1 | import { 2 | CLOSE_BRACKET, 3 | OPEN_BRACKET, 4 | RULE_END, 5 | RULE_SEPARATOR, 6 | toAST, 7 | } from '@filbert-js/css-ast'; 8 | 9 | const isMediaQuery = /@media/; 10 | const isPseudoSelector = /&:/; 11 | function prefix(name, value) { 12 | return `${name}${RULE_SEPARATOR}${value}${RULE_END}`; 13 | } 14 | const _opt = { prefix }; 15 | export const createParser = (options) => ({ css, namespace }) => { 16 | const root = toAST(css); 17 | const { prefix } = Object.assign({}, _opt, options); 18 | function nodeToStyleBlock({ node, selector }) { 19 | // build style string for rules 20 | const ruleBlock = rulesToStyleBlock(node.rules, selector); 21 | // process children 22 | const childrenBlock = node.children 23 | .map((child) => { 24 | // TODO: add support for @import,@font-face 25 | if (isMediaQuery.test(child.raw_selector)) { 26 | // handle media query 27 | const block = nodeToStyleBlock({ node: child, selector }); 28 | return `${child.raw_selector}${OPEN_BRACKET}${block}${CLOSE_BRACKET}`; 29 | } 30 | const selectors = child.raw_selector.split(','); 31 | const _selectors = selectors 32 | .map((s) => { 33 | if (isPseudoSelector.test(s)) { 34 | // handle pseudo selectors 35 | return s.replace(/&/g, namespace); 36 | } else if (s.includes('&')) { 37 | // a case of nested selector(self ref) e.g header & {...} -> header {...} 38 | return s.replace(/&/g, namespace); 39 | } else { 40 | // namespace the child selector with self e.g p {...} -> p {...} 41 | return `${selector} ${s}`; 42 | } 43 | }) 44 | .join(','); 45 | return nodeToStyleBlock({ node: child, selector: _selectors }); 46 | }) 47 | .join(' '); 48 | return `${ruleBlock} ${childrenBlock}`.trim(); 49 | } 50 | function rulesToStyleBlock(rules, selector) { 51 | const rulesSTR = rules.reduce((agg, rule) => { 52 | return `${agg}${prefix(rule.name, rule.value)}`; 53 | }, ''); 54 | const selectorBlock = `${selector}${OPEN_BRACKET}${rulesSTR}${CLOSE_BRACKET}`; 55 | return selectorBlock; 56 | } 57 | return nodeToStyleBlock({ 58 | node: root, 59 | selector: namespace, 60 | }); 61 | }; 62 | -------------------------------------------------------------------------------- /packages/browser-stylesheet/index.js: -------------------------------------------------------------------------------- 1 | import { TYPES_CSS, TYPES_GLOBAL, TYPES_KEYFRAMES } from '@filbert-js/types'; 2 | 3 | import { StyleSheet } from '@filbert-js/stylesheet'; 4 | import { createParser } from '@filbert-js/css-parser'; 5 | 6 | const cssParser = createParser(); 7 | const isBrowser = () => ![typeof window, typeof document].includes('undefined'); 8 | 9 | function overrides(el) { 10 | const orgAppend = el.append; 11 | el.append = function append(child) { 12 | if (typeof child === 'string') { 13 | // text node 14 | el.textContent = child; 15 | } else { 16 | orgAppend.call(el, child); 17 | } 18 | }; 19 | el.getChildById = function getChildById(id) { 20 | return document.getElementById(id); 21 | }; 22 | el.isBeforeChild = function (node1, node2) { 23 | const children = this.children; 24 | let a = -1, 25 | b = -1; 26 | for (let index = 0; index < children.length; index++) { 27 | const element = children[index]; 28 | if (element === node1) { 29 | b = index; 30 | } 31 | if (element === node2) { 32 | a = index; 33 | } 34 | } 35 | return a < b; 36 | }; 37 | return el; 38 | } 39 | const init = () => { 40 | const root = isBrowser() ? overrides(document.head) : undefined; 41 | const css = { 42 | [TYPES_GLOBAL]: {}, 43 | [TYPES_CSS]: {}, 44 | [TYPES_KEYFRAMES]: {}, 45 | }; 46 | if (isBrowser()) { 47 | Array.from(document.querySelectorAll('[data-type="styled-css"]')).reduce( 48 | (agg, el) => { 49 | const id = el.getAttribute('id'); 50 | const type = el.getAttribute('styled-type'); 51 | agg[type][id] = el.textContent; 52 | return agg; 53 | }, 54 | css, 55 | ); 56 | } 57 | 58 | function getRoot() { 59 | return root; 60 | } 61 | function createElement(type) { 62 | return overrides(document.createElement(type)); 63 | } 64 | function findElementByStyleId(cls) { 65 | return document.querySelector('.' + cls); 66 | } 67 | return { getRoot, createElement, findElementByStyleId, css }; 68 | }; 69 | 70 | export const createStylesheet = (options = {}) => { 71 | const { getRoot, createElement, findElementByStyleId, css } = init(); 72 | return new StyleSheet({ 73 | getRoot, 74 | createElement, 75 | findElementByStyleId, 76 | cssParser, 77 | css, 78 | ...options, 79 | }); 80 | }; 81 | -------------------------------------------------------------------------------- /packages/core/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/core 2 | 3 | ## 0.0.14 4 | 5 | ### Patch Changes 6 | 7 | - 5ba6c20: fix stylesheet ordering 8 | - Updated dependencies [5ba6c20] 9 | - @filbert-js/browser-stylesheet@0.0.10 10 | - @filbert-js/css-ast@0.0.8 11 | - @filbert-js/stylesheet@0.0.8 12 | - @filbert-js/theming@0.0.7 13 | - @filbert-js/style-sheet-context@0.0.10 14 | - @filbert-js/css-parser@0.0.9 15 | 16 | ## 0.0.13 17 | 18 | ### Patch Changes 19 | 20 | - fcf4d50: Add @filbert-js/stylesheet to @filbert-js/core dependency list. 21 | 22 | ## 0.0.12 23 | 24 | ### Patch Changes 25 | 26 | - b3e80f1: Remove react from dependencies list in core 27 | - Updated dependencies [b3e80f1] 28 | - @filbert-js/browser-stylesheet@0.0.9 29 | - @filbert-js/css-parser@0.0.8 30 | - @filbert-js/style-sheet-context@0.0.9 31 | - @filbert-js/theming@0.0.6 32 | 33 | ## 0.0.11 34 | 35 | ### Patch Changes 36 | 37 | - 67bbe4a: add @filbert-js/types to deps 38 | - 985f0e3: reuse filbert-types/merge type+label 39 | - Updated dependencies [985f0e3] 40 | - @filbert-js/types@0.0.6 41 | - @filbert-js/style-sheet-context@0.0.8 42 | 43 | ## 0.0.10 44 | 45 | ### Patch Changes 46 | 47 | - @filbert-js/browser-stylesheet@0.0.7 48 | - @filbert-js/style-sheet-context@0.0.7 49 | 50 | ## 0.0.9 51 | 52 | ### Patch Changes 53 | 54 | - dc6e795: - (Website): add examples using `filbert-js` with `preact`/`cra`/`nextjs`/`gatsby` 55 | - (CSS-AST): handle `url` as css value 56 | - @filbert-js/browser-stylesheet@0.0.6 57 | - @filbert-js/style-sheet-context@0.0.6 58 | 59 | ## 0.0.8 60 | 61 | ### Patch Changes 62 | 63 | - 002e3f5: - Prepend #**PURE** comment to help minifiers with dead code elimination (=DCE) 64 | - Remove `StyleSheetContext` from `styled` api 65 | - Refactored website(sidebar) 66 | 67 | ## 0.0.7 68 | 69 | ### Patch Changes 70 | 71 | - 28ecee8: - Add `babel-plugin-filbert`/ `gatsby-browser.js` to `gatsby-plugin-filbert` 72 | - remove `babel-plugin-filbert`/ `gatsby-browser.js` from `website` 73 | - Fix `jsx` API: handle null `props` case & `children` 74 | 75 | ## 0.0.6 76 | 77 | ### Patch Changes 78 | 79 | - fa304df: Add cache for hashing 80 | 81 | ## 0.0.5 82 | 83 | ### Patch Changes 84 | 85 | - 0ef9584: - Add `as` Prop 86 | - Add `forward ref` 87 | - Updated dependencies [0ef9584] 88 | - @filbert-js/browser-stylesheet@0.0.5 89 | - @filbert-js/style-sheet-context@0.0.5 90 | - @filbert-js/theming@0.0.5 91 | - @filbert-js/types@0.0.5 92 | -------------------------------------------------------------------------------- /website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@filbert-js/website", 3 | "private": true, 4 | "version": "0.0.16", 5 | "repository": "https://github.com/kuldeepkeshwar/filbert-js", 6 | "description": "A light weight(~1KB) css-in-js solution(framework)🎨", 7 | "homepage": "https://filbert-js.vercel.app", 8 | "author": "Kuldeep Keshwar ", 9 | "keywords": [ 10 | "javascript", 11 | "react", 12 | "preact", 13 | "css", 14 | "css-in-js", 15 | "filbert-js", 16 | "1kb", 17 | "light-weight", 18 | "styling", 19 | "styled", 20 | "emotion", 21 | "styled-components" 22 | ], 23 | "license": "MIT", 24 | "dependencies": { 25 | "layout-ui": "^0.0.2", 26 | "@filbert-js/core": "^0.0.14", 27 | "lodash-es": "^4.17.15", 28 | "prism-react-renderer": "^1.1.1", 29 | "prismjs": "^1.20.0", 30 | "react": "^16.12.0", 31 | "react-dom": "^16.12.0", 32 | "react-helmet": "^6.1.0", 33 | "react-live": "^2.2.2" 34 | }, 35 | "devDependencies": { 36 | "babel-standalone": "^6.26.0", 37 | "@mdx-js/mdx": "latest", 38 | "@mdx-js/react": "latest", 39 | "escape-goat": "1.3.0", 40 | "gatsby": "^2.23.10", 41 | "gatsby-image": "^2.4.8", 42 | "gatsby-plugin-filbert": "^0.0.16", 43 | "gatsby-plugin-catch-links": "^2.3.7", 44 | "gatsby-plugin-google-analytics": "^2.3.10", 45 | "gatsby-plugin-manifest": "^2.4.17", 46 | "gatsby-plugin-mdx": "^1.2.19", 47 | "gatsby-plugin-react-helmet": "^3.3.5", 48 | "gatsby-plugin-react-svg": "^3.0.0", 49 | "gatsby-plugin-sharp": "^2.6.13", 50 | "gatsby-plugin-sitemap": "^2.4.7", 51 | "gatsby-remark-autolink-headers": "^2.3.7", 52 | "gatsby-remark-prismjs": "^3.5.6", 53 | "gatsby-remark-smartypants": "^2.3.6", 54 | "gatsby-source-filesystem": "^2.3.13", 55 | "gatsby-transformer-sharp": "^2.5.6", 56 | "gatsby-transformer-yaml": "^2.4.8", 57 | "prettier": "2.0.5", 58 | "prop-types": "^15.7.2", 59 | "unist-util-visit": "^2.0.2", 60 | "webpack-bundle-analyzer": "^3.8.0" 61 | }, 62 | "scripts": { 63 | "build": "gatsby build", 64 | "develop": "gatsby develop", 65 | "format": "prettier --write \"**/*.{js,jsx,ts,tsx,json,md}\"", 66 | "start": "npm run develop", 67 | "serve": "gatsby serve", 68 | "clean": "gatsby clean", 69 | "test": "echo \"Write tests! -> https://gatsby.dev/unit-testing\" && exit 1", 70 | "deploy": "vercel" 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /website/gatsby-config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const packageJson = require('./package.json'); 3 | const { homepage, description, author, keywords } = packageJson; 4 | const packages = require('./docs-yaml')().filter( 5 | ({ title }) => title === 'Packages', 6 | )[0].items; 7 | module.exports = { 8 | siteMetadata: { 9 | siteUrl: homepage, 10 | title: `filbert`, 11 | description, 12 | author, 13 | keywords, 14 | }, 15 | plugins: packages 16 | .map((pkg) => 17 | path.resolve( 18 | `${__dirname}/../packages/${pkg.replace('@filbert-js/', '')}/README.md`, 19 | ), 20 | ) 21 | .map((file) => ({ 22 | resolve: 'gatsby-source-filesystem', 23 | options: { 24 | path: file, 25 | }, 26 | })) 27 | .concat([ 28 | { 29 | resolve: 'gatsby-source-filesystem', 30 | options: { 31 | path: `${__dirname}/../README.md`, 32 | }, 33 | }, 34 | { 35 | resolve: 'gatsby-source-filesystem', 36 | options: { 37 | path: `${__dirname}/docs`, 38 | }, 39 | }, 40 | 41 | { 42 | resolve: `gatsby-plugin-manifest`, 43 | options: { 44 | name: `filbert`, 45 | short_name: `filbert`, 46 | start_url: `/`, 47 | background_color: `#663399`, 48 | theme_color: `#663399`, 49 | display: `fullscreen`, 50 | icon: `../filbert.png`, // This path is relative to the root of the site. 51 | }, 52 | }, 53 | { 54 | resolve: `gatsby-plugin-mdx`, 55 | options: { 56 | extensions: ['.mdx', '.md'], 57 | remarkPlugins: [require('./plugins/gatsby-remark-live-code')], 58 | gatsbyRemarkPlugins: [ 59 | { resolve: 'gatsby-remark-autolink-headers' }, 60 | { resolve: 'gatsby-remark-smartypants' }, 61 | ], 62 | }, 63 | }, 64 | { 65 | resolve: 'gatsby-plugin-react-svg', 66 | options: { 67 | rule: { 68 | include: /icons/, // See below to configure properly 69 | }, 70 | }, 71 | }, 72 | { 73 | resolve: `gatsby-plugin-google-analytics`, 74 | options: { 75 | trackingId: 'UA-171640923-1', 76 | }, 77 | }, 78 | 79 | 'gatsby-plugin-filbert', 80 | `gatsby-plugin-react-helmet`, 81 | 'gatsby-plugin-sharp', 82 | 'gatsby-transformer-sharp', 83 | 'gatsby-plugin-catch-links', 84 | 'gatsby-plugin-sitemap', 85 | ]), 86 | }; 87 | -------------------------------------------------------------------------------- /website/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # @filbert-js/website 2 | 3 | ## 0.0.16 4 | 5 | ### Patch Changes 6 | 7 | - 5ba6c20: fix stylesheet ordering 8 | - Updated dependencies [5ba6c20] 9 | - @filbert-js/core@0.0.14 10 | 11 | ## 0.0.15 12 | 13 | ### Patch Changes 14 | 15 | - Updated dependencies [fcf4d50] 16 | - @filbert-js/core@0.0.13 17 | 18 | ## 0.0.14 19 | 20 | ### Patch Changes 21 | 22 | - b3e80f1: Remove react from dependencies list in core 23 | - Updated dependencies [b3e80f1] 24 | - @filbert-js/core@0.0.12 25 | 26 | ## 0.0.13 27 | 28 | ### Patch Changes 29 | 30 | - Updated dependencies [67bbe4a] 31 | - Updated dependencies [985f0e3] 32 | - @filbert-js/core@0.0.11 33 | 34 | ## 0.0.12 35 | 36 | ### Patch Changes 37 | 38 | - @filbert-js/core@0.0.10 39 | 40 | ## 0.0.11 41 | 42 | ### Patch Changes 43 | 44 | - dc6e795: - (Website): add examples using `filbert-js` with `preact`/`cra`/`nextjs`/`gatsby` 45 | - (CSS-AST): handle `url` as css value 46 | - Updated dependencies [dc6e795] 47 | - @filbert-js/core@0.0.9 48 | 49 | ## 0.0.10 50 | 51 | ### Patch Changes 52 | 53 | - 4affc53: remove pragma annotation dependency 54 | 55 | ## 0.0.9 56 | 57 | ### Patch Changes 58 | 59 | - 002e3f5: - Prepend #**PURE** comment to help minifiers with dead code elimination (=DCE) 60 | - Remove `StyleSheetContext` from `styled` api 61 | - Refactored website(sidebar) 62 | - Updated dependencies [002e3f5] 63 | - @filbert-js/core@0.0.8 64 | 65 | ## 0.0.8 66 | 67 | ### Patch Changes 68 | 69 | - 28ecee8: - Add `babel-plugin-filbert`/ `gatsby-browser.js` to `gatsby-plugin-filbert` 70 | - remove `babel-plugin-filbert`/ `gatsby-browser.js` from `website` 71 | - Fix `jsx` API: handle null `props` case & `children` 72 | - Updated dependencies [28ecee8] 73 | - @filbert-js/core@0.0.7 74 | 75 | ## 0.0.7 76 | 77 | ### Patch Changes 78 | 79 | - 9965e28: Make Gatsby plugin filbert work. 80 | - move `packages/gatsby-plugin-filbert/src/gatsby-ssr.js` to `packages/gatsby-plugin-filbert/gatsby-ssr.js` for gatsby to resolve plugin. 81 | - Updated dependencies [9965e28] 82 | - gatsby-plugin-filbert@0.0.6 83 | 84 | ## 0.0.6 85 | 86 | ### Patch Changes 87 | 88 | - Updated dependencies [fa304df] 89 | - @filbert-js/core@0.0.6 90 | 91 | ## 0.0.5 92 | 93 | ### Patch Changes 94 | 95 | - Updated dependencies [0ef9584] 96 | - @filbert-js/core@0.0.5 97 | - @filbert-js/autoprefixer@0.0.5 98 | - @filbert-js/browser-stylesheet@0.0.5 99 | - @filbert-js/css-parser@0.0.5 100 | - gatsby-plugin-filbert@0.0.5 101 | - @filbert-js/style-sheet-context@0.0.5 102 | -------------------------------------------------------------------------------- /benchmarks/size/emotion/src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /benchmarks/size/filbert/src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /benchmarks/size/vanilla-css/src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /benchmarks/size/styled-components/src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /benchmarks/performance/index.js: -------------------------------------------------------------------------------- 1 | const Benchmark = require('benchmark'); 2 | 3 | const react = require('react'); 4 | const { renderToString: render } = require('react-dom/server'); 5 | 6 | const filbert = require('@filbert-js/core'); 7 | const filbertVersion = require('@filbert-js/core/package.json').version; 8 | const createStylesheet = require('@filbert-js/server-stylesheet') 9 | .createStylesheet; 10 | 11 | const styledComponents = require('styled-components'); 12 | const styledVersion = require('styled-components/package.json').version; 13 | const emotion = require('@emotion/styled').default; 14 | const createEmotionServer = require('create-emotion-server').default; 15 | const createCache = require('@emotion/cache').default; 16 | const CacheProvider = require('@emotion/core').CacheProvider; 17 | const emotionVersion = require('@emotion/styled/package.json').version; 18 | 19 | const filbertSheet = createStylesheet(); 20 | const styledSheet = new styledComponents.ServerStyleSheet(); 21 | const cache = createCache(); 22 | const { extractCritical } = createEmotionServer(cache); 23 | 24 | const component = (styled) => { 25 | return styled('div')` 26 | opacity: ${(props) => (props.counter > 0.5 ? 1 : 0)}; 27 | @media (min-width: 1px) { 28 | rule: all; 29 | } 30 | &:hover { 31 | another: 1; 32 | display: block; 33 | } 34 | `; 35 | }; 36 | 37 | function renderFilbertComponent(sheet, Foo) { 38 | render( 39 | sheet.collectStyles(react.createElement(Foo, { counter: Math.random() })), 40 | ); 41 | sheet.getStyles(); 42 | } 43 | function renderStyledComponent(sheet, Foo) { 44 | render( 45 | sheet.collectStyles(react.createElement(Foo, { counter: Math.random() })), 46 | ); 47 | sheet.getStyleTags(); 48 | } 49 | function renderEmotionComponent(Foo) { 50 | extractCritical( 51 | render( 52 | react.createElement(CacheProvider, { value: cache }, [ 53 | react.createElement(Foo, { key: '1', counter: Math.random() }), 54 | ]), 55 | ), 56 | ); 57 | } 58 | 59 | const suite = new Benchmark.Suite('styled'); 60 | suite 61 | .add(`filbert@${filbertVersion}`, () => { 62 | renderFilbertComponent(filbertSheet, component(filbert.styled)); 63 | }) 64 | .add(`emotion@${emotionVersion}`, () => { 65 | renderEmotionComponent(component(emotion)); 66 | }) 67 | .add(`styled-components@${styledVersion}`, () => { 68 | renderStyledComponent(styledSheet, component(styledComponents.default)); 69 | }) 70 | .on('error', (e) => console.log(e)) 71 | .on('cycle', function (event) { 72 | console.log(String(event.target)); 73 | }) 74 | .on('complete', function () { 75 | const fastest = this.filter('fastest').map('name')[0]; 76 | console.log('\nFastest is: ' + fastest); 77 | }) 78 | .run({ async: true }); 79 | -------------------------------------------------------------------------------- /website/docs/server-side-rendering.md: -------------------------------------------------------------------------------- 1 | ### Vanilla: Server-Side Rendering 2 | 3 | ```js editor=static 4 | import { renderToString } from 'react-dom/server'; 5 | import { createStylesheet } from '@filbert-js/server-stylesheet'; 6 | import App from './App'; 7 | 8 | const sheet = createStylesheet(); 9 | const app = renderToString(sheet.collectStyles()); 10 | const styleHTML = sheet.getStyles(); 11 | // Or 12 | // const styleTags = sheet.getReactElements(); // give React elements 13 | 14 | const html = ` 15 | 16 | ${styleHTML} 17 | 18 |
${app}
19 | 20 | 21 | `; 22 | ``` 23 | 24 | ### Next.js: Server-Side Rendering 25 | 26 | In `Next.js` world, create a file `pages/_document.js` 27 | 28 | ```js editor=static 29 | // pages/_document.js 30 | 31 | import Document from 'next/document'; 32 | import { createStylesheet } from '@filbert-js/server-stylesheet'; 33 | 34 | class MyDocument extends Document { 35 | static async getInitialProps(ctx) { 36 | const sheet = createStylesheet(); 37 | const originalRenderPage = ctx.renderPage; 38 | try { 39 | ctx.renderPage = () => 40 | originalRenderPage({ 41 | enhanceApp: (App) => { 42 | return (props) => { 43 | return sheet.collectStyles(); 44 | }; 45 | }, 46 | }); 47 | const initialProps = await Document.getInitialProps(ctx); 48 | 49 | const styleTags = sheet.getReactElements(); 50 | return { 51 | ...initialProps, 52 | styles: ( 53 | <> 54 | {styleTags} 55 | {initialProps.styles} 56 | 57 | ), 58 | }; 59 | } finally { 60 | } 61 | } 62 | } 63 | 64 | export default MyDocument; 65 | ``` 66 | 67 | Check out [official nextjs example](https://github.com/vercel/next.js/tree/canary/examples/with-filbert) 68 | 69 | ### Gatsby.js: Server-Side Rendering 70 | 71 | In `Gatsby.js` world, create a file `gatsby-ssr.js` 72 | 73 | ```js editor=static 74 | // gatsby-ssr.js 75 | import { createStylesheet } from '@filbert-js/server-stylesheet'; 76 | 77 | const sheetByPathname = new Map(); 78 | 79 | export const wrapRootElement = ({ element, pathname }) => { 80 | const sheet = createStylesheet(); 81 | sheetByPathname.set(pathname, sheet); 82 | return sheet.collectStyles(element); 83 | }; 84 | 85 | export const onRenderBody = ({ setHeadComponents, pathname }) => { 86 | const sheet = sheetByPathname.get(pathname); 87 | if (sheet) { 88 | const styleTags = sheet.getReactElements(); 89 | setHeadComponents(styleTags); 90 | sheetByPathname.delete(pathname); 91 | } 92 | }; 93 | ``` 94 | 95 | Or 96 | 97 | Directly use [gatsby-plugin-filbert](https://github.com/kuldeepkeshwar/filbert-js/tree/master/packages/gatsby-plugin-filbert) 98 | -------------------------------------------------------------------------------- /packages/css-ast/ast.js: -------------------------------------------------------------------------------- 1 | import { 2 | CLOSE_BRACKET, 3 | OPEN_BRACKET, 4 | RULE_END, 5 | RULE_SEPARATOR, 6 | } from './constants'; 7 | 8 | function Node({ 9 | children = [], 10 | rules = [], 11 | start = -1, 12 | end = -1, 13 | raw, 14 | parent, 15 | }) { 16 | this.children = children; 17 | this.rules = rules; 18 | this.start = start; 19 | this.end = end; 20 | this.raw = raw; 21 | this.raw_selector = undefined; 22 | this.parent = parent; 23 | } 24 | const holeRegex = /(url\(|"|').*?(\)|"|')/g; 25 | // put holes for urls/string-with-quotes 26 | function handleCSSValues(str) { 27 | let a; 28 | const holes = {}; 29 | let i = 0; 30 | while ((a = holeRegex.exec(str)) !== null) { 31 | const hole = `_${++i}_`; 32 | const [val] = a; 33 | str = str.replace(val, hole); 34 | holes[hole] = val.toString(); 35 | } 36 | return [str, holes]; 37 | } 38 | export function toAST(raw) { 39 | const root = new Node({ 40 | start: 0, 41 | end: raw.length - 1, 42 | raw: raw, 43 | }); 44 | 45 | let current = root; 46 | for (let i = 0; i < raw.length; i++) { 47 | if (raw[i] === OPEN_BRACKET) { 48 | const b = new Node({ start: i, parent: current }); 49 | current.children.push(b); 50 | current = b; 51 | } 52 | if (raw[i] === CLOSE_BRACKET) { 53 | const b = current; 54 | b.end = i; 55 | b.raw = raw.substring(b.start + 1, b.end); 56 | current = b.parent; 57 | buildRules(b, raw); 58 | } 59 | } 60 | buildRules(current, raw); 61 | return root; 62 | } 63 | 64 | function buildRules(block, raw) { 65 | const childSeparator = `$_${Date.now()}`; 66 | let blockStr = block.raw; 67 | let holes; 68 | // remove sub blocks 69 | block.children.forEach((child, index) => { 70 | const childStr = raw.substring(child.start, child.end + 1); 71 | blockStr = blockStr.replace( 72 | childStr, 73 | `${childSeparator}${index}${RULE_END}`, 74 | ); 75 | }); 76 | [blockStr, holes] = handleCSSValues(blockStr); 77 | // split rules 78 | const rules = blockStr.split(RULE_END).reduce((agg, ruleStr) => { 79 | if (!ruleStr.trim()) { 80 | return agg; 81 | } 82 | if (ruleStr.indexOf(childSeparator) === -1) { 83 | // split only property name, combine back value(s) 84 | let [name, value] = ruleStr.split(RULE_SEPARATOR); 85 | name = name.trim(); 86 | value = value.trim(); 87 | agg.push({ 88 | name: name.trim(), 89 | value: typeof holes[value] != 'undefined' ? holes[value] : value, 90 | }); 91 | } else { 92 | const [raw_selector, childIndex] = ruleStr.split(childSeparator); 93 | block.children[childIndex].raw_selector = raw_selector.trim(); 94 | blockStr = blockStr.replace(`${ruleStr}${RULE_END}`, ''); 95 | } 96 | return agg; 97 | }, []); 98 | block.rules = rules; 99 | } 100 | -------------------------------------------------------------------------------- /website/src/components/Layout.jsx: -------------------------------------------------------------------------------- 1 | import { Global, styled } from '@filbert-js/core'; 2 | 3 | import CloseIcon from './../images/icons/close.svg'; 4 | import HamburgerIcon from './../images/icons/hamburger.svg'; 5 | import { Header } from './Header'; 6 | import React from 'react'; 7 | import { Sidebar } from './Sidebar'; 8 | 9 | const Screen = styled.div` 10 | display: grid; 11 | grid-template-columns: minmax(220px, 25%) 1fr; 12 | grid-template-rows: 40px auto; 13 | grid-column-gap: 1rem; 14 | margin: 0 auto; 15 | padding: 0 2rem 1rem 2rem; 16 | width: 100%; 17 | max-width: 64em; 18 | 19 | background: var(--colors-app-background); 20 | color: var(--colors-app-color); 21 | @media screen and (max-width: 52em) { 22 | grid-template-columns: 1fr; 23 | } 24 | `; 25 | const Top = styled.div` 26 | grid-area: 1 / 1 / 2 / 3; 27 | padding-top: 1rem; 28 | position: sticky; 29 | top: 0; 30 | background: inherit; 31 | z-index: 1; 32 | @media screen and (max-width: 52em) { 33 | grid-area: 1 / 1 / 2 /2; 34 | } 35 | `; 36 | const Side = styled.div` 37 | grid-area: 2 / 1 / 3 / 1; 38 | @media screen and (max-width: 52em) { 39 | display: ${({ toggle }) => (toggle ? 'none' : 'block')}; 40 | } 41 | `; 42 | 43 | const Main = styled.div` 44 | grid-area: 2 / 2 / 3 / 3; 45 | @media screen and (max-width: 52em) { 46 | grid-area: 2 / 1 / 2 /2; 47 | display: ${({ toggle }) => (toggle ? 'block' : 'none')}; 48 | } 49 | background: var(--colors-app-background); 50 | color: var(--colors-app-color); 51 | border-color: var(--colors-app-border-color); 52 | `; 53 | const ToggleButton = styled.button` 54 | display: none; 55 | @media screen and (max-width: 52em) { 56 | display: block; 57 | position: fixed; 58 | bottom: 0; 59 | right: 0; 60 | border-radius: 50%; 61 | background-color: #036fca; 62 | padding: 1rem; 63 | margin: 2rem; 64 | animation: 0.25s ease-in animation-1m49nxd; 65 | transition: 150ms ease-in-out background-color; 66 | border: 0; 67 | } 68 | `; 69 | const globalStyles = ` 70 | @import url('https://fonts.googleapis.com/css?family=Roboto+Mono&display=swap'); 71 | body { 72 | font-family: 'Inter', sans-serif; 73 | margin: 0; 74 | background: var(--colors-app-background); 75 | color: var(--colors-app-color); 76 | } 77 | * { 78 | box-sizing: border-box; 79 | } 80 | `; 81 | export function Layout({ children }) { 82 | const [toggle, setToggle] = React.useState(true); 83 | 84 | return ( 85 | <> 86 | 87 | 88 | 89 |
90 | 91 | 92 | 93 | 94 |
{children}
95 | 96 | setToggle(!toggle)}> 97 | {toggle ? : } 98 | 99 | 100 | ); 101 | } 102 | -------------------------------------------------------------------------------- /benchmarks/size/emotion/README.md: -------------------------------------------------------------------------------- 1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 2 | 3 | ## Available Scripts 4 | 5 | In the project directory, you can run: 6 | 7 | ### `yarn start` 8 | 9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 11 | 12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console. 14 | 15 | ### `yarn test` 16 | 17 | Launches the test runner in the interactive watch mode.
18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 19 | 20 | ### `yarn build` 21 | 22 | Builds the app for production to the `build` folder.
23 | It correctly bundles React in production mode and optimizes the build for the best performance. 24 | 25 | The build is minified and the filenames include the hashes.
26 | Your app is ready to be deployed! 27 | 28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 29 | 30 | ### `yarn eject` 31 | 32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 33 | 34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 35 | 36 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 37 | 38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 39 | 40 | ## Learn More 41 | 42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 43 | 44 | To learn React, check out the [React documentation](https://reactjs.org/). 45 | 46 | ### Code Splitting 47 | 48 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting 49 | 50 | ### Analyzing the Bundle Size 51 | 52 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size 53 | 54 | ### Making a Progressive Web App 55 | 56 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app 57 | 58 | ### Advanced Configuration 59 | 60 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration 61 | 62 | ### Deployment 63 | 64 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment 65 | 66 | ### `yarn build` fails to minify 67 | 68 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify 69 | -------------------------------------------------------------------------------- /benchmarks/size/filbert/README.md: -------------------------------------------------------------------------------- 1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 2 | 3 | ## Available Scripts 4 | 5 | In the project directory, you can run: 6 | 7 | ### `yarn start` 8 | 9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 11 | 12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console. 14 | 15 | ### `yarn test` 16 | 17 | Launches the test runner in the interactive watch mode.
18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 19 | 20 | ### `yarn build` 21 | 22 | Builds the app for production to the `build` folder.
23 | It correctly bundles React in production mode and optimizes the build for the best performance. 24 | 25 | The build is minified and the filenames include the hashes.
26 | Your app is ready to be deployed! 27 | 28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 29 | 30 | ### `yarn eject` 31 | 32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 33 | 34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 35 | 36 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 37 | 38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 39 | 40 | ## Learn More 41 | 42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 43 | 44 | To learn React, check out the [React documentation](https://reactjs.org/). 45 | 46 | ### Code Splitting 47 | 48 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting 49 | 50 | ### Analyzing the Bundle Size 51 | 52 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size 53 | 54 | ### Making a Progressive Web App 55 | 56 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app 57 | 58 | ### Advanced Configuration 59 | 60 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration 61 | 62 | ### Deployment 63 | 64 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment 65 | 66 | ### `yarn build` fails to minify 67 | 68 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify 69 | -------------------------------------------------------------------------------- /benchmarks/size/vanilla-css/README.md: -------------------------------------------------------------------------------- 1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 2 | 3 | ## Available Scripts 4 | 5 | In the project directory, you can run: 6 | 7 | ### `yarn start` 8 | 9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 11 | 12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console. 14 | 15 | ### `yarn test` 16 | 17 | Launches the test runner in the interactive watch mode.
18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 19 | 20 | ### `yarn build` 21 | 22 | Builds the app for production to the `build` folder.
23 | It correctly bundles React in production mode and optimizes the build for the best performance. 24 | 25 | The build is minified and the filenames include the hashes.
26 | Your app is ready to be deployed! 27 | 28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 29 | 30 | ### `yarn eject` 31 | 32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 33 | 34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 35 | 36 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 37 | 38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 39 | 40 | ## Learn More 41 | 42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 43 | 44 | To learn React, check out the [React documentation](https://reactjs.org/). 45 | 46 | ### Code Splitting 47 | 48 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting 49 | 50 | ### Analyzing the Bundle Size 51 | 52 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size 53 | 54 | ### Making a Progressive Web App 55 | 56 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app 57 | 58 | ### Advanced Configuration 59 | 60 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration 61 | 62 | ### Deployment 63 | 64 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment 65 | 66 | ### `yarn build` fails to minify 67 | 68 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify 69 | -------------------------------------------------------------------------------- /benchmarks/size/styled-components/README.md: -------------------------------------------------------------------------------- 1 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 2 | 3 | ## Available Scripts 4 | 5 | In the project directory, you can run: 6 | 7 | ### `yarn start` 8 | 9 | Runs the app in the development mode.
10 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser. 11 | 12 | The page will reload if you make edits.
13 | You will also see any lint errors in the console. 14 | 15 | ### `yarn test` 16 | 17 | Launches the test runner in the interactive watch mode.
18 | See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information. 19 | 20 | ### `yarn build` 21 | 22 | Builds the app for production to the `build` folder.
23 | It correctly bundles React in production mode and optimizes the build for the best performance. 24 | 25 | The build is minified and the filenames include the hashes.
26 | Your app is ready to be deployed! 27 | 28 | See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. 29 | 30 | ### `yarn eject` 31 | 32 | **Note: this is a one-way operation. Once you `eject`, you can’t go back!** 33 | 34 | If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project. 35 | 36 | Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own. 37 | 38 | You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it. 39 | 40 | ## Learn More 41 | 42 | You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started). 43 | 44 | To learn React, check out the [React documentation](https://reactjs.org/). 45 | 46 | ### Code Splitting 47 | 48 | This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting 49 | 50 | ### Analyzing the Bundle Size 51 | 52 | This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size 53 | 54 | ### Making a Progressive Web App 55 | 56 | This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app 57 | 58 | ### Advanced Configuration 59 | 60 | This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration 61 | 62 | ### Deployment 63 | 64 | This section has moved here: https://facebook.github.io/create-react-app/docs/deployment 65 | 66 | ### `yarn build` fails to minify 67 | 68 | This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify 69 | -------------------------------------------------------------------------------- /packages/stylesheet/index.js: -------------------------------------------------------------------------------- 1 | import { 2 | RAW, 3 | TYPES_CSS, 4 | TYPES_GLOBAL, 5 | TYPES_KEYFRAMES, 6 | } from '@filbert-js/types'; 7 | 8 | export function StyleSheet({ 9 | getRoot, 10 | createElement, 11 | findElementByStyleId, 12 | cssParser, 13 | css, 14 | }) { 15 | const _css = css || { 16 | [TYPES_GLOBAL]: {}, 17 | [TYPES_CSS]: {}, 18 | [TYPES_KEYFRAMES]: {}, 19 | }; 20 | const root = getRoot(); 21 | function createStyleTag(id, styleType, label) { 22 | const el = createElement('style'); 23 | [ 24 | ['data-type', 'styled-css'], 25 | ['id', id], 26 | ['styled-type', styleType], 27 | ['styled-component-type', label], 28 | ].forEach(([key, value]) => value && el.setAttribute(key, value)); 29 | return el; 30 | } 31 | function createStyles(id, css, sourceOrder, label) { 32 | if (!_css[TYPES_CSS][id]) { 33 | const el = createStyleTag(id, TYPES_CSS, label); 34 | const styles = cssParser({ css, namespace: `.${id}` }); 35 | el.append(styles); 36 | _css[TYPES_CSS][id] = styles; 37 | // ensure source order 38 | if (sourceOrder) { 39 | root.insertBefore(el, root.getChildById(sourceOrder)); 40 | } else { 41 | root.append(el); 42 | } 43 | } else { 44 | // ensure source order 45 | const el = root.getChildById(id); 46 | const elBefore = root.getChildById(sourceOrder); 47 | // check before changing element order 48 | if (sourceOrder && root.isBeforeChild(el, elBefore)) { 49 | root.insertBefore(el, elBefore); 50 | } 51 | } 52 | } 53 | function createKeyframes(keyframe) { 54 | if (!_css[TYPES_KEYFRAMES][keyframe]) { 55 | const el = createStyleTag(keyframe, TYPES_KEYFRAMES); 56 | const styles = `@keyframes ${keyframe} {${keyframe[RAW]}}`; 57 | el.append(styles); 58 | root.append(el); 59 | _css[TYPES_KEYFRAMES][keyframe] = styles; 60 | } 61 | } 62 | function createGlobalStyles(id, styles) { 63 | if (!_css[TYPES_GLOBAL][id]) { 64 | const el = createStyleTag(id, TYPES_GLOBAL); 65 | const classBlock = styles.trim(); 66 | el.append(classBlock); 67 | _css[TYPES_GLOBAL][id] = classBlock; 68 | root.append(el); 69 | } else { 70 | const el = root.getChildById(id); 71 | const classBlock = styles.trim(); 72 | 73 | el.append(classBlock); 74 | _css[TYPES_GLOBAL][id] = classBlock; 75 | } 76 | } 77 | function removeStyles(hash, type) { 78 | if (TYPES_CSS === type && _css[type][hash]) { 79 | const elUsingCls = findElementByStyleId(hash); 80 | if (!elUsingCls) { 81 | delete _css[type][hash]; 82 | root.getChildById(hash).remove(); 83 | } 84 | } else if (TYPES_GLOBAL === type) { 85 | delete _css[type][hash]; 86 | root.getChildById(hash).remove(); 87 | } 88 | } 89 | function getStyles() { 90 | return { root, css: _css }; 91 | } 92 | 93 | return { 94 | getStyles, 95 | createStyles, 96 | createKeyframes, 97 | createGlobalStyles, 98 | removeStyles, 99 | }; 100 | } 101 | -------------------------------------------------------------------------------- /filbert.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | --------------------------------------------------------------------------------