├── .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 | Tauri Controls 4 | 5 | 6 | ![](https://img.shields.io/bundlephobia/min/%40tauri-controls%2Fsolid) 7 | ![](https://img.shields.io/bundlephobia/minzip/%40tauri-controls%2Fsolid) 8 | [![](https://img.shields.io/npm/dt/%40tauri-controls%2Fsolid)](https://npmjs.com/package/tauri-controls) ![SolidJS](https://img.shields.io/badge/SolidJS-2c4f7c?logo=solid&logoColor=c8c9cb) 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 | 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 | 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 | 29 | 39 | 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 | 71 | 77 | 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 | 23 | 37 | 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 | Tauri Controls 4 | 5 | 6 | ![](https://img.shields.io/bundlephobia/min/@tauri-controls/svelte) 7 | ![](https://img.shields.io/bundlephobia/minzip/@tauri-controls/svelte) 8 | ![](https://img.shields.io/npm/dt/@tauri-controls/svelte) 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 | 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 | 81 | 89 | 101 |
102 | -------------------------------------------------------------------------------- /apps/tauri-controls-svelte/src/lib/controls/Windows.svelte: -------------------------------------------------------------------------------- 1 | 19 | 20 |
21 | 27 | 41 | 47 |
48 | -------------------------------------------------------------------------------- /apps/tauri-controls-svelte/src/lib/controls/linux/Gnome.svelte: -------------------------------------------------------------------------------- 1 | 19 | 20 |
24 | 30 | 40 | 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 | 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 | Tauri Controls 4 | 5 | 6 | ![](https://img.shields.io/bundlephobia/min/%40tauri-controls%2Fvue) 7 | ![](https://img.shields.io/bundlephobia/minzip/%40tauri-controls%2Fvue) 8 | [![](https://img.shields.io/npm/dt/%40tauri-controls%2Fvue)](https://npmjs.com/package/tauri-controls) [![Vue.js](https://img.shields.io/badge/Vue.js-%2335495e.svg?logo=vuedotjs&logoColor=%234FC08D)](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 | 115 | -------------------------------------------------------------------------------- /apps/tauri-controls-vue/src/components/LogoSvg.vue: -------------------------------------------------------------------------------- 1 | 19 | -------------------------------------------------------------------------------- /apps/tauri-controls-vue/src/components/Menu.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 12 | -------------------------------------------------------------------------------- /apps/tauri-controls-vue/src/components/ThemeSwitch.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 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 | 61 | -------------------------------------------------------------------------------- /apps/tauri-controls-vue/src/tauri-controls/WindowTitlebar.vue: -------------------------------------------------------------------------------- 1 | 44 | 45 | 65 | -------------------------------------------------------------------------------- /apps/tauri-controls-vue/src/tauri-controls/components/Button.vue: -------------------------------------------------------------------------------- 1 | 4 | 16 | -------------------------------------------------------------------------------- /apps/tauri-controls-vue/src/tauri-controls/controls/MacOs.vue: -------------------------------------------------------------------------------- 1 | 33 | 34 | 67 | -------------------------------------------------------------------------------- /apps/tauri-controls-vue/src/tauri-controls/controls/Windows.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 41 | -------------------------------------------------------------------------------- /apps/tauri-controls-vue/src/tauri-controls/controls/linux/Gnome.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 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 | Tauri Controls 4 | 5 | 6 | [![](https://img.shields.io/bundlephobia/min/tauri-controls)](https://bundlephobia.com/) 7 | [![](https://img.shields.io/bundlephobia/minzip/tauri-controls)](https://bundlephobia.com/) 8 | [![](https://img.shields.io/npm/dt/tauri-controls)](https://npmjs.com/package/tauri-controls) 9 | 10 | [![](https://img.shields.io/badge/React-20232A?logo=react&logoColor=61DAFB)](https://www.npmjs.com/package/tauri-controls) [![](https://img.shields.io/badge/Svelte-4A4A55?logo=svelte&logoColor=FF3E00)](https://www.npmjs.com/package/@tauri-controls/svelte) [![SolidJS](https://img.shields.io/badge/SolidJS-2c4f7c?logo=solid&logoColor=c8c9cb)](https://www.npmjs.com/package/@tauri-controls/solid) [![Vue.js](https://img.shields.io/badge/Vue.js-%2335495e.svg?logo=vuedotjs&logoColor=%234FC08D)](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 | ![](https://github.com/agmmnn/tauri-controls/assets/16024979/214677d4-dd70-4e6b-96c3-b9d1a1356f05) 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 | ![](https://github.com/agmmnn/tauri-controls/assets/16024979/7be3dde4-7953-4188-af12-abd4445c0bf9) 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 | ![Example](https://i.imgur.com/OAO22HC.png) 132 | ![Example](https://i.imgur.com/hq389kn.png) 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 | 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 | 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 | 22 | 32 | 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 | 56 | 62 | 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 | 19 | 33 | 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 | --------------------------------------------------------------------------------