├── .github └── ISSUE_TEMPLATE │ ├── config.yml │ ├── 🐞-bug-report.md │ └── 🚀-new-feature-proposal.md ├── .gitignore ├── CONTRIBUTING.MD ├── LICENSE ├── README.md ├── color-code.md ├── example ├── .gitignore ├── components │ ├── accordion │ │ ├── index.html │ │ └── js │ │ │ └── script.js │ ├── alert-dialog │ │ ├── alert.html │ │ ├── index.html │ │ └── js │ │ │ └── script.js │ ├── alert │ │ └── index.html │ ├── annonce_pill │ │ └── index.html │ ├── aspect-ratio │ │ └── index.html │ ├── avatar │ │ └── index.html │ ├── badge │ │ └── index.html │ ├── breadcrumbs │ │ └── index.html │ ├── button │ │ └── index.html │ ├── card │ │ └── index.html │ ├── checkbox │ │ └── index.html │ ├── chip │ │ └── index.html │ ├── container │ │ └── index.html │ ├── divider │ │ └── index.html │ ├── dropdown │ │ ├── index.html │ │ └── js │ │ │ └── script.js │ ├── form │ │ └── index.html │ ├── icon │ │ └── index.html │ ├── input │ │ └── index.html │ ├── kbd │ │ └── index.html │ ├── link │ │ └── index.html │ ├── meter │ │ └── index.html │ ├── pagination │ │ └── index.html │ ├── popover │ │ ├── index.html │ │ └── js │ │ │ └── script.js │ ├── progress │ │ └── index.html │ ├── radio │ │ └── index.html │ ├── range │ │ ├── index.html │ │ └── js │ │ │ └── script.js │ ├── select │ │ └── index.html │ ├── skeleton │ │ └── index.html │ ├── slideover │ │ ├── index.html │ │ └── js │ │ │ └── script.js │ ├── switch │ │ └── index.html │ ├── table │ │ └── index.html │ ├── tabs │ │ ├── index.html │ │ └── js │ │ │ └── script.js │ ├── text-area │ │ ├── index.html │ │ └── js │ │ │ └── script.js │ └── tooltip │ │ ├── index.html │ │ └── js │ │ └── script.js ├── index.html ├── js │ ├── load.theme.js │ └── theme.js ├── package.json ├── src │ ├── app-ui.css │ ├── button.css │ ├── config-ui.css │ ├── main.ts │ ├── style.css │ ├── themes │ │ ├── air.css │ │ ├── earth.css │ │ ├── fire.css │ │ └── water.css │ ├── ui.css │ └── vite-env.d.ts ├── tsconfig.json ├── uno.config.ts └── vite.config.ts ├── favicon-dark.png ├── lerna.json ├── nx.json ├── package-lock.json ├── package.json ├── packages ├── flexilla │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── build.config.ts │ ├── favicon-dark.png │ ├── package.json │ ├── src │ │ ├── flexillaVariants.ts │ │ └── index.ts │ └── tsconfig.json ├── preset-bg │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── build.config.ts │ ├── favicon-dark.png │ ├── package.json │ ├── src │ │ ├── index.ts │ │ └── rules │ │ │ ├── const.ts │ │ │ ├── index.ts │ │ │ └── types.ts │ └── tsconfig.json ├── preset-ui │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── build.config.ts │ ├── favicon-dark.png │ ├── package.json │ ├── src │ │ ├── colors │ │ │ ├── genColor.ts │ │ │ └── getPreconfigColors.ts │ │ ├── css │ │ │ ├── default │ │ │ │ ├── base.css │ │ │ │ ├── dark.css │ │ │ │ └── light.css │ │ │ └── themes │ │ │ │ ├── air.css │ │ │ │ ├── default.css │ │ │ │ ├── earth.css │ │ │ │ ├── fire.css │ │ │ │ └── water.css │ │ ├── index.ts │ │ ├── rules │ │ │ ├── const.ts │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── utils.ts │ │ ├── shortcuts │ │ │ ├── accordion │ │ │ │ ├── const.ts │ │ │ │ └── index.ts │ │ │ ├── aspect-ratio │ │ │ │ └── index.ts │ │ │ ├── avatar │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── badge │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── button │ │ │ │ ├── baseHelpers.ts │ │ │ │ ├── const.ts │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── checkbox │ │ │ │ └── index.ts │ │ │ ├── divider │ │ │ │ └── index.ts │ │ │ ├── helpers │ │ │ │ ├── genSize.ts │ │ │ │ ├── genTextColor.ts │ │ │ │ ├── helper-const.ts │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── input │ │ │ │ ├── const.ts │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── kbd │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ ├── meter │ │ │ │ └── index.ts │ │ │ ├── progress │ │ │ │ └── index.ts │ │ │ ├── radio │ │ │ │ ├── helper.ts │ │ │ │ └── index.ts │ │ │ ├── range │ │ │ │ └── index.ts │ │ │ ├── shortcut_helper.ts │ │ │ ├── switch │ │ │ │ ├── const.ts │ │ │ │ └── index.ts │ │ │ ├── types.ts │ │ │ ├── ui │ │ │ │ ├── index.ts │ │ │ │ └── types.ts │ │ │ └── utilities │ │ │ │ └── index.ts │ │ ├── types │ │ │ ├── base.ts │ │ │ ├── index.ts │ │ │ ├── types.ts │ │ │ └── ui-t.ts │ │ ├── ui-theme │ │ │ ├── index.ts │ │ │ └── ui.ts │ │ ├── ui │ │ │ ├── buttons │ │ │ │ ├── button-default.ts │ │ │ │ ├── helpers.ts │ │ │ │ └── index.ts │ │ │ ├── index.ts │ │ │ ├── type.ts │ │ │ └── ui-variants │ │ │ │ ├── default-val.ts │ │ │ │ ├── index.ts │ │ │ │ └── ui-helpers.ts │ │ ├── utils │ │ │ ├── colors-utils.ts │ │ │ ├── index.ts │ │ │ └── size-utils.ts │ │ └── variants │ │ │ └── index.ts │ └── tsconfig.json └── unify-variant │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── build.config.ts │ ├── favicon-dark.png │ ├── package.json │ ├── src │ ├── browser-pseudo.ts │ ├── index.ts │ └── stateVariants.ts │ └── tsconfig.json └── shared └── tsconfig.json /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: Community Chat 4 | url: https://discord.gg/6VN6zTPZAy 5 | about: Ask and discuss real-time with other users on the unifyPreset channel on the UnifyUI Community's server. 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/🐞-bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F41E Bug report" 3 | about: Report an issue with Unify Preset 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | --- 13 | name: "\U0001F41E Bug report" 14 | about: Create a report to help us improve the Themer 15 | title: '' 16 | labels: '' 17 | assignees: '' 18 | 19 | --- 20 | 21 | **Describe the bug** 22 | A clear and concise description of what the bug is. 23 | 24 | **To Reproduce** 25 | Steps to reproduce the behavior: 26 | 1. Go to '...' 27 | 2. Click on '....' 28 | 3. Scroll down to '....' 29 | 4. See error 30 | 31 | **Expected behavior** 32 | A clear and concise description of what you expected to happen. 33 | 34 | **Screenshots** 35 | If applicable, add screenshots to help explain your problem. 36 | 37 | **Desktop (please complete the following information):** 38 | - OS: [e.g. iOS] 39 | - Browser [e.g. chrome, safari] 40 | - Version [e.g. 22] 41 | 42 | **Smartphone (please complete the following information):** 43 | - Device: [e.g. iPhone6] 44 | - OS: [e.g. iOS8.1] 45 | - Browser [e.g. stock browser, safari] 46 | - Version [e.g. 22] 47 | 48 | **Screenshots** 49 | If applicable, add screenshots to help explain your problem. 50 | 51 | **Desktop (please complete the following information):** 52 | - OS: [e.g. iOS] 53 | - Browser [e.g. chrome, safari] 54 | - Version [e.g. 22] 55 | 56 | **Smartphone (please complete the following information):** 57 | - Device: [e.g. iPhone6] 58 | - OS: [e.g. iOS8.1] 59 | - Browser [e.g. stock browser, safari] 60 | - Version [e.g. 22] 61 | 62 | **Additional context** 63 | Add any other context about the problem here. 64 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/🚀-new-feature-proposal.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F680 New feature(Feature, Components, Variants and improvements) proposal" 3 | about: Suggest a new feature to be addedd 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | lerna-debug.log 3 | dist 4 | .nx 5 | **/.DS_STORE -------------------------------------------------------------------------------- /CONTRIBUTING.MD: -------------------------------------------------------------------------------- 1 | # Contributing Guide 2 | Every contribution is welcome to this open source project. However, before submitting your contribution, be sure to take a moment and read the following guidelines. 3 | 4 | - [Contributing Guide](#contributing-guide) 5 | - [Don't know how to contribute or new to Open Source?](#dont-know-how-to-contribute-or-new-to-open-source) 6 | - [Have a question?](#have-a-question) 7 | - [Prerequisites](#prerequisites) 8 | - [VS Code Extensions](#vs-code-extensions) 9 | - [commit-convention](#commit-convention) 10 | - [Pull Request Guidelines](#pull-request-guidelines) 11 | - [Steps to PR](#steps-to-pr) 12 | - [Local Development](#local-development) 13 | 14 | 15 | ## Don't know how to contribute or new to Open Source? 16 | 17 | Take a look at : 18 | 1. [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/) 19 | 2. [How to Contribute to an Open Source Project on GitHub](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github) 20 | 21 | ## Have a question? 22 | 23 | 1. Check our [Github Issues]() to see if someone has already answered your question. 24 | 2. Join our community on [Discord](https://discord.gg/6VN6zTPZAy) and feel free to ask everything you want. 25 | 26 | 27 | ### Prerequisites 28 | 29 | - Code Editor 30 | - NodeJS LTS 31 | 32 | #### VS Code Extensions 33 | 34 | 1. [UnoCSS](https://marketplace.visualstudio.com/items?itemName=antfu.unocss) 35 | 36 | 37 | ## commit-convention 38 | 39 | 40 | 41 | ## Pull Request Guidelines 42 | 43 | - The `main` branch is basically a snapshot of the latest stable version. All development must be done in dedicated branches. 44 | 45 | 46 | ### Steps to PR 47 | 48 | 1. Fork of this repository and clone your fork 49 | 50 | 2. Create a new branch out of the `main` branch. 51 | 52 | 3. Make and commit your changes following the 53 | [commit convention](CONTRIBUTING.MD#commit-convention). 54 | 55 | ## Local Development 56 | 57 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Unify UI 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

UnoUI Preset

4 |

UnoCSS Toolkit.

5 |

6 | 7 | 8 | ## UnoUI (UnifyUI-Preset) 9 | 10 | UnoUI Preset is a collection of UnoCSS Presets. 11 | 12 | > **Not** : This project is a WIP, you can test it and report bug... Your contribution is much valualed for us, help us to make it better. 13 | 14 | ### Preset UI 15 | 16 | Preset UI stands at the forefront of UI customization, offering a comprehensive theming library designed to empower developers and designers alike. At its core, preset-ui leverages the power and flexibility of UnoCSS and provides a variety of themes that can be easily customized to match your brand and style. 17 | 18 | [Read more here](./packages/preset-ui/README.md) 19 | 20 | #### Install Preset UI 21 | 22 | ```bash 23 | npm i -D @unifydev/preset-ui 24 | # or 25 | yarn add @unifydev/preset-ui -D 26 | # or 27 | pnpm add @unifydev/preset-ui -D 28 | ``` 29 | 30 | ### UnifyVariant 31 | 32 | This is a preset package that provides variants for Components Libraries based on data-state attribute value, and help to create custom variant selector. 33 | 34 | [Know more here](./packages/unify-variant/README.md) 35 | 36 | 37 | ### Config 38 | 39 | in your uno.config.(ts|js) 40 | 41 | ```js 42 | 43 | import { 44 | defineConfig, presetAttributify, presetWind3, 45 | } from "unocss"; 46 | 47 | import { colors } from "@unocss/preset-mini/colors"; 48 | 49 | // import the preset 50 | import {presetUI} from "@unifydev/preset-ui" 51 | 52 | 53 | export default defineConfig({ 54 | presets: [ 55 | presetWind3({dark: "class"}), 56 | presetAttributify(), // optional 57 | presetUI({}), 58 | ], 59 | }); 60 | 61 | ``` 62 | 63 | ### Use PresetUI 64 | 65 | ```html 66 |
67 |

68 | Badges 69 |

70 |
71 | 72 | badge 73 | 74 | 75 | badge 76 | 77 |
78 |
79 | ``` 80 | 81 | ## Contributing 82 | 83 | If you're interested in contributing to Uno-UI, please read our [contributing docs](CONTRIBUTING.MD) before submitting a pull request. 84 | 85 | ### Join Our Community 🌍 86 | 87 | Contribute, collaborate, and become a part of our mission 🚀 88 | - [Discord Community](https://discord.gg/6VN6zTPZAy) 89 | 90 | 91 | ## Acknowledgments 🌟 92 | 93 | - [Antfu](https://github.com/antfu) 94 | - [UnoCSS](https://github.com/unocss/unocss) 95 | - [Phojie Rengel](https://github.com/phojie) - [Una UI](https://github.com/una-ui/una-ui) 96 | 97 | 98 | ## Support Us 99 | 100 | If you like this project and want to support us, feel free to get in touch with one of maintainers : 101 | 102 | - [Johnkat MJ](mailto:johnkatembue4@gmail.com) -------------------------------------------------------------------------------- /color-code.md: -------------------------------------------------------------------------------- 1 | 2 | # Colors 3 | 4 | > **Important** Don't configure colors in uno.config, preset-ui already handled it! 5 | 6 | 7 | ## CSS Variables 8 | 9 | > **Note** : you need to provide every color with all shades from 50 to 950, for white color provide it via a `--c-white` variable 10 | 11 | ```css 12 | :root { 13 | /* global colors */ 14 | 15 | --c-white: value; 16 | /* bg colors */ 17 | --bg: var(--c-white); 18 | --bg-subtle: var(--c-gray-50); 19 | --bg-surface: var(--c-gray-100); 20 | --bg-muted: var(--c-gray-200); 21 | --bg-surface-elevated: var(--c-gray-300); 22 | 23 | /* text foreground */ 24 | --fg: var(--c-gray-700); 25 | --fg-muted: var(--c-gray-600); 26 | --fg-title: var(--c-gray-900); 27 | --fg-subtitle: var(--c-gray-800); 28 | 29 | /* border colors */ 30 | --border: var(--c-gray-200); 31 | --border-subtle: var(--c-gray-50); 32 | --border-light: var(--c-gray-200); 33 | --border-strong: var(--c-gray-300); 34 | --border-emphasis: var(--c-gray-400); 35 | 36 | /* gray colors */ 37 | --c-gray-50: value; 38 | --c-gray-100: value; 39 | /* ... other shades */ 40 | --c-gray-950: value; 41 | 42 | /* repeat the same for other colors : primary, secondary, accent, info,.... */ 43 | } 44 | ``` 45 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /example/components/accordion/js/script.js: -------------------------------------------------------------------------------- 1 | import { Accordion } from "@flexilla/accordion"; 2 | 3 | Accordion.autoInit("[data-accordion]") -------------------------------------------------------------------------------- /example/components/alert-dialog/alert.html: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unoforge/unify-preset/3e7470b22ee297f2a69601fb84a1907e3ae2db72/example/components/alert-dialog/alert.html -------------------------------------------------------------------------------- /example/components/alert-dialog/js/script.js: -------------------------------------------------------------------------------- 1 | import { Modal } from "@flexilla/modal"; 2 | import "@flexilla/modal/modal.css" 3 | 4 | // Initialize modals on elements with the 'data-alert-dialog' attribute. 5 | const modals = Array.from(document.querySelectorAll("[data-alert-dialog]")); 6 | for (const modal of modals) { 7 | new Modal(modal); 8 | } 9 | -------------------------------------------------------------------------------- /example/components/annonce_pill/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 |
13 |
14 | 19 |
20 |
21 |
22 |
23 |

24 | Default/Fill Default 25 |

26 |
27 |
28 | 30 | Unoify V1 is now Released! 31 | 32 |
33 |
34 |
36 | Unoify V1 is now Released! Check it 38 |
39 |
40 |
41 |
42 |
43 |

44 | Outline 45 |

46 | 54 |
55 |
56 |

57 | With pill - Icon 58 |

59 | 70 |
71 |
72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /example/components/aspect-ratio/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 |
13 |
14 | 19 |
20 |
21 |
22 |
23 |

24 | Video/TV 25 |

26 |
27 |
28 | Image by Johnnathan Tshibangu 29 |
30 |
31 |
32 |
33 |

34 | Square 35 |

36 |
37 |
38 | Image by Johnnathan Tshibangu 39 |
40 |
41 |
42 |
43 |

44 | 35mm film 45 |

46 |
47 |
48 | Image by Johnnathan Tshibangu 49 |
50 |
51 |
52 |
53 |

54 | Standard TV/Monitor 55 |

56 |
57 |
58 | Image by Johnnathan Tshibangu 59 |
60 |
61 |
62 |
63 |

64 | Ultrawide monitor 65 |

66 |
67 |
68 | Image by Johnnathan Tshibangu 69 |
70 |
71 |
72 |
73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /example/components/container/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 |
13 |
14 | 19 |
20 |
21 |
22 |
23 |

24 | Container : Default 25 |

26 |
27 |
28 |
29 | 30 |
31 |
32 |
33 |
34 |
35 |

36 | Container : Max-w7xl 37 |

38 |
39 |
40 |
41 | 42 |
43 |
44 |
45 |
46 |
47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /example/components/divider/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 |
13 |
14 | 19 |
20 |
21 |
22 |
23 |

24 | Divider 25 |

26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |

34 | Size : Height 35 |

36 |
37 |
38 |
39 |
40 |
41 |
42 | 43 |
44 |
45 |
46 |
47 |

48 | Corner Radius 49 |

50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |

59 | With label 60 |

61 |
62 |
63 | Label Start 64 |
65 |
66 | Label Center 67 |
68 |
69 | Label Start 70 |
71 |
72 | Custom label 73 |
74 |
75 |
76 |
77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /example/components/dropdown/js/script.js: -------------------------------------------------------------------------------- 1 | import { Dropdown } from "@flexilla/dropdown"; 2 | import "@flexilla/dropdown/dropdown.css"; 3 | 4 | const dropdowns = Array.from(document.querySelectorAll("[data-drop-down]")); 5 | for (const dropdown of dropdowns) { 6 | new Dropdown(dropdown); 7 | } 8 | -------------------------------------------------------------------------------- /example/components/icon/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 |
13 |
14 | 19 |
20 |
21 |
22 |
23 |

24 | Icon Default 25 |

26 |
27 | 30 | 33 | 36 | 40 | 44 |
45 |
46 |
47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /example/components/kbd/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 |
13 |
14 | 19 |
20 |
21 |
22 |
23 |

24 | Kbd Defaulft 25 |

26 |
27 | 28 | Ctrl 29 | 30 | 31 | Alt 32 | 33 | 35 | Ctrl + A 36 | 37 | 39 | fn + F12 40 | 41 | 43 | A + Ctrl 44 | 45 |
46 |
47 |
48 |

49 | KBD with Icon - Symbol 50 |

51 |
52 | 53 | 54 | 55 | 56 | 57 | 59 | 60 | 61 | 63 | / 64 | 65 |
66 |
67 |
68 |

69 | Grouped 70 |

71 |
72 |
73 | 74 | 75 | 76 | 77 | + 78 | B 79 | 80 | 81 | And 82 | 83 | 84 | 85 | 86 | 87 | + R 88 | 89 |
90 |
91 |
92 |
93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /example/components/link/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 |
13 |
14 | 19 |
20 |
21 |
22 |
23 |

24 | Link Defaulft 25 |

26 |
27 |
28 | 29 | Profile Page 30 | 31 |
32 |
33 |
34 |
35 |

36 | Underline 37 |

38 | 58 |
59 |
60 |

61 | With Icon 62 |

63 | 86 |
87 |
88 |

89 | Button Link 90 |

91 | 103 |
104 |
105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /example/components/meter/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 |
13 |
14 | 19 |
20 |
21 |
22 |
23 |

Meter

24 |
25 | 30 | 35 |
36 |
37 |
38 |

39 | Progress indicator 40 |

41 |
42 |
43 |
44 | 40% 45 |
46 | 51 |
52 |
53 | 58 |
62 | 70% 63 |
64 |
65 |
66 |
67 |
68 |

Meter Size

69 |
70 | 75 | 80 | 85 | 90 | 95 | 100 |
101 |
102 |
103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /example/components/popover/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 |
13 |
14 | 19 |
20 |
21 |
22 |
23 |

24 | Default PopOver 25 |

26 |
27 | 31 | 37 |
38 |
39 |
40 |

41 | With Content 42 |

43 |
44 | 53 | 65 |
66 |
67 |
68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /example/components/popover/js/script.js: -------------------------------------------------------------------------------- 1 | import { Popover } from "@flexilla/popover"; 2 | 3 | 4 | Popover.autoInit("[data-popover]") 5 | -------------------------------------------------------------------------------- /example/components/range/js/script.js: -------------------------------------------------------------------------------- 1 | import { CustomRange } from "@flexilla/flexilla" 2 | 3 | 4 | CustomRange.autoInit("[data-custom-range-wrapper]"); -------------------------------------------------------------------------------- /example/components/skeleton/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 |
13 |
14 | 19 |
20 |
21 |
22 |
23 |

24 | Skeleton 25 |

26 |
27 |
28 |
29 |
30 |
31 |

sd

32 |

33 | description 34 |

35 |

36 | description 37 |

38 |
39 |
40 |
41 |
42 |
43 |

44 | Card Skeleton 45 |

46 |
47 |
48 |
49 | 50 |
51 |
52 |

sd

53 |

54 | description 55 |

56 |

57 | description 58 |

59 |
60 |
61 |
62 |
63 |
64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /example/components/slideover/js/script.js: -------------------------------------------------------------------------------- 1 | import { OffCanvas } from "@flexilla/offcanvas"; 2 | 3 | const slideOvers = Array.from(document.querySelectorAll("[data-slideover]")); 4 | 5 | for (const slideover of slideOvers) { 6 | new OffCanvas(slideover); 7 | } 8 | -------------------------------------------------------------------------------- /example/components/tabs/js/script.js: -------------------------------------------------------------------------------- 1 | import { Tabs } from "@flexilla/flexilla"; 2 | 3 | Tabs.autoInit("[data-tabs]") 4 | -------------------------------------------------------------------------------- /example/components/text-area/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 |
13 |
14 | 19 |
20 |
21 | 22 |
23 |
24 |

25 | Default TextArea 26 |

27 |
28 | 29 |
30 |
31 |
32 |

33 | NoResize TextArea 34 |

35 |
36 | 37 |
38 |
39 |
40 |

41 | AutoResize 42 |

43 |
44 | 45 |
46 |
47 |
48 |

49 | With Label 50 |

51 |
52 |
53 | 54 | 56 |
57 |
58 |
59 |
60 |

61 | Disabled 62 |

63 |
64 | 65 |
66 |
67 |
68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /example/components/text-area/js/script.js: -------------------------------------------------------------------------------- 1 | import { AutoResizeTextArea } from "@flexilla/auto-resize-area"; 2 | const resizableTextAreas = Array.from( 3 | document.querySelectorAll("textarea[data-autoresizable]") 4 | ); 5 | 6 | for (const resizableTextArea of resizableTextAreas) { 7 | new AutoResizeTextArea(resizableTextArea); 8 | } -------------------------------------------------------------------------------- /example/components/tooltip/js/script.js: -------------------------------------------------------------------------------- 1 | import { Tooltip } from "@flexilla/tooltip"; 2 | import "@flexilla/tooltip/tooltip.css" 3 | 4 | const tooltips = Array.from(document.querySelectorAll("[data-fx-tooltip]")); 5 | for (const tooltip of tooltips) { 6 | new Tooltip(tooltip); 7 | } 8 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 |
13 |
14 | 19 |
20 |
21 |
22 |
23 |

24 | Grid (Rectangle) 25 |

26 |
27 |
30 |
31 |
32 |
33 |
34 |

35 | Grid (Square) 36 |

37 |
38 |
41 |
42 |
43 |
44 |
45 |

46 | Grid (Square) 47 |

48 |
49 |
52 |
53 |
54 |
55 |
56 |

57 | Grid stripped (Rectangle) 58 |

59 |
60 |
63 |
64 |
65 |
66 |
67 |

68 | Grid stripped (Square) 69 |

70 |
71 |
74 |
75 |
76 |
77 |
78 |

79 | Grid stripped reverse 80 |

81 |
82 |
85 |
86 |
87 |
88 | 89 |
90 |

91 | Radial BG 92 |

93 |
94 |
97 |
98 |
99 |
100 | 101 |
102 |

103 | Radial BG 104 |

105 |
106 |
109 |
110 |
111 |
112 | 113 |
114 |

115 | Grid dotted 116 |

117 |
118 |
120 |
121 |
122 | 123 |
124 |

125 | Grid dotted stripped oval 126 |

127 |
128 |
130 |
131 |
132 |
133 |
134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /example/js/load.theme.js: -------------------------------------------------------------------------------- 1 | const getThemePreferenceInit = () => { 2 | const currentTheme = localStorage.getItem("theme"); 3 | if (localStorage !== undefined && currentTheme) { 4 | return currentTheme; 5 | } 6 | return window.matchMedia("(prefers-color-scheme: dark)").matches 7 | ? "dark" 8 | : "light"; 9 | }; 10 | const isDark = getThemePreferenceInit() === "dark"; 11 | document.documentElement.classList[isDark ? "add" : "remove"]("dark"); 12 | 13 | if (localStorage) { 14 | const observer = new MutationObserver(() => { 15 | const isDark = document.documentElement.classList.contains("dark"); 16 | localStorage.setItem("theme", isDark ? "dark" : "light"); 17 | }); 18 | observer.observe(document.documentElement, { 19 | attributes: true, 20 | attributeFilter: ["class"], 21 | }); 22 | } 23 | -------------------------------------------------------------------------------- /example/js/theme.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | const getThemePreference = () => { 4 | const currentTheme = localStorage.getItem("theme"); 5 | if (localStorage !== undefined && currentTheme) { 6 | return currentTheme; 7 | } 8 | return window.matchMedia("(prefers-color-scheme: dark)").matches 9 | ? "dark" 10 | : "light"; 11 | }; 12 | 13 | const themeSwitcher = () => { 14 | const switchTheme = document.querySelector("[data-switch-theme]"); 15 | 16 | const isDark = getThemePreference() === "dark"; 17 | document.documentElement.classList[isDark ? "add" : "remove"]("dark"); 18 | if (switchTheme) { 19 | switchTheme.addEventListener("click", (e) => { 20 | e.preventDefault(); 21 | const doc = document.documentElement; 22 | if (doc) { 23 | const isDarkTheme = getThemePreference() === "dark"; 24 | doc.classList[isDarkTheme ? "remove" : "add"]("dark"); 25 | localStorage.setItem("theme", isDarkTheme ? "light" : "dark"); 26 | } 27 | }); 28 | } 29 | }; 30 | 31 | themeSwitcher(); 32 | -------------------------------------------------------------------------------- /example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite", 8 | "build": "tsc && vite build", 9 | "preview": "vite preview" 10 | }, 11 | "devDependencies": { 12 | "@iconify-json/carbon": "^1.2.7", 13 | "@iconify-json/ph": "^1.2.2", 14 | "@unifydev/flexilla": "^0.0.0", 15 | "typescript": "~5.7.2", 16 | "unocss": "^66.0.0", 17 | "vite": "^6.1.0" 18 | }, 19 | "dependencies": { 20 | "@flexilla/flexilla": "^2.1.0" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /example/src/app-ui.css: -------------------------------------------------------------------------------- 1 | 2 | :root { 3 | --bg: var(--c-white); 4 | --bg-subtle: var(--c-gray-50); 5 | --bg-surface: var(--c-gray-100); 6 | --bg-muted: var(--c-gray-200); 7 | --bg-surface-elevated: var(--c-gray-300); 8 | 9 | --fg: var(--c-gray-700); 10 | --fg-muted: var(--c-gray-600); 11 | --fg-title: var(--c-gray-900); 12 | --fg-subtitle: var(--c-gray-800); 13 | --border: var(--c-gray-200); 14 | 15 | --border-subtle: var(--c-gray-50); 16 | --border-light: var(--c-gray-200); 17 | --border-strong: var(--c-gray-300); 18 | --border-emphasis: var(--c-gray-400); 19 | 20 | --ui-checkbox-bg: var(--bg); 21 | --ui-checkbox-border: var(--border-strong); 22 | --ui-radio-bg: var(--bg); 23 | --ui-radio-border: var(--border-strong); 24 | 25 | --switch-checked-thumb-primary: var(--primary-600) 26 | 27 | } 28 | 29 | .dark { 30 | /* Background colors */ 31 | --bg:var(--c-gray-950); 32 | --bg-subtle: var(--c-gray-900); 33 | --bg-surface: var(--c-gray-900); 34 | --bg-muted: var(--c-gray-800); 35 | --bg-surface-elevated: var(--c-gray-700); 36 | 37 | /* Foreground colors */ 38 | --fg: var(--c-gray-300); 39 | --fg-title: var(--c-white); 40 | --fg-subtitle: var(--c-gray-200); 41 | --fg-muted: var(--c-gray-300); 42 | --fg-light: var(--c-gray-400); 43 | 44 | /* Border colors */ 45 | --border: var(--c-gray-900); 46 | --border-light: var(--c-gray-800); 47 | --border-subtle: var(--c-gray-900); 48 | --border-strong: var(--c-gray-700); 49 | --border-emphasis: var(--c-gray-600); 50 | 51 | --ui-checkbox-border: var(--border-light); 52 | 53 | } -------------------------------------------------------------------------------- /example/src/config-ui.css: -------------------------------------------------------------------------------- 1 | /* @import url(./button.css); */ 2 | @import url(./ui.css); 3 | @import url(./app-ui.css); 4 | 5 | 6 | :root { 7 | --switch-knob-white: var(--c-white); 8 | 9 | --range-thumb-bg-gray: var(--bg); 10 | --range-track-bg-gray: var(--c-gray-200); 11 | /* --switch-checked-knob-white: var(--c-white); */ 12 | 13 | 14 | 15 | --uno-ring-offset-color: hsl(var(--bg)); 16 | --uno-input-image-color: red; 17 | } 18 | 19 | 20 | 21 | .dark { 22 | --switch-knob-white: var(--c-white); 23 | 24 | --range-thumb-bg-gray: var(--c-gray-800); 25 | --range-track-bg-gray: var(--c-gray-900); 26 | /* --switch-checked-knob-white: var(--c-black); */ 27 | } 28 | 29 | 30 | 31 | @keyframes fadeIn { 32 | from { 33 | opacity: 0; 34 | visibility: hidden; 35 | } 36 | 37 | to { 38 | opacity: 1; 39 | visibility: visible; 40 | } 41 | } 42 | 43 | @keyframes fadeOut { 44 | from { 45 | opacity: 1; 46 | visibility: visible; 47 | } 48 | 49 | to { 50 | opacity: 0; 51 | visibility: hidden; 52 | } 53 | } 54 | 55 | @keyframes fadeInScale { 56 | from { 57 | opacity: 0; 58 | visibility: hidden; 59 | transform: scale(0.95); 60 | -webkit-transform: scale(0.95); 61 | -moz-transform: scale(0.95); 62 | -ms-transform: scale(0.95); 63 | -o-transform: scale(0.95); 64 | } 65 | 66 | to { 67 | opacity: 1; 68 | visibility: visible; 69 | transform: scale(1); 70 | -webkit-transform: scale(1); 71 | -moz-transform: scale(1); 72 | -ms-transform: scale(1); 73 | -o-transform: scale(1); 74 | } 75 | } 76 | 77 | @keyframes fadeOutScale { 78 | from { 79 | opacity: 1; 80 | visibility: visible; 81 | transform: scale(1); 82 | -webkit-transform: scale(1); 83 | -moz-transform: scale(1); 84 | -ms-transform: scale(1); 85 | -o-transform: scale(1); 86 | } 87 | 88 | to { 89 | opacity: 0; 90 | visibility: hidden; 91 | transform: scale(0.95); 92 | -webkit-transform: scale(0.95); 93 | -moz-transform: scale(0.95); 94 | -ms-transform: scale(0.95); 95 | -o-transform: scale(0.95); 96 | } 97 | } 98 | 99 | @keyframes slide-down-animation-modal { 100 | from { 101 | transform: translateY(-60px); 102 | opacity: 0; 103 | -webkit-transform: translateY(-60px); 104 | -moz-transform: translateY(-60px); 105 | -ms-transform: translateY(-60px); 106 | -o-transform: translateY(-60px); 107 | } 108 | 109 | to { 110 | transform: translateY(0); 111 | opacity: 1; 112 | -webkit-transform: translateY(0); 113 | -moz-transform: translateY(0); 114 | -ms-transform: translateY(0); 115 | -o-transform: translateY(0); 116 | } 117 | } 118 | 119 | @keyframes slide-up-animation-modal { 120 | from { 121 | transform: translateY(60px); 122 | opacity: 0; 123 | -webkit-transform: translateY(60px); 124 | -moz-transform: translateY(60px); 125 | -ms-transform: translateY(60px); 126 | -o-transform: translateY(60px); 127 | } 128 | 129 | to { 130 | transform: translateY(0); 131 | opacity: 1; 132 | -webkit-transform: translateY(0); 133 | -moz-transform: translateY(0); 134 | -ms-transform: translateY(0); 135 | -o-transform: translateY(0); 136 | } 137 | } -------------------------------------------------------------------------------- /example/src/main.ts: -------------------------------------------------------------------------------- 1 | import 'virtual:uno.css' 2 | import '@unocss/reset/tailwind.css'; 3 | import "./style.css" 4 | 5 | import "./../js/theme.js" -------------------------------------------------------------------------------- /example/src/themes/air.css: -------------------------------------------------------------------------------- 1 | [data-palette=air] { 2 | --c-primary-50: var(--c-air-orange-50); 3 | --c-primary-100: var(--c-air-orange-100); 4 | --c-primary-200: var(--c-air-orange-200); 5 | --c-primary-300: var(--c-air-orange-300); 6 | --c-primary-400: var(--c-air-orange-400); 7 | --c-primary-500: var(--c-air-orange-500); 8 | --c-primary-600: var(--c-air-orange-600); 9 | --c-primary-700: var(--c-air-orange-700); 10 | --c-primary-800: var(--c-air-orange-800); 11 | --c-primary-900: var(--c-air-orange-900); 12 | --c-primary-950: var(--c-air-orange-950); 13 | 14 | --c-secondary-50: var(--c-thunderbird-50); 15 | --c-secondary-100: var(--c-thunderbird-100); 16 | --c-secondary-200: var(--c-thunderbird-200); 17 | --c-secondary-300: var(--c-thunderbird-300); 18 | --c-secondary-400: var(--c-thunderbird-400); 19 | --c-secondary-500: var(--c-thunderbird-500); 20 | --c-secondary-600: var(--c-thunderbird-600); 21 | --c-secondary-700: var(--c-thunderbird-700); 22 | --c-secondary-800: var(--c-thunderbird-800); 23 | --c-secondary-900: var(--c-thunderbird-900); 24 | --c-secondary-950: var(--c-thunderbird-950); 25 | 26 | 27 | --c-accent-50: var(--c-air-yellow-50); 28 | --c-accent-100: var(--c-air-yellow-100); 29 | --c-accent-200: var(--c-air-yellow-200); 30 | --c-accent-300: var(--c-air-yellow-300); 31 | --c-accent-400: var(--c-air-yellow-400); 32 | --c-accent-500: var(--c-air-yellow-500); 33 | --c-accent-600: var(--c-air-yellow-600); 34 | --c-accent-700: var(--c-air-yellow-700); 35 | --c-accent-800: var(--c-air-yellow-800); 36 | --c-accent-900: var(--c-air-yellow-900); 37 | --c-accent-950: var(--c-air-yellow-950); 38 | 39 | 40 | --c-info-50: var(--c-sky-50); 41 | --c-info-100: var(--c-sky-100); 42 | --c-info-200: var(--c-sky-200); 43 | --c-info-300: var(--c-sky-300); 44 | --c-info-400: var(--c-sky-400); 45 | --c-info-500: var(--c-sky-500); 46 | --c-info-600: var(--c-sky-600); 47 | --c-info-700: var(--c-sky-700); 48 | --c-info-800: var(--c-sky-800); 49 | --c-info-900: var(--c-sky-900); 50 | --c-info-950: var(--c-sky-950); 51 | 52 | 53 | --c-gray-50: var(--c-neutral-50); 54 | --c-gray-100: var(--c-neutral-100); 55 | --c-gray-200: var(--c-neutral-200); 56 | --c-gray-300: var(--c-neutral-300); 57 | --c-gray-400: var(--c-neutral-400); 58 | --c-gray-500: var(--c-neutral-500); 59 | --c-gray-600: var(--c-neutral-600); 60 | --c-gray-700: var(--c-neutral-700); 61 | --c-gray-800: var(--c-neutral-800); 62 | --c-gray-900: var(--c-neutral-900); 63 | --c-gray-950: var(--c-neutral-950); 64 | } -------------------------------------------------------------------------------- /example/src/themes/earth.css: -------------------------------------------------------------------------------- 1 | [data-palette=earth] { 2 | --c-primary-50: var(--c-eucalyptus-50); 3 | --c-primary-100: var(--c-eucalyptus-100); 4 | --c-primary-200: var(--c-eucalyptus-200); 5 | --c-primary-300: var(--c-eucalyptus-300); 6 | --c-primary-400: var(--c-eucalyptus-400); 7 | --c-primary-500: var(--c-eucalyptus-500); 8 | --c-primary-600: var(--c-eucalyptus-600); 9 | --c-primary-700: var(--c-eucalyptus-700); 10 | --c-primary-800: var(--c-eucalyptus-800); 11 | --c-primary-900: var(--c-eucalyptus-900); 12 | --c-primary-950: var(--c-eucalyptus-950); 13 | 14 | --c-secondary-50: var(--c-air-yellow-50); 15 | --c-secondary-100: var(--c-air-yellow-100); 16 | --c-secondary-200: var(--c-air-yellow-200); 17 | --c-secondary-300: var(--c-air-yellow-300); 18 | --c-secondary-400: var(--c-air-yellow-400); 19 | --c-secondary-500: var(--c-air-yellow-500); 20 | --c-secondary-600: var(--c-air-yellow-600); 21 | --c-secondary-700: var(--c-air-yellow-700); 22 | --c-secondary-800: var(--c-air-yellow-800); 23 | --c-secondary-900: var(--c-air-yellow-900); 24 | --c-secondary-950: var(--c-air-yellow-950); 25 | 26 | --c-accent-50: var(--c-thunderbird-50); 27 | --c-accent-100: var(--c-thunderbird-100); 28 | --c-accent-200: var(--c-thunderbird-200); 29 | --c-accent-300: var(--c-thunderbird-300); 30 | --c-accent-400: var(--c-thunderbird-400); 31 | --c-accent-500: var(--c-thunderbird-500); 32 | --c-accent-600: var(--c-thunderbird-600); 33 | --c-accent-700: var(--c-thunderbird-700); 34 | --c-accent-800: var(--c-thunderbird-800); 35 | --c-accent-900: var(--c-thunderbird-900); 36 | --c-accent-950: var(--c-thunderbird-950); 37 | 38 | --c-warning-50: var(--c-camouflage-50); 39 | --c-warning-100: var(--c-camouflage-100); 40 | --c-warning-200: var(--c-camouflage-200); 41 | --c-warning-300: var(--c-camouflage-300); 42 | --c-warning-400: var(--c-camouflage-400); 43 | --c-warning-500: var(--c-camouflage-500); 44 | --c-warning-600: var(--c-camouflage-600); 45 | --c-warning-700: var(--c-camouflage-700); 46 | --c-warning-800: var(--c-camouflage-800); 47 | --c-warning-900: var(--c-camouflage-900); 48 | --c-warning-950: var(--c-camouflage-950); 49 | 50 | --c-info-50: 210 30% 97%; 51 | --c-info-100: 210 29% 85%; 52 | --c-info-200: 210 30% 70%; 53 | --c-info-300: 208 28% 53%; 54 | --c-info-400: 210 50% 40%; 55 | --c-info-500: 210 100% 25%; 56 | --c-info-600: 210 100% 22%; 57 | --c-info-700: 210 100% 18%; 58 | --c-info-800: 210 100% 15%; 59 | --c-info-900: 210 100% 11%; 60 | --c-info-950: 210 100% 7%; 61 | 62 | --c-gray-50: 195 38% 97%; 63 | --c-gray-100: 200 25% 95%; 64 | --c-gray-200: 200 20% 91%; 65 | --c-gray-300: 196 18% 80%; 66 | --c-gray-400: 200 11% 64%; 67 | --c-gray-500: 200 9% 47%; 68 | --c-gray-600: 200 12% 35%; 69 | --c-gray-700: 200 18% 27%; 70 | --c-gray-800: 204 22% 17%; 71 | --c-gray-900: 200 26% 8%; 72 | --c-gray-925: 200 29% 6%; 73 | --c-gray-950: 200 33% 1%; 74 | } 75 | -------------------------------------------------------------------------------- /example/src/themes/fire.css: -------------------------------------------------------------------------------- 1 | [data-palette=fire] { 2 | --c-primary-50: var(--c-thunderbird-50); 3 | --c-primary-100: var(--c-thunderbird-100); 4 | --c-primary-200: var(--c-thunderbird-200); 5 | --c-primary-300: var(--c-thunderbird-300); 6 | --c-primary-400: var(--c-thunderbird-400); 7 | --c-primary-500: var(--c-thunderbird-500); 8 | --c-primary-600: var(--c-thunderbird-600); 9 | --c-primary-700: var(--c-thunderbird-700); 10 | --c-primary-800: var(--c-thunderbird-800); 11 | --c-primary-900: var(--c-thunderbird-900); 12 | --c-primary-950: var(--c-thunderbird-950); 13 | 14 | --c-secondary-50: var(--c-air-orange-50); 15 | --c-secondary-100: var(--c-air-orange-100); 16 | --c-secondary-200: var(--c-air-orange-200); 17 | --c-secondary-300: var(--c-air-orange-300); 18 | --c-secondary-400: var(--c-air-orange-400); 19 | --c-secondary-500: var(--c-air-orange-500); 20 | --c-secondary-600: var(--c-air-orange-600); 21 | --c-secondary-700: var(--c-air-orange-700); 22 | --c-secondary-800: var(--c-air-orange-800); 23 | --c-secondary-900: var(--c-air-orange-900); 24 | --c-secondary-950: var(--c-air-orange-950); 25 | 26 | 27 | --c-gray-50: var(--c-stone-50); 28 | --c-gray-100: var(--c-stone-100); 29 | --c-gray-200: var(--c-stone-200); 30 | --c-gray-300: var(--c-stone-300); 31 | --c-gray-400: var(--c-stone-400); 32 | --c-gray-500: var(--c-stone-500); 33 | --c-gray-600: var(--c-stone-600); 34 | --c-gray-700: var(--c-stone-700); 35 | --c-gray-800: var(--c-stone-800); 36 | --c-gray-900: var(--c-stone-900); 37 | --c-gray-950: var(--c-stone-950); 38 | } 39 | -------------------------------------------------------------------------------- /example/src/themes/water.css: -------------------------------------------------------------------------------- 1 | [data-palette="water"] { 2 | --c-primary-50: 213 36% 97%; 3 | --c-primary-100: 213 41% 94%; 4 | --c-primary-200: 213 54% 86%; 5 | --c-primary-300: 210 57% 74%; 6 | --c-primary-400: 208 56% 60%; 7 | --c-primary-500: 209 50% 48%; 8 | --c-primary-600: 210 55% 40%; 9 | --c-primary-700: 211 55% 32%; 10 | --c-primary-800: 212 52% 27%; 11 | --c-primary-900: 213 46% 24%; 12 | --c-primary-950: 214 46% 16%; 13 | 14 | --c-secondary-50: var(--c-teal-50); 15 | --c-secondary-100: var(--c-teal-100); 16 | --c-secondary-200: var(--c-teal-200); 17 | --c-secondary-300: var(--c-teal-300); 18 | --c-secondary-400: var(--c-teal-400); 19 | --c-secondary-500: var(--c-teal-500); 20 | --c-secondary-600: var(--c-teal-600); 21 | --c-secondary-700: var(--c-teal-700); 22 | --c-secondary-800: var(--c-teal-800); 23 | --c-secondary-900: var(--c-teal-900); 24 | --c-secondary-950: var(--c-teal-950); 25 | 26 | 27 | --c-accent-50: var(--c-dodger-blue-50); 28 | --c-accent-100: var(--c-dodger-blue-100); 29 | --c-accent-200: var(--c-dodger-blue-200); 30 | --c-accent-300: var(--c-dodger-blue-300); 31 | --c-accent-400: var(--c-dodger-blue-400); 32 | --c-accent-500: var(--c-dodger-blue-500); 33 | --c-accent-600: var(--c-dodger-blue-600); 34 | --c-accent-700: var(--c-dodger-blue-700); 35 | --c-accent-800: var(--c-dodger-blue-800); 36 | --c-accent-900: var(--c-dodger-blue-900); 37 | --c-accent-950: var(--c-dodger-blue-950); 38 | 39 | 40 | --c-gray-50: var(--c-gray-base-50); 41 | --c-gray-100: var(--c-gray-base-100); 42 | --c-gray-200: var(--c-gray-base-200); 43 | --c-gray-300: var(--c-gray-base-300); 44 | --c-gray-400: var(--c-gray-base-400); 45 | --c-gray-500: var(--c-gray-base-500); 46 | --c-gray-600: var(--c-gray-base-600); 47 | --c-gray-700: var(--c-gray-base-700); 48 | --c-gray-800: var(--c-gray-base-800); 49 | --c-gray-900: var(--c-gray-base-900); 50 | --c-gray-950: var(--c-gray-base-950); 51 | } 52 | -------------------------------------------------------------------------------- /example/src/vite-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "isolatedModules": true, 13 | "moduleDetection": "force", 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true, 21 | "noUncheckedSideEffectImports": true 22 | }, 23 | "include": ["src"] 24 | } 25 | -------------------------------------------------------------------------------- /example/uno.config.ts: -------------------------------------------------------------------------------- 1 | import { 2 | defineConfig, 3 | presetIcons, 4 | presetWind3, 5 | } from "unocss"; 6 | 7 | import { flexillaPreset } from "@unifydev/flexilla" 8 | import { presetUI } from "@unifydev/preset-ui" 9 | 10 | 11 | export default defineConfig({ 12 | presets: [ 13 | presetWind3({dark: "class",}), 14 | presetIcons({ 15 | collections: { 16 | //@ts-ignore 17 | ph: () => 18 | import("@iconify-json/ph/icons.json").then((i) => i.default), 19 | carbon: () => import("@iconify-json/carbon/icons.json") 20 | }, 21 | }), 22 | presetUI({}) as any, 23 | // presetBg() as any, 24 | flexillaPreset(), 25 | ], 26 | }) -------------------------------------------------------------------------------- /example/vite.config.ts: -------------------------------------------------------------------------------- 1 | import UnoCSS from 'unocss/vite' 2 | import { defineConfig } from 'vite' 3 | 4 | export default defineConfig({ 5 | plugins: [ 6 | UnoCSS(), 7 | ], 8 | }) -------------------------------------------------------------------------------- /favicon-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unoforge/unify-preset/3e7470b22ee297f2a69601fb84a1907e3ae2db72/favicon-dark.png -------------------------------------------------------------------------------- /lerna.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "node_modules/lerna/schemas/lerna-schema.json", 3 | "version": "independent" 4 | } 5 | -------------------------------------------------------------------------------- /nx.json: -------------------------------------------------------------------------------- 1 | { 2 | "targetDefaults": { 3 | "dev": { 4 | "dependsOn": [] 5 | }, 6 | "build": { 7 | "cache": true, 8 | "dependsOn": [], 9 | "outputs": [ 10 | "{projectRoot}/dist" 11 | ] 12 | }, 13 | "preview": { 14 | "dependsOn": [] 15 | }, 16 | "format": { 17 | "cache": true, 18 | "dependsOn": [] 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "root", 3 | "private": true, 4 | "description": "UnifyPreset : UnoCSS Preset Collection", 5 | "workspaces": [ 6 | "packages/*" 7 | ], 8 | "devDependencies": { 9 | "lerna": "^8.1.2" 10 | }, 11 | "scripts": { 12 | "b-preset-bg": "npx lerna run build --scope=@unifydev/preset-bg", 13 | "b-unify-variant": "npx lerna run build --scope=@unifydev/unify-variant", 14 | "b-preset-ui": "npx lerna run build --scope=@unifydev/preset-ui", 15 | "b-flexilla": "npx lerna run build --scope=@unifydev/flexilla", 16 | "build": "npm run b-preset-bg && npm run b-unify-variant && npm run b-preset-ui && npm run b-flexilla" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /packages/flexilla/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /packages/flexilla/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 UnifyUI Dev 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/flexilla/README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

Flexilla Preset

4 |

Variants for Flexilla, UnoVue,...

5 |

6 | 7 | 8 | ## Flexilla-Variant 9 | 10 | This is a preset package that provides variants for Components Libraries based on data-state attribute value, and help to create custom variant selector. 11 | 12 | ### Data State Variants 13 | 14 | Generate variants selector based on data-state attribute, however you can use it with other data-* attributes like (data-name="john" then `fx-john:p4`) 15 | 16 | - [X] Radix 17 | - [X] Flexilla 18 | - [X] Radix Vue 19 | 20 | `fx-open:bg-red` : will be applied if element has data-state='open' 21 | 22 | ### browserVariant 23 | 24 | Easily create custom variants for browser selector like ::moz-* ::webki... 25 | 26 | 27 | 28 | ## Usage 29 | 30 | ### Installation 31 | 32 | ```bash 33 | npm i -D @unifydev/flexilla 34 | ``` 35 | or 36 | ```bash 37 | yarn add @unifydev/flexilla -D 38 | ``` 39 | Or 40 | ```bash 41 | bun add @unifydev/flexilla -d 42 | ``` 43 | 44 | ### Config 45 | 46 | In you `uno.config.(js|ts)` : 47 | ```js 48 | // import the packages 49 | import { flexillaPreset } from '@unifydev/unify-variant' 50 | 51 | export default defineConfig({ 52 | presets:[ 53 | flexillaPreset({/* change prefix if needed, default is fx **/ }) 54 | ] 55 | }); 56 | 57 | ``` 58 | 59 | 60 | ### Use it 61 | 62 | Now you can use : 63 | 64 | - `fx-visible:opacity-100 fx-visible:visible` : this will apply opacity:1 and visiblity:visible to the element when the data-state attribute is open. 65 | 66 | 67 | ## Contributing 68 | 69 | If you're interested in contributing to Unify-UI, please read our [contributing docs](CONTRIBUTING.MD) before submitting a pull request. 70 | 71 | ### Join Our Community 🌍 72 | 73 | Contribute, collaborate, and become a part of our mission 🚀 74 | - [Discord Community](https://discord.gg/6VN6zTPZAy) -------------------------------------------------------------------------------- /packages/flexilla/build.config.ts: -------------------------------------------------------------------------------- 1 | import { defineBuildConfig } from 'unbuild' 2 | 3 | export default defineBuildConfig({ 4 | entries: ['src/index'], 5 | declaration: true, 6 | clean: true, 7 | rollup: { 8 | emitCJS: true, 9 | }, 10 | externals: ['unocss','@unifydev/unify-variant', '@unocss/preset-uno'], 11 | failOnWarn:false, 12 | }) -------------------------------------------------------------------------------- /packages/flexilla/favicon-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unoforge/unify-preset/3e7470b22ee297f2a69601fb84a1907e3ae2db72/packages/flexilla/favicon-dark.png -------------------------------------------------------------------------------- /packages/flexilla/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@unifydev/flexilla", 3 | "version": "0.1.2", 4 | "description": "Variants, shortcuts, utilities for flexilla", 5 | "publishConfig": { 6 | "access": "public" 7 | }, 8 | "main": "./dist/index.cjs", 9 | "module": "./dist/index.mjs", 10 | "types": "./dist/index.d.ts", 11 | "exports": { 12 | ".": { 13 | "types": "./dist/index.d.ts", 14 | "require": "./dist/index.cjs", 15 | "import": "./dist/index.mjs" 16 | } 17 | }, 18 | "scripts": { 19 | "build": "rimraf dist && unbuild", 20 | "format": "biome format --write ./src" 21 | }, 22 | "files": [ 23 | "dist", 24 | "!dist/index.d.cts", 25 | "!dist/index.d.mts", 26 | "README.md", 27 | "favicon-dark.png", 28 | "package.json", 29 | "!.gitignore", 30 | "!tsconfig.json", 31 | "!biome.js" 32 | ], 33 | "author": "Johnkat MJ", 34 | "license": "MIT", 35 | "devDependencies": { 36 | "@types/node": "^22.14.1", 37 | "@unocss/reset": "^0.58.6", 38 | "rimraf": "^6.0.1", 39 | "ts-node": "^10.9.2", 40 | "typescript": "^5.8.3", 41 | "unbuild": "^3.5.0", 42 | "unocss": "^v66.0.0" 43 | }, 44 | "dependencies": { 45 | "@unifydev/unify-variant": "latest" 46 | }, 47 | "keywords": [ 48 | "uno preset", 49 | "unocss", 50 | "unocss component", 51 | "unocss ui", 52 | "unocss", 53 | "flexilla" 54 | ], 55 | "repository": { 56 | "type": "git", 57 | "url": "https://github.com/unoforge/unify-preset" 58 | }, 59 | "bugs": { 60 | "url": "https://github.com/unoforge/unify-preset/issues" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /packages/flexilla/src/flexillaVariants.ts: -------------------------------------------------------------------------------- 1 | import { dataStateVariants } from "@unifydev/unify-variant"; 2 | import type { Variant } from "unocss"; 3 | import type { Theme } from "@unocss/preset-uno"; 4 | 5 | export const getAllVariants = (prefixState?: string) => { 6 | const variants = [ 7 | dataStateVariants({ 8 | prefix: prefixState, 9 | variants: 10 | "visible|hidden|active|inactive|open|close|opened|closed|resize|minimize|maximaze|opened|closed|maximazed|resized|copied", 11 | selector: "data-state", 12 | }) 13 | ] as Variant[]; 14 | 15 | return variants; 16 | }; 17 | -------------------------------------------------------------------------------- /packages/flexilla/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Preset } from 'unocss' 2 | import { getAllVariants } from './flexillaVariants' 3 | 4 | type MyPresetOptions = { 5 | prefix?: string 6 | } 7 | 8 | function flexillaPreset(options: MyPresetOptions = { prefix: "fx" }): Preset { 9 | return { 10 | name: '@unifydev/flexilla', 11 | variants: getAllVariants(options.prefix), 12 | shortcuts: { 13 | 'ui-tabs-indicator': 'absolute transform-origin-[0_0] w-[var(--un-tab-indicator-width)] h-[var(--un-tab-indicator-height)] top-[var(--un-tab-indicator-top)] left-[var(--un-tab-indicator-left)]', 14 | 'ui-animated-modal-content': 'animate-[var(--un-modal-animation)] animate-fill-both', 15 | 'ui-animated-tab-panel': 'animate-[var(--un-tab-show-animation)] animate-fill-both', 16 | 'ui-overlay': 'fixed inset-0' 17 | }, 18 | rules: [ 19 | [ 20 | 'ui-popper', { 21 | position: "fixed", 22 | left: "var(--fx-popper-placement-x)", 23 | top: "var(--fx-popper-placement-y)" 24 | } 25 | ] 26 | ] 27 | } 28 | } 29 | 30 | export { flexillaPreset } -------------------------------------------------------------------------------- /packages/flexilla/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./../../shared/tsconfig.json", 3 | "include": ["src"] 4 | } -------------------------------------------------------------------------------- /packages/preset-bg/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /packages/preset-bg/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 UnoForge 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-bg/README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

Preset-BG

4 |

UI Background.

5 |

6 | 7 | This presset is a customizable collection of gradient, grid, radial background by [bg.ibelick.com](https://bg.ibelick.com/) 8 | 9 | ### Credit 10 | 11 | - [Ibelick](https://twitter.com/Ibelick) for creating [bg.ibelick.com](https://bg.ibelick.com/) 12 | 13 | ## Usage 14 | 15 | ### Installation 16 | 17 | ```bash 18 | npm i -D @unifydev/preset-bg 19 | ``` 20 | 21 | Note that PresetBG is a dev dependency 22 | 23 | ### Config 24 | 25 | In you `uno.config.(js|ts)` : 26 | 27 | ```js 28 | ... 29 | // import the packages 30 | import {presetBg} from '@unifydev/preset-bg' 31 | 32 | export default defineConfig({ 33 | // ...config 34 | presets: [ 35 | //other presets 36 | presetBg() 37 | ], 38 | }); 39 | 40 | ``` 41 | 42 | ### Use it 43 | 44 | Now you can use : 45 | 46 | Grid 47 | 48 | ```html 49 |
50 | 54 |
55 | ``` 56 | 57 | In CSS 58 | 59 | ```css 60 | :root { 61 | --unify-grid-dotted-bg-gray: valueHere; 62 | } 63 | ``` 64 | 65 | ## Contributing 66 | 67 | If you're interested in contributing to Unify-UI, please read our [contributing docs](CONTRIBUTING.MD) before submitting a pull request. 68 | 69 | ### Join Our Community 🌍 70 | 71 | Contribute, collaborate, and become a part of our mission 🚀 72 | 73 | - [Discord Community](https://discord.gg/6VN6zTPZAy) 74 | 75 | ## Support Us 76 | 77 | If you like this project and want to support us, feel free to get in touch with one of maintainers : 78 | 79 | - [Johnkat MJ](mailto:johnkatembue4@gmail.com) 80 | -------------------------------------------------------------------------------- /packages/preset-bg/build.config.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'node:path' 2 | import { defineBuildConfig } from 'unbuild' 3 | 4 | 5 | export default defineBuildConfig({ 6 | entries: ['src/index'], 7 | declaration: true, 8 | clean: true, 9 | rollup: { 10 | emitCJS: true, 11 | alias: { 12 | entries: { 13 | "@/types": resolve(__dirname, './src/types/'), 14 | "@/utils": resolve(__dirname, './src/utils/') 15 | }, 16 | }, 17 | dts: { 18 | compilerOptions: { 19 | baseUrl: "./", 20 | paths: { 21 | "@/*": ["src/*"] 22 | } 23 | } 24 | } 25 | }, 26 | 27 | failOnWarn: false, 28 | externals: ['unocss', "@unifydev/unify-variant", '@unocss/preset-mini/utils', '@unocss/rule-utils', '@unocss/core'], 29 | }) -------------------------------------------------------------------------------- /packages/preset-bg/favicon-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unoforge/unify-preset/3e7470b22ee297f2a69601fb84a1907e3ae2db72/packages/preset-bg/favicon-dark.png -------------------------------------------------------------------------------- /packages/preset-bg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@unifydev/preset-bg", 3 | "version": "0.2.1", 4 | "description": "UnoCSS Theming Toolkit, create modern and beautifull Web Ui", 5 | "publishConfig": { 6 | "access": "public" 7 | }, 8 | "main": "./dist/index.cjs", 9 | "module": "./dist/index.mjs", 10 | "types": "./dist/index.d.ts", 11 | "exports": { 12 | ".": { 13 | "types": "./dist/index.d.ts", 14 | "require": "./dist/index.cjs", 15 | "import": "./dist/index.mjs" 16 | } 17 | }, 18 | "scripts": { 19 | "format": "biome format --write ./src", 20 | "build": "rimraf dist && unbuild" 21 | }, 22 | "files": [ 23 | "dist", 24 | "README.md", 25 | "favicon-dark.png", 26 | "package.json", 27 | "!.gitignore", 28 | "!tsconfig.json", 29 | "!biome.js" 30 | ], 31 | "author": "Johnkat MJ", 32 | "license": "MIT", 33 | "devDependencies": { 34 | "@types/node": "^22.14.1", 35 | "rimraf": "^6.0.1", 36 | "ts-node": "^10.9.2", 37 | "typescript": "^5.8.3", 38 | "unbuild": "^3.5.0", 39 | "unocss": "^v66.0.0" 40 | }, 41 | "keywords": [ 42 | "Preset BG", 43 | "unify preset", 44 | "atomic ui library", 45 | "unocss ui", 46 | "theming ui library", 47 | "unocss components", 48 | "modern ui", 49 | "component library", 50 | "unify ui", 51 | "unifyui", 52 | "uno ui", 53 | "unoui", 54 | "unoforge" 55 | ], 56 | "repository": { 57 | "type": "git", 58 | "url": "https://github.com/unoforge/unify-preset" 59 | }, 60 | "bugs": { 61 | "url": "https://github.com/unoforge/unify-preset/issues" 62 | }, 63 | "gitHead": "1a4a3121332b2961338fd7920369d64ba3bab0e5" 64 | } 65 | -------------------------------------------------------------------------------- /packages/preset-bg/src/index.ts: -------------------------------------------------------------------------------- 1 | import type { Preset } from "unocss"; 2 | import { getAllRules } from "./rules"; 3 | 4 | /** 5 | * Preset BG 6 | * @returns 7 | */ 8 | function presetBg(): Preset { 9 | const rules = getAllRules(); 10 | return { 11 | name: "preset-bg", 12 | rules, 13 | }; 14 | } 15 | 16 | export { presetBg }; 17 | -------------------------------------------------------------------------------- /packages/preset-bg/src/rules/const.ts: -------------------------------------------------------------------------------- 1 | import type { Squares, UiSizeVariants } from "./types"; 2 | 3 | export const gridRecSizes: UiSizeVariants = { 4 | xs: { 5 | height: 18, 6 | width: 10 7 | }, 8 | sm: { 9 | height: 21, 10 | width: 12 11 | }, 12 | md: { 13 | height: 24, 14 | width: 14 15 | }, 16 | lg: { 17 | height: 26, 18 | width: 16 19 | }, 20 | xl: { 21 | height: 30, 22 | width: 18 23 | }, 24 | '2xl': { 25 | height: 32, 26 | width: 20 27 | } 28 | } 29 | 30 | 31 | 32 | export const gridSquareSizes: Squares = { 33 | xs: 10, 34 | sm: 15, 35 | md: 20, 36 | lg: 25, 37 | xl: 30, 38 | '2xl': 35 39 | } -------------------------------------------------------------------------------- /packages/preset-bg/src/rules/index.ts: -------------------------------------------------------------------------------- 1 | 2 | import type { Rule } from "unocss"; 3 | import type { Theme } from "@unocss/preset-uno"; 4 | import { gridSquareSizes, gridRecSizes } from "./const"; 5 | import type { variantSize } from "./types"; 6 | 7 | 8 | export const getAllRules = () => { 9 | const rules = [ 10 | [ 11 | "ui-grid-dotted", 12 | { 13 | "--dotsize": "1px", 14 | "background-image": "radial-gradient(currentColor var(--dotsize), transparent var(--dotsize))", 15 | "background-size": 'var(--unify-ui-grid-width) var(--unify-ui-grid-height)', 16 | }, 17 | ], 18 | [ 19 | "ui-radial-gradient", 20 | { 21 | background: 'radial-gradient(125% 125% at 50% 10%, var(--unify-radial-bg) 40%, currentColor 100%)' 22 | }, 23 | ], 24 | [ 25 | "ui-radial-gradient-reverse", 26 | { 27 | background: 'radial-gradient(125% 125% at 50% 90%, var(--unify-radial-bg) 40%, currentColor 100%)' 28 | }, 29 | ], 30 | [ 31 | "ui-grid", 32 | { 33 | "--unify-grid-color": 'currentColor', 34 | "background-image": `linear-gradient(to right, var(--unify-grid-color) 1px, transparent 1px), linear-gradient(to bottom, var(--unify-grid-color) 1px, transparent 1px)`, 35 | "background-size": 'var(--unify-ui-grid-width) var(--unify-ui-grid-height)', 36 | }, 37 | ], 38 | [ 39 | "ui-striped-overlay-mask-reverse", 40 | { 41 | "mask-image": "radial-gradient(ellipse 60% 50% at 50% 100%, #000 70%, transparent 110%)" 42 | }, 43 | ], 44 | [ 45 | "ui-striped-overlay-mask", 46 | { 47 | "mask-image": "radial-gradient(ellipse 60% 50% at 50% 0%, #000 70%, transparent 110%)" 48 | }, 49 | ], 50 | [ 51 | "ui-striped-mask-oval", 52 | { 53 | "mask-image": "radial-gradient(ellipse 50% 50% at 50% 50%, #000 70%, transparent 100%)" 54 | }, 55 | ], 56 | 57 | [ 58 | /^ui-grid-w-(xs|sm|md|lg|xl|2xl)$/, 59 | ([, d]) => ({ "--unify-ui-grid-width": `${gridRecSizes[d as variantSize]?.width}px` }), 60 | { autocomplete: 'ui-grid-w-(xs|sm|md|lg|xl|2xl)' } 61 | ], 62 | [ 63 | /^ui-grid-h-(xs|sm|md|lg|xl|2xl)$/, 64 | ([, d]) => ({ "--unify-ui-grid-height": `${gridRecSizes[d as variantSize]?.height}px` }), 65 | { autocomplete: 'ui-grid-h-(xs|sm|md|lg|xl|2xl)' } 66 | ], 67 | [ 68 | /^ui-grid-square-(xs|sm|md|lg|xl|2xl)$/, 69 | ([, d]) => ({ 70 | "--unify-ui-grid-width": `${gridSquareSizes[d as variantSize]}px`, 71 | "--unify-ui-grid-height": `${gridSquareSizes[d as variantSize]}px` 72 | }), 73 | { autocomplete: 'ui-grid-square-(xs|sm|md|lg|xl|2xl)' } 74 | ], 75 | [ 76 | /^ui-grid-rec-(xs|sm|md|lg|xl|2xl)$/, 77 | ([, d]) => ({ 78 | "--unify-ui-grid-width": `${gridRecSizes[d as variantSize]?.width}px`, 79 | "--unify-ui-grid-height": `${gridRecSizes[d as variantSize]?.height}px` 80 | }), 81 | { autocomplete: 'ui-grid-rec-(xs|sm|md|lg|xl|2xl)' } 82 | ], 83 | 84 | ] as Rule[]; 85 | 86 | return rules; 87 | }; 88 | -------------------------------------------------------------------------------- /packages/preset-bg/src/rules/types.ts: -------------------------------------------------------------------------------- 1 | export type variantSize = "xs" | "xl" | "sm" | "md" | "lg" | "xl" | "2xl"; 2 | 3 | export type UiSizeVariants = Record 4 | export type Squares = Record 5 | 6 | -------------------------------------------------------------------------------- /packages/preset-bg/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./../../shared/tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "paths": { 6 | "@/*": ["src/*"] 7 | } 8 | }, 9 | "include": ["src"] 10 | } -------------------------------------------------------------------------------- /packages/preset-ui/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /packages/preset-ui/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 UnoForge 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-ui/README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

Preset UI

4 |

UnoCSS Theming Toolkit.

5 |

6 | 7 | ## Preset-UI 8 | 9 | Preset UI stands at the forefront of UI customization, offering a comprehensive theming library designed to empower developers and designers alike. At its core, preset-ui leverages the power and flexibility of UnoCSS and provides a variety of themes that can be easily customized to match your brand and style. 10 | 11 | > **Not** : This project is a WIP, you can test it and report bug... Your contribution is much valualed for us, help us to make it better. 12 | 13 | ## Concepts 🧠 14 | 15 | - **🖌️ Component-Level Theming:** Customize each component independently, allowing for detailed personalization while maintaining overall harmony. 16 | 17 | - **🎯 Atomic Library:** Following UNOCSS design principles, Unify Preset adopts an atomic approach . It generates CSS only for the utilities you use, optimizing both speed and efficiency. 18 | 19 | ## Features 20 | 21 | - **Atomic Library by Nature:** Configure what you need, and use when you need it. 22 | - **🛠️ Customizable:** Tailor each component to fit your vision, ensuring a unique and cohesive look across your application. 23 | - **📈 Efficient Scaling:** Our preset ensures your project remains lightweight and fast, no matter its size. 24 | - **🎨 Consistent Yet Flexible:** Achieve a consistent look and feel without sacrificing the creativity and uniqueness of individual components. 25 | 26 | ## Usage 27 | 28 | ### Installation 29 | 30 | ```bash 31 | npm i -D @unifydev/preset-ui 32 | # or 33 | yarn add @unifydev/preset-ui -D 34 | # or 35 | pnpm add @unifydev/preset-ui -D 36 | ``` 37 | 38 | ### Config 39 | 40 | in your uno.config.(ts|js) 41 | 42 | ```js 43 | import { defineConfig, presetAttributify, presetWind3 } from "unocss"; 44 | 45 | import { colors } from "@unocss/preset-mini/colors"; 46 | // import the preset 47 | import { presetUI } from "@unifydev/preset-ui"; 48 | 49 | export default defineConfig({ 50 | presets: [presetWind3({ dark: "class" }), presetAttributify(), presetUI({})], 51 | }); 52 | ``` 53 | 54 | ### Use it 55 | 56 | ```html 57 |
58 |

Badges

59 |
60 | badge 61 | badge 62 |
63 |
64 | ``` 65 | 66 | ## Contributing 67 | 68 | If you're interested in contributing to Unify-UI, please read our [contributing docs](CONTRIBUTING.MD) before submitting a pull request. 69 | 70 | ### Join Our Community 🌍 71 | 72 | Contribute, collaborate, and become a part of our mission 🚀 73 | 74 | - [Discord Community](https://discord.gg/6VN6zTPZAy) 75 | -------------------------------------------------------------------------------- /packages/preset-ui/build.config.ts: -------------------------------------------------------------------------------- 1 | import { resolve } from 'node:path' 2 | import { defineBuildConfig } from 'unbuild' 3 | import fs from 'fs'; 4 | import path from 'path'; 5 | 6 | 7 | async function copyFolder(src: string, dest: string): Promise { 8 | try { 9 | if (!fs.existsSync(dest)) { 10 | await fs.promises.mkdir(dest, { recursive: true }); 11 | } 12 | const items = await fs.promises.readdir(src); 13 | 14 | for (const item of items) { 15 | const srcItem = path.join(src, item); 16 | const destItem = path.join(dest, item); 17 | 18 | const stat = await fs.promises.stat(srcItem); 19 | 20 | if (stat.isDirectory()) { 21 | await copyFolder(srcItem, destItem); 22 | } else { 23 | await fs.promises.copyFile(srcItem, destItem); 24 | } 25 | } 26 | console.log(`✔ Theme copied from ${src} to ${dest}`); 27 | } catch (err) { 28 | console.error('Error copying folder:', err); 29 | } 30 | } 31 | 32 | 33 | export default defineBuildConfig({ 34 | entries: ['src/index'], 35 | declaration: true, 36 | clean: true, 37 | rollup: { 38 | emitCJS: true, 39 | alias: { 40 | entries: { 41 | "@/types": resolve(__dirname, './src/types/'), 42 | "@/utils": resolve(__dirname, './src/utils/'), 43 | "@/rules": resolve(__dirname, './src/rules'), 44 | "@/shortcuts": resolve(__dirname, './src/shortcuts/'), 45 | "@/ui": resolve(__dirname, "./src/ui/"), 46 | "@/colors":resolve(__dirname, "./src/colors/") 47 | }, 48 | }, 49 | dts: { 50 | compilerOptions: { 51 | baseUrl: "./", 52 | paths: { 53 | "@/*": ["src/*"] 54 | } 55 | } 56 | } 57 | }, 58 | failOnWarn: false, 59 | externals: ['unocss', "@unifydev/unify-variant", '@unocss/preset-mini/utils', '@unocss/rule-utils', '@unocss/core'], 60 | hooks: { 61 | 'mkdist:done':async () => { 62 | await copyFolder('src/css', 'dist/css') 63 | } 64 | } 65 | }) -------------------------------------------------------------------------------- /packages/preset-ui/favicon-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unoforge/unify-preset/3e7470b22ee297f2a69601fb84a1907e3ae2db72/packages/preset-ui/favicon-dark.png -------------------------------------------------------------------------------- /packages/preset-ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@unifydev/preset-ui", 3 | "version": "1.2.8", 4 | "description": "UnoCSS Theming Toolkit, create modern and beautifull Web Ui", 5 | "publishConfig": { 6 | "access": "public" 7 | }, 8 | "main": "./dist/index.cjs", 9 | "module": "./dist/index.mjs", 10 | "types": "./dist/index.d.ts", 11 | "exports": { 12 | ".": { 13 | "types": "./dist/index.d.ts", 14 | "require": "./dist/index.cjs", 15 | "import": "./dist/index.mjs" 16 | }, 17 | "./css/default/base.css": "./dist/css/default/base.css", 18 | "./css/default/dark.css": "./dist/css/default/dark.css", 19 | "./css/default/light.css": "./dist/css/default/light.css", 20 | "./themes/air.css": "./dist/css/themes/air.css", 21 | "./themes/water.css": "./dist/css/themes/water.css", 22 | "./themes/earth.css": "./dist/css/themes/earth.css", 23 | "./themes/fire.css": "./dist/css/themes/fire.css" 24 | }, 25 | "scripts": { 26 | "format": "biome format --write ./src", 27 | "build": "rimraf dist && unbuild" 28 | }, 29 | "files": [ 30 | "dist", 31 | "README.md", 32 | "favicon-dark.png", 33 | "package.json", 34 | "!.gitignore", 35 | "!tsconfig.json", 36 | "!biome.js" 37 | ], 38 | "author": "Johnkat MJ", 39 | "license": "MIT", 40 | "dependencies": { 41 | "@unifydev/preset-bg": "latest", 42 | "@unifydev/unify-variant": "latest" 43 | }, 44 | "devDependencies": { 45 | "@types/node": "^22.14.1", 46 | "rimraf": "^6.0.1", 47 | "ts-node": "^10.9.2", 48 | "typescript": "^5.8.3", 49 | "unbuild": "^3.5.0", 50 | "unocss": "^v66.0.0" 51 | }, 52 | "keywords": [ 53 | "Preset UI", 54 | "unify preset", 55 | "atomic ui library", 56 | "unocss ui", 57 | "theming ui library", 58 | "unocss components", 59 | "modern ui", 60 | "component library", 61 | "unify ui", 62 | "unifyui", 63 | "uno ui", 64 | "unoui", 65 | "unoforge" 66 | ], 67 | "repository": { 68 | "type": "git", 69 | "url": "https://github.com/unoforge/unify-preset" 70 | }, 71 | "bugs": { 72 | "url": "https://github.com/unoforge/unify-preset/issues" 73 | }, 74 | "gitHead": "1a4a3121332b2961338fd7920369d64ba3bab0e5" 75 | } 76 | -------------------------------------------------------------------------------- /packages/preset-ui/src/colors/genColor.ts: -------------------------------------------------------------------------------- 1 | import { uiColorFormat } from "@/types"; 2 | 3 | export const getBrice = (colorMode: uiColorFormat, value: string, colorPrefix?: string) => { 4 | const color_prefix = colorPrefix ? colorPrefix === '' || colorPrefix === "none" ? `--${value}` : `--${colorPrefix}-${value}` : `--c-${value}`; 5 | if (colorMode === "rgb") return `rgb(var(${color_prefix}), )` 6 | else if (colorMode === "hsl") return `hsl(var(${color_prefix}))` 7 | else return `oklch(var(${color_prefix}))` 8 | } 9 | export const genColorValue = (initialKey: string, colorMode: uiColorFormat, colorPrefix?: string) => { 10 | return { 11 | DEFAULT: getBrice(colorMode, `${initialKey}-DEFAULT`, colorPrefix), 12 | 50: getBrice(colorMode, `${initialKey}-50`, colorPrefix), 13 | 1: getBrice(colorMode, `${initialKey}-100`, colorPrefix), 14 | 2: getBrice(colorMode, `${initialKey}-200`, colorPrefix), 15 | 3: getBrice(colorMode, `${initialKey}-300`, colorPrefix), 16 | 4: getBrice(colorMode, `${initialKey}-400`, colorPrefix), 17 | 5: getBrice(colorMode, `${initialKey}-500`, colorPrefix), 18 | 6: getBrice(colorMode, `${initialKey}-600`, colorPrefix), 19 | 7: getBrice(colorMode, `${initialKey}-700`, colorPrefix), 20 | 8: getBrice(colorMode, `${initialKey}-800`, colorPrefix), 21 | 9: getBrice(colorMode, `${initialKey}-900`, colorPrefix), 22 | 100: getBrice(colorMode, `${initialKey}-100`, colorPrefix), 23 | 200: getBrice(colorMode, `${initialKey}-200`, colorPrefix), 24 | 300: getBrice(colorMode, `${initialKey}-300`, colorPrefix), 25 | 400: getBrice(colorMode, `${initialKey}-400`, colorPrefix), 26 | 500: getBrice(colorMode, `${initialKey}-500`, colorPrefix), 27 | 600: getBrice(colorMode, `${initialKey}-600`, colorPrefix), 28 | 700: getBrice(colorMode, `${initialKey}-700`, colorPrefix), 29 | 800: getBrice(colorMode, `${initialKey}-800`, colorPrefix), 30 | 900: getBrice(colorMode, `${initialKey}-900`, colorPrefix), 31 | 950: getBrice(colorMode, `${initialKey}-950`, colorPrefix) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/preset-ui/src/colors/getPreconfigColors.ts: -------------------------------------------------------------------------------- 1 | import { uiColorFormat } from "@/types" 2 | import { genColorValue } from "./genColor" 3 | export const themeColors = (colorMode: uiColorFormat, colorPrefix?: string) => { 4 | return { 5 | primary: genColorValue("primary", colorMode, colorPrefix), 6 | secondary: genColorValue("secondary", colorMode, colorPrefix), 7 | accent: genColorValue("accent", colorMode, colorPrefix), 8 | success: genColorValue("success", colorMode, colorPrefix), 9 | warning: genColorValue("warning", colorMode, colorPrefix), 10 | info: genColorValue("info", colorMode, colorPrefix), 11 | danger: genColorValue("danger", colorMode, colorPrefix), 12 | gray: genColorValue("gray", colorMode, colorPrefix), 13 | } 14 | } -------------------------------------------------------------------------------- /packages/preset-ui/src/css/default/base.css: -------------------------------------------------------------------------------- 1 | 2 | :root { 3 | /* Background colors */ 4 | --bg: var(--c-white); 5 | --bg-subtle: var(--c-gray-50); 6 | --bg-surface: var(--c-gray-100); 7 | --bg-muted: var(--c-gray-200); 8 | --bg-surface-elevated: var(--c-gray-300); 9 | 10 | /* Foreground colors */ 11 | --fg: var(--c-gray-700); 12 | --fg-muted: var(--c-gray-600); 13 | --fg-title: var(--c-gray-900); 14 | --fg-subtitle: var(--c-gray-800); 15 | 16 | /* Border colors */ 17 | --border: var(--c-gray-200); 18 | --border-subtle: var(--c-gray-50); 19 | --border-light: var(--c-gray-200); 20 | --border-strong: var(--c-gray-300); 21 | --border-emphasis: var(--c-gray-400); 22 | } 23 | 24 | .dark { 25 | /* Background colors */ 26 | --bg:var(--c-gray-950); 27 | --bg-subtle: var(--c-gray-900); 28 | --bg-surface: var(--c-gray-900); 29 | --bg-muted: var(--c-gray-800); 30 | --bg-surface-elevated: var(--c-gray-700); 31 | 32 | /* Foreground colors */ 33 | --fg-text: var(--c-gray-300); 34 | --fg-title: var(--c-white); 35 | --fg-subtitle: var(--c-gray-200); 36 | --fg-muted: var(--c-gray-300); 37 | --fg-light: var(--c-gray-400); 38 | 39 | /* Border colors */ 40 | --border: var(--c-gray-900); 41 | --border-light: var(--c-gray-800); 42 | --border-subtle: var(--c-gray-900); 43 | --border-strong: var(--c-gray-700); 44 | --border-emphasis: var(--c-gray-600); 45 | } -------------------------------------------------------------------------------- /packages/preset-ui/src/css/default/dark.css: -------------------------------------------------------------------------------- 1 | 2 | :root { 3 | /* Background colors */ 4 | --bg:var(--c-gray-950); 5 | --bg-subtle: var(--c-gray-900); 6 | --bg-surface: var(--c-gray-900); 7 | --bg-muted: var(--c-gray-800); 8 | --bg-surface-elevated: var(--c-gray-700); 9 | 10 | /* Foreground colors */ 11 | --fg-text: var(--c-gray-300); 12 | --fg-title: var(--c-white); 13 | --fg-subtitle: var(--c-gray-200); 14 | --fg-muted: var(--c-gray-300); 15 | --fg-light: var(--c-gray-400); 16 | 17 | /* Border colors */ 18 | --border: var(--c-gray-900); 19 | --border-light: var(--c-gray-800); 20 | --border-subtle: var(--c-gray-900); 21 | --border-strong: var(--c-gray-700); 22 | --border-emphasis: var(--c-gray-600); 23 | } -------------------------------------------------------------------------------- /packages/preset-ui/src/css/default/light.css: -------------------------------------------------------------------------------- 1 | 2 | :root { 3 | /* Background colors */ 4 | --bg: var(--c-white); 5 | --bg-subtle: var(--c-gray-50); 6 | --bg-surface: var(--c-gray-100); 7 | --bg-muted: var(--c-gray-200); 8 | --bg-surface-elevated: var(--c-gray-300); 9 | 10 | /* Foreground colors */ 11 | --fg: var(--c-gray-700); 12 | --fg-muted: var(--c-gray-600); 13 | --fg-title: var(--c-gray-900); 14 | --fg-subtitle: var(--c-gray-800); 15 | --border: var(--c-gray-200); 16 | 17 | /* Border colors */ 18 | --border-subtle: var(--c-gray-50); 19 | --border-light: var(--c-gray-200); 20 | --border-strong: var(--c-gray-300); 21 | --border-emphasis: var(--c-gray-400); 22 | } -------------------------------------------------------------------------------- /packages/preset-ui/src/css/themes/air.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --c-white: 0 0% 100%; 3 | --c-primary-50: 36 100% 94%; 4 | --c-primary-100: 36 100% 83%; 5 | --c-primary-200: 32 100% 71%; 6 | --c-primary-300: 25 100% 63%; 7 | --c-primary-400: 19 100% 58%; 8 | --c-primary-500: 16 100% 50%; 9 | --c-primary-600: 15 100% 48%; 10 | --c-primary-700: 14 100% 45%; 11 | --c-primary-800: 13 100% 42%; 12 | --c-primary-900: 12 100% 37%; 13 | --c-primary-950: 12 100% 27%; 14 | 15 | --c-secondary-50: 3 100% 97%; 16 | --c-secondary-100: 3 100% 94%; 17 | --c-secondary-200: 3 100% 89%; 18 | --c-secondary-300: 2 100% 81%; 19 | --c-secondary-400: 2 100% 70%; 20 | --c-secondary-500: 2 98% 60%; 21 | --c-secondary-600: 2 85% 47%; 22 | --c-secondary-700: 2 86% 42%; 23 | --c-secondary-800: 2 81% 35%; 24 | --c-secondary-900: 2 67% 31%; 25 | --c-secondary-950: 2 87% 15%; 26 | 27 | --c-danger-50: 0 86% 97%; 28 | --c-danger-100: 0 93% 94%; 29 | --c-danger-200: 0 96% 89%; 30 | --c-danger-300: 0 94% 82%; 31 | --c-danger-400: 0 91% 71%; 32 | --c-danger-500: 0 84% 60%; 33 | --c-danger-600: 0 72% 51%; 34 | --c-danger-700: 0 74% 42%; 35 | --c-danger-800: 0 70% 35%; 36 | --c-danger-900: 0 63% 31%; 37 | --c-danger-950: 0 75% 15%; 38 | 39 | --c-accent-50: 46 70% 95%; 40 | --c-accent-100: 45 67% 88%; 41 | --c-accent-200: 45 65% 77%; 42 | --c-accent-300: 42 74% 64%; 43 | --c-accent-400: 37 74% 53%; 44 | --c-accent-500: 39 65% 47%; 45 | --c-accent-600: 37 67% 40%; 46 | --c-accent-700: 36 64% 33%; 47 | --c-accent-800: 35 57% 29%; 48 | --c-accent-900: 34 51% 26%; 49 | --c-accent-950: 32 58% 14%; 50 | 51 | --c-warning-50: 33 100% 96%; 52 | --c-warning-100: 34 100% 92%; 53 | --c-warning-200: 32 98% 83%; 54 | --c-warning-300: 31 97% 72%; 55 | --c-warning-400: 27 96% 61%; 56 | --c-warning-500: 25 95% 53%; 57 | --c-warning-600: 21 90% 48%; 58 | --c-warning-700: 17 88% 40%; 59 | --c-warning-800: 15 79% 34%; 60 | --c-warning-900: 15 75% 28%; 61 | --c-warning-950: 17 82% 14%; 62 | 63 | --c-success-50: 151 81% 96%; 64 | --c-success-100: 149 80% 90%; 65 | --c-success-200: 152 76% 80%; 66 | --c-success-300: 156 72% 67%; 67 | --c-success-400: 158 64% 52%; 68 | --c-success-500: 160 84% 39%; 69 | --c-success-600: 161 94% 30%; 70 | --c-success-700: 163 94% 24%; 71 | --c-success-800: 163 88% 20%; 72 | --c-success-900: 164 86% 16%; 73 | --c-success-950: 167 91% 9%; 74 | 75 | --c-info-50: 204 100% 97%; 76 | --c-info-100: 204 94% 94%; 77 | --c-info-200: 201 94% 86%; 78 | --c-info-300: 199 95% 74%; 79 | --c-info-400: 198 93% 60%; 80 | --c-info-500: 199 89% 48%; 81 | --c-info-600: 200 98% 39%; 82 | --c-info-700: 201 96% 32%; 83 | --c-info-800: 201 90% 27%; 84 | --c-info-900: 202 80% 24%; 85 | --c-info-950: 204 80% 16%; 86 | 87 | --c-gray-50: 0 0% 98%; 88 | --c-gray-100: 0 0% 96%; 89 | --c-gray-200: 0 0% 90%; 90 | --c-gray-300: 0 0% 83%; 91 | --c-gray-400: 0 0% 64%; 92 | --c-gray-500: 0 0% 45%; 93 | --c-gray-600: 0 0% 32%; 94 | --c-gray-700: 0 0% 25%; 95 | --c-gray-800: 0 0% 15%; 96 | --c-gray-900: 0 0% 9%; 97 | --c-gray-950: 0 0% 4%; 98 | } -------------------------------------------------------------------------------- /packages/preset-ui/src/css/themes/default.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --c-white: 0 0% 100%; 3 | --c-primary-50: 252 100% 97%; 4 | --c-primary-100: 252 100% 94%; 5 | --c-primary-200: 251 98% 89%; 6 | --c-primary-300: 249 95% 82%; 7 | --c-primary-400: 247 90% 74%; 8 | --c-primary-500: 245 86% 67%; 9 | --c-primary-600: 243 75% 59%; 10 | --c-primary-700: 244 57% 51%; 11 | --c-primary-800: 245 54% 41%; 12 | --c-primary-900: 245 47% 35%; 13 | --c-primary-950: 246 47% 20%; 14 | 15 | --c-secondary-50: 183 100% 96%; 16 | --c-secondary-100: 185 96% 90%; 17 | --c-secondary-200: 186 93% 82%; 18 | --c-secondary-300: 187 92% 69%; 19 | --c-secondary-400: 188 86% 53%; 20 | --c-secondary-500: 187 97% 43%; 21 | --c-secondary-600: 187 92% 36%; 22 | --c-secondary-700: 188 78% 31%; 23 | --c-secondary-800: 201 90% 27%; 24 | --c-secondary-900: 190 56% 24%; 25 | --c-secondary-950: 192 79% 15%; 26 | 27 | --c-accent-50: 210 100% 97%; 28 | --c-accent-100: 209 92% 94%; 29 | --c-accent-200: 209 90% 86%; 30 | --c-accent-300: 209 89% 74%; 31 | --c-accent-400: 209 88% 60%; 32 | --c-accent-500: 208 84% 48%; 33 | --c-accent-600: 209 92% 36%; 34 | --c-accent-700: 210 90% 32%; 35 | --c-accent-800: 211 84% 27%; 36 | --c-accent-900: 212 75% 24%; 37 | --c-accent-950: 214 75% 16%; 38 | 39 | --c-success-50: 151 81% 96%; 40 | --c-success-100: 149 80% 90%; 41 | --c-success-200: 152 76% 80%; 42 | --c-success-300: 156 72% 67%; 43 | --c-success-400: 158 64% 52%; 44 | --c-success-500: 160 84% 39%; 45 | --c-success-600: 161 94% 30%; 46 | --c-success-700: 163 94% 24%; 47 | --c-success-800: 163 88% 20%; 48 | --c-success-900: 164 86% 16%; 49 | --c-success-950: 167 91% 9%; 50 | 51 | --c-warning-50: 33 100% 96%; 52 | --c-warning-100: 34 100% 92%; 53 | --c-warning-200: 32 98% 83%; 54 | --c-warning-300: 31 97% 72%; 55 | --c-warning-400: 27 96% 61%; 56 | --c-warning-500: 25 95% 53%; 57 | --c-warning-600: 21 90% 48%; 58 | --c-warning-700: 17 88% 40%; 59 | --c-warning-800: 15 79% 34%; 60 | --c-warning-900: 15 75% 28%; 61 | --c-warning-950: 17 82% 14%; 62 | 63 | --c-info-50: 204 100% 97%; 64 | --c-info-100: 204 94% 94%; 65 | --c-info-200: 201 94% 86%; 66 | --c-info-300: 199 95% 74%; 67 | --c-info-400: 198 93% 60%; 68 | --c-info-500: 199 89% 48%; 69 | --c-info-600: 200 98% 39%; 70 | --c-info-700: 201 96% 32%; 71 | --c-info-800: 201 90% 27%; 72 | --c-info-900: 202 80% 24%; 73 | --c-info-950: 204 80% 16%; 74 | 75 | --c-danger-50: 0 86% 97%; 76 | --c-danger-100: 0 93% 94%; 77 | --c-danger-200: 0 96% 89%; 78 | --c-danger-300: 0 94% 82%; 79 | --c-danger-400: 0 91% 71%; 80 | --c-danger-500: 0 84% 60%; 81 | --c-danger-600: 0 72% 51%; 82 | --c-danger-700: 0 74% 42%; 83 | --c-danger-800: 0 70% 35%; 84 | --c-danger-900: 0 63% 31%; 85 | --c-danger-950: 0 75% 15%; 86 | 87 | --c-gray-50: 0 0% 98%; 88 | --c-gray-100: 240 5% 96%; 89 | --c-gray-200: 240 6% 90%; 90 | --c-gray-300: 240 5% 84%; 91 | --c-gray-400: 240 5% 65%; 92 | --c-gray-500: 240 4% 46%; 93 | --c-gray-600: 240 5% 34%; 94 | --c-gray-700: 240 5% 26%; 95 | --c-gray-800: 240 4% 16%; 96 | --c-gray-900: 240 6% 10%; 97 | --c-gray-950: 240 10% 4%; 98 | } -------------------------------------------------------------------------------- /packages/preset-ui/src/css/themes/earth.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --c-white: 0 0% 100%; 3 | --c-primary-50: 140 42% 96%; 4 | --c-primary-100: 141 50% 90%; 5 | --c-primary-200: 145 39% 80%; 6 | --c-primary-300: 146 39% 67%; 7 | --c-primary-400: 147 37% 52%; 8 | --c-primary-500: 148 48% 35%; 9 | --c-primary-600: 149 54% 30%; 10 | --c-primary-700: 149 53% 24%; 11 | --c-primary-800: 150 51% 20%; 12 | --c-primary-900: 152 48% 16%; 13 | --c-primary-950: 153 52% 9%; 14 | 15 | --c-secondary-50: 46 70% 95%; 16 | --c-secondary-100: 45 67% 88%; 17 | --c-secondary-200: 45 65% 77%; 18 | --c-secondary-300: 42 74% 64%; 19 | --c-secondary-400: 37 74% 53%; 20 | --c-secondary-500: 39 65% 47%; 21 | --c-secondary-600: 37 67% 40%; 22 | --c-secondary-700: 36 64% 33%; 23 | --c-secondary-800: 35 57% 29%; 24 | --c-secondary-900: 34 51% 26%; 25 | --c-secondary-950: 32 58% 14%; 26 | 27 | --c-accent-50: 3 100% 97%; 28 | --c-accent-100: 3 100% 94%; 29 | --c-accent-200: 3 100% 89%; 30 | --c-accent-300: 2 100% 81%; 31 | --c-accent-400: 2 100% 70%; 32 | --c-accent-500: 2 98% 60%; 33 | --c-accent-600: 2 85% 47%; 34 | --c-accent-700: 2 86% 42%; 35 | --c-accent-800: 2 81% 35%; 36 | --c-accent-900: 2 67% 31%; 37 | --c-accent-950: 2 87% 15%; 38 | 39 | --c-warning-50: 46 87% 95%; 40 | --c-warning-100: 45 81% 89%; 41 | --c-warning-200: 45 77% 80%; 42 | --c-warning-300: 43 74% 67%; 43 | --c-warning-400: 43 70% 55%; 44 | --c-warning-500: 43 72% 44%; 45 | --c-warning-600: 43 76% 35%; 46 | --c-warning-700: 44 70% 27%; 47 | --c-warning-800: 45 62% 23%; 48 | --c-warning-900: 46 55% 20%; 49 | --c-warning-950: 46 72% 14%; 50 | 51 | --c-success-50: 151 81% 96%; 52 | --c-success-100: 149 80% 90%; 53 | --c-success-200: 152 76% 80%; 54 | --c-success-300: 156 72% 67%; 55 | --c-success-400: 158 64% 52%; 56 | --c-success-500: 160 84% 39%; 57 | --c-success-600: 161 94% 30%; 58 | --c-success-700: 163 94% 24%; 59 | --c-success-800: 163 88% 20%; 60 | --c-success-900: 164 86% 16%; 61 | --c-success-950: 167 91% 9%; 62 | 63 | --c-info-50: 210 30% 97%; 64 | --c-info-100: 210 29% 85%; 65 | --c-info-200: 210 30% 70%; 66 | --c-info-300: 208 28% 53%; 67 | --c-info-400: 210 50% 40%; 68 | --c-info-500: 210 100% 25%; 69 | --c-info-600: 210 100% 22%; 70 | --c-info-700: 210 100% 18%; 71 | --c-info-800: 210 100% 15%; 72 | --c-info-900: 210 100% 11%; 73 | --c-info-950: 210 100% 7%; 74 | 75 | --c-danger-50: 0 86% 97%; 76 | --c-danger-100: 0 93% 94%; 77 | --c-danger-200: 0 96% 89%; 78 | --c-danger-300: 0 94% 82%; 79 | --c-danger-400: 0 91% 71%; 80 | --c-danger-500: 0 84% 60%; 81 | --c-danger-600: 0 72% 51%; 82 | --c-danger-700: 0 74% 42%; 83 | --c-danger-800: 0 70% 35%; 84 | --c-danger-900: 0 63% 31%; 85 | --c-danger-950: 0 75% 15%; 86 | 87 | --c-gray-50: 195 38% 97%; 88 | --c-gray-100: 200 25% 95%; 89 | --c-gray-200: 200 20% 91%; 90 | --c-gray-300: 196 18% 80%; 91 | --c-gray-400: 200 11% 64%; 92 | --c-gray-500: 200 9% 47%; 93 | --c-gray-600: 200 12% 35%; 94 | --c-gray-700: 200 18% 27%; 95 | --c-gray-800: 204 22% 17%; 96 | --c-gray-900: 200 26% 8%; 97 | --c-gray-925: 200 29% 6%; 98 | --c-gray-950: 200 33% 1%; 99 | } -------------------------------------------------------------------------------- /packages/preset-ui/src/css/themes/fire.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --c-white: 0 0% 100%; 3 | --c-primary-50: 3 100% 97%; 4 | --c-primary-100: 3 100% 94%; 5 | --c-primary-200: 3 100% 89%; 6 | --c-primary-300: 2 100% 81%; 7 | --c-primary-400: 2 100% 70%; 8 | --c-primary-500: 2 98% 60%; 9 | --c-primary-600: 2 85% 47%; 10 | --c-primary-700: 2 86% 42%; 11 | --c-primary-800: 2 81% 35%; 12 | --c-primary-900: 2 67% 31%; 13 | --c-primary-950: 2 87% 15%; 14 | 15 | --c-secondary-50: 36 100% 94%; 16 | --c-secondary-100: 36 100% 83%; 17 | --c-secondary-200: 32 100% 71%; 18 | --c-secondary-300: 25 100% 63%; 19 | --c-secondary-400: 19 100% 58%; 20 | --c-secondary-500: 16 100% 50%; 21 | --c-secondary-600: 15 100% 48%; 22 | --c-secondary-700: 14 100% 45%; 23 | --c-secondary-800: 13 100% 42%; 24 | --c-secondary-900: 12 100% 37%; 25 | --c-secondary-950: 12 100% 27%; 26 | 27 | --c-accent-50: 210 100% 97%; 28 | --c-accent-100: 209 92% 94%; 29 | --c-accent-200: 209 90% 86%; 30 | --c-accent-300: 209 89% 74%; 31 | --c-accent-400: 209 88% 60%; 32 | --c-accent-500: 208 84% 48%; 33 | --c-accent-600: 209 92% 36%; 34 | --c-accent-700: 210 90% 32%; 35 | --c-accent-800: 211 84% 27%; 36 | --c-accent-900: 212 75% 24%; 37 | --c-accent-950: 214 75% 16%; 38 | 39 | --c-success-50: 151 81% 96%; 40 | --c-success-100: 149 80% 90%; 41 | --c-success-200: 152 76% 80%; 42 | --c-success-300: 156 72% 67%; 43 | --c-success-400: 158 64% 52%; 44 | --c-success-500: 160 84% 39%; 45 | --c-success-600: 161 94% 30%; 46 | --c-success-700: 163 94% 24%; 47 | --c-success-800: 163 88% 20%; 48 | --c-success-900: 164 86% 16%; 49 | --c-success-950: 167 91% 9%; 50 | 51 | --c-warning-50: 33 100% 96%; 52 | --c-warning-100: 34 100% 92%; 53 | --c-warning-200: 32 98% 83%; 54 | --c-warning-300: 31 97% 72%; 55 | --c-warning-400: 27 96% 61%; 56 | --c-warning-500: 25 95% 53%; 57 | --c-warning-600: 21 90% 48%; 58 | --c-warning-700: 17 88% 40%; 59 | --c-warning-800: 15 79% 34%; 60 | --c-warning-900: 15 75% 28%; 61 | --c-warning-950: 17 82% 14%; 62 | 63 | --c-info-50: 204 100% 97%; 64 | --c-info-100: 204 94% 94%; 65 | --c-info-200: 201 94% 86%; 66 | --c-info-300: 199 95% 74%; 67 | --c-info-400: 198 93% 60%; 68 | --c-info-500: 199 89% 48%; 69 | --c-info-600: 200 98% 39%; 70 | --c-info-700: 201 96% 32%; 71 | --c-info-800: 201 90% 27%; 72 | --c-info-900: 202 80% 24%; 73 | --c-info-950: 204 80% 16%; 74 | 75 | --c-danger-50: 0 86% 97%; 76 | --c-danger-100: 0 93% 94%; 77 | --c-danger-200: 0 96% 89%; 78 | --c-danger-300: 0 94% 82%; 79 | --c-danger-400: 0 91% 71%; 80 | --c-danger-500: 0 84% 60%; 81 | --c-danger-600: 0 72% 51%; 82 | --c-danger-700: 0 74% 42%; 83 | --c-danger-800: 0 70% 35%; 84 | --c-danger-900: 0 63% 31%; 85 | --c-danger-950: 0 75% 15%; 86 | 87 | --c-gray-50: 60 9% 98%; 88 | --c-gray-100: 60 5% 96%; 89 | --c-gray-200: 20 6% 90%; 90 | --c-gray-300: 24 6% 83%; 91 | --c-gray-400: 24 5% 64%; 92 | --c-gray-500: 25 5% 45%; 93 | --c-gray-600: 33 5% 32%; 94 | --c-gray-700: 30 6% 25%; 95 | --c-gray-800: 12 6% 15%; 96 | --c-gray-900: 24 10% 10%; 97 | --c-gray-950: 20 14% 4%; 98 | } -------------------------------------------------------------------------------- /packages/preset-ui/src/css/themes/water.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --c-white: 0 0% 100%; 3 | --c-primary-50: 213 36% 97%; 4 | --c-primary-100: 213 41% 94%; 5 | --c-primary-200: 213 54% 86%; 6 | --c-primary-300: 210 57% 74%; 7 | --c-primary-400: 208 56% 60%; 8 | --c-primary-500: 209 50% 48%; 9 | --c-primary-600: 210 55% 40%; 10 | --c-primary-700: 211 55% 32%; 11 | --c-primary-800: 212 52% 27%; 12 | --c-primary-900: 213 46% 24%; 13 | --c-primary-950: 214 46% 16%; 14 | 15 | --c-secondary-50: 166 76% 97%; 16 | --c-secondary-100: 167 85% 89%; 17 | --c-secondary-200: 168 84% 78%; 18 | --c-secondary-300: 171 77% 64%; 19 | --c-secondary-400: 172 66% 50%; 20 | --c-secondary-500: 173 80% 40%; 21 | --c-secondary-600: 175 84% 32%; 22 | --c-secondary-700: 175 77% 26%; 23 | --c-secondary-800: 176 69% 22%; 24 | --c-secondary-900: 176 61% 19%; 25 | --c-secondary-950: 180 84% 10%; 26 | 27 | --c-accent-50: 210 92% 97%; 28 | --c-accent-100: 209 88% 94%; 29 | --c-accent-200: 208 86% 86%; 30 | --c-accent-300: 208 86% 74%; 31 | --c-accent-400: 208 84% 60%; 32 | --c-accent-500: 208 79% 51%; 33 | --c-accent-600: 209 88% 39%; 34 | --c-accent-700: 210 87% 32%; 35 | --c-accent-800: 211 80% 27%; 36 | --c-accent-900: 212 72% 24%; 37 | --c-accent-950: 214 73% 16%; 38 | 39 | --c-success-50: 151 81% 96%; 40 | --c-success-100: 149 80% 90%; 41 | --c-success-200: 152 76% 80%; 42 | --c-success-300: 156 72% 67%; 43 | --c-success-400: 158 64% 52%; 44 | --c-success-500: 160 84% 39%; 45 | --c-success-600: 161 94% 30%; 46 | --c-success-700: 163 94% 24%; 47 | --c-success-800: 163 88% 20%; 48 | --c-success-900: 164 86% 16%; 49 | --c-success-950: 167 91% 9%; 50 | 51 | --c-warning-50: 33 100% 96%; 52 | --c-warning-100: 34 100% 92%; 53 | --c-warning-200: 32 98% 83%; 54 | --c-warning-300: 31 97% 72%; 55 | --c-warning-400: 27 96% 61%; 56 | --c-warning-500: 25 95% 53%; 57 | --c-warning-600: 21 90% 48%; 58 | --c-warning-700: 17 88% 40%; 59 | --c-warning-800: 15 79% 34%; 60 | --c-warning-900: 15 75% 28%; 61 | --c-warning-950: 17 82% 14%; 62 | 63 | --c-info-50: 204 100% 97%; 64 | --c-info-100: 204 94% 94%; 65 | --c-info-200: 201 94% 86%; 66 | --c-info-300: 199 95% 74%; 67 | --c-info-400: 198 93% 60%; 68 | --c-info-500: 199 89% 48%; 69 | --c-info-600: 200 98% 39%; 70 | --c-info-700: 201 96% 32%; 71 | --c-info-800: 201 90% 27%; 72 | --c-info-900: 202 80% 24%; 73 | --c-info-950: 204 80% 16%; 74 | 75 | --c-danger-50: 0 86% 97%; 76 | --c-danger-100: 0 93% 94%; 77 | --c-danger-200: 0 96% 89%; 78 | --c-danger-300: 0 94% 82%; 79 | --c-danger-400: 0 91% 71%; 80 | --c-danger-500: 0 84% 60%; 81 | --c-danger-600: 0 72% 51%; 82 | --c-danger-700: 0 74% 42%; 83 | --c-danger-800: 0 70% 35%; 84 | --c-danger-900: 0 63% 31%; 85 | --c-danger-950: 0 75% 15%; 86 | 87 | --c-gray-50: 210 20% 98%; 88 | --c-gray-100: 220 14% 96%; 89 | --c-gray-200: 220 13% 91%; 90 | --c-gray-300: 216 12% 84%; 91 | --c-gray-400: 218 11% 65%; 92 | --c-gray-500: 220 9% 46%; 93 | --c-gray-600: 215 14% 34%; 94 | --c-gray-700: 217 19% 27%; 95 | --c-gray-800: 215 28% 17%; 96 | --c-gray-900: 221 39% 11%; 97 | --c-gray-950: 224 71% 4%; 98 | } -------------------------------------------------------------------------------- /packages/preset-ui/src/index.ts: -------------------------------------------------------------------------------- 1 | import type { Preset } from "unocss"; 2 | import type { presetUiConfig, UiHelperConfig } from "./types"; 3 | import { getAllShortcut } from "./shortcuts/"; 4 | import { getAllRules } from "./rules"; 5 | import { getAllVariants } from "./variants"; 6 | import { theme } from "./ui-theme"; 7 | import { presetBg } from "@unifydev/preset-bg"; 8 | import { ThingsToExclude } from "./ui/type"; 9 | import { getAllUIShortcut } from "./ui"; 10 | import { getUiTheme } from "./ui-theme/ui"; 11 | 12 | 13 | function presetUIHelper(config?: UiHelperConfig): Preset { 14 | const colorFormat = config?.colorFormat || "hsl" 15 | const appearance = config?.appearance || "both" 16 | const varPrefix = config?.variablePrefix || "c" 17 | const excluded: ThingsToExclude | undefined = config?.exclude 18 | const shortcuts = getAllUIShortcut({ 19 | prefix: varPrefix, 20 | colorFormat, 21 | components: config?.components, 22 | appearance: appearance, 23 | exclude: excluded 24 | }); 25 | return { 26 | name: "preset-ui-helper", 27 | shortcuts, 28 | theme: getUiTheme(colorFormat, varPrefix) 29 | }; 30 | } 31 | 32 | 33 | /** 34 | * A preset for Unocss which provides the following features: 35 | * - Generate shortcuts for background, border, text color, and other styles 36 | * - Generate rules for flexbox, position, size, and other layout styles 37 | * - Generate variants for border radius, box shadow, and other styles 38 | * - Generate theme styles for colors 39 | * - Support for both light and dark appearances 40 | * @param config - An object with the following properties: 41 | * - colorFormat - The format of the color in the shortcut. Default is "hsl". 42 | * - appearance - The appearance of the theme. Default is "both". 43 | * - prefixDataStateVariant - The prefix of the data-state variant. Default is "fx". 44 | * - uiGen - An object with the following properties: 45 | * - exclude - An object with the key as variant name and the value as a boolean indicating whether to exclude the variant. Default is empty object. 46 | * - components 47 | */ 48 | function presetUI(config?: presetUiConfig): Preset { 49 | const colorFormat = config?.colorFormat || "hsl" 50 | const shortcuts = getAllShortcut({ 51 | colorFormat, 52 | components: config?.components, 53 | baseVariants: config?.baseVariants, 54 | appearance: config?.appearance || "both" 55 | }); 56 | 57 | const rules = getAllRules(colorFormat); 58 | const variants = getAllVariants(); 59 | 60 | const presets = [ 61 | presetBg(), 62 | presetUIHelper({ 63 | variablePrefix: config?.uiGen?.variablePrefix, 64 | colorFormat, 65 | appearance: config?.appearance, 66 | components: config?.uiGen?.components, 67 | exclude: config?.uiGen?.exclude 68 | }) 69 | ] 70 | 71 | return { 72 | name: "unify-preset", 73 | variants, 74 | shortcuts, 75 | rules, 76 | theme, 77 | presets 78 | }; 79 | } 80 | 81 | 82 | 83 | export { presetUI, type presetUiConfig, type UiHelperConfig }; 84 | -------------------------------------------------------------------------------- /packages/preset-ui/src/rules/const.ts: -------------------------------------------------------------------------------- 1 | export const progress_MeterHeightSize: Record = { 2 | xs: "0.25rem", 3 | sm: "0.375rem", 4 | md: "0.5rem", 5 | lg: "0.75rem", 6 | xl: "1rem", 7 | "2xl": "1.5rem", 8 | }; 9 | export const radius: Record = { 10 | none: "0px", 11 | sm: "0.125rem", 12 | md: "0.375rem", 13 | lg: "0.5rem", 14 | xl: "0.75rem", 15 | "2xl": "1rem", 16 | "3xl": "1.5rem", 17 | full: "9999px", 18 | }; 19 | 20 | export const rangeSizes = { 21 | xs: { 22 | mt: "0.125rem", 23 | size: "0.5rem", 24 | track: "0.25rem", 25 | }, 26 | sm: { 27 | mt: "3px", 28 | size: "0.75rem", 29 | track: "0.375rem", 30 | }, 31 | md: { 32 | mt: "0.25rem", 33 | size: "1rem", 34 | track: "0.5rem", 35 | }, 36 | lg: { 37 | mt: "0.375rem", 38 | size: "1.25rem", 39 | track: "0.625rem", 40 | }, 41 | xl: { 42 | mt: "0.375rem", 43 | size: "1.5rem", 44 | track: "0.75rem", 45 | }, 46 | }; 47 | 48 | -------------------------------------------------------------------------------- /packages/preset-ui/src/rules/types.ts: -------------------------------------------------------------------------------- 1 | export type variantSize = "xs" | "xl" | "sm" | "md" | "lg" | "xl"; 2 | export type BarShade = "light" | "gray" | "high" | "higher"; 3 | -------------------------------------------------------------------------------- /packages/preset-ui/src/rules/utils.ts: -------------------------------------------------------------------------------- 1 | import { 2 | progress_MeterHeightSize, 3 | radius, 4 | rangeSizes, 5 | } from "./const"; 6 | import type { variantSize } from "./types"; 7 | 8 | export const getRangeSize = (val: variantSize) => { 9 | return rangeSizes[val]; 10 | }; 11 | export const getSizeProgress_Meter = (val: string) => { 12 | return progress_MeterHeightSize[val]; 13 | }; 14 | 15 | export const getRadius = (val: string) => { 16 | return radius[val]; 17 | }; 18 | 19 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/accordion/const.ts: -------------------------------------------------------------------------------- 1 | import type { AccordionItemBordered, BaseDividerC } from "./types"; 2 | 3 | const defaultDividerGray: BaseDividerC = { 4 | shade: "200", 5 | dark: "800", 6 | }; 7 | 8 | const defaultDividerColor: BaseDividerC = { 9 | shade: "600", 10 | dark: "500", 11 | }; 12 | 13 | const itemWithBorderGray: AccordionItemBordered = { 14 | prefix: "border-b", 15 | border: { 16 | shade: "200", 17 | dark: { shade: "800" }, 18 | }, 19 | }; 20 | 21 | const itemWithBorder: AccordionItemBordered = { 22 | prefix: "border-b", 23 | border: { 24 | shade: "600", 25 | dark: { shade: "500" }, 26 | }, 27 | }; 28 | 29 | export const defaultAcValues = { 30 | defaultDividerGray, 31 | defaultDividerColor, 32 | itemWithBorderGray, 33 | itemWithBorder, 34 | }; 35 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/accordion/index.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | import { uiColorFormat } from "@/types"; 4 | import type { Shortcut } from "unocss"; 5 | import { getColorFormat } from "@/utils/colors-utils"; 6 | 7 | const getAccordionShortcuts = (colorFormat:uiColorFormat) => { 8 | 9 | const dynamicAccordions: Shortcut[] = [ 10 | [ 11 | /^accordion-wrapper-joined(-(\S+))?$/, 12 | ([, , color = "gray"]) => `divide-[var(--ui-accordion-divider-size,1px)] divide-[${getColorFormat(`--ui-accordion-divider-${color}`, colorFormat)}]`, 13 | { autocomplete: ["wrapper-joined", "wrapper-joined-$colors"] }, 14 | ], 15 | [ 16 | /^accordion-item-border-bottom(-(\S+))?$/, 17 | ([, , color = "gray"]) => `border-b-[${getColorFormat(`--ui-border-${color}`, colorFormat)}]`, 18 | { 19 | autocomplete: [ 20 | "accordion-item-border-bottom", 21 | "accordion-item-border-bottom-$colors", 22 | ], 23 | }, 24 | ], 25 | ]; 26 | 27 | return [...dynamicAccordions]; 28 | }; 29 | 30 | export { getAccordionShortcuts }; 31 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/aspect-ratio/index.ts: -------------------------------------------------------------------------------- 1 | const getAspectRatioShortcuts = () => { 2 | const aspectRatio = { 3 | "aspect-ultrawide": "aspect-[21/9]", 4 | "aspect-standard-tv": "aspect-[4/3]", 5 | "aspect-35mm-film": "aspect-[3/2]", 6 | }; 7 | return [aspectRatio]; 8 | }; 9 | 10 | export { getAspectRatioShortcuts }; 11 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/avatar/index.ts: -------------------------------------------------------------------------------- 1 | import { getConfigValue } from "@/utils"; 2 | 3 | import type { Avatar } from "./types"; 4 | 5 | const getAvatarShortcuts = ( 6 | avatar?: Avatar 7 | ) => { 8 | const { xs, sm, md, xl, lg } = Object.assign({}, { 9 | xs: 6.5, 10 | sm: 8, 11 | md: 9.5, 12 | lg: 10.5, 13 | xl: 12, 14 | }, avatar?.sizes); 15 | 16 | const avatars = { 17 | "avatar-fit-none": "object-none", 18 | "avatar-fit-fill": "object-fill", 19 | "avatar-fit-cover": "object-cover", 20 | "avatar-fit-contain": "object-contain", 21 | "avatar-fit-scale-down": "object-scale-down", 22 | "avatar-xs": `size-${getConfigValue(xs)}`, 23 | "avatar-sm": `size-${getConfigValue(sm)}`, 24 | "avatar-md": `size-${getConfigValue(md)}`, 25 | "avatar-lg": `size-${getConfigValue(lg)}`, 26 | "avatar-xl": `size-${getConfigValue(xl)}`, 27 | "avatar-placeholder": "flex items-center justify-center truncate", 28 | "avatar-placeholder-xs": `size-${getConfigValue(xs)} text-xs`, 29 | "avatar-placeholder-sm": `size-${getConfigValue(sm)} text-sm`, 30 | "avatar-placeholder-md": `size-${getConfigValue(md)} text-sm`, 31 | "avatar-placeholder-lg": `size-${getConfigValue(lg)} text-base`, 32 | "avatar-placeholder-xl": `size-${getConfigValue(xl)} text-base`, 33 | }; 34 | 35 | return [avatars]; 36 | }; 37 | export { getAvatarShortcuts, type Avatar }; 38 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/avatar/types.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | VariantSizeBoth, 3 | } from "@/types"; 4 | 5 | export type Avatar = { 6 | sizes?: VariantSizeBoth; 7 | }; 8 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/badge/index.ts: -------------------------------------------------------------------------------- 1 | import type { ElSizeBase } from "@/types"; 2 | import { uiSizeVariants, genUiSizes, } from "../helpers"; 3 | 4 | import type { Badge } from "./types"; 5 | 6 | const getBadgeShortcuts = ( 7 | badge?: Badge, 8 | ) => { 9 | const { xs, sm, md, xl, lg } = Object.assign({}, uiSizeVariants, badge?.sizes); 10 | 11 | const badges = { 12 | "badge-xs": `${genUiSizes(xs as ElSizeBase, "xs")}`, 13 | "badge-sm": `${genUiSizes(sm as ElSizeBase, "sm")}`, 14 | "badge-md": `${genUiSizes(md as ElSizeBase, "md")}`, 15 | "badge-lg": `${genUiSizes(lg as ElSizeBase, "lg")}`, 16 | "badge-xl": `${genUiSizes(xl as ElSizeBase, "xl")}`, 17 | }; 18 | return [badges]; 19 | }; 20 | 21 | export { getBadgeShortcuts, type Badge }; 22 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/badge/types.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | ElSizeVariants, 3 | } from "@/types"; 4 | 5 | export type Badge = { 6 | sizes?: ElSizeVariants; 7 | }; 8 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/button/baseHelpers.ts: -------------------------------------------------------------------------------- 1 | import { Appearance } from "@/types"; 2 | 3 | export const genBtnVariantFlat = () => `bg-[--btn-flat-bg] hover-bg-[--btn-flat-hover-bg] focus-visible-outline-[--btn-flat-hover-bg] active-bg-[--btn-flat-press] [--btn-focus-outline-color:--btn-flat-hover-bg]` 4 | 5 | export const genBtnVariantSolidBase = () => { 6 | return `bg-[--btn-solid-color] hover:bg-[--btn-solid-color-hover] 7 | active-bg-[--btn-solid-color-press] 8 | focus-visible-outline-[--btn-solid-color-hover] 9 | [background-image:radial-gradient(farthest-corner_at_50%_-50%,_rgba(255,_255,_255,_.1)_0%,_transparent_100%)] 10 | [box-shadow:inset_0px_2px_0_var(--btn-solid-top-shadow),_inset_0px_-2px_0_var(--btn-solid-bottom-shadow)] 11 | [--btn-focus-outline-color:--btn-solid-color-hover]` 12 | } 13 | 14 | 15 | export const genBtnVariantFlexiBase = () => { 16 | return `bg-[--btn-flexi-bg] shadow-[0_-1px_0_0px_var(--btn-flexi-shadow-a)_inset,0_0_0_1px_var(--btn-flexi-shadow-b)_inset,0_0.5px_0_1.5px_var(--btn-flexi-shadow-c)_inset] 17 | hover:bg-[--btn-flexi-bg-hover] 18 | active:bg-[--btn-flexi-bg-active] 19 | focus:bg-[--btn-flexi-bg-active] 20 | active:[--btn-flexi-shadow-a:var(--btn-flexi-shadow-active-a)] 21 | active:[--btn-flexi-shadow-b:var(--btn-flexi-shadow-active-b)] 22 | active:[--btn-flexi-shadow-c:var(--btn-flexi-shadow-active-c)] 23 | focus:[--btn-flexi-shadow-a:var(--btn-flexi-shadow-active-a)] 24 | focus:[--btn-flexi-shadow-b:var(--btn-flexi-shadow-active-b)] 25 | focus:[--btn-flexi-shadow-c:var(--btn-flexi-shadow-active-c)] 26 | [--btn-focus-outline-color:var(--btn-flexi-bg-hover)]`; 27 | }; 28 | 29 | export const genBtnOutlineBase = (appearance: Appearance) => { 30 | return `[background-image:radial-gradient(76%_151%_at_52%_-52%,rgba(255,255,255,var(--outline-radial-opacity))_0%,transparent_100%)] [box-shadow:rgba(255,255,255,var(--inner-border-color))_0px_1px_0px_0px_inset,var(--btn-outline-color)_0px_0px_0px_1px,0px_1px_2px_rgba(0,0,0,0.1)] hover:brightness-[0.98] active:brightness-100 bg-[--btn-outline-bg] 31 | hover:bg-[--btn-outline-bg-hover] active:bg-[--btn-outline-bg] 32 | text-[--btn-outline-text-color] focus-visible-outline-[--btn-outline-color-hover] 33 | ${appearance === "light" || appearance === "both" ? `[--outline-radial-opacity:0.6] [--inner-border-color:1]` : ''} 34 | ${appearance === "dark" ? `[background-image:none] [--outline-radial-opacity:0.2] [--inner-border-color:0]` : appearance === "both" ? 'dark-[background-image:none] dark-[--inner-border-color:0] dark-[--outline-radial-opacity:0.2]' : ''}` 35 | } 36 | 37 | export const genBtnSoftBase = ({ isGhost }: { isGhost: boolean }) => { 38 | const key = isGhost ? 'ghost' : 'soft' 39 | return ` 40 | ${isGhost ? 'bg-transparent' : 41 | `bg-[--btn-soft-bg-color]` 42 | } 43 | hover-bg-[--btn-${key}-bg-color-hover] 44 | active-bg-[--btn-${key}-bg-color-press] 45 | text-[--btn-${key}-text-color] 46 | hover-text-[var(--btn-${key}-text-color-hover,--btn-${key}-text-color)] 47 | active-text-[var(--btn-${key}-text-color-hover,--btn-${key}-text-color)] 48 | [--btn-focus-outline-color:--btn-${key}-text-color]` 49 | } 50 | 51 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/button/const.ts: -------------------------------------------------------------------------------- 1 | import type { RingBase } from "@/types"; 2 | import type { 3 | BtnIconSizes, 4 | BtnSizes, 5 | Button, 6 | } from "./types"; 7 | 8 | 9 | 10 | const btnSizes: BtnSizes = { 11 | xs: { 12 | height: 7, 13 | px: 3, 14 | textSize: "sm", 15 | }, 16 | sm: { 17 | height: 8, 18 | px: 3.5, 19 | textSize: "sm", 20 | }, 21 | md: { 22 | height: 9, 23 | px: 4, 24 | textSize: "base", 25 | }, 26 | lg: { 27 | height: 10, 28 | px: 5, 29 | textSize: "base", 30 | }, 31 | xl: { 32 | height: 12, 33 | px: 6, 34 | textSize: "lg", 35 | }, 36 | }; 37 | 38 | const btnIconSizes: BtnIconSizes = { 39 | xs: { 40 | size: 6, 41 | textSize: "sm", 42 | }, 43 | sm: { 44 | size: 8, 45 | textSize: "sm", 46 | }, 47 | md: { 48 | size: 9.5, 49 | textSize: "base", 50 | }, 51 | lg: { 52 | size: 10.5, 53 | textSize: "base", 54 | }, 55 | xl: { 56 | size: 12, 57 | textSize: "base", 58 | }, 59 | }; 60 | 61 | const ringBase: RingBase = { 62 | size: 2, 63 | offset: 2, 64 | }; 65 | 66 | 67 | export const btnCongig: Button = { 68 | sizes: btnSizes, 69 | iconSizes: btnIconSizes, 70 | ringBase, 71 | }; -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/button/index.ts: -------------------------------------------------------------------------------- 1 | import type { BtnIconBase, BtnSizeBase, Button } from "./types"; 2 | import { getConfigValue } from "@/utils"; 3 | import { btnCongig } from "./const"; 4 | 5 | import type { Appearance, SharedFormConfig } from "@/types"; 6 | import { genBtnOutlineBase, genBtnSoftBase, genBtnVariantFlexiBase, genBtnVariantSolidBase } from "./baseHelpers"; 7 | 8 | 9 | const getBtnSizeInfo = (sizeVariant: BtnSizeBase) => { 10 | return `h-${getConfigValue(sizeVariant?.height)} px-${getConfigValue( 11 | sizeVariant.px, 12 | )} text-${sizeVariant.textSize}`; 13 | }; 14 | const getBtnIconSizeInfo = (sizeVariant: BtnIconBase) => { 15 | return `truncate justify-center size-${getConfigValue( 16 | sizeVariant.size, 17 | )} text-${sizeVariant.textSize}`; 18 | }; 19 | 20 | const getBtnShortcuts = ({ 21 | button, 22 | formConfig, 23 | appearance 24 | }: { button?: Button; formConfig?: SharedFormConfig, appearance:Appearance }) => { 25 | const btn = Object.assign({}, btnCongig, button) 26 | 27 | const btnSizes = btn.sizes; 28 | const btnIconSizes = btn.iconSizes; 29 | 30 | 31 | const ringBase = Object.assign({}, formConfig?.ringBase, btn.ringBase) 32 | 33 | const btnOutlineOnFocus = () => 34 | `focus-visible-outline focus-visible-[outline-offset:var(--btn-focus-outline-offset,${ringBase.offset}px)] 35 | focus-visible-[outline-width:var(--btn-focus-outline-width,${ringBase.size}px)] 36 | focus-visible-[outline-color:var(--btn-focus-outline-color)]`; 37 | const btns = { 38 | btn: "flex items-center disabled-opacity-50 disabled-cursor-not-allowed disabled-hover-opacity-70 outline-0 outline-transparent", 39 | "btn-xs": `${getBtnSizeInfo(btnSizes?.xs as BtnSizeBase)}`, 40 | "btn-sm": `${getBtnSizeInfo(btnSizes?.sm as BtnSizeBase)}`, 41 | "btn-md": `${getBtnSizeInfo(btnSizes?.md as BtnSizeBase)}`, 42 | "btn-lg": `${getBtnSizeInfo(btnSizes?.lg as BtnSizeBase)}`, 43 | "btn-xl": `${getBtnSizeInfo(btnSizes?.xl as BtnSizeBase)}`, 44 | "btn-icon-xs": `${getBtnIconSizeInfo(btnIconSizes?.xs as BtnIconBase)}`, 45 | "btn-icon-sm": `${getBtnIconSizeInfo(btnIconSizes?.sm as BtnIconBase)}`, 46 | "btn-icon-md": `${getBtnIconSizeInfo(btnIconSizes?.md as BtnIconBase)}`, 47 | "btn-icon-lg": `${getBtnIconSizeInfo(btnIconSizes?.lg as BtnIconBase)}`, 48 | "btn-icon-xl": `${getBtnIconSizeInfo(btnIconSizes?.xl as BtnIconBase)}`, 49 | "btn-solid": `${genBtnVariantSolidBase()} ${btnOutlineOnFocus()}`, 50 | "btn-flexi": `${genBtnVariantFlexiBase()} ${btnOutlineOnFocus()}`, 51 | "btn-white": `${genBtnVariantFlexiBase()} ${btnOutlineOnFocus()}`, 52 | "btn-outline": `${genBtnOutlineBase(appearance)} ${btnOutlineOnFocus()}`, 53 | "btn-soft": `${genBtnSoftBase({ isGhost: false })} ${btnOutlineOnFocus()}`, 54 | "btn-ghost": `${genBtnSoftBase({ isGhost: true })} ${btnOutlineOnFocus()}`, 55 | "btn-cn":'bg-[var(--btn-cn-bg-color)] text-[var(--btn-cn-text-color)] shadow-xs hover:bg-[var(--btn-cn-bg-hover-color)] [--btn-focus-outline-color:--btn-cn-bg-hover-color]' 56 | }; 57 | 58 | 59 | return [btns]; 60 | }; 61 | 62 | export { getBtnShortcuts, type Button }; 63 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/button/types.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | TextSize, 3 | RingBase, 4 | } from "@/types"; 5 | 6 | 7 | 8 | export type BtnSizeBase = { 9 | height?: number | string; 10 | px?: number | string; 11 | textSize?: TextSize; 12 | }; 13 | 14 | export type BtnSizes = { 15 | xs?: BtnSizeBase; 16 | sm?: BtnSizeBase; 17 | md?: BtnSizeBase; 18 | lg?: BtnSizeBase; 19 | xl?: BtnSizeBase; 20 | }; 21 | 22 | export type BtnIconBase = { size?: number | string; textSize?: TextSize }; 23 | export type BtnIconSizes = { 24 | xs?: BtnIconBase; 25 | sm?: BtnIconBase; 26 | md?: BtnIconBase; 27 | lg?: BtnIconBase; 28 | xl?: BtnIconBase; 29 | }; 30 | 31 | export type Button = { 32 | ringBase?: RingBase; 33 | sizes?: BtnSizes; 34 | iconSizes?: BtnIconSizes; 35 | }; -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/checkbox/index.ts: -------------------------------------------------------------------------------- 1 | import { uiColorFormat } from "@/types"; 2 | import { getColorFormat } from "@/utils/colors-utils"; 3 | 4 | const getFormCheckboxShortcuts = (colorFormat: uiColorFormat) => { 5 | 6 | const baseUtilities = `disabled-op50 disabled-cursor-not-allowed outline-0 outline-transparent focus-visible:ring-1 focus-visible:ring-current focus:ring-0 focus:ring-transparent focus:ring-offset-transparent 7 | focus-visible:ring-offset-[${getColorFormat(`--ui-ring-bg`, colorFormat)}] 8 | focus-visible:ring-offset-2`; 9 | 10 | const checkbox = { 11 | "ui-form-checkbox": `${baseUtilities} bg-[${getColorFormat(`--ui-checkbox-bg`, colorFormat)}] b b-[${getColorFormat(`--ui-checkbox-border`, colorFormat)}] 12 | checked-bg-current checked-b-transparent 13 | checked:preset-internal-checkbox-icon 14 | indeterminate-bg-current indeterminate-b-transparent 15 | indeterminate:preset-internal-checkbox-indeterminate-icon 16 | indeterminate:[border-color:transparent] 17 | indeterminate:[background-color:currentColor] 18 | indeterminate:[background-size:100%_100%] 19 | indeterminate:[background-position:center] 20 | indeterminate:[background-repeat:no-repeat] 21 | 22 | ` 23 | } 24 | 25 | 26 | return [checkbox]; 27 | }; 28 | 29 | export { getFormCheckboxShortcuts }; 30 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/divider/index.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | const getDividerShortcuts = () => { 4 | const dividers = { 5 | "divider-custom": 6 | "relative before-absolute before-content-empty before-inset-x-0 flex items-center", 7 | "divider-custom-1": "before-h-px ", 8 | "divider-custom-2": "before-h-2px", 9 | "divider-custom-3": "before-h-3px", 10 | "divider-custom-4": "before-h-4px", 11 | "divider-custom-6": "before-h-6px", 12 | "divider-custom-8": "before-h-8px", 13 | }; 14 | 15 | return [dividers]; 16 | }; 17 | 18 | export { getDividerShortcuts }; 19 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/helpers/genSize.ts: -------------------------------------------------------------------------------- 1 | import { CardSizeBase, ElSizeBase, InputSizeBase, SizeVariantBase } from "@/types"; 2 | import { getConfigValue } from "@/utils"; 3 | 4 | 5 | 6 | const textSizes: Record = { 7 | '2xs': "0.75rem", 8 | xs: "0.75rem", 9 | sm: "1rem", 10 | md: "1rem", 11 | base:"1rem", 12 | lg: "1.125rem", 13 | xl: "1.25rem", 14 | '2xl': "1.5rem" 15 | } 16 | 17 | const convertSize = (size: number | string) => typeof size === 'number' ? `${size * 0.25}rem` : size 18 | 19 | export const genUiSizes = (size: ElSizeBase, val: SizeVariantBase) => `[padding:var(--ui-s-py-${val},${convertSize(size.py)})_var(--ui-s-px-${val},${convertSize(size.px)})] [font-size:var(--ui-s-text-${val},_${textSizes[size.textSize]})]` 20 | 21 | export const genInputSizes = (size: InputSizeBase, val: SizeVariantBase) => ` 22 | [padding-left:var(--ui-input-px-${val},${convertSize(size.px)})] 23 | [padding-right:var(--ui-input-px-${val},${convertSize(size.px)})] 24 | [height:var(--ui-input-height-${val},${convertSize(size.height)})] 25 | [font-size:var(--ui-input-text-${val},_${textSizes[size.textSize]})]` 26 | 27 | 28 | export const getUiCardSize = (sizeVariant: CardSizeBase) => `p-${getConfigValue(sizeVariant.padding)} text-${sizeVariant.textSize}`; 29 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/helpers/genTextColor.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | Appearance, 3 | BaseTypoColor, 4 | } from "@/types"; 5 | import { getShortcutsIfNotSame } from "@/utils"; 6 | 7 | export const genTextColor = ( 8 | appearance: Appearance, 9 | baseTypoColor: BaseTypoColor, 10 | ) => { 11 | const { light, dark } = baseTypoColor; 12 | const lightVar = ` 13 | ${ 14 | appearance === "light" || appearance === "both" ? `text-${light}` : "" 15 | } 16 | `; 17 | const darkVar = ` 18 | ${ 19 | appearance === "dark" 20 | ? `text-${dark}` 21 | : appearance === "both" 22 | ? ` 23 | ${getShortcutsIfNotSame({ 24 | val1: light, 25 | val2: dark, 26 | shortcuts: `dark-text-${dark}`, 27 | })}` 28 | : "" 29 | } 30 | `; 31 | return `${lightVar} ${darkVar}`; 32 | }; -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/helpers/helper-const.ts: -------------------------------------------------------------------------------- 1 | import type { RingBase, ElSizeVariants, CardSizeVariant, TextTypos, } from "@/types"; 2 | 3 | 4 | export const uiSizeVariants: ElSizeVariants = { 5 | xs: { py: 0.5, px: 1, textSize: "xs" }, 6 | sm: { py: 0.65, px: 1.5, textSize: "xs" }, 7 | md: { py: 1, px: 2, textSize: "sm" }, 8 | lg: { py: 1.115, px: 2.5, textSize: "base" }, 9 | xl: { py: 1.3, px: 3, textSize: "base" }, 10 | } 11 | 12 | export const cardSizeVariants: CardSizeVariant = { 13 | xs: { padding: 2.5, textSize: "xs" }, 14 | sm: { padding: 3, textSize: "sm" }, 15 | md: { padding: 4, textSize: "base" }, 16 | lg: { padding: 6, textSize: "base" }, 17 | xl: { padding: 8, textSize: "base" }, 18 | } 19 | 20 | 21 | 22 | 23 | const ringBase: RingBase = { 24 | size: 2, 25 | offset: 2, 26 | }; 27 | 28 | 29 | const textTypo: TextTypos = { 30 | "x-body": "text-10px", 31 | "xs-body": "text-xs", 32 | body: "text-base", 33 | "x-title": "text-lg sm-text-xl md-text-2xl", 34 | title: "text-3xl sm-text-4xl/snug lg-text-5xl", 35 | "l-title": "text-3xl/tight md-text-4xl/tight xl-text-5xl/tight", 36 | "xl-title": "text-3xl/tight lg-text-4xl/tight xl-text-5xl/tight", 37 | '2xl-title': "text-3xl/tight md-text-4xl/tight xl-text-6xl/tight" 38 | } 39 | 40 | export const helperDefaultValues = { 41 | ringBase, 42 | textTypo 43 | }; -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/helpers/index.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | export * from "./helper-const"; 4 | export * from "./genSize" 5 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/index.ts: -------------------------------------------------------------------------------- 1 | import type { Preset, StaticShortcutMap } from "unocss"; 2 | import type { Components } from "./types"; 3 | import { getBtnShortcuts } from "./button"; 4 | import { getBadgeShortcuts } from "./badge"; 5 | import type { Appearance, SharedFormConfig, uiColorFormat, } from "../types"; 6 | import { getAspectRatioShortcuts } from "./aspect-ratio"; 7 | import { getAvatarShortcuts } from "./avatar"; 8 | import { getGeneralShortcuts } from "./utilities"; 9 | import { getDividerShortcuts } from "./divider"; 10 | import { getFormInputShortcuts } from "./input"; 11 | import { getKdbShortcuts } from "./kbd"; 12 | import { getAccordionShortcuts } from "./accordion"; 13 | import { getFormCheckboxShortcuts } from "./checkbox"; 14 | import { getFormRadioShortcuts } from "./radio"; 15 | import { getMeterShortcuts } from "./meter"; 16 | import { getRangeSlideShortcuts } from "./range"; 17 | import { getProgressBarShortcuts } from "./progress"; 18 | import { getSwitchShortcuts } from "./switch"; 19 | import { getUiShortcuts } from "./ui"; 20 | import type { BaseVariants } from "./ui/types"; 21 | 22 | export const getAllShortcut = ({ 23 | components, 24 | form, 25 | baseVariants, 26 | colorFormat, 27 | appearance 28 | }: { 29 | components?: Components; 30 | baseVariants?: BaseVariants, 31 | form?: SharedFormConfig; 32 | colorFormat: uiColorFormat; 33 | appearance:Appearance 34 | }) => { 35 | const generalShortcuts = getGeneralShortcuts(); 36 | 37 | const button = getBtnShortcuts({ 38 | button: components?.button, 39 | formConfig: form, 40 | appearance 41 | }); 42 | const badge = getBadgeShortcuts(components?.badge); 43 | 44 | const accordion = getAccordionShortcuts(colorFormat); 45 | const aspectRatio = getAspectRatioShortcuts(); 46 | const avatar = getAvatarShortcuts(components?.avatar); 47 | const checkbox = getFormCheckboxShortcuts(colorFormat); 48 | const divider = getDividerShortcuts(); 49 | 50 | const inputForm = getFormInputShortcuts({ 51 | input: components?.input, 52 | colorFormat 53 | }); 54 | const kbd = getKdbShortcuts({ kdb: components?.kbd, colorFormat}); 55 | 56 | const meter = getMeterShortcuts(); 57 | const progress = getProgressBarShortcuts(); 58 | const radio = getFormRadioShortcuts(colorFormat); 59 | const range = getRangeSlideShortcuts(); 60 | const switchShortcuts = getSwitchShortcuts(); 61 | 62 | const uiShortcuts = getUiShortcuts(baseVariants) 63 | const shortcuts = [ 64 | ...generalShortcuts, 65 | ...accordion, 66 | ...aspectRatio, 67 | ...avatar, 68 | ...badge, 69 | ...button, 70 | ...checkbox, 71 | ...divider, 72 | ...inputForm, 73 | ...kbd, 74 | ...meter, 75 | ...progress, 76 | ...radio, 77 | ...range, 78 | ...switchShortcuts, 79 | ...uiShortcuts 80 | ] as Exclude; 81 | return shortcuts; 82 | }; 83 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/input/const.ts: -------------------------------------------------------------------------------- 1 | import type { InputSizeVariant, RingBase } from "@/types"; 2 | 3 | export const defRingBase: RingBase = { 4 | size: 2, 5 | offset: 6, 6 | }; 7 | 8 | export const InputSizes: InputSizeVariant = { 9 | "2xs": { 10 | px: 2, 11 | textSize: "xs", 12 | height:7.5 13 | }, 14 | xs: { 15 | px: 2.5, 16 | textSize: "xs", 17 | height:7 18 | }, 19 | sm: { 20 | px: 2.5, 21 | textSize: "sm", 22 | height:8 23 | }, 24 | md: { 25 | px: 3, 26 | textSize: "sm", 27 | height:9 28 | }, 29 | lg: { 30 | px: 4, 31 | textSize: "sm", 32 | height:10 33 | }, 34 | xl: { 35 | px: 5, 36 | textSize: "base", 37 | height:12 38 | }, 39 | } -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/input/index.ts: -------------------------------------------------------------------------------- 1 | import type { InputSizeBase, uiColorFormat } from "@/types"; 2 | import { InputSizes } from "./const"; 3 | import type { Input } from "./types"; 4 | import { genInputSizes } from "../helpers"; 5 | import { getColorFormat } from "@/utils/colors-utils"; 6 | 7 | 8 | const getFormInputShortcuts = ({ 9 | input, 10 | colorFormat 11 | }: { input?: Input, colorFormat: uiColorFormat }) => { 12 | 13 | const size = input?.size || InputSizes 14 | const _2xs = size["2xs"] 15 | const xs = size.xs; 16 | const sm = size.sm; 17 | const md = size.md; 18 | const lg = size.lg; 19 | const xl = size.xl; 20 | 21 | const borderFocus = `outline-offset-0 focus-outline focus-outline-offset-0 focus-border-transparent focus-outline-2 focus-outline-[${getColorFormat('--ui-input-focus-outline', colorFormat)}]`; 22 | 23 | const inputs = { 24 | 'ui-form-input': `${borderFocus} disabled:hover:cursor-not-allowed disabled:opacity-80`, 25 | "ui-form-input-2xs": `${genInputSizes(_2xs as InputSizeBase, "2xs")}`, 26 | "ui-form-input-xs": `${genInputSizes(xs as InputSizeBase, "xs")}`, 27 | "ui-form-input-sm": `${genInputSizes(sm as InputSizeBase, "sm")}`, 28 | "ui-form-input-md": `${genInputSizes(md as InputSizeBase, "md")}`, 29 | "ui-form-input-lg": `${genInputSizes(lg as InputSizeBase, "lg")}`, 30 | "ui-form-input-xl": `${genInputSizes(xl as InputSizeBase, "xl")}`, 31 | 'ui-form-base': `appearance-none wfull placeholder-[color:${getColorFormat('--ui-input-place-holder', colorFormat)}] invalid:[outline-color:${getColorFormat('--ui-input-invalid-outline', colorFormat)}] 32 | [line-height:1.5rem] 33 | `, 34 | 'ui-form-select': ` [background-position:right_0.5rem_center] 35 | [background-repeat:no-repeat] [background-size:1.5em_1.5em] 36 | [padding-right:2.5rem] [print-color-adjust:exact] 37 | preset-internal-select-icon`, 38 | 'ui-form-multiselect': `[background-image:unset] [background-position:unset] [background-repeat:unset] [background-size:unset] [padding-right:0.75rem] [print-color-adjust:unset]`, 39 | 'ui-checkbox-radio-base': `appearance-none p-0 [print-color-adjust:exact] 40 | [display:inline-block] [vertical-align:middle] 41 | [background-origin:border-box] [user-select:none] [flex-shrink:0] 42 | [--un-shadow:0_0_#0000] focus-outline-2 43 | focus-outline-offset-2 44 | focus-[outline-color:var(--check-radio-offset-color,currentColor)] 45 | focus-ring-0 focus-ring-transparent 46 | checked-focus-[background-color:currentColor] 47 | 48 | checked-hover-[border-color:transparent] 49 | [border-color:transparent] 50 | [background-color:currentColor] 51 | [background-size:100%_100%] 52 | [background-position:center] 53 | [background-repeat:no-repeat]` 54 | }; 55 | 56 | return [inputs]; 57 | }; 58 | 59 | export { getFormInputShortcuts, type Input }; 60 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/input/types.ts: -------------------------------------------------------------------------------- 1 | import type { ElSizeVariants } from "@/types"; 2 | 3 | export type Input = { 4 | size?: ElSizeVariants; 5 | }; 6 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/kbd/index.ts: -------------------------------------------------------------------------------- 1 | import { getConfigValue } from "@/utils"; 2 | import { 3 | uiSizeVariants 4 | } from "../helpers"; 5 | import type { Kbd } from "./types"; 6 | import { uiColorFormat } from "@/types"; 7 | import { getColorFormat } from "@/utils/colors-utils"; 8 | 9 | const getKdbShortcuts = ({ 10 | kdb: kbd, colorFormat 11 | }: { kdb?: Kbd, colorFormat: uiColorFormat }) => { 12 | const { xs, sm, md, xl, lg } = Object.assign({}, uiSizeVariants, kbd?.sizes); 13 | 14 | const kbds = { 15 | "kbd-xs": `py-${getConfigValue(xs?.py)} px-${getConfigValue(xs?.px)} text-${xs?.textSize}`, 16 | "kbd-sm": `py-${getConfigValue(sm?.py)} px-${getConfigValue(sm?.px)} text-${sm?.textSize}`, 17 | "kbd-md": `py-${getConfigValue(md?.py)} px-${getConfigValue(md?.px)} text-${md?.textSize}`, 18 | "kbd-lg": `py-${getConfigValue(lg?.py)} px-${getConfigValue(lg?.px)} text-${lg?.textSize}`, 19 | "kbd-xl": `py-${getConfigValue(xl?.py)} px-${getConfigValue(xl?.px)} text-${xl?.textSize}`, 20 | "kbd-outer-shadow": `bg-[${getColorFormat('--bg-body',colorFormat)}] border border-[${getColorFormat('--ui-kbd-outer-border',colorFormat)}] shadow-outer`, 21 | }; 22 | 23 | 24 | return [kbds]; 25 | }; 26 | 27 | export { getKdbShortcuts, type Kbd }; 28 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/kbd/types.ts: -------------------------------------------------------------------------------- 1 | import type { 2 | ElSizeVariants, 3 | } from "@/types"; 4 | 5 | export type Kbd = { 6 | sizes?: ElSizeVariants; 7 | }; 8 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/meter/index.ts: -------------------------------------------------------------------------------- 1 | const getMeterShortcuts = () => { 2 | const meters = { 3 | 'ui-meter': `block h-[--metter-bar-height] w-full moz-meter-bar:moz-meter overflow-y-hidden rounded-[--metter-bar-radius] bg-none 4 | metter-bar:h-[--metter-bar-height] metter-bar:border-none metter-bar:bg-transparent metter-bar:bg-none 5 | meter-inner-el:relative meter-inner-el:block meter-optimum-val:h-[--metter-bar-height] 6 | meter-optimum-val:rounded-[--metter-bar-radius] meter-optimum-val:border-none meter-optimum-val:bg-current 7 | meter-optimum-val:bg-none meter-optimum-val:transition-all`, 8 | }; 9 | return [meters]; 10 | }; 11 | 12 | export { getMeterShortcuts }; 13 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/progress/index.ts: -------------------------------------------------------------------------------- 1 | const getProgressBarShortcuts = () => { 2 | const progress = { 3 | "ui-progress-bar": `appearance-none w-full h-[--progressbar-height] 4 | w-progress-bar:w-full 5 | w-progress-bar:rounded-[--progress-bar-radius] 6 | w-progress-bar:bg-[--progress-bar-bg] w-progress-value:bg-current 7 | w-progress-value:rounded-[--progress-bar-radius] 8 | w-progress-value:ease-linear w-progress-value:transition-all moz-progress-bar`, 9 | "ui-progress-bar-indeterminate": ` indeterminate:relative 10 | indeterminate:z-10 11 | indeterminate:w-full 12 | indeterminate:overflow-hidden 13 | indeterminate:after:rounded-full 14 | indeterminate:after:absolute 15 | indeterminate:after:content-empty 16 | indeterminate:after:inset-y-0 17 | indeterminate:after:flex 18 | indeterminate:after:w-52 19 | indeterminate:after:bg-red600 20 | w-indeterminate-p-value:w-full 21 | w-indeterminate-p-value:h-full 22 | `, 23 | 24 | "ui-progress-bar-indeterminate-marquee": "indeterminate:after:animate-marquee", 25 | "ui-progress-bar-indeterminate-carousel": 26 | "indeterminate:after:animate-carousel", 27 | "ui-progress-bar-indeterminate-swing": "indeterminate:after:animate-swing", 28 | }; 29 | 30 | return [progress]; 31 | }; 32 | 33 | export { getProgressBarShortcuts }; 34 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/radio/helper.ts: -------------------------------------------------------------------------------- 1 | import type { Appearance } from "@/types"; 2 | 3 | export const getRadioBase = (appearance: Appearance, color: string) => { 4 | const lightV = `${ 5 | appearance === "light" || appearance === "both" 6 | ? `bg-white b b-gray-200 text-${color}-600` 7 | : "" 8 | }`; 9 | 10 | const darkV = `${ 11 | appearance === "dark" 12 | ? `text-${color}-600 checked-bg-current checked-b-transparent indeterminate-bg-current indeterminate-b-transparent b bg-gray-950 b-gray-800` 13 | : appearance === "both" 14 | ? `dark-text-${color}-600 dark-checked-bg-current dark-checked-b-transparent dark-indeterminate-bg-current dark-indeterminate-b-transparent dark-bg-gray-950 dark-b-gray-800` 15 | : "" 16 | }`; 17 | 18 | return `${lightV} ${darkV}`; 19 | }; 20 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/radio/index.ts: -------------------------------------------------------------------------------- 1 | import { uiColorFormat } from "@/types"; 2 | import { getColorFormat } from "@/utils/colors-utils"; 3 | 4 | const getFormRadioShortcuts = (colorFormat:uiColorFormat) => { 5 | 6 | const baseUtilities = `disabled-op50 disabled-cursor-not-allowed outline-0 outline-transparent 7 | focus-visible:ring-2 focus-visible:ring-current focus:ring-0 focus:ring-transparent focus:ring-offset-transparent 8 | focus-visible:ring-offset-[${getColorFormat('--ui-radio-bg',colorFormat)}] 9 | focus-visible:ring-offset-2`; 10 | 11 | const radio ={ 12 | "ui-form-radio":`${baseUtilities} checked-bg-current checked-b-transparent 13 | indeterminate-bg-current indeterminate-b-transparent 14 | checked:preset-internal-radio-icon 15 | 16 | `, 17 | } 18 | 19 | 20 | return [radio]; 21 | }; 22 | 23 | export { getFormRadioShortcuts }; 24 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/range/index.ts: -------------------------------------------------------------------------------- 1 | 2 | const getRangeSlideShortcuts = () => { 3 | const ranges = { 4 | "moz-range-slide-thumb": 5 | `relative z-[1] appearance-none rounded-full ring-2 ring-current size-[--ui-range-thumb-size] 6 | mt-[calc(var(--ui-range-mt)*-1)] border-0 bg-[--ui-range-thumb-bg]`, 7 | "moz-range-slide-track": 8 | `group-disabled:bg-opacity-50 bg-[--ui-range-track-bg] h-[--ui-range-track-height] rounded-lg`, 9 | 'ui-input-range': `w-full absolute appearance-none bg-transparent 10 | disabled:cursor-not-allowed disabled:opacity-50 11 | range-slider-thumb:ring-2 12 | range-slider-thumb:ring-current 13 | range-slider-thumb:bg-[--ui-range-thumb-bg] 14 | range-slider-thumb:size-[--ui-range-thumb-size] 15 | range-slider-thumb:mt-[calc(var(--ui-range-mt)*-1)] 16 | range-slider-thumb:appearance-none range-slider-thumb:rounded-full 17 | range-slider-thumb:relative 18 | range-slider-thumb:z-[1] 19 | slider-runnable-track:text-current 20 | slider-runnable-track:group-disabled:bg-opacity-60 21 | slider-runnable-track:rounded-lg 22 | slider-runnable-track:bg-[--ui-range-track-bg] 23 | slider-runnable-track:h-[--ui-range-track-height] 24 | moz-range-thumb:moz-range-slide-thumb 25 | moz-range-track:moz-range-slide-track outline-0 outline-transparent focus-visible-outline focus-visible:outline-2 focus-visible:outline-current outline-transparent 26 | focus-visible:outline-offset-2`, 27 | }; 28 | return [ranges]; 29 | }; 30 | export { getRangeSlideShortcuts }; 31 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/shortcut_helper.ts: -------------------------------------------------------------------------------- 1 | export const getBackgroundOpacity = (opacity?: number) => 2 | typeof opacity === "number" ? `/${opacity}` : ""; 3 | 4 | export const getRealOpacityValue = (opacity: number) => typeof opacity === 'number' ? `${opacity / 100}` : '1'; 5 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/switch/const.ts: -------------------------------------------------------------------------------- 1 | 2 | // Extra Small (xs) 3 | const xs = { 4 | width: '2.25rem', 5 | height: '1.25rem', 6 | knob: { 7 | size: '1rem', 8 | left: '0.125rem', // initial position 9 | top: '0.125rem', 10 | checkedLeft: '1.125rem' // position when checked 11 | } 12 | }; 13 | 14 | // Small (sm) 15 | const sm = { 16 | width: '2.5rem', 17 | height: '1.5rem', 18 | knob: { 19 | // The class "before:size-5" in Tailwind usually corresponds to 1.25rem 20 | size: '1.25rem', 21 | left: '0.125rem', 22 | top: '0.125rem', 23 | checkedLeft: '1.125rem' 24 | } 25 | }; 26 | 27 | // Medium (md) 28 | const md = { 29 | width: '3rem', 30 | height: '1.75rem', 31 | knob: { 32 | size: '1.25rem', 33 | left: '0.25rem', 34 | top: '0.25rem', 35 | checkedLeft: '1.5rem' 36 | } 37 | }; 38 | 39 | // Large (lg) 40 | const lg = { 41 | width: '3.5rem', 42 | height: '2rem', 43 | knob: { 44 | size: '1.5rem', 45 | left: '0.25rem', 46 | top: '0.25rem', 47 | checkedLeft: '1.75rem' 48 | } 49 | }; 50 | 51 | export const switchSizeVariants = { 52 | xs, 53 | sm, 54 | md, 55 | lg, 56 | }; 57 | 58 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/switch/index.ts: -------------------------------------------------------------------------------- 1 | 2 | import { switchSizeVariants } from "./const"; 3 | 4 | 5 | 6 | const getSwitch = (size: "xs" | "sm" | "md" | "lg") => { 7 | const switchSize = switchSizeVariants[size] 8 | return `[--toggle-width:var(--ui-switch-${size}-w,${switchSize.width})] 9 | [--toggle-height:var(--ui-switch-${size}-h,${switchSize.height})] 10 | [--knob-size:var(--ui-switch-${size}-knob-size,${switchSize.knob.size})] 11 | [--knob-left:var(--ui-switch-${size}-knob-left,${switchSize.knob.left})] 12 | [--knob-top:var(--ui-switch-${size}-knob-top,${switchSize.knob.top})] 13 | [--knob-checked-left:var(--ui-switch-${size}-knob-checked-left,${switchSize.knob.checkedLeft})] 14 | ` 15 | } 16 | 17 | const getSwitchOutline = (size: "xs" | "sm" | "md" | "lg") => { 18 | const switchSize = switchSizeVariants[size] 19 | return `[--toggle-width:var(--ui-switch-${size}-w,${switchSize.width})] 20 | [--toggle-height:var(--ui-switch-${size}-h,${switchSize.height})] 21 | [--knob-size:var(--ui-switch-${size}-knob-size,${switchSize.knob.size})] 22 | [--knob-left:calc(var(--ui-switch-${size}-knob-left,${switchSize.knob.left})_-_var(--switch-border-width))] 23 | [--knob-top:calc(var(--ui-switch-${size}-knob-top,${switchSize.knob.top})_-_var(--switch-border-width))] 24 | [--knob-checked-left:calc(var(--ui-switch-${size}-knob-checked-left,${switchSize.knob.checkedLeft})_-_var(--switch-border-width))] 25 | ` 26 | } 27 | const getSwitchShortcuts = () => { 28 | const switchs = { 29 | switch: `appearance-none cursor-pointer w-[--toggle-width] h-[--toggle-height] rounded-[var(--toggle-radius,9999px)] 30 | relative before:absolute before:w-[var(--knob-width,var(--knob-size))] before:h-[var(--knob-height,var(--knob-size))] before:content-empty 31 | before:bg-[--knob-bg] before:rounded-[var(--knob-radius,9999px)] ease-linear transition-all duration-300 32 | before:left-[--knob-left] before:top-[--knob-top] checked:before:left-[--knob-checked-left] before:ease-linear 33 | before:transition-all before:duration-300 disabled:opacity-70 disabled:cursor-not-allowed 34 | checked:bg-current checked:before:bg-[var(--knob-bg-checked,var(--knob-bg))]`, 35 | 36 | 'switch-outline': `appearance-none 37 | [--switch-border-width:var(--ui-switch-border-width,1px)] [border-style:solid] [border-width:var(--switch-border-width)] 38 | cursor-pointer w-[--toggle-width] h-[--toggle-height] rounded-[var(--toggle-radius,9999px)] 39 | relative before:absolute before:w-[var(--knob-width,var(--knob-size))] before:h-[var(--knob-height,var(--knob-size))] before:content-empty 40 | before:bg-[--knob-bg] before:rounded-[var(--knob-radius,9999px)] ease-linear transition-all duration-300 41 | before:left-[--knob-left] before:top-[--knob-top] checked:before:left-[--knob-checked-left] before:ease-linear 42 | before:transition-all before:duration-300 disabled:opacity-70 disabled:cursor-not-allowed 43 | checked:bg-current checked:before:bg-[var(--knob-bg-checked,var(--knob-bg))]`, 44 | 45 | "switch-xs": `${getSwitch("xs")}`, 46 | "switch-sm": `${getSwitch("sm")}`, 47 | "switch-md": `${getSwitch("md")}`, 48 | "switch-lg": `${getSwitch("lg")}`, 49 | 50 | "switch-outline-xs": `${getSwitchOutline("xs")}`, 51 | "switch-outline-sm": `${getSwitchOutline("sm")}`, 52 | "switch-outline-md": `${getSwitchOutline("md")}`, 53 | "switch-outline-lg": `${getSwitchOutline("lg")}` 54 | }; 55 | 56 | return [switchs]; 57 | }; 58 | export { getSwitchShortcuts }; 59 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/types.ts: -------------------------------------------------------------------------------- 1 | 2 | import type { Avatar } from "./avatar"; 3 | import type { Badge } from "./badge/"; 4 | import type { Button } from "./button/"; 5 | import type { Input } from "./input"; 6 | import type { Kbd } from "./kbd"; 7 | 8 | export type Components = { 9 | avatar?: Avatar; 10 | badge?: Badge; 11 | button?: Button; 12 | input?: Input; 13 | kbd?: Kbd; 14 | }; 15 | -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/ui/index.ts: -------------------------------------------------------------------------------- 1 | import type { SizeVariantBase, } from "@/types"; 2 | 3 | import { cardSizeVariants, genUiSizes, getUiCardSize, uiSizeVariants } from "../helpers"; 4 | 5 | import type { Shortcut } from "unocss"; 6 | import type { BaseVariants } from "./types"; 7 | 8 | 9 | const getUiShortcuts = ( 10 | globalUi?: BaseVariants, 11 | ) => { 12 | const defaultSizes: BaseVariants = { 13 | size: uiSizeVariants, 14 | cardSize: cardSizeVariants 15 | } 16 | const { size: sizes, cardSize } = Object.assign({}, defaultSizes, globalUi) 17 | 18 | const baseUi = { 19 | 'ui-soft': "bg-[--ui-soft-bg] text-[--ui-soft-text]", 20 | 'ui-solid': "bg-[--ui-solid-bg] text-[--ui-solid-text]", 21 | 'ui-outline': "text-[--ui-outline-text] border border-[--ui-outline-border]", 22 | 'ui-subtle': "bg-[--ui-subtle-bg] border text-[--ui-subtle-text] border-[--ui-subtle-border]", 23 | "ui-card":" p-[var(--card-padding)] rounded-[var(--card-radius)]", 24 | "inner-radius":"[border-radius:calc(var(--card-radius)-var(--card-padding))]" 25 | } 26 | 27 | 28 | const dynamicUi: Shortcut[] = [ 29 | [ 30 | /^ui-card-(xs|sm|md|lg|xl)$/, 31 | ([, size]) => { 32 | if (cardSize) { 33 | const uSize = cardSize[size as SizeVariantBase] 34 | if (uSize) 35 | return `${getUiCardSize(uSize)}`; 36 | } 37 | }, 38 | { autocomplete: ["ui-card-(xs|sm|md|lg|xl)"], }, 39 | ], 40 | [ 41 | /^ui-(sz|size)-(xs|sm|md|lg|xl)$/, 42 | ([, , size]) => { 43 | if (sizes) { 44 | const uSize = sizes[size as SizeVariantBase] 45 | if (uSize) 46 | return `${genUiSizes(uSize, size as SizeVariantBase)}`; 47 | } 48 | }, 49 | { autocomplete: ["ui-size-(xs|sm|md|lg|xl)", "ui-sz-(xs|sm|md|lg|xl)"], }, 50 | ], 51 | ]; 52 | 53 | return [baseUi, ...dynamicUi]; 54 | }; 55 | 56 | export { getUiShortcuts }; -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/ui/types.ts: -------------------------------------------------------------------------------- 1 | import type { CardSizeVariant, ElSizeVariants } from "@/types" 2 | 3 | 4 | 5 | export type BaseVariants = { 6 | size?: ElSizeVariants, 7 | cardSize?: CardSizeVariant 8 | } -------------------------------------------------------------------------------- /packages/preset-ui/src/shortcuts/utilities/index.ts: -------------------------------------------------------------------------------- 1 | import type { TextVariantBase } from "@/types"; 2 | import { helperDefaultValues } from "../helpers"; 3 | import type { Shortcut } from "unocss"; 4 | 5 | 6 | const getGeneralShortcuts = () => { 7 | const textTypo = helperDefaultValues.textTypo 8 | const utils: Record = { 9 | 10 | "ui-bg-clip-text": "text-transparent bg-clip-text", 11 | "ui-text-transparent": "text-transparent bg-clip-text", 12 | 13 | //flex 14 | "d-flex-justify-center": "flex justify-center", 15 | "d-flex-justify-start": "flex justify-start", 16 | "d-flex-justify-end": "flex justify-end", 17 | "d-flex-items-start": "flex items-start", 18 | "d-flex-items-center": "flex items-center", 19 | "d-flex-items-end": "flex items-end", 20 | "d-flex-between": "flex justify-between", 21 | "d-flex-place-center": "flex justify-center items-center", 22 | 23 | // pseudo before and after 24 | "before-empty": "before-absolute before-content-empty", 25 | "after-empty": "after-absolute after-content-empty", 26 | "before-after-empty": "before-absolute before-content-empty after-absolute after-content-empty", 27 | "before-0-x": "before-empty before-inset-x-0", 28 | "before-0-y": "before-empty before-inset-y-0", 29 | 'before-0': "before-empty before-inset-0", 30 | "after-0-x": "after-empty after-inset-x-0", 31 | "after-0-y": "after-empty after-inset-y-0", 32 | 'after-0': "after-empty after-inset-0", 33 | "before-after-0-x": "before-empty before-inset-x-0 after-empty inset-x-0", 34 | "before-after-0-y": "before-empty before-inset-y-0 after-empty inset-y-0", 35 | 'before-after-0': "before-empty after-empty before-inset-0 after-inset-0" 36 | }; 37 | 38 | 39 | const dynamicUtils: Shortcut[] = [ 40 | [ 41 | /^(txt|ui-text)-(xs-body|x-body|body|x-title|title|l-title)$/, 42 | ([, size]) => { 43 | if (["xs-body", "x-body", "body", "x-title", "title", "l-title"].includes(size)) { 44 | return `${textTypo[size as TextVariantBase]}` 45 | } 46 | }, 47 | { autocomplete: ["(txt|ui-text)-(xs-body|x-body|body|x-title|title|l-title)"] }, 48 | ], 49 | ]; 50 | 51 | return [utils, ...dynamicUtils]; 52 | }; 53 | export { getGeneralShortcuts }; 54 | -------------------------------------------------------------------------------- /packages/preset-ui/src/types/base.ts: -------------------------------------------------------------------------------- 1 | 2 | export type SemanticColorNames = 'primary' | 'secondary' | 'accent' | 'info' | 'success' | 'warning' | 'danger' | 'gray' | "neutral" | "white" 3 | 4 | 5 | export type SizeVariantBase = "2xs" | "xs" | "sm" | "md" | "lg" | "xl" 6 | export type TextSize = "xs" | "sm" | "base" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "6xl" | "7xl" | "8xl" | "9xl" 7 | export type TextVariantBase = "xs-body" | "x-body" | "body" | "x-title" | "title" | "l-title" 8 | export type FontWeightBase = "100" | "200" | "300" | "400" | "500" | "600" | "700" | "800" | "900" | "thin" | "light" | "normal" | "black" 9 | 10 | type BorderPosition = "b" | "t" | "l" | "r" | "x" | "y"; 11 | export type BorderPrefix = "border" | `border-${BorderPosition}`; 12 | 13 | 14 | export type BaseTypoColor = { 15 | light: string; 16 | dark: string; 17 | }; 18 | export type TextTypoColor = { 19 | title: BaseTypoColor; 20 | subTitle: BaseTypoColor; 21 | text: BaseTypoColor; 22 | subText: BaseTypoColor; 23 | }; 24 | 25 | 26 | export type SizeBaseVaraint = { 27 | '2xs'?: T; 28 | xs?: T; 29 | sm?: T; 30 | md?: T; 31 | lg?: T; 32 | xl?: T; 33 | } 34 | 35 | export type ElSizeBase = { py: number | string; px: number | string; textSize: TextSize } 36 | export type CardSizeBase = { padding: number | string; textSize: TextSize } 37 | export type InputSizeBase = { px: number | string; textSize: TextSize, height:number|string} 38 | 39 | 40 | export type ElSizeVariants = SizeBaseVaraint 41 | export type CardSizeVariant = SizeBaseVaraint 42 | export type InputSizeVariant = SizeBaseVaraint 43 | 44 | export type RingBase = { 45 | offset: number; 46 | size: number; 47 | }; 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | export type TextTypos = { 57 | 'xs-body'?: string, 58 | 'x-body'?: string, 59 | body?: string, 60 | 'x-title'?: string, 61 | title?: string, 62 | 'l-title'?: string, 63 | 'xl-title'?: string, 64 | '2xl-title'?: string, 65 | } 66 | -------------------------------------------------------------------------------- /packages/preset-ui/src/types/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./base"; 2 | export * from "./types"; 3 | 4 | export type Appearance = "light"|"dark"|"both" -------------------------------------------------------------------------------- /packages/preset-ui/src/types/types.ts: -------------------------------------------------------------------------------- 1 | import type { BaseVariants } from "@/shortcuts/ui/types"; 2 | import type { 3 | Appearance, 4 | RingBase, 5 | } from "."; 6 | import type { Components } from "@/shortcuts/types"; 7 | import { ThingsToExclude, UiButton } from "@/ui/type"; 8 | 9 | export type uiColorFormat = "rgb" | "hex" | "hsl" | "oklch" | "none" 10 | 11 | export type VariantSizeBoth = { 12 | xs?: number | string; 13 | sm?: number | string; 14 | md?: number | string; 15 | lg?: number | string; 16 | xl?: number | string; 17 | }; 18 | 19 | export type SharedFormConfig = { 20 | ringBase?: RingBase; 21 | }; 22 | 23 | 24 | export type formOutline = { 25 | borderSize?: number | string; 26 | }; 27 | 28 | 29 | 30 | export type UiHelperConfig = { 31 | variablePrefix?: string, 32 | colorFormat?: uiColorFormat, 33 | components?: { 34 | button?: UiButton 35 | }, 36 | exclude?: ThingsToExclude, 37 | appearance?: Appearance 38 | } 39 | 40 | export type presetUiConfig = { 41 | components?: Components; 42 | baseVariants?: BaseVariants, 43 | colorFormat?: uiColorFormat; 44 | appearance?: Appearance, 45 | uiGen?: UiHelperConfig 46 | }; 47 | -------------------------------------------------------------------------------- /packages/preset-ui/src/types/ui-t.ts: -------------------------------------------------------------------------------- 1 | export type ColorShade = 2 | | "50" 3 | | "100" 4 | | "200" 5 | | "300" 6 | | "400" 7 | | "500" 8 | | "600" 9 | | "700" 10 | | "800" 11 | | "900" 12 | | "950" 13 | | "white" 14 | 15 | export type BaseVariant = { 16 | base?: { 17 | primary?: T; 18 | secondary?: T; 19 | accent?: T; 20 | success?: T; 21 | warning?: T; 22 | info?: T; 23 | danger?: T; 24 | gray?: T; 25 | white?: T; 26 | neutral?: T 27 | }; 28 | custom?: Record; 29 | global?: T; 30 | }; 31 | 32 | 33 | export type formOutlineBase = { 34 | borderShade: ColorShade; 35 | borderOpacity?: number; 36 | textShade: ColorShade; 37 | bg: ColorShade, 38 | bgOpacity?: number, 39 | bgHover?: ColorShade, 40 | bgHoverOpacity?: number 41 | }; 42 | 43 | export type UiBtnOutline = formOutlineBase & { 44 | borderSize?: number | string; 45 | dark?: formOutlineBase; 46 | }; -------------------------------------------------------------------------------- /packages/preset-ui/src/ui-theme/index.ts: -------------------------------------------------------------------------------- 1 | 2 | import type { Theme } from "@unocss/preset-uno"; 3 | 4 | export const theme: Theme = { 5 | animation: { 6 | keyframes: { 7 | indeterminate: "{0%{ left: -100%; } 100%{ left: 100%; }}", 8 | carousel: "{0%{ left: 0%;} 100%{ left: 100%;}}", 9 | "carousel-inverse": "{0% { left: 100%;} 100%{ left: 0%;}}", 10 | marquee: "{ 0%{ left: 0%;} 50%{ left: 100%;} 100%{ left: 0%;}}", 11 | swing: "{0% { left: 0%;} 50%{ left: 105%;} 100%{left: 0%;}}", 12 | "background-shine": 13 | "{ from{ background-position: 0 0} to{ background-position: -200% 0;}}", 14 | 15 | // VueRadix animation 16 | 'vr-accordion-down': 17 | "{from{ height: 0; } to{ height: var(--radix-accordion-content-height); }}", 18 | 'vr-accordion-up': 19 | "{from{ height: var(--radix-accordion-content-height); } to { height: 0; }}", 20 | 'vr-collapsible-down': 21 | "{from { height: 0; } to: { height: var(--radix-collapsible-content-height); }}", 22 | 'vr-collapsible-up': 23 | "{from { height: var(--radix-collapsible-content-height); } to{ height: 0; }}", 24 | 25 | // Flexilla 26 | 'fx-accordion-down': 27 | "{from{ height: 0; } to{ height: var(--fx-accordion-content-height); }}", 28 | 'fx-accordion-up': 29 | "{from{ height: var(--fx-accordion-content-height); } to { height: 0; }}", 30 | 'fx-collapsible-down': 31 | "{from { height: 0; } to: { height: var(--fx-collapsible-content-height); }}", 32 | 'fx-collapsible-up': 33 | "{from { height: var(--fx-collapsible-content-height); } to{ height: 0; }}" 34 | }, 35 | durations: { 36 | indeterminate: "5s", 37 | marquee: "5s", 38 | carousel: "5s", 39 | "carousel-inverse": "5s", 40 | swing: "5s", 41 | "background-shine": "2s", 42 | "vr-accordion-down": "0.2s", 43 | "vr-accordion-up": "0.2s", 44 | "vr-collapsible-down": "0.2s", 45 | "vr-collapsible-up": "0.2s", 46 | "fx-accordion-down": "0.2s", 47 | "fx-accordion-up": "0.2s", 48 | "fx-collapsible-down": "0.2s", 49 | "fx-collapsible-up": "0.2s" 50 | }, 51 | timingFns: { 52 | "background-shine": "linear", 53 | "vr-accordion-down": "ease-in-out", 54 | "vr-accordion-up": "ease-in-out", 55 | "vr-collapsible-down": "ease-in-out", 56 | "vr-collapsible-up": "ease-in-out", 57 | "fx-accordion-down": "ease-in-out", 58 | "fx-accordion-up": "ease-in-out", 59 | "fx-collapsible-down": "ease-in-out", 60 | "fx-collapsible-up": "ease-in-out" 61 | }, 62 | counts: { 63 | indeterminate: "infinite", 64 | marquee: "infinite", 65 | carousel: "infinite", 66 | "carousel-inverse": "infinite", 67 | swing: "infinite", 68 | "background-shine": "infinite", 69 | }, 70 | }, 71 | }; 72 | -------------------------------------------------------------------------------- /packages/preset-ui/src/ui-theme/ui.ts: -------------------------------------------------------------------------------- 1 | import { getBrice } from "@/colors/genColor"; 2 | import { themeColors } from "@/colors/getPreconfigColors"; 3 | import { uiColorFormat } from "@/types"; 4 | import type { Theme } from "@unocss/preset-uno"; 5 | 6 | export const getUiTheme = (colorMode: uiColorFormat, colorPrefix?: string) => { 7 | const colors = themeColors(colorMode, colorPrefix); 8 | const theme: Theme = { 9 | colors: { 10 | bg: { 11 | DEFAULT: getBrice(colorMode, "bg", "none"), 12 | surface: getBrice(colorMode, "bg-surface", "none"), 13 | subtle: getBrice(colorMode, "bg-subtle", "none"), 14 | muted: getBrice(colorMode, "bg-muted", "none"), 15 | 'surface-elevated': getBrice(colorMode, "bg-surface-elevated", "none"), 16 | input:getBrice(colorMode, "bg-input", "none"), 17 | 'input-gray':getBrice(colorMode, "bg-input-gray", "none"), 18 | }, 19 | fg: { 20 | DEFAULT: getBrice(colorMode, "fg", "none"), 21 | title: getBrice(colorMode, "fg-title", "none"), 22 | subtitle: getBrice(colorMode, "fg-subtitle", "none"), 23 | muted: getBrice(colorMode, "fg-muted", "none"), 24 | input:getBrice(colorMode, "fg-input", "none"), 25 | }, 26 | border: { 27 | DEFAULT: getBrice(colorMode, "border", "none"), 28 | light: getBrice(colorMode, "border-light", "none"), 29 | subtle: getBrice(colorMode, "border-subtle", "none"), 30 | strong: getBrice(colorMode, "border-strong", "none"), 31 | emphasis: getBrice(colorMode, "border-emphasis", "none"), 32 | input: getBrice(colorMode, "border-input", "none"), 33 | }, 34 | card:{ 35 | DEFAULT: getBrice(colorMode, "card", "none"), 36 | elevated: getBrice(colorMode, "card-elevated", "none"), 37 | surface: getBrice(colorMode, "card-surface", "none"), 38 | gray: getBrice(colorMode, "card-gray", "none"), 39 | }, 40 | popover:{ 41 | DEFAULT: getBrice(colorMode, "popover", "none"), 42 | surface: getBrice(colorMode, "popover-surface", "none"), 43 | elevated: getBrice(colorMode, "popover-elevated", "none"), 44 | gray: getBrice(colorMode, "popover-gray", "none"), 45 | }, 46 | 47 | dark: getBrice(colorMode, "gray-950", colorPrefix), 48 | white: getBrice(colorMode, "white", colorPrefix), 49 | ...colors 50 | } 51 | }; 52 | return theme 53 | } -------------------------------------------------------------------------------- /packages/preset-ui/src/ui/index.ts: -------------------------------------------------------------------------------- 1 | 2 | import { Appearance, uiColorFormat } from "@/types"; 3 | import type { Preset, StaticShortcutMap } from "unocss"; 4 | import { ThingsToExclude, UiButton, UiCommon } from "./type"; 5 | import { getUiBtnShortcuts } from "./buttons"; 6 | import { getCommonUiShortcuts } from "./ui-variants"; 7 | 8 | export const getAllUIShortcut = ({ 9 | components, 10 | colorFormat, 11 | appearance, 12 | prefix, 13 | exclude 14 | }: { 15 | components?: { 16 | button?: UiButton, 17 | common?: UiCommon 18 | }; 19 | colorFormat: uiColorFormat; 20 | appearance: Appearance, 21 | prefix?: string, 22 | exclude?: ThingsToExclude 23 | }) => { 24 | const btn = getUiBtnShortcuts({ button: components?.button, colorFormat, appearance, prefix, exclude: exclude }); 25 | 26 | const commonUi = getCommonUiShortcuts({ uiCommon: components?.common, colorFormat, appearance, prefix }) 27 | const shortcuts = [ 28 | ...btn, 29 | ...commonUi 30 | ] as Exclude; 31 | return shortcuts; 32 | }; 33 | 34 | -------------------------------------------------------------------------------- /packages/preset-ui/src/ui/type.ts: -------------------------------------------------------------------------------- 1 | import { ColorShade, BaseVariant, UiBtnOutline } from "@/types/ui-t"; 2 | 3 | 4 | export type PredefinedValues = 'primary' | "secondary" | "accent" | "danger" | "warning" | "success" | "info" | "neutral" | "white" | "gray" | string; 5 | 6 | export type ExcludedVariants = "all" | "none" | PredefinedValues[] 7 | export type ThingsToExclude = { 8 | btn?: { 9 | solid?: ExcludedVariants, 10 | flexi?: ExcludedVariants, 11 | soft?: ExcludedVariants, 12 | ghost?: ExcludedVariants, 13 | outlined?: ExcludedVariants, 14 | cn?: ExcludedVariants, 15 | } | "all" | "none", 16 | ui?: { 17 | solid?: ExcludedVariants, 18 | outline?: ExcludedVariants, 19 | soft?: ExcludedVariants, 20 | subtle?: ExcludedVariants 21 | } 22 | }; 23 | 24 | export type UiSoftBase = { 25 | textShade: ColorShade; 26 | bgShade: ColorShade; 27 | opacity: number; 28 | }; 29 | 30 | export type UiSoft = UiSoftBase & { 31 | dark?: UiSoftBase; 32 | }; 33 | 34 | export type UiSolidBase = { 35 | bgShade: ColorShade; 36 | textColor: string; 37 | }; 38 | 39 | export type UiSolid = UiSolidBase & { 40 | dark?: UiSolidBase; 41 | }; 42 | 43 | export type UiOutlineBase = { 44 | textShade: ColorShade; 45 | borderShade: ColorShade; 46 | }; 47 | 48 | export type UiOutline = UiOutlineBase & { 49 | dark?: UiOutlineBase; 50 | }; 51 | 52 | export type UiSubtleBase = { 53 | textShade: ColorShade; 54 | bgShade: ColorShade; 55 | opacity: number; 56 | borderShade: ColorShade; 57 | borderOpacity: number; 58 | }; 59 | 60 | export type UiSubtle = UiSubtleBase & { 61 | dark?: UiSubtleBase; 62 | }; 63 | 64 | export type UiSoftVariants = BaseVariant; 65 | export type UiSolidVariants = BaseVariant; 66 | export type UiOutlineVariants = BaseVariant; 67 | export type UiSubtleVariants = BaseVariant; 68 | 69 | 70 | 71 | 72 | export type Btn_GhostSoftBase = { 73 | bgShade?: ColorShade; 74 | bgOpacity?: number; 75 | hoverBgOpacity: number; 76 | hoverBgShade: ColorShade; 77 | pressBgShade: ColorShade; 78 | pressOpacity: number; 79 | textShade: ColorShade; 80 | textHover?: ColorShade 81 | }; 82 | 83 | export type BtnGhostOrSoft = Btn_GhostSoftBase & { 84 | dark?: Btn_GhostSoftBase; 85 | }; 86 | 87 | 88 | 89 | export type SoliddBtnShadeBase = { 90 | bgShade: ColorShade; 91 | bgHoverShade: ColorShade; 92 | bgPressShade: ColorShade; 93 | topShadow: ColorShade; 94 | bottomShadow: ColorShade; 95 | topShadowHover: ColorShade; 96 | bottomShadowHover: ColorShade; 97 | } 98 | 99 | export type SolidBtnShade = SoliddBtnShadeBase & { 100 | dark?: SoliddBtnShadeBase; 101 | } 102 | export type FlexiBtnShadeBase = { 103 | bgShade: ColorShade; 104 | hoverBgShade: ColorShade; 105 | activeBgShade: ColorShade; 106 | shadowShadeA: ColorShade; 107 | shadowShadeB: ColorShade; 108 | shadowShadeC: ColorShade; 109 | activeShadowShadeA: ColorShade; 110 | activeShadowShadeB: ColorShade; 111 | activeShadowShadeC: ColorShade; 112 | }; 113 | export type FlexiBtnShade = FlexiBtnShadeBase & { 114 | dark?: FlexiBtnShadeBase; 115 | }; 116 | 117 | export type CnBtnBase = { 118 | bgColor: ColorShade, 119 | textColor: string; 120 | hoverBgColor: string; 121 | hoverBgOpacity?:number, 122 | } 123 | export type CnBtn = CnBtnBase & { 124 | dark?: CnBtnBase; 125 | } 126 | 127 | 128 | 129 | export type BtnSolidVariants = BaseVariant; 130 | export type BtnFlexiVariants = BaseVariant; 131 | export type BtnSoftVariants = BaseVariant; 132 | export type BtnGhostVariants = BaseVariant; 133 | export type BtnOutlineVariants = BaseVariant 134 | export type BtnCnVariants = BaseVariant 135 | 136 | export type UiButton = { 137 | solidVariants?: BtnSolidVariants 138 | flexiVariants?: BtnFlexiVariants, 139 | outlineVariants?: BtnOutlineVariants, 140 | softVariants?: BtnSoftVariants, 141 | ghostVariants?: BtnGhostVariants, 142 | cnVariants?: BtnCnVariants, 143 | }; 144 | 145 | export type UiCommon = { 146 | uiVariants?: { 147 | solid?: UiSolidVariants, 148 | soft?: UiSoftVariants, 149 | outline?: UiOutlineVariants, 150 | subtle?: UiSubtleVariants 151 | }, 152 | } 153 | 154 | export type UiVariants = { 155 | solid: UiSolidVariants, 156 | soft: UiSoftVariants, 157 | outline: UiOutlineVariants, 158 | subtle: UiSubtleVariants 159 | } -------------------------------------------------------------------------------- /packages/preset-ui/src/ui/ui-variants/default-val.ts: -------------------------------------------------------------------------------- 1 | import { UiCommon, UiOutline, UiSolid, UiSubtle } from "../type"; 2 | 3 | 4 | 5 | const defaultSolidShades: UiSolid = { bgShade: "600", textColor: "white", dark: { bgShade: "500", textColor: "white" } }; 6 | 7 | const defaultSolidGrayShades: UiSolid = { bgShade: "100", textColor: "gray-700", dark: { bgShade: "900", textColor: "gray-300" } }; 8 | 9 | const defaultNeutralSolidShades: UiSolid = { bgShade: "900", textColor: "white", dark: { bgShade: "white", textColor: "gray-900" } } 10 | 11 | 12 | const defaultSubtleShades: UiSubtle = { 13 | bgShade: "50", 14 | opacity: 100, 15 | borderShade: "300", 16 | borderOpacity: 20, 17 | textShade: "700", 18 | dark: { 19 | bgShade: "600", 20 | opacity: 15, 21 | borderShade: "500", 22 | borderOpacity: 40, 23 | textShade: "300", 24 | } 25 | } 26 | 27 | const defaultSubtleNeutral: UiSubtle = { 28 | bgShade: "950", 29 | opacity: 10, 30 | borderShade: "900", 31 | borderOpacity: 70, 32 | textShade: "900", 33 | dark: { 34 | bgShade: "50", 35 | opacity:20, 36 | borderShade: "800", 37 | borderOpacity: 60, 38 | textShade: "white", 39 | } 40 | } 41 | const defaultSubtleGray: UiSubtle = { 42 | bgShade: "50", 43 | opacity: 100, 44 | borderShade: "400", 45 | borderOpacity: 30, 46 | textShade: "800", 47 | dark: { 48 | bgShade: "600", 49 | opacity: 20, 50 | borderShade: "500", 51 | borderOpacity: 40, 52 | textShade: "300", 53 | }, 54 | }; 55 | 56 | 57 | 58 | const defaultOutlineELement: UiOutline = { 59 | borderShade: "600", textShade: "600", dark: { borderShade: "500", textShade: "500" }, 60 | }; 61 | 62 | const defaultOutlineGrayELement: UiOutline = { 63 | borderShade: "200", textShade: "700", dark: { borderShade: "800", textShade: "300" }, 64 | }; 65 | 66 | const defaultOutlineNeutral: UiOutline = { 67 | borderShade: "800", textShade: "700", dark: { borderShade: "400", textShade: "300" }, 68 | }; 69 | 70 | 71 | 72 | 73 | 74 | 75 | export const defaultUiConfig: UiCommon = { 76 | uiVariants: { 77 | solid: { 78 | base: { 79 | neutral: defaultNeutralSolidShades, 80 | gray: defaultSolidGrayShades 81 | }, 82 | global: defaultSolidShades 83 | }, 84 | subtle: { 85 | base: { 86 | gray: defaultSubtleGray, 87 | neutral: defaultSubtleNeutral 88 | }, 89 | global: defaultSubtleShades 90 | }, 91 | soft: { 92 | base: { 93 | gray: defaultSubtleGray, 94 | neutral: defaultSubtleNeutral 95 | }, 96 | global: defaultSubtleShades 97 | }, 98 | outline: { 99 | base: { 100 | gray: defaultOutlineGrayELement, 101 | neutral: defaultOutlineNeutral 102 | }, 103 | global: defaultOutlineELement 104 | } 105 | } 106 | } -------------------------------------------------------------------------------- /packages/preset-ui/src/utils/colors-utils.ts: -------------------------------------------------------------------------------- 1 | import { getRealOpacityValue } from "@/shortcuts/shortcut_helper"; 2 | import { uiColorFormat } from "@/types"; 3 | import { ColorShade } from "@/types/ui-t"; 4 | 5 | 6 | export const getColorFormat = (color: string, format_?: uiColorFormat, defaultVar_?: string) => { 7 | const defaultVar = defaultVar_ && defaultVar_ !== '' ? `,${defaultVar_}` : ''; 8 | const format = format_ || "hsl"; 9 | return format === "rgb" ? `rgb(var(${color}${defaultVar}))` : format === "hex" ? `var(${color}${defaultVar})` : format === "oklch" ? `oklch(var(${color}${defaultVar}))` : format === "hsl" ? `hsl(var(${color}))` : `var(${color})`; 10 | } 11 | 12 | export const getColorFormatWithOpacity = (color: string, opacity: number, format_?: uiColorFormat, defaultVar_?: string) => { 13 | const defaultVar = defaultVar_ && defaultVar_ !== '' ? `,${defaultVar_}` : ''; 14 | const format = format_ || "hsl"; 15 | return format === "rgb" ? `rgb(var(${color}${defaultVar})/${getRealOpacityValue(opacity)})` 16 | : format === "hex" ? `var(${color}${defaultVar})` 17 | : format === "oklch" ? `oklch(var(${color}${defaultVar})/${getRealOpacityValue(opacity)})` 18 | : format === "hsl" ? `hsl(var(${color})/${getRealOpacityValue(opacity)})` 19 | : `var(${color}/${opacity})`; 20 | } 21 | 22 | 23 | export const getVarName = (color: string, shade?: ColorShade|string, prefix: string = 'c') => { 24 | const shadeList = ["50", "100", "200", "300", "400", "500", "600", "700", "800", "900", "950", "white"] 25 | const colorName = color === 'white' || color === 'neutral' ? 'gray' : color; 26 | const prefixStr = prefix === 'none' || prefix === '' ? '' : `${prefix}-`; 27 | 28 | if (shade === 'white') { 29 | return `--${prefixStr}white`; 30 | } 31 | if (!shadeList.includes(shade as string)) { 32 | return `--${prefixStr}${shadeList[0]}`; 33 | } 34 | 35 | return `--${prefixStr}${colorName}-${shade}`; 36 | }; 37 | -------------------------------------------------------------------------------- /packages/preset-ui/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | import { PredefinedValues, ThingsToExclude } from "@/ui/type"; 2 | import type { Theme } from "unocss/preset-mini"; 3 | 4 | 5 | export const getConfigValue = (value: number | string | undefined) => 6 | typeof value === "number" 7 | ? value 8 | : typeof value === "string" 9 | ? `[${value}]` 10 | : ""; 11 | 12 | /** 13 | * This function check to value 1: light and 2 : dark, if the 2 values are same then return an empty string to avoid CSS duplication in output 14 | * @param 15 | * @returns 16 | */ 17 | export const getShortcutsIfNotSame = ({ 18 | val1, 19 | val2, 20 | shortcuts, 21 | }: { val1: string; val2: string; shortcuts: string }) => 22 | val1 === val2 ? "" : shortcuts; 23 | 24 | 25 | export const isValidColor = (color: string, theme: Theme) => { 26 | const colors = theme.colors; 27 | return !colors ? false : Object.keys(colors).includes(color); 28 | }; 29 | 30 | 31 | 32 | export const isVariantExcluded = (config: ThingsToExclude | undefined, type: keyof ThingsToExclude, variant: string, value: PredefinedValues) => { 33 | if (!config) return false 34 | 35 | const typeConfig = config[type]; 36 | if (typeConfig === "all") return true; 37 | if (typeConfig === "none") return false; 38 | 39 | if (typeof typeConfig === 'object') { 40 | const variantConfig = typeConfig[variant as keyof typeof typeConfig]; 41 | if (variantConfig === "all") return true; 42 | if (variantConfig === "none") return false; 43 | if (Array.isArray(variantConfig)) return variantConfig.includes(value); 44 | } 45 | return false; 46 | } -------------------------------------------------------------------------------- /packages/preset-ui/src/utils/size-utils.ts: -------------------------------------------------------------------------------- 1 | import type { Theme } from "unocss/preset-mini"; 2 | 3 | export const isValidSize = (size: string, theme: Theme) => { 4 | const sizes_ = theme.spacing; 5 | return !sizes_ ? false : Object.keys(sizes_).includes(size); 6 | }; -------------------------------------------------------------------------------- /packages/preset-ui/src/variants/index.ts: -------------------------------------------------------------------------------- 1 | import { browserVariants } from "@unifydev/unify-variant"; 2 | import type { Variant } from "unocss"; 3 | import type { Theme } from "@unocss/preset-uno"; 4 | 5 | export const getAllVariants = () => { 6 | const variants = [ 7 | browserVariants({ 8 | variants: { 9 | "meter-inner-el": "::-webkit-meter-inner-element", 10 | "meter-optimum-val": "::-webkit-meter-optimum-value", 11 | "metter-bar": "::-webkit-meter-bar", 12 | "moz-meter-bar": "::-moz-meter-bar", 13 | 14 | "range-slider-thumb": "::-webkit-slider-thumb", 15 | "moz-range-thumb": "::-moz-range-thumb", 16 | "slider-runnable-track": "::-webkit-slider-runnable-track", 17 | "moz-range-track": "::-moz-range-track", 18 | 19 | "w-progress-bar": "::-webkit-progress-bar", 20 | "w-progress-value": "::-webkit-progress-value", 21 | "m-progress-bar": "::-moz-progress-bar", 22 | "w-indeterminate-p-value": ":indeterminate::-webkit-progress-value", 23 | 24 | 'v-webkit-datetime-edit': '::-webkit-datetime-edit', 25 | 'v-webkit-datetime-edit-year-field': '::-webkit-datetime-edit-year-field', 26 | 'v-webkit-datetime-edit-month-field': '::-webkit-datetime-edit-month-field', 27 | 'v-webkit-datetime-edit-day-field': '::-webkit-datetime-edit-day-field', 28 | 'v-webkit-datetime-edit-hour-field': '::-webkit-datetime-edit-hour-field', 29 | 'v-webkit-datetime-edit-minute-field': '::-webkit-datetime-edit-minute-field', 30 | 'v-webkit-datetime-edit-second-field': '::-webkit-datetime-edit-second-field', 31 | 'v-webkit-datetime-edit-millisecond-field': '::-webkit-datetime-edit-millisecond-field', 32 | 'v-webkit-datetime-edit-meridiem-field': '::-webkit-datetime-edit-meridiem-field', 33 | 'v-webkit-datetime-edit-fields-wrapper': '::-webkit-datetime-edit-fields-wrapper', 34 | 'v-webkit-date-and-time-value': '::-webkit-date-and-time-value' 35 | }, 36 | }), 37 | ] as Variant[]; 38 | 39 | return variants; 40 | }; 41 | -------------------------------------------------------------------------------- /packages/preset-ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./../../shared/tsconfig.json", 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "paths": { 6 | "@/*": ["src/*"] 7 | } 8 | }, 9 | "include": ["src"] 10 | } -------------------------------------------------------------------------------- /packages/unify-variant/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Editor directories and files 16 | .vscode/* 17 | !.vscode/extensions.json 18 | .idea 19 | .DS_Store 20 | *.suo 21 | *.ntvs* 22 | *.njsproj 23 | *.sln 24 | *.sw? 25 | -------------------------------------------------------------------------------- /packages/unify-variant/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 UnifyUI Dev 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/unify-variant/README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

Unify-Variant

4 |

Variant for differents Components UI Libraries.

5 |

6 | 7 | 8 | ## UnoUI-Variant 9 | 10 | This is a preset package that provides variants for Components Libraries based on data-state attribute value, and help to create custom variant selector. 11 | 12 | ### Data State Variants 13 | 14 | Generate variants selector based on data-state attribute, however you can use it with other data-* attributes like (data-state="john" then `fx-john:p4`) 15 | 16 | - [X] Radix 17 | - [X] Flexilla 18 | - [X] Radix Vue 19 | 20 | `fx-open:bg-red` : will be applied if element has data-state='open' 21 | 22 | ### browserVariant 23 | 24 | Easily create custom variants for browser selector like ::moz-* ::webki... 25 | 26 | 27 | ## Usage 28 | 29 | ### Installation 30 | 31 | ```bash 32 | npm i -D @unifydev/unify-preset 33 | ``` 34 | or 35 | ```bash 36 | yarn add @unifydev/unify-preset -D 37 | ``` 38 | Or 39 | ```bash 40 | bun add @unifydev/unify-preset -d 41 | ``` 42 | 43 | ### Config 44 | 45 | In you `uno.config.(js|ts)` : 46 | ```js 47 | ... 48 | // import the packages 49 | import {dataStateVariants, browserVariants} from '@unifydev/unify-variant' 50 | 51 | export default defineConfig({ 52 | // ...config 53 | variant:[ 54 | dataStateVariants({ 55 | prefix: 'fx', // prefix, you can use whatever you want as prefix 56 | variants: "visible|hidden|active|inactive|open|close|resize|minimize|maximaze", // indicate all values, those values will help to generate variant 57 | selector: "data-state" //Indicate the data-attribute to be used 58 | }), 59 | browserVariants({ 60 | variants: { 61 | "meter-inner-el": "::-webkit-meter-inner-element", 62 | "meter-optimum-val": "::-webkit-meter-optimum-value", 63 | "metter-bar": "::-webkit-meter-bar", 64 | "moz-meter-bar": "::-moz-meter-bar" 65 | } 66 | }), 67 | ] 68 | }); 69 | 70 | ``` 71 | 72 | 73 | ### Use it 74 | 75 | Now you can use : 76 | 77 | - `metter-bar:bg-red` 78 | 79 | 80 | ## Contributing 81 | 82 | If you're interested in contributing to Unify-UI, please read our [contributing docs](CONTRIBUTING.MD) before submitting a pull request. 83 | 84 | ### Join Our Community 🌍 85 | 86 | Contribute, collaborate, and become a part of our mission 🚀 87 | - [Discord Community](https://discord.gg/6VN6zTPZAy) 88 | 89 | ## Support Us 90 | 91 | If you like this project and want to support us, feel free to get in touch with one of maintainers : 92 | 93 | - [Johnkat MJ](mailto:johnkatembue4@gmail.com) -------------------------------------------------------------------------------- /packages/unify-variant/build.config.ts: -------------------------------------------------------------------------------- 1 | import { defineBuildConfig } from 'unbuild' 2 | 3 | export default defineBuildConfig({ 4 | entries: ['src/index'], 5 | declaration: true, 6 | clean: true, 7 | rollup: { 8 | emitCJS: true, 9 | }, 10 | externals: ['unocss'], 11 | }) -------------------------------------------------------------------------------- /packages/unify-variant/favicon-dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unoforge/unify-preset/3e7470b22ee297f2a69601fb84a1907e3ae2db72/packages/unify-variant/favicon-dark.png -------------------------------------------------------------------------------- /packages/unify-variant/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@unifydev/unify-variant", 3 | "version": "0.3.0", 4 | "description": "UnoCSS Variants", 5 | "publishConfig": { 6 | "access": "public" 7 | }, 8 | "main": "./dist/index.cjs", 9 | "module": "./dist/index.mjs", 10 | "types": "./dist/index.d.ts", 11 | "exports": { 12 | ".": { 13 | "types": "./dist/index.d.ts", 14 | "require": "./dist/index.cjs", 15 | "import": "./dist/index.mjs" 16 | } 17 | }, 18 | "scripts": { 19 | "build": "rimraf dist && unbuild", 20 | "format": "biome format --write ./src" 21 | }, 22 | "files": [ 23 | "dist", 24 | "!dist/index.d.cts", 25 | "!dist/index.d.mts", 26 | "README.md", 27 | "favicon-dark.png", 28 | "package.json", 29 | "!.gitignore", 30 | "!tsconfig.json", 31 | "!biome.js" 32 | ], 33 | "author": "Johnkat MJ", 34 | "license": "MIT", 35 | "devDependencies": { 36 | "@types/node": "^22.14.1", 37 | "rimraf": "^6.0.1", 38 | "ts-node": "^10.9.2", 39 | "typescript": "^5.8.3", 40 | "unbuild": "^3.5.0", 41 | "unocss": "^v66.0.0" 42 | }, 43 | "keywords": [ 44 | "variants", 45 | "unocss preset", 46 | "unocss variant", 47 | "custom variants", 48 | "unifyui", 49 | "unify-preset", 50 | "uno ui", 51 | "unoui", 52 | "unoforge" 53 | ], 54 | "repository": { 55 | "type": "git", 56 | "url": "https://github.com/unoforge/unify-preset" 57 | }, 58 | "bugs": { 59 | "url": "https://github.com/unoforge/unify-preset/issues" 60 | }, 61 | "gitHead": "1a4a3121332b2961338fd7920369d64ba3bab0e5" 62 | } 63 | -------------------------------------------------------------------------------- /packages/unify-variant/src/browser-pseudo.ts: -------------------------------------------------------------------------------- 1 | import type { Variant } from "unocss"; 2 | 3 | export type BrowserVariantOptions = { 4 | prefix?: string; 5 | variants: Record, 6 | }; 7 | 8 | export const browserVariants = (options: BrowserVariantOptions): Variant => { 9 | const { prefix = '', variants } = options; 10 | 11 | const prefix_ = prefix !== '' ? `${prefix}-` : '' 12 | const keys = Object.keys(variants).join('|'); 13 | 14 | function getValue(key: string): string | undefined { 15 | return variants[key]; 16 | } 17 | 18 | return { 19 | name: 'browser-pseudo', 20 | match: (matcher: string) => { 21 | 22 | const regex = new RegExp(`^${prefix_}(${keys})[:-]`); 23 | const match = matcher.match(regex); 24 | 25 | if (!match) return matcher; 26 | const variant = match[1] 27 | const aliasPseudo = getValue(variant) 28 | 29 | return { 30 | matcher: matcher.slice(match[0].length), 31 | // biome-ignore lint/suspicious/noExplicitAny: 32 | selector: (s: any) => `${s}${aliasPseudo}`, 33 | 34 | } 35 | }, 36 | autocomplete:[`${prefix_}${variants}`] 37 | }; 38 | }; -------------------------------------------------------------------------------- /packages/unify-variant/src/index.ts: -------------------------------------------------------------------------------- 1 | export { dataStateVariants , type DataStateVariantOptions } from "./stateVariants" 2 | export { browserVariants, type BrowserVariantOptions } from "./browser-pseudo" -------------------------------------------------------------------------------- /packages/unify-variant/src/stateVariants.ts: -------------------------------------------------------------------------------- 1 | import type { Variant } from "unocss"; 2 | 3 | export type DataStateVariantOptions = { 4 | prefix?: string; 5 | variants: string; 6 | selector: string; 7 | isAttrBoolean?: boolean; 8 | }; 9 | 10 | export const dataStateVariants = (options: DataStateVariantOptions): Variant => { 11 | const { 12 | prefix = 'fx', 13 | variants, 14 | selector, 15 | isAttrBoolean, 16 | } = options; 17 | 18 | return { 19 | name: 'state-variant', 20 | match: (matcher: string) => { 21 | const regex = new RegExp(`^(peer-|group-|where-)?${prefix}(-not)?-(${variants})[:-]`); 22 | const match = matcher.match(regex); 23 | 24 | if (!match) return matcher; 25 | 26 | const attrGen = !isAttrBoolean 27 | ? `[${selector}~='${match[3]}']` 28 | : `[${selector}-${match[3]}]`; 29 | 30 | return { 31 | matcher: matcher.slice(match[0].length), 32 | // biome-ignore lint/suspicious/noExplicitAny: 33 | selector: (s: any) => { 34 | const beforePrefixSelector = match[1] ? `${match[1]}` : ''; 35 | const preSelector = beforePrefixSelector === "peer-" ? 36 | `.peer${attrGen} ~` : beforePrefixSelector === "group-" ? `.group${attrGen} ` : "" 37 | return (match[2] === '-not') 38 | ? ( 39 | beforePrefixSelector === "where-" ? `:where([${selector}]:not(${attrGen})) ${s}` : 40 | (beforePrefixSelector === "peer-" ? 41 | `.peer:not(${attrGen}) ~ ${s}` : 42 | beforePrefixSelector === "group-" ? 43 | `.group:not(${attrGen}) ${s}` : `${s}`) 44 | ) 45 | : ( 46 | beforePrefixSelector === "where-" ? `:where(${attrGen}) ${s}` : 47 | `${preSelector}${s}${preSelector !== "" ? "" : `${attrGen}`}` 48 | ); 49 | }, 50 | }; 51 | }, 52 | autocomplete: [`${prefix}-(${variants})`] 53 | }; 54 | }; -------------------------------------------------------------------------------- /packages/unify-variant/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./../../shared/tsconfig.json", 3 | "include": ["src"] 4 | } -------------------------------------------------------------------------------- /shared/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": [ 7 | "ES2020", 8 | "DOM", 9 | "DOM.Iterable" 10 | ], 11 | "skipLibCheck": true, 12 | /* Bundler mode */ 13 | "moduleResolution": "bundler", 14 | "allowImportingTsExtensions": true, 15 | "resolveJsonModule": true, 16 | "isolatedModules": true, 17 | "noEmit": true, 18 | /* Linting */ 19 | "strict": true, 20 | "noUnusedLocals": true, 21 | "noUnusedParameters": true, 22 | "noFallthroughCasesInSwitch": true, 23 | "declaration": true, // Set to true to generate declaration files (.d.ts) 24 | "declarationMap": false, 25 | }, 26 | } --------------------------------------------------------------------------------