├── .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 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | Default/Fill Default
25 |
26 |
27 |
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 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | Video/TV
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | Square
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | 35mm film
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 | Standard TV/Monitor
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | Ultrawide monitor
65 |
66 |
67 |
68 |
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 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | Container : Default
25 |
26 |
33 |
34 |
35 |
36 | Container : Max-w7xl
37 |
38 |
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 |
16 |
17 |
18 |
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 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | Icon Default
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
38 |
39 |
40 |
42 |
43 |
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 |
16 |
17 |
18 |
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 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | Link Defaulft
25 |
26 |
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 |
16 |
17 |
18 |
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 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | Default PopOver
25 |
26 |
27 |
29 | Show Content
30 |
31 |
37 |
38 |
39 |
40 |
41 | With Content
42 |
43 |
44 |
46 |
48 |
49 |
Johnkat MJ
50 | FrontEnd Designer
51 |
52 |
53 |
55 |
56 |
57 |
John Doe
58 |
12k followers
59 |
60 |
62 | Follow
63 |
64 |
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 |
16 |
17 |
18 |
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 |
16 |
17 |
18 |
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 | Your Message
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 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | Grid (Rectangle)
25 |
26 |
32 |
33 |
34 |
35 | Grid (Square)
36 |
37 |
43 |
44 |
45 |
46 | Grid (Square)
47 |
48 |
54 |
55 |
56 |
57 | Grid stripped (Rectangle)
58 |
59 |
65 |
66 |
67 |
68 | Grid stripped (Square)
69 |
70 |
76 |
77 |
78 |
79 | Grid stripped reverse
80 |
81 |
87 |
88 |
89 |
90 |
91 | Radial BG
92 |
93 |
99 |
100 |
101 |
102 |
103 | Radial BG
104 |
105 |
111 |
112 |
113 |
114 |
115 | Grid dotted
116 |
117 |
121 |
122 |
123 |
124 |
125 | Grid dotted stripped oval
126 |
127 |
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 | }
--------------------------------------------------------------------------------