├── .changeset
├── README.md
└── config.json
├── .eslintrc.js
├── .github
└── README.md
├── .gitignore
├── .npmrc
├── .prettierignore
├── TODOs.md
├── apps
├── tauri-controls-solid
│ ├── .gitignore
│ ├── CHANGELOG.md
│ ├── LICENSE
│ ├── README.md
│ ├── bun.lockb
│ ├── index.html
│ ├── package.json
│ ├── postcss.config.cjs
│ ├── prettier.config.cjs
│ ├── src-tauri
│ │ ├── Cargo.lock
│ │ ├── Cargo.toml
│ │ ├── build.rs
│ │ ├── capabilities
│ │ │ └── main.json
│ │ ├── gen
│ │ │ └── schemas
│ │ │ │ ├── acl-manifests.json
│ │ │ │ ├── capabilities.json
│ │ │ │ ├── desktop-schema.json
│ │ │ │ ├── macOS-schema.json
│ │ │ │ └── windows-schema.json
│ │ ├── icons
│ │ │ ├── 128x128.png
│ │ │ ├── 128x128@2x.png
│ │ │ ├── 32x32.png
│ │ │ ├── Square107x107Logo.png
│ │ │ ├── Square142x142Logo.png
│ │ │ ├── Square150x150Logo.png
│ │ │ ├── Square284x284Logo.png
│ │ │ ├── Square30x30Logo.png
│ │ │ ├── Square310x310Logo.png
│ │ │ ├── Square44x44Logo.png
│ │ │ ├── Square71x71Logo.png
│ │ │ ├── Square89x89Logo.png
│ │ │ ├── StoreLogo.png
│ │ │ ├── icon.icns
│ │ │ ├── icon.ico
│ │ │ └── icon.png
│ │ ├── src
│ │ │ └── main.rs
│ │ └── tauri.conf.json
│ ├── src
│ │ ├── App.tsx
│ │ ├── index.tsx
│ │ ├── style.css
│ │ └── tauri-controls
│ │ │ ├── components
│ │ │ ├── button.tsx
│ │ │ └── icons.tsx
│ │ │ ├── controls
│ │ │ ├── index.ts
│ │ │ ├── linux
│ │ │ │ ├── gnome.tsx
│ │ │ │ └── index.ts
│ │ │ ├── macos.tsx
│ │ │ └── windows.tsx
│ │ │ ├── index.css
│ │ │ ├── index.ts
│ │ │ ├── libs
│ │ │ ├── plugin-os.ts
│ │ │ └── plugin-window.ts
│ │ │ ├── types.ts
│ │ │ ├── window-controls.tsx
│ │ │ └── window-titlebar.tsx
│ ├── tailwind.config.js
│ ├── tsconfig.json
│ ├── tsconfig.node.json
│ └── vite.config.ts
├── tauri-controls-svelte
│ ├── .eslintignore
│ ├── .eslintrc.cjs
│ ├── .gitignore
│ ├── .npmrc
│ ├── .prettierignore
│ ├── CHANGELOG.md
│ ├── LICENSE
│ ├── README.md
│ ├── bun.lockb
│ ├── package.json
│ ├── playwright.config.ts
│ ├── postcss.config.cjs
│ ├── prettier.config.cjs
│ ├── src-tauri
│ │ ├── .gitignore
│ │ ├── Cargo.lock
│ │ ├── Cargo.toml
│ │ ├── build.rs
│ │ ├── capabilities
│ │ │ └── main.json
│ │ ├── gen
│ │ │ └── schemas
│ │ │ │ ├── acl-manifests.json
│ │ │ │ ├── capabilities.json
│ │ │ │ ├── desktop-schema.json
│ │ │ │ └── macOS-schema.json
│ │ ├── icons
│ │ │ ├── 128x128.png
│ │ │ ├── 128x128@2x.png
│ │ │ ├── 32x32.png
│ │ │ ├── Square107x107Logo.png
│ │ │ ├── Square142x142Logo.png
│ │ │ ├── Square150x150Logo.png
│ │ │ ├── Square284x284Logo.png
│ │ │ ├── Square30x30Logo.png
│ │ │ ├── Square310x310Logo.png
│ │ │ ├── Square44x44Logo.png
│ │ │ ├── Square71x71Logo.png
│ │ │ ├── Square89x89Logo.png
│ │ │ ├── StoreLogo.png
│ │ │ ├── icon.icns
│ │ │ ├── icon.ico
│ │ │ └── icon.png
│ │ ├── src
│ │ │ └── main.rs
│ │ └── tauri.conf.json
│ ├── src
│ │ ├── app.d.ts
│ │ ├── app.html
│ │ ├── index.test.ts
│ │ ├── lib
│ │ │ ├── WindowControls.svelte
│ │ │ ├── WindowTitlebar.svelte
│ │ │ ├── components
│ │ │ │ ├── Button.svelte
│ │ │ │ └── Icons.svelte
│ │ │ ├── controls
│ │ │ │ ├── MacOs.svelte
│ │ │ │ ├── Windows.svelte
│ │ │ │ └── linux
│ │ │ │ │ └── Gnome.svelte
│ │ │ ├── index.ts
│ │ │ ├── types.ts
│ │ │ └── utils
│ │ │ │ ├── os.ts
│ │ │ │ ├── utils.ts
│ │ │ │ └── window.ts
│ │ ├── routes
│ │ │ ├── +page.svelte
│ │ │ └── theme-switch.svelte
│ │ └── style.css
│ ├── static
│ │ └── favicon.png
│ ├── svelte.config.js
│ ├── tailwind-build.config.js
│ ├── tailwind.config.js
│ ├── tests
│ │ └── test.ts
│ ├── tsconfig.json
│ └── vite.config.ts
├── tauri-controls-vue
│ ├── .gitignore
│ ├── CHANGELOG.md
│ ├── LICENSE
│ ├── README.md
│ ├── bun.lockb
│ ├── index.html
│ ├── package.json
│ ├── postcss.config.js
│ ├── prettier.config.cjs
│ ├── src-tauri
│ │ ├── .gitignore
│ │ ├── Cargo.lock
│ │ ├── Cargo.toml
│ │ ├── build.rs
│ │ ├── capabilities
│ │ │ └── main.json
│ │ ├── gen
│ │ │ └── schemas
│ │ │ │ ├── acl-manifests.json
│ │ │ │ ├── capabilities.json
│ │ │ │ ├── desktop-schema.json
│ │ │ │ ├── macOS-schema.json
│ │ │ │ └── windows-schema.json
│ │ ├── icons
│ │ │ ├── 128x128.png
│ │ │ ├── 128x128@2x.png
│ │ │ ├── 32x32.png
│ │ │ ├── Square107x107Logo.png
│ │ │ ├── Square142x142Logo.png
│ │ │ ├── Square150x150Logo.png
│ │ │ ├── Square284x284Logo.png
│ │ │ ├── Square30x30Logo.png
│ │ │ ├── Square310x310Logo.png
│ │ │ ├── Square44x44Logo.png
│ │ │ ├── Square71x71Logo.png
│ │ │ ├── Square89x89Logo.png
│ │ │ ├── StoreLogo.png
│ │ │ ├── icon.icns
│ │ │ ├── icon.ico
│ │ │ └── icon.png
│ │ ├── src
│ │ │ └── main.rs
│ │ └── tauri.conf.json
│ ├── src
│ │ ├── App.vue
│ │ ├── components
│ │ │ ├── LogoSvg.vue
│ │ │ ├── Menu.vue
│ │ │ └── ThemeSwitch.vue
│ │ ├── main.ts
│ │ ├── styles.css
│ │ ├── tauri-controls
│ │ │ ├── WindowControls.vue
│ │ │ ├── WindowTitlebar.vue
│ │ │ ├── components
│ │ │ │ ├── Button.vue
│ │ │ │ └── Icons.vue
│ │ │ ├── controls
│ │ │ │ ├── MacOs.vue
│ │ │ │ ├── Windows.vue
│ │ │ │ └── linux
│ │ │ │ │ └── Gnome.vue
│ │ │ ├── index.css
│ │ │ ├── index.ts
│ │ │ ├── types.ts
│ │ │ └── utils
│ │ │ │ ├── os.ts
│ │ │ │ └── window.ts
│ │ └── vite-env.d.ts
│ ├── tailwind.config.js
│ ├── tsconfig.json
│ ├── tsconfig.node.json
│ └── vite.config.ts
└── tauri-controls
│ ├── .eslintrc.cjs
│ ├── .gitignore
│ ├── .prettierignore
│ ├── CHANGELOG.md
│ ├── LICENSE
│ ├── README.md
│ ├── bun.lockb
│ ├── index.html
│ ├── package.json
│ ├── postcss.config.cjs
│ ├── prettier.config.cjs
│ ├── src-tauri
│ ├── Cargo.lock
│ ├── Cargo.toml
│ ├── build.rs
│ ├── capabilities
│ │ └── main.json
│ ├── gen
│ │ └── schemas
│ │ │ ├── acl-manifests.json
│ │ │ ├── capabilities.json
│ │ │ ├── desktop-schema.json
│ │ │ ├── macOS-schema.json
│ │ │ └── windows-schema.json
│ ├── icons
│ │ ├── 128x128.png
│ │ ├── 128x128@2x.png
│ │ ├── 32x32.png
│ │ ├── Square107x107Logo.png
│ │ ├── Square142x142Logo.png
│ │ ├── Square150x150Logo.png
│ │ ├── Square284x284Logo.png
│ │ ├── Square30x30Logo.png
│ │ ├── Square310x310Logo.png
│ │ ├── Square44x44Logo.png
│ │ ├── Square71x71Logo.png
│ │ ├── Square89x89Logo.png
│ │ ├── StoreLogo.png
│ │ ├── icon.icns
│ │ ├── icon.ico
│ │ └── icon.png
│ ├── src
│ │ └── main.rs
│ └── tauri.conf.json
│ ├── src
│ ├── App.tsx
│ ├── main.tsx
│ ├── style.css
│ ├── tauri-controls
│ │ ├── components
│ │ │ ├── button.tsx
│ │ │ └── icons.tsx
│ │ ├── contexts
│ │ │ └── plugin-window.tsx
│ │ ├── controls
│ │ │ ├── index.ts
│ │ │ ├── linux
│ │ │ │ ├── gnome.tsx
│ │ │ │ └── index.ts
│ │ │ ├── macos.tsx
│ │ │ └── windows.tsx
│ │ ├── index.css
│ │ ├── index.ts
│ │ ├── libs
│ │ │ ├── plugin-os.ts
│ │ │ └── utils.ts
│ │ ├── types.ts
│ │ ├── window-controls.tsx
│ │ └── window-titlebar.tsx
│ └── vite-env.d.ts
│ ├── tailwind.config.js
│ ├── tsconfig.json
│ ├── tsconfig.node.json
│ └── vite.config.ts
├── bun.lockb
├── package.json
├── prettier.config.js
└── turbo.json
/.changeset/README.md:
--------------------------------------------------------------------------------
1 | # Changesets
2 |
3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works
4 | with multi-package repos, or single-package repos to help you version and publish your code. You can
5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets)
6 |
7 | We have a quick list of common questions to get you started engaging with this project in
8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md)
9 |
--------------------------------------------------------------------------------
/.changeset/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json",
3 | "changelog": "@changesets/changelog-git",
4 | "access": "public",
5 | "baseBranch": "master",
6 | "commit": false,
7 | "fixed": [],
8 | "linked": [],
9 | "ignore": [],
10 | "updateInternalDependencies": "patch"
11 | }
12 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | // This tells ESLint to load the config from the package `eslint-config-custom`
4 | extends: ["custom"],
5 | settings: {
6 | next: {
7 | rootDir: ["apps/*/"],
8 | },
9 | },
10 | };
11 |
--------------------------------------------------------------------------------
/.github/README.md:
--------------------------------------------------------------------------------
1 | ../apps/tauri-controls/README.md
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | node_modules
5 | .pnp
6 | .pnp.js
7 |
8 | # testing
9 | coverage
10 |
11 | # next.js
12 | .next/
13 | out/
14 | build
15 | dist
16 |
17 | # misc
18 | .DS_Store
19 | *.pem
20 | *.tgz
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env
29 | .env.local
30 | .env.development.local
31 | .env.test.local
32 | .env.production.local
33 |
34 | # turbo
35 | .turbo
36 |
37 | # vercel
38 | .vercel
39 |
40 |
41 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | auto-install-peers = true
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | .env
4 | .env.*
5 | !.env.example
6 |
7 | # Ignore files for PNPM, NPM and YARN
8 | pnpm-lock.yaml
9 | package-lock.json
10 | yarn.lock
11 |
--------------------------------------------------------------------------------
/TODOs.md:
--------------------------------------------------------------------------------
1 | # TODOs / Known Issues:
2 |
3 | > Ticked items have been implemented or fixed.
4 |
5 | ### tauri-controls (General):
6 |
7 | - [x] Auto-determine controls position if no platform is specified (e.g., MacOS left, others right).
8 | - [x] Next.js/SSR support.
9 | - [x] Svelte/SvelteKit implementation.
10 | - [ ] Detect disabled window controls and disable the buttons accordingly. [#7](https://github.com/agmmnn/tauri-controls/issues/7)
11 | - [ ] \[macOS] Adjust max icon behavior when window is fullscreen. [📷](https://i.imgur.com/7FmMOZN.png)
12 | - [ ] Extend support to other Linux DEs' default themes, Budgie/KDE.
13 | - [ ] \[macOS] Option to hide controls -like `hide` but- only if the window is fullscreen and on macOS.
14 |
15 | ### tauri-controls (React):
16 |
17 | - [ ] \[macOS] IsWindowMaximized not work on macOS (react, solid). [#10](https://github.com/agmmnn/tauri-controls/issues/10)
18 |
19 | ### @tauri-controls/svelte:
20 |
21 | - [ ] Maximize icon does not change to "Unmaximize" when the window is maximized.
22 |
23 | ### @tauri-controls/solid:
24 |
25 | - [ ] \[macOS] IsWindowMaximized not work on macOS (react, solid). [#10](https://github.com/agmmnn/tauri-controls/issues/10)
26 |
27 | ### @tauri-controls/vue:
28 |
29 | - [x] Maximize icon does not change when the window is maximized by double clicking on the titlebar (data-tauri-drag-region).
30 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 |
4 | src-tauri/target
5 | *.tgz
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # @tauri-controls/solid
2 |
3 | ## 0.4.0
4 |
5 | ### Minor Changes
6 |
7 | - fix: compatibility with the latest Tauri V2 release
8 | chore: switch package manager from pnpm to bun
9 |
10 | ## 0.3.0
11 |
12 | ### Minor Changes
13 |
14 | - fix: Remove all Tauri dependencies from the list of dependecies. This will require the user to install these (which were already in the instructions), but allow for more control of a single version of these packages. #20, thanks to @jbolda
15 |
16 | ## 0.2.0
17 |
18 | ### Minor Changes
19 |
20 | - fix: compatibility with the latest Tauri release
21 |
22 | ## 0.1.3
23 |
24 | ### Patch Changes
25 |
26 | - fix: package.json types export
27 |
28 | ## 0.1.2
29 |
30 | ### Patch Changes
31 |
32 | - fix(react,solid): temp disable isWindowMaximized on macOS #10
33 | chore: demo-app gap to space, update deps, format code
34 | feat: gnome more accurate button spacing, fix icons sizes (svelte, vue)
35 | feat: macos controls use space instead of mr, px-2 to px-3
36 |
37 | ## 0.1.1
38 |
39 | ### Patch Changes
40 |
41 | - Add [changeset](https://github.com/changesets/changesets)
42 | - Add [publish-packages script](https://turbo.build/repo/docs/handbook/publishing-packages/versioning-and-publishing#using-changesets-with-turborepo)
43 | - Add License file
44 | - Update readme files
45 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 agmmnn
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 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 
7 | 
8 | [](https://npmjs.com/package/tauri-controls) 
9 |
10 | ## @tauri-controls/solid
11 |
12 | ```bash
13 | pnpm add @tauri-controls/solid
14 | ```
15 |
16 | https://github.com/agmmnn/tauri-controls
17 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/bun.lockb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-solid/bun.lockb
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Demo-Solid
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@tauri-controls/solid",
3 | "description": "🚥 Native-looking window controls for Tauri 2.",
4 | "private": false,
5 | "version": "0.4.0",
6 | "type": "module",
7 | "license": "MIT",
8 | "scripts": {
9 | "start": "vite",
10 | "dev": "vite",
11 | "build": "tsc && vite build",
12 | "serve": "vite preview",
13 | "tauri": "tauri",
14 | "tauri:dev": "tauri dev",
15 | "format": "prettier --write . --config ./prettier.config.cjs"
16 | },
17 | "publishConfig": {
18 | "access": "public"
19 | },
20 | "repository": {
21 | "type": "git",
22 | "url": "https://github.com/agmmnn/tauri-controls"
23 | },
24 | "keywords": [],
25 | "author": "agmmnn",
26 | "bugs": {
27 | "url": "https://github.com/agmmnn/tauri-controls/issues"
28 | },
29 | "homepage": "https://github.com/agmmnn/tauri-controls#readme",
30 | "files": [
31 | "dist"
32 | ],
33 | "exports": {
34 | ".": {
35 | "import": "./dist/tauri-controls.js",
36 | "types": "./dist/index.d.ts"
37 | }
38 | },
39 | "module": "./dist/tauri-controls.js",
40 | "types": "./dist/index.d.ts",
41 | "dependencies": {},
42 | "devDependencies": {
43 | "@ianvs/prettier-plugin-sort-imports": "^4.2.1",
44 | "@rollup/plugin-terser": "^0.4.4",
45 | "@tauri-apps/api": "2.0.0-beta.6",
46 | "@tauri-apps/cli": "2.0.0-beta.11",
47 | "@tauri-apps/plugin-os": "2.0.0-beta.2",
48 | "autoprefixer": "^10.4.19",
49 | "postcss": "^8.4.38",
50 | "prettier": "^3.2.5",
51 | "prettier-plugin-tailwindcss": "^0.5.12",
52 | "tailwindcss": "^3.4.1",
53 | "typescript": "^5.4.3",
54 | "vite": "^5.2.4",
55 | "vite-plugin-dts": "^3.7.3",
56 | "vite-plugin-solid": "^2.10.2"
57 | },
58 | "peerDependencies": {
59 | "solid-js": "^1.7.8",
60 | "tailwind-merge": "^1.14.0"
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/postcss.config.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/prettier.config.cjs:
--------------------------------------------------------------------------------
1 | /** @type {import('prettier').Config} */
2 | module.exports = {
3 | endOfLine: "lf",
4 | semi: false,
5 | singleQuote: false,
6 | tabWidth: 2,
7 | trailingComma: "es5",
8 | importOrderParserPlugins: ["typescript", "jsx", "decorators-legacy"],
9 | plugins: [
10 | "@ianvs/prettier-plugin-sort-imports",
11 | "prettier-plugin-tailwindcss",
12 | ],
13 | }
14 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src-tauri/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "tauri-demos"
3 | version = "0.1.0"
4 | description = "A Tauri App"
5 | authors = ["you"]
6 | license = "MIT"
7 | repository = ""
8 | edition = "2021"
9 |
10 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
11 |
12 | [build-dependencies]
13 | tauri-build = { version = "2.0.0-beta.10", features = [] }
14 |
15 | [dependencies]
16 | serde = { version = "1.0", features = ["derive"] }
17 | serde_json = "1.0"
18 | tauri = { version = "2.0.0-beta.13", features = ["macos-private-api"] }
19 | tauri-plugin-os = "2.0.0-beta.3"
20 | tauri-plugin-shell = "2.0.0-beta.3"
21 |
22 |
23 | [features]
24 | # by default Tauri runs in production mode
25 | # when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL
26 | default = ["custom-protocol"]
27 | # this feature is used used for production builds where `devPath` points to the filesystem
28 | # DO NOT remove this
29 | custom-protocol = ["tauri/custom-protocol"]
30 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src-tauri/build.rs:
--------------------------------------------------------------------------------
1 | fn main() {
2 | tauri_build::build()
3 | }
4 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src-tauri/capabilities/main.json:
--------------------------------------------------------------------------------
1 | {
2 | "identifier": "main-capability",
3 | "description": "Capability for the main window",
4 | "windows": ["main"],
5 | "permissions": [
6 | "path:default",
7 | "event:default",
8 | "window:default",
9 | "window:allow-close",
10 | "window:allow-minimize",
11 | "window:allow-maximize",
12 | "window:allow-start-dragging",
13 | "window:allow-toggle-maximize",
14 | "app:default",
15 | "image:default",
16 | "resources:default",
17 | "menu:default",
18 | "tray:default",
19 | "shell:default",
20 | "os:default"
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src-tauri/gen/schemas/capabilities.json:
--------------------------------------------------------------------------------
1 | {"main-capability":{"identifier":"main-capability","description":"Capability for the main window","local":true,"windows":["main"],"permissions":["path:default","event:default","window:default","window:allow-close","window:allow-minimize","window:allow-maximize","window:allow-start-dragging","window:allow-toggle-maximize","app:default","image:default","resources:default","menu:default","tray:default","shell:default","os:default"]}}
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src-tauri/icons/128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-solid/src-tauri/icons/128x128.png
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src-tauri/icons/128x128@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-solid/src-tauri/icons/128x128@2x.png
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src-tauri/icons/32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-solid/src-tauri/icons/32x32.png
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src-tauri/icons/Square107x107Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-solid/src-tauri/icons/Square107x107Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src-tauri/icons/Square142x142Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-solid/src-tauri/icons/Square142x142Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src-tauri/icons/Square150x150Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-solid/src-tauri/icons/Square150x150Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src-tauri/icons/Square284x284Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-solid/src-tauri/icons/Square284x284Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src-tauri/icons/Square30x30Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-solid/src-tauri/icons/Square30x30Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src-tauri/icons/Square310x310Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-solid/src-tauri/icons/Square310x310Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src-tauri/icons/Square44x44Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-solid/src-tauri/icons/Square44x44Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src-tauri/icons/Square71x71Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-solid/src-tauri/icons/Square71x71Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src-tauri/icons/Square89x89Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-solid/src-tauri/icons/Square89x89Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src-tauri/icons/StoreLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-solid/src-tauri/icons/StoreLogo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src-tauri/icons/icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-solid/src-tauri/icons/icon.icns
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src-tauri/icons/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-solid/src-tauri/icons/icon.ico
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src-tauri/icons/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-solid/src-tauri/icons/icon.png
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src-tauri/src/main.rs:
--------------------------------------------------------------------------------
1 | // Prevents additional console window on Windows in release
2 | #![cfg_attr(
3 | all(not(debug_assertions), target_os = "windows"),
4 | windows_subsystem = "windows"
5 | )]
6 |
7 | // Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
8 | #[tauri::command]
9 | fn greet(name: &str) -> String {
10 | format!("Hello, {}! You've been greeted from Rust!", name)
11 | }
12 |
13 | fn main() {
14 | tauri::Builder::default()
15 | .invoke_handler(tauri::generate_handler![greet])
16 | .plugin(tauri_plugin_os::init())
17 | .plugin(tauri_plugin_shell::init())
18 | .run(tauri::generate_context!())
19 | .expect("error while running tauri application");
20 | }
21 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src-tauri/tauri.conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../node_modules/@tauri-apps/cli/schema.json",
3 | "productName": "tauri-demos",
4 | "identifier": "com.yourname.dev",
5 | "build": {
6 | "beforeDevCommand": "bun run dev",
7 | "beforeBuildCommand": "bun run build",
8 | "devUrl": "http://localhost:1423",
9 | "frontendDist": "../dist"
10 | },
11 | "app": {
12 | "macOSPrivateApi": true,
13 | "security": {
14 | "csp": null
15 | },
16 | "windows": [
17 | {
18 | "title": "Demo-Solid",
19 | "center": true,
20 | "transparent": true,
21 | "decorations": false,
22 | "resizable": true,
23 | "width": 1000,
24 | "height": 800
25 | }
26 | ],
27 | "withGlobalTauri": false
28 | },
29 | "bundle": {
30 | "active": true,
31 | "category": "DeveloperTool",
32 | "copyright": "",
33 | "externalBin": [],
34 | "icon": [
35 | "icons/32x32.png",
36 | "icons/128x128.png",
37 | "icons/128x128@2x.png",
38 | "icons/icon.icns",
39 | "icons/icon.ico"
40 | ],
41 | "longDescription": "",
42 | "macOS": {
43 | "entitlements": null,
44 | "exceptionDomain": "",
45 | "frameworks": [],
46 | "providerShortName": null,
47 | "signingIdentity": null
48 | },
49 | "resources": [],
50 | "shortDescription": "",
51 | "targets": "all",
52 | "windows": {
53 | "certificateThumbprint": null,
54 | "digestAlgorithm": "sha256",
55 | "timestampUrl": "",
56 | "nsis": {
57 | "installerIcon": "./icons/icon.ico"
58 | }
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src/App.tsx:
--------------------------------------------------------------------------------
1 | import "./style.css"
2 | import { For } from "solid-js"
3 | import { WindowControls } from "./tauri-controls/window-controls"
4 | import { WindowTitlebar } from "./tauri-controls/window-titlebar"
5 |
6 | function App() {
7 | return (
8 |
9 |
10 |
11 |
12 | @tauri-controls/solid
13 |
14 |
15 | WindowControls
16 |
17 | {/* OnlyControls */}
18 |
19 | {(x) => }
20 |
21 | justify=true:
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | WindowTitlebar
30 |
31 |
content
32 | {/* Icon+Title Controls */}
33 |
{(x) => }
34 | {/* Icon Menu Title Controls */}
35 |
{(x) => }
36 |
43 |
44 | titlebar content without w-full (macos but on the right side)
45 |
46 |
47 |
54 |
55 | titlebar content without w-full (windows but on the left side)
56 |
57 |
58 |
59 |
60 | )
61 | }
62 |
63 | const platforms = ["windows", "macos", "gnome"]
64 |
65 | const OnlyControls = ({ platform }: any) => {
66 | return
67 | }
68 |
69 | /* Icon+Title Controls */
70 | const IMC = ({ platform }: any) => {
71 | return (
72 |
77 |
81 |
82 | Title
83 |
84 |
85 | )
86 | }
87 |
88 | /* Icon Menu Title Controls */
89 | const IMTC = ({ platform }: any) => {
90 | return (
91 |
99 |
100 |
101 |
102 |
103 |
104 |
108 | Title
109 |
110 |
111 | )
112 | }
113 |
114 | const Menu = () => {
115 | const items = ["File", "Edit", "View", "Account", "Theme"]
116 |
117 | return (
118 |
119 | {(x) => {x} }
120 |
121 | )
122 | }
123 |
124 | const ThemeSwitch = () => {
125 | function toggle() {
126 | document.documentElement.classList.toggle("dark")
127 | }
128 |
129 | return (
130 |
134 | Toggle Theme
135 |
136 | )
137 | }
138 |
139 | const LogoSvg = () => (
140 |
152 |
153 |
154 |
155 |
156 | )
157 |
158 | export default App
159 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src/index.tsx:
--------------------------------------------------------------------------------
1 | /* @refresh reload */
2 | import { render } from "solid-js/web"
3 | import App from "./App"
4 |
5 | render(() => , document.getElementById("root") as HTMLElement)
6 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src/style.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | /* * {
6 | border: 1px solid #7dadf9;
7 | } */
8 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src/tauri-controls/components/button.tsx:
--------------------------------------------------------------------------------
1 | import { splitProps, type ComponentProps } from "solid-js"
2 | import { twMerge } from "tailwind-merge"
3 |
4 | export function Button(props: ComponentProps<"button">) {
5 | const [local, otherProps] = splitProps(props, ["class", "children"])
6 | return (
7 |
14 | {local.children}
15 |
16 | )
17 | }
18 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src/tauri-controls/controls/index.ts:
--------------------------------------------------------------------------------
1 | export { Windows } from "./windows"
2 | export { MacOS } from "./macos"
3 | export { Gnome } from "./linux"
4 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src/tauri-controls/controls/linux/gnome.tsx:
--------------------------------------------------------------------------------
1 | import { splitProps, type ComponentProps } from "solid-js"
2 | import { twMerge } from "tailwind-merge"
3 | import { Button } from "../../components/button"
4 | import { Icons } from "../../components/icons"
5 | import {
6 | closeWindow,
7 | isWindowMaximized,
8 | maximizeWindow,
9 | minimizeWindow,
10 | } from "../../libs/plugin-window"
11 |
12 | export function Gnome(props: ComponentProps<"div">) {
13 | const [local, otherProps] = splitProps(props, ["class"])
14 |
15 | return (
16 |
23 |
27 |
28 |
29 |
33 | {isWindowMaximized() ? (
34 |
35 | ) : (
36 |
37 | )}
38 |
39 |
43 |
44 |
45 |
46 | )
47 | }
48 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src/tauri-controls/controls/linux/index.ts:
--------------------------------------------------------------------------------
1 | export { Gnome } from "./gnome"
2 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src/tauri-controls/controls/macos.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | createSignal,
3 | onCleanup,
4 | onMount,
5 | splitProps,
6 | type ComponentProps,
7 | } from "solid-js"
8 | import { twMerge } from "tailwind-merge"
9 | import { Button } from "../components/button"
10 | import { Icons } from "../components/icons"
11 | import {
12 | closeWindow,
13 | fullscreenWindow,
14 | maximizeWindow,
15 | minimizeWindow,
16 | } from "../libs/plugin-window"
17 |
18 | export function MacOS(props: ComponentProps<"div">) {
19 | const [local, otherProps] = splitProps(props, ["class"])
20 |
21 | const [isAltKeyPressed, setIsAltKeyPressed] = createSignal(false)
22 | const [isHovering, setIsHovering] = createSignal(false)
23 |
24 | const key = "Alt"
25 |
26 | const handleMouseEnter = () => {
27 | setIsHovering(true)
28 | }
29 | const handleMouseLeave = () => {
30 | setIsHovering(false)
31 | }
32 |
33 | const handleAltKeyDown = (e: KeyboardEvent) => {
34 | if (e.key === key) {
35 | setIsAltKeyPressed(true)
36 | }
37 | }
38 | const handleAltKeyUp = (e: KeyboardEvent) => {
39 | if (e.key === key) {
40 | setIsAltKeyPressed(false)
41 | }
42 | }
43 | onMount(() => {
44 | // Attach event listeners when the component mounts
45 | window.addEventListener("keydown", handleAltKeyDown)
46 | window.addEventListener("keyup", handleAltKeyUp)
47 | })
48 |
49 | onCleanup(() => {
50 | // Remove event listeners when the component unmounts
51 | window.removeEventListener("keydown", handleAltKeyDown)
52 | window.removeEventListener("keyup", handleAltKeyUp)
53 | })
54 |
55 | return (
56 |
65 |
69 | {isHovering() && }
70 |
71 |
75 | {isHovering() && }
76 |
77 |
83 | {isHovering() &&
84 | (isAltKeyPressed() ? : )}
85 |
86 |
87 | )
88 | }
89 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src/tauri-controls/controls/windows.tsx:
--------------------------------------------------------------------------------
1 | import { splitProps, type ComponentProps } from "solid-js"
2 | import { twMerge } from "tailwind-merge"
3 | import { Button } from "../components/button"
4 | import { Icons } from "../components/icons"
5 | import {
6 | closeWindow,
7 | isWindowMaximized,
8 | maximizeWindow,
9 | minimizeWindow,
10 | } from "../libs/plugin-window"
11 |
12 | export function Windows(props: ComponentProps<"div">) {
13 | const [local, otherProps] = splitProps(props, ["class"])
14 |
15 | return (
16 |
17 |
21 |
22 |
23 |
31 | {isWindowMaximized() ? (
32 |
33 | ) : (
34 |
35 | )}
36 |
37 |
41 |
42 |
43 |
44 | )
45 | }
46 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src/tauri-controls/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src/tauri-controls/index.ts:
--------------------------------------------------------------------------------
1 | import "./index.css"
2 |
3 | export type { WindowControlsProps, WindowTitlebarProps } from "./types"
4 |
5 | export { WindowControls } from "./window-controls"
6 | export { WindowTitlebar } from "./window-titlebar"
7 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src/tauri-controls/libs/plugin-os.ts:
--------------------------------------------------------------------------------
1 | import type { OsType } from "@tauri-apps/plugin-os"
2 |
3 | let osType: OsType | undefined = undefined
4 | let osTypePromise: Promise | null = null
5 |
6 | if (typeof window !== "undefined") {
7 | osTypePromise = import("@tauri-apps/plugin-os").then((module) => {
8 | return module.type().then((x) => {
9 | osType = x // Assign the value of osType here
10 | return x // Return the value to the promise chain
11 | })
12 | })
13 | }
14 |
15 | // A helper function to get the OS type, which returns a Promise
16 | export function getOsType(): Promise {
17 | if (!osTypePromise) {
18 | // If the module was already loaded, just return the result
19 | return Promise.resolve(osType!) // Use non-null assertion
20 | }
21 |
22 | // If the module is still loading, wait for it to finish and return the result
23 | return osTypePromise
24 | }
25 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src/tauri-controls/libs/plugin-window.ts:
--------------------------------------------------------------------------------
1 | import type { Window } from "@tauri-apps/api/window"
2 | import { createEffect, createSignal, onCleanup } from "solid-js"
3 | import { getOsType } from "./plugin-os"
4 |
5 | export const [appWindow, setAppWindow] = createSignal(null)
6 | export const [isWindowMaximized, setIsWindowMaximized] = createSignal(false)
7 |
8 | import("@tauri-apps/api").then((module) => {
9 | setAppWindow(module.window.getCurrent())
10 | })
11 |
12 | // Update the isWindowMaximized state when the window is resized
13 | const updateIsWindowMaximized = async () => {
14 | const window = appWindow()
15 | if (window) {
16 | const resolvedPromise = await window.isMaximized()
17 | setIsWindowMaximized(resolvedPromise)
18 | }
19 | }
20 |
21 | createEffect(async () => {
22 | const osname = await getOsType()
23 | // temporary: https://github.com/agmmnn/tauri-controls/issues/10#issuecomment-1675884962
24 | if (osname !== "macos") {
25 | updateIsWindowMaximized()
26 | let unlisten: () => void = () => {}
27 |
28 | const window = appWindow()
29 | if (window) {
30 | unlisten = await window.onResized(() => {
31 | updateIsWindowMaximized()
32 | })
33 | }
34 |
35 | // Cleanup the listener when the component unmounts
36 | unlisten && onCleanup(unlisten)
37 | }
38 | })
39 |
40 | export const minimizeWindow = async () => {
41 | await appWindow()?.minimize()
42 | }
43 |
44 | export const maximizeWindow = async () => {
45 | await appWindow()?.toggleMaximize()
46 | }
47 |
48 | export const fullscreenWindow = async () => {
49 | const window = appWindow()
50 | if (window) {
51 | const fullscreen = await window.isFullscreen()
52 | await window.setFullscreen(!fullscreen)
53 | }
54 | }
55 |
56 | export const closeWindow = async () => {
57 | await appWindow()?.close()
58 | }
59 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src/tauri-controls/types.ts:
--------------------------------------------------------------------------------
1 | import type { ComponentProps } from "solid-js"
2 |
3 | /**
4 | * Interface for window controls.
5 | * If the `platform` property is not specified, the library will automatically detect
6 | * the operating system the app is running on and display the appropriate elements.
7 | */
8 | export interface WindowControlsProps extends ComponentProps<"div"> {
9 | /**
10 | * Specifies which platform's window controls to display.
11 | * It can be one of "windows", "macos", or "gnome".
12 | * If the `platform` property is not specified, the library will automatically detect
13 | * the operating system the app is running on and display the appropriate elements.
14 | */
15 | platform?: "windows" | "macos" | "gnome"
16 |
17 | /**
18 | * Indicates whether the window controls should be shown or hidden.
19 | * @default false
20 | */
21 | hide?: boolean
22 |
23 | /**
24 | * - "display": "display: none;" making them completely invisible and not taking up any space.
25 | * - "visibility": "visibility: hidden;" making them invisible but still occupying the same space.
26 | * @default "display"
27 | */
28 | hideMethod?: "display" | "visibility"
29 |
30 | /**
31 | * Justify/Snap WindowControls
32 | *
33 | * @default false, (if not defined in WindowTitlebar automatically assigned)
34 | */
35 | justify?: boolean
36 |
37 | /**
38 | * Specifies the Linux desktop environment for which the window controls are intended.
39 | * This property is applicable only when the platform is set to "linux".
40 | * @default "gnome"
41 | */
42 | // linuxDesktop?: "gnome" | "kde" | "budgie"
43 |
44 | /**
45 | * Indicates whether to prevent the right-click context menu.
46 | * When set to true, it will prevent the default right-click behavior.
47 | * (only in production, default false)
48 | */
49 | // preventRightClickMenu?: "always" | "production"
50 |
51 | /** `data-tauri-drag-region` */
52 | "data-tauri-drag-region"?: boolean
53 | }
54 |
55 | /**
56 | * Interface for titlebar
57 | */
58 | export interface WindowTitlebarProps extends ComponentProps<"div"> {
59 | /**
60 | * The `controlsOrder` property is an optional property used in the `WindowControls` interface.
61 | * It allows you to specify the order in which the window controls should be rendered relative to the children.
62 | * (default: system)
63 | *
64 | * When `controlsOrder` is not specified or set to `system`, the default behavior will be as follows:
65 | * - For platforms other than macOS, the controls will be on the right side of the children.
66 | * - For macOS, the controls will be on the left side of the children (similar to "left" option).
67 | *
68 | * Possible values for `controlsOrder`:
69 | * - "right": The window controls will be rendered to the right of the children.
70 | * - "left": The window controls will be rendered to the left of the children. This order applies only when the platform is macOS (macOS window controls are usually located on the left side of the title bar).
71 | * - "platform": for OS-based positioning specified in `windowControlsProps`
72 | * @default "system"
73 | */
74 | controlsOrder?: "right" | "left" | "platform" | "system"
75 |
76 | /**
77 | * `WindowControls` props
78 | */
79 | windowControlsProps?: WindowControlsProps
80 | }
81 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src/tauri-controls/window-controls.tsx:
--------------------------------------------------------------------------------
1 | import { Match, mergeProps, onMount, splitProps, Switch } from "solid-js"
2 | import { twMerge } from "tailwind-merge"
3 | import { Gnome, MacOS, Windows } from "./controls"
4 | import { getOsType } from "./libs/plugin-os"
5 | import type { WindowControlsProps } from "./types"
6 |
7 | export function WindowControls(props: WindowControlsProps) {
8 | const [rawLocal, otherProps] = splitProps(props, [
9 | "class",
10 | "hideMethod",
11 | "hide",
12 | "platform",
13 | "justify",
14 | ])
15 |
16 | const local = mergeProps(
17 | {
18 | justify: false,
19 | hide: false,
20 | hideMethod: "display",
21 | },
22 | rawLocal
23 | )
24 |
25 | onMount(() => {
26 | getOsType().then((type) => {
27 | if (!local.platform) {
28 | switch (type) {
29 | case "macos":
30 | local.platform = "macos"
31 | break
32 | case "linux":
33 | local.platform = "gnome"
34 | break
35 | default:
36 | local.platform = "windows"
37 | }
38 | }
39 | })
40 | })
41 |
42 | const customClass = twMerge(
43 | "flex",
44 | local.class,
45 | local.hide && (local.hideMethod === "display" ? "hidden" : "invisible")
46 | )
47 |
48 | // Determine the default platform based on the operating system if not specified
49 | return (
50 |
56 | }
57 | >
58 |
59 |
63 |
64 |
65 |
69 |
70 |
71 |
75 |
76 |
77 | )
78 | }
79 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/src/tauri-controls/window-titlebar.tsx:
--------------------------------------------------------------------------------
1 | import type { OsType } from "@tauri-apps/plugin-os"
2 | import { createSignal, mergeProps, onMount, splitProps } from "solid-js"
3 | import { twMerge } from "tailwind-merge"
4 | import { getOsType } from "./libs/plugin-os"
5 | import type { WindowTitlebarProps } from "./types"
6 | import { WindowControls } from "./window-controls"
7 |
8 | export function WindowTitlebar(props: WindowTitlebarProps) {
9 | const [osType, setOsType] = createSignal(undefined)
10 |
11 | const [rawLocal, otherProps] = splitProps(props, [
12 | "children",
13 | "controlsOrder",
14 | "class",
15 | "windowControlsProps",
16 | ])
17 |
18 | const local = mergeProps(
19 | {
20 | controlsOrder: "system",
21 | },
22 | rawLocal
23 | )
24 |
25 | onMount(() => {
26 | getOsType().then((type) => {
27 | setOsType(type)
28 | })
29 | })
30 |
31 | const left = () =>
32 | local.controlsOrder === "left" ||
33 | (local.controlsOrder === "platform" &&
34 | local.windowControlsProps?.platform === "macos") ||
35 | (local.controlsOrder === "system" && osType() === "macos")
36 |
37 | const customProps = (ml: string) => {
38 | if (local.windowControlsProps?.justify !== undefined)
39 | return local.windowControlsProps
40 |
41 | const {
42 | justify: windowControlsJustify,
43 | class: windowControlsClassName,
44 | ...restProps
45 | } = local.windowControlsProps || {}
46 | return {
47 | justify: false,
48 | class: twMerge(windowControlsClassName, ml),
49 | ...restProps,
50 | }
51 | }
52 |
53 | return (
54 |
62 | {left() ? (
63 | <>
64 |
65 | {local.children}
66 | >
67 | ) : (
68 | <>
69 | {local.children}
70 |
71 | >
72 | )}
73 |
74 | )
75 | }
76 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | darkMode: "class",
4 | content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
5 | // content: ["./src/tauri-controls/**/*.{js,ts,jsx,tsx}"],
6 | theme: {
7 | extend: {},
8 | },
9 | plugins: [],
10 | }
11 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/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 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "noEmit": true,
15 | "jsx": "preserve",
16 | "jsxImportSource": "solid-js",
17 |
18 | /* Linting */
19 | "strict": true,
20 | "noUnusedLocals": true,
21 | "noUnusedParameters": true,
22 | "noFallthroughCasesInSwitch": true
23 | },
24 | "include": ["src"],
25 | "references": [{ "path": "./tsconfig.node.json" }]
26 | }
27 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "skipLibCheck": true,
5 | "module": "ESNext",
6 | "moduleResolution": "bundler",
7 | "allowSyntheticDefaultImports": true
8 | },
9 | "include": ["vite.config.ts"]
10 | }
11 |
--------------------------------------------------------------------------------
/apps/tauri-controls-solid/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { resolve } from "node:path"
2 | import terser from "@rollup/plugin-terser"
3 | import { defineConfig } from "vite"
4 | import dts from "vite-plugin-dts"
5 | import solidPlugin from "vite-plugin-solid"
6 | import * as packageJson from "./package.json"
7 |
8 | // https://vitejs.dev/config/
9 | export default defineConfig((_) => ({
10 | plugins: [
11 | dts({
12 | include: ["./src/tauri-controls"],
13 | rollupTypes: true,
14 | }),
15 | solidPlugin(),
16 | ],
17 |
18 | build: {
19 | lib: {
20 | entry: resolve("src", "tauri-controls/index.ts"),
21 | name: "TauriControls",
22 | formats: ["es"], //"umd"
23 | fileName: () => `tauri-controls.js`,
24 | },
25 | rollupOptions: {
26 | external: [...Object.keys(packageJson.peerDependencies)],
27 | plugins: [terser()],
28 | output: {
29 | globals: {
30 | react: "React",
31 | "react-dom": "ReactDOM",
32 | "@tauri-apps/plugin-os": "pluginOs",
33 | clsx: "clsx",
34 | "tailwind-merge": "tailwindMerge",
35 | "@tauri-apps/plugin-window": "pluginWindow",
36 | },
37 | intro: 'import "./style.css";',
38 | plugins: [terser()],
39 | },
40 | },
41 | },
42 |
43 | // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
44 | //
45 | // 1. prevent vite from obscuring rust errors
46 | clearScreen: false,
47 | // 2. tauri expects a fixed port, fail if that port is not available
48 | server: {
49 | port: 1423,
50 | strictPort: true,
51 | },
52 | // 3. to make use of `TAURI_DEBUG` and other env variables
53 | // https://tauri.studio/v1/api/config#buildconfig.beforedevcommand
54 | envPrefix: ["VITE_", "TAURI_"],
55 | }))
56 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/.eslintignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /build
4 | /.svelte-kit
5 | /package
6 | .env
7 | .env.*
8 | !.env.example
9 | .turbo
10 |
11 | # Ignore files for PNPM, NPM and YARN
12 | pnpm-lock.yaml
13 | package-lock.json
14 | yarn.lock
15 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | root: true,
3 | extends: [
4 | "eslint:recommended",
5 | "plugin:@typescript-eslint/recommended",
6 | "plugin:svelte/recommended",
7 | "prettier"
8 | ],
9 | parser: "@typescript-eslint/parser",
10 | plugins: ["@typescript-eslint"],
11 | parserOptions: {
12 | sourceType: "module",
13 | ecmaVersion: 2020,
14 | extraFileExtensions: [".svelte"]
15 | },
16 | env: {
17 | browser: true,
18 | es2017: true,
19 | node: true
20 | },
21 | overrides: [
22 | {
23 | files: ["*.svelte"],
24 | parser: "svelte-eslint-parser",
25 | parserOptions: {
26 | parser: "@typescript-eslint/parser"
27 | }
28 | }
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /build
4 | /dist
5 | /.svelte-kit
6 | /package
7 | .env
8 | .env.*
9 | !.env.example
10 | vite.config.js.timestamp-*
11 | vite.config.ts.timestamp-*
12 | .turbo
13 | *.tgz
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/.npmrc:
--------------------------------------------------------------------------------
1 | engine-strict=true
2 | resolution-mode=highest
3 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/.prettierignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /build
4 | dist
5 | .svelte-kit
6 | /package
7 | .env
8 | .env.*
9 | !.env.example
10 | /src-tauri/target
11 | .turbo
12 |
13 | # Ignore files for PNPM, NPM and YARN
14 | pnpm-lock.yaml
15 | package-lock.json
16 | yarn.lock
17 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # @tauri-controls/svelte
2 |
3 | ## 0.4.0
4 |
5 | ### Minor Changes
6 |
7 | - fix: compatibility with the latest Tauri V2 release
8 | chore: switch package manager from pnpm to bun
9 |
10 | ## 0.3.0
11 |
12 | ### Minor Changes
13 |
14 | - fix: Remove all Tauri dependencies from the list of dependecies. This will require the user to install these (which were already in the instructions), but allow for more control of a single version of these packages. #20, thanks to @jbolda
15 |
16 | ## 0.2.0
17 |
18 | ### Minor Changes
19 |
20 | - fix: compatibility with the latest Tauri release
21 |
22 | ## 0.1.2
23 |
24 | ### Patch Changes
25 |
26 | - feat: gnome more accurate button spacing, fix icons sizes (svelte, vue)
27 | feat: macos controls use space instead of mr, px-2 to px-3
28 | chore: demo-app gap to space, update deps, format code
29 |
30 | ## 0.1.1
31 |
32 | ### Patch Changes
33 |
34 | - Add [changeset](https://github.com/changesets/changesets)
35 | - Add [publish-packages script](https://turbo.build/repo/docs/handbook/publishing-packages/versioning-and-publishing#using-changesets-with-turborepo)
36 | - Add License file
37 | - Update readme files
38 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 agmmnn
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 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 
7 | 
8 | 
9 |
10 | ## @tauri-controls/svelte
11 |
12 | ```bash
13 | pnpm add @tauri-controls/svelte
14 | ```
15 |
16 | https://github.com/agmmnn/tauri-controls
17 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/bun.lockb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-svelte/bun.lockb
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@tauri-controls/svelte",
3 | "description": "🚥 Native-looking window controls for Tauri 2.",
4 | "private": false,
5 | "version": "0.4.0",
6 | "type": "module",
7 | "license": "MIT",
8 | "scripts": {
9 | "dev": "vite dev",
10 | "build": "vite build && npm run package",
11 | "build:tailwind": "tailwind -c ./tailwind-build.config.js -i ./src/lib/index.css -o ./dist/index.css",
12 | "build:watch": "vite build --watch",
13 | "preview": "vite preview",
14 | "package": "svelte-kit sync && svelte-package && publint",
15 | "prepublishOnly": "npm run package",
16 | "test": "npm run test:integration && npm run test:unit",
17 | "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
18 | "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
19 | "lint": "prettier --plugin-search-dir . --check . && eslint .",
20 | "format": "prettier --write --plugin prettier-plugin-svelte .",
21 | "test:integration": "playwright test",
22 | "test:unit": "vitest",
23 | "sw": "svelte-package -w",
24 | "tauri": "tauri",
25 | "tauri:dev": "tauri dev"
26 | },
27 | "publishConfig": {
28 | "access": "public"
29 | },
30 | "repository": {
31 | "type": "git",
32 | "url": "https://github.com/agmmnn/tauri-controls"
33 | },
34 | "author": "agmmnn",
35 | "bugs": {
36 | "url": "https://github.com/agmmnn/tauri-controls/issues"
37 | },
38 | "homepage": "https://github.com/agmmnn/tauri-controls#readme",
39 | "svelte": "./dist/index.js",
40 | "types": "./dist/index.d.ts",
41 | "exports": {
42 | ".": {
43 | "types": "./dist/index.d.ts",
44 | "svelte": "./dist/index.js",
45 | "WindowControls.svelte": "./dist/WindowControls.svelte",
46 | "WindowTitlebar.svelte": "./dist/WindowTitlebar.svelte"
47 | }
48 | },
49 | "files": [
50 | "dist",
51 | "!dist/**/*.test.*",
52 | "!dist/**/*.spec.*"
53 | ],
54 | "devDependencies": {
55 | "@ianvs/prettier-plugin-sort-imports": "^4.2.1",
56 | "@playwright/test": "^1.42.1",
57 | "@rollup/plugin-node-resolve": "^15.2.3",
58 | "@rollup/plugin-terser": "^0.4.4",
59 | "@sveltejs/adapter-auto": "^3.1.1",
60 | "@sveltejs/kit": "^2.5.4",
61 | "@sveltejs/package": "^2.3.0",
62 | "@tauri-apps/api": "2.0.0-beta.6",
63 | "@tauri-apps/cli": "2.0.0-beta.11",
64 | "@tauri-apps/plugin-os": "2.0.0-beta.2",
65 | "@typescript-eslint/eslint-plugin": "^7.3.1",
66 | "@typescript-eslint/parser": "^7.3.1",
67 | "autoprefixer": "^10.4.19",
68 | "eslint": "^8.57.0",
69 | "eslint-config-prettier": "^9.1.0",
70 | "eslint-plugin-svelte": "^2.35.1",
71 | "esm-env": "^1.0.0",
72 | "postcss": "^8.4.38",
73 | "prettier": "^3.2.5",
74 | "prettier-plugin-svelte": "^3.2.2",
75 | "prettier-plugin-tailwindcss": "^0.5.12",
76 | "publint": "^0.2.7",
77 | "rollup-plugin-svelte": "^7.2.0",
78 | "svelte": "^4.2.12",
79 | "svelte-check": "^3.6.8",
80 | "tailwindcss": "^3.4.1",
81 | "taze": "^0.13.3",
82 | "tslib": "^2.6.2",
83 | "typescript": "^5.4.3",
84 | "vite": "^5.2.4",
85 | "vite-plugin-dts": "^3.7.3",
86 | "vitest": "^1.4.0"
87 | },
88 | "peerDependencies": {
89 | "clsx": "^2.0.0",
90 | "svelte": "^4.1.2",
91 | "tailwind-merge": "^1.14.0"
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/playwright.config.ts:
--------------------------------------------------------------------------------
1 | import type { PlaywrightTestConfig } from "@playwright/test"
2 |
3 | const config: PlaywrightTestConfig = {
4 | webServer: {
5 | command: "npm run build && npm run preview",
6 | port: 4173
7 | },
8 | testDir: "tests",
9 | testMatch: /(.+\.)?(test|spec)\.[jt]s/
10 | }
11 |
12 | export default config
13 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/postcss.config.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {}
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/prettier.config.cjs:
--------------------------------------------------------------------------------
1 | /** @type {import('prettier').Config} */
2 | module.exports = {
3 | endOfLine: "lf",
4 | semi: false,
5 | singleQuote: false,
6 | tabWidth: 2,
7 | trailingComma: "none",
8 | plugins: [
9 | "prettier-plugin-svelte",
10 | "@ianvs/prettier-plugin-sort-imports",
11 | "prettier-plugin-tailwindcss"
12 | ],
13 | overrides: [{ files: "*.svelte", options: { parser: "svelte" } }]
14 | }
15 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/.gitignore:
--------------------------------------------------------------------------------
1 | # Generated by Cargo
2 | # will have compiled files and executables
3 | /target/
4 |
5 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "tauri-demos"
3 | version = "0.1.0"
4 | description = "A Tauri App"
5 | authors = ["you"]
6 | license = "MIT"
7 | repository = ""
8 | edition = "2021"
9 |
10 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
11 |
12 | [build-dependencies]
13 | tauri-build = { version = "2.0.0-beta.10", features = [] }
14 |
15 | [dependencies]
16 | serde = { version = "1.0", features = ["derive"] }
17 | serde_json = "1.0"
18 | tauri = { version = "2.0.0-beta.13", features = ["macos-private-api"] }
19 | tauri-plugin-os = "2.0.0-beta.3"
20 | tauri-plugin-shell = "2.0.0-beta.3"
21 |
22 |
23 | [features]
24 | # by default Tauri runs in production mode
25 | # when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL
26 | default = ["custom-protocol"]
27 | # this feature is used used for production builds where `devPath` points to the filesystem
28 | # DO NOT remove this
29 | custom-protocol = ["tauri/custom-protocol"]
30 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/build.rs:
--------------------------------------------------------------------------------
1 | fn main() {
2 | tauri_build::build()
3 | }
4 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/capabilities/main.json:
--------------------------------------------------------------------------------
1 | {
2 | "identifier": "main-capability",
3 | "description": "Capability for the main window",
4 | "windows": [
5 | "main"
6 | ],
7 | "permissions": [
8 | "path:default",
9 | "event:default",
10 | "window:default",
11 | "window:allow-close",
12 | "window:allow-minimize",
13 | "window:allow-maximize",
14 | "window:allow-start-dragging",
15 | "window:allow-toggle-maximize",
16 | "app:default",
17 | "image:default",
18 | "resources:default",
19 | "menu:default",
20 | "tray:default",
21 | "shell:default",
22 | "os:default"
23 | ]
24 | }
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/gen/schemas/capabilities.json:
--------------------------------------------------------------------------------
1 | {"main-capability":{"identifier":"main-capability","description":"Capability for the main window","local":true,"windows":["main"],"permissions":["path:default","event:default","window:default","window:allow-close","window:allow-minimize","window:allow-maximize","window:allow-start-dragging","window:allow-toggle-maximize","app:default","image:default","resources:default","menu:default","tray:default","shell:default","os:default"]}}
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/icons/128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-svelte/src-tauri/icons/128x128.png
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/icons/128x128@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-svelte/src-tauri/icons/128x128@2x.png
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/icons/32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-svelte/src-tauri/icons/32x32.png
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/icons/Square107x107Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-svelte/src-tauri/icons/Square107x107Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/icons/Square142x142Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-svelte/src-tauri/icons/Square142x142Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/icons/Square150x150Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-svelte/src-tauri/icons/Square150x150Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/icons/Square284x284Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-svelte/src-tauri/icons/Square284x284Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/icons/Square30x30Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-svelte/src-tauri/icons/Square30x30Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/icons/Square310x310Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-svelte/src-tauri/icons/Square310x310Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/icons/Square44x44Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-svelte/src-tauri/icons/Square44x44Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/icons/Square71x71Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-svelte/src-tauri/icons/Square71x71Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/icons/Square89x89Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-svelte/src-tauri/icons/Square89x89Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/icons/StoreLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-svelte/src-tauri/icons/StoreLogo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/icons/icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-svelte/src-tauri/icons/icon.icns
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/icons/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-svelte/src-tauri/icons/icon.ico
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/icons/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-svelte/src-tauri/icons/icon.png
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/src/main.rs:
--------------------------------------------------------------------------------
1 | // Prevents additional console window on Windows in release
2 | #![cfg_attr(
3 | all(not(debug_assertions), target_os = "windows"),
4 | windows_subsystem = "windows"
5 | )]
6 |
7 | // Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
8 | #[tauri::command]
9 | fn greet(name: &str) -> String {
10 | format!("Hello, {}! You've been greeted from Rust!", name)
11 | }
12 |
13 | fn main() {
14 | tauri::Builder::default()
15 | .invoke_handler(tauri::generate_handler![greet])
16 | .plugin(tauri_plugin_os::init())
17 | .plugin(tauri_plugin_shell::init())
18 | .run(tauri::generate_context!())
19 | .expect("error while running tauri application");
20 | }
21 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src-tauri/tauri.conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../node_modules/@tauri-apps/cli/schema.json",
3 | "productName": "tauri-demos",
4 | "identifier": "com.yourname.dev",
5 | "build": {
6 | "beforeDevCommand": "bun run dev",
7 | "beforeBuildCommand": "bun run build",
8 | "devUrl": "http://localhost:1422",
9 | "frontendDist": "../dist"
10 | },
11 | "app": {
12 | "macOSPrivateApi": true,
13 | "security": {
14 | "csp": null
15 | },
16 | "windows": [
17 | {
18 | "title": "Demo-Solid",
19 | "center": true,
20 | "transparent": true,
21 | "decorations": false,
22 | "resizable": true,
23 | "width": 1000,
24 | "height": 800
25 | }
26 | ],
27 | "withGlobalTauri": false
28 | },
29 | "bundle": {
30 | "active": true,
31 | "category": "DeveloperTool",
32 | "copyright": "",
33 | "externalBin": [],
34 | "icon": [
35 | "icons/32x32.png",
36 | "icons/128x128.png",
37 | "icons/128x128@2x.png",
38 | "icons/icon.icns",
39 | "icons/icon.ico"
40 | ],
41 | "longDescription": "",
42 | "macOS": {
43 | "entitlements": null,
44 | "exceptionDomain": "",
45 | "frameworks": [],
46 | "providerShortName": null,
47 | "signingIdentity": null
48 | },
49 | "resources": [],
50 | "shortDescription": "",
51 | "targets": "all",
52 | "windows": {
53 | "certificateThumbprint": null,
54 | "digestAlgorithm": "sha256",
55 | "timestampUrl": "",
56 | "nsis": {
57 | "installerIcon": "./icons/icon.ico"
58 | }
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src/app.d.ts:
--------------------------------------------------------------------------------
1 | // See https://kit.svelte.dev/docs/types#app
2 | // for information about these interfaces
3 | declare global {
4 | namespace App {
5 | // interface Error {}
6 | // interface Locals {}
7 | // interface PageData {}
8 | // interface Platform {}
9 | }
10 | }
11 |
12 | export {}
13 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src/app.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | %sveltekit.head%
8 |
9 |
13 | %sveltekit.body%
14 |
15 |
16 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src/index.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from "vitest"
2 |
3 | describe("sum test", () => {
4 | it("adds 1 + 2 to equal 3", () => {
5 | expect(1 + 2).toBe(3)
6 | })
7 | })
8 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src/lib/WindowControls.svelte:
--------------------------------------------------------------------------------
1 |
33 |
34 | {#if platform === "windows"}
35 |
36 | {:else if platform === "macos"}
37 |
38 | {:else if platform === "gnome"}
39 |
40 | {:else}
41 |
42 | {/if}
43 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src/lib/WindowTitlebar.svelte:
--------------------------------------------------------------------------------
1 |
31 |
32 |
40 | {#if left}
41 |
42 |
43 | {:else}
44 |
45 |
46 | {/if}
47 |
48 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src/lib/components/Button.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src/lib/components/Icons.svelte:
--------------------------------------------------------------------------------
1 |
4 |
5 | {#if icon === "minimizeWin"}
6 |
14 |
19 |
20 | {:else if icon === "maximizeWin"}
21 |
29 |
34 |
35 | {:else if icon === "maximizeRestoreWin"}
36 |
44 |
49 |
50 | {:else if icon === "closeWin"}
51 |
59 |
64 |
65 | {:else if icon === "closeMac"}
66 |
74 |
78 |
79 | {:else if icon === "minMac"}
80 |
88 |
89 |
95 |
96 |
97 | {:else if icon === "fullMac"}
98 |
106 |
107 |
113 |
114 |
115 | {:else if icon === "plusMac"}
116 |
124 |
125 |
131 |
132 |
133 | {/if}
134 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src/lib/controls/MacOs.svelte:
--------------------------------------------------------------------------------
1 |
61 |
62 |
73 |
77 | {#if isHovering}
78 |
79 | {/if}
80 |
81 |
85 | {#if isHovering}
86 |
87 | {/if}
88 |
89 |
93 | {#if isHovering}
94 | {#if isAltKeyPressed}
95 |
96 | {:else}
97 |
98 | {/if}
99 | {/if}
100 |
101 |
102 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src/lib/controls/Windows.svelte:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 | minimizeWindow()}
23 | class="max-h-8 w-[46px] cursor-default rounded-none bg-transparent text-black/90 hover:bg-black/[.05] active:bg-black/[.03] dark:text-white dark:hover:bg-white/[.06] dark:active:bg-white/[.04]"
24 | >
25 |
26 |
27 | maximizeWindow()}
29 | class={cn(
30 | "max-h-8 w-[46px] cursor-default rounded-none bg-transparent",
31 | "text-black/90 hover:bg-black/[.05] active:bg-black/[.03] dark:text-white dark:hover:bg-white/[.06] dark:active:bg-white/[.04]"
32 | // !isMaximizable && "text-white/[.36]",
33 | )}
34 | >
35 | {#if isWindowMaximized}
36 |
37 | {:else}
38 |
39 | {/if}
40 |
41 | closeWindow()}
43 | class="max-h-8 w-[46px] cursor-default rounded-none bg-transparent text-black/90 hover:bg-[#c42b1c] hover:text-white active:bg-[#c42b1c]/90 dark:text-white"
44 | >
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src/lib/controls/linux/Gnome.svelte:
--------------------------------------------------------------------------------
1 |
19 |
20 |
24 | minimizeWindow()}
26 | class="m-0 aspect-square h-6 w-6 cursor-default rounded-full bg-[#dadada] p-0 text-[#3d3d3d] hover:bg-[#d1d1d1] active:bg-[#bfbfbf] dark:bg-[#373737] dark:text-white dark:hover:bg-[#424242] dark:active:bg-[#565656]"
27 | >
28 |
29 |
30 | maximizeWindow()}
32 | class="m-0 aspect-square h-6 w-6 cursor-default rounded-full bg-[#dadada] p-0 text-[#3d3d3d] hover:bg-[#d1d1d1] active:bg-[#bfbfbf] dark:bg-[#373737] dark:text-white dark:hover:bg-[#424242] dark:active:bg-[#565656]"
33 | >
34 | {#if isWindowMaximized}
35 |
36 | {:else}
37 |
38 | {/if}
39 |
40 | closeWindow()}
42 | class="m-0 aspect-square h-6 w-6 cursor-default rounded-full bg-[#dadada] p-0 text-[#3d3d3d] hover:bg-[#d1d1d1] active:bg-[#bfbfbf] dark:bg-[#373737] dark:text-white dark:hover:bg-[#424242] dark:active:bg-[#565656]"
43 | >
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src/lib/index.ts:
--------------------------------------------------------------------------------
1 | // import "../style.css"
2 | import WindowControls from "$lib/WindowControls.svelte"
3 | import WindowTitlebar from "$lib/WindowTitlebar.svelte"
4 |
5 | export type { WindowControlsProps, WindowTitlebarProps } from "./types"
6 |
7 | export { WindowControls, WindowTitlebar }
8 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src/lib/types.ts:
--------------------------------------------------------------------------------
1 | import type { HTMLAttributes } from "svelte/elements"
2 |
3 | /**
4 | * Interface for window controls.
5 | * If the `platform` property is not specified, the library will automatically detect
6 | * the operating system the app is running on and display the appropriate elements.
7 | */
8 | export interface WindowControlsProps extends HTMLAttributes {
9 | /**
10 | * Specifies which platform's window controls to display.
11 | * It can be one of "windows", "macos", or "gnome".
12 | * If the `platform` property is not specified, the library will automatically detect
13 | * the operating system the app is running on and display the appropriate elements.
14 | */
15 | platform?: "windows" | "macos" | "gnome"
16 |
17 | /**
18 | * Indicates whether the window controls should be shown or hidden.
19 | * (default: false)
20 | */
21 | hide?: boolean
22 |
23 | /**
24 | * - "display": "display: none;" making them completely invisible and not taking up any space.
25 | * - "visibility": "visibility: hidden;" making them invisible but still occupying the same space.
26 | * (default: "display")
27 | */
28 | hideMethod?: "display" | "visibility"
29 |
30 | /**
31 | * Justify/Snap WindowControls
32 | *
33 | * @default false, (if not defined in WindowTitlebar automatically assigned)
34 | */
35 | justify?: boolean
36 |
37 | /**
38 | * Specifies the Linux desktop environment for which the window controls are intended.
39 | * This property is applicable only when the platform is set to "linux".
40 | * (default: "gnome")
41 | */
42 | // linuxDesktop?: "gnome" | "kde" | "budgie"
43 |
44 | /**
45 | * Indicates whether to prevent the right-click context menu.
46 | * When set to true, it will prevent the default right-click behavior.
47 | * (only in production, default false)
48 | */
49 | // preventRightClickMenu?: "always" | "production"
50 |
51 | /** `data-tauri-drag-region` */
52 | "data-tauri-drag-region"?: boolean
53 | }
54 |
55 | /**
56 | * Interface for titlebar
57 | */
58 | export interface WindowTitlebarProps extends HTMLAttributes {
59 | /**
60 | * The `controlsOrder` property is an optional property used in the `WindowControls` interface.
61 | * It allows you to specify the order in which the window controls should be rendered relative to the children.
62 | * (default: system)
63 | *
64 | * When `controlsOrder` is not specified or set to `system`, the default behavior will be as follows:
65 | * - For platforms other than macOS, the controls will be on the right side of the children.
66 | * - For macOS, the controls will be on the left side of the children (similar to "left" option).
67 | *
68 | * Possible values for `controlsOrder`:
69 | * - "right": The window controls will be rendered to the right of the children.
70 | * - "left": The window controls will be rendered to the left of the children. This order applies only when the platform is macOS (macOS window controls are usually located on the left side of the title bar).
71 | * - "platform": for OS-based positioning specified in `windowControlsProps`
72 | */
73 | controlsOrder?: "right" | "left" | "platform" | "system"
74 |
75 | /**
76 | * `WindowControls` props
77 | */
78 | windowControlsProps?: WindowControlsProps
79 | }
80 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src/lib/utils/os.ts:
--------------------------------------------------------------------------------
1 | import type { OsType } from "@tauri-apps/plugin-os"
2 |
3 | export let osType: OsType
4 |
5 | if (typeof window !== "undefined") {
6 | import("@tauri-apps/plugin-os").then((module) => {
7 | module.type().then((x) => (osType = x))
8 | })
9 | }
10 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src/lib/utils/utils.ts:
--------------------------------------------------------------------------------
1 | import { clsx, type ClassValue } from "clsx"
2 | import { twMerge } from "tailwind-merge"
3 |
4 | export function cn(...inputs: ClassValue[]) {
5 | return twMerge(clsx(inputs))
6 | }
7 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src/lib/utils/window.ts:
--------------------------------------------------------------------------------
1 | import type { Window } from "@tauri-apps/api/window"
2 | import { writable, type Writable, get } from "svelte/store"
3 |
4 | export let appWindow: Writable = writable(undefined);
5 |
6 | export const initializeAppWindow = async () => {
7 | import("@tauri-apps/api").then((mod) => {
8 | appWindow.set(mod.window.getCurrent());
9 | })
10 | }
11 |
12 | export const minimizeWindow = () => {
13 | get(appWindow)?.minimize()
14 | }
15 |
16 | export const maximizeWindow = async () => {
17 | await get(appWindow)?.toggleMaximize()
18 | }
19 |
20 | export const closeWindow = () => {
21 | get(appWindow)?.close()
22 | }
23 |
24 | export const fullscreenWindow = async () => {
25 | const fullscreen = await get(appWindow)?.isFullscreen()
26 |
27 | if (fullscreen) {
28 | await get(appWindow)?.setFullscreen(false)
29 | } else {
30 | await get(appWindow)?.setFullscreen(true)
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src/routes/+page.svelte:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 | Demo-Svelte
12 |
13 |
14 |
17 |
18 |
19 |
@tauri-controls/svelte
22 |
25 | WindowControls
26 |
27 |
28 |
31 | {#each platforms as platform}
32 |
33 | {/each}
34 |
35 |
36 |
37 | justify=true:
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
48 | WindowTitlebar
49 |
50 |
51 |
content
52 |
53 |
54 | {#each platforms as platform}
55 |
60 |
64 |
76 |
77 |
78 |
79 |
80 | Title
81 |
82 |
83 | {/each}
84 |
85 |
86 | {#each platforms as platform}
87 |
95 |
96 |
108 |
109 |
110 |
111 |
112 |
115 | {#each menuItems as x (x)}
116 | {x}
117 | {/each}
118 |
119 |
120 |
121 |
125 | Title
126 |
127 |
128 | {/each}
129 |
130 |
137 |
140 | titlebar content without w-full (macos but on the right side)
141 |
142 |
143 |
150 |
153 | titlebar content without w-full (windows but on the left side)
154 |
155 |
156 |
157 |
158 |
159 |
167 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src/routes/theme-switch.svelte:
--------------------------------------------------------------------------------
1 |
6 |
7 |
11 | Toggle Theme
12 |
13 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/src/style.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/static/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-svelte/static/favicon.png
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/svelte.config.js:
--------------------------------------------------------------------------------
1 | import adapter from "@sveltejs/adapter-auto"
2 | import { vitePreprocess } from "@sveltejs/vite-plugin-svelte"
3 |
4 | /** @type {import('@sveltejs/kit').Config} */
5 | const config = {
6 | kit: {
7 | // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
8 | // If your environment is not supported or you settled on a specific environment, switch out the adapter.
9 | // See https://kit.svelte.dev/docs/adapters for more information about adapters.
10 | adapter: adapter(),
11 | alias: {
12 | $lib: "src/lib"
13 | }
14 | },
15 |
16 | preprocess: [vitePreprocess({})]
17 | }
18 |
19 | export default config
20 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/tailwind-build.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | darkMode: "class",
4 | content: ["./src/lib/**/*.{js,svelte,ts}"],
5 | theme: {
6 | extend: {}
7 | },
8 | plugins: []
9 | }
10 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | darkMode: "class",
4 | content: ["./src/**/*.{html,js,svelte,ts}"],
5 | theme: {
6 | extend: {}
7 | },
8 | plugins: []
9 | }
10 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/tests/test.ts:
--------------------------------------------------------------------------------
1 | import { expect, test } from "@playwright/test"
2 |
3 | test("index page has expected h1", async ({ page }) => {
4 | await page.goto("/")
5 | await expect(
6 | page.getByRole("heading", { name: "Welcome to SvelteKit" })
7 | ).toBeVisible()
8 | })
9 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "./.svelte-kit/tsconfig.json",
3 | "compilerOptions": {
4 | "target": "ESNext",
5 | "lib": ["ESNext", "DOM"],
6 | "moduleResolution": "Node",
7 | "module": "ESNext",
8 | "allowJs": true,
9 | "checkJs": true,
10 | "esModuleInterop": true,
11 | "forceConsistentCasingInFileNames": true,
12 | "resolveJsonModule": true,
13 | "skipLibCheck": true,
14 | "sourceMap": true,
15 | "strict": true,
16 | "declaration": true,
17 | "noEmit": true,
18 | "outDir": "./dist",
19 | "declarationMap": true,
20 | "baseUrl": ".",
21 | "typeRoots": ["./node_modules/@types", "./src/lib/types.ts"],
22 | "paths": {
23 | "$lib": ["src/lib"],
24 | "$lib/*": ["src/lib/*"]
25 | }
26 | },
27 | "include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.ts", "src/**/*.svelte"]
28 | }
29 |
--------------------------------------------------------------------------------
/apps/tauri-controls-svelte/vite.config.ts:
--------------------------------------------------------------------------------
1 | // import resolve from "@rollup/plugin-node-resolve"
2 | import terser from "@rollup/plugin-terser"
3 | import { sveltekit } from "@sveltejs/kit/vite"
4 | // import svelte from "rollup-plugin-svelte"
5 | import { defineConfig } from "vitest/config"
6 |
7 | export default defineConfig({
8 | plugins: [sveltekit(), terser()],
9 | test: {
10 | include: ["src/**/*.{test,spec}.{js,ts}"]
11 | },
12 | build: {
13 | rollupOptions: {
14 | plugins: [
15 | // svelte({}),
16 | // resolve({ browser: true }),
17 | terser()
18 | ]
19 | }
20 | },
21 |
22 | clearScreen: false,
23 | server: {
24 | port: 1422,
25 | strictPort: true
26 | },
27 | envPrefix: ["VITE_", "TAURI_"]
28 | })
29 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 |
4 | src-tauri/target
5 | *.tgz
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # @tauri-controls/vue
2 |
3 | ## 0.4.0
4 |
5 | ### Minor Changes
6 |
7 | - fix: compatibility with the latest Tauri V2 release
8 | chore: switch package manager from pnpm to bun
9 |
10 | ## 0.3.0
11 |
12 | ### Minor Changes
13 |
14 | - fix: Remove all Tauri dependencies from the list of dependecies. This will require the user to install these (which were already in the instructions), but allow for more control of a single version of these packages. #20, thanks to @jbolda
15 |
16 | ## 0.2.0
17 |
18 | ### Minor Changes
19 |
20 | - fix: compatibility with the latest Tauri release
21 |
22 | ## 0.1.3
23 |
24 | ### Patch Changes
25 |
26 | - fix: package.json types export
27 |
28 | ## 0.1.2
29 |
30 | ### Patch Changes
31 |
32 | - feat: gnome more accurate button spacing, fix icons sizes (svelte, vue)
33 | fix(vue): pass attrs (props) to icons
34 | feat: macos controls use space instead of mr, px-2 to px-3
35 | chore: demo-app gap to space, update deps, format code
36 |
37 | ## 0.1.1
38 |
39 | ### Patch Changes
40 |
41 | - fix vue package
42 |
43 | ## 0.1.0
44 |
45 | ### Minor Changes
46 |
47 | - Add: Vue Implementation
48 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 agmmnn
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 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 
7 | 
8 | [](https://npmjs.com/package/tauri-controls) [](https://www.npmjs.com/package/@tauri-controls/vue)
9 |
10 | ## @tauri-controls/vue
11 |
12 | ```bash
13 | pnpm add @tauri-controls/vue
14 | ```
15 |
16 | https://github.com/agmmnn/tauri-controls
17 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/bun.lockb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-vue/bun.lockb
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Demo-Vue
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@tauri-controls/vue",
3 | "description": "🚥 Native-looking window controls for Tauri 2.",
4 | "private": false,
5 | "version": "0.4.0",
6 | "type": "module",
7 | "license": "MIT",
8 | "scripts": {
9 | "dev": "vite",
10 | "build": "vue-tsc --noEmit && vite build",
11 | "preview": "vite preview",
12 | "tauri": "tauri",
13 | "tauri:dev": "tauri dev",
14 | "format": "prettier --write . --config ./prettier.config.cjs"
15 | },
16 | "publishConfig": {
17 | "access": "public"
18 | },
19 | "repository": {
20 | "type": "git",
21 | "url": "https://github.com/agmmnn/tauri-controls"
22 | },
23 | "author": "agmmnn",
24 | "bugs": {
25 | "url": "https://github.com/agmmnn/tauri-controls/issues"
26 | },
27 | "homepage": "https://github.com/agmmnn/tauri-controls#readme",
28 | "files": [
29 | "dist"
30 | ],
31 | "exports": {
32 | ".": {
33 | "import": "./dist/tauri-controls.js",
34 | "types": "./dist/index.d.ts"
35 | }
36 | },
37 | "module": "./dist/tauri-controls.js",
38 | "types": "./dist/index.d.ts",
39 | "dependencies": {
40 | "@vueuse/core": "^10.9.0"
41 | },
42 | "devDependencies": {
43 | "@rollup/plugin-terser": "^0.4.4",
44 | "@tauri-apps/api": "2.0.0-beta.6",
45 | "@tauri-apps/cli": "2.0.0-beta.11",
46 | "@tauri-apps/plugin-os": "2.0.0-beta.2",
47 | "@vitejs/plugin-vue": "^5.0.4",
48 | "autoprefixer": "^10.4.19",
49 | "postcss": "^8.4.38",
50 | "prettier-plugin-tailwindcss": "^0.5.12",
51 | "tailwindcss": "^3.4.1",
52 | "typescript": "^5.4.3",
53 | "vite": "^5.2.4",
54 | "vite-plugin-dts": "^3.7.3",
55 | "vue-tsc": "^2.0.7"
56 | },
57 | "peerDependencies": {
58 | "tailwind-merge": "^1.14.0",
59 | "vue": "^3.3.4"
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/postcss.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/prettier.config.cjs:
--------------------------------------------------------------------------------
1 | /** @type {import('prettier').Config} */
2 | module.exports = {
3 | endOfLine: "lf",
4 | semi: false,
5 | singleQuote: false,
6 | tabWidth: 2,
7 | trailingComma: "es5",
8 | importOrderParserPlugins: ["typescript", "decorators-legacy"],
9 | plugins: [
10 | "@ianvs/prettier-plugin-sort-imports",
11 | "prettier-plugin-tailwindcss",
12 | ],
13 | }
14 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/.gitignore:
--------------------------------------------------------------------------------
1 | # Generated by Cargo
2 | # will have compiled files and executables
3 | /target/
4 |
5 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "tauri-demos"
3 | version = "0.1.0"
4 | description = "A Tauri App"
5 | authors = ["you"]
6 | license = "MIT"
7 | repository = ""
8 | edition = "2021"
9 |
10 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
11 |
12 | [build-dependencies]
13 | tauri-build = { version = "2.0.0-beta.10", features = [] }
14 |
15 | [dependencies]
16 | serde = { version = "1.0", features = ["derive"] }
17 | serde_json = "1.0"
18 | tauri = { version = "2.0.0-beta.13", features = ["macos-private-api"] }
19 | tauri-plugin-os = "2.0.0-beta.3"
20 | tauri-plugin-shell = "2.0.0-beta.3"
21 |
22 |
23 | [features]
24 | # by default Tauri runs in production mode
25 | # when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL
26 | default = ["custom-protocol"]
27 | # this feature is used used for production builds where `devPath` points to the filesystem
28 | # DO NOT remove this
29 | custom-protocol = ["tauri/custom-protocol"]
30 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/build.rs:
--------------------------------------------------------------------------------
1 | fn main() {
2 | tauri_build::build()
3 | }
4 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/capabilities/main.json:
--------------------------------------------------------------------------------
1 | {
2 | "identifier": "main-capability",
3 | "description": "Capability for the main window",
4 | "windows": ["main"],
5 | "permissions": [
6 | "path:default",
7 | "event:default",
8 | "window:default",
9 | "window:allow-close",
10 | "window:allow-minimize",
11 | "window:allow-maximize",
12 | "window:allow-start-dragging",
13 | "window:allow-toggle-maximize",
14 | "app:default",
15 | "image:default",
16 | "resources:default",
17 | "menu:default",
18 | "tray:default",
19 | "shell:default",
20 | "os:default"
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/gen/schemas/capabilities.json:
--------------------------------------------------------------------------------
1 | {"main-capability":{"identifier":"main-capability","description":"Capability for the main window","local":true,"windows":["main"],"permissions":["path:default","event:default","window:default","window:allow-close","window:allow-minimize","window:allow-maximize","window:allow-start-dragging","window:allow-toggle-maximize","app:default","image:default","resources:default","menu:default","tray:default","shell:default","os:default"]}}
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/icons/128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-vue/src-tauri/icons/128x128.png
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/icons/128x128@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-vue/src-tauri/icons/128x128@2x.png
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/icons/32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-vue/src-tauri/icons/32x32.png
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/icons/Square107x107Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-vue/src-tauri/icons/Square107x107Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/icons/Square142x142Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-vue/src-tauri/icons/Square142x142Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/icons/Square150x150Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-vue/src-tauri/icons/Square150x150Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/icons/Square284x284Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-vue/src-tauri/icons/Square284x284Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/icons/Square30x30Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-vue/src-tauri/icons/Square30x30Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/icons/Square310x310Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-vue/src-tauri/icons/Square310x310Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/icons/Square44x44Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-vue/src-tauri/icons/Square44x44Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/icons/Square71x71Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-vue/src-tauri/icons/Square71x71Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/icons/Square89x89Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-vue/src-tauri/icons/Square89x89Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/icons/StoreLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-vue/src-tauri/icons/StoreLogo.png
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/icons/icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-vue/src-tauri/icons/icon.icns
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/icons/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-vue/src-tauri/icons/icon.ico
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/icons/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls-vue/src-tauri/icons/icon.png
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/src/main.rs:
--------------------------------------------------------------------------------
1 | // Prevents additional console window on Windows in release
2 | #![cfg_attr(
3 | all(not(debug_assertions), target_os = "windows"),
4 | windows_subsystem = "windows"
5 | )]
6 |
7 | // Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
8 | #[tauri::command]
9 | fn greet(name: &str) -> String {
10 | format!("Hello, {}! You've been greeted from Rust!", name)
11 | }
12 |
13 | fn main() {
14 | tauri::Builder::default()
15 | .invoke_handler(tauri::generate_handler![greet])
16 | .plugin(tauri_plugin_os::init())
17 | .plugin(tauri_plugin_shell::init())
18 | .run(tauri::generate_context!())
19 | .expect("error while running tauri application");
20 | }
21 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src-tauri/tauri.conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../node_modules/@tauri-apps/cli/schema.json",
3 | "productName": "tauri-demos",
4 | "identifier": "com.yourname.dev",
5 | "build": {
6 | "beforeDevCommand": "bun run dev",
7 | "beforeBuildCommand": "bun run build",
8 | "devUrl": "http://localhost:1412",
9 | "frontendDist": "../dist"
10 | },
11 | "app": {
12 | "macOSPrivateApi": true,
13 | "security": {
14 | "csp": null
15 | },
16 | "windows": [
17 | {
18 | "fullscreen": false,
19 | "title": "Demo-Vue",
20 | "center": true,
21 | "transparent": true,
22 | "decorations": false,
23 | "resizable": true,
24 | "width": 1000,
25 | "height": 800
26 | }
27 | ],
28 | "withGlobalTauri": false
29 | },
30 | "bundle": {
31 | "active": true,
32 | "category": "DeveloperTool",
33 | "copyright": "",
34 | "externalBin": [],
35 | "icon": [
36 | "icons/32x32.png",
37 | "icons/128x128.png",
38 | "icons/128x128@2x.png",
39 | "icons/icon.icns",
40 | "icons/icon.ico"
41 | ],
42 | "longDescription": "",
43 | "macOS": {
44 | "entitlements": null,
45 | "exceptionDomain": "",
46 | "frameworks": [],
47 | "providerShortName": null,
48 | "signingIdentity": null
49 | },
50 | "resources": [],
51 | "shortDescription": "",
52 | "targets": "all",
53 | "windows": {
54 | "certificateThumbprint": null,
55 | "digestAlgorithm": "sha256",
56 | "timestampUrl": "",
57 | "nsis": {
58 | "installerIcon": "./icons/icon.ico"
59 | }
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src/App.vue:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
15 |
16 |
17 |
18 | @tauri-controls/vue
19 |
20 |
23 | WindowControls
24 |
25 |
26 |
29 |
34 |
35 | justify=true:
36 |
37 |
38 |
39 |
40 |
41 |
42 |
45 | WindowTitlebar
46 |
47 |
content
48 |
49 |
56 |
60 |
61 | Title
62 |
63 |
64 |
65 |
73 |
74 |
75 |
76 |
77 |
81 | Title
82 |
83 |
84 |
92 |
95 | titlebar content without w-full (macos but on the right side)
96 |
97 |
98 |
106 |
109 | titlebar content without w-full (windows but on the left side)
110 |
111 |
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src/components/LogoSvg.vue:
--------------------------------------------------------------------------------
1 |
2 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src/components/Menu.vue:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
9 | {{ item }}
10 |
11 |
12 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src/components/ThemeSwitch.vue:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
12 | Toggle Theme
13 |
14 |
15 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src/main.ts:
--------------------------------------------------------------------------------
1 | import { createApp } from "vue"
2 | import "./styles.css"
3 | import App from "./App.vue"
4 |
5 | createApp(App).mount("#app")
6 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src/styles.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src/tauri-controls/WindowControls.vue:
--------------------------------------------------------------------------------
1 |
45 |
46 |
47 |
51 |
55 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src/tauri-controls/WindowTitlebar.vue:
--------------------------------------------------------------------------------
1 |
44 |
45 |
46 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src/tauri-controls/components/Button.vue:
--------------------------------------------------------------------------------
1 |
4 |
5 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src/tauri-controls/controls/MacOs.vue:
--------------------------------------------------------------------------------
1 |
33 |
34 |
35 |
44 |
48 |
49 |
50 |
54 |
55 |
56 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src/tauri-controls/controls/Windows.vue:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
15 |
19 |
20 |
21 |
30 |
31 |
32 |
33 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src/tauri-controls/controls/linux/Gnome.vue:
--------------------------------------------------------------------------------
1 |
12 |
13 |
14 |
22 |
26 |
27 |
28 |
32 |
37 |
38 |
39 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src/tauri-controls/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src/tauri-controls/index.ts:
--------------------------------------------------------------------------------
1 | import "./index.css"
2 | import WindowControls from "./WindowControls.vue"
3 | import WindowTitlebar from "./WindowTitlebar.vue"
4 |
5 | export type { WindowControlsProps, WindowTitlebarProps } from "./types"
6 |
7 | export { WindowControls, WindowTitlebar }
8 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src/tauri-controls/types.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Interface for window controls.
3 | * If the `platform` property is not specified, the library will automatically detect
4 | * the operating system the app is running on and display the appropriate elements.
5 | */
6 | export interface WindowControlsProps {
7 | /**
8 | * Specifies which platform's window controls to display.
9 | * It can be one of "windows", "macos", or "gnome".
10 | * If the `platform` property is not specified, the library will automatically detect
11 | * the operating system the app is running on and display the appropriate elements.
12 | */
13 | platform?: "windows" | "macos" | "gnome"
14 |
15 | /**
16 | * Indicates whether the window controls should be shown or hidden.
17 | * @default false
18 | */
19 | hide?: boolean
20 |
21 | /**
22 | * - "display": "display: none;" making them completely invisible and not taking up any space.
23 | * - "visibility": "visibility: hidden;" making them invisible but still occupying the same space.
24 | * @default "display"
25 | */
26 | hideMethod?: "display" | "visibility"
27 |
28 | /**
29 | * Justify/Snap WindowControls
30 | *
31 | * @default false, (if not defined in WindowTitlebar automatically assigned)
32 | */
33 | justify?: boolean
34 |
35 | /**
36 | * Specifies the Linux desktop environment for which the window controls are intended.
37 | * This property is applicable only when the platform is set to "linux".
38 | * @default "gnome"
39 | */
40 | // linuxDesktop?: "gnome" | "kde" | "budgie"
41 |
42 | /**
43 | * Indicates whether to prevent the right-click context menu.
44 | * When set to true, it will prevent the default right-click behavior.
45 | * (only in production, default false)
46 | */
47 | // preventRightClickMenu?: "always" | "production"
48 |
49 | /** `data-tauri-drag-region` */
50 | // "data-tauri-drag-region"?: boolean
51 |
52 | /**
53 | * to add custom class to window controls
54 | */
55 | className?: string
56 | }
57 |
58 | /**
59 | * Interface for titlebar
60 | */
61 | export interface WindowTitlebarProps {
62 | /**
63 | * The `controlsOrder` property is an optional property used in the `WindowControls` interface.
64 | * It allows you to specify the order in which the window controls should be rendered relative to the children.
65 | * (default: system)
66 | *
67 | * When `controlsOrder` is not specified or set to `system`, the default behavior will be as follows:
68 | * - For platforms other than macOS, the controls will be on the right side of the children.
69 | * - For macOS, the controls will be on the left side of the children (similar to "left" option).
70 | *
71 | * Possible values for `controlsOrder`:
72 | * - "right": The window controls will be rendered to the right of the children.
73 | * - "left": The window controls will be rendered to the left of the children. This order applies only when the platform is macOS (macOS window controls are usually located on the left side of the title bar).
74 | * - "platform": for OS-based positioning specified in `windowControlsProps`
75 | * @default "system"
76 | */
77 | controlsOrder?: "right" | "left" | "platform" | "system"
78 |
79 | /**
80 | * `WindowControls` props
81 | */
82 | windowControlsProps?: WindowControlsProps
83 | }
84 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src/tauri-controls/utils/os.ts:
--------------------------------------------------------------------------------
1 | import type { OsType } from "@tauri-apps/plugin-os"
2 |
3 | let osType: OsType | undefined = undefined
4 | let osTypePromise: Promise | null = null
5 |
6 | if (typeof window !== "undefined") {
7 | osTypePromise = import("@tauri-apps/plugin-os").then((module) => {
8 | return module.type().then((x) => {
9 | osType = x // Assign the value of osType here
10 | return x // Return the value to the promise chain
11 | })
12 | })
13 | }
14 |
15 | // A helper function to get the OS type, which returns a Promise
16 | export function getOsType(): Promise {
17 | if (!osTypePromise) {
18 | // If the module was already loaded, just return the result
19 | return Promise.resolve(osType!) // Use non-null assertion
20 | }
21 |
22 | // If the module is still loading, wait for it to finish and return the result
23 | return osTypePromise
24 | }
25 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src/tauri-controls/utils/window.ts:
--------------------------------------------------------------------------------
1 | import type { window } from "@tauri-apps/api"
2 | import { ref } from "vue"
3 |
4 | export const appWindow = ref(null)
5 | export const isWindowMaximized = ref(false)
6 |
7 | import("@tauri-apps/api").then((module) => {
8 | appWindow.value = module.window.getCurrent()
9 | appWindow.value.onResized(async () => {
10 | const isMaximized = await appWindow.value?.isMaximized()
11 | if (isMaximized !== undefined) {
12 | isWindowMaximized.value = isMaximized
13 | }
14 | })
15 | })
16 |
17 | export const minimizeWindow = async () => {
18 | await appWindow.value?.minimize()
19 | }
20 |
21 | export const maximizeWindow = async () => {
22 | await appWindow.value?.toggleMaximize()
23 | }
24 |
25 | export const fullscreenWindow = async () => {
26 | if (appWindow) {
27 | const fullscreen = await appWindow.value?.isFullscreen()
28 | await appWindow.value?.setFullscreen(!fullscreen)
29 | }
30 | }
31 |
32 | export const closeWindow = async () => {
33 | await appWindow.value?.close()
34 | }
35 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
3 | declare module "*.vue" {
4 | import type { DefineComponent } from "vue"
5 | const component: DefineComponent<{}, {}, any>
6 | export default component
7 | }
8 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | darkMode: "class",
4 | content: ["./index.html", "./src/**/*.{vue,js,ts,jsx,tsx}"],
5 | theme: {
6 | extend: {},
7 | },
8 | plugins: [],
9 | }
10 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/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 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "noEmit": true,
15 | "jsx": "preserve",
16 |
17 | /* Linting */
18 | "strict": true,
19 | "noUnusedLocals": true,
20 | "noUnusedParameters": true,
21 | "noFallthroughCasesInSwitch": true
22 | },
23 | "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue"],
24 | "references": [{ "path": "./tsconfig.node.json" }]
25 | }
26 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "skipLibCheck": true,
5 | "module": "ESNext",
6 | "moduleResolution": "bundler",
7 | "allowSyntheticDefaultImports": true
8 | },
9 | "include": ["vite.config.ts"]
10 | }
11 |
--------------------------------------------------------------------------------
/apps/tauri-controls-vue/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { resolve } from "node:path"
2 | import terser from "@rollup/plugin-terser"
3 | import vue from "@vitejs/plugin-vue"
4 | import { defineConfig } from "vite"
5 | import dts from "vite-plugin-dts"
6 | import * as packageJson from "./package.json"
7 |
8 | // https://vitejs.dev/config/
9 | export default defineConfig(async () => ({
10 | plugins: [
11 | vue(),
12 | dts({
13 | include: ["./src/tauri-controls"],
14 | rollupTypes: true,
15 | }),
16 | ],
17 |
18 | build: {
19 | lib: {
20 | entry: resolve("src", "tauri-controls/index.ts"),
21 | name: "TauriControls",
22 | formats: ["es"], // "umd"
23 | fileName: () => `tauri-controls.js`,
24 | },
25 | rollupOptions: {
26 | external: [...Object.keys(packageJson.peerDependencies)],
27 | plugins: [terser()],
28 | output: {
29 | globals: {
30 | vue: "Vue",
31 | "@tauri-apps/plugin-os": "pluginOs",
32 | "tailwind-merge": "tailwindMerge",
33 | "@tauri-apps/plugin-window": "pluginWindow",
34 | },
35 | intro: 'import "./style.css";',
36 | plugins: [terser()],
37 | },
38 | },
39 | },
40 |
41 | // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
42 | //
43 | // 1. prevent vite from obscuring rust errors
44 | clearScreen: false,
45 | // 2. tauri expects a fixed port, fail if that port is not available
46 | server: {
47 | port: 1412,
48 | strictPort: true,
49 | },
50 | // 3. to make use of `TAURI_DEBUG` and other env variables
51 | // https://tauri.studio/v1/api/config#buildconfig.beforedevcommand
52 | envPrefix: ["VITE_", "TAURI_"],
53 | }))
54 |
--------------------------------------------------------------------------------
/apps/tauri-controls/.eslintrc.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | env: {
3 | browser: true,
4 | es2021: true,
5 | node: true,
6 | },
7 | extends: [
8 | "eslint:recommended",
9 | "plugin:react/recommended",
10 | "prettier",
11 | "plugin:@typescript-eslint/recommended",
12 | "plugin:react-hooks/recommended",
13 | ],
14 | settings: {
15 | react: {
16 | version: "detect",
17 | },
18 | },
19 | overrides: [],
20 | parserOptions: {
21 | ecmaVersion: "latest",
22 | sourceType: "module",
23 | },
24 | plugins: ["react"],
25 | rules: {
26 | "react/jsx-key": "off",
27 | "react/react-in-jsx-scope": "off",
28 | "no-unused-vars": "off",
29 | "@typescript-eslint/no-unused-vars": "warn",
30 | "no-console": "warn",
31 | "@typescript-eslint/no-explicit-any": 0,
32 | },
33 | }
34 |
--------------------------------------------------------------------------------
/apps/tauri-controls/.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 | others
15 | *.tgz
16 | .turbo
17 |
18 | # Editor directories and files
19 | .vscode/*
20 | !.vscode/extensions.json
21 | .idea
22 | .DS_Store
23 | *.suo
24 | *.ntvs*
25 | *.njsproj
26 | *.sln
27 | *.sw?
28 |
29 | src-tauri/target
30 |
--------------------------------------------------------------------------------
/apps/tauri-controls/.prettierignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | /build
4 | /dist
5 | /package
6 | .env
7 | .env.*
8 | !.env.example
9 | /src-tauri/target
10 | .turbo
11 |
12 | # Ignore files for PNPM, NPM and YARN
13 | pnpm-lock.yaml
14 | package-lock.json
15 | yarn.lock
16 |
--------------------------------------------------------------------------------
/apps/tauri-controls/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # tauri-controls
2 |
3 | ## 0.4.0
4 |
5 | ### Minor Changes
6 |
7 | - fix: compatibility with the latest Tauri V2 release
8 | chore: switch package manager from pnpm to bun
9 |
10 | ## 0.3.0
11 |
12 | ### Minor Changes
13 |
14 | - fix: Remove all Tauri dependencies from the list of dependecies. This will require the user to install these (which were already in the instructions), but allow for more control of a single version of these packages. #20, thanks to @jbolda
15 |
16 | ## 0.2.0
17 |
18 | ### Minor Changes
19 |
20 | - fix: compatibility with the latest Tauri release
21 |
22 | ## 0.1.3
23 |
24 | ### Patch Changes
25 |
26 | - fix: package.json types export
27 |
28 | ## 0.1.2
29 |
30 | ### Patch Changes
31 |
32 | - fix(react,solid): temp disable isWindowMaximized on macOS #10
33 | chore: demo-app gap to space, update deps, format code
34 | feat: gnome more accurate button spacing, fix icons sizes (svelte, vue)
35 | feat: macos controls use space instead of mr, px-2 to px-3
36 |
37 | ## 0.1.1
38 |
39 | ### Patch Changes
40 |
41 | - Add [changeset](https://github.com/changesets/changesets)
42 | - Add [publish-packages script](https://turbo.build/repo/docs/handbook/publishing-packages/versioning-and-publishing#using-changesets-with-turborepo)
43 | - Update readme file
44 |
--------------------------------------------------------------------------------
/apps/tauri-controls/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 agmmnn
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 |
--------------------------------------------------------------------------------
/apps/tauri-controls/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | [](https://bundlephobia.com/)
7 | [](https://bundlephobia.com/)
8 | [](https://npmjs.com/package/tauri-controls)
9 |
10 | [](https://www.npmjs.com/package/tauri-controls) [](https://www.npmjs.com/package/@tauri-controls/svelte) [](https://www.npmjs.com/package/@tauri-controls/solid) [](https://www.npmjs.com/package/@tauri-controls/vue)
11 |
12 | **Tauri Controls** is a library that provides native-looking **window controls** for [Tauri 2](https://beta.tauri.app) applications. You can enhance the user experience of your Tauri 2 applications with window controls that mimic the identical native controls on the current system.
13 |
14 | `tauri-controls` uses Tauri's [js/ts APIs](https://next--tauri.netlify.app/next/api/js) to handle window events and just provides native-looking (designed according to official system design prototypes) html elements, not native, _it does not rely on the system's native APIs_.
15 |
16 | The following designs are taken as reference:
17 |
18 | - [Windows UI 3](https://www.figma.com/community/file/1159947337437047524) @microsoft
19 | - [Apple Design Resources - macOS](https://www.figma.com/community/file/1251588934545918753) @apple
20 |
21 | ## How to use
22 |
23 | ### Install Dependencies
24 |
25 | ```bash
26 | # React:
27 | bun add tauri-controls
28 |
29 | # Svelte:
30 | bun add @tauri-controls/svelte
31 |
32 | # Solid.js:
33 | bun add @tauri-controls/solid
34 |
35 | # Vue.js:
36 | bun add @tauri-controls/vue
37 | ```
38 |
39 | ```bash
40 | # Install peer dependencies:
41 | bun add @tauri-apps/plugin-os @tauri-apps/api
42 | bun add -D clsx tailwind-merge
43 | ```
44 |
45 | > For **Svelte** projects, include the following line in the `content` section of your `tailwind.config.js`:
46 | >
47 | > ```js
48 | > "./node_modules/@tauri-controls/svelte/**/*.{js,svelte,ts}"
49 | > ```
50 |
51 | Then, make sure to include the following tauri plugins in your `src-tauri` directory:
52 |
53 | ```bash
54 | cargo add tauri-plugin-window tauri-plugin-os
55 | ```
56 |
57 | Don't forget to register plugins in your main function.
58 |
59 | ```rust
60 | fn main() {
61 | tauri::Builder::default()
62 | .plugin(tauri_plugin_os::init())
63 | .plugin(tauri_plugin_window::init())
64 | .run(tauri::generate_context!())
65 | .expect("error while running tauri application");
66 | }
67 | ```
68 |
69 | > _If you get the message "Not allowed by scope" in the terminal after a production build, try [this](https://github.com/agmmnn/tauri-controls/issues/1#issuecomment-1653557673)._
70 |
71 | ### Add to Your Code
72 |
73 | And simply add the `WindowTitlebar` or `WindowControls` component to your code, depending on your needs:
74 |
75 | #### WindowTitlebar
76 |
77 | The `WindowTitlebar` component handles the window titlebar and dynamically adjusts the **window control buttons** and **titlebar content** order based on the current operating system.
78 |
79 | ```tsx
80 | import { WindowTitlebar } from "tauri-controls"
81 |
82 | function MyTitlebar() {
83 | return (
84 | {/* Place your titlebar content here */}
85 | )
86 | }
87 | ```
88 |
89 | When no platform is specified, the current system will be detected and the matching element will be returned. This feature is a great solution for cross-platform releases.
90 |
91 | 
92 |
93 | #### WindowControls
94 |
95 | Use the `WindowControls` component only for window controls.
96 |
97 | ```tsx
98 | import { WindowControls } from "tauri-controls"
99 |
100 | function MyTitlebar() {
101 | return
102 | }
103 | ```
104 |
105 | 
106 |
107 | ### More examples:
108 |
109 | - [in React](https://github.com/agmmnn/tauri-controls/blob/master/apps/tauri-controls/src/App.tsx)
110 | - [in Svelte](https://github.com/agmmnn/tauri-controls/blob/master/apps/tauri-controls-svelte/src/routes/%2Bpage.svelte)
111 | - [in Solid.js](https://github.com/agmmnn/tauri-controls/blob/master/apps/tauri-controls-solid/src/App.tsx)
112 | - [in Vue.js](https://github.com/agmmnn/tauri-controls/blob/master/apps/tauri-controls-vue/src/App.vue)
113 |
114 | ## Options
115 |
116 | ### `WindowTitlebar`:
117 |
118 | - `controlsOrder?: "right" | "left" | "platform" | "system"`: Specifies the order of window controls. **platform**: to get OS-based positioning specified in _windowControlsProps_.
119 | **system**: to automatically detect the platform and position the controls accordingly (default).
120 | - `windowControlsProps?: WindowControlsProps`: Additional props to pass to the `WindowControls` component.
121 |
122 | ### `WindowControls`:
123 |
124 | - `platform?: "windows" | "macos" | "gnome"`: Specifies which platform's window controls to display. If the _platform_ property is not specified, the library will automatically detect the operating system the app is running on and display the appropriate element.
125 | - `justify?: boolean`: If set to `true`, `WindowControls` will justify/snap in the flexbox where it is located.
126 | - `hide?: boolean`: If set to `true`, the window controls will be hidden.
127 | - `hideMethod?: "display" | "visibility"`: Determines how the window controls will be hidden.
128 |
129 | You can also provide additional props to elements, such as `data-tauri-drag-region`, for further enhancements.
130 |
131 | 
132 | 
133 |
134 | ## Figma
135 |
136 | Check out the design implementation on Figma for a visual reference. [Desktop Native Window Controls - Figma](https://www.figma.com/file/ms2vbZx5lEGxHqHR8fAfQm/Desktop-Native-Window-Controls?type=design&node-id=4%3A6020&mode=design&t=PIbVTsr8zWmIFsNr-1).
137 |
138 | These sources were utilized:
139 |
140 | - [Windows UI 3](https://www.figma.com/community/file/1159947337437047524) @microsoft
141 | - [Apple Design Resources - macOS](https://www.figma.com/community/file/1251588934545918753) @apple
142 | - [macOS Monterey UI Kit for Figma](https://www.figma.com/community/file/1034539431656086181/macOS-Monterey-UI-Kit-for-Figma) @joey
143 | - [Spotify Desktop App Clone](https://www.figma.com/community/file/1028665514709480268/Spotify-Desktop-App-Clone) @uidesignguide
144 |
145 | ## Development and Contribution
146 |
147 | ```bash
148 | bun dev
149 |
150 | bun tauri:dev
151 | ```
152 |
153 | Project Structure:
154 |
155 | ```bash
156 | .
157 | ├── /apps
158 | │ ├── /tauri-controls # Main application (React)
159 | │ ├── /tauri-controls-solid # Solid.js implementation
160 | │ └── /tauri-controls-svelte # Svelte implementation
161 | ├── /packages # Shared packages
162 | ├── package.json # Project configuration
163 | ├── pnpm-workspace.yaml # Workspace configuration
164 | └── turbo.json # TurboRepo configuration
165 | ```
166 |
167 | If you're interested in contributing, check out our [TODO list](https://github.com/agmmnn/tauri-controls/blob/master/TODOs.md) for tasks you can help with. Your contributions are appreciated!
168 |
169 | ## Contributors
170 |
171 | This project is made possible by the contributions of various individuals. Thank you to all the contributors who have helped make this project better.
172 |
173 | - **[tauri-controls](https://www.npmjs.com/package/tauri-controls), [@tauri-controls/svelte](https://www.npmjs.com/package/@tauri-controls/svelte)**: [@agmmnn](https://github.com/agmmnn)
174 | - **[@tauri-controls/solid](https://www.npmjs.com/package/@tauri-controls/solid)**: [@ronanru](https://github.com/ronanru)
175 | - **[@tauri-controls/vue](https://www.npmjs.com/package/@tauri-controls/vue)**: [@allenli178](https://github.com/allenli178)
176 |
177 | ## Further Reading
178 |
179 | - [Feature request: Add setting for titlebar style with native window controls support - tauri-apps/tauri#2663](https://github.com/tauri-apps/tauri/issues/2663)
180 | - [Window Controls Overlay for Installed Desktop Web Apps - WICG](https://github.com/WICG/window-controls-overlay/blob/main/explainer.md)
181 | - [Window Controls Overlay - Electron](https://www.electronjs.org/docs/latest/tutorial/window-customization#window-controls-overlay-macos-windows)
182 | - [Window Controls Overlay API - MDN](https://developer.mozilla.org/en-US/docs/Web/API/Window_Controls_Overlay_API)
183 |
184 | ## License
185 |
186 | MIT
187 |
--------------------------------------------------------------------------------
/apps/tauri-controls/bun.lockb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls/bun.lockb
--------------------------------------------------------------------------------
/apps/tauri-controls/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Demo-React
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/apps/tauri-controls/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tauri-controls",
3 | "description": "🚥 Native-looking window controls for Tauri 2.",
4 | "private": false,
5 | "version": "0.4.0",
6 | "type": "module",
7 | "license": "MIT",
8 | "scripts": {
9 | "dev": "vite",
10 | "build": "tsc && vite build",
11 | "build:watch": "vite build --watch",
12 | "preview": "vite preview",
13 | "lint": "eslint src --ext .js,.jsx,.ts,.tsx",
14 | "format": "prettier --write . --config ./prettier.config.cjs",
15 | "tauri": "tauri",
16 | "tauri:dev": "tauri dev"
17 | },
18 | "publishConfig": {
19 | "access": "public"
20 | },
21 | "repository": {
22 | "type": "git",
23 | "url": "https://github.com/agmmnn/tauri-controls"
24 | },
25 | "author": "agmmnn",
26 | "bugs": {
27 | "url": "https://github.com/agmmnn/tauri-controls/issues"
28 | },
29 | "homepage": "https://github.com/agmmnn/tauri-controls#readme",
30 | "files": [
31 | "dist"
32 | ],
33 | "exports": {
34 | ".": {
35 | "import": "./dist/tauri-controls.js",
36 | "types": "./dist/index.d.ts"
37 | }
38 | },
39 | "module": "./dist/tauri-controls.js",
40 | "types": "./dist/index.d.ts",
41 | "dependencies": {},
42 | "devDependencies": {
43 | "@ianvs/prettier-plugin-sort-imports": "^4.2.1",
44 | "@rollup/plugin-terser": "^0.4.4",
45 | "@tauri-apps/api": "2.0.0-beta.6",
46 | "@tauri-apps/cli": "2.0.0-beta.11",
47 | "@tauri-apps/plugin-os": "2.0.0-beta.2",
48 | "@types/node": "^20.11.30",
49 | "@types/react": "^18.2.69",
50 | "@types/react-dom": "^18.2.22",
51 | "@typescript-eslint/eslint-plugin": "^7.3.1",
52 | "@typescript-eslint/parser": "^7.3.1",
53 | "@vitejs/plugin-react-swc": "^3.6.0",
54 | "autoprefixer": "^10.4.19",
55 | "eslint": "^8.57.0",
56 | "eslint-config-prettier": "^9.1.0",
57 | "eslint-plugin-import": "^2.29.1",
58 | "eslint-plugin-react": "^7.34.1",
59 | "eslint-plugin-react-hooks": "^4.6.0",
60 | "postcss": "^8.4.38",
61 | "prettier": "^3.2.5",
62 | "prettier-plugin-tailwindcss": "^0.5.12",
63 | "rollup": "^4.13.0",
64 | "rollup-plugin-postcss": "^4.0.2",
65 | "tailwindcss": "^3.4.1",
66 | "typescript": "^5.4.3",
67 | "vite": "^5.2.4",
68 | "vite-plugin-dts": "^3.7.3",
69 | "vite-plugin-linter": "^2.1.1",
70 | "vite-tsconfig-paths": "^4.3.2"
71 | },
72 | "peerDependencies": {
73 | "clsx": "^2.0.0",
74 | "react": "^18.2.0",
75 | "react-dom": "^18.2.0",
76 | "tailwind-merge": "^1.14.0"
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/apps/tauri-controls/postcss.config.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/apps/tauri-controls/prettier.config.cjs:
--------------------------------------------------------------------------------
1 | /** @type {import('prettier').Config} */
2 | module.exports = {
3 | endOfLine: "lf",
4 | semi: false,
5 | singleQuote: false,
6 | tabWidth: 2,
7 | trailingComma: "es5",
8 | importOrderParserPlugins: ["typescript", "jsx", "decorators-legacy"],
9 | plugins: [
10 | "@ianvs/prettier-plugin-sort-imports",
11 | "prettier-plugin-tailwindcss",
12 | ],
13 | }
14 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src-tauri/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "tauri-demos"
3 | version = "0.1.0"
4 | description = "A Tauri App"
5 | authors = ["you"]
6 | license = "MIT"
7 | repository = ""
8 | edition = "2021"
9 |
10 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
11 |
12 | [build-dependencies]
13 | tauri-build = { version = "2.0.0-beta.10", features = [] }
14 |
15 | [dependencies]
16 | serde = { version = "1.0", features = ["derive"] }
17 | serde_json = "1.0"
18 | tauri = { version = "2.0.0-beta.13", features = ["macos-private-api"] }
19 | tauri-plugin-os = "2.0.0-beta.3"
20 | tauri-plugin-shell = "2.0.0-beta.3"
21 |
22 |
23 | [features]
24 | # by default Tauri runs in production mode
25 | # when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL
26 | default = ["custom-protocol"]
27 | # this feature is used used for production builds where `devPath` points to the filesystem
28 | # DO NOT remove this
29 | custom-protocol = ["tauri/custom-protocol"]
30 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src-tauri/build.rs:
--------------------------------------------------------------------------------
1 | fn main() {
2 | tauri_build::build()
3 | }
4 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src-tauri/capabilities/main.json:
--------------------------------------------------------------------------------
1 | {
2 | "identifier": "main-capability",
3 | "description": "Capability for the main window",
4 | "windows": ["main"],
5 | "permissions": [
6 | "path:default",
7 | "event:default",
8 | "window:default",
9 | "window:allow-close",
10 | "window:allow-minimize",
11 | "window:allow-maximize",
12 | "window:allow-start-dragging",
13 | "window:allow-toggle-maximize",
14 | "app:default",
15 | "image:default",
16 | "resources:default",
17 | "menu:default",
18 | "tray:default",
19 | "shell:default",
20 | "os:default"
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src-tauri/gen/schemas/capabilities.json:
--------------------------------------------------------------------------------
1 | {"main-capability":{"identifier":"main-capability","description":"Capability for the main window","local":true,"windows":["main"],"permissions":["path:default","event:default","window:default","window:allow-close","window:allow-minimize","window:allow-maximize","window:allow-start-dragging","window:allow-toggle-maximize","app:default","image:default","resources:default","menu:default","tray:default","shell:default","os:default"]}}
--------------------------------------------------------------------------------
/apps/tauri-controls/src-tauri/icons/128x128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls/src-tauri/icons/128x128.png
--------------------------------------------------------------------------------
/apps/tauri-controls/src-tauri/icons/128x128@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls/src-tauri/icons/128x128@2x.png
--------------------------------------------------------------------------------
/apps/tauri-controls/src-tauri/icons/32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls/src-tauri/icons/32x32.png
--------------------------------------------------------------------------------
/apps/tauri-controls/src-tauri/icons/Square107x107Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls/src-tauri/icons/Square107x107Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls/src-tauri/icons/Square142x142Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls/src-tauri/icons/Square142x142Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls/src-tauri/icons/Square150x150Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls/src-tauri/icons/Square150x150Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls/src-tauri/icons/Square284x284Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls/src-tauri/icons/Square284x284Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls/src-tauri/icons/Square30x30Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls/src-tauri/icons/Square30x30Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls/src-tauri/icons/Square310x310Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls/src-tauri/icons/Square310x310Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls/src-tauri/icons/Square44x44Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls/src-tauri/icons/Square44x44Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls/src-tauri/icons/Square71x71Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls/src-tauri/icons/Square71x71Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls/src-tauri/icons/Square89x89Logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls/src-tauri/icons/Square89x89Logo.png
--------------------------------------------------------------------------------
/apps/tauri-controls/src-tauri/icons/StoreLogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls/src-tauri/icons/StoreLogo.png
--------------------------------------------------------------------------------
/apps/tauri-controls/src-tauri/icons/icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls/src-tauri/icons/icon.icns
--------------------------------------------------------------------------------
/apps/tauri-controls/src-tauri/icons/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls/src-tauri/icons/icon.ico
--------------------------------------------------------------------------------
/apps/tauri-controls/src-tauri/icons/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/apps/tauri-controls/src-tauri/icons/icon.png
--------------------------------------------------------------------------------
/apps/tauri-controls/src-tauri/src/main.rs:
--------------------------------------------------------------------------------
1 | // Prevents additional console window on Windows in release
2 | #![cfg_attr(
3 | all(not(debug_assertions), target_os = "windows"),
4 | windows_subsystem = "windows"
5 | )]
6 |
7 | // Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
8 | #[tauri::command]
9 | fn greet(name: &str) -> String {
10 | format!("Hello, {}! You've been greeted from Rust!", name)
11 | }
12 |
13 | fn main() {
14 | tauri::Builder::default()
15 | .invoke_handler(tauri::generate_handler![greet])
16 | .plugin(tauri_plugin_os::init())
17 | .plugin(tauri_plugin_shell::init())
18 | .run(tauri::generate_context!())
19 | .expect("error while running tauri application");
20 | }
21 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src-tauri/tauri.conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "../node_modules/@tauri-apps/cli/schema.json",
3 | "productName": "tauri-demos",
4 | "identifier": "com.yourname.dev",
5 | "build": {
6 | "beforeDevCommand": "bun run dev",
7 | "beforeBuildCommand": "bun run build",
8 | "devUrl": "http://localhost:1421",
9 | "frontendDist": "../dist"
10 | },
11 | "app": {
12 | "macOSPrivateApi": true,
13 | "security": {
14 | "csp": null
15 | },
16 | "windows": [
17 | {
18 | "title": "Demo-React",
19 | "center": true,
20 | "transparent": true,
21 | "decorations": false,
22 | "resizable": true,
23 | "width": 1000,
24 | "height": 800
25 | }
26 | ],
27 | "withGlobalTauri": false
28 | },
29 | "bundle": {
30 | "active": true,
31 | "category": "DeveloperTool",
32 | "copyright": "",
33 | "externalBin": [],
34 | "icon": [
35 | "icons/32x32.png",
36 | "icons/128x128.png",
37 | "icons/128x128@2x.png",
38 | "icons/icon.icns",
39 | "icons/icon.ico"
40 | ],
41 | "longDescription": "",
42 | "macOS": {
43 | "entitlements": null,
44 | "exceptionDomain": "",
45 | "frameworks": [],
46 | "providerShortName": null,
47 | "signingIdentity": null
48 | },
49 | "resources": [],
50 | "shortDescription": "",
51 | "targets": "all",
52 | "windows": {
53 | "certificateThumbprint": null,
54 | "digestAlgorithm": "sha256",
55 | "timestampUrl": "",
56 | "nsis": {
57 | "installerIcon": "./icons/icon.ico"
58 | }
59 | }
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src/App.tsx:
--------------------------------------------------------------------------------
1 | import "./style.css"
2 | import React, { useState } from "react"
3 | import { WindowControls } from "./tauri-controls/window-controls"
4 | import { WindowTitlebar } from "./tauri-controls/window-titlebar"
5 |
6 | function App() {
7 | return (
8 |
9 |
10 |
11 |
12 | tauri-controls
13 |
14 |
15 | WindowControls
16 |
17 | {/* OnlyControls */}
18 |
19 | {platforms.map((x) => (
20 |
21 | ))}
22 |
23 | justify=true:
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | WindowTitlebar
32 |
33 |
content
34 | {/* Icon+Title Controls */}
35 | {platforms.map((x) => (
36 |
37 | ))}
38 | {/* Icon Menu Title Controls */}
39 | {platforms.map((x) => (
40 |
41 | ))}
42 |
49 |
50 | titlebar content without w-full (macos but on the right side)
51 |
52 |
53 |
60 |
61 | titlebar content without w-full (windows but on the left side)
62 |
63 |
64 |
65 |
66 | )
67 | }
68 |
69 | const Content = () => {
70 | const Inside = () => (
71 | Content
72 | )
73 | return (
74 | <>
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | >
85 | )
86 | }
87 |
88 | const platforms = ["windows", "macos", "gnome"]
89 |
90 | const OnlyControls = ({ platform }: any) => {
91 | return
92 | }
93 |
94 | /* Icon+Title Controls */
95 | const IMC = ({ platform }: any) => {
96 | return (
97 |
102 |
106 |
107 | Title
108 |
109 |
110 | )
111 | }
112 |
113 | /* Icon Menu Title Controls */
114 | const IMTC = ({ platform }: any) => {
115 | return (
116 |
124 |
125 |
126 |
127 |
128 |
129 |
133 | Title
134 |
135 |
136 | )
137 | }
138 |
139 | const Menu = () => {
140 | const items = ["File", "Edit", "View", "Account", "Theme"]
141 |
142 | return (
143 |
144 | {items.map((x) => (
145 | {x}
146 | ))}
147 |
148 | )
149 | }
150 |
151 | const ThemeSwitch = () => {
152 | function toggle() {
153 | document.documentElement.classList.toggle("dark")
154 | }
155 |
156 | return (
157 |
161 | Toggle Theme
162 |
163 | )
164 | }
165 |
166 | const LogoSvg = () => (
167 |
179 |
180 |
181 |
182 |
183 | )
184 |
185 | export default App
186 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src/main.tsx:
--------------------------------------------------------------------------------
1 | import React from "react"
2 | import ReactDOM from "react-dom/client"
3 | import App from "./App"
4 |
5 | ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
6 |
7 |
8 |
9 | )
10 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src/style.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | /* * {
6 | border: 1px solid #7dadf9;
7 | } */
8 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src/tauri-controls/components/button.tsx:
--------------------------------------------------------------------------------
1 | import type { ButtonHTMLAttributes } from "react"
2 | import { cn } from "src/tauri-controls/libs/utils"
3 |
4 | export function Button({
5 | className,
6 | children,
7 | ...props
8 | }: ButtonHTMLAttributes) {
9 | return (
10 |
17 | {children}
18 |
19 | )
20 | }
21 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src/tauri-controls/contexts/plugin-window.tsx:
--------------------------------------------------------------------------------
1 | import type { Window } from "@tauri-apps/api/window"
2 | import React, { createContext, useCallback, useEffect, useState } from "react"
3 | import { getOsType } from "../libs/plugin-os"
4 |
5 | interface TauriAppWindowContextType {
6 | appWindow: Window | null
7 | isWindowMaximized: boolean
8 | minimizeWindow: () => Promise
9 | maximizeWindow: () => Promise
10 | fullscreenWindow: () => Promise
11 | closeWindow: () => Promise
12 | }
13 |
14 | const TauriAppWindowContext = createContext({
15 | appWindow: null,
16 | isWindowMaximized: false,
17 | minimizeWindow: () => Promise.resolve(),
18 | maximizeWindow: () => Promise.resolve(),
19 | fullscreenWindow: () => Promise.resolve(),
20 | closeWindow: () => Promise.resolve(),
21 | })
22 |
23 | interface TauriAppWindowProviderProps {
24 | children: React.ReactNode
25 | }
26 |
27 | export const TauriAppWindowProvider: React.FC = ({
28 | children,
29 | }: any) => {
30 | const [appWindow, setAppWindow] = useState(null)
31 | const [isWindowMaximized, setIsWindowMaximized] = useState(false)
32 |
33 | // Fetch the Tauri window plugin when the component mounts
34 | // Dynamically import plugin-window for next.js, sveltekit, nuxt etc. support:
35 | // https://github.com/tauri-apps/plugins-workspace/issues/217
36 | useEffect(() => {
37 | if (typeof window !== "undefined") {
38 | import("@tauri-apps/api").then((module) => {
39 | setAppWindow(module.window.getCurrent())
40 | })
41 | }
42 | }, [])
43 |
44 | // Update the isWindowMaximized state when the window is resized
45 | const updateIsWindowMaximized = useCallback(async () => {
46 | if (appWindow) {
47 | const _isWindowMaximized = await appWindow.isMaximized()
48 | setIsWindowMaximized(_isWindowMaximized)
49 | }
50 | }, [appWindow])
51 |
52 | useEffect(() => {
53 | getOsType().then((osname) => {
54 | // temporary: https://github.com/agmmnn/tauri-controls/issues/10#issuecomment-1675884962
55 | if (osname !== "macos") {
56 | updateIsWindowMaximized()
57 | let unlisten: () => void = () => {}
58 |
59 | const listen = async () => {
60 | if (appWindow) {
61 | unlisten = await appWindow.onResized(() => {
62 | updateIsWindowMaximized()
63 | })
64 | }
65 | }
66 | listen()
67 |
68 | // Cleanup the listener when the component unmounts
69 | return () => unlisten && unlisten()
70 | }
71 | })
72 | }, [appWindow, updateIsWindowMaximized])
73 |
74 | const minimizeWindow = async () => {
75 | if (appWindow) {
76 | await appWindow.minimize()
77 | }
78 | }
79 |
80 | const maximizeWindow = async () => {
81 | if (appWindow) {
82 | await appWindow.toggleMaximize()
83 | }
84 | }
85 |
86 | const fullscreenWindow = async () => {
87 | if (appWindow) {
88 | const fullscreen = await appWindow.isFullscreen()
89 | if (fullscreen) {
90 | await appWindow.setFullscreen(false)
91 | } else {
92 | await appWindow.setFullscreen(true)
93 | }
94 | }
95 | }
96 |
97 | const closeWindow = async () => {
98 | if (appWindow) {
99 | await appWindow.close()
100 | }
101 | }
102 |
103 | // Provide the context values to the children components
104 | return (
105 |
115 | {children}
116 |
117 | )
118 | }
119 |
120 | export default TauriAppWindowContext
121 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src/tauri-controls/controls/index.ts:
--------------------------------------------------------------------------------
1 | export { Windows } from "./windows"
2 | export { MacOS } from "./macos"
3 | export { Gnome } from "./linux"
4 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src/tauri-controls/controls/linux/gnome.tsx:
--------------------------------------------------------------------------------
1 | import React, { useContext, type HTMLProps } from "react"
2 | import { Button } from "src/tauri-controls/components/button"
3 | import { Icons } from "src/tauri-controls/components/icons"
4 | import TauriAppWindowContext from "src/tauri-controls/contexts/plugin-window"
5 | import { cn } from "src/tauri-controls/libs/utils"
6 |
7 | export function Gnome({ className, ...props }: HTMLProps) {
8 | const { isWindowMaximized, minimizeWindow, maximizeWindow, closeWindow } =
9 | useContext(TauriAppWindowContext)
10 |
11 | return (
12 |
16 |
20 |
21 |
22 |
26 | {!isWindowMaximized ? (
27 |
28 | ) : (
29 |
30 | )}
31 |
32 |
36 |
37 |
38 |
39 | )
40 | }
41 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src/tauri-controls/controls/linux/index.ts:
--------------------------------------------------------------------------------
1 | export { Gnome } from "./gnome"
2 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src/tauri-controls/controls/macos.tsx:
--------------------------------------------------------------------------------
1 | import { useContext, useEffect, useState, type HTMLProps } from "react"
2 | import { Icons } from "src/tauri-controls/components/icons"
3 | import { cn } from "src/tauri-controls/libs/utils"
4 | import { Button } from "../components/button"
5 | import TauriAppWindowContext from "../contexts/plugin-window"
6 |
7 | export function MacOS({ className, ...props }: HTMLProps) {
8 | const { minimizeWindow, maximizeWindow, fullscreenWindow, closeWindow } =
9 | useContext(TauriAppWindowContext)
10 |
11 | const [isAltKeyPressed, setIsAltKeyPressed] = useState(false)
12 | const [isHovering, setIsHovering] = useState(false)
13 |
14 | const last = isAltKeyPressed ? :
15 | const key = "Alt"
16 |
17 | const handleMouseEnter = () => {
18 | setIsHovering(true)
19 | }
20 | const handleMouseLeave = () => {
21 | setIsHovering(false)
22 | }
23 |
24 | const handleAltKeyDown = (e: KeyboardEvent) => {
25 | if (e.key === key) {
26 | setIsAltKeyPressed(true)
27 | }
28 | }
29 | const handleAltKeyUp = (e: KeyboardEvent) => {
30 | if (e.key === key) {
31 | setIsAltKeyPressed(false)
32 | }
33 | }
34 | useEffect(() => {
35 | // Attach event listeners when the component mounts
36 | window.addEventListener("keydown", handleAltKeyDown)
37 | window.addEventListener("keyup", handleAltKeyUp)
38 | }, [])
39 |
40 | return (
41 |
50 |
54 | {isHovering && }
55 |
56 |
60 | {isHovering && }
61 |
62 |
68 | {isHovering && last}
69 |
70 |
71 | )
72 | }
73 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src/tauri-controls/controls/windows.tsx:
--------------------------------------------------------------------------------
1 | import { useContext, type HTMLProps } from "react"
2 | import { Icons } from "src/tauri-controls/components/icons"
3 | import TauriAppWindowContext from "src/tauri-controls/contexts/plugin-window"
4 | import { cn } from "src/tauri-controls/libs/utils"
5 | import { Button } from "../components/button"
6 |
7 | export function Windows({ className, ...props }: HTMLProps) {
8 | const { isWindowMaximized, minimizeWindow, maximizeWindow, closeWindow } =
9 | useContext(TauriAppWindowContext)
10 |
11 | return (
12 |
13 |
17 |
18 |
19 |
27 | {!isWindowMaximized ? (
28 |
29 | ) : (
30 |
31 | )}
32 |
33 |
37 |
38 |
39 |
40 | )
41 | }
42 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src/tauri-controls/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src/tauri-controls/index.ts:
--------------------------------------------------------------------------------
1 | import "./index.css"
2 |
3 | export type { WindowControlsProps, WindowTitlebarProps } from "./types"
4 |
5 | export { WindowControls } from "./window-controls"
6 | export { WindowTitlebar } from "./window-titlebar"
7 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src/tauri-controls/libs/plugin-os.ts:
--------------------------------------------------------------------------------
1 | import type { OsType } from "@tauri-apps/plugin-os"
2 |
3 | let osType: OsType | undefined = undefined
4 | let osTypePromise: Promise | null = null
5 |
6 | if (typeof window !== "undefined") {
7 | osTypePromise = import("@tauri-apps/plugin-os").then((module) => {
8 | return module.type().then((x) => {
9 | osType = x // Assign the value of osType here
10 | return x // Return the value to the promise chain
11 | })
12 | })
13 | }
14 |
15 | // A helper function to get the OS type, which returns a Promise
16 | export function getOsType(): Promise {
17 | if (!osTypePromise) {
18 | // If the module was already loaded, just return the result
19 | return Promise.resolve(osType!) // Use non-null assertion
20 | }
21 |
22 | // If the module is still loading, wait for it to finish and return the result
23 | return osTypePromise
24 | }
25 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src/tauri-controls/libs/utils.ts:
--------------------------------------------------------------------------------
1 | import { clsx, type ClassValue } from "clsx"
2 | import { twMerge } from "tailwind-merge"
3 |
4 | export function cn(...inputs: ClassValue[]) {
5 | return twMerge(clsx(inputs))
6 | }
7 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src/tauri-controls/types.ts:
--------------------------------------------------------------------------------
1 | import type { HTMLProps } from "react"
2 |
3 | /**
4 | * Interface for window controls.
5 | * If the `platform` property is not specified, the library will automatically detect
6 | * the operating system the app is running on and display the appropriate elements.
7 | */
8 | export interface WindowControlsProps extends HTMLProps {
9 | /**
10 | * Specifies which platform's window controls to display.
11 | * It can be one of "windows", "macos", or "gnome".
12 | * If the `platform` property is not specified, the library will automatically detect
13 | * the operating system the app is running on and display the appropriate elements.
14 | */
15 | platform?: "windows" | "macos" | "gnome"
16 |
17 | /**
18 | * Indicates whether the window controls should be shown or hidden.
19 | * @default false
20 | */
21 | hide?: boolean
22 |
23 | /**
24 | * - "display": "display: none;" making them completely invisible and not taking up any space.
25 | * - "visibility": "visibility: hidden;" making them invisible but still occupying the same space.
26 | * @default "display"
27 | */
28 | hideMethod?: "display" | "visibility"
29 |
30 | /**
31 | * Justify/Snap WindowControls
32 | *
33 | * @default false, (if not defined in WindowTitlebar automatically assigned)
34 | */
35 | justify?: boolean
36 |
37 | /**
38 | * Specifies the Linux desktop environment for which the window controls are intended.
39 | * This property is applicable only when the platform is set to "linux".
40 | * @default "gnome"
41 | */
42 | // linuxDesktop?: "gnome" | "kde" | "budgie"
43 |
44 | /**
45 | * Indicates whether to prevent the right-click context menu.
46 | * When set to true, it will prevent the default right-click behavior.
47 | * (only in production, default false)
48 | */
49 | // preventRightClickMenu?: "always" | "production"
50 |
51 | /** `data-tauri-drag-region` */
52 | "data-tauri-drag-region"?: boolean
53 | }
54 |
55 | /**
56 | * Interface for titlebar
57 | */
58 | export interface WindowTitlebarProps extends HTMLProps {
59 | /**
60 | * The `controlsOrder` property is an optional property used in the `WindowControls` interface.
61 | * It allows you to specify the order in which the window controls should be rendered relative to the children.
62 | * (default: system)
63 | *
64 | * When `controlsOrder` is not specified or set to `system`, the default behavior will be as follows:
65 | * - For platforms other than macOS, the controls will be on the right side of the children.
66 | * - For macOS, the controls will be on the left side of the children (similar to "left" option).
67 | *
68 | * Possible values for `controlsOrder`:
69 | * - "right": The window controls will be rendered to the right of the children.
70 | * - "left": The window controls will be rendered to the left of the children. This order applies only when the platform is macOS (macOS window controls are usually located on the left side of the title bar).
71 | * - "platform": for OS-based positioning specified in `windowControlsProps`
72 | * @default "system"
73 | */
74 | controlsOrder?: "right" | "left" | "platform" | "system"
75 |
76 | /**
77 | * `WindowControls` props
78 | */
79 | windowControlsProps?: WindowControlsProps
80 | }
81 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src/tauri-controls/window-controls.tsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react"
2 | import { cn } from "src/tauri-controls/libs/utils"
3 | import { TauriAppWindowProvider } from "./contexts/plugin-window"
4 | import { Gnome, MacOS, Windows } from "./controls"
5 | import { getOsType } from "./libs/plugin-os"
6 | import type { WindowControlsProps } from "./types"
7 |
8 | export function WindowControls({
9 | platform,
10 | justify = false,
11 | hide = false,
12 | hideMethod = "display",
13 | // linuxDesktop = "gnome",
14 | className,
15 | ...props
16 | }: WindowControlsProps) {
17 | const [osType, setOsType] = useState(undefined)
18 |
19 | useEffect(() => {
20 | getOsType().then((type) => {
21 | setOsType(type)
22 | })
23 | }, [])
24 |
25 | const customClass = cn(
26 | "flex",
27 | className,
28 | hide && (hideMethod === "display" ? "hidden" : "invisible")
29 | )
30 |
31 | // Determine the default platform based on the operating system if not specified
32 | if (!platform) {
33 | switch (osType) {
34 | case "macos":
35 | platform = "macos"
36 | break
37 | case "linux":
38 | platform = "gnome"
39 | break
40 | default:
41 | platform = "windows"
42 | }
43 | }
44 |
45 | const ControlsComponent = () => {
46 | switch (platform) {
47 | case "windows":
48 | return (
49 |
53 | )
54 | case "macos":
55 | return (
56 |
57 | )
58 | case "gnome":
59 | return (
60 |
61 | )
62 | default:
63 | return (
64 |
68 | )
69 | }
70 | }
71 |
72 | return (
73 |
74 |
75 |
76 | )
77 | }
78 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src/tauri-controls/window-titlebar.tsx:
--------------------------------------------------------------------------------
1 | import type { OsType } from "@tauri-apps/plugin-os"
2 | import { useEffect, useState } from "react"
3 | import { cn } from "src/tauri-controls/libs/utils"
4 | import { getOsType } from "./libs/plugin-os"
5 | import type { WindowTitlebarProps } from "./types"
6 | import { WindowControls } from "./window-controls"
7 |
8 | export function WindowTitlebar({
9 | children,
10 | controlsOrder = "system",
11 | className,
12 | windowControlsProps,
13 | ...props
14 | }: WindowTitlebarProps) {
15 | const [osType, setOsType] = useState(undefined)
16 |
17 | useEffect(() => {
18 | getOsType().then((type) => {
19 | setOsType(type)
20 | })
21 | }, [])
22 |
23 | const left =
24 | controlsOrder === "left" ||
25 | (controlsOrder === "platform" &&
26 | windowControlsProps?.platform === "macos") ||
27 | (controlsOrder === "system" && osType === "macos")
28 |
29 | const customProps = (ml: string) => {
30 | if (windowControlsProps?.justify !== undefined) return windowControlsProps
31 |
32 | const {
33 | justify: windowControlsJustify,
34 | className: windowControlsClassName,
35 | ...restProps
36 | } = windowControlsProps || {}
37 | return {
38 | justify: false,
39 | className: cn(windowControlsClassName, ml),
40 | ...restProps,
41 | }
42 | }
43 |
44 | return (
45 |
53 | {left ? (
54 | <>
55 |
56 | {children}
57 | >
58 | ) : (
59 | <>
60 | {children}
61 |
62 | >
63 | )}
64 |
65 | )
66 | }
67 |
--------------------------------------------------------------------------------
/apps/tauri-controls/src/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/apps/tauri-controls/tailwind.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('tailwindcss').Config} */
2 | export default {
3 | darkMode: "class",
4 | content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
5 | // content: ["./src/tauri-controls/**/*.{js,ts,jsx,tsx}"],
6 | theme: {
7 | extend: {},
8 | },
9 | plugins: [],
10 | }
11 |
--------------------------------------------------------------------------------
/apps/tauri-controls/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ESNext",
4 | "useDefineForClassFields": true,
5 | "lib": ["DOM", "DOM.Iterable", "ESNext"],
6 | "allowJs": false,
7 | "allowSyntheticDefaultImports": true,
8 | "strict": true,
9 | "forceConsistentCasingInFileNames": true,
10 | "module": "ESNext",
11 | "moduleResolution": "Node",
12 | "resolveJsonModule": true,
13 | "isolatedModules": true,
14 | "noEmit": true,
15 | "jsx": "react-jsx",
16 | "declaration": true,
17 | "outDir": "./dist",
18 | "skipLibCheck": true,
19 | "esModuleInterop": true,
20 | "declarationMap": true,
21 | "baseUrl": ".",
22 | "paths": {
23 | "tauri-controls": ["src/tauri-controls/index.ts"]
24 | },
25 | "typeRoots": ["node_modules/@types", "src/tauri-controls/types.ts"]
26 | },
27 | "include": ["src", "src/tauri-controls"],
28 | "references": [{ "path": "./tsconfig.node.json" }]
29 | }
30 |
--------------------------------------------------------------------------------
/apps/tauri-controls/tsconfig.node.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "composite": true,
4 | "module": "ESNext",
5 | "moduleResolution": "Node",
6 | "allowSyntheticDefaultImports": true,
7 | "resolveJsonModule": true
8 | },
9 | "include": ["vite.config.ts", "package.json"]
10 | }
11 |
--------------------------------------------------------------------------------
/apps/tauri-controls/vite.config.ts:
--------------------------------------------------------------------------------
1 | import { resolve } from "node:path"
2 | import terser from "@rollup/plugin-terser"
3 | import react from "@vitejs/plugin-react-swc"
4 | import { defineConfig } from "vite"
5 | import dts from "vite-plugin-dts"
6 | import tsConfigPaths from "vite-tsconfig-paths"
7 | import * as packageJson from "./package.json"
8 |
9 | export default defineConfig((configEnv) => ({
10 | plugins: [
11 | dts({
12 | include: ["./src/tauri-controls"],
13 | rollupTypes: true,
14 | }),
15 | react(),
16 | tsConfigPaths(),
17 | // linterPlugin({
18 | // include: ["./src/tauri-controls/**/*.{ts,tsx}"],
19 | // linters: [new EsLinter({ configEnv })],
20 | // }),
21 | ],
22 | build: {
23 | lib: {
24 | entry: resolve("src", "tauri-controls/index.ts"),
25 | name: "TauriControls",
26 | formats: ["es"], //"umd"
27 | fileName: () => `tauri-controls.js`,
28 | },
29 | rollupOptions: {
30 | external: [...Object.keys(packageJson.peerDependencies)],
31 | plugins: [terser()],
32 | output: {
33 | globals: {
34 | react: "React",
35 | "react-dom": "ReactDOM",
36 | "@tauri-apps/plugin-os": "pluginOs",
37 | clsx: "clsx",
38 | "tailwind-merge": "tailwindMerge",
39 | "@tauri-apps/plugin-window": "pluginWindow",
40 | },
41 | intro: 'import "./style.css";',
42 | plugins: [terser()],
43 | },
44 | },
45 | },
46 |
47 | clearScreen: false,
48 | server: {
49 | port: 1421,
50 | strictPort: true,
51 | },
52 | envPrefix: ["VITE_", "TAURI_"],
53 | }))
54 |
--------------------------------------------------------------------------------
/bun.lockb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/agmmnn/tauri-controls/f3592f08395de513ec842fdc347639bef68ca974/bun.lockb
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "tauri-controls-root",
3 | "private": true,
4 | "version": "1.0.0",
5 | "workspaces": ["apps/*"],
6 | "scripts": {
7 | "build": "turbo run build",
8 | "dev": "turbo run dev",
9 | "preview": "turbo run preview",
10 | "build:watch": "turbo run build:watch",
11 | "lint": "turbo run lint",
12 | "format": "prettier --write \"**/*.{ts,tsx,md}\" && turbo run format",
13 | "publish-packages": "turbo run build && changeset version && changeset publish",
14 | "taze": "taze minor -r -w -i false -I",
15 | "changeset": "changeset",
16 | "taze:major": "taze major -r -w -i false -I",
17 | "tauri:dev": "turbo run tauri:dev"
18 | },
19 | "devDependencies": {
20 | "@changesets/cli": "^2.27.1",
21 | "@tauri-apps/api": "2.0.0-beta.6",
22 | "@turbo/gen": "^1.13.0",
23 | "eslint": "^8.57.0",
24 | "prettier": "^3.2.5",
25 | "taze": "^0.13.3",
26 | "turbo": "1.13"
27 | },
28 | "packageManager": "bun@1.0.35",
29 | "dependencies": {
30 | "@changesets/changelog-git": "^0.2.0"
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/prettier.config.js:
--------------------------------------------------------------------------------
1 | /** @type {import('prettier').Config} */
2 | module.exports = {
3 | endOfLine: "lf",
4 | semi: false,
5 | singleQuote: false,
6 | tabWidth: 2,
7 | trailingComma: "none",
8 | plugins: [
9 | "prettier-plugin-svelte",
10 | "@ianvs/prettier-plugin-sort-imports",
11 | "prettier-plugin-tailwindcss"
12 | ],
13 | overrides: [{ files: "*.svelte", options: { parser: "svelte" } }]
14 | }
15 |
--------------------------------------------------------------------------------
/turbo.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://turbo.build/schema.json",
3 | "globalDependencies": [
4 | "**/.env.*local"
5 | ],
6 | "pipeline": {
7 | "dev": {
8 | "cache": false,
9 | "persistent": true
10 | },
11 | "preview": {
12 | "dependsOn": [
13 | "^preview"
14 | ],
15 | "cache": false
16 | },
17 | "build": {
18 | "dependsOn": [
19 | "^build"
20 | ]
21 | },
22 | "build:watch": {
23 | "dependsOn": [
24 | "^build:watch"
25 | ]
26 | },
27 | "format": {},
28 | "lint": {},
29 | "tauri": {
30 | "dependsOn": [
31 | "^tauri"
32 | ],
33 | "cache": false
34 | },
35 | "tauri:dev": {
36 | "dependsOn": [
37 | "^tauri"
38 | ],
39 | "cache": false
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------