├── .editorconfig ├── .github └── workflows │ ├── docs.yml │ ├── main.yml │ └── size.yml ├── .gitignore ├── .npmrc ├── .nvmrc ├── .vscode ├── extensions.json └── settings.json ├── LICENSE ├── README.md ├── TODO.md ├── benchmarks ├── CHANGELOG.md ├── README.md ├── beamwind.min.mjs ├── oceanwind.min.mjs ├── package.json ├── run.mjs └── tsconfig.json ├── examples └── svelte │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── public │ ├── favicon.ico │ ├── index.html │ ├── logo.svg │ └── robots.txt │ ├── snowpack.config.js │ ├── src │ ├── app.svelte │ ├── index.ts │ └── types │ │ └── ambient.d.ts │ ├── svelte.config.js │ └── tsconfig.json ├── lerna.json ├── package-scripts.js ├── package.json ├── packages ├── beamwind │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package-scripts.js │ ├── package.json │ ├── src │ │ ├── __fixtures__ │ │ │ ├── process-plugins.d.ts │ │ │ └── process-plugins.mjs │ │ ├── index.test.ts │ │ └── index.ts │ └── tsconfig.json ├── colors │ ├── .nvmrc │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package-scripts.js │ ├── package.json │ ├── src │ │ ├── colors.test.ts │ │ ├── colors.ts │ │ ├── index.ts │ │ ├── system.test.ts │ │ └── system.ts │ └── tsconfig.json ├── core │ ├── .nvmrc │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package-scripts.js │ ├── package.json │ ├── src │ │ ├── __fixtures__ │ │ │ ├── ie11-reset.mjs │ │ │ ├── ie11-reset.mjs.d.ts │ │ │ └── theme.ts │ │ ├── __tests__ │ │ │ ├── api.json │ │ │ ├── api.test.ts │ │ │ ├── dark-mode.test.ts │ │ │ ├── hash.test.ts │ │ │ ├── ie11.test.ts │ │ │ ├── init.test.ts │ │ │ ├── injector-dom.test.ts │ │ │ ├── mode.test.ts │ │ │ ├── plugins.test.ts │ │ │ ├── precedence.test.ts │ │ │ ├── prefix.test.ts │ │ │ ├── ssr-no-op.test.ts │ │ │ ├── theme.test.ts │ │ │ └── util.test.ts │ │ ├── context.ts │ │ ├── css.ts │ │ ├── env.ts │ │ ├── hash.ts │ │ ├── helpers.ts │ │ ├── index.ts │ │ ├── injectors.ts │ │ ├── instance.ts │ │ ├── is.ts │ │ ├── modes.ts │ │ ├── plugins.ts │ │ ├── precedence.ts │ │ ├── prefix.ts │ │ ├── process.ts │ │ ├── theme.ts │ │ ├── types │ │ │ └── index.ts │ │ ├── util.ts │ │ └── variants.ts │ └── tsconfig.json ├── play │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package-scripts.js │ ├── package.json │ ├── src │ │ ├── index.test.ts │ │ └── index.ts │ └── tsconfig.json ├── preflight │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package-scripts.js │ ├── package.json │ ├── src │ │ ├── index.ts │ │ ├── preflight.test.ts │ │ └── preflight.ts │ └── tsconfig.json ├── preset-play │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package-scripts.js │ ├── package.json │ ├── src │ │ ├── __tests__ │ │ │ ├── play.test.ts │ │ │ └── ssr.test.ts │ │ ├── index.ts │ │ ├── is.ts │ │ ├── play.ts │ │ └── theme.ts │ └── tsconfig.json ├── preset-system │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package-scripts.js │ ├── package.json │ ├── src │ │ ├── index.ts │ │ ├── theme.test.ts │ │ ├── theme.ts │ │ └── types.ts │ └── tsconfig.json ├── preset-tailwind │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package-scripts.js │ ├── package.json │ ├── src │ │ ├── index.ts │ │ ├── theme.test.ts │ │ └── theme.ts │ └── tsconfig.json ├── reset │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package-scripts.js │ ├── package.json │ ├── src │ │ ├── index.ts │ │ ├── reset.test.ts │ │ └── reset.ts │ └── tsconfig.json ├── system │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package-scripts.js │ ├── package.json │ ├── src │ │ ├── index.test.ts │ │ └── index.ts │ └── tsconfig.json └── types │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package-scripts.js │ ├── package.json │ ├── src │ ├── common.ts │ ├── config.ts │ ├── core.ts │ ├── index.ts │ ├── instance.ts │ ├── mode.ts │ ├── theme.ts │ └── util.ts │ └── tsconfig.json ├── tsconfig.json ├── types ├── CHANGELOG.md ├── README.md ├── index.d.ts ├── modules.d.ts ├── package.json └── tsconfig.json └── yarn.lock /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | # All files should use 5 | # - tabs unless specified otherwise 6 | # - unix-style newlines with a newline ending every file 7 | [*] 8 | indent_style = space 9 | indent_size = 2 10 | end_of_line = lf 11 | charset = utf-8 12 | trim_trailing_whitespace = true 13 | insert_final_newline = true 14 | 15 | [*.md] 16 | trim_trailing_whitespace = false 17 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: Build and Deploy Docs 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | tags: 8 | - '*' 9 | 10 | jobs: 11 | build-and-deploy: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout 🛎️ 15 | uses: actions/checkout@v2 16 | with: 17 | # for the deployment to work correctly 18 | persist-credentials: false 19 | 20 | - name: Use Node ${{ matrix.node }} 21 | uses: actions/setup-node@v1 22 | with: 23 | node-version: ${{ matrix.node }} 24 | 25 | - name: Install 🔧 26 | uses: bahmutov/npm-install@v1 27 | 28 | - name: Build 🔧 29 | run: yarn run docs 30 | 31 | - name: Deploy 🚀 32 | uses: JamesIves/github-pages-deploy-action@3.7.1 33 | with: 34 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 35 | BASE_BRANCH: main 36 | BRANCH: gh-pages # The branch the action should deploy to. 37 | FOLDER: docs # The folder the action should deploy. 38 | CLEAN: true # Automatically remove deleted files from the deploy branch 39 | CLEAN_EXCLUDE: '["CNAME", ".nojekyll"]' 40 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: [push] 3 | jobs: 4 | build: 5 | name: Build, lint, and test on Node ${{ matrix.node }} and ${{ matrix.os }} 6 | 7 | runs-on: ${{ matrix.os }} 8 | strategy: 9 | matrix: 10 | node: ['14.x'] 11 | os: [ubuntu-latest] 12 | 13 | steps: 14 | - name: Checkout 🛎️ 15 | uses: actions/checkout@v2 16 | 17 | - name: Use Node ${{ matrix.node }} 18 | uses: actions/setup-node@v1 19 | with: 20 | node-version: ${{ matrix.node }} 21 | 22 | - name: Install 🔧 23 | uses: bahmutov/npm-install@v1 24 | 25 | - name: Test 26 | run: yarn run ci 27 | 28 | - name: Build 29 | run: yarn run build 30 | 31 | - name: Coveralls 32 | uses: coverallsapp/github-action@master 33 | with: 34 | github-token: ${{ secrets.GITHUB_TOKEN }} 35 | flag-name: build-${{ matrix.node }}-${{ matrix.os }} 36 | parallel: true 37 | 38 | finish: 39 | needs: build 40 | runs-on: ubuntu-latest 41 | steps: 42 | - name: Coveralls Finished 43 | uses: coverallsapp/github-action@master 44 | with: 45 | github-token: ${{ secrets.github_token }} 46 | parallel-finished: true 47 | -------------------------------------------------------------------------------- /.github/workflows/size.yml: -------------------------------------------------------------------------------- 1 | name: size 2 | on: [pull_request] 3 | jobs: 4 | size: 5 | runs-on: ubuntu-latest 6 | env: 7 | CI_JOB_NUMBER: 1 8 | steps: 9 | - name: Checkout repo 10 | uses: actions/checkout@v2 11 | 12 | - name: Install deps and build (with cache) 13 | uses: bahmutov/npm-install@v1 14 | 15 | - name: size-limit - @beamwind/core 16 | uses: andresz1/size-limit-action@v1 17 | with: 18 | github_token: ${{ secrets.GITHUB_TOKEN }} 19 | skip_step: install 20 | directory: packages/core 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .build 2 | build 3 | node_modules 4 | web_modules 5 | 6 | .cache 7 | dist 8 | __generated__ 9 | 10 | docs 11 | !packages/*/docs 12 | 13 | benchmarks/*.min.mjs 14 | 15 | # Svelte Component type defs 16 | *.svelte.tsx 17 | __svelte-jsx.d.ts 18 | __svelte-shims.d.ts 19 | 20 | # Logs 21 | logs 22 | *.log 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | lerna-debug.log* 27 | 28 | # Diagnostic reports (https://nodejs.org/api/report.html) 29 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 30 | 31 | # Runtime data 32 | pids 33 | *.pid 34 | *.seed 35 | *.pid.lock 36 | 37 | # Directory for instrumented libs generated by jscoverage/JSCover 38 | lib-cov 39 | 40 | # Coverage directory used by tools like istanbul 41 | coverage/ 42 | *.lcov 43 | 44 | # nyc test coverage 45 | .nyc_output 46 | 47 | # Dependency directories 48 | node_modules/ 49 | jspm_packages/ 50 | 51 | # TypeScript v1 declaration files 52 | typings/ 53 | 54 | # TypeScript cache 55 | *.tsbuildinfo 56 | 57 | # Optional npm cache directory 58 | .npm 59 | 60 | # Optional eslint cache 61 | .eslintcache 62 | 63 | # Optional REPL history 64 | .node_repl_history 65 | 66 | # Output of 'npm pack' 67 | *.tgz 68 | 69 | # Yarn Integrity file 70 | .yarn-integrity 71 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | registry = https://registry.npmjs.org/ 2 | -------------------------------------------------------------------------------- /.nvmrc: -------------------------------------------------------------------------------- 1 | v14 2 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "Orta.vscode-jest", 4 | "esbenp.prettier-vscode", 5 | "dbaeumer.vscode-eslint", 6 | "drknoxy.eslint-disable-snippets", 7 | "eg2.vscode-npm-script", 8 | "herrmannplatz.npm-dependency-links", 9 | "visualstudioexptteam.vscodeintellicode", 10 | "ibm.output-colorizer", 11 | "christian-kohler.path-intellisense", 12 | "kisstkondoros.vscode-gutter-preview", 13 | "philsinatra.nested-comments" 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib" 3 | } 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 [these people](https://github.com/kenoxa/beamwind/graphs/contributors) 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 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | Link to https://nerdcave.com/tailwind-cheat-sheet 2 | 3 | pre-commit hook to format files 4 | 5 | tailwind compat: compare generated CSS rule 6 | 7 | https://github.com/tailwindlabs/tailwindcss-aspect-ratio 8 | https://tailwindcss.com/docs/container 9 | 10 | - @beamwind/prose: https://tailwindcss.com/docs/typography-plugin 11 | - implement as plugin?? 12 | 13 | Server Side Rendering: @beamwind/ssr 14 | 15 | https://tailwindui.com/components 16 | @tailwindcss/forms: https://github.com/tailwindlabs/tailwindcss-forms 17 | 18 | @beamwind/styled like styled-components 19 | 20 | Autocompletion: 21 | https://tailwindcss.com/docs/intellisense 22 | https://github.com/kingdaro/typescript-plugin-tw-template 23 | 24 | https://github.com/ben-rogerson/twin.macro 25 | 💥 Add important to any class with a trailing bang! 26 | 27 | tw.macro like https://github.com/ben-rogerson/twin.macro 28 | 29 | bw`hidden!` 30 | // ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ 31 | { "display": "none !important" } 32 | 33 | @beamwind/css like https://emotion.sh/docs/@emotion/css 34 | maybe useful for inline plugins or advanced use cases 35 | 36 | - convert declarations in to dash case 37 | - nested declarations as inline plugins 38 | -------------------------------------------------------------------------------- /benchmarks/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | ## [1.0.2](https://github.com/kenoxa/beamwind/compare/@beamwind/benchmarks@1.0.1...@beamwind/benchmarks@1.0.2) (2020-11-25) 7 | 8 | **Note:** Version bump only for package @beamwind/benchmarks 9 | 10 | ## 1.0.1 (2020-11-25) 11 | 12 | **Note:** Version bump only for package @beamwind/benchmarks 13 | -------------------------------------------------------------------------------- /benchmarks/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | - [@beamwind/benchmarks](#beamwindbenchmarks) 6 | - [Results](#results) 7 | 8 | 9 | 10 | # @beamwind/benchmarks 11 | 12 | > beanchmarks of oceanwind vs beamwind 13 | 14 | ```sh 15 | node run.mjs 16 | ``` 17 | 18 | ## Results 19 | 20 | ``` 21 | # Strings 22 | oceanwind x 140,151 ops/sec ±1.40% (89 runs sampled) 23 | beamwind x 1,028,192 ops/sec ±1.46% (92 runs sampled) 24 | 25 | # Arrays 26 | oceanwind x 144,539 ops/sec ±1.59% (84 runs sampled) 27 | beamwind x 1,376,261 ops/sec ±2.25% (83 runs sampled) 28 | 29 | # Objects 30 | oceanwind x 103,511 ops/sec ±3.49% (83 runs sampled) 31 | beamwind x 873,491 ops/sec ±1.40% (86 runs sampled) 32 | 33 | # Grouping 34 | oceanwind x 27,725 ops/sec ±6.31% (85 runs sampled) 35 | beamwind x 230,017 ops/sec ±1.83% (87 runs sampled) 36 | ``` 37 | 38 | Using https://github.com/lukejacksonn/oceanwind/pull/36 39 | 40 | ``` 41 | # Setup and first insert 42 | oceanwind x 17,692 ops/sec ±2.80% (82 runs sampled) 43 | beamwind x 59,437 ops/sec ±1.64% (90 runs sampled) 44 | 45 | # Strings 46 | oceanwind x 15,379 ops/sec ±0.80% (90 runs sampled) 47 | beamwind x 95,811 ops/sec ±1.29% (89 runs sampled) 48 | 49 | # Arrays 50 | oceanwind x 131,698 ops/sec ±1.24% (89 runs sampled) 51 | beamwind x 947,284 ops/sec ±0.93% (90 runs sampled) 52 | 53 | # Objects 54 | oceanwind x 102,932 ops/sec ±1.44% (92 runs sampled) 55 | beamwind x 612,728 ops/sec ±0.52% (95 runs sampled) 56 | 57 | # Grouping 58 | oceanwind x 31,644 ops/sec ±1.22% (92 runs sampled) 59 | beamwind x 137,831 ops/sec ±1.27% (90 runs sampled) 60 | ``` 61 | -------------------------------------------------------------------------------- /benchmarks/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@beamwind/benchmarks", 3 | "version": "1.0.2", 4 | "private": "true", 5 | "type": "module", 6 | "dependencies": { 7 | "beamwind": "^1.2.0", 8 | "benchmark": "^2.1.4", 9 | "oceanwind": "^0.10.0" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /benchmarks/run.mjs: -------------------------------------------------------------------------------- 1 | import benchmark from 'benchmark' 2 | 3 | import { themed } from './oceanwind.min.mjs' 4 | 5 | // Build beamwind 6 | // esbuild --platform=node --target=node14 --format=esm --outfile=benchmarks/beamwind.min.mjs --minify --bundle packages/beamwind/src/index.ts 7 | import { bw, setup, strict, createInstance } from './beamwind.min.mjs' 8 | 9 | const ow = themed({ strict: true }) 10 | setup({ mode: strict }) 11 | 12 | const { Suite } = benchmark 13 | 14 | benchInitial() 15 | 16 | bench('Strings', (impl) => [ 17 | impl('min-h-screen bg-gray-100 py-6 flex flex-col justify-center sm:py-12'), 18 | impl('absolute inset-0 shadow-lg'), 19 | impl('py-8 text-base leading-6 space-y-4 text-gray-700 sm:text-lg sm:leading-7'), 20 | ]) 21 | // TODO bench('Tag Template Literal', (impl) => impl`bg-gray-500 ${false && 'rounded'}`) 22 | bench('Arrays', (impl) => impl(['bg-gray-500', false && 'rounded'])) 23 | bench('Objects', (impl) => impl({ 'bg-gray-500': true, rounded: true })) 24 | bench( 25 | 'Grouping', 26 | (impl) => impl` 27 | sm:hover:( 28 | bg-black 29 | text-white 30 | ) 31 | md:(bg-white hover:text-black) 32 | `, 33 | ) 34 | 35 | function bench(name, run) { 36 | console.log(`\n# ${name}`) 37 | 38 | new Suite() 39 | .add('oceanwind', () => run(ow)) 40 | .add('beamwind', () => run(bw)) 41 | .on('cycle', (event) => console.log(` ${event.target}`)) 42 | .run() 43 | } 44 | 45 | function benchInitial() { 46 | console.log(`\n# Setup and first insert`) 47 | const tokens = 'rounded underline uppercase' 48 | 49 | new Suite() 50 | .add('oceanwind', () => { 51 | const ow = themed({ strict: true }) 52 | return ow(tokens) 53 | }) 54 | .add('beamwind', () => { 55 | const { bw } = createInstance({ mode: strict }) 56 | return bw(tokens) 57 | }) 58 | .on('cycle', (event) => console.log(` ${event.target}`)) 59 | .run() 60 | } 61 | -------------------------------------------------------------------------------- /benchmarks/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/tsconfig", 3 | "extends": "../tsconfig.json", 4 | "include": ["."] 5 | } 6 | -------------------------------------------------------------------------------- /examples/svelte/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # 1.2.0 (2020-11-25) 7 | 8 | ### Features 9 | 10 | - add svelte example ([a029ed6](https://github.com/kenoxa/beamwind/commit/a029ed6267b1a1816dec74dbaaacacf6cfbd2615)) 11 | 12 | # 1.1.0 (2020-11-25) 13 | 14 | ### Features 15 | 16 | - add svelte example ([a029ed6](https://github.com/kenoxa/beamwind/commit/a029ed6267b1a1816dec74dbaaacacf6cfbd2615)) 17 | -------------------------------------------------------------------------------- /examples/svelte/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 [these people](https://github.com/kenoxa/beamwind/graphs/contributors) 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 | -------------------------------------------------------------------------------- /examples/svelte/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | - [New Project](#new-project) 6 | - [Available Scripts](#available-scripts) 7 | 8 | 9 | 10 | # New Project 11 | 12 | > ✨ Bootstrapped with Create Snowpack App (CSA). 13 | 14 | ## Available Scripts 15 | 16 | ### npm start 17 | 18 | Runs the app in the development mode. 19 | Open http://localhost:8080 to view it in the browser. 20 | 21 | The page will reload if you make edits. 22 | You will also see any lint errors in the console. 23 | 24 | ### npm test 25 | 26 | Launches the test runner in the interactive watch mode. 27 | See the section about running tests for more information. 28 | 29 | ### npm run build 30 | 31 | Builds a static copy of your site to the `build/` folder. 32 | Your app is ready to be deployed! 33 | 34 | **For the best production performance:** Add a build bundler plugin like [@snowpack/plugin-webpack](https://github.com/snowpackjs/snowpack/tree/master/plugins/plugin-webpack) or [snowpack-plugin-rollup-bundle](https://github.com/ParamagicDev/snowpack-plugin-rollup-bundle) to your `snowpack.config.json` config file. 35 | 36 | ### Q: What about Eject? 37 | 38 | No eject needed! Snowpack guarantees zero lock-in, and CSA strives for the same. 39 | -------------------------------------------------------------------------------- /examples/svelte/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@beamwind/example-svelte", 3 | "version": "1.2.0", 4 | "private": true, 5 | "description": "beamwind svelte exmaple", 6 | "keywords": [ 7 | "beamwind", 8 | "tailwind" 9 | ], 10 | "homepage": "https://github.com/kenoxa/beamwind#readme", 11 | "bugs": { 12 | "url": "https://github.com/kenoxa/beamwind/issues" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/kenoxa/beamwind.git", 17 | "directory": "examples/svelte" 18 | }, 19 | "license": "MIT", 20 | "author": "Kenoxa GmbH ", 21 | "main": "src/index.ts", 22 | "scripts": { 23 | "build": "snowpack build", 24 | "check": "svelte-check", 25 | "start": "snowpack dev", 26 | "start:reload": "snowpack dev --reload" 27 | }, 28 | "prettier": "@carv/prettier-config", 29 | "eslintConfig": { 30 | "extends": "@carv/eslint-config", 31 | "root": true 32 | }, 33 | "dependencies": { 34 | "@beamwind/play": "^2.0.0", 35 | "svelte": "^3.24.0" 36 | }, 37 | "devDependencies": { 38 | "@carv/types": "^1.3.1", 39 | "@snowpack/plugin-svelte": "^3.3.0", 40 | "@snowpack/web-test-runner-plugin": "^0.1.4", 41 | "@testing-library/svelte": "^3.0.0", 42 | "@types/snowpack-env": "^2.3.0", 43 | "chai": "^4.2.0", 44 | "snowpack": "^2.17.1", 45 | "svelte-check": "^1.1.11", 46 | "svelte-preprocess": "^4.0.8" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /examples/svelte/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kenoxa/beamwind/e503a49330b02247abf3ffd9bc85e2f0b6f04c5c/examples/svelte/public/favicon.ico -------------------------------------------------------------------------------- /examples/svelte/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Snowpack App 9 | 10 | 11 | 12 | 13 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /examples/svelte/public/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /examples/svelte/public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /examples/svelte/snowpack.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import("snowpack").SnowpackUserConfig } */ 2 | module.exports = { 3 | mount: { 4 | public: '/', 5 | src: '/_dist_', 6 | }, 7 | plugins: ['@snowpack/plugin-svelte'], 8 | install: [ 9 | /* ... */ 10 | ], 11 | installOptions: { 12 | packageLookupFields: ['esnext'], 13 | installTypes: true, 14 | rollup: { 15 | context: 'self', 16 | }, 17 | }, 18 | devOptions: { 19 | /* ... */ 20 | }, 21 | buildOptions: { 22 | baseUrl: '/', 23 | }, 24 | proxy: { 25 | /* ... */ 26 | }, 27 | alias: { 28 | beamwind: 'beamwind/dist/esnext/beamwind.js', 29 | '@beamwind/colors': '@beamwind/colors/dist/esnext/colors.js', 30 | '@beamwind/core': '@beamwind/core/dist/esnext/core.js', 31 | '@beamwind/play': '@beamwind/play/dist/esnext/play.js', 32 | '@beamwind/preflight': '@beamwind/preflight/dist/esnext/preflight.js', 33 | '@beamwind/preset-play': '@beamwind/preset-play/dist/esnext/preset-play.js', 34 | '@beamwind/preset-system': '@beamwind/preset-system/dist/esnext/preset-system.js', 35 | '@beamwind/preset-tailwind': '@beamwind/preset-tailwind/dist/esnext/preset-tailwind.js', 36 | '@beamwind/reset': '@beamwind/reset/dist/esnext/reset.js', 37 | '@beamwind/system': '@beamwind/system/dist/esnext/system.js', 38 | '@beamwind/types': '@beamwind/types/dist/esnext/types.js', 39 | }, 40 | } 41 | -------------------------------------------------------------------------------- /examples/svelte/src/index.ts: -------------------------------------------------------------------------------- 1 | import { setup } from '@beamwind/play' 2 | 3 | if (import.meta.env.MODE !== 'production') { 4 | setup({ hash: false }) 5 | } 6 | 7 | import App from './app.svelte' 8 | 9 | const app = new App({ 10 | target: document.body, 11 | }) 12 | 13 | export default app 14 | 15 | // Hot Module Replacement (HMR) - Remove this snippet to remove HMR. 16 | // Learn more: https://www.snowpack.dev/#hot-module-replacement 17 | if (import.meta.hot) { 18 | import.meta.hot.accept() 19 | import.meta.hot.dispose(() => { 20 | app.$destroy() 21 | }) 22 | } 23 | -------------------------------------------------------------------------------- /examples/svelte/src/types/ambient.d.ts: -------------------------------------------------------------------------------- 1 | import '@carv/types' 2 | import 'svelte' 3 | -------------------------------------------------------------------------------- /examples/svelte/svelte.config.js: -------------------------------------------------------------------------------- 1 | const autoPreprocess = require('svelte-preprocess') 2 | 3 | module.exports = { 4 | preprocess: autoPreprocess({ 5 | sourceMap: true, 6 | 7 | defaults: { 8 | script: 'typescript', 9 | }, 10 | 11 | /** 12 | * Type checking can be skipped by setting 'transpileOnly: true'. 13 | * This speeds up your build process. 14 | * 15 | * Checking is done using svelte-check 16 | */ 17 | typescript: { 18 | transpileOnly: true, 19 | }, 20 | }), 21 | } 22 | -------------------------------------------------------------------------------- /examples/svelte/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/tsconfig", 3 | "extends": "../../tsconfig.json", 4 | "include": ["src", "../../types"] 5 | } 6 | -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "npmClient": "yarn", 3 | "version": "independent", 4 | "useWorkspaces": true, 5 | "command": { 6 | "publish": { 7 | "contents": "dist", 8 | "conventionalCommits": true, 9 | "createRelease": "github" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /package-scripts.js: -------------------------------------------------------------------------------- 1 | module.exports = require('@carv/esbundle/nps-preset') 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@beamwind/monorepo", 3 | "version": "0.0.0-independent", 4 | "private": true, 5 | "homepage": "https://github.com/kenoxa/beamwind", 6 | "bugs": "https://github.com/kenoxa/beamwind/issues", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/kenoxa/beamwind.git" 10 | }, 11 | "license": "MIT", 12 | "author": "Kenoxa GmbH ", 13 | "workspaces": [ 14 | "benchmarks", 15 | "types", 16 | "examples/*", 17 | "packages/*" 18 | ], 19 | "scripts": { 20 | "build": "lerna run --no-private build", 21 | "ci": "nps", 22 | "clean": "nps clean && lerna exec -- nps clean", 23 | "docs": "nps docs && lerna exec --no-private -- nps docs.package", 24 | "format": "nps format && lerna exec -- nps format.package", 25 | "preinstall": "npx only-allow yarn", 26 | "publish": "lerna publish --no-private", 27 | "test": "nps", 28 | "preversion": "lerna exec -- nps prepare && nps test", 29 | "version": "lerna exec -- nps version" 30 | }, 31 | "prettier": "@carv/prettier-config", 32 | "eslintConfig": { 33 | "extends": "@carv/eslint-config", 34 | "root": true 35 | }, 36 | "jest": { 37 | "projects": [ 38 | "/packages/*" 39 | ] 40 | }, 41 | "devDependencies": { 42 | "@carv/esbundle": "^1.1.5", 43 | "@carv/eslint-config": "^1.6.0", 44 | "@carv/jest-preset": "^1.1.6", 45 | "@carv/prettier-config": "^1.1.0", 46 | "@carv/tsconfig": "^1.3.0", 47 | "@carv/types": "^1.3.1", 48 | "eslint": "^7.3.1", 49 | "jest": "^26.1.0", 50 | "lerna": "^3.22.1", 51 | "nps": "^5.9.12", 52 | "only-allow": "^1.0.0", 53 | "prettier": "^2.0.5", 54 | "typescript": "^4.1.0" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /packages/beamwind/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | ## [2.1.1](https://github.com/kenoxa/beamwind/compare/beamwind@2.1.0...beamwind@2.1.1) (2020-12-05) 7 | 8 | **Note:** Version bump only for package beamwind 9 | 10 | # [2.1.0](https://github.com/kenoxa/beamwind/compare/beamwind@2.0.3...beamwind@2.1.0) (2020-12-04) 11 | 12 | ### Features 13 | 14 | - transform-gpu ([a28342f](https://github.com/kenoxa/beamwind/commit/a28342fbd7ae8a2a2d035306e35abbd40c54bdff)) 15 | 16 | ## [2.0.3](https://github.com/kenoxa/beamwind/compare/beamwind@2.0.2...beamwind@2.0.3) (2020-12-02) 17 | 18 | **Note:** Version bump only for package beamwind 19 | 20 | ## [2.0.2](https://github.com/kenoxa/beamwind/compare/beamwind@2.0.1...beamwind@2.0.2) (2020-12-01) 21 | 22 | **Note:** Version bump only for package beamwind 23 | 24 | ## [2.0.1](https://github.com/kenoxa/beamwind/compare/beamwind@2.0.0...beamwind@2.0.1) (2020-12-01) 25 | 26 | **Note:** Version bump only for package beamwind 27 | 28 | # [2.0.0](https://github.com/kenoxa/beamwind/compare/beamwind@1.5.1...beamwind@2.0.0) (2020-11-30) 29 | 30 | ### Bug Fixes 31 | 32 | - filter out vendor specific pseudo classes to prevent unnecessary warnings ([ef2b467](https://github.com/kenoxa/beamwind/commit/ef2b467310a6ecc1fc7222cf6dd9f099b432f52b)) 33 | -------------------------------------------------------------------------------- /packages/beamwind/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 [these people](https://github.com/kenoxa/beamwind/graphs/contributors) 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/beamwind/README.md: -------------------------------------------------------------------------------- 1 | # beamwind 2 | 3 | > ready to go beamwind with [@beamwind/preflight](https://github.com/kenoxa/beamwind/blob/main/packages/preflight) and [@beamwind/preset-tailwind](https://github.com/kenoxa/beamwind/blob/main/packages/preset-tailwind) 4 | 5 | [![MIT License](https://flat.badgen.net/github/license/kenoxa/beamwind)](https://github.com/kenoxa/beamwind/blob/main/LICENSE) 6 | [![Latest Release](https://flat.badgen.net/npm/v/beamwind?icon=npm&label)](https://www.npmjs.com/package/beamwind) 7 | [![Github](https://flat.badgen.net/badge/icon/kenoxa%2Fbeamwind?icon=github&label)](https://github.com/kenoxa/beamwind/blob/main/packages/beamwind) 8 | [![Typescript](https://flat.badgen.net/badge/icon/included?icon=typescript&label)](https://unpkg.com/browse/beamwind/types/beamwind.d.ts) 9 | [![Bundle Size](https://flat.badgen.net/bundlephobia/minzip/beamwind?icon=packagephobia&label&color=blue)](https://bundlephobia.com/result?p=beamwind) 10 | 11 | > [Read the docs](https://beamwind.js.org) | 12 | > [API](https://beamwind.js.org/packages/beamwind) | 13 | > [Change Log](https://github.com/kenoxa/beamwind/blob/main/packages/beamwind/CHANGELOG.md) | 14 | > [⚡️ Demo](https://esm.codes/#Ly8gQmVhbXdpbmQgZGVtbyAoYmFzZWQgb24gY29kZSBieSBAbHVrZWphY2tzb25uIC0gY3JlYXRvciBvZiBvY2VhbndpbmQpCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAKaW1wb3J0IHsgcmVuZGVyLCBodG1sIH0gZnJvbSAnaHR0cHM6Ly9ucG0ucmV2ZXJzZWh0dHAuY29tL3ByZWFjdCxwcmVhY3QvaG9va3MsaHRtL3ByZWFjdCc7CmltcG9ydCB7IGJ3IH0gZnJvbSAnaHR0cHM6Ly91bnBrZy5jb20vYmVhbXdpbmQ/bW9kdWxlJwoKCmNvbnN0IHN0eWxlID0gewogIC8vIEV4YW1wbGUgb2YgYWJzdHJhY3RlZCBzdHlsZQogIGNvbnRhaW5lcjogYndgaC1mdWxsIGJnLXBpbmstNzAwIHRleHQtd2hpdGUgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXJgCn0KCnJlbmRlcigKICBodG1sYAogICAgPGRpdiBjbGFzcz0ke3N0eWxlLmNvbnRhaW5lcn0+CiAgICAgIDxoMSBjbGFzcz0kewogICAgICAgIC8vIEV4YW1wbGUgb2YgYW4gaW5saW5lIHN0eWxlCiAgICAgICAgYndgCiAgICAgICAgICB0ZXh0KDR4bCB1bmRlcmxpbmUpCiAgICAgICAgICBmb250KGJvbGQgc2FucykKICAgICAgICAgIHRyYW5zaXRpb24KICAgICAgICAgIGhvdmVyOih0cmFuc2Zvcm0gcm90YXRlLTYgc2NhbGUtMTI1IGN1cnNvci1wb2ludGVyKQogICAgICAgICAgYWN0aXZlOih0cmFuc2Zvcm0gLXJvdGF0ZS0xMiBzY2FsZS0xNTApCiAgICAgICAgYAogICAgICB9PkhlbGxvIFdvcmxkPC9oMT4KICAgIDwvZGl2PgogIGAsCiAgZG9jdW1lbnQuYm9keQopOw==) 15 | 16 | --- 17 | 18 | 19 | 20 | 21 | 22 | 23 | - [Installation](#installation) 24 | - [Usage](#usage) 25 | - [Contribute](#contribute) 26 | - [License](#license) 27 | 28 | 29 | 30 | 31 | ## Installation 32 | 33 | ```sh 34 | npm install beamwind 35 | ``` 36 | 37 | ## Usage 38 | 39 | > Please refer to the [main documentation](https://beamwind.js.org#usage) and [@beamwind/preset-tailwind](https://github.com/kenoxa/beamwind/blob/main/packages/preset-tailwind) for further information. 40 | 41 | ```js 42 | import { bw } from 'beamwind' 43 | 44 | bw`text-purple-500` 45 | ``` 46 | 47 | For further customization `setup` is exported: 48 | 49 | ```js 50 | import { bw, setup } from 'beamwind' 51 | 52 | setup({ 53 | colors: { 54 | 'red-500': '#DC2626', 55 | }, 56 | }) 57 | 58 | bw`text-red-500` // will result in a DC2626 text-color 59 | ``` 60 | 61 | ## Contribute 62 | 63 | Thanks for being willing to contribute! 64 | 65 | > This project is free and open-source, so if you think this project can help you or anyone else, you may [star it on GitHub](https://github.com/kenoxa/beamwind). Feel free to [open an issue](https://github.com/kenoxa/beamwind/issues) if you have any idea, question, or you've found a bug. 66 | 67 | **Working on your first Pull Request?** You can learn how from this _free_ series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) 68 | 69 | We are following the [Conventional Commits](https://www.conventionalcommits.org) convention. 70 | 71 | ### Sponsors 72 | 73 | [![Kenoxa GmbH](https://images.opencollective.com/kenoxa/9c25796/logo/68.png)](https://www.kenoxa.com) [Kenoxa GmbH](https://www.kenoxa.com) 74 | 75 | ## License 76 | 77 | [MIT](https://github.com/kenoxa/beamwind/blob/main/LICENSE) © [Kenoxa GmbH](https://kenoxa.com) 78 | -------------------------------------------------------------------------------- /packages/beamwind/package-scripts.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../package-scripts') 2 | -------------------------------------------------------------------------------- /packages/beamwind/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "beamwind", 3 | "version": "2.1.1", 4 | "description": "ready to go beamwind tailwind theme and preflight", 5 | "keywords": [ 6 | "beamwind", 7 | "tailwind" 8 | ], 9 | "homepage": "https://github.com/kenoxa/beamwind#readme", 10 | "bugs": { 11 | "url": "https://github.com/kenoxa/beamwind/issues" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/kenoxa/beamwind.git", 16 | "directory": "packages/beamwind" 17 | }, 18 | "license": "MIT", 19 | "author": "Kenoxa GmbH ", 20 | "main": "src/index.ts", 21 | "scripts": { 22 | "build": "nps", 23 | "postbuild": "size-limit", 24 | "prepublishOnly": "nps", 25 | "size": "size-limit", 26 | "test": "nps" 27 | }, 28 | "prettier": "@carv/prettier-config", 29 | "eslintConfig": { 30 | "extends": "@carv/eslint-config", 31 | "root": true 32 | }, 33 | "jest": { 34 | "preset": "@carv/jest-preset" 35 | }, 36 | "dependencies": { 37 | "@beamwind/core": "^2.3.0", 38 | "@beamwind/preflight": "^2.0.2", 39 | "@beamwind/preset-tailwind": "^2.0.2" 40 | }, 41 | "devDependencies": { 42 | "@size-limit/preset-small-lib": "^4.6.0", 43 | "dlv": "^1.1.3", 44 | "nps": "^5.9.12", 45 | "size-limit": "^4.6.0", 46 | "tailwindcss": "^2.0.1" 47 | }, 48 | "publishConfig": { 49 | "access": "public" 50 | }, 51 | "size-limit": [ 52 | { 53 | "path": "./dist/script/beamwind.js", 54 | "limit": "11 KB" 55 | } 56 | ] 57 | } 58 | -------------------------------------------------------------------------------- /packages/beamwind/src/__fixtures__/process-plugins.d.ts: -------------------------------------------------------------------------------- 1 | export declare function processPlugins(): { 2 | screens: Record 3 | variants: string[] 4 | directives: Record }> 5 | darkMode: false | 'media' | 'class' 6 | prefix: string 7 | separator: string 8 | } 9 | -------------------------------------------------------------------------------- /packages/beamwind/src/__fixtures__/process-plugins.mjs: -------------------------------------------------------------------------------- 1 | import dlv from 'dlv' 2 | 3 | import corePlugins from 'tailwindcss/lib/corePlugins.js' 4 | import resolveConfig from 'tailwindcss/lib/util/resolveConfig.js' 5 | import defaultConfig from 'tailwindcss/stubs/defaultConfig.stub.js' 6 | import transformThemeValue from 'tailwindcss/lib/util/transformThemeValue.js' 7 | 8 | export function processPlugins() { 9 | const config = resolveConfig([defaultConfig]) 10 | 11 | const plugins = [...corePlugins(config), ...dlv(config, 'plugins', [])] 12 | 13 | const { 14 | theme: { screens }, 15 | variantOrder: variants, 16 | darkMode, 17 | prefix, 18 | separator, 19 | } = config 20 | 21 | // eslint-disable-next-line unicorn/consistent-function-scoping 22 | const applyConfiguredPrefix = (selector) => selector 23 | 24 | const getConfigValue = (path, defaultValue) => (path ? dlv(config, path, defaultValue) : config) 25 | 26 | const utilities = {} 27 | 28 | plugins.forEach((plugin) => { 29 | if (plugin.__isOptionsFunction) { 30 | plugin = plugin() 31 | } 32 | 33 | const handler = typeof plugin === 'function' ? plugin : dlv(plugin, 'handler', () => {}) 34 | 35 | handler({ 36 | // Postcss, 37 | config: getConfigValue, 38 | 39 | theme: (path, defaultValue) => { 40 | const [pathRoot, ...subPaths] = path.split('.') 41 | 42 | const value = getConfigValue(['theme', pathRoot, ...subPaths], defaultValue) 43 | 44 | return transformThemeValue(pathRoot)(value) 45 | }, 46 | 47 | corePlugins: (path) => { 48 | if (Array.isArray(config.corePlugins)) { 49 | return config.corePlugins.includes(path) 50 | } 51 | 52 | return getConfigValue(`corePlugins.${path}`, true) 53 | }, 54 | 55 | variants: (path, defaultValue) => { 56 | if (Array.isArray(config.variants)) { 57 | return config.variants 58 | } 59 | 60 | return getConfigValue(`variants.${path}`, defaultValue) 61 | }, 62 | 63 | // No escaping of class names as we use theme as directives 64 | e: (className) => className, 65 | 66 | prefix: applyConfiguredPrefix, 67 | 68 | addUtilities: (newUtilities) => { 69 | // => const defaultOptions = { variants: [], respectPrefix: true, respectImportant: true } 70 | 71 | // options = Array.isArray(options) 72 | // ? { ...defaultOptions, variants: options } 73 | // : { ...defaultOptions, ...options } 74 | 75 | // .directive => CSS rule 76 | Object.assign(utilities, ...(Array.isArray(newUtilities) ? newUtilities : [newUtilities])) 77 | 78 | // =>pluginUtilities.push( 79 | // wrapWithLayer(wrapWithVariants(styles.nodes, options.variants), 'utilities'), 80 | // ) 81 | }, 82 | 83 | addComponents: (_components, _options) => { 84 | // => const defaultOptions = { variants: [], respectPrefix: true } 85 | // options = Array.isArray(options) 86 | // ? { ...defaultOptions, variants: options } 87 | // : { ...defaultOptions, ...options } 88 | // pluginComponents.push( 89 | // wrapWithLayer(wrapWithVariants(styles.nodes, options.variants), 'components'), 90 | // ) 91 | }, 92 | 93 | addBase: (_baseStyles) => { 94 | // => pluginBaseStyles.push(wrapWithLayer(parseStyles(baseStyles), 'base')) 95 | }, 96 | 97 | addVariant: (_name, _generator, _options = {}) => { 98 | // =>pluginVariantGenerators[name] = generateVariantFunction(generator, options) 99 | }, 100 | }) 101 | }) 102 | 103 | const directives = { 104 | group: { selector: '.group', properties: {} }, 105 | } 106 | 107 | for (const selector of Object.keys(utilities)) { 108 | // '@keyframes spin' 109 | if (selector[0] === '@') { 110 | continue 111 | } 112 | 113 | // '.ordinal, .slashed-zero, .lining-nums, .oldstyle-nums' 114 | if (selector.includes(',')) { 115 | continue 116 | } 117 | 118 | // '.placeholder-black::placeholder' 119 | // '.divide-pink-50 > :not([hidden]) ~ :not([hidden])' 120 | const [_, directive] = /^\.([^\s:]+)/.exec(selector) || [] 121 | 122 | if (directive) { 123 | // Unescape 124 | // '.w-4\\/5' 125 | // '.space-x-2\\.5' 126 | directives[directive.replace(/\\/g, '')] = { 127 | selector, 128 | properties: utilities[selector], 129 | } 130 | } 131 | } 132 | 133 | return { 134 | screens, 135 | variants, 136 | directives, 137 | darkMode, 138 | prefix, 139 | separator, 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /packages/beamwind/src/index.test.ts: -------------------------------------------------------------------------------- 1 | import { bw, setup, strict } from '.' 2 | 3 | setup({ mode: strict }) 4 | 5 | test('smoke', () => { 6 | expect( 7 | bw`absolute inset-0 bg-gradient-to-r from-blue-400 to-blue-500 shadow-lg transform -skew-y-6 sm:skew-y-0 sm:-rotate-6 sm:rounded-3xl`, 8 | ).toBe( 9 | '_1mkfpkn _o006n8 _1gt8na1 _3r61se _b5dbz4 _lae5pa _gqktp6 _1iwjs3j _1w053pr _1vzslrt _9pmjrn', 10 | ) 11 | }) 12 | 13 | test('readme example', () => { 14 | expect(bw`h-full bg-pink-700 text-white flex items-center justify-center`).toBe( 15 | '_ma35kl _jlwdch _hmry11 _1l0yvu6 _1ylnts1 _qemgvh', 16 | ) 17 | 18 | expect( 19 | bw` 20 | text(4xl underline) 21 | font(bold sans) 22 | transition 23 | hover:(transform rotate-6 scale-125 cursor-pointer) 24 | active:(transform -rotate-12 scale-150) 25 | `, 26 | ).toBe( 27 | '_9zien4 _1rn96fu _1u8tsvs _vx8z01 _iniysy _1crosn3 _fim2ix _z6b2rb _vdrcah _vzti3v _rqq84r _1mwh623', 28 | ) 29 | }) 30 | 31 | test('all tailwind directives are available', async () => { 32 | const { processPlugins } = await import('./__fixtures__/process-plugins') 33 | 34 | const { directives } = processPlugins() 35 | 36 | for (const directive of Object.keys(directives)) { 37 | try { 38 | expect(bw(directive)).toBeTruthy() 39 | } catch (error) { 40 | if (isFontVariantNumeric(directive)) { 41 | // TODO https://tailwindcss.com/docs/font-variant-numeric 42 | } else { 43 | console.warn(directive, directives[directive]) 44 | throw error 45 | } 46 | } 47 | } 48 | }) 49 | 50 | function isFontVariantNumeric(directive: string): boolean { 51 | return ( 52 | directive === 'ordinal' || 53 | directive.endsWith('-zero') || 54 | directive.endsWith('-nums') || 55 | directive.endsWith('-fractions') 56 | ) 57 | } 58 | -------------------------------------------------------------------------------- /packages/beamwind/src/index.ts: -------------------------------------------------------------------------------- 1 | import tailwind from '@beamwind/preset-tailwind' 2 | import preflight from '@beamwind/preflight' 3 | import { createInstance } from '@beamwind/core' 4 | 5 | const instance = createInstance([tailwind(), preflight()]) 6 | 7 | export const { bw } = instance 8 | export const { setup } = instance 9 | export const { theme } = instance 10 | 11 | // Re-export common configuration utilities 12 | export { 13 | strict, 14 | warn, 15 | noprefix, 16 | cyrb32, 17 | cssomInjector, 18 | noOpInjector, 19 | virtualInjector, 20 | createInstance, 21 | } from '@beamwind/core' 22 | -------------------------------------------------------------------------------- /packages/beamwind/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/tsconfig", 3 | "extends": "../../tsconfig.json", 4 | "include": ["src", "../../types"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/colors/.nvmrc: -------------------------------------------------------------------------------- 1 | v14 2 | -------------------------------------------------------------------------------- /packages/colors/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | ## [2.0.3](https://github.com/kenoxa/beamwind/compare/@beamwind/colors@2.0.2...@beamwind/colors@2.0.3) (2020-12-02) 7 | 8 | ### Bug Fixes 9 | 10 | - generate shade and on colors ([9a653fa](https://github.com/kenoxa/beamwind/commit/9a653fa41160b30a21a58d118902c6238272ec38)) 11 | 12 | ## [2.0.2](https://github.com/kenoxa/beamwind/compare/@beamwind/colors@2.0.1...@beamwind/colors@2.0.2) (2020-12-01) 13 | 14 | ### Bug Fixes 15 | 16 | - color variant creation ([9984a11](https://github.com/kenoxa/beamwind/commit/9984a110f825a1940e5ef2644697ea8ee8ec385a)) 17 | 18 | ## [2.0.1](https://github.com/kenoxa/beamwind/compare/@beamwind/colors@2.0.0...@beamwind/colors@2.0.1) (2020-12-01) 19 | 20 | ### Bug Fixes 21 | 22 | - remove contrast fallback warning ([ded4b65](https://github.com/kenoxa/beamwind/commit/ded4b65bae1f577c78ed98a4323360700cd42860)) 23 | 24 | # [2.0.0](https://github.com/kenoxa/beamwind/compare/@beamwind/colors@1.0.5...@beamwind/colors@2.0.0) (2020-11-30) 25 | 26 | **Note:** Version bump only for package @beamwind/colors 27 | 28 | ## [1.0.5](https://github.com/kenoxa/beamwind/compare/@beamwind/colors@1.0.4...@beamwind/colors@1.0.5) (2020-11-27) 29 | 30 | **Note:** Version bump only for package @beamwind/colors 31 | 32 | ## [1.0.4](https://github.com/kenoxa/beamwind/compare/@beamwind/colors@1.0.3...@beamwind/colors@1.0.4) (2020-11-26) 33 | 34 | **Note:** Version bump only for package @beamwind/colors 35 | 36 | ## [1.0.3](https://github.com/kenoxa/beamwind/compare/@beamwind/colors@1.0.2...@beamwind/colors@1.0.3) (2020-11-26) 37 | 38 | **Note:** Version bump only for package @beamwind/colors 39 | 40 | ## [1.0.2](https://github.com/kenoxa/beamwind/compare/@beamwind/colors@1.0.1...@beamwind/colors@1.0.2) (2020-11-25) 41 | 42 | **Note:** Version bump only for package @beamwind/colors 43 | 44 | ## 1.0.1 (2020-11-25) 45 | 46 | **Note:** Version bump only for package @beamwind/colors 47 | -------------------------------------------------------------------------------- /packages/colors/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 [these people](https://github.com/kenoxa/beamwind/graphs/contributors) 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/colors/README.md: -------------------------------------------------------------------------------- 1 | # @beamwind/colors 2 | 3 | > color utilities for beamwind 4 | 5 | [![MIT License](https://flat.badgen.net/github/license/kenoxa/beamwind)](https://github.com/kenoxa/beamwind/blob/main/LICENSE) 6 | [![Latest Release](https://flat.badgen.net/npm/v/@beamwind/colors?icon=npm&label)](https://www.npmjs.com/package/@beamwind/colors) 7 | [![Github](https://flat.badgen.net/badge/icon/kenoxa%2Fbeamwind?icon=github&label)](https://github.com/kenoxa/beamwind/blob/main/packages/colors) 8 | [![Typescript](https://flat.badgen.net/badge/icon/included?icon=typescript&label)](https://unpkg.com/browse/@beamwind/colors/types/colors.d.ts) 9 | [![Bundle Size](https://flat.badgen.net/bundlephobia/minzip/@beamwind/colors?icon=packagephobia&label&color=blue)](https://bundlephobia.com/result?p=@beamwind/colors) 10 | 11 | > [Read the docs](https://beamwind.js.org) | 12 | > [API](https://beamwind.js.org/packages/colors) | 13 | > [Change Log](https://github.com/kenoxa/beamwind/blob/main/packages/colors/CHANGELOG.md) | 14 | 15 | --- 16 | 17 | 18 | 19 | 20 | 21 | 22 | - [Installation](#installation) 23 | - [API](#api) 24 | - [Inspired by and based on](#inspired-by-and-based-on) 25 | - [Contribute](#contribute) 26 | - [License](#license) 27 | 28 | 29 | 30 | 31 | ## Installation 32 | 33 | ```sh 34 | npm install @beamwind/colors 35 | ``` 36 | 37 | And then import it: 38 | 39 | ```js 40 | import { createColorVariants } from '@beamwind/colors' 41 | ``` 42 | 43 | ## [API](https://beamwind.js.org/packages/colors) 44 | 45 | ## Inspired by and based on 46 | 47 | - [polished](https://github.com/styled-components/polished) 48 | - [Braid Design Tones](https://seek-oss.github.io/braid-design-system/foundations/tones) 49 | 50 | ## Contribute 51 | 52 | Thanks for being willing to contribute! 53 | 54 | > This project is free and open-source, so if you think this project can help you or anyone else, you may [star it on GitHub](https://github.com/kenoxa/beamwind). Feel free to [open an issue](https://github.com/kenoxa/beamwind/issues) if you have any idea, question, or you've found a bug. 55 | 56 | **Working on your first Pull Request?** You can learn how from this _free_ series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) 57 | 58 | We are following the [Conventional Commits](https://www.conventionalcommits.org) convention. 59 | 60 | ### Sponsors 61 | 62 | [![Kenoxa GmbH](https://images.opencollective.com/kenoxa/9c25796/logo/68.png)](https://www.kenoxa.com) [Kenoxa GmbH](https://www.kenoxa.com) 63 | 64 | ## License 65 | 66 | [MIT](https://github.com/kenoxa/beamwind/blob/main/LICENSE) © [Kenoxa GmbH](https://kenoxa.com) 67 | -------------------------------------------------------------------------------- /packages/colors/package-scripts.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../package-scripts') 2 | -------------------------------------------------------------------------------- /packages/colors/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@beamwind/colors", 3 | "version": "2.0.3", 4 | "description": "color utilities for beamwind", 5 | "keywords": [ 6 | "beamwind", 7 | "tailwind" 8 | ], 9 | "homepage": "https://github.com/kenoxa/beamwind#readme", 10 | "bugs": { 11 | "url": "https://github.com/kenoxa/beamwind/issues" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/kenoxa/beamwind.git", 16 | "directory": "packages/colors" 17 | }, 18 | "license": "MIT", 19 | "author": "Kenoxa GmbH ", 20 | "main": "src/index.ts", 21 | "scripts": { 22 | "build": "nps", 23 | "postbuild": "size-limit", 24 | "prepublishOnly": "nps", 25 | "size": "size-limit", 26 | "test": "nps" 27 | }, 28 | "prettier": "@carv/prettier-config", 29 | "eslintConfig": { 30 | "extends": "@carv/eslint-config", 31 | "root": true 32 | }, 33 | "jest": { 34 | "preset": "@carv/jest-preset" 35 | }, 36 | "devDependencies": { 37 | "@size-limit/preset-small-lib": "^4.6.0", 38 | "nps": "^5.9.12", 39 | "size-limit": "^4.6.0" 40 | }, 41 | "publishConfig": { 42 | "access": "public" 43 | }, 44 | "size-limit": [ 45 | { 46 | "path": "dist/esnext/colors.js", 47 | "limit": "2 KB" 48 | } 49 | ] 50 | } 51 | -------------------------------------------------------------------------------- /packages/colors/src/colors.test.ts: -------------------------------------------------------------------------------- 1 | import { 2 | getContrastVariant, 3 | getShadeVariant, 4 | getLightVariant, 5 | isLight, 6 | getDarkVariant, 7 | } from './colors' 8 | 9 | test.each([ 10 | ['#000', false], 11 | ['#333', false], 12 | ['#666', false], 13 | ['#888', false], 14 | ['#aaa', false], 15 | ['#bbb', false], 16 | ['#fcf6e1', true], 17 | ['#ccc', true], 18 | ['#ddd', true], 19 | ['#fff', true], 20 | ])('isLight(%j) => %j', (rgb, expected) => { 21 | expect(isLight(rgb)).toBe(expected) 22 | }) 23 | 24 | test.each([ 25 | ['#138a08', '#e8f5e7'], 26 | ['#d0011b', '#f4e4e6'], 27 | ['#ffc600', '#fcf6e1'], 28 | ])('getLightVariant(%j) => %j', (rgb, lighter) => { 29 | expect(getLightVariant(rgb)).toBe(lighter) 30 | }) 31 | 32 | test.each([ 33 | ['#138a08', '#061a04'], 34 | ['#d0011b', '#1c0306'], 35 | ['#ffc600', '#1e190b'], 36 | ])('getDarkVariant(%j) => %j', (rgb, darker) => { 37 | expect(getDarkVariant(rgb)).toBe(darker) 38 | }) 39 | 40 | test.each([ 41 | ['#138a08', '#000'], 42 | ['#d0011b', '#f4e4e6'], 43 | ['#0d3880', '#e8ecf4'], 44 | ['#9556b7', '#f7f5f9'], 45 | ['#001324', '#ebf2f7'], 46 | ['#1e468c', '#e8ecf2'], 47 | ['#ffc600', '#1e190b'], 48 | ['#fbf08b', '#23210e'], 49 | ['#000', '#f2f2f2'], 50 | ['#333', '#efefef'], 51 | ['#666', '#ececec'], 52 | ['#888', '#000'], 53 | ['#aaa', '#000'], 54 | ['#ccc', '#191919'], 55 | ['#ddd', '#1a1a1a'], 56 | ['#fff', '#1c1c1c'], 57 | ])('getContrastVariant(%j) => %j', (rgb, contrast) => { 58 | expect(getContrastVariant(rgb)).toBe(contrast) 59 | }) 60 | 61 | test.each([ 62 | ['#138a08', 0.05, undefined, '#16a209'], 63 | ['#d0011b', 0.05, undefined, '#e9011e'], 64 | ['#138a08', -0.05, undefined, '#107207'], 65 | ['#d0011b', -0.05, undefined, '#b70118'], 66 | ['#0d3880', 0.1, 0.05, '#0b2e69'], 67 | ['#ffc600', 0.1, 0.05, '#cc9e00'], 68 | ['#fff', 0.1, undefined, '#e6e6e6'], 69 | ['#fff', -0.1, undefined, '#ffffff'], 70 | ['#000', 0.1, undefined, '#1a1a1a'], 71 | ['#000', -0.1, undefined, '#000000'], 72 | ])('getShadeVariant(%j, %s, %s) => %j', (rgb, ifLight, ifDark, expected) => { 73 | expect(getShadeVariant(rgb, ifLight, ifDark)).toBe(expected) 74 | }) 75 | -------------------------------------------------------------------------------- /packages/colors/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from './colors' 2 | export * from './system' 3 | -------------------------------------------------------------------------------- /packages/colors/src/system.test.ts: -------------------------------------------------------------------------------- 1 | import { generateColors } from './system' 2 | 3 | test.each([ 4 | [ 5 | { 6 | surface: '#fafafa', 7 | 'on-surface': '#222', 8 | primary: '#0d3880', 9 | 'primary-active': '#1e40af', 10 | red: 'red', 11 | 'purple-200': '#DDD6FE', 12 | 'purple-500': '#8B5CF6', 13 | 'purple-800': '#5B21B6', 14 | }, 15 | { 16 | 'on-primary': '#e8ecf4', 17 | 'on-primary-active': '#e6e9f2', 18 | 'on-primary-disabled': '#eaeef5', 19 | 'on-primary-focus': '#e6ebf3', 20 | 'on-primary-hover': '#e7ecf4', 21 | 'on-primary-selected': '#e5eaf3', 22 | 'on-purple-200': '#130f26', 23 | 'on-purple-200-active': '#000', 24 | 'on-purple-200-disabled': '#1c1c1c', 25 | 'on-purple-200-focus': '#000', 26 | 'on-purple-200-hover': '#000', 27 | 'on-purple-200-selected': '#000', 28 | 'on-purple-500': '#000', 29 | 'on-purple-500-active': '#000', 30 | 'on-purple-500-disabled': '#e6e1f2', 31 | 'on-purple-500-focus': '#000', 32 | 'on-purple-500-hover': '#000', 33 | 'on-purple-500-selected': '#000', 34 | 'on-purple-800': '#eae6f2', 35 | 'on-purple-800-active': '#ece8f3', 36 | 'on-purple-800-disabled': '#ece8f3', 37 | 'on-purple-800-focus': '#e9e4f1', 38 | 'on-purple-800-hover': '#eae5f1', 39 | 'on-purple-800-selected': '#e8e3f1', 40 | 'on-surface': '#222', 41 | 'on-surface-active': '#191919', 42 | 'on-surface-disabled': '#1c1c1c', 43 | 'on-surface-focus': '#1a1a1a', 44 | 'on-surface-hover': '#1b1b1b', 45 | 'on-surface-selected': '#1a1a1a', 46 | primary: '#0d3880', 47 | 'primary-active': '#1e40af', 48 | 'primary-disabled': '#082452', 49 | 'primary-focus': '#124cae', 50 | 'primary-hover': '#0f4297', 51 | 'primary-selected': '#1351ba', 52 | 'purple-200': '#DDD6FE', 53 | 'purple-200-active': '#9f8bfc', 54 | 'purple-200-disabled': '#ffffff', 55 | 'purple-200-focus': '#b4a4fd', 56 | 'purple-200-hover': '#c8bdfd', 57 | 'purple-200-selected': '#a998fc', 58 | 'purple-500': '#8B5CF6', 59 | 'purple-500-active': '#bfa4fa', 60 | 'purple-500-disabled': '#692cf3', 61 | 'purple-500-focus': '#ad8cf9', 62 | 'purple-500-hover': '#9c74f7', 63 | 'purple-500-selected': '#b698f9', 64 | 'purple-800': '#5B21B6', 65 | 'purple-800-active': '#8146dd', 66 | 'purple-800-disabled': '#45198b', 67 | 'purple-800-focus': '#7230da', 68 | 'purple-800-hover': '#6625cc', 69 | 'purple-800-selected': '#7a3bdc', 70 | red: 'red', 71 | surface: '#fafafa', 72 | 'surface-active': '#d4d4d4', 73 | 'surface-disabled': '#ffffff', 74 | 'surface-focus': '#e1e1e1', 75 | 'surface-hover': '#ededed', 76 | 'surface-selected': '#dadada', 77 | }, 78 | ], 79 | ])('generateColors(%j) => %j', (colors, expected) => { 80 | expect(generateColors(colors)).toStrictEqual(expected) 81 | }) 82 | -------------------------------------------------------------------------------- /packages/colors/src/system.ts: -------------------------------------------------------------------------------- 1 | import { getContrastVariant, getShadeVariant } from './colors' 2 | 3 | export type ThemeColors = Record 4 | 5 | export interface Shades 6 | extends Record { 7 | hover?: number | [darker: number, lighter: number] 8 | active?: number | [darker: number, lighter: number] 9 | disabled?: number | [darker: number, lighter: number] 10 | selected?: number | [darker: number, lighter: number] 11 | } 12 | 13 | const isHEXColor = (color: string | undefined): color is string => 14 | typeof color === 'string' && color[0] === '#' 15 | 16 | const startsWith = (string: string, prefix: string): boolean => 17 | string.slice(0, prefix.length) === prefix 18 | 19 | export const createOnColor = (colors: ThemeColors, key: string, color = colors[key]): ThemeColors => 20 | isHEXColor(color) && !startsWith(key, 'on-') && !colors[`on-${key}`] 21 | ? { 22 | [`on-${key}`]: getContrastVariant(color), 23 | } 24 | : {} 25 | 26 | export const generateOnColors = (base: ThemeColors): ThemeColors => 27 | Object.keys(base) 28 | // eslint-disable-next-line unicorn/no-reduce 29 | .reduce((colors, key) => ({ ...colors, ...createOnColor(colors, key) }), base) 30 | 31 | export const createShadeVariants = ( 32 | colors: ThemeColors, 33 | key: string, 34 | shades: Shades = {}, 35 | color = colors[key], 36 | ): ThemeColors => { 37 | shades = { 38 | hover: [0.05, -0.05], 39 | focus: [0.1, -0.1], 40 | active: [0.15, -0.15], 41 | selected: [0.125, -0.125], 42 | disabled: [-0.085, 0.1], 43 | ...shades, 44 | } 45 | 46 | // Ignore keys which already have a shade suffix 47 | return isHEXColor(color) && !((key.split('-').pop() as string) in shades) 48 | ? Object.keys(shades) 49 | // eslint-disable-next-line unicorn/no-reduce 50 | .reduce((result, shade) => { 51 | const amount = shades[shade] 52 | 53 | if (amount != null && !colors[`${key}-${shade}`]) { 54 | result[`${key}-${shade}`] = Array.isArray(amount) 55 | ? getShadeVariant(color, amount[0], amount[1]) 56 | : getShadeVariant(color, amount) 57 | } 58 | 59 | return result 60 | }, {} as ThemeColors) 61 | : {} 62 | } 63 | 64 | export const generateColors = (base: ThemeColors, shades?: Shades): ThemeColors => 65 | Object.keys(base) 66 | // eslint-disable-next-line unicorn/no-reduce 67 | .reduce((colors, key) => { 68 | const shadesVariants = createShadeVariants(colors, key, shades) 69 | 70 | return { 71 | ...colors, 72 | ...createOnColor(colors, key), 73 | ...shadesVariants, 74 | ...generateOnColors(shadesVariants), 75 | } 76 | }, base) 77 | -------------------------------------------------------------------------------- /packages/colors/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/tsconfig", 3 | "extends": "../../tsconfig.json", 4 | "include": ["src", "../../types"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/core/.nvmrc: -------------------------------------------------------------------------------- 1 | v14 2 | -------------------------------------------------------------------------------- /packages/core/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # [2.3.0](https://github.com/kenoxa/beamwind/compare/@beamwind/core@2.2.0...@beamwind/core@2.3.0) (2020-12-05) 7 | 8 | ### Bug Fixes 9 | 10 | - transform resets its css properties to break inheritence ([c521414](https://github.com/kenoxa/beamwind/commit/c521414571e3e36b156e6ecc0e80cb66025a2826)) 11 | 12 | ### Features 13 | 14 | - ring defaults ([e50bfdf](https://github.com/kenoxa/beamwind/commit/e50bfdf1edf3dfb2421b4d9ab3a73d09eb1da475)) 15 | - support negated values in directive groupings ([b1b66ff](https://github.com/kenoxa/beamwind/commit/b1b66ff78dace4f5d9aaeb9ee9eb960bb3b7583d)) 16 | 17 | # [2.2.0](https://github.com/kenoxa/beamwind/compare/@beamwind/core@2.1.0...@beamwind/core@2.2.0) (2020-12-04) 18 | 19 | ### Features 20 | 21 | - :first, :last, :odd and :event states ([0d1c514](https://github.com/kenoxa/beamwind/commit/0d1c514e10e76b604780fae90712540787655239)) 22 | - background clip directives ([ea52dd1](https://github.com/kenoxa/beamwind/commit/ea52dd1d3eb474237b68582794d59756895db356)) 23 | - contents directive ([993f823](https://github.com/kenoxa/beamwind/commit/993f8239716c4c798ecb246801e62a51a3845df7)) 24 | - dark mode ([11eb4aa](https://github.com/kenoxa/beamwind/commit/11eb4aafefb815d5afcd8238935bc48d4094df14)) 25 | - display contents directive ([a118f6b](https://github.com/kenoxa/beamwind/commit/a118f6bedd1b22fd9180cb03e63cbc9d2dbf885f)) 26 | - gap-x & gap-y ([e90f388](https://github.com/kenoxa/beamwind/commit/e90f388c0d7843fe353e5655f329c3b4169c67c7)) 27 | - overscroll behavior ([035e50b](https://github.com/kenoxa/beamwind/commit/035e50ba7c275bdd2e708aebafb86eeb54a725d4)) 28 | - place directives ([b3c5d94](https://github.com/kenoxa/beamwind/commit/b3c5d941640900da56a2c2423a2aca9db6f7d676)) 29 | - space and divide reverse directives ([f526cb2](https://github.com/kenoxa/beamwind/commit/f526cb2114a4f3ce7c91870cf559fee08dc260cc)) 30 | - transform-gpu ([a28342f](https://github.com/kenoxa/beamwind/commit/a28342fbd7ae8a2a2d035306e35abbd40c54bdff)) 31 | 32 | # [2.1.0](https://github.com/kenoxa/beamwind/compare/@beamwind/core@2.0.2...@beamwind/core@2.1.0) (2020-12-02) 33 | 34 | ### Bug Fixes 35 | 36 | - cssom injector nonce handling ([6ca6c4d](https://github.com/kenoxa/beamwind/commit/6ca6c4d6c5212a0a8bd734367f0768cd79541fb4)) 37 | 38 | ### Features 39 | 40 | - support background images from theme ([492ffe0](https://github.com/kenoxa/beamwind/commit/492ffe063197d4af1a6ea2daff89e8e43d0855ed)) 41 | 42 | ## [2.0.2](https://github.com/kenoxa/beamwind/compare/@beamwind/core@2.0.1...@beamwind/core@2.0.2) (2020-12-01) 43 | 44 | ### Bug Fixes 45 | 46 | - sequential grouping generate valid directive ([c25f8cc](https://github.com/kenoxa/beamwind/commit/c25f8cccc495606797d2ddd9512ef1e2f9326186)) 47 | 48 | ## [2.0.1](https://github.com/kenoxa/beamwind/compare/@beamwind/core@2.0.0...@beamwind/core@2.0.1) (2020-12-01) 49 | 50 | **Note:** Version bump only for package @beamwind/core 51 | 52 | # 2.0.0 (2020-11-30) 53 | 54 | - BREAKING CHANGE: rewrite to be strict by default like oceanwind 55 | 56 | All core plugins have been adjusted to use a theme value resolver. That 57 | is hooked into the new `mode.unknown()` handler which may convert 58 | unknown values. 59 | 60 | The main package (beamwind) is now pre-configured with a tailwind v2 61 | theme. The lenient behavior is available via @beamwind/play. 62 | -------------------------------------------------------------------------------- /packages/core/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 [these people](https://github.com/kenoxa/beamwind/graphs/contributors) 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/core/README.md: -------------------------------------------------------------------------------- 1 | # @beamwind/core 2 | 3 | > compiles [Tailwind CSS] like shorthand syntax into CSS at runtime 4 | 5 | [![MIT License](https://flat.badgen.net/github/license/kenoxa/beamwind)](https://github.com/kenoxa/beamwind/blob/main/LICENSE) 6 | [![Latest Release](https://flat.badgen.net/npm/v/@beamwind/core?icon=npm&label)](https://www.npmjs.com/package/@beamwind/core) 7 | [![Github](https://flat.badgen.net/badge/icon/kenoxa%2Fbeamwind?icon=github&label)](https://github.com/kenoxa/beamwind/blob/main/packages/core) 8 | [![Typescript](https://flat.badgen.net/badge/icon/included?icon=typescript&label)](https://unpkg.com/browse/@beamwind/core/types/core.d.ts) 9 | [![Bundle Size](https://flat.badgen.net/bundlephobia/minzip/@beamwind/core?icon=packagephobia&label&color=blue)](https://bundlephobia.com/result?p=@beamwind/core) 10 | 11 | > [Read the docs](https://beamwind.js.org) | 12 | > [API](https://beamwind.js.org/packages/core) | 13 | > [Change Log](https://github.com/kenoxa/beamwind/blob/main/packages/core/CHANGELOG.md) 14 | 15 | --- 16 | 17 | > The [core theme](https://github.com/kenoxa/beamwind/blob/main/packages/core/src/theme.js) is bare bones as most projects have their own colors, sizes, ... and naming system. You probably want use one of the following: 18 | > 19 | > - [beamwind](https://github.com/kenoxa/beamwind/blob/main/packages/beamwind) - using the [tailwind default theme](https://github.com/kenoxa/beamwind/blob/main/packages/preset-tailwind) and [preflight](https://github.com/kenoxa/beamwind/blob/main/packages/preflight) 20 | > - [@beamwind/system](https://github.com/kenoxa/beamwind/blob/main/packages/system) - using a [semantic design system](https://github.com/kenoxa/beamwind/blob/main/packages/preset-system) and [preflight](https://github.com/kenoxa/beamwind/blob/main/packages/preflight) 21 | > - [@beamwind/play](https://github.com/kenoxa/beamwind/blob/main/packages/play) - combining the [tailwind default theme](https://github.com/kenoxa/beamwind/blob/main/packages/preset-tailwind), the [semantic design system](https://github.com/kenoxa/beamwind/blob/main/packages/preset-system) and [preflight](https://github.com/kenoxa/beamwind/blob/main/packages/preflight) with [auto-conversion of unknown theme values](https://github.com/kenoxa/beamwind/blob/main/packages/preset-play) 22 | 23 | --- 24 | 25 | 26 | 27 | 28 | 29 | 30 | - [Installation](#installation) 31 | - [Contribute](#contribute) 32 | - [License](#license) 33 | 34 | 35 | 36 | 37 | ## Installation 38 | 39 | ```sh 40 | npm install @beamwind/core 41 | ``` 42 | 43 | And then import it: 44 | 45 | ```js 46 | import { bw } from '@beamwind/core' 47 | ``` 48 | 49 | > Please refer to the [main documentation](https://beamwind.js.org#usage) for further information. 50 | 51 | ## Contribute 52 | 53 | Thanks for being willing to contribute! 54 | 55 | > This project is free and open-source, so if you think this project can help you or anyone else, you may [star it on GitHub](https://github.com/kenoxa/beamwind). Feel free to [open an issue](https://github.com/kenoxa/beamwind/issues) if you have any idea, question, or you've found a bug. 56 | 57 | **Working on your first Pull Request?** You can learn how from this _free_ series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) 58 | 59 | We are following the [Conventional Commits](https://www.conventionalcommits.org) convention. 60 | 61 | ### Sponsors 62 | 63 | [![Kenoxa GmbH](https://images.opencollective.com/kenoxa/9c25796/logo/68.png)](https://www.kenoxa.com) [Kenoxa GmbH](https://www.kenoxa.com) 64 | 65 | ## License 66 | 67 | [MIT](https://github.com/kenoxa/beamwind/blob/main/LICENSE) © [Kenoxa GmbH](https://kenoxa.com) 68 | 69 | [tailwind css]: https://tailwindcss.com 70 | [oceanwind]: https://www.npmjs.com/package/oceanwind 71 | [otion]: https://www.npmjs.com/package/otion 72 | -------------------------------------------------------------------------------- /packages/core/package-scripts.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../package-scripts') 2 | -------------------------------------------------------------------------------- /packages/core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@beamwind/core", 3 | "version": "2.3.0", 4 | "description": "compiles tailwind like shorthand syntax into css at runtime", 5 | "keywords": [ 6 | "beamwind", 7 | "tailwind" 8 | ], 9 | "homepage": "https://github.com/kenoxa/beamwind#readme", 10 | "bugs": { 11 | "url": "https://github.com/kenoxa/beamwind/issues" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/kenoxa/beamwind.git", 16 | "directory": "packages/core" 17 | }, 18 | "license": "MIT", 19 | "author": "Kenoxa GmbH ", 20 | "main": "src/index.ts", 21 | "scripts": { 22 | "build": "nps", 23 | "postbuild": "size-limit", 24 | "prepublishOnly": "nps", 25 | "size": "size-limit", 26 | "test": "nps" 27 | }, 28 | "prettier": "@carv/prettier-config", 29 | "eslintConfig": { 30 | "extends": "@carv/eslint-config", 31 | "root": true 32 | }, 33 | "jest": { 34 | "preset": "@carv/jest-preset" 35 | }, 36 | "dependencies": { 37 | "tiny-css-prefixer": "^1.1.4" 38 | }, 39 | "devDependencies": { 40 | "@size-limit/preset-small-lib": "^4.6.0", 41 | "nps": "^5.9.12", 42 | "size-limit": "^4.6.0" 43 | }, 44 | "publishConfig": { 45 | "access": "public" 46 | }, 47 | "size-limit": [ 48 | { 49 | "path": "./dist/esnext/core.js", 50 | "limit": "8.5 KB" 51 | } 52 | ] 53 | } 54 | -------------------------------------------------------------------------------- /packages/core/src/__fixtures__/ie11-reset.mjs: -------------------------------------------------------------------------------- 1 | // Remove some modern APIs to emulate IE11 2 | 3 | delete Math.imul 4 | delete globalThis.CSS 5 | delete globalThis.Map 6 | -------------------------------------------------------------------------------- /packages/core/src/__fixtures__/ie11-reset.mjs.d.ts: -------------------------------------------------------------------------------- 1 | export default null 2 | -------------------------------------------------------------------------------- /packages/core/src/__tests__/dark-mode.test.ts: -------------------------------------------------------------------------------- 1 | import type { Instance, Injector } from '../types' 2 | 3 | import { createInstance, virtualInjector } from '..' 4 | 5 | import theme from '../__fixtures__/theme' 6 | 7 | let injector: Injector 8 | let instance: Instance 9 | 10 | beforeEach(() => { 11 | injector = virtualInjector() 12 | instance = createInstance({ injector, theme, hash: false }) 13 | }) 14 | 15 | test('default to dark mode media strategy', () => { 16 | expect(instance.bw('text-white dark:text-black')).toBe('text-white dark:text-black') 17 | expect(injector.target).toMatchObject([ 18 | '.text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}', 19 | '@media (prefers-color-scheme:dark){.dark\\:text-black{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}}', 20 | ]) 21 | }) 22 | 23 | test('dark mode class strategy', () => { 24 | instance.setup({ darkMode: 'class' }) 25 | expect(instance.bw('text-white dark:text-black')).toBe('text-white dark:text-black') 26 | expect(injector.target).toMatchObject([ 27 | '.text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}', 28 | '.dark .dark\\:text-black{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}', 29 | ]) 30 | }) 31 | 32 | test('dark mode custom class strategy', () => { 33 | instance.setup({ darkMode: 'class', darkModeClass: 'dunkel' }) 34 | 35 | expect(instance.bw('text-white dark:text-black')).toBe('text-white dark:text-black') 36 | expect(injector.target).toMatchObject([ 37 | '.text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}', 38 | '.dunkel .dark\\:text-black{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}', 39 | ]) 40 | }) 41 | 42 | test('stacking with screens', () => { 43 | expect(instance.bw('text-#111 dark:text-#222 lg:text-black lg:dark:text-white')).toBe( 44 | 'text-#111 dark:text-#222 lg:text-black lg:dark:text-white', 45 | ) 46 | expect(injector.target).toMatchObject([ 47 | '.text-\\#111{--text-opacity:1;color:#111;color:rgba(17,17,17,var(--text-opacity))}', 48 | '@media (prefers-color-scheme:dark){.dark\\:text-\\#222{--text-opacity:1;color:#222;color:rgba(34,34,34,var(--text-opacity))}}', 49 | '@media (min-width: 1024px){.lg\\:text-black{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}}', 50 | '@media (min-width: 1024px){@media (prefers-color-scheme:dark){.lg\\:dark\\:text-white{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}}}', 51 | ]) 52 | }) 53 | 54 | test('stacking with other variants', () => { 55 | expect(instance.bw('text-#111 hover:text-#222 lg:dark:text-black lg:dark:hover:text-white')).toBe( 56 | 'text-#111 hover:text-#222 lg:dark:text-black lg:dark:hover:text-white', 57 | ) 58 | expect(injector.target).toMatchObject([ 59 | '.text-\\#111{--text-opacity:1;color:#111;color:rgba(17,17,17,var(--text-opacity))}', 60 | '.hover\\:text-\\#222:hover{--text-opacity:1;color:#222;color:rgba(34,34,34,var(--text-opacity))}', 61 | '@media (min-width: 1024px){@media (prefers-color-scheme:dark){.lg\\:dark\\:text-black{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}}}', 62 | '@media (min-width: 1024px){@media (prefers-color-scheme:dark){.lg\\:dark\\:hover\\:text-white:hover{--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}}}', 63 | ]) 64 | }) 65 | -------------------------------------------------------------------------------- /packages/core/src/__tests__/hash.test.ts: -------------------------------------------------------------------------------- 1 | import type { Instance, Injector } from '../types' 2 | 3 | import { createInstance, virtualInjector, noprefix } from '..' 4 | 5 | import theme from '../__fixtures__/theme' 6 | 7 | let injector: Injector 8 | let instance: Instance 9 | 10 | beforeEach(() => { 11 | injector = virtualInjector() 12 | instance = createInstance({ injector, theme, prefix: noprefix }) 13 | }) 14 | 15 | test('class names are hashed', () => { 16 | expect(instance.bw('group flex pt-4 text-center')).toBe('_1bk5mm5 _1l0yvu6 _xqpuic _1gpf024') 17 | expect(injector.target).toMatchObject([ 18 | '._1l0yvu6{display:flex}', 19 | '._xqpuic{padding-top:1rem}', 20 | '._1gpf024{text-align:center}', 21 | ]) 22 | }) 23 | 24 | test('keyframes are hashed', () => { 25 | expect(instance.bw('animate-pulse')).toBe('_wlxg8c') 26 | expect(injector.target).toMatchObject([ 27 | '._wlxg8c{animation:_1gyyyrk 2s cubic-bezier(0.4,0,0.6,1) infinite}', 28 | '@keyframes _1gyyyrk{0%,100%{opacity:1}50%{opacity:.5}}', 29 | ]) 30 | }) 31 | 32 | test('same declarations are inserted only once', () => { 33 | expect(instance.bw('border-x border-lr')).toBe('_5mfhy3 _5mfhy3') 34 | expect(injector.target).toMatchObject(['._5mfhy3{border-left-width:1px;border-right-width:1px}']) 35 | }) 36 | 37 | test('same color is inserted only once', () => { 38 | instance.setup({ 39 | theme: { 40 | extend: { 41 | colors: { 42 | '#0d3880': (theme) => theme('colors', 'primary'), 43 | }, 44 | }, 45 | }, 46 | }) 47 | 48 | expect(instance.bw('text-primary text-#0d3880')).toBe('_w64b8 _w64b8') 49 | expect(injector.target).toMatchObject([ 50 | '._w64b8{--_9esraz:1;color:#0d3880;color:rgba(13,56,128,var(--_9esraz))}', 51 | ]) 52 | }) 53 | 54 | test('transform', () => { 55 | expect(instance.bw('transform')).toBe('_gqktp6') 56 | expect(injector.target).toMatchObject([ 57 | '._gqktp6{--_wo1cv4:0;--_hov5ig:0;--_ld4lhp:0;--_harkfw:0;--_9bg65f:0;--_z0bztv:1;--_ceh22:1;transform:translateX(var(--_wo1cv4,0)) translateY(var(--_hov5ig,0)) rotate(var(--_ld4lhp,0)) skewX(var(--_harkfw,0)) skewY(var(--_9bg65f,0)) scaleX(var(--_z0bztv,1)) scaleY(var(--_ceh22,1))}', 58 | ]) 59 | }) 60 | 61 | test('scale', () => { 62 | expect(instance.bw('scale-90')).toBe('_1ftb7ve') 63 | expect(injector.target).toMatchObject([ 64 | '._1ftb7ve{--_z0bztv:.9;--_ceh22:.9;transform:scale(.9);transform:translateX(var(--_wo1cv4,0)) translateY(var(--_hov5ig,0)) rotate(var(--_ld4lhp,0)) skewX(var(--_harkfw,0)) skewY(var(--_9bg65f,0)) scaleX(var(--_z0bztv,1)) scaleY(var(--_ceh22,1))}', 65 | ]) 66 | }) 67 | 68 | test('bg-gradient-to-r', () => { 69 | expect(instance.bw('bg-gradient-to-r')).toBe('_1gt8na1') 70 | expect(injector.target).toMatchObject([ 71 | '._1gt8na1{background-image:linear-gradient(to right,var(--_1j5yf11,var(--_1iasyn4,transparent),var(--_3cvhiv,transparent)))}', 72 | ]) 73 | }) 74 | 75 | test('different variant producde different hashes', () => { 76 | expect(instance.bw('sm:text-center lg:text-center')).toBe('_1vpmzwf _6lc98d') 77 | expect(injector.target).toMatchObject([ 78 | '@media (min-width: 640px){._1vpmzwf{text-align:center}}', 79 | '@media (min-width: 1024px){._6lc98d{text-align:center}}', 80 | ]) 81 | }) 82 | -------------------------------------------------------------------------------- /packages/core/src/__tests__/ie11.test.ts: -------------------------------------------------------------------------------- 1 | import type { Instance, Injector } from '../types' 2 | 3 | import theme from '../__fixtures__/theme' 4 | 5 | let injector: Injector 6 | let instance: Instance 7 | 8 | beforeEach(async () => { 9 | await import('../__fixtures__/ie11-reset.mjs') 10 | 11 | const { createInstance, virtualInjector, noprefix } = await import('..') 12 | 13 | injector = virtualInjector() 14 | instance = createInstance({ injector, theme, prefix: noprefix }) 15 | }) 16 | 17 | test('class names are hashed', () => { 18 | expect(instance.bw('group flex pt-4 text-center')).toBe('_1bk5mm5 _1l0yvu6 _xqpuic _1gpf024') 19 | expect(injector.target).toMatchObject([ 20 | '._1l0yvu6{display:flex}', 21 | '._xqpuic{padding-top:1rem}', 22 | '._1gpf024{text-align:center}', 23 | ]) 24 | }) 25 | -------------------------------------------------------------------------------- /packages/core/src/__tests__/init.test.ts: -------------------------------------------------------------------------------- 1 | import type { OnInit, Instance, Injector } from '../types' 2 | 3 | import { createInstance, virtualInjector, noprefix } from '..' 4 | 5 | let injector: Injector 6 | let instance: Instance 7 | 8 | beforeEach(() => { 9 | injector = virtualInjector() 10 | instance = createInstance({ injector, hash: false, prefix: noprefix }) 11 | }) 12 | 13 | test('call init before first insert', () => { 14 | const init: OnInit = jest.fn((insert) => { 15 | insert('html{margin:0}') 16 | insert('body{padding:0}') 17 | }) 18 | 19 | // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment 20 | instance.setup({ init }) 21 | 22 | expect(init).not.toHaveBeenCalled() 23 | 24 | expect(instance.bw('text-center underline')).toBe('text-center underline') 25 | expect(instance.bw('hidden')).toBe('hidden') 26 | 27 | expect(init).toHaveBeenCalledTimes(1) 28 | 29 | expect(injector.target).toMatchObject([ 30 | 'html{margin:0}', 31 | 'body{padding:0}', 32 | '.hidden{display:none}', 33 | '.text-center{text-align:center}', 34 | '.underline{text-decoration:underline}', 35 | ]) 36 | }) 37 | 38 | test('several init function can be used', () => { 39 | const init1: OnInit = jest.fn((insert) => { 40 | insert('html{margin:0}') 41 | }) 42 | 43 | const init2: OnInit = jest.fn((insert) => { 44 | insert('body{padding:0}') 45 | }) 46 | 47 | // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment 48 | instance.setup([{ init: init1 }, { init: init2 }]) 49 | 50 | expect(init1).not.toHaveBeenCalled() 51 | expect(init2).not.toHaveBeenCalled() 52 | 53 | expect(instance.bw('text-center underline')).toBe('text-center underline') 54 | expect(instance.bw('hidden')).toBe('hidden') 55 | 56 | expect(init1).toHaveBeenCalledTimes(1) 57 | expect(init2).toHaveBeenCalledTimes(1) 58 | 59 | expect(injector.target).toMatchObject([ 60 | 'html{margin:0}', 61 | 'body{padding:0}', 62 | '.hidden{display:none}', 63 | '.text-center{text-align:center}', 64 | '.underline{text-decoration:underline}', 65 | ]) 66 | }) 67 | -------------------------------------------------------------------------------- /packages/core/src/__tests__/injector-dom.test.ts: -------------------------------------------------------------------------------- 1 | import { createInstance, noOpInjector } from '..' 2 | 3 | test('injects in to a style sheet element', () => { 4 | const nonce = Math.random().toString(36) 5 | 6 | const { bw, setup } = createInstance({ nonce }) 7 | 8 | expect(document.querySelector('#__beamwind')).toBeFalsy() 9 | 10 | expect(bw('group flex text-center md:text-left')).toBe('_1bk5mm5 _1l0yvu6 _1gpf024 _d88ggk') 11 | 12 | const style = document.querySelector('#__beamwind') as HTMLStyleElement 13 | 14 | expect(style).toBeInstanceOf(HTMLStyleElement) 15 | expect(style.nonce).toBe(nonce) 16 | 17 | expect([...(style.sheet?.cssRules || [])].map((rule) => rule.cssText)).toMatchObject([ 18 | '._1l0yvu6 {display: flex;}', 19 | '._1gpf024 {text-align: center;}', 20 | '@media (min-width: 768px) {._d88ggk {text-align: left;}}', 21 | ]) 22 | 23 | // Can not change injector after first use 24 | expect(() => { 25 | setup({ injector: noOpInjector() }) 26 | }).toThrow('Changing the injector after first use is not supported') 27 | }) 28 | -------------------------------------------------------------------------------- /packages/core/src/__tests__/mode.test.ts: -------------------------------------------------------------------------------- 1 | import { createInstance, virtualInjector, bw, mode, strict } from '..' 2 | 3 | test('mode warn (default)', () => { 4 | const consoleWarn = console.warn 5 | 6 | try { 7 | console.warn = jest.fn() 8 | 9 | expect(bw('unknown-directive')).toBe('') 10 | expect(console.warn).toHaveBeenCalledTimes(1) 11 | expect(console.warn).toHaveBeenCalledWith( 12 | `[unknown-directive] No plugin for "unknown-directive" found`, 13 | ) 14 | 15 | expect(bw('rounded-t-xxx')).toBe('_ymtp7f') 16 | expect(console.warn).toHaveBeenCalledTimes(2) 17 | expect(console.warn).toHaveBeenLastCalledWith(`No theme value found for borderRadius["t-xxx"]`) 18 | 19 | expect(bw('gap')).toBe('_ymtp7f') 20 | expect(console.warn).toHaveBeenCalledTimes(3) 21 | expect(console.warn).toHaveBeenLastCalledWith(`No theme value found for gap["DEFAULT"]`) 22 | } finally { 23 | console.warn = consoleWarn 24 | } 25 | }) 26 | 27 | test('mode strict', () => { 28 | const instance = createInstance({ 29 | injector: virtualInjector(), 30 | hash: false, 31 | mode: strict, 32 | }) 33 | 34 | expect(() => instance.bw('unknown-directive')).toThrow( 35 | `[unknown-directive] No plugin for "unknown-directive" found`, 36 | ) 37 | }) 38 | 39 | test('ignore vendor specific pseudo classes errors', () => { 40 | const injector = virtualInjector() 41 | const warn = jest.fn() 42 | 43 | injector.insert = jest.fn((rule) => { 44 | if (rule.includes(':-moz')) { 45 | throw new Error( 46 | `Failed to execute 'insertRule' on 'CSSStyleSheet': Failed to parse the rule '${rule}'.`, 47 | ) 48 | } 49 | }) 50 | 51 | const instance = createInstance({ 52 | injector, 53 | hash: false, 54 | mode: mode(warn), 55 | init(insert) { 56 | insert('::-moz-focus-inner{border-style:none;padding:0}') 57 | insert(':-moz-focusring{outline:1px dotted ButtonText}') 58 | }, 59 | }) 60 | 61 | expect(instance.bw('underline text-center')).toBe('underline text-center') 62 | 63 | expect(injector.insert).toHaveBeenCalledTimes(4) 64 | expect(injector.insert).toHaveBeenNthCalledWith( 65 | 1, 66 | '::-moz-focus-inner{border-style:none;padding:0}', 67 | 0, 68 | ) 69 | expect(injector.insert).toHaveBeenNthCalledWith( 70 | 2, 71 | ':-moz-focusring{outline:1px dotted ButtonText}', 72 | 0, 73 | ) 74 | expect(injector.insert).toHaveBeenNthCalledWith(3, '.underline{text-decoration:underline}', 0) 75 | expect(injector.insert).toHaveBeenNthCalledWith(4, '.text-center{text-align:center}', 1) 76 | 77 | expect(warn).toHaveBeenCalledTimes(0) 78 | }) 79 | 80 | test('propagate other errors to warn', () => { 81 | const injector = virtualInjector() 82 | const warn = jest.fn() 83 | 84 | injector.insert = jest.fn((rule) => { 85 | if (rule.includes('-web')) { 86 | throw new Error( 87 | `Failed to execute 'insertRule' on 'CSSStyleSheet': Failed to parse the rule '${rule}'.`, 88 | ) 89 | } 90 | }) 91 | 92 | const instance = createInstance({ 93 | injector, 94 | hash: false, 95 | mode: mode(warn), 96 | init(insert) { 97 | insert('.invalid-web{}') 98 | }, 99 | }) 100 | 101 | expect(instance.bw('underline')).toBe('underline') 102 | 103 | expect(injector.insert).toHaveBeenCalledTimes(2) 104 | expect(injector.insert).toHaveBeenNthCalledWith(1, '.invalid-web{}', 0) 105 | expect(injector.insert).toHaveBeenNthCalledWith(2, '.underline{text-decoration:underline}', 0) 106 | 107 | expect(warn).toHaveBeenCalledTimes(1) 108 | expect(warn).toHaveBeenNthCalledWith( 109 | 1, 110 | `Failed to execute 'insertRule' on 'CSSStyleSheet': Failed to parse the rule '.invalid-web{}'.`, 111 | ) 112 | }) 113 | -------------------------------------------------------------------------------- /packages/core/src/__tests__/plugins.test.ts: -------------------------------------------------------------------------------- 1 | import type { Instance, Injector, InlinePlugin } from '../types' 2 | 3 | import { createInstance, virtualInjector, noprefix, apply, strict } from '..' 4 | 5 | import theme from '../__fixtures__/theme' 6 | 7 | let injector: Injector 8 | let instance: Instance 9 | 10 | beforeEach(() => { 11 | injector = virtualInjector() 12 | instance = createInstance({ injector, theme, prefix: noprefix, hash: false }) 13 | }) 14 | 15 | test('value can be a token string', () => { 16 | instance.setup({ 17 | plugins: { 18 | card: 'max-w-md mx-auto bg-surface rounded-xl shadow-md overflow-hidden md:max-w-2xl', 19 | }, 20 | }) 21 | 22 | expect(instance.bw('mx-auto card my-md')).toBe( 23 | 'mx-auto max-w-md mx-auto bg-surface rounded-xl shadow-md overflow-hidden md:max-w-2xl my-md', 24 | ) 25 | expect(injector.target).toMatchObject([ 26 | '.bg-surface{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity));--text-opacity:1;color:#111;color:rgba(17,17,17,var(--text-opacity))}', 27 | '.mx-auto{margin-left:auto;margin-right:auto}', 28 | '.shadow-md{--shadow:0 4px 6px -1px rgba(0,0,0,0.1),0 2px 4px -1px rgba(0,0,0,0.06);box-shadow:0 4px 6px -1px rgba(0,0,0,0.1),0 2px 4px -1px rgba(0,0,0,0.06);box-shadow:var(--ring-offset-shadow,0 0 transparent),var(--ring-shadow,0 0 transparent),var(--shadow,0 0 transparent)}', 29 | '.my-md{margin-bottom:.875rem;margin-top:.875rem}', 30 | '.overflow-hidden{overflow:hidden}', 31 | '.max-w-md{max-width:28rem}', 32 | '.rounded-xl{border-radius:0.75rem}', 33 | '@media (min-width: 768px){.md\\:max-w-2xl{max-width:42rem}}', 34 | ]) 35 | }) 36 | 37 | test('plugin can return new tokens to parse using `apply`', () => { 38 | instance.setup({ 39 | mode: strict, 40 | 41 | plugins: { 42 | btn(parts, theme) { 43 | if (parts[1]) { 44 | const color = theme('colors', parts[1], '') 45 | 46 | if (color) { 47 | return apply`bg-${parts[1]} hover:bg-on-${parts[1]} active:(bg-${parts[1]} underline)` 48 | } 49 | } else { 50 | return apply('font-bold py-2 px-4 rounded') 51 | } 52 | }, 53 | }, 54 | }) 55 | 56 | expect(instance.bw('btn')).toBe('font-bold py-2 px-4 rounded') 57 | expect(instance.bw('btn-primary cursor-not-allowed')).toBe( 58 | 'bg-primary hover:bg-on-primary active:bg-primary active:underline cursor-not-allowed', 59 | ) 60 | expect(instance.bw('btn cursor-not-allowed btn-primary transition')).toBe( 61 | 'font-bold py-2 px-4 rounded cursor-not-allowed bg-primary hover:bg-on-primary active:bg-primary active:underline transition', 62 | ) 63 | 64 | expect(() => instance.bw('btn-unknown-color')).toThrow( 65 | `[btn-unknown-color] Plugin "btn" had no result`, 66 | ) 67 | }) 68 | 69 | test('inline plugin: token string', () => { 70 | // eslint-disable-next-line unicorn/consistent-function-scoping 71 | const inlinePlugin: InlinePlugin = () => 'font-bold text-xl' 72 | 73 | expect(instance.bw(inlinePlugin)).toBe('font-bold text-xl') 74 | expect(injector.target).toMatchObject([ 75 | '.text-xl{font-size:1.25rem;line-height:1.75rem}', 76 | '.font-bold{font-weight:700}', 77 | ]) 78 | }) 79 | 80 | test('inline plugin: css declarations', () => { 81 | const inlinePlugin: InlinePlugin = jest.fn((theme) => ({ 82 | 'font-weight': theme('fontWeight', 'extrabold'), 83 | color: theme('colors', 'primary'), 84 | })) 85 | 86 | const className = instance.bw(inlinePlugin) 87 | 88 | expect(className).toMatch(/__\w*_\d+/) 89 | expect(injector.target).toMatchObject([`.${className}{font-weight:800;color:#0d3880}`]) 90 | expect(inlinePlugin).toHaveBeenCalledTimes(1) 91 | }) 92 | -------------------------------------------------------------------------------- /packages/core/src/__tests__/prefix.test.ts: -------------------------------------------------------------------------------- 1 | import type { Instance, Injector } from '../types' 2 | 3 | import { createInstance, virtualInjector } from '..' 4 | 5 | let injector: Injector 6 | let instance: Instance 7 | 8 | beforeEach(() => { 9 | injector = virtualInjector() 10 | instance = createInstance({ injector, hash: false }) 11 | 12 | instance.setup({ 13 | plugins: { 14 | 'scroll-snap': (parts) => { 15 | return { 'scroll-snap-type': parts[1] } 16 | }, 17 | }, 18 | }) 19 | }) 20 | 21 | test('add prefix', () => { 22 | expect(instance.bw('sticky scroll-snap-x appearance-menulist-button')).toBe( 23 | 'sticky scroll-snap-x appearance-menulist-button', 24 | ) 25 | expect(injector.target).toMatchObject([ 26 | '.appearance-menulist-button{appearance:menulist-button;-moz-appearance:menulist-button;-webkit-appearance:menulist-button}', 27 | '.sticky{position:-webkit-sticky, sticky}', 28 | '.scroll-snap-x{scroll-snap-type:x;-ms-scroll-snap-type:x;-webkit-scroll-snap-type:x}', 29 | ]) 30 | }) 31 | -------------------------------------------------------------------------------- /packages/core/src/__tests__/ssr-no-op.test.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable tsdoc/syntax */ 2 | /** 3 | * @jest-environment node 4 | */ 5 | /* eslint-enable tsdoc/syntax */ 6 | 7 | import { bw } from '..' 8 | 9 | test('uses the no-op injector by default', () => { 10 | expect(bw('group flex text-center md:text-left')).toBe('_1bk5mm5 _1l0yvu6 _1gpf024 _d88ggk') 11 | }) 12 | -------------------------------------------------------------------------------- /packages/core/src/__tests__/theme.test.ts: -------------------------------------------------------------------------------- 1 | import type { Instance, Injector } from '../types' 2 | 3 | import { createInstance, virtualInjector, noprefix } from '..' 4 | 5 | import theme from '../__fixtures__/theme' 6 | 7 | let injector: Injector 8 | let instance: Instance 9 | 10 | beforeEach(() => { 11 | injector = virtualInjector() 12 | instance = createInstance({ injector, theme, prefix: noprefix, hash: false }) 13 | }) 14 | 15 | test('adjust theme using callback', () => { 16 | instance.setup({ 17 | theme: (theme) => ({ 18 | colors: { 19 | ...theme('colors'), 20 | red: theme('colors', 'critical'), 21 | }, 22 | }), 23 | }) 24 | 25 | expect(instance.bw('bg-primary text-red')).toBe('bg-primary text-red') 26 | expect(injector.target).toMatchObject([ 27 | '.bg-primary{--bg-opacity:1;background-color:#0d3880;background-color:rgba(13,56,128,var(--bg-opacity));--text-opacity:1;color:#e8ecf4;color:rgba(232,236,244,var(--text-opacity))}', 28 | '.text-red{--text-opacity:1;color:#d0011b;color:rgba(208,1,27,var(--text-opacity))}', 29 | ]) 30 | }) 31 | 32 | test('theme resolved', () => { 33 | expect(instance.theme('colors')).toHaveProperty('current', 'currentColor') 34 | expect(instance.theme('colors', 'current')).toBe('currentColor') 35 | expect(instance.theme('colors', 'yyyy', 'xxxx')).toBe('xxxx') 36 | }) 37 | 38 | test('on-* text color is added to bg-color', () => { 39 | instance.setup({ 40 | theme: { 41 | extend: { 42 | colors: { 'on-primary': 'red' }, 43 | }, 44 | }, 45 | }) 46 | 47 | expect(instance.bw('bg-primary')).toBe('bg-primary') 48 | expect(injector.target).toMatchObject([ 49 | '.bg-primary{--bg-opacity:1;background-color:#0d3880;background-color:rgba(13,56,128,var(--bg-opacity));--text-opacity:1;color:red}', 50 | ]) 51 | }) 52 | -------------------------------------------------------------------------------- /packages/core/src/__tests__/util.test.ts: -------------------------------------------------------------------------------- 1 | import { sortedInsertionIndex } from '../util' 2 | 3 | test.each([ 4 | [[], 1, 0], 5 | [[0], 1, 1], 6 | [[1], 0, 0], 7 | [[1, 2], 0, 0], 8 | [[1, 2], 1, 1], 9 | [[1, 2], 2, 2], 10 | [[1, 2], 3, 2], 11 | [[1, 2, 3], 0, 0], 12 | [[1, 2, 3], 1, 1], 13 | [[1, 2, 3], 2, 2], 14 | [[1, 2, 3], 3, 3], 15 | [[1, 2, 3], 4, 3], 16 | [[1, 2, 3, 4], 0, 0], 17 | [[1, 2, 3, 4], 1, 1], 18 | [[1, 2, 3, 4], 2, 2], 19 | [[1, 2, 3, 4], 3, 3], 20 | [[1, 2, 3, 4], 4, 4], 21 | [[1, 2, 3, 4], 5, 4], 22 | ])('sortedInsertionIndex(%j, %s) => %s', (array, element, index) => { 23 | expect(sortedInsertionIndex(array, element)).toBe(index) 24 | }) 25 | -------------------------------------------------------------------------------- /packages/core/src/css.ts: -------------------------------------------------------------------------------- 1 | import type { SelectorDecorator } from './types' 2 | import { join, tail } from './util' 3 | 4 | export const escape = 5 | (typeof CSS !== 'undefined' && CSS.escape) || 6 | // Simplified: escaping only special characters 7 | ((className: string): string => className.replace(/[!"#$%&'()*+,./:;<=>?@[\]^`{|}~]/g, '\\$&')) 8 | 9 | const isGroupVariant = (variant: string): boolean => variant.slice(0, 7) === ':group-' 10 | const isPseudoVariant = (variant: string): boolean => variant[0] === ':' && !isGroupVariant(variant) 11 | export const isAtRuleVariant = (variant: string): boolean => variant[0] === '@' 12 | 13 | export const toClassName = (token: string, variants: readonly string[]): string => { 14 | const base = join(variants, '') 15 | 16 | return (base && tail(base) + ':') + token 17 | } 18 | 19 | const createSelector = ( 20 | className: string, 21 | variants: readonly string[], 22 | selectorDecorator: SelectorDecorator, 23 | tag: (token: string) => string, 24 | ): string => 25 | selectorDecorator( 26 | // eslint-disable-next-line unicorn/no-reduce 27 | variants.reduce( 28 | (selector, variant) => 29 | // .group:hover .group-hover\:text-gray-500 30 | (isGroupVariant(variant) ? `.${escape(tag('group'))}:${tail(variant, 7)} ` : '') + 31 | selector + 32 | (isPseudoVariant(variant) ? variant : ''), 33 | '.' + escape(className), 34 | ), 35 | ) 36 | 37 | export const createRule = ( 38 | className: string, 39 | variants: readonly string[], 40 | declaration: string, 41 | selectorDecorator: SelectorDecorator, 42 | tag: (token: string) => string, 43 | ): string => // eslint-disable-line max-params 44 | // eslint-disable-next-line unicorn/no-reduce 45 | variants.reduceRight( 46 | (rule, variant) => (isAtRuleVariant(variant) ? `${variant}{${rule}}` : rule), 47 | `${createSelector(className, variants, selectorDecorator, tag)}{${declaration}}`, 48 | ) 49 | -------------------------------------------------------------------------------- /packages/core/src/env.ts: -------------------------------------------------------------------------------- 1 | export const isBrowser = typeof window !== 'undefined' 2 | -------------------------------------------------------------------------------- /packages/core/src/hash.ts: -------------------------------------------------------------------------------- 1 | import type { Hasher } from './types' 2 | 3 | // Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul 4 | const imul = 5 | Math.imul || 6 | ((opA: number, opB: number): number => { 7 | /* eslint-disable unicorn/prefer-math-trunc */ 8 | // Ensure that opB is an integer. opA will automatically be coerced. 9 | opB |= 0 10 | 11 | // Floating points give us 53 bits of precision to work with plus 1 sign bit 12 | // automatically handled for our convienence: 13 | // 1. 0x003fffff /*opA & 0x000fffff*/ * 0x7fffffff /*opB*/ = 0x1fffff7fc00001 14 | // 0x1fffff7fc00001 < Number.MAX_SAFE_INTEGER /*0x1fffffffffffff*/ 15 | let result = (opA & 0x003fffff) * opB 16 | 17 | // 2. We can remove an integer coersion from the statement above because: 18 | // 0x1fffff7fc00001 + 0xffc00000 = 0x1fffffff800001 19 | // 0x1fffffff800001 < Number.MAX_SAFE_INTEGER /*0x1fffffffffffff*/ 20 | if (opA & 0xffc00000 /* !== 0 */) result += ((opA & 0xffc00000) * opB) | 0 21 | 22 | return result | 0 23 | /* eslint-enable unicorn/prefer-math-trunc */ 24 | }) 25 | 26 | // Based on https://stackoverflow.com/a/52171480 27 | export const cyrb32: Hasher = (value: string): string => { 28 | let h = 9 29 | 30 | for (let index = value.length; index--; ) { 31 | h = imul(h ^ value.charCodeAt(index), 0x5f356495) 32 | } 33 | 34 | return '_' + ((h ^ (h >>> 9)) >>> 0).toString(36) 35 | } 36 | -------------------------------------------------------------------------------- /packages/core/src/helpers.ts: -------------------------------------------------------------------------------- 1 | import type { Declarations, PluginApply, PluginTokenResult } from './types' 2 | 3 | import { joinTruthy, asTokens } from './util' 4 | 5 | export const apply: PluginApply = (...tokens: unknown[]): PluginTokenResult => (parse) => 6 | parse(asTokens(tokens)) 7 | 8 | const positions = (resolve: (position: string) => undefined | string[] | void) => ( 9 | value: string | string[] | undefined, 10 | position: string, 11 | prefix?: string, 12 | suffix?: string, 13 | ): Declarations | undefined => { 14 | if (value) { 15 | const properties = position && resolve(position) 16 | 17 | if (properties && properties.length > 0) { 18 | // eslint-disable-next-line unicorn/no-reduce 19 | return properties.reduce((declarations, property) => { 20 | declarations[joinTruthy([prefix, property, suffix])] = value 21 | return declarations 22 | }, {} as Declarations) 23 | } 24 | } 25 | } 26 | 27 | const CORNERS: Record = { 28 | t: ['top-left', 'top-right'], 29 | r: ['top-right', 'bottom-right'], 30 | b: ['bottom-left', 'bottom-right'], 31 | l: ['bottom-left', 'top-left'], 32 | tl: ['top-left'], 33 | tr: ['top-right'], 34 | bl: ['bottom-left'], 35 | br: ['bottom-right'], 36 | } 37 | 38 | export const corners = positions((key) => CORNERS[key]) 39 | 40 | const X_Y_TO_EDGES: Record = { x: 'lr', y: 'tb' } 41 | 42 | const EDGES: Record = { 43 | t: 'top', 44 | r: 'right', 45 | b: 'bottom', 46 | l: 'left', 47 | } 48 | 49 | export const expandEdges = (key: string): string[] | undefined => { 50 | const parts = (X_Y_TO_EDGES[key] || key || '') 51 | .split('') 52 | .sort() 53 | // eslint-disable-next-line unicorn/no-reduce, array-callback-return 54 | .reduce((result, edge) => { 55 | if (result && EDGES[edge]) { 56 | result.push(EDGES[edge] as string) 57 | return result 58 | } 59 | }, [] as string[] | undefined | void) as string[] | undefined 60 | 61 | if (parts && parts.length > 0) return parts 62 | } 63 | 64 | // Support several edges like 'tr' 65 | // 'x' and 'y' can not be combined with others because size 'xl' 66 | // Every char must be a edge position 67 | // Sort to have consistent declaration ordering 68 | export const edges = positions(expandEdges) 69 | -------------------------------------------------------------------------------- /packages/core/src/index.ts: -------------------------------------------------------------------------------- 1 | import { createInstance } from './instance' 2 | 3 | const instance = createInstance() 4 | 5 | export const { bw } = instance 6 | export const { setup } = instance 7 | export const { theme } = instance 8 | 9 | export * from './hash' 10 | export * from './injectors' 11 | export * from './instance' 12 | export * from './prefix' 13 | export * from './modes' 14 | export { join, tail } from './util' 15 | export * from './helpers' 16 | -------------------------------------------------------------------------------- /packages/core/src/injectors.ts: -------------------------------------------------------------------------------- 1 | // Based on https://github.com/kripod/otion/blob/main/packages/otion/src/injectors.ts 2 | // License MIT 3 | import type { InjectorConfig, Injector } from './types' 4 | 5 | const STYLE_ELEMENT_ID = '__beamwind' 6 | 7 | const getStyleElement = (nonce?: string): HTMLStyleElement => { 8 | // Hydrate existing style element if available 9 | // eslint-disable-next-line unicorn/prefer-query-selector 10 | let element = document.getElementById(STYLE_ELEMENT_ID) as HTMLStyleElement | null 11 | 12 | if (!element) { 13 | // Create a new one otherwise 14 | element = document.createElement('style') 15 | 16 | element.id = STYLE_ELEMENT_ID 17 | nonce && (element.nonce = nonce) 18 | 19 | // eslint-disable-next-line unicorn/prefer-node-append 20 | document.head.appendChild(element) 21 | } 22 | 23 | return element 24 | } 25 | 26 | /** 27 | * Creates an injector which collects style rules during server-side rendering. 28 | */ 29 | export const virtualInjector = ({ target = [] }: InjectorConfig = {}): Injector< 30 | string[] 31 | > => ({ 32 | target, 33 | insert: (rule, index) => target.splice(index, 0, rule), 34 | }) 35 | 36 | /** 37 | * Creates an injector which inserts style rules through the CSS Object Model. 38 | */ 39 | export const cssomInjector = ({ 40 | nonce, 41 | target = getStyleElement(nonce).sheet as CSSStyleSheet, 42 | }: InjectorConfig = {}): Injector => ({ 43 | target, 44 | insert: target.insertRule.bind(target), 45 | }) 46 | 47 | /** 48 | * An injector placeholder which performs no operations. Useful for avoiding errors in a non-browser environment. 49 | */ 50 | export const noOpInjector = (): Injector => ({ 51 | target: null, 52 | insert: () => { 53 | /* No-Op */ 54 | }, 55 | }) 56 | -------------------------------------------------------------------------------- /packages/core/src/instance.ts: -------------------------------------------------------------------------------- 1 | import type { Instance, ConfigurationOptions } from './types' 2 | 3 | import { createContext } from './context' 4 | import { asTokens } from './util' 5 | import { process } from './process' 6 | 7 | export const createInstance = ( 8 | options?: ConfigurationOptions | ConfigurationOptions[], 9 | ): Instance => { 10 | const context = createContext(options) 11 | 12 | return { 13 | bw: (...tokens: unknown[]) => process(asTokens(tokens), context), 14 | 15 | setup: context.c, 16 | 17 | theme: context.r, 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /packages/core/src/is.ts: -------------------------------------------------------------------------------- 1 | const is = (value: unknown, type: string): boolean => typeof value === type 2 | 3 | export const string = (value: unknown): value is string => is(value, 'string') 4 | 5 | // eslint-disable-next-line @typescript-eslint/ban-types 6 | export const object = (value: unknown): value is object => value != null && is(value, 'object') 7 | 8 | export const array = Array.isArray 9 | 10 | // eslint-disable-next-line unicorn/prevent-abbreviations, @typescript-eslint/ban-types 11 | const fn = (value: unknown): value is T => is(value, 'function') 12 | 13 | export { fn as function } 14 | -------------------------------------------------------------------------------- /packages/core/src/modes.ts: -------------------------------------------------------------------------------- 1 | import type { Mode } from './types' 2 | 3 | import { join } from './util' 4 | 5 | export const mode = (report: (message: string) => void): Mode => ({ 6 | unknown(section, parts, optional) { 7 | if (!optional) { 8 | // TODO hint about possible values, did you mean ... 9 | // TODO stacktrace from callee [message, new Error().stack.split('at ').pop()].join(' '); 10 | report(`No theme value found for ${section}[${JSON.stringify(join(parts) || 'DEFAULT')}]`) 11 | } 12 | }, 13 | 14 | warn(message, directive) { 15 | report((directive ? `[${directive}] ` : '') + message) 16 | }, 17 | }) 18 | 19 | export const warn = mode((message) => console.warn(message)) 20 | 21 | export const strict = mode((message) => { 22 | throw new Error(message) 23 | }) 24 | -------------------------------------------------------------------------------- /packages/core/src/prefix.ts: -------------------------------------------------------------------------------- 1 | import type { Prefixer } from './types' 2 | 3 | import { prefixProperty, prefixValue } from 'tiny-css-prefixer' 4 | 5 | export const autoprefix: Prefixer = (property: string, value: string): string => { 6 | const declaration = `${property}:${prefixValue(property, value)}` 7 | let cssText = declaration 8 | const flag = prefixProperty(property) 9 | if (flag & 0b001) cssText += `;-ms-${declaration}` 10 | if (flag & 0b010) cssText += `;-moz-${declaration}` 11 | if (flag & 0b100) cssText += `;-webkit-${declaration}` 12 | return cssText 13 | } 14 | 15 | export const noprefix: Prefixer = (property: string, value: string): string => 16 | `${property}:${value}` 17 | -------------------------------------------------------------------------------- /packages/core/src/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from '@beamwind/types' 2 | -------------------------------------------------------------------------------- /packages/core/src/util.ts: -------------------------------------------------------------------------------- 1 | import type { Falsy, Token } from './types' 2 | 3 | import * as is from './is' 4 | 5 | export const join = (parts: readonly string[], separator = '-'): string => parts.join(separator) 6 | 7 | export const joinTruthy = (parts: readonly (string | Falsy)[], separator?: string): string => 8 | join(parts.filter(Boolean) as string[], separator) 9 | 10 | export const tail = (array: T, startIndex = 1): T => 11 | array.slice(startIndex) as T 12 | 13 | export const identity = (value: T): T => value 14 | 15 | export const capitalize = (value: string): string => value[0].toUpperCase() + tail(value) 16 | 17 | const uppercasePattern = /([A-Z])/g 18 | const prefixAndLowerCase = (char: string): string => `-${char.toLowerCase()}` 19 | export const hyphenate = (value: string): string => value.replace(uppercasePattern, prefixAndLowerCase) 20 | 21 | 22 | export interface Cache { 23 | has(key: string): boolean 24 | get(key: string): V | undefined 25 | set(key: string, value: V): void 26 | } 27 | 28 | export const createCache = (): Cache => { 29 | if (typeof Map === 'function') { 30 | return new Map() 31 | } 32 | 33 | const store = Object.create(null) as Record 34 | 35 | return { 36 | has(key) { 37 | return key in store 38 | }, 39 | 40 | get(key) { 41 | return store[key] 42 | }, 43 | 44 | set(key, value) { 45 | store[key] = value 46 | }, 47 | } 48 | } 49 | 50 | const interleave = (strings: TemplateStringsArray, interpolations: Token[]): Token[] => { 51 | const result: Token[] = [strings[0]] 52 | 53 | for (let index = 0; index < interpolations.length; ) { 54 | // Join consecutive strings 55 | if (is.string(interpolations[index])) { 56 | ;(result[result.length - 1] as string) += (interpolations[index] as string) + strings[++index] 57 | } else { 58 | if (interpolations[index]) { 59 | result.push(interpolations[index]) 60 | } 61 | 62 | result.push(strings[++index]) 63 | } 64 | } 65 | 66 | return result 67 | } 68 | 69 | export const asTokens = (tokens: unknown[]): Token[] => 70 | is.array(tokens[0]) && is.array(((tokens[0] as unknown) as TemplateStringsArray).raw) 71 | ? interleave((tokens[0] as unknown) as TemplateStringsArray, tail(tokens) as Token[]) 72 | : (tokens as Token[]) 73 | 74 | /** 75 | * Find the array index of where to add an element to keep it sorted. 76 | * 77 | * @returns The insertion index 78 | */ 79 | export const sortedInsertionIndex = (array: readonly number[], element: number): number => { 80 | let high = array.length 81 | 82 | // Theres only one option then 83 | if (high === 0) return 0 84 | 85 | // Find position by binary search 86 | for (let low = 0; low < high; ) { 87 | const pivot = (high + low) >> 1 88 | 89 | // Less-Then-Equal to add new equal element after all existing equal elements (stable sort) 90 | if (array[pivot] <= element) { 91 | low = pivot + 1 92 | } else { 93 | high = pivot 94 | } 95 | } 96 | 97 | return high 98 | } 99 | 100 | export const merge = (a: A, b: Partial | undefined): A & B => 101 | (a && b ? { ...a, ...b } : a || b || {}) as A & B 102 | -------------------------------------------------------------------------------- /packages/core/src/variants.ts: -------------------------------------------------------------------------------- 1 | import type { ThemeResolver } from './types' 2 | import { tail } from './util' 3 | 4 | let size: string | undefined 5 | 6 | const variants: Record = { 7 | ':dark': '@media (prefers-color-scheme:dark)', 8 | ':sticky': '@supports ((position: -webkit-sticky) or (position:sticky))', 9 | ':motion-reduce': '@media (prefers-reduced-motion:reduce)', 10 | ':motion-safe': '@media (prefers-reduced-motion:no-preference)', 11 | ':first': ':first-child', 12 | ':last': ':last-child', 13 | ':even': ':nth-child(2n)', 14 | ':odd': ':nth-child(odd)', 15 | } 16 | 17 | /* eslint-disable no-return-assign, no-cond-assign */ 18 | export const createVariant = (variant: string, theme: ThemeResolver): string => 19 | (size = theme('screens', tail(variant))) 20 | ? `@media (min-width: ${size})` 21 | : variants[variant] || variant 22 | /* eslint-enable no-return-assign, no-cond-assign */ 23 | -------------------------------------------------------------------------------- /packages/core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/tsconfig", 3 | "extends": "../../tsconfig.json", 4 | "include": ["src", "../../types"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/play/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | ## [2.1.1](https://github.com/kenoxa/beamwind/compare/@beamwind/play@2.1.0...@beamwind/play@2.1.1) (2020-12-05) 7 | 8 | **Note:** Version bump only for package @beamwind/play 9 | 10 | # [2.1.0](https://github.com/kenoxa/beamwind/compare/@beamwind/play@2.0.4...@beamwind/play@2.1.0) (2020-12-04) 11 | 12 | ### Features 13 | 14 | - transform-gpu ([a28342f](https://github.com/kenoxa/beamwind/commit/a28342fbd7ae8a2a2d035306e35abbd40c54bdff)) 15 | 16 | ## [2.0.4](https://github.com/kenoxa/beamwind/compare/@beamwind/play@2.0.3...@beamwind/play@2.0.4) (2020-12-02) 17 | 18 | **Note:** Version bump only for package @beamwind/play 19 | 20 | ## [2.0.3](https://github.com/kenoxa/beamwind/compare/@beamwind/play@2.0.2...@beamwind/play@2.0.3) (2020-12-01) 21 | 22 | **Note:** Version bump only for package @beamwind/play 23 | 24 | ## [2.0.2](https://github.com/kenoxa/beamwind/compare/@beamwind/play@2.0.1...@beamwind/play@2.0.2) (2020-12-01) 25 | 26 | **Note:** Version bump only for package @beamwind/play 27 | 28 | ## [2.0.1](https://github.com/kenoxa/beamwind/compare/@beamwind/play@2.0.0...@beamwind/play@2.0.1) (2020-12-01) 29 | 30 | **Note:** Version bump only for package @beamwind/play 31 | 32 | # 2.0.0 (2020-11-30) 33 | 34 | **Note:** Version bump only for package @beamwind/play 35 | -------------------------------------------------------------------------------- /packages/play/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 [these people](https://github.com/kenoxa/beamwind/graphs/contributors) 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/play/README.md: -------------------------------------------------------------------------------- 1 | # @beamwind/play 2 | 3 | > ready to go beamwind for rapid prototyping using [@beamwind/preset-tailwind](https://github.com/kenoxa/beamwind/blob/main/packages/preset-tailwind) & [@beamwind/preset-system](https://github.com/kenoxa/beamwind/blob/main/packages/preset-tailwind) with [auto-conversion of values](https://github.com/kenoxa/beamwind/blob/main/packages/preset-play) 4 | 5 | [![MIT License](https://flat.badgen.net/github/license/kenoxa/beamwind)](https://github.com/kenoxa/beamwind/blob/main/LICENSE) 6 | [![Latest Release](https://flat.badgen.net/npm/v/@beamwind/play?icon=npm&label)](https://www.npmjs.com/package/@beamwind/play) 7 | [![Github](https://flat.badgen.net/badge/icon/kenoxa%2Fbeamwind?icon=github&label)](https://github.com/kenoxa/beamwind/blob/main/packages/play) 8 | [![Typescript](https://flat.badgen.net/badge/icon/included?icon=typescript&label)](https://unpkg.com/browse/@beamwind/play/types/play.d.ts) 9 | [![Bundle Size](https://flat.badgen.net/bundlephobia/minzip/@beamwind/play?icon=packagephobia&label&color=blue)](https://bundlephobia.com/result?p=@beamwind/play) 10 | 11 | > [Read the docs](https://beamwind.js.org) | 12 | > [API](https://beamwind.js.org/packages/play) | 13 | > [Change Log](https://github.com/kenoxa/beamwind/blob/main/packages/play/CHANGELOG.md) > [⚡️ Demo](https://esm.codes/#Ly8gQmVhbXdpbmQgZGVtbyAoYmFzZWQgb24gY29kZSBieSBAbHVrZWphY2tzb25uIC0gY3JlYXRvciBvZiBvY2VhbndpbmQpCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAKaW1wb3J0IHsgcmVuZGVyLCBodG1sIH0gZnJvbSAnaHR0cHM6Ly9ucG0ucmV2ZXJzZWh0dHAuY29tL3ByZWFjdCxwcmVhY3QvaG9va3MsaHRtL3ByZWFjdCc7CmltcG9ydCB7IGJ3IH0gZnJvbSAnaHR0cHM6Ly91bnBrZy5jb20vQGJlYW13aW5kL3BsYXk/bW9kdWxlJwoKLy8gVGFpbHdpbmQgYW5kIFN5c3RlbSB0aGVtZSB2YWx1ZXMgYXJlIGF2YWlsYWJsZQoKY29uc3Qgc3R5bGUgPSB7CiAgLy8gRXhhbXBsZSBvZiBhYnN0cmFjdGVkIHN0eWxlCiAgY29udGFpbmVyOiBid2BoLWZ1bGwgYmctI0RCMjc3NyB0ZXh0LSNFNUU3RUIgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXJgCn0KCnJlbmRlcigKICBodG1sYAogICAgPGRpdiBjbGFzcz0ke3N0eWxlLmNvbnRhaW5lcn0+CiAgICAgIDxoMSBjbGFzcz0kewogICAgICAgIC8vIEV4YW1wbGUgb2YgYW4gaW5saW5lIHN0eWxlCiAgICAgICAgYndgCiAgICAgICAgICB0ZXh0KDIuNXJlbSB1bmRlcmxpbmUpCiAgICAgICAgICBmb250KGJvbGQgc2FucykKICAgICAgICAgIHRyYW5zaXRpb24KICAgICAgICAgIGhvdmVyOih0cmFuc2Zvcm0gcm90YXRlLTcgc2NhbGUtMTM1IGN1cnNvci1wb2ludGVyKQogICAgICAgICAgYWN0aXZlOih0cmFuc2Zvcm0gLXJvdGF0ZS0yMyBzY2FsZS0xNzUpCiAgICAgICAgYAogICAgICB9PkhlbGxvIFdvcmxkPC9oMT4KICAgIDwvZGl2PgogIGAsCiAgZG9jdW1lbnQuYm9keQopOw==) 14 | 15 | --- 16 | 17 | > This package should be used for _prototyping only_ as it usually prevents a consistent UI experience. 18 | 19 | --- 20 | 21 | 22 | 23 | 24 | 25 | 26 | - [Installation](#installation) 27 | - [Usage](#usage) 28 | - [Support](#support) 29 | - [Contribute](#contribute) 30 | - [Sponsors](#sponsors) 31 | - [License](#license) 32 | 33 | 34 | 35 | 36 | ## Installation 37 | 38 | ```sh 39 | npm install @beamwind/play 40 | ``` 41 | 42 | ## Usage 43 | 44 | > Please refer to the [main documentation](https://beamwind.js.org#usage) and [@beamwind/preset-play](https://github.com/kenoxa/beamwind/blob/main/packages/preset-play) for further information. 45 | 46 | ```js 47 | import { bw } from '@beamwind/play' 48 | 49 | bw`h-full bg-#9556b7 rotate-5 scale-92` 50 | ``` 51 | 52 | ## Support 53 | 54 | This project is free and open-source, so if you think this project can help you or anyone else, you may [star it on GitHub](https://github.com/kenoxa/beamwind). Feel free to [open an issue](https://github.com/kenoxa/beamwind/issues) if you have any idea, question, or you've found a bug. 55 | 56 | ## Contribute 57 | 58 | Thanks for being willing to contribute! 59 | 60 | **Working on your first Pull Request?** You can learn how from this _free_ series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) 61 | 62 | We are following the [Conventional Commits](https://www.conventionalcommits.org) convention. 63 | 64 | ## Sponsors 65 | 66 | [![Kenoxa GmbH](https://images.opencollective.com/kenoxa/9c25796/logo/68.png)](https://www.kenoxa.com) [Kenoxa GmbH](https://www.kenoxa.com) 67 | 68 | ## License 69 | 70 | [MIT](https://github.com/kenoxa/beamwind/blob/main/LICENSE) © [Kenoxa GmbH](https://kenoxa.com) 71 | -------------------------------------------------------------------------------- /packages/play/package-scripts.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../package-scripts') 2 | -------------------------------------------------------------------------------- /packages/play/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@beamwind/play", 3 | "version": "2.1.1", 4 | "description": "ready to go beamwind for rapid prototyping using tailwind & system preset with auto-conversion of values", 5 | "keywords": [ 6 | "beamwind", 7 | "tailwind" 8 | ], 9 | "homepage": "https://github.com/kenoxa/beamwind#readme", 10 | "bugs": { 11 | "url": "https://github.com/kenoxa/beamwind/issues" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/kenoxa/beamwind.git", 16 | "directory": "packages/play" 17 | }, 18 | "license": "MIT", 19 | "author": "Kenoxa GmbH ", 20 | "main": "src/index.ts", 21 | "scripts": { 22 | "build": "nps", 23 | "prepublishOnly": "nps", 24 | "test": "nps" 25 | }, 26 | "prettier": "@carv/prettier-config", 27 | "eslintConfig": { 28 | "extends": "@carv/eslint-config", 29 | "root": true 30 | }, 31 | "jest": { 32 | "preset": "@carv/jest-preset" 33 | }, 34 | "dependencies": { 35 | "@beamwind/core": "^2.3.0", 36 | "@beamwind/preflight": "^2.0.2", 37 | "@beamwind/preset-play": "^2.0.4", 38 | "@beamwind/preset-system": "^2.3.0", 39 | "@beamwind/preset-tailwind": "^2.0.2" 40 | }, 41 | "devDependencies": { 42 | "nps": "^5.9.12" 43 | }, 44 | "publishConfig": { 45 | "access": "public" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /packages/play/src/index.test.ts: -------------------------------------------------------------------------------- 1 | import { bw } from '.' 2 | 3 | beforeAll(() => { 4 | console.warn = (message: string) => { 5 | throw new Error(message) 6 | } 7 | }) 8 | 9 | test('smoke', () => { 10 | expect( 11 | bw`absolute inset-0 bg-gradient-to-r from-promote to-purple-200 shadow-lg transform -skew-y-md sm:skew-y-none sm:-rotate-lg sm:rounded-3xl`, 12 | ).toBe( 13 | '_1mkfpkn _o006n8 _1gt8na1 _bgnw62 _k5uxb4 _lae5pa _gqktp6 _i5h0pq _1w053pr _1vzslrt _9pmjrn', 14 | ) 15 | }) 16 | 17 | test('readme example', () => { 18 | expect(bw`h-full bg-#DB2777 text-#E5E7EB flex items-center justify-center`).toBe( 19 | '_ma35kl _1pncuk4 _ctkn65 _1l0yvu6 _1ylnts1 _qemgvh', 20 | ) 21 | 22 | expect( 23 | bw` 24 | text(2.5rem underline) 25 | font(bold sans) 26 | transition 27 | hover:(transform rotate-7 scale-135 cursor-pointer) 28 | active:(transform -rotate-23 scale-175) 29 | `, 30 | ).toBe( 31 | '_1r5djcv _1rn96fu _1u8tsvs _vx8z01 _iniysy _1crosn3 _1oeys2y _1brxud0 _vdrcah _vzti3v _1op7k1b _b53wdb', 32 | ) 33 | }) 34 | -------------------------------------------------------------------------------- /packages/play/src/index.ts: -------------------------------------------------------------------------------- 1 | import tailwind from '@beamwind/preset-tailwind' 2 | import system from '@beamwind/preset-system' 3 | import play from '@beamwind/preset-play' 4 | import preflight from '@beamwind/preflight' 5 | import { createInstance, warn } from '@beamwind/core' 6 | 7 | const instance = createInstance([preflight(), tailwind(), system(), play({ mode: warn })]) 8 | 9 | export const { bw } = instance 10 | export const { setup } = instance 11 | export const { theme } = instance 12 | 13 | // Re-export common configuration utilities 14 | export { noprefix, cyrb32, cssomInjector, noOpInjector, virtualInjector } from '@beamwind/core' 15 | -------------------------------------------------------------------------------- /packages/play/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/tsconfig", 3 | "extends": "../../tsconfig.json", 4 | "include": ["src", "../../types"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/preflight/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | ## [2.0.2](https://github.com/kenoxa/beamwind/compare/@beamwind/preflight@2.0.1...@beamwind/preflight@2.0.2) (2020-12-05) 7 | 8 | **Note:** Version bump only for package @beamwind/preflight 9 | 10 | ## [2.0.1](https://github.com/kenoxa/beamwind/compare/@beamwind/preflight@2.0.0...@beamwind/preflight@2.0.1) (2020-12-04) 11 | 12 | **Note:** Version bump only for package @beamwind/preflight 13 | 14 | # [2.0.0](https://github.com/kenoxa/beamwind/compare/@beamwind/preflight@1.2.1...@beamwind/preflight@2.0.0) (2020-11-30) 15 | 16 | **Note:** Version bump only for package @beamwind/preflight 17 | 18 | ## [1.2.1](https://github.com/kenoxa/beamwind/compare/@beamwind/preflight@1.2.0...@beamwind/preflight@1.2.1) (2020-11-27) 19 | 20 | **Note:** Version bump only for package @beamwind/preflight 21 | 22 | # [1.2.0](https://github.com/kenoxa/beamwind/compare/@beamwind/preflight@1.1.1...@beamwind/preflight@1.2.0) (2020-11-27) 23 | 24 | ### Features 25 | 26 | - support bg, text, divide, border and placeholder opacity ([18d7fe9](https://github.com/kenoxa/beamwind/commit/18d7fe9c0c3bb319bee75f11a1f96954ff9e0eb9)) 27 | 28 | ## [1.1.1](https://github.com/kenoxa/beamwind/compare/@beamwind/preflight@1.1.0...@beamwind/preflight@1.1.1) (2020-11-26) 29 | 30 | ### Bug Fixes 31 | 32 | - use 'bw' instead of cx in preparation for intellisense ([9fdb322](https://github.com/kenoxa/beamwind/commit/9fdb3226262609d5d732c1fa2f72d0796c6a8250)) 33 | 34 | # [1.1.0](https://github.com/kenoxa/beamwind/compare/@beamwind/preflight@1.0.4...@beamwind/preflight@1.1.0) (2020-11-26) 35 | 36 | ### Features 37 | 38 | - inline plugins ([5ac827a](https://github.com/kenoxa/beamwind/commit/5ac827a30007854b47f03739676d1827144ce9c3)) 39 | 40 | ## [1.0.4](https://github.com/kenoxa/beamwind/compare/@beamwind/preflight@1.0.3...@beamwind/preflight@1.0.4) (2020-11-26) 41 | 42 | **Note:** Version bump only for package @beamwind/preflight 43 | 44 | ## [1.0.3](https://github.com/kenoxa/beamwind/compare/@beamwind/preflight@1.0.2...@beamwind/preflight@1.0.3) (2020-11-26) 45 | 46 | ### Bug Fixes 47 | 48 | - invalid rules are logged and insert can be called after init ([9aa8f53](https://github.com/kenoxa/beamwind/commit/9aa8f53f3bdf32f7f7a014151d6e399b0ab18e26)) 49 | 50 | ## [1.0.2](https://github.com/kenoxa/beamwind/compare/@beamwind/preflight@1.0.1...@beamwind/preflight@1.0.2) (2020-11-25) 51 | 52 | **Note:** Version bump only for package @beamwind/preflight 53 | 54 | ## 1.0.1 (2020-11-25) 55 | 56 | **Note:** Version bump only for package @beamwind/preflight 57 | -------------------------------------------------------------------------------- /packages/preflight/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 [these people](https://github.com/kenoxa/beamwind/graphs/contributors) 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/preflight/README.md: -------------------------------------------------------------------------------- 1 | # @beamwind/preflight 2 | 3 | > an opinionated set of base styles for modern browsers based on [Tailwind Preflight](https://tailwindcss.com/docs/preflight) 4 | 5 | [![MIT License](https://flat.badgen.net/github/license/kenoxa/beamwind)](https://github.com/kenoxa/beamwind/blob/main/LICENSE) 6 | [![Latest Release](https://flat.badgen.net/npm/v/@beamwind/preflight?icon=npm&label)](https://www.npmjs.com/package/@beamwind/preflight) 7 | [![Github](https://flat.badgen.net/badge/icon/kenoxa%2Fbeamwind?icon=github&label)](https://github.com/kenoxa/beamwind/blob/main/packages/preflight) 8 | [![Typescript](https://flat.badgen.net/badge/icon/included?icon=typescript&label)](https://unpkg.com/browse/@beamwind/preflight/types/preflight.d.ts) 9 | [![Bundle Size](https://flat.badgen.net/bundlephobia/minzip/@beamwind/preflight?icon=packagephobia&label&color=blue)](https://bundlephobia.com/result?p=@beamwind/preflight) 10 | 11 | > [Read the docs](https://beamwind.js.org) | 12 | > [API](https://beamwind.js.org/packages/preflight) | 13 | > [Change Log](https://github.com/kenoxa/beamwind/blob/main/packages/preflight/CHANGELOG.md) 14 | 15 | --- 16 | 17 | Built on top of [modern-normalize](https://github.com/sindresorhus/modern-normalize), @beamwind/preflight is designed for and tested on the latest stable versions of Chrome, Firefox, Edge, and Safari. Preflight does not support any version of IE, including IE 11. 18 | 19 | If you need to support IE 11, we recommend using [@beamwind/reset](https://github.com/kenoxa/beamwind/blob/main/packages/reset). 20 | 21 | 22 | 23 | 24 | 25 | 26 | - [Installation](#installation) 27 | - [Usage](#usage) 28 | - [Contribute](#contribute) 29 | - [License](#license) 30 | 31 | 32 | 33 | 34 | ## Installation 35 | 36 | ```sh 37 | npm install @beamwind/preflight 38 | ``` 39 | 40 | ## Usage 41 | 42 | > Please refer to the [main documentation](https://beamwind.js.org#usage) for further information. 43 | 44 | ```js 45 | import { setup } from 'beamwind' 46 | import preflight from '@beamwind/preflight' 47 | 48 | setup(preflight()) 49 | ``` 50 | 51 | ## Contribute 52 | 53 | Thanks for being willing to contribute! 54 | 55 | > This project is free and open-source, so if you think this project can help you or anyone else, you may [star it on GitHub](https://github.com/kenoxa/beamwind). Feel free to [open an issue](https://github.com/kenoxa/beamwind/issues) if you have any idea, question, or you've found a bug. 56 | 57 | **Working on your first Pull Request?** You can learn how from this _free_ series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) 58 | 59 | We are following the [Conventional Commits](https://www.conventionalcommits.org) convention. 60 | 61 | ### Sponsors 62 | 63 | [![Kenoxa GmbH](https://images.opencollective.com/kenoxa/9c25796/logo/68.png)](https://www.kenoxa.com) [Kenoxa GmbH](https://www.kenoxa.com) 64 | 65 | ## License 66 | 67 | [MIT](https://github.com/kenoxa/beamwind/blob/main/LICENSE) © [Kenoxa GmbH](https://kenoxa.com) 68 | -------------------------------------------------------------------------------- /packages/preflight/package-scripts.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../package-scripts') 2 | -------------------------------------------------------------------------------- /packages/preflight/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@beamwind/preflight", 3 | "version": "2.0.2", 4 | "description": "An opinionated set of base styles for modern browsers", 5 | "keywords": [ 6 | "beamwind", 7 | "tailwind" 8 | ], 9 | "homepage": "https://github.com/kenoxa/beamwind#readme", 10 | "bugs": { 11 | "url": "https://github.com/kenoxa/beamwind/issues" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/kenoxa/beamwind.git", 16 | "directory": "packages/preflight" 17 | }, 18 | "license": "MIT", 19 | "author": "Kenoxa GmbH ", 20 | "main": "src/index.ts", 21 | "scripts": { 22 | "build": "nps", 23 | "prepublishOnly": "nps", 24 | "test": "nps" 25 | }, 26 | "prettier": "@carv/prettier-config", 27 | "eslintConfig": { 28 | "extends": "@carv/eslint-config", 29 | "root": true 30 | }, 31 | "jest": { 32 | "preset": "@carv/jest-preset" 33 | }, 34 | "devDependencies": { 35 | "nps": "^5.9.12" 36 | }, 37 | "publishConfig": { 38 | "access": "public" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/preflight/src/index.ts: -------------------------------------------------------------------------------- 1 | import type { ConfigurationOptions } from '@beamwind/types' 2 | 3 | import { preflight } from './preflight' 4 | 5 | export default (): ConfigurationOptions => ({ 6 | init(insert, theme): void { 7 | preflight(theme).forEach(insert) 8 | }, 9 | }) 10 | -------------------------------------------------------------------------------- /packages/preflight/src/preflight.test.ts: -------------------------------------------------------------------------------- 1 | import type { Instance, Injector } from '@beamwind/types' 2 | 3 | import { createInstance, virtualInjector } from '@beamwind/core' 4 | 5 | import preflight from '..' 6 | 7 | let injector: Injector 8 | let instance: Instance 9 | 10 | beforeEach(() => { 11 | injector = virtualInjector() 12 | instance = createInstance({ injector, hash: false }) 13 | }) 14 | 15 | test('add preflight styles', () => { 16 | instance.setup(preflight()) 17 | 18 | expect(instance.bw('text-left')).toBe('text-left') 19 | 20 | expect(injector.target).toMatchObject([ 21 | ':root{-moz-tab-size:4;tab-size:4}', 22 | 'blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}', 23 | 'button{background-color:transparent;background-image:none}', 24 | "button,[type='button'],[type='reset'],[type='submit']{-webkit-appearance:button}", 25 | 'button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}', 26 | 'fieldset{margin:0;padding:0}', 27 | 'ol,ul{list-style:none;margin:0;padding:0}', 28 | 'html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif}', 29 | 'body{margin:0;font-family:inherit;line-height:inherit}', 30 | '*,::before,::after{box-sizing:border-box;border:0 solid currentColor}', 31 | 'hr{height:0;color:inherit;border-top-width:1px}', 32 | 'img{border-style:solid}', 33 | 'textarea{resize:vertical}', 34 | 'input::placeholder,textarea::placeholder{color:#a1a1aa}', 35 | 'button,[role="button"]{cursor:pointer}', 36 | 'table{text-indent:0;border-color:inherit;border-collapse:collapse}', 37 | 'h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}', 38 | 'a{color:inherit;text-decoration:inherit}', 39 | 'button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;margin:0;padding:0;line-height:inherit;color:inherit}', 40 | 'button,select{text-transform:none}', 41 | '::-moz-focus-inner{border-style:none;padding:0}', 42 | ':-moz-focusring{outline:1px dotted ButtonText}', 43 | ':-moz-ui-invalid{box-shadow:none}', 44 | 'legend{padding:0}', 45 | 'progress{vertical-align:baseline}', 46 | '::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}', 47 | '[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}', 48 | '::-webkit-search-decoration{-webkit-appearance:none}', 49 | '::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}', 50 | 'summary{display:list-item}', 51 | 'abbr[title]{text-decoration:underline dotted}', 52 | 'b,strong{font-weight:bolder}', 53 | 'pre,code,kbd,samp{font-family:ui-monospace,monospace;font-size:1em}', 54 | 'sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}', 55 | 'sub{bottom:-0.25em}', 56 | 'sup{top:-0.5em}', 57 | 'img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}', 58 | 'img,video{max-width:100%;height:auto}', 59 | '.text-left{text-align:left}', 60 | ]) 61 | }) 62 | 63 | test('add preflight styles with custom theme', () => { 64 | instance.setup([ 65 | preflight(), 66 | { 67 | theme: { 68 | extend: { 69 | fontFamily: { sans: 'ui-sans-serif', mono: 'ui-monospace' }, 70 | borderColor: { DEFAULT: '#222' }, 71 | placeholderColor: { DEFAULT: '#333' }, 72 | }, 73 | }, 74 | }, 75 | ]) 76 | 77 | expect(instance.bw('text-left')).toBe('text-left') 78 | 79 | expect(injector.target).toContain( 80 | 'html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif}', 81 | ) 82 | expect(injector.target).toContain('*,::before,::after{box-sizing:border-box;border:0 solid #222}') 83 | expect(injector.target).toContain('input::placeholder,textarea::placeholder{color:#333}') 84 | expect(injector.target).toContain('pre,code,kbd,samp{font-family:ui-monospace;font-size:1em}') 85 | }) 86 | 87 | test('add preflight styles with theme missing some values', () => { 88 | instance.setup([ 89 | preflight(), 90 | { 91 | theme: { 92 | fontFamily: { sans: 'ui-sans-serif', mono: 'ui-monospace' }, 93 | borderColor: {}, 94 | placeholderColor: {}, 95 | }, 96 | }, 97 | ]) 98 | 99 | expect(instance.bw('text-left')).toBe('text-left') 100 | 101 | expect(injector.target).toContain( 102 | '*,::before,::after{box-sizing:border-box;border:0 solid currentColor}', 103 | ) 104 | expect(injector.target).toContain('input::placeholder,textarea::placeholder{color:#a1a1aa}') 105 | }) 106 | -------------------------------------------------------------------------------- /packages/preflight/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/tsconfig", 3 | "extends": "../../tsconfig.json", 4 | "include": ["src", "../../types"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/preset-play/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | ## [2.0.4](https://github.com/kenoxa/beamwind/compare/@beamwind/preset-play@2.0.3...@beamwind/preset-play@2.0.4) (2020-12-05) 7 | 8 | **Note:** Version bump only for package @beamwind/preset-play 9 | 10 | ## [2.0.3](https://github.com/kenoxa/beamwind/compare/@beamwind/preset-play@2.0.2...@beamwind/preset-play@2.0.3) (2020-12-04) 11 | 12 | **Note:** Version bump only for package @beamwind/preset-play 13 | 14 | ## [2.0.2](https://github.com/kenoxa/beamwind/compare/@beamwind/preset-play@2.0.1...@beamwind/preset-play@2.0.2) (2020-12-01) 15 | 16 | ### Bug Fixes 17 | 18 | - svelte example ([9a85077](https://github.com/kenoxa/beamwind/commit/9a85077e1a4e1674a18b5668cd9b022fa64a6b4c)) 19 | 20 | ## [2.0.1](https://github.com/kenoxa/beamwind/compare/@beamwind/preset-play@2.0.0...@beamwind/preset-play@2.0.1) (2020-12-01) 21 | 22 | ### Bug Fixes 23 | 24 | - auto convert font sizes ([d9919c0](https://github.com/kenoxa/beamwind/commit/d9919c04173a4c670bdef261aef411a6fffcb243)) 25 | - provide base color set for stroke ([55b9487](https://github.com/kenoxa/beamwind/commit/55b9487ee97842117b522d30f37e74d6c7088b54)) 26 | 27 | # 2.0.0 (2020-11-30) 28 | 29 | **Note:** Version bump only for package @beamwind/preset-play 30 | -------------------------------------------------------------------------------- /packages/preset-play/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 [these people](https://github.com/kenoxa/beamwind/graphs/contributors) 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/preset-play/README.md: -------------------------------------------------------------------------------- 1 | # @beamwind/preset-play 2 | 3 | > rapid prototyping for beamwind using auto-conversion of values 4 | 5 | [![MIT License](https://flat.badgen.net/github/license/kenoxa/beamwind)](https://github.com/kenoxa/beamwind/blob/main/LICENSE) 6 | [![Latest Release](https://flat.badgen.net/npm/v/@beamwind/preset-play?icon=npm&label)](https://www.npmjs.com/package/@beamwind/preset-play) 7 | [![Github](https://flat.badgen.net/badge/icon/kenoxa%2Fbeamwind?icon=github&label)](https://github.com/kenoxa/beamwind/blob/main/packages/preset-play) 8 | [![Typescript](https://flat.badgen.net/badge/icon/included?icon=typescript&label)](https://unpkg.com/browse/@beamwind/preset-play/types/preset-play.d.ts) 9 | [![Bundle Size](https://flat.badgen.net/bundlephobia/minzip/@beamwind/preset-play?icon=packagephobia&label&color=blue)](https://bundlephobia.com/result?p=@beamwind/preset-play) 10 | 11 | > [Read the docs](https://beamwind.js.org) | 12 | > [API](https://beamwind.js.org/packages/preset-play) | 13 | > [Change Log](https://github.com/kenoxa/beamwind/blob/main/packages/preset-play/CHANGELOG.md) 14 | 15 | --- 16 | 17 | > This is a only a preset. [@beamwind/play](https://github.com/kenoxa/beamwind/blob/main/packages/play) provides a ready to use `bw` export. 18 | > This preset should be used for _prototyping only_ as it usually prevents a consistent UI experience. 19 | 20 | --- 21 | 22 | 23 | 24 | 25 | 26 | 27 | - [Installation](#installation) 28 | - [Usage](#usage) 29 | - [Contribute](#contribute) 30 | - [License](#license) 31 | 32 | 33 | 34 | 35 | ## Installation 36 | 37 | ```sh 38 | npm install @beamwind/preset-play 39 | ``` 40 | 41 | ## Usage 42 | 43 | > Please refer to the [main documentation](https://beamwind.js.org#usage) for further information. 44 | 45 | ```js 46 | import { setup, warn } from '@beamwind/core' 47 | import play from '@beamwind/preset-play' 48 | 49 | // Use warn as fallback if no conversion could be made 50 | setup(play(warn)) 51 | ``` 52 | 53 | See [preset-play/src/play.ts](https://github.com/kenoxa/beamwind/blob/main/packages/preset-play/src/play.ts) which conversions are applied. 54 | 55 | Most tailwind classes use a deterministic number calculation scheme (for example [width](https://tailwindcss.com/docs/width)). If beamwind detects a number in a directive and there is not mapped value in the theme it uses the following algorithm to generate a CSS value which aligns with the tailwind rules for that directive: 56 | 57 | - decimal numbers (`2` or `1.5`) are divided by a divisor and a unit is added (`w-2.5` becomes `width: 0.625rem;`) 58 | - fractions (`1/6` or `3/5`) are evaluated and `%` is used as a unit (`w-4/5` becomes `width: 80%;`) 59 | 60 | - most directives are lenient when a value is not found in the theme: 61 | 62 | - decimal numbers (`2` or `1.5`) are divided by a divisor and a unit is added (`w-2.5` becomes `width: 0.625rem;`) 63 | - fractions (`1/6` or `3/5`) are evaluated and `%` is added as a unit (`w-4/5` becomes `width: 80%;`) 64 | - color names (`text-rebeccapurple`) and hex colors (`text-#009900`) 65 | 66 | - `bg-gradient` accepts additionally to the side-or-corner parameter (`bg-gradient-to-tr`) an angle or mixed parameters: 67 | - `bg-gradient` - defaults to `180deg` eg `to bottom` 68 | - `bg-gradient-45` 69 | - `bg-gradient-0.25turn` 70 | - `bg-gradient-to-bottom-left` 71 | 72 | ## Contribute 73 | 74 | Thanks for being willing to contribute! 75 | 76 | > This project is free and open-source, so if you think this project can help you or anyone else, you may [star it on GitHub](https://github.com/kenoxa/beamwind). Feel free to [open an issue](https://github.com/kenoxa/beamwind/issues) if you have any idea, question, or you've found a bug. 77 | 78 | **Working on your first Pull Request?** You can learn how from this _free_ series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) 79 | 80 | We are following the [Conventional Commits](https://www.conventionalcommits.org) convention. 81 | 82 | ### Sponsors 83 | 84 | [![Kenoxa GmbH](https://images.opencollective.com/kenoxa/9c25796/logo/68.png)](https://www.kenoxa.com) [Kenoxa GmbH](https://www.kenoxa.com) 85 | 86 | ## License 87 | 88 | [MIT](https://github.com/kenoxa/beamwind/blob/main/LICENSE) © [Kenoxa GmbH](https://kenoxa.com) 89 | -------------------------------------------------------------------------------- /packages/preset-play/package-scripts.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../package-scripts') 2 | -------------------------------------------------------------------------------- /packages/preset-play/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@beamwind/preset-play", 3 | "version": "2.0.4", 4 | "description": "rapid prototyping for beamwind using auto-conversion of values", 5 | "keywords": [ 6 | "beamwind", 7 | "tailwind" 8 | ], 9 | "homepage": "https://github.com/kenoxa/beamwind#readme", 10 | "bugs": { 11 | "url": "https://github.com/kenoxa/beamwind/issues" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/kenoxa/beamwind.git", 16 | "directory": "packages/preset-play" 17 | }, 18 | "license": "MIT", 19 | "author": "Kenoxa GmbH ", 20 | "main": "src/index.ts", 21 | "scripts": { 22 | "build": "nps", 23 | "prepublishOnly": "nps", 24 | "test": "nps" 25 | }, 26 | "prettier": "@carv/prettier-config", 27 | "eslintConfig": { 28 | "extends": "@carv/eslint-config", 29 | "root": true 30 | }, 31 | "jest": { 32 | "preset": "@carv/jest-preset" 33 | }, 34 | "devDependencies": { 35 | "nps": "^5.9.12" 36 | }, 37 | "publishConfig": { 38 | "access": "public" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/preset-play/src/__tests__/play.test.ts: -------------------------------------------------------------------------------- 1 | import type { Theme } from '@beamwind/types' 2 | 3 | import { strict, theme } from '@beamwind/core' 4 | import { play } from '../play' 5 | 6 | test.each([ 7 | ['borderWidth', ['px'], '1px'], 8 | ['borderWidth', ['0'], '0px'], 9 | ['borderWidth', ['1'], '1px'], 10 | ['borderWidth', ['2'], '2px'], 11 | ['divideWidth', ['px'], '1px'], 12 | ['divideWidth', ['0'], '0px'], 13 | ['divideWidth', ['1'], '1px'], 14 | ['divideWidth', ['2'], '2px'], 15 | ['spacing', ['px'], '1px'], 16 | ['spacing', ['1'], '0.25rem'], 17 | ['spacing', ['2'], '0.5rem'], 18 | ['spacing', ['64'], '16rem'], 19 | ['spacing', ['1/5'], '20%'], 20 | ['spacing', ['3/7'], '42.857143%'], 21 | ['borderRadius', ['.5rem'], '.5rem'], 22 | ['fontSize', ['2.5rem'], '2.5rem'], 23 | ['durations', ['100'], '100ms'], 24 | ['transitionDelay', ['2s'], '2s'], 25 | ['opacity', ['50'], '0.5'], 26 | ['opacity', ['86.54321'], '0.865432'], 27 | ['rotate', ['180'], '180deg'], 28 | ['rotate', ['0.25turn'], '0.25turn'], 29 | ['width', ['screen'], '100vw'], 30 | ['width', ['px'], '1px'], 31 | ['width', ['50'], '12.5rem'], 32 | ['width', ['5/12'], '41.666667%'], 33 | ['maxWidth', ['30em'], '30em'], 34 | ['height', ['screen'], '100vh'], 35 | ['height', ['px'], '1px'], 36 | ['height', ['96'], '24rem'], 37 | ['height', ['1/12'], '8.333333%'], 38 | ['maxHeight', ['36vmin'], '36vmin'], 39 | ['divideColor', ['current'], 'currentColor'], 40 | ['divideColor', ['fuchsia'], 'fuchsia'], 41 | ['divideColor', ['#123456'], '#123456'], 42 | ['divideColor', ['#aaa'], '#aaa'], 43 | ['order', ['1'], '1'], 44 | ['strokeWidth', ['0'], '0'], 45 | ['transitionTimingFunction', ['ease', 'in', 'out'], 'ease-in-out'], 46 | ])('%s: %j => %s', (section, parts, expected) => { 47 | expect(play(strict).unknown(section as keyof Theme, parts, false, theme)).toBe(expected) 48 | }) 49 | 50 | test.each([ 51 | ['borderWidth', []], 52 | ['borderWidth', ['DEFAULT']], 53 | ['borderWidth', ['1', '2']], 54 | ['inset', []], 55 | ['inset', ['DEFAULT']], 56 | ['inset', ['1', '2']], 57 | ['transitionDuration', []], 58 | ['transitionDuration', ['DEFAULT']], 59 | ['transitionDuration', ['1', '2']], 60 | ['borderOpacity', []], 61 | ['borderOpacity', ['DEFAULT']], 62 | ['borderOpacity', ['1', '2']], 63 | ['rotate', []], 64 | ['rotate', ['DEFAULT']], 65 | ['rotate', ['1', '2']], 66 | ['maxWidth', []], 67 | ['maxWidth', ['DEFAULT']], 68 | ['maxWidth', ['1', '2']], 69 | ['maxHeight', []], 70 | ['maxHeight', ['DEFAULT']], 71 | ['maxHeight', ['1', '2']], 72 | ['gradientColorStops', []], 73 | ['gradientColorStops', ['DEFAULT']], 74 | ['gradientColorStops', ['1', '2']], 75 | ['strokeWidth', []], 76 | ['strokeWidth', ['DEFAULT']], 77 | ['strokeWidth', ['1', '2']], 78 | ['transitionProperty', []], 79 | ])('%s: %j => warning', (section, parts) => { 80 | const report = { 81 | unknown: jest.fn(), 82 | warn: jest.fn(), 83 | } 84 | 85 | expect(play(report).unknown(section as keyof Theme, parts, false, theme)).toBeUndefined() 86 | 87 | expect(report.unknown).toHaveBeenCalledTimes(1) 88 | expect(report.unknown).toHaveBeenCalledWith(section, parts, false, theme) 89 | }) 90 | -------------------------------------------------------------------------------- /packages/preset-play/src/__tests__/ssr.test.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable tsdoc/syntax */ 2 | /** 3 | * @jest-environment node 4 | */ 5 | /* eslint-enable tsdoc/syntax */ 6 | 7 | import type { Theme } from '@beamwind/types' 8 | 9 | import { strict, theme } from '@beamwind/core' 10 | import { play } from '../play' 11 | 12 | // Simulate non-browser enviroment 13 | // eslint-disable-next-line @typescript-eslint/no-explicit-any 14 | delete (globalThis as any).Option 15 | 16 | test.each([ 17 | ['ringColor', ['current'], 'currentColor'], 18 | ['ringColor', ['#123456'], '#123456'], 19 | ['ringColor', ['#aaa'], '#aaa'], 20 | ])('%s: %j => %s', (section, parts, expected) => { 21 | expect(play(strict).unknown(section as keyof Theme, parts, false, theme)).toBe(expected) 22 | }) 23 | 24 | test.each([['ringColor', ['fuchsia'], 'fuchsia']])('%s: %j => warning', (section, parts) => { 25 | const report = { 26 | unknown: jest.fn(), 27 | warn: jest.fn(), 28 | } 29 | 30 | expect(play(report).unknown(section as keyof Theme, parts, false, theme)).toBeUndefined() 31 | 32 | expect(report.unknown).toHaveBeenCalledTimes(1) 33 | expect(report.unknown).toHaveBeenCalledWith(section, parts, false, theme) 34 | }) 35 | -------------------------------------------------------------------------------- /packages/preset-play/src/index.ts: -------------------------------------------------------------------------------- 1 | import type { ConfigurationOptions, Mode } from '@beamwind/types' 2 | 3 | import { play } from './play' 4 | import { theme } from './theme' 5 | 6 | export interface PlayOptions { 7 | mode: Mode 8 | } 9 | 10 | export default ({ mode }: PlayOptions): ConfigurationOptions => ({ theme, mode: play(mode) }) 11 | -------------------------------------------------------------------------------- /packages/preset-play/src/is.ts: -------------------------------------------------------------------------------- 1 | export const numberLike = (value: string): boolean => /^[-+]?(?:\d*\.)?\d+$/.test(value) 2 | -------------------------------------------------------------------------------- /packages/preset-play/src/play.ts: -------------------------------------------------------------------------------- 1 | /* eslint-disable @typescript-eslint/consistent-type-assertions */ 2 | import type { Mode } from '@beamwind/types' 3 | 4 | import * as is from './is' 5 | 6 | const join = (parts: readonly string[], separator = '-'): string => parts.join(separator) 7 | 8 | const isColor = (color: string): boolean => { 9 | if (typeof Option === 'function') { 10 | const s = new Option().style 11 | s.color = color 12 | return s.color !== '' 13 | } 14 | 15 | return /^#[\da-f]{3,8}$/i.test(color) 16 | } 17 | 18 | const asSize = (value: string): string | undefined => 19 | /[-+]?(?:\d*\.)?\d+(?:ch|r?em|ex|ic|r?lh|v(?:[hwib]|min|max)|px|cm|mm|in|p[ct]|%)/.test(value) 20 | ? value 21 | : undefined 22 | 23 | const asAngle = (value: string): string | undefined => 24 | /[-+]?(?:\d*\.)?\d+(?:deg|g?rad|turn)/.test(value) ? value : undefined 25 | 26 | const asTime = (value: string): string | undefined => 27 | /[-+]?(?:\d*\.)?\d+m?s/.test(value) ? value : undefined 28 | 29 | const asNumber = (value: string): string | undefined => (is.numberLike(value) ? value : undefined) 30 | 31 | // Shared variables 32 | let match: RegExpExecArray | null 33 | 34 | const withUnit = (value: string, unit?: string): string => (unit ? value + unit : value) 35 | 36 | const divide = ( 37 | dividend: string | number, 38 | divisor: string | number, 39 | unit?: string, 40 | factor?: number, 41 | ): string => 42 | withUnit(String(Number(((Number(dividend) / Number(divisor)) * (factor || 1)).toFixed(6))), unit) 43 | 44 | const convert = (value: string, unit: string, screenUnit?: 'h' | 'w'): undefined | string => { 45 | if (value === 'px') return '1px' 46 | 47 | if (screenUnit && value === 'screen') { 48 | return `100v${screenUnit}` 49 | } 50 | 51 | if (is.numberLike(value)) { 52 | // X = 1 => 0.25rem 53 | return unit === 'rem' ? divide(value, 4, 'rem') : withUnit(value, unit) 54 | } 55 | 56 | if (unit === 'rem' && (match = /^(-?\d+)\/(-?\d+)$/.exec(value))) { 57 | // X = 4/6 => 66.6666% 58 | return divide(match[1], match[2], '%', 100) 59 | } 60 | } 61 | 62 | export const play = (parent: Mode): Mode => ({ 63 | // eslint-disable-next-line complexity 64 | unknown(section, parts, optional, theme) { 65 | let value: unknown 66 | 67 | switch (section) { 68 | case 'borderWidth': 69 | case 'divideWidth': 70 | case 'ringWidth': 71 | case 'ringOffsetWidth': 72 | case 'borderRadius': 73 | if (parts.length === 1) { 74 | value = convert(parts[0], 'px') || asSize(parts[0]) 75 | } 76 | 77 | break 78 | 79 | case 'spacing': 80 | case 'letterSpacing': 81 | case 'lineHeight': 82 | case 'gap': 83 | case 'inset': 84 | case 'translate': 85 | case 'fontSize': 86 | if (parts.length === 1) { 87 | value = convert(parts[0], 'rem') || asSize(parts[0]) 88 | } 89 | 90 | break 91 | 92 | case 'durations': 93 | case 'transitionDuration': 94 | case 'transitionDelay': 95 | if (parts.length === 1) { 96 | value = convert(parts[0], 'ms') || asTime(parts[0]) 97 | } 98 | 99 | break 100 | 101 | case 'opacity': 102 | case 'backgroundOpacity': 103 | case 'borderOpacity': 104 | case 'scale': 105 | if (parts.length === 1) { 106 | value = asNumber(parts[0]) && divide(parts[0], 100) 107 | } 108 | 109 | break 110 | 111 | case 'rotate': 112 | case 'skew': 113 | // '180deg' 114 | // '0.25turn' 115 | // 'to left' 116 | if (parts.length === 1) { 117 | value = convert(parts[0], 'deg') || asAngle(parts[0]) 118 | } 119 | 120 | break 121 | 122 | case 'width': 123 | case 'maxWidth': 124 | // .w-64 width: 16rem; 125 | // .w-auto width: auto; 126 | // .w-px width: 1px; 127 | // .w-1/2 width: 50%; 128 | // .w-full width: 100%; 129 | // .w-screen width: 100vw; 130 | if (parts.length === 1) { 131 | value = convert(parts[0], 'rem', 'w') || asSize(parts[0]) 132 | } 133 | 134 | break 135 | 136 | case 'height': 137 | case 'maxHeight': 138 | // .w-64 width: 16rem; 139 | // .w-auto width: auto; 140 | // .w-px width: 1px; 141 | // .w-1/2 width: 50%; 142 | // .w-full width: 100%; 143 | // .w-screen width: 100vw; 144 | if (parts.length === 1) { 145 | value = convert(parts[0], 'rem', 'h') || asSize(parts[0]) 146 | } 147 | 148 | break 149 | 150 | // This includes 'transparent', #AAA or named colors 151 | case 'gradientColorStops': 152 | case 'borderColor': 153 | case 'backgroundColor': 154 | case 'colors': 155 | case 'divideColor': 156 | case 'fill': 157 | case 'placeholderColor': 158 | case 'ringColor': 159 | case 'ringOffsetColor': 160 | case 'stroke': 161 | case 'textColor': 162 | if (parts.length === 1) { 163 | if (parts[0] === 'current') { 164 | return 'currentColor' 165 | } 166 | 167 | if (isColor(parts[0])) { 168 | return parts[0] 169 | } 170 | } 171 | 172 | break 173 | 174 | case 'order': 175 | case 'strokeWidth': 176 | case 'fontWeight': 177 | case 'zIndex': 178 | if (parts.length === 1) { 179 | value = asNumber(parts[0]) 180 | } 181 | 182 | break 183 | 184 | case 'transitionProperty': 185 | case 'transitionTimingFunction': 186 | if (parts.length > 0) { 187 | // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-explicit-any 188 | return join(parts) as any 189 | } 190 | 191 | break 192 | } 193 | 194 | return value == null ? parent.unknown(section, parts, optional, theme) : value 195 | }, 196 | 197 | warn: parent.warn, 198 | }) 199 | 200 | /* eslint-enable @typescript-eslint/consistent-type-assertions */ 201 | -------------------------------------------------------------------------------- /packages/preset-play/src/theme.ts: -------------------------------------------------------------------------------- 1 | import type { ThemeConfiguration } from '@beamwind/types' 2 | 3 | export const theme: ThemeConfiguration = (base) => ({ 4 | stroke: (theme) => ({ 5 | ...base('stroke'), 6 | ...theme('colors'), 7 | }), 8 | }) 9 | -------------------------------------------------------------------------------- /packages/preset-play/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/tsconfig", 3 | "extends": "../../tsconfig.json", 4 | "include": ["src", "../../types"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/preset-system/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # [2.3.0](https://github.com/kenoxa/beamwind/compare/@beamwind/preset-system@2.2.0...@beamwind/preset-system@2.3.0) (2020-12-05) 7 | 8 | ### Features 9 | 10 | - ring defaults ([e50bfdf](https://github.com/kenoxa/beamwind/commit/e50bfdf1edf3dfb2421b4d9ab3a73d09eb1da475)) 11 | 12 | # [2.2.0](https://github.com/kenoxa/beamwind/compare/@beamwind/preset-system@2.1.0...@beamwind/preset-system@2.2.0) (2020-12-04) 13 | 14 | ### Features 15 | 16 | - dark mode ([11eb4aa](https://github.com/kenoxa/beamwind/commit/11eb4aafefb815d5afcd8238935bc48d4094df14)) 17 | 18 | # [2.1.0](https://github.com/kenoxa/beamwind/compare/@beamwind/preset-system@2.0.3...@beamwind/preset-system@2.1.0) (2020-12-02) 19 | 20 | ### Bug Fixes 21 | 22 | - generate shade and on colors ([9a653fa](https://github.com/kenoxa/beamwind/commit/9a653fa41160b30a21a58d118902c6238272ec38)) 23 | 24 | ### Features 25 | 26 | - support background images from theme ([492ffe0](https://github.com/kenoxa/beamwind/commit/492ffe063197d4af1a6ea2daff89e8e43d0855ed)) 27 | 28 | ## [2.0.3](https://github.com/kenoxa/beamwind/compare/@beamwind/preset-system@2.0.1...@beamwind/preset-system@2.0.3) (2020-12-01) 29 | 30 | ### Bug Fixes 31 | 32 | - color variant creation ([9984a11](https://github.com/kenoxa/beamwind/commit/9984a110f825a1940e5ef2644697ea8ee8ec385a)) 33 | 34 | ## [2.0.2](https://github.com/kenoxa/beamwind/compare/@beamwind/preset-system@2.0.1...@beamwind/preset-system@2.0.2) (2020-12-01) 35 | 36 | **Note:** Version bump only for package @beamwind/preset-system 37 | 38 | ## [2.0.1](https://github.com/kenoxa/beamwind/compare/@beamwind/preset-system@2.0.0...@beamwind/preset-system@2.0.1) (2020-12-01) 39 | 40 | ### Bug Fixes 41 | 42 | - use colors from base theme to generate variants ([7ee8a8c](https://github.com/kenoxa/beamwind/commit/7ee8a8c8e63936017e11ce22e830c312efe5ca42)) 43 | 44 | # 2.0.0 (2020-11-30) 45 | 46 | **Note:** Version bump only for package @beamwind/preset-system 47 | 48 | ## [1.0.5](https://github.com/kenoxa/beamwind/compare/@beamwind/preset-semantic@1.0.4...@beamwind/preset-semantic@1.0.5) (2020-11-27) 49 | 50 | **Note:** Version bump only for package @beamwind/preset-semantic 51 | 52 | ## [1.0.4](https://github.com/kenoxa/beamwind/compare/@beamwind/preset-semantic@1.0.3...@beamwind/preset-semantic@1.0.4) (2020-11-26) 53 | 54 | **Note:** Version bump only for package @beamwind/preset-semantic 55 | 56 | ## [1.0.3](https://github.com/kenoxa/beamwind/compare/@beamwind/preset-semantic@1.0.2...@beamwind/preset-semantic@1.0.3) (2020-11-26) 57 | 58 | **Note:** Version bump only for package @beamwind/preset-semantic 59 | 60 | ## [1.0.2](https://github.com/kenoxa/beamwind/compare/@beamwind/preset-semantic@1.0.1...@beamwind/preset-semantic@1.0.2) (2020-11-25) 61 | 62 | **Note:** Version bump only for package @beamwind/preset-semantic 63 | 64 | ## 1.0.1 (2020-11-25) 65 | 66 | **Note:** Version bump only for package @beamwind/preset-semantic 67 | -------------------------------------------------------------------------------- /packages/preset-system/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 [these people](https://github.com/kenoxa/beamwind/graphs/contributors) 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/preset-system/package-scripts.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../package-scripts') 2 | -------------------------------------------------------------------------------- /packages/preset-system/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@beamwind/preset-system", 3 | "version": "2.3.0", 4 | "description": "beamwind design system preset using a semantic naming scheme", 5 | "keywords": [ 6 | "beamwind", 7 | "tailwind" 8 | ], 9 | "homepage": "https://github.com/kenoxa/beamwind#readme", 10 | "bugs": { 11 | "url": "https://github.com/kenoxa/beamwind/issues" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/kenoxa/beamwind.git", 16 | "directory": "packages/preset-system" 17 | }, 18 | "license": "MIT", 19 | "author": "Kenoxa GmbH ", 20 | "main": "src/index.ts", 21 | "scripts": { 22 | "build": "nps", 23 | "prepublishOnly": "nps", 24 | "test": "nps" 25 | }, 26 | "prettier": "@carv/prettier-config", 27 | "eslintConfig": { 28 | "extends": "@carv/eslint-config", 29 | "root": true 30 | }, 31 | "jest": { 32 | "preset": "@carv/jest-preset" 33 | }, 34 | "dependencies": { 35 | "@beamwind/colors": "^2.0.3" 36 | }, 37 | "devDependencies": { 38 | "nps": "^5.9.12" 39 | }, 40 | "publishConfig": { 41 | "access": "public" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /packages/preset-system/src/index.ts: -------------------------------------------------------------------------------- 1 | import type { ConfigurationOptions } from '@beamwind/types' 2 | 3 | import type { Options } from './types' 4 | 5 | import { theme } from './theme' 6 | 7 | export default (options?: Options): ConfigurationOptions => ({ 8 | theme: theme(options), 9 | }) 10 | 11 | export * from './types' 12 | -------------------------------------------------------------------------------- /packages/preset-system/src/theme.test.ts: -------------------------------------------------------------------------------- 1 | import { theme as makeTheme } from './theme' 2 | 3 | test('theme values', () => { 4 | // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/ban-types 5 | const theme = (makeTheme() as Function)(() => ({})) 6 | 7 | expect(theme.extend?.height).toStrictEqual({ 8 | '1/2': '50%', 9 | '1/3': '33.333333%', 10 | '2/3': '66.666667%', 11 | '1/4': '25%', 12 | '2/4': '50%', 13 | '3/4': '75%', 14 | '1/5': '20%', 15 | '2/5': '40%', 16 | '3/5': '60%', 17 | '4/5': '80%', 18 | '1/6': '16.666667%', 19 | '2/6': '33.333333%', 20 | '3/6': '50%', 21 | '4/6': '66.666667%', 22 | '5/6': '83.333333%', 23 | }) 24 | }) 25 | -------------------------------------------------------------------------------- /packages/preset-system/src/types.ts: -------------------------------------------------------------------------------- 1 | import type { Shades } from '@beamwind/colors' 2 | 3 | export interface Options { 4 | colors?: Record 5 | shades?: Shades 6 | } 7 | -------------------------------------------------------------------------------- /packages/preset-system/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/tsconfig", 3 | "extends": "../../tsconfig.json", 4 | "include": ["src", "../../types"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/preset-tailwind/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | ## [2.0.2](https://github.com/kenoxa/beamwind/compare/@beamwind/preset-tailwind@2.0.1...@beamwind/preset-tailwind@2.0.2) (2020-12-05) 7 | 8 | **Note:** Version bump only for package @beamwind/preset-tailwind 9 | 10 | ## [2.0.1](https://github.com/kenoxa/beamwind/compare/@beamwind/preset-tailwind@2.0.0...@beamwind/preset-tailwind@2.0.1) (2020-12-04) 11 | 12 | **Note:** Version bump only for package @beamwind/preset-tailwind 13 | 14 | # [2.0.0](https://github.com/kenoxa/beamwind/compare/@beamwind/preset-tailwind@1.0.4...@beamwind/preset-tailwind@2.0.0) (2020-11-30) 15 | 16 | **Note:** Version bump only for package @beamwind/preset-tailwind 17 | 18 | ## [1.0.4](https://github.com/kenoxa/beamwind/compare/@beamwind/preset-tailwind@1.0.3...@beamwind/preset-tailwind@1.0.4) (2020-11-27) 19 | 20 | **Note:** Version bump only for package @beamwind/preset-tailwind 21 | 22 | ## [1.0.3](https://github.com/kenoxa/beamwind/compare/@beamwind/preset-tailwind@1.0.2...@beamwind/preset-tailwind@1.0.3) (2020-11-26) 23 | 24 | **Note:** Version bump only for package @beamwind/preset-tailwind 25 | 26 | ## [1.0.2](https://github.com/kenoxa/beamwind/compare/@beamwind/preset-tailwind@1.0.1...@beamwind/preset-tailwind@1.0.2) (2020-11-26) 27 | 28 | **Note:** Version bump only for package @beamwind/preset-tailwind 29 | 30 | ## 1.0.1 (2020-11-25) 31 | 32 | **Note:** Version bump only for package @beamwind/preset-tailwind 33 | -------------------------------------------------------------------------------- /packages/preset-tailwind/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 [these people](https://github.com/kenoxa/beamwind/graphs/contributors) 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/preset-tailwind/README.md: -------------------------------------------------------------------------------- 1 | # @beamwind/preset-tailwind 2 | 3 | > beamwind preset mirroring the [tailwind default theme](https://github.com/tailwindlabs/tailwindcss/blob/master/stubs/defaultConfig.stub.js) 4 | 5 | [![MIT License](https://flat.badgen.net/github/license/kenoxa/beamwind)](https://github.com/kenoxa/beamwind/blob/main/LICENSE) 6 | [![Latest Release](https://flat.badgen.net/npm/v/@beamwind/preset-tailwind?icon=npm&label)](https://www.npmjs.com/package/@beamwind/preset-tailwind) 7 | [![Github](https://flat.badgen.net/badge/icon/kenoxa%2Fbeamwind?icon=github&label)](https://github.com/kenoxa/beamwind/blob/main/packages/preset-tailwind) 8 | [![Typescript](https://flat.badgen.net/badge/icon/included?icon=typescript&label)](https://unpkg.com/browse/@beamwind/preset-tailwind/types/preset-tailwind.d.ts) 9 | [![Bundle Size](https://flat.badgen.net/bundlephobia/minzip/@beamwind/preset-tailwind?icon=packagephobia&label&color=blue)](https://bundlephobia.com/result?p=@beamwind/preset-tailwind) 10 | 11 | > [Read the docs](https://beamwind.js.org) | 12 | > [API](https://beamwind.js.org/packages/preset-tailwind) | 13 | > [Change Log](https://github.com/kenoxa/beamwind/blob/main/packages/preset-tailwind/CHANGELOG.md) 14 | 15 | --- 16 | 17 | > This is a only a preset. [beamwind](https://github.com/kenoxa/beamwind/blob/main/packages/beamwind) provides a ready to use `bw` export. 18 | 19 | --- 20 | 21 | 22 | 23 | 24 | 25 | 26 | - [Installation](#installation) 27 | - [Usage](#usage) 28 | - [Contribute](#contribute) 29 | - [License](#license) 30 | 31 | 32 | 33 | 34 | ## Installation 35 | 36 | ```sh 37 | npm install @beamwind/preset-tailwind 38 | ``` 39 | 40 | ## Usage 41 | 42 | > Please refer to the [main documentation](https://beamwind.js.org#usage) for further information. 43 | 44 | ```js 45 | import { setup } from '@beamwind/core' 46 | import tailwind from '@beamwind/preset-tailwind' 47 | 48 | setup(tailwind()) 49 | ``` 50 | 51 | See [preset-tailwind/src/theme.ts](https://github.com/kenoxa/beamwind/blob/main/packages/preset-tailwind/src/theme.ts) and [core/src/theme.ts](https://github.com/kenoxa/beamwind/blob/main/packages/core//src/theme.ts) for the set values. 52 | 53 | ## Contribute 54 | 55 | Thanks for being willing to contribute! 56 | 57 | > This project is free and open-source, so if you think this project can help you or anyone else, you may [star it on GitHub](https://github.com/kenoxa/beamwind). Feel free to [open an issue](https://github.com/kenoxa/beamwind/issues) if you have any idea, question, or you've found a bug. 58 | 59 | **Working on your first Pull Request?** You can learn how from this _free_ series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) 60 | 61 | We are following the [Conventional Commits](https://www.conventionalcommits.org) convention. 62 | 63 | ### Sponsors 64 | 65 | [![Kenoxa GmbH](https://images.opencollective.com/kenoxa/9c25796/logo/68.png)](https://www.kenoxa.com) [Kenoxa GmbH](https://www.kenoxa.com) 66 | 67 | ## License 68 | 69 | [MIT](https://github.com/kenoxa/beamwind/blob/main/LICENSE) © [Kenoxa GmbH](https://kenoxa.com) 70 | -------------------------------------------------------------------------------- /packages/preset-tailwind/package-scripts.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../package-scripts') 2 | -------------------------------------------------------------------------------- /packages/preset-tailwind/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@beamwind/preset-tailwind", 3 | "version": "2.0.2", 4 | "description": "beamwind preset mirroring tailwind default theme", 5 | "keywords": [ 6 | "beamwind", 7 | "tailwind" 8 | ], 9 | "homepage": "https://github.com/kenoxa/beamwind#readme", 10 | "bugs": { 11 | "url": "https://github.com/kenoxa/beamwind/issues" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/kenoxa/beamwind.git", 16 | "directory": "packages/preset-tailwind" 17 | }, 18 | "license": "MIT", 19 | "author": "Kenoxa GmbH ", 20 | "main": "src/index.ts", 21 | "scripts": { 22 | "build": "nps", 23 | "prepublishOnly": "nps", 24 | "test": "nps" 25 | }, 26 | "prettier": "@carv/prettier-config", 27 | "eslintConfig": { 28 | "extends": "@carv/eslint-config", 29 | "root": true 30 | }, 31 | "jest": { 32 | "preset": "@carv/jest-preset" 33 | }, 34 | "devDependencies": { 35 | "@beamwind/types": "^2.2.0", 36 | "nps": "^5.9.12" 37 | }, 38 | "publishConfig": { 39 | "access": "public" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /packages/preset-tailwind/src/index.ts: -------------------------------------------------------------------------------- 1 | import type { ConfigurationOptions } from '@beamwind/types' 2 | 3 | import { theme } from './theme' 4 | 5 | export default (): ConfigurationOptions => ({ theme }) 6 | -------------------------------------------------------------------------------- /packages/preset-tailwind/src/theme.test.ts: -------------------------------------------------------------------------------- 1 | import { theme } from './theme' 2 | 3 | test('theme values', () => { 4 | expect(theme.extend?.spacing).toStrictEqual({ 5 | 0.5: '0.125rem', 6 | 1: '0.25rem', 7 | 1.5: '0.375rem', 8 | 2: '0.5rem', 9 | 2.5: '0.625rem', 10 | 3: '0.75rem', 11 | 3.5: '0.875rem', 12 | 4: '1rem', 13 | 5: '1.25rem', 14 | 6: '1.5rem', 15 | 7: '1.75rem', 16 | 8: '2rem', 17 | 9: '2.25rem', 18 | 10: '2.5rem', 19 | 11: '2.75rem', 20 | 12: '3rem', 21 | 14: '3.5rem', 22 | 16: '4rem', 23 | 20: '5rem', 24 | 24: '6rem', 25 | 28: '7rem', 26 | 32: '8rem', 27 | 36: '9rem', 28 | 40: '10rem', 29 | 44: '11rem', 30 | 48: '12rem', 31 | 52: '13rem', 32 | 56: '14rem', 33 | 60: '15rem', 34 | 64: '16rem', 35 | 72: '18rem', 36 | 80: '20rem', 37 | 96: '24rem', 38 | }) 39 | 40 | expect(theme.extend?.height).toStrictEqual({ 41 | '1/2': '50%', 42 | '1/3': '33.333333%', 43 | '2/3': '66.666667%', 44 | '1/4': '25%', 45 | '2/4': '50%', 46 | '3/4': '75%', 47 | '1/5': '20%', 48 | '2/5': '40%', 49 | '3/5': '60%', 50 | '4/5': '80%', 51 | '1/6': '16.666667%', 52 | '2/6': '33.333333%', 53 | '3/6': '50%', 54 | '4/6': '66.666667%', 55 | '5/6': '83.333333%', 56 | }) 57 | 58 | expect(theme.extend?.borderWidth).toStrictEqual({ 59 | DEFAULT: '1px', 60 | 0: '0px', 61 | 1: '1px', 62 | 2: '2px', 63 | 4: '4px', 64 | 8: '8px', 65 | }) 66 | 67 | expect(theme.extend?.ringOffsetWidth).toStrictEqual({ 68 | 0: '0px', 69 | 1: '1px', 70 | 2: '2px', 71 | 4: '4px', 72 | 8: '8px', 73 | }) 74 | 75 | expect(theme.extend?.rotate).toStrictEqual({ 76 | 0: '0deg', 77 | 1: '1deg', 78 | 2: '2deg', 79 | 3: '3deg', 80 | 6: '6deg', 81 | 12: '12deg', 82 | 45: '45deg', 83 | 90: '90deg', 84 | 180: '180deg', 85 | }) 86 | 87 | expect(theme.extend?.skew).toStrictEqual({ 88 | 0: '0deg', 89 | 1: '1deg', 90 | 2: '2deg', 91 | 3: '3deg', 92 | 6: '6deg', 93 | 12: '12deg', 94 | }) 95 | 96 | expect(theme.extend?.lineHeight).toStrictEqual({ 97 | 3: '0.75rem', 98 | 4: '1rem', 99 | 5: '1.25rem', 100 | 6: '1.5rem', 101 | 7: '1.75rem', 102 | 8: '2rem', 103 | 9: '2.25rem', 104 | 10: '2.5rem', 105 | }) 106 | 107 | expect(theme.extend?.opacity).toStrictEqual({ 108 | 5: '0.05', 109 | 10: '0.1', 110 | 20: '0.2', 111 | 30: '0.3', 112 | 40: '0.4', 113 | 50: '0.5', 114 | 60: '0.6', 115 | 70: '0.7', 116 | 80: '0.8', 117 | 90: '0.9', 118 | 95: '0.95', 119 | }) 120 | 121 | expect(theme.extend?.order).toStrictEqual({ 122 | 1: '1', 123 | 2: '2', 124 | 3: '3', 125 | 4: '4', 126 | 5: '5', 127 | 6: '6', 128 | 7: '7', 129 | 8: '8', 130 | 9: '9', 131 | 10: '10', 132 | 11: '11', 133 | 12: '12', 134 | }) 135 | 136 | expect(theme.extend?.strokeWidth).toStrictEqual({ 137 | 0: '0', 138 | 1: '1', 139 | 2: '2', 140 | }) 141 | 142 | expect(theme.extend?.zIndex).toStrictEqual({ 143 | 0: '0', 144 | 10: '10', 145 | 20: '20', 146 | 30: '30', 147 | 40: '40', 148 | 50: '50', 149 | }) 150 | 151 | expect(theme.extend?.scale).toStrictEqual({ 152 | 0: '0', 153 | 50: '.5', 154 | 75: '.75', 155 | 90: '0.9', 156 | 95: '0.95', 157 | 100: '1', 158 | 105: '1.05', 159 | 110: '1.1', 160 | 125: '1.25', 161 | 150: '1.5', 162 | }) 163 | 164 | expect(theme.extend?.durations).toStrictEqual({ 165 | 75: '75ms', 166 | 100: '100ms', 167 | 150: '150ms', 168 | 200: '200ms', 169 | 300: '300ms', 170 | 500: '500ms', 171 | 700: '700ms', 172 | 1000: '1000ms', 173 | }) 174 | }) 175 | -------------------------------------------------------------------------------- /packages/preset-tailwind/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/tsconfig", 3 | "extends": "../../tsconfig.json", 4 | "include": ["src", "../../types"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/reset/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | ## [2.0.2](https://github.com/kenoxa/beamwind/compare/@beamwind/reset@2.0.1...@beamwind/reset@2.0.2) (2020-12-05) 7 | 8 | **Note:** Version bump only for package @beamwind/reset 9 | 10 | ## [2.0.1](https://github.com/kenoxa/beamwind/compare/@beamwind/reset@2.0.0...@beamwind/reset@2.0.1) (2020-12-04) 11 | 12 | **Note:** Version bump only for package @beamwind/reset 13 | 14 | # [2.0.0](https://github.com/kenoxa/beamwind/compare/@beamwind/reset@1.2.1...@beamwind/reset@2.0.0) (2020-11-30) 15 | 16 | **Note:** Version bump only for package @beamwind/reset 17 | 18 | ## [1.2.1](https://github.com/kenoxa/beamwind/compare/@beamwind/reset@1.2.0...@beamwind/reset@1.2.1) (2020-11-27) 19 | 20 | **Note:** Version bump only for package @beamwind/reset 21 | 22 | # [1.2.0](https://github.com/kenoxa/beamwind/compare/@beamwind/reset@1.1.1...@beamwind/reset@1.2.0) (2020-11-27) 23 | 24 | ### Features 25 | 26 | - support bg, text, divide, border and placeholder opacity ([18d7fe9](https://github.com/kenoxa/beamwind/commit/18d7fe9c0c3bb319bee75f11a1f96954ff9e0eb9)) 27 | 28 | ## [1.1.1](https://github.com/kenoxa/beamwind/compare/@beamwind/reset@1.1.0...@beamwind/reset@1.1.1) (2020-11-26) 29 | 30 | ### Bug Fixes 31 | 32 | - use 'bw' instead of cx in preparation for intellisense ([9fdb322](https://github.com/kenoxa/beamwind/commit/9fdb3226262609d5d732c1fa2f72d0796c6a8250)) 33 | 34 | # [1.1.0](https://github.com/kenoxa/beamwind/compare/@beamwind/reset@1.0.4...@beamwind/reset@1.1.0) (2020-11-26) 35 | 36 | ### Features 37 | 38 | - inline plugins ([5ac827a](https://github.com/kenoxa/beamwind/commit/5ac827a30007854b47f03739676d1827144ce9c3)) 39 | 40 | ## [1.0.4](https://github.com/kenoxa/beamwind/compare/@beamwind/reset@1.0.3...@beamwind/reset@1.0.4) (2020-11-26) 41 | 42 | **Note:** Version bump only for package @beamwind/reset 43 | 44 | ## [1.0.3](https://github.com/kenoxa/beamwind/compare/@beamwind/reset@1.0.2...@beamwind/reset@1.0.3) (2020-11-26) 45 | 46 | **Note:** Version bump only for package @beamwind/reset 47 | 48 | ## [1.0.2](https://github.com/kenoxa/beamwind/compare/@beamwind/reset@1.0.1...@beamwind/reset@1.0.2) (2020-11-25) 49 | 50 | **Note:** Version bump only for package @beamwind/reset 51 | 52 | ## 1.0.1 (2020-11-25) 53 | 54 | **Note:** Version bump only for package @beamwind/reset 55 | -------------------------------------------------------------------------------- /packages/reset/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 [these people](https://github.com/kenoxa/beamwind/graphs/contributors) 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/reset/README.md: -------------------------------------------------------------------------------- 1 | # @beamwind/reset 2 | 3 | > an opinionated set of base styles for legacy browsers like IE10/11 based on [Tailwind Preflight v1](https://v1.tailwindcss.com/docs/preflight) 4 | 5 | [![MIT License](https://flat.badgen.net/github/license/kenoxa/beamwind)](https://github.com/kenoxa/beamwind/blob/main/LICENSE) 6 | [![Latest Release](https://flat.badgen.net/npm/v/@beamwind/reset?icon=npm&label)](https://www.npmjs.com/package/@beamwind/reset) 7 | [![Github](https://flat.badgen.net/badge/icon/kenoxa%2Fbeamwind?icon=github&label)](https://github.com/kenoxa/beamwind/blob/main/packages/reset) 8 | [![Typescript](https://flat.badgen.net/badge/icon/included?icon=typescript&label)](https://unpkg.com/browse/@beamwind/reset/types/reset.d.ts) 9 | [![Bundle Size](https://flat.badgen.net/bundlephobia/minzip/@beamwind/reset?icon=packagephobia&label&color=blue)](https://bundlephobia.com/result?p=@beamwind/reset) 10 | 11 | > [Read the docs](https://beamwind.js.org) | 12 | > [API](https://beamwind.js.org/packages/reset) | 13 | > [Change Log](https://github.com/kenoxa/beamwind/blob/main/packages/reset/CHANGELOG.md) 14 | 15 | --- 16 | 17 | Built on top of [normalize.css](https://github.com/necolas/normalize.css/), @beamwind/reset is a set of base styles that are designed to smooth over cross-browser inconsistencies and make it easier for you to work within the constraints of your design system. 18 | 19 | If you do **not** need to support IE 10/11, we recommend using [@beamwind/preflight](https://github.com/kenoxa/beamwind/blob/main/packages/preflight). 20 | 21 | 22 | 23 | 24 | 25 | 26 | - [Installation](#installation) 27 | - [Usage](#usage) 28 | - [Contribute](#contribute) 29 | - [License](#license) 30 | 31 | 32 | 33 | 34 | ## Installation 35 | 36 | ```sh 37 | npm install @beamwind/reset 38 | ``` 39 | 40 | ## Usage 41 | 42 | > Please refer to the [main documentation](https://beamwind.js.org#usage) for further information. 43 | 44 | ```js 45 | import { setup } from '@beamwind/core' 46 | import reset from '@beamwind/reset' 47 | 48 | setup(reset()) 49 | ``` 50 | 51 | ## Contribute 52 | 53 | Thanks for being willing to contribute! 54 | 55 | > This project is free and open-source, so if you think this project can help you or anyone else, you may [star it on GitHub](https://github.com/kenoxa/beamwind). Feel free to [open an issue](https://github.com/kenoxa/beamwind/issues) if you have any idea, question, or you've found a bug. 56 | 57 | **Working on your first Pull Request?** You can learn how from this _free_ series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) 58 | 59 | We are following the [Conventional Commits](https://www.conventionalcommits.org) convention. 60 | 61 | ### Sponsors 62 | 63 | [![Kenoxa GmbH](https://images.opencollective.com/kenoxa/9c25796/logo/68.png)](https://www.kenoxa.com) [Kenoxa GmbH](https://www.kenoxa.com) 64 | 65 | ## License 66 | 67 | [MIT](https://github.com/kenoxa/beamwind/blob/main/LICENSE) © [Kenoxa GmbH](https://kenoxa.com) 68 | -------------------------------------------------------------------------------- /packages/reset/package-scripts.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../package-scripts') 2 | -------------------------------------------------------------------------------- /packages/reset/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@beamwind/reset", 3 | "version": "2.0.2", 4 | "description": "An opinionated set of base styles for legacy browsers like IE10/11", 5 | "keywords": [ 6 | "beamwind", 7 | "tailwind" 8 | ], 9 | "homepage": "https://github.com/kenoxa/beamwind#readme", 10 | "bugs": { 11 | "url": "https://github.com/kenoxa/beamwind/issues" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/kenoxa/beamwind.git", 16 | "directory": "packages/reset" 17 | }, 18 | "license": "MIT", 19 | "author": "Kenoxa GmbH ", 20 | "main": "src/index.ts", 21 | "scripts": { 22 | "build": "nps", 23 | "prepublishOnly": "nps", 24 | "test": "nps" 25 | }, 26 | "prettier": "@carv/prettier-config", 27 | "eslintConfig": { 28 | "extends": "@carv/eslint-config", 29 | "root": true 30 | }, 31 | "jest": { 32 | "preset": "@carv/jest-preset" 33 | }, 34 | "devDependencies": { 35 | "nps": "^5.9.12" 36 | }, 37 | "publishConfig": { 38 | "access": "public" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/reset/src/index.ts: -------------------------------------------------------------------------------- 1 | import type { ConfigurationOptions } from '@beamwind/types' 2 | 3 | import { reset } from './reset' 4 | 5 | export default (): ConfigurationOptions => ({ 6 | init(insert, theme): void { 7 | reset(theme).forEach(insert) 8 | }, 9 | }) 10 | -------------------------------------------------------------------------------- /packages/reset/src/reset.test.ts: -------------------------------------------------------------------------------- 1 | import type { Instance, Injector } from '@beamwind/types' 2 | 3 | import { createInstance, virtualInjector } from '@beamwind/core' 4 | 5 | import reset from '..' 6 | 7 | let injector: Injector 8 | let instance: Instance 9 | 10 | beforeEach(() => { 11 | injector = virtualInjector() 12 | instance = createInstance({ injector, hash: false }) 13 | }) 14 | 15 | test('add reset styles', () => { 16 | instance.setup(reset()) 17 | 18 | expect(instance.bw('text-left')).toBe('text-left') 19 | 20 | expect(injector.target).toMatchObject([ 21 | ':root{-moz-tab-size:4;tab-size:4}', 22 | 'blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}', 23 | 'button{background-color:transparent;background-image:none}', 24 | "button,[type='button'],[type='reset'],[type='submit']{-webkit-appearance:button}", 25 | 'button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}', 26 | 'fieldset{margin:0;padding:0}', 27 | 'ol,ul{list-style:none;margin:0;padding:0}', 28 | 'html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif,system-ui,sans-serif}', 29 | 'body{margin:0;font-family:inherit;line-height:inherit}', 30 | '*,::before,::after{box-sizing:border-box;border:0 solid currentColor}', 31 | 'hr{height:0;overflow:visible;color:inherit;border-top-width:1px}', 32 | 'img{border-style:solid}', 33 | 'textarea{overflow:auto;resize:vertical}', 34 | 'input::placeholder,textarea::placeholder{color:#a1a1aa}', 35 | 'button,[role="button"]{cursor:pointer}', 36 | 'table{text-indent:0;border-color:inherit;border-collapse:collapse}', 37 | 'h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}', 38 | 'a{color:inherit;text-decoration:inherit}', 39 | 'button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;margin:0;padding:0;line-height:inherit;color:inherit}', 40 | 'button,select{text-transform:none}', 41 | '::-moz-focus-inner{border-style:none;padding:0}', 42 | ':-moz-focusring{outline:1px dotted ButtonText}', 43 | ':-moz-ui-invalid{box-shadow:none}', 44 | 'legend{color:inherit;display:table;max-width:100%;padding:0;white-space:normal;}', 45 | 'progress{vertical-align:baseline}', 46 | '::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}', 47 | '[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}', 48 | '::-webkit-search-decoration{-webkit-appearance:none}', 49 | '::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}', 50 | 'summary{display:list-item}', 51 | 'abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}', 52 | 'b,strong{font-weight:bolder}', 53 | 'pre,code,kbd,samp{font-family:ui-monospace,monospace;font-size:1em}', 54 | 'sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}', 55 | 'sub{bottom:-0.25em}', 56 | 'sup{top:-0.5em}', 57 | 'img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}', 58 | 'img,video{max-width:100%;height:auto}', 59 | 'main{display: block}', 60 | 'a{background-color:transparent}', 61 | 'img{border-style:none}', 62 | 'button,input{overflow:visible}', 63 | '[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}', 64 | 'details{display:block}', 65 | 'summary{display:list-item}', 66 | 'template{display:none}', 67 | '[hidden]{display:none}', 68 | '.text-left{text-align:left}', 69 | ]) 70 | }) 71 | 72 | test('add reset styles with custom theme', () => { 73 | instance.setup([ 74 | reset(), 75 | { 76 | theme: { 77 | extend: { 78 | fontFamily: { sans: 'ui-sans-serif', mono: 'ui-monospace' }, 79 | borderColor: { DEFAULT: '#222' }, 80 | placeholderColor: { DEFAULT: '#333' }, 81 | }, 82 | }, 83 | }, 84 | ]) 85 | 86 | expect(instance.bw('text-left')).toBe('text-left') 87 | 88 | expect(injector.target).toContain( 89 | 'html{line-height:1.5;-webkit-text-size-adjust:100%;font-family:ui-sans-serif}', 90 | ) 91 | expect(injector.target).toContain('*,::before,::after{box-sizing:border-box;border:0 solid #222}') 92 | expect(injector.target).toContain('input::placeholder,textarea::placeholder{color:#333}') 93 | expect(injector.target).toContain('pre,code,kbd,samp{font-family:ui-monospace;font-size:1em}') 94 | }) 95 | 96 | test('add reset styles with theme missing some values', () => { 97 | instance.setup([ 98 | reset(), 99 | { 100 | theme: { 101 | fontFamily: { sans: 'ui-sans-serif', mono: 'ui-monospace' }, 102 | borderColor: {}, 103 | placeholderColor: {}, 104 | }, 105 | }, 106 | ]) 107 | 108 | expect(instance.bw('text-left')).toBe('text-left') 109 | 110 | expect(injector.target).toContain( 111 | '*,::before,::after{box-sizing:border-box;border:0 solid currentColor}', 112 | ) 113 | expect(injector.target).toContain('input::placeholder,textarea::placeholder{color:#a1a1aa}') 114 | }) 115 | -------------------------------------------------------------------------------- /packages/reset/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/tsconfig", 3 | "extends": "../../tsconfig.json", 4 | "include": ["src", "../../types"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/system/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | ## [2.1.1](https://github.com/kenoxa/beamwind/compare/@beamwind/system@2.1.0...@beamwind/system@2.1.1) (2020-12-05) 7 | 8 | **Note:** Version bump only for package @beamwind/system 9 | 10 | # [2.1.0](https://github.com/kenoxa/beamwind/compare/@beamwind/system@2.0.4...@beamwind/system@2.1.0) (2020-12-04) 11 | 12 | ### Features 13 | 14 | - transform-gpu ([a28342f](https://github.com/kenoxa/beamwind/commit/a28342fbd7ae8a2a2d035306e35abbd40c54bdff)) 15 | 16 | ## [2.0.4](https://github.com/kenoxa/beamwind/compare/@beamwind/system@2.0.3...@beamwind/system@2.0.4) (2020-12-02) 17 | 18 | **Note:** Version bump only for package @beamwind/system 19 | 20 | ## [2.0.3](https://github.com/kenoxa/beamwind/compare/@beamwind/system@2.0.2...@beamwind/system@2.0.3) (2020-12-01) 21 | 22 | ### Bug Fixes 23 | 24 | - color variant creation ([9984a11](https://github.com/kenoxa/beamwind/commit/9984a110f825a1940e5ef2644697ea8ee8ec385a)) 25 | 26 | ## [2.0.2](https://github.com/kenoxa/beamwind/compare/@beamwind/system@2.0.1...@beamwind/system@2.0.2) (2020-12-01) 27 | 28 | **Note:** Version bump only for package @beamwind/system 29 | 30 | ## [2.0.1](https://github.com/kenoxa/beamwind/compare/@beamwind/system@2.0.0...@beamwind/system@2.0.1) (2020-12-01) 31 | 32 | **Note:** Version bump only for package @beamwind/system 33 | 34 | # 2.0.0 (2020-11-30) 35 | 36 | **Note:** Version bump only for package @beamwind/system 37 | -------------------------------------------------------------------------------- /packages/system/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 [these people](https://github.com/kenoxa/beamwind/graphs/contributors) 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/system/README.md: -------------------------------------------------------------------------------- 1 | # @beamwind/system 2 | 3 | > ready to go beamwind for using [@beamwind/preset-system](https://github.com/kenoxa/beamwind/blob/main/packages/preset-system) 4 | 5 | [![MIT License](https://flat.badgen.net/github/license/kenoxa/beamwind)](https://github.com/kenoxa/beamwind/blob/main/LICENSE) 6 | [![Latest Release](https://flat.badgen.net/npm/v/@beamwind/system?icon=npm&label)](https://www.npmjs.com/package/@beamwind/system) 7 | [![Github](https://flat.badgen.net/badge/icon/kenoxa%2Fbeamwind?icon=github&label)](https://github.com/kenoxa/beamwind/blob/main/packages/system) 8 | [![Typescript](https://flat.badgen.net/badge/icon/included?icon=typescript&label)](https://unpkg.com/browse/@beamwind/system/types/system.d.ts) 9 | [![Bundle Size](https://flat.badgen.net/bundlephobia/minzip/@beamwind/system?icon=packagephobia&label&color=blue)](https://bundlephobia.com/result?p=@beamwind/system) 10 | 11 | > [Read the docs](https://beamwind.js.org) | 12 | > [API](https://beamwind.js.org/packages/system) | 13 | > [Change Log](https://github.com/kenoxa/beamwind/blob/main/packages/system/CHANGELOG.md) > [⚡️ Demo](https://esm.codes/#Ly8gQmVhbXdpbmQgZGVtbyAoYmFzZWQgb24gY29kZSBieSBAbHVrZWphY2tzb25uIC0gY3JlYXRvciBvZiBvY2VhbndpbmQpCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAgICAKaW1wb3J0IHsgcmVuZGVyLCBodG1sIH0gZnJvbSAnaHR0cHM6Ly9ucG0ucmV2ZXJzZWh0dHAuY29tL3ByZWFjdCxwcmVhY3QvaG9va3MsaHRtL3ByZWFjdCc7CmltcG9ydCB7IGJ3IH0gZnJvbSAnaHR0cHM6Ly91bnBrZy5jb20vQGJlYW13aW5kL3BsYXk/bW9kdWxlJwoKY29uc3Qgc3R5bGUgPSB7CiAgLy8gRXhhbXBsZSBvZiBhYnN0cmFjdGVkIHN0eWxlCiAgY29udGFpbmVyOiBid2BoLWZ1bGwgYmctcHJvbW90ZSBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlcmAKfQoKcmVuZGVyKAogIGh0bWxgCiAgICA8ZGl2IGNsYXNzPSR7c3R5bGUuY29udGFpbmVyfT4KICAgICAgPGgxIGNsYXNzPSR7CiAgICAgICAgLy8gRXhhbXBsZSBvZiBhbiBpbmxpbmUgc3R5bGUKICAgICAgICBid2AKICAgICAgICAgIHRleHQoNHhsIHVuZGVybGluZSkKICAgICAgICAgIGZvbnQoYm9sZCBzYW5zKQogICAgICAgICAgdHJhbnNpdGlvbgogICAgICAgICAgaG92ZXI6KHRyYW5zZm9ybSByb3RhdGUtbWQgc2NhbGUtMnhsIGN1cnNvci1wb2ludGVyKQogICAgICAgICAgYWN0aXZlOih0cmFuc2Zvcm0gLXJvdGF0ZS14bCBzY2FsZS0zeGwpCiAgICAgICAgYAogICAgICB9PkhlbGxvIFdvcmxkPC9oMT4KICAgIDwvZGl2PgogIGAsCiAgZG9jdW1lbnQuYm9keQopOw==) 14 | 15 | --- 16 | 17 | @beamwind/system tries to follow a semantic naming approach by using a common _language_ to reduce the guess work. A small set of well known design tokens hopefully prevents magic values or ambiguous names. This creates a taxonomy of tokenized variables used by system adopters and library’s components. The more predictably the model is catalogued, the easier it is to apply, maintain, and endure. 18 | 19 | > Please see [@beamwind/preset-system](https://github.com/kenoxa/beamwind/blob/main/packages/preset-system) for further information. 20 | 21 | 22 | 23 | 24 | 25 | 26 | - [Installation](#installation) 27 | - [Usage](#usage) 28 | - [Contribute](#contribute) 29 | - [License](#license) 30 | 31 | 32 | 33 | 34 | ## Installation 35 | 36 | ```sh 37 | npm install @beamwind/system 38 | ``` 39 | 40 | ## Usage 41 | 42 | > Please refer to the [main documentation](https://beamwind.js.org#usage) and [@beamwind/preset-system](https://github.com/kenoxa/beamwind/blob/main/packages/preset-system) for further information. 43 | 44 | ```js 45 | import { bw } from '@beamwind/system' 46 | 47 | bw`text-critical` 48 | ``` 49 | 50 | For further customization `setup` is exported: 51 | 52 | ```js 53 | import { bw, setup } from '@beamwind/system' 54 | 55 | setup({ 56 | colors: { 57 | important: '#DC2626', 58 | }, 59 | }) 60 | 61 | bw`text-important` // will result in a #DC2626 as text color 62 | ``` 63 | 64 | ## Contribute 65 | 66 | Thanks for being willing to contribute! 67 | 68 | > This project is free and open-source, so if you think this project can help you or anyone else, you may [star it on GitHub](https://github.com/kenoxa/beamwind). Feel free to [open an issue](https://github.com/kenoxa/beamwind/issues) if you have any idea, question, or you've found a bug. 69 | 70 | **Working on your first Pull Request?** You can learn how from this _free_ series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) 71 | 72 | We are following the [Conventional Commits](https://www.conventionalcommits.org) convention. 73 | 74 | ### Sponsors 75 | 76 | [![Kenoxa GmbH](https://images.opencollective.com/kenoxa/9c25796/logo/68.png)](https://www.kenoxa.com) [Kenoxa GmbH](https://www.kenoxa.com) 77 | 78 | ## License 79 | 80 | [MIT](https://github.com/kenoxa/beamwind/blob/main/LICENSE) © [Kenoxa GmbH](https://kenoxa.com) 81 | -------------------------------------------------------------------------------- /packages/system/package-scripts.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../package-scripts') 2 | -------------------------------------------------------------------------------- /packages/system/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@beamwind/system", 3 | "version": "2.1.1", 4 | "description": "ready to go beamwind fusing a semantic design system", 5 | "keywords": [ 6 | "beamwind", 7 | "tailwind" 8 | ], 9 | "homepage": "https://github.com/kenoxa/beamwind#readme", 10 | "bugs": { 11 | "url": "https://github.com/kenoxa/beamwind/issues" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/kenoxa/beamwind.git", 16 | "directory": "packages/system" 17 | }, 18 | "license": "MIT", 19 | "author": "Kenoxa GmbH ", 20 | "main": "src/index.ts", 21 | "scripts": { 22 | "build": "nps", 23 | "postbuild": "size-limit", 24 | "prepublishOnly": "nps", 25 | "size": "size-limit", 26 | "test": "nps" 27 | }, 28 | "prettier": "@carv/prettier-config", 29 | "eslintConfig": { 30 | "extends": "@carv/eslint-config", 31 | "root": true 32 | }, 33 | "jest": { 34 | "preset": "@carv/jest-preset" 35 | }, 36 | "dependencies": { 37 | "@beamwind/core": "^2.3.0", 38 | "@beamwind/preflight": "^2.0.2", 39 | "@beamwind/preset-system": "^2.3.0" 40 | }, 41 | "devDependencies": { 42 | "@size-limit/preset-small-lib": "^4.6.0", 43 | "nps": "^5.9.12", 44 | "size-limit": "^4.6.0" 45 | }, 46 | "publishConfig": { 47 | "access": "public" 48 | }, 49 | "size-limit": [ 50 | { 51 | "path": "./dist/script/system.js", 52 | "limit": "11.5 KB" 53 | } 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /packages/system/src/index.test.ts: -------------------------------------------------------------------------------- 1 | import { bw, setup, strict } from '.' 2 | 3 | setup({ mode: strict }) 4 | 5 | test('smoke', () => { 6 | expect( 7 | bw`absolute inset-0 bg-gradient-to-r from-promote to-on-promote shadow-lg transform -skew-y-md sm:skew-y-none sm:-rotate-lg sm:rounded-3xl`, 8 | ).toBe( 9 | '_1mkfpkn _o006n8 _1gt8na1 _bgnw62 _1afdwys _lae5pa _gqktp6 _i5h0pq _1w053pr _1vzslrt _9pmjrn', 10 | ) 11 | }) 12 | 13 | test('readme example', () => { 14 | expect(bw`h-full bg-promote flex items-center justify-center`).toBe( 15 | '_ma35kl _1qb3hgf _1l0yvu6 _1ylnts1 _qemgvh', 16 | ) 17 | 18 | expect( 19 | bw` 20 | text(4xl underline) 21 | font(bold sans) 22 | transition 23 | hover:(transform rotate-md scale-2xl cursor-pointer) 24 | active:(transform -rotate-xl scale-3xl) 25 | `, 26 | ).toBe( 27 | '_9zien4 _1rn96fu _1u8tsvs _vx8z01 _iniysy _1crosn3 _1ry7tt8 _z6b2rb _vdrcah _vzti3v _rqq84r _1mwh623', 28 | ) 29 | }) 30 | -------------------------------------------------------------------------------- /packages/system/src/index.ts: -------------------------------------------------------------------------------- 1 | import system from '@beamwind/preset-system' 2 | import preflight from '@beamwind/preflight' 3 | import { createInstance } from '@beamwind/core' 4 | 5 | const instance = createInstance([preflight(), system()]) 6 | 7 | export const { bw } = instance 8 | export const { setup } = instance 9 | export const { theme } = instance 10 | 11 | // Re-export common configuration utilities 12 | export { 13 | strict, 14 | warn, 15 | noprefix, 16 | cyrb32, 17 | cssomInjector, 18 | noOpInjector, 19 | virtualInjector, 20 | } from '@beamwind/core' 21 | -------------------------------------------------------------------------------- /packages/system/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/tsconfig", 3 | "extends": "../../tsconfig.json", 4 | "include": ["src", "../../types"] 5 | } 6 | -------------------------------------------------------------------------------- /packages/types/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to this project will be documented in this file. 4 | See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. 5 | 6 | # [2.2.0](https://github.com/kenoxa/beamwind/compare/@beamwind/types@2.1.0...@beamwind/types@2.2.0) (2020-12-05) 7 | 8 | ### Features 9 | 10 | - ring defaults ([e50bfdf](https://github.com/kenoxa/beamwind/commit/e50bfdf1edf3dfb2421b4d9ab3a73d09eb1da475)) 11 | 12 | # [2.1.0](https://github.com/kenoxa/beamwind/compare/@beamwind/types@2.0.0...@beamwind/types@2.1.0) (2020-12-04) 13 | 14 | ### Features 15 | 16 | - dark mode ([11eb4aa](https://github.com/kenoxa/beamwind/commit/11eb4aafefb815d5afcd8238935bc48d4094df14)) 17 | 18 | # 2.0.0 (2020-11-30) 19 | 20 | **Note:** Version bump only for package @beamwind/types 21 | -------------------------------------------------------------------------------- /packages/types/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 [these people](https://github.com/kenoxa/beamwind/graphs/contributors) 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/README.md: -------------------------------------------------------------------------------- 1 | # @beamwind/types 2 | 3 | > common typescript types used in beamwind projects 4 | 5 | [![MIT License](https://flat.badgen.net/github/license/kenoxa/beamwind)](https://github.com/kenoxa/beamwind/blob/main/LICENSE) 6 | [![Latest Release](https://flat.badgen.net/npm/v/@beamwind/types?icon=npm&label)](https://www.npmjs.com/package/@beamwind/types) 7 | [![Github](https://flat.badgen.net/badge/icon/kenoxa%2Fbeamwind?icon=github&label)](https://github.com/kenoxa/beamwind/blob/main/packages/types) 8 | [![Typescript](https://flat.badgen.net/badge/icon/included?icon=typescript&label)](https://unpkg.com/browse/@beamwind/types/types/types.d.ts) 9 | [![Bundle Size](https://flat.badgen.net/bundlephobia/minzip/@beamwind/types?icon=packagephobia&label&color=blue)](https://bundlephobia.com/result?p=@beamwind/types) 10 | 11 | > [Read the docs](https://beamwind.js.org) | 12 | > [API](https://beamwind.js.org/packages/types) | 13 | > [Change Log](https://github.com/kenoxa/beamwind/blob/main/packages/types/CHANGELOG.md) 14 | 15 | --- 16 | 17 | 18 | 19 | 20 | 21 | 22 | - [Installation](#installation) 23 | - [Usage](#usage) 24 | - [Contribute](#contribute) 25 | - [License](#license) 26 | 27 | 28 | 29 | 30 | ## Installation 31 | 32 | ```sh 33 | npm install @beamwind/types 34 | ``` 35 | 36 | ## Usage 37 | 38 | > Please refer to the [main documentation](https://beamwind.js.org#usage) for further information. 39 | 40 | ```js 41 | import type { Theme } from '@beamwind/types' 42 | ``` 43 | 44 | ## Contribute 45 | 46 | Thanks for being willing to contribute! 47 | 48 | > This project is free and open-source, so if you think this project can help you or anyone else, you may [star it on GitHub](https://github.com/kenoxa/beamwind). Feel free to [open an issue](https://github.com/kenoxa/beamwind/issues) if you have any idea, question, or you've found a bug. 49 | 50 | **Working on your first Pull Request?** You can learn how from this _free_ series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/series/how-to-contribute-to-an-open-source-project-on-github) 51 | 52 | We are following the [Conventional Commits](https://www.conventionalcommits.org) convention. 53 | 54 | ### Sponsors 55 | 56 | [![Kenoxa GmbH](https://images.opencollective.com/kenoxa/9c25796/logo/68.png)](https://www.kenoxa.com) [Kenoxa GmbH](https://www.kenoxa.com) 57 | 58 | ## License 59 | 60 | [MIT](https://github.com/kenoxa/beamwind/blob/main/LICENSE) © [Kenoxa GmbH](https://kenoxa.com) 61 | -------------------------------------------------------------------------------- /packages/types/package-scripts.js: -------------------------------------------------------------------------------- 1 | module.exports = require('../../package-scripts') 2 | -------------------------------------------------------------------------------- /packages/types/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@beamwind/types", 3 | "version": "2.2.0", 4 | "description": "Common typescript types", 5 | "keywords": [ 6 | "beamwind", 7 | "tailwind" 8 | ], 9 | "homepage": "https://github.com/kenoxa/beamwind#readme", 10 | "bugs": { 11 | "url": "https://github.com/kenoxa/beamwind/issues" 12 | }, 13 | "repository": { 14 | "type": "git", 15 | "url": "git+https://github.com/kenoxa/beamwind.git", 16 | "directory": "packages/types" 17 | }, 18 | "license": "MIT", 19 | "author": "Kenoxa GmbH ", 20 | "main": "src/index.ts", 21 | "scripts": { 22 | "build": "nps", 23 | "prepublishOnly": "nps", 24 | "test": "nps" 25 | }, 26 | "prettier": "@carv/prettier-config", 27 | "eslintConfig": { 28 | "extends": "@carv/eslint-config", 29 | "root": true 30 | }, 31 | "jest": { 32 | "preset": "@carv/jest-preset" 33 | }, 34 | "devDependencies": { 35 | "nps": "^5.9.12" 36 | }, 37 | "publishConfig": { 38 | "access": "public" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/types/src/common.ts: -------------------------------------------------------------------------------- 1 | // Declaration => property: value 2 | // rule => selector { declaration } 3 | 4 | import type { Falsy } from './util' 5 | 6 | export type Declarations = Record 7 | -------------------------------------------------------------------------------- /packages/types/src/config.ts: -------------------------------------------------------------------------------- 1 | import type { ThemeConfiguration, ThemeResolver } from './theme' 2 | import type { Plugin } from './core' 3 | import type { Mode } from './mode' 4 | 5 | export interface InjectorConfig { 6 | /** 7 | * Sets a cryptographic nonce (number used once) on the enclosing `