mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2025-11-04 13:31:13 +00:00
update shadcn components
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://next.shadcn-svelte.com/schema.json",
|
"$schema": "https://shadcn-svelte.com/schema.json",
|
||||||
|
"style": "default",
|
||||||
"tailwind": {
|
"tailwind": {
|
||||||
"css": "src/app.css",
|
"css": "src/app.css",
|
||||||
"baseColor": "slate"
|
"baseColor": "slate"
|
||||||
@@ -12,5 +13,5 @@
|
|||||||
"lib": "$lib"
|
"lib": "$lib"
|
||||||
},
|
},
|
||||||
"typescript": true,
|
"typescript": true,
|
||||||
"registry": "https://next.shadcn-svelte.com/registry"
|
"registry": "https://shadcn-svelte.com/registry"
|
||||||
}
|
}
|
||||||
|
|||||||
134
website/package-lock.json
generated
134
website/package-lock.json
generated
@@ -27,11 +27,10 @@
|
|||||||
"png.js": "^0.2.1",
|
"png.js": "^0.2.1",
|
||||||
"sanitize-html": "^2.17.0",
|
"sanitize-html": "^2.17.0",
|
||||||
"sortablejs": "^1.15.6",
|
"sortablejs": "^1.15.6",
|
||||||
"tailwind-merge": "^3.3.0",
|
"tailwind-merge": "^3.3.0"
|
||||||
"tailwind-variants": "^1.0.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@lucide/svelte": "^0.513.0",
|
"@lucide/svelte": "^0.544.0",
|
||||||
"@sveltejs/adapter-static": "^3.0.8",
|
"@sveltejs/adapter-static": "^3.0.8",
|
||||||
"@sveltejs/enhanced-img": "^0.6.0",
|
"@sveltejs/enhanced-img": "^0.6.0",
|
||||||
"@sveltejs/kit": "^2.21.2",
|
"@sveltejs/kit": "^2.21.2",
|
||||||
@@ -48,7 +47,7 @@
|
|||||||
"@types/sortablejs": "^1.15.8",
|
"@types/sortablejs": "^1.15.8",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.33.1",
|
"@typescript-eslint/eslint-plugin": "^8.33.1",
|
||||||
"@typescript-eslint/parser": "^8.33.1",
|
"@typescript-eslint/parser": "^8.33.1",
|
||||||
"bits-ui": "^2.5.0",
|
"bits-ui": "^2.12.0",
|
||||||
"eslint": "^9.28.0",
|
"eslint": "^9.28.0",
|
||||||
"eslint-config-prettier": "^10.1.5",
|
"eslint-config-prettier": "^10.1.5",
|
||||||
"eslint-plugin-svelte": "^3.9.1",
|
"eslint-plugin-svelte": "^3.9.1",
|
||||||
@@ -56,14 +55,15 @@
|
|||||||
"glob": "^11.0.2",
|
"glob": "^11.0.2",
|
||||||
"lucide-static": "^0.513.0",
|
"lucide-static": "^0.513.0",
|
||||||
"mdsvex": "^0.12.6",
|
"mdsvex": "^0.12.6",
|
||||||
"mode-watcher": "^1.0.7",
|
"mode-watcher": "^1.1.0",
|
||||||
"paneforge": "^1.0.0-next.5",
|
"paneforge": "^1.0.0-next.5",
|
||||||
"postcss": "^8.4.47",
|
"postcss": "^8.4.47",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
"prettier-plugin-svelte": "^3.4.0",
|
"prettier-plugin-svelte": "^3.4.0",
|
||||||
"svelte": "^5.33.18",
|
"svelte": "^5.33.18",
|
||||||
"svelte-check": "^4.0.0",
|
"svelte-check": "^4.0.0",
|
||||||
"svelte-sonner": "^1.0.4",
|
"svelte-sonner": "^1.0.5",
|
||||||
|
"tailwind-variants": "^3.1.1",
|
||||||
"tailwindcss": "^4.1.8",
|
"tailwindcss": "^4.1.8",
|
||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"tsx": "^4.19.1",
|
"tsx": "^4.19.1",
|
||||||
@@ -1625,9 +1625,9 @@
|
|||||||
"integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw=="
|
"integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw=="
|
||||||
},
|
},
|
||||||
"node_modules/@lucide/svelte": {
|
"node_modules/@lucide/svelte": {
|
||||||
"version": "0.513.0",
|
"version": "0.544.0",
|
||||||
"resolved": "https://registry.npmjs.org/@lucide/svelte/-/svelte-0.513.0.tgz",
|
"resolved": "https://registry.npmjs.org/@lucide/svelte/-/svelte-0.544.0.tgz",
|
||||||
"integrity": "sha512-XwBQMQkMlr9qp9yVg+epx5MzhBBrqul8atO00y/ZfhlKRJuQZVmq3ELibApqyBtj9ys0Ai4FH/SZcODTUFYXig==",
|
"integrity": "sha512-9f9O6uxng2pLB01sxNySHduJN3HTl5p0HDu4H26VR51vhZfiMzyOMe9Mhof3XAk4l813eTtl+/DYRvGyoRR+yw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
@@ -3233,23 +3233,21 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"node_modules/bits-ui": {
|
"node_modules/bits-ui": {
|
||||||
"version": "2.5.0",
|
"version": "2.12.0",
|
||||||
"resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-2.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/bits-ui/-/bits-ui-2.12.0.tgz",
|
||||||
"integrity": "sha512-PbjylA1UWd4A/c5AYqie/EVxQ1/8uugmJKLg9whLoBBHbfPEBGhK09dCPrahK9kA6DRHhMmij0XXIUGIfrmNow==",
|
"integrity": "sha512-8NF4ILNyAJlIxDXpl/akGXGBV5QmZAe+8gTfPttM5P6/+LrijumcSfFXY5cr4QkXwTmLA7H5stYpbgJf2XFJvg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@floating-ui/core": "^1.7.0",
|
"@floating-ui/core": "^1.7.1",
|
||||||
"@floating-ui/dom": "^1.7.0",
|
"@floating-ui/dom": "^1.7.1",
|
||||||
"css.escape": "^1.5.1",
|
|
||||||
"esm-env": "^1.1.2",
|
"esm-env": "^1.1.2",
|
||||||
"runed": "^0.28.0",
|
"runed": "^0.35.1",
|
||||||
"svelte-toolbelt": "^0.9.1",
|
"svelte-toolbelt": "^0.10.6",
|
||||||
"tabbable": "^6.2.0"
|
"tabbable": "^6.2.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=20",
|
"node": ">=20"
|
||||||
"pnpm": ">=8.7.0"
|
|
||||||
},
|
},
|
||||||
"funding": {
|
"funding": {
|
||||||
"url": "https://github.com/sponsors/huntabyte"
|
"url": "https://github.com/sponsors/huntabyte"
|
||||||
@@ -3260,9 +3258,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/bits-ui/node_modules/runed": {
|
"node_modules/bits-ui/node_modules/runed": {
|
||||||
"version": "0.28.0",
|
"version": "0.35.1",
|
||||||
"resolved": "https://registry.npmjs.org/runed/-/runed-0.28.0.tgz",
|
"resolved": "https://registry.npmjs.org/runed/-/runed-0.35.1.tgz",
|
||||||
"integrity": "sha512-k2xx7RuO9hWcdd9f+8JoBeqWtYrm5CALfgpkg2YDB80ds/QE4w0qqu34A7fqiAwiBBSBQOid7TLxwxVC27ymWQ==",
|
"integrity": "sha512-2F4Q/FZzbeJTFdIS/PuOoPRSm92sA2LhzTnv6FXhCoENb3huf5+fDuNOg1LNvGOouy3u/225qxmuJvcV3IZK5Q==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
"https://github.com/sponsors/huntabyte",
|
"https://github.com/sponsors/huntabyte",
|
||||||
@@ -3270,23 +3268,31 @@
|
|||||||
],
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"esm-env": "^1.0.0"
|
"dequal": "^2.0.3",
|
||||||
|
"esm-env": "^1.0.0",
|
||||||
|
"lz-string": "^1.5.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
"@sveltejs/kit": "^2.21.0",
|
||||||
"svelte": "^5.7.0"
|
"svelte": "^5.7.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@sveltejs/kit": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/bits-ui/node_modules/svelte-toolbelt": {
|
"node_modules/bits-ui/node_modules/svelte-toolbelt": {
|
||||||
"version": "0.9.1",
|
"version": "0.10.6",
|
||||||
"resolved": "https://registry.npmjs.org/svelte-toolbelt/-/svelte-toolbelt-0.9.1.tgz",
|
"resolved": "https://registry.npmjs.org/svelte-toolbelt/-/svelte-toolbelt-0.10.6.tgz",
|
||||||
"integrity": "sha512-wBX6MtYw/kpht80j5zLpxJyR9soLizXPIAIWEVd9llAi17SR44ZdG291bldjB7r/K5duC0opDFcuhk2cA1hb8g==",
|
"integrity": "sha512-YWuX+RE+CnWYx09yseAe4ZVMM7e7GRFZM6OYWpBKOb++s+SQ8RBIMMe+Bs/CznBMc0QPLjr+vDBxTAkozXsFXQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
"https://github.com/sponsors/huntabyte"
|
"https://github.com/sponsors/huntabyte"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"clsx": "^2.1.1",
|
"clsx": "^2.1.1",
|
||||||
"runed": "^0.28.0",
|
"runed": "^0.35.1",
|
||||||
"style-to-object": "^1.0.8"
|
"style-to-object": "^1.0.8"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -3891,13 +3897,6 @@
|
|||||||
"node": "*"
|
"node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/css.escape": {
|
|
||||||
"version": "1.5.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz",
|
|
||||||
"integrity": "sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/csscolorparser": {
|
"node_modules/csscolorparser": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz",
|
||||||
@@ -4053,6 +4052,16 @@
|
|||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/dequal": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/des.js": {
|
"node_modules/des.js": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/des.js/-/des.js-1.1.0.tgz",
|
||||||
@@ -6019,6 +6028,16 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/lz-string": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"lz-string": "bin/bin.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/magic-string": {
|
"node_modules/magic-string": {
|
||||||
"version": "0.30.17",
|
"version": "0.30.17",
|
||||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
|
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
|
||||||
@@ -6369,9 +6388,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/mode-watcher": {
|
"node_modules/mode-watcher": {
|
||||||
"version": "1.0.7",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/mode-watcher/-/mode-watcher-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/mode-watcher/-/mode-watcher-1.1.0.tgz",
|
||||||
"integrity": "sha512-ZGA7ZGdOvBJeTQkzdBOnXSgTkO6U6iIFWJoyGCTt6oHNg9XP9NBvS26De+V4W2aqI+B0yYXUskFG2VnEo3zyMQ==",
|
"integrity": "sha512-mUT9RRGPDYenk59qJauN1rhsIMKBmWA3xMF+uRwE8MW/tjhaDSCCARqkSuDTq8vr4/2KcAxIGVjACxTjdk5C3g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -8292,22 +8311,22 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/svelte-sonner": {
|
"node_modules/svelte-sonner": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/svelte-sonner/-/svelte-sonner-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/svelte-sonner/-/svelte-sonner-1.0.5.tgz",
|
||||||
"integrity": "sha512-ctm9jeV0Rf3im2J6RU1emccrJFjRSdNSPsLlxaF62TLZw9bB1D40U/U7+wqEgohJY/X7FBdghdj0BFQF/IqKPQ==",
|
"integrity": "sha512-9dpGPFqKb/QWudYqGnEz93vuY+NgCEvyNvxoCLMVGw6sDN/3oVeKV1xiEirW2E1N3vJEyj5imSBNOGltQHA7mg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"runed": "^0.26.0"
|
"runed": "^0.28.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"svelte": "^5.0.0"
|
"svelte": "^5.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/svelte-sonner/node_modules/runed": {
|
"node_modules/svelte-sonner/node_modules/runed": {
|
||||||
"version": "0.26.0",
|
"version": "0.28.0",
|
||||||
"resolved": "https://registry.npmjs.org/runed/-/runed-0.26.0.tgz",
|
"resolved": "https://registry.npmjs.org/runed/-/runed-0.28.0.tgz",
|
||||||
"integrity": "sha512-qWFv0cvLVRd8pdl/AslqzvtQyEn5KaIugEernwg9G98uJVSZcs/ygvPBvF80LA46V8pwRvSKnaVLDI3+i2wubw==",
|
"integrity": "sha512-k2xx7RuO9hWcdd9f+8JoBeqWtYrm5CALfgpkg2YDB80ds/QE4w0qqu34A7fqiAwiBBSBQOid7TLxwxVC27ymWQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"funding": [
|
"funding": [
|
||||||
"https://github.com/sponsors/huntabyte",
|
"https://github.com/sponsors/huntabyte",
|
||||||
@@ -8376,35 +8395,30 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tailwind-variants": {
|
"node_modules/tailwind-variants": {
|
||||||
"version": "1.0.0",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/tailwind-variants/-/tailwind-variants-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/tailwind-variants/-/tailwind-variants-3.1.1.tgz",
|
||||||
"integrity": "sha512-2WSbv4ulEEyuBKomOunut65D8UZwxrHoRfYnxGcQNnHqlSCp2+B7Yz2W+yrNDrxRodOXtGD/1oCcKGNBnUqMqA==",
|
"integrity": "sha512-ftLXe3krnqkMHsuBTEmaVUXYovXtPyTK7ckEfDRXS8PBZx0bAUas+A0jYxuKA5b8qg++wvQ3d2MQ7l/xeZxbZQ==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
|
||||||
"tailwind-merge": "3.0.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=16.x",
|
"node": ">=16.x",
|
||||||
"pnpm": ">=7.x"
|
"pnpm": ">=7.x"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
|
"tailwind-merge": ">=3.0.0",
|
||||||
"tailwindcss": "*"
|
"tailwindcss": "*"
|
||||||
}
|
},
|
||||||
},
|
"peerDependenciesMeta": {
|
||||||
"node_modules/tailwind-variants/node_modules/tailwind-merge": {
|
"tailwind-merge": {
|
||||||
"version": "3.0.2",
|
"optional": true
|
||||||
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-3.0.2.tgz",
|
}
|
||||||
"integrity": "sha512-l7z+OYZ7mu3DTqrL88RiKrKIqO3NcpEO8V/Od04bNpvk0kiIFndGEoqfuzvj4yuhRkHKjRkII2z+KS2HfPcSxw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"funding": {
|
|
||||||
"type": "github",
|
|
||||||
"url": "https://github.com/sponsors/dcastil"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/tailwindcss": {
|
"node_modules/tailwindcss": {
|
||||||
"version": "4.1.8",
|
"version": "4.1.8",
|
||||||
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.8.tgz",
|
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.8.tgz",
|
||||||
"integrity": "sha512-kjeW8gjdxasbmFKpVGrGd5T4i40mV5J2Rasw48QARfYeQ8YS9x02ON9SFWax3Qf616rt4Cp3nVNIj6Hd1mP3og==",
|
"integrity": "sha512-kjeW8gjdxasbmFKpVGrGd5T4i40mV5J2Rasw48QARfYeQ8YS9x02ON9SFWax3Qf616rt4Cp3nVNIj6Hd1mP3og==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/tapable": {
|
"node_modules/tapable": {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
"format": "prettier --write ."
|
"format": "prettier --write ."
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@lucide/svelte": "^0.513.0",
|
"@lucide/svelte": "^0.544.0",
|
||||||
"@sveltejs/adapter-static": "^3.0.8",
|
"@sveltejs/adapter-static": "^3.0.8",
|
||||||
"@sveltejs/enhanced-img": "^0.6.0",
|
"@sveltejs/enhanced-img": "^0.6.0",
|
||||||
"@sveltejs/kit": "^2.21.2",
|
"@sveltejs/kit": "^2.21.2",
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
"@types/sortablejs": "^1.15.8",
|
"@types/sortablejs": "^1.15.8",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.33.1",
|
"@typescript-eslint/eslint-plugin": "^8.33.1",
|
||||||
"@typescript-eslint/parser": "^8.33.1",
|
"@typescript-eslint/parser": "^8.33.1",
|
||||||
"bits-ui": "^2.5.0",
|
"bits-ui": "^2.12.0",
|
||||||
"eslint": "^9.28.0",
|
"eslint": "^9.28.0",
|
||||||
"eslint-config-prettier": "^10.1.5",
|
"eslint-config-prettier": "^10.1.5",
|
||||||
"eslint-plugin-svelte": "^3.9.1",
|
"eslint-plugin-svelte": "^3.9.1",
|
||||||
@@ -39,14 +39,15 @@
|
|||||||
"glob": "^11.0.2",
|
"glob": "^11.0.2",
|
||||||
"lucide-static": "^0.513.0",
|
"lucide-static": "^0.513.0",
|
||||||
"mdsvex": "^0.12.6",
|
"mdsvex": "^0.12.6",
|
||||||
"mode-watcher": "^1.0.7",
|
"mode-watcher": "^1.1.0",
|
||||||
"paneforge": "^1.0.0-next.5",
|
"paneforge": "^1.0.0-next.5",
|
||||||
"postcss": "^8.4.47",
|
"postcss": "^8.4.47",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
"prettier-plugin-svelte": "^3.4.0",
|
"prettier-plugin-svelte": "^3.4.0",
|
||||||
"svelte": "^5.33.18",
|
"svelte": "^5.33.18",
|
||||||
"svelte-check": "^4.0.0",
|
"svelte-check": "^4.0.0",
|
||||||
"svelte-sonner": "^1.0.4",
|
"svelte-sonner": "^1.0.5",
|
||||||
|
"tailwind-variants": "^3.1.1",
|
||||||
"tailwindcss": "^4.1.8",
|
"tailwindcss": "^4.1.8",
|
||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"tsx": "^4.19.1",
|
"tsx": "^4.19.1",
|
||||||
@@ -77,7 +78,6 @@
|
|||||||
"png.js": "^0.2.1",
|
"png.js": "^0.2.1",
|
||||||
"sanitize-html": "^2.17.0",
|
"sanitize-html": "^2.17.0",
|
||||||
"sortablejs": "^1.15.6",
|
"sortablejs": "^1.15.6",
|
||||||
"tailwind-merge": "^3.3.0",
|
"tailwind-merge": "^3.3.0"
|
||||||
"tailwind-variants": "^1.0.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { CircleHelp } from '@lucide/svelte';
|
import { CircleQuestionMark } from '@lucide/svelte';
|
||||||
import { i18n } from '$lib/i18n.svelte';
|
import { i18n } from '$lib/i18n.svelte';
|
||||||
|
|
||||||
export let link: string | undefined = undefined;
|
export let link: string | undefined = undefined;
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
<div
|
<div
|
||||||
class="text-sm bg-secondary rounded border flex flex-row items-center p-2 {$$props.class || ''}"
|
class="text-sm bg-secondary rounded border flex flex-row items-center p-2 {$$props.class || ''}"
|
||||||
>
|
>
|
||||||
<CircleHelp size="16" class="w-4 mr-2 shrink-0 grow-0" />
|
<CircleQuestionMark size="16" class="w-4 mr-2 shrink-0 grow-0" />
|
||||||
<div>
|
<div>
|
||||||
<slot />
|
<slot />
|
||||||
{#if link}
|
{#if link}
|
||||||
|
|||||||
@@ -120,13 +120,13 @@
|
|||||||
</Menubar.Trigger>
|
</Menubar.Trigger>
|
||||||
<Menubar.Content class="border-none">
|
<Menubar.Content class="border-none">
|
||||||
<Menubar.Item onclick={createFile}>
|
<Menubar.Item onclick={createFile}>
|
||||||
<Plus size="16" class="mr-1" />
|
<Plus size="16" />
|
||||||
{i18n._('menu.new')}
|
{i18n._('menu.new')}
|
||||||
<Shortcut key="+" ctrl={true} />
|
<Shortcut key="+" ctrl={true} />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
<Menubar.Separator />
|
<Menubar.Separator />
|
||||||
<Menubar.Item onclick={triggerFileInput}>
|
<Menubar.Item onclick={triggerFileInput}>
|
||||||
<FolderOpen size="16" class="mr-1" />
|
<FolderOpen size="16" />
|
||||||
{i18n._('menu.open')}
|
{i18n._('menu.open')}
|
||||||
<Shortcut key="O" ctrl={true} />
|
<Shortcut key="O" ctrl={true} />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
@@ -135,7 +135,7 @@
|
|||||||
onclick={fileActions.duplicateSelection}
|
onclick={fileActions.duplicateSelection}
|
||||||
disabled={$selection.size == 0}
|
disabled={$selection.size == 0}
|
||||||
>
|
>
|
||||||
<Copy size="16" class="mr-1" />
|
<Copy size="16" />
|
||||||
{i18n._('menu.duplicate')}
|
{i18n._('menu.duplicate')}
|
||||||
<Shortcut key="D" ctrl={true} />
|
<Shortcut key="D" ctrl={true} />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
@@ -144,7 +144,7 @@
|
|||||||
onclick={fileActions.deleteSelectedFiles}
|
onclick={fileActions.deleteSelectedFiles}
|
||||||
disabled={$selection.size == 0}
|
disabled={$selection.size == 0}
|
||||||
>
|
>
|
||||||
<FileX size="16" class="mr-1" />
|
<FileX size="16" />
|
||||||
{i18n._('menu.close')}
|
{i18n._('menu.close')}
|
||||||
<Shortcut key="⌫" ctrl={true} />
|
<Shortcut key="⌫" ctrl={true} />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
@@ -152,7 +152,7 @@
|
|||||||
onclick={fileActions.deleteAllFiles}
|
onclick={fileActions.deleteAllFiles}
|
||||||
disabled={fileStateCollection.size == 0}
|
disabled={fileStateCollection.size == 0}
|
||||||
>
|
>
|
||||||
<FileX size="16" class="mr-1" />
|
<FileX size="16" />
|
||||||
{i18n._('menu.close_all')}
|
{i18n._('menu.close_all')}
|
||||||
<Shortcut key="⌫" ctrl={true} shift={true} />
|
<Shortcut key="⌫" ctrl={true} shift={true} />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
@@ -161,7 +161,7 @@
|
|||||||
onclick={() => (exportState.current = ExportState.SELECTION)}
|
onclick={() => (exportState.current = ExportState.SELECTION)}
|
||||||
disabled={$selection.size == 0}
|
disabled={$selection.size == 0}
|
||||||
>
|
>
|
||||||
<Download size="16" class="mr-1" />
|
<Download size="16" />
|
||||||
{i18n._('menu.export')}
|
{i18n._('menu.export')}
|
||||||
<Shortcut key="S" ctrl={true} />
|
<Shortcut key="S" ctrl={true} />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
@@ -169,7 +169,7 @@
|
|||||||
onclick={() => (exportState.current = ExportState.ALL)}
|
onclick={() => (exportState.current = ExportState.ALL)}
|
||||||
disabled={fileStateCollection.size == 0}
|
disabled={fileStateCollection.size == 0}
|
||||||
>
|
>
|
||||||
<Download size="16" class="mr-1" />
|
<Download size="16" />
|
||||||
{i18n._('menu.export_all')}
|
{i18n._('menu.export_all')}
|
||||||
<Shortcut key="S" ctrl={true} shift={true} />
|
<Shortcut key="S" ctrl={true} shift={true} />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
@@ -185,7 +185,7 @@
|
|||||||
onclick={() => fileActionManager.undo()}
|
onclick={() => fileActionManager.undo()}
|
||||||
disabled={!fileActionManager.canUndo}
|
disabled={!fileActionManager.canUndo}
|
||||||
>
|
>
|
||||||
<Undo2 size="16" class="mr-1" />
|
<Undo2 size="16" />
|
||||||
{i18n._('menu.undo')}
|
{i18n._('menu.undo')}
|
||||||
<Shortcut key="Z" ctrl={true} />
|
<Shortcut key="Z" ctrl={true} />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
@@ -193,7 +193,7 @@
|
|||||||
onclick={() => fileActionManager.redo()}
|
onclick={() => fileActionManager.redo()}
|
||||||
disabled={!fileActionManager.canRedo}
|
disabled={!fileActionManager.canRedo}
|
||||||
>
|
>
|
||||||
<Redo2 size="16" class="mr-1" />
|
<Redo2 size="16" />
|
||||||
{i18n._('menu.redo')}
|
{i18n._('menu.redo')}
|
||||||
<Shortcut key="Z" ctrl={true} shift={true} />
|
<Shortcut key="Z" ctrl={true} shift={true} />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
@@ -209,7 +209,7 @@
|
|||||||
)}
|
)}
|
||||||
onclick={() => (editMetadata.current = true)}
|
onclick={() => (editMetadata.current = true)}
|
||||||
>
|
>
|
||||||
<Info size="16" class="mr-1" />
|
<Info size="16" />
|
||||||
{i18n._('menu.metadata.button')}
|
{i18n._('menu.metadata.button')}
|
||||||
<Shortcut key="I" ctrl={true} />
|
<Shortcut key="I" ctrl={true} />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
@@ -224,7 +224,7 @@
|
|||||||
)}
|
)}
|
||||||
onclick={() => (editStyle.current = true)}
|
onclick={() => (editStyle.current = true)}
|
||||||
>
|
>
|
||||||
<PaintBucket size="16" class="mr-1" />
|
<PaintBucket size="16" />
|
||||||
{i18n._('menu.style.button')}
|
{i18n._('menu.style.button')}
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
<Menubar.Item
|
<Menubar.Item
|
||||||
@@ -238,10 +238,10 @@
|
|||||||
disabled={$selection.size == 0}
|
disabled={$selection.size == 0}
|
||||||
>
|
>
|
||||||
<!-- {#if $allHidden}
|
<!-- {#if $allHidden}
|
||||||
<Eye size="16" class="mr-1" />
|
<Eye size="16" />
|
||||||
{i18n._('menu.unhide')}
|
{i18n._('menu.unhide')}
|
||||||
{:else}
|
{:else}
|
||||||
<EyeOff size="16" class="mr-1" />
|
<EyeOff size="16" />
|
||||||
{i18n._('menu.hide')}
|
{i18n._('menu.hide')}
|
||||||
{/if} -->
|
{/if} -->
|
||||||
<Shortcut key="H" ctrl={true} />
|
<Shortcut key="H" ctrl={true} />
|
||||||
@@ -256,7 +256,7 @@
|
|||||||
)}
|
)}
|
||||||
disabled={$selection.size !== 1}
|
disabled={$selection.size !== 1}
|
||||||
>
|
>
|
||||||
<Plus size="16" class="mr-1" />
|
<Plus size="16" />
|
||||||
{i18n._('menu.new_track')}
|
{i18n._('menu.new_track')}
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
{:else if $selection
|
{:else if $selection
|
||||||
@@ -273,7 +273,7 @@
|
|||||||
}}
|
}}
|
||||||
disabled={$selection.size !== 1}
|
disabled={$selection.size !== 1}
|
||||||
>
|
>
|
||||||
<Plus size="16" class="mr-1" />
|
<Plus size="16" />
|
||||||
{i18n._('menu.new_segment')}
|
{i18n._('menu.new_segment')}
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -283,7 +283,7 @@
|
|||||||
onclick={selection.selectAll}
|
onclick={selection.selectAll}
|
||||||
disabled={fileStateCollection.size == 0}
|
disabled={fileStateCollection.size == 0}
|
||||||
>
|
>
|
||||||
<FileStack size="16" class="mr-1" />
|
<FileStack size="16" />
|
||||||
{i18n._('menu.select_all')}
|
{i18n._('menu.select_all')}
|
||||||
<Shortcut key="A" ctrl={true} />
|
<Shortcut key="A" ctrl={true} />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
@@ -294,7 +294,7 @@
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Maximize size="16" class="mr-1" />
|
<Maximize size="16" />
|
||||||
{i18n._('menu.center')}
|
{i18n._('menu.center')}
|
||||||
<Shortcut key="⏎" ctrl={true} />
|
<Shortcut key="⏎" ctrl={true} />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
@@ -304,7 +304,7 @@
|
|||||||
onclick={selection.copySelection}
|
onclick={selection.copySelection}
|
||||||
disabled={$selection.size === 0}
|
disabled={$selection.size === 0}
|
||||||
>
|
>
|
||||||
<ClipboardCopy size="16" class="mr-1" />
|
<ClipboardCopy size="16" />
|
||||||
{i18n._('menu.copy')}
|
{i18n._('menu.copy')}
|
||||||
<Shortcut key="C" ctrl={true} />
|
<Shortcut key="C" ctrl={true} />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
@@ -312,7 +312,7 @@
|
|||||||
onclick={selection.cutSelection}
|
onclick={selection.cutSelection}
|
||||||
disabled={$selection.size === 0}
|
disabled={$selection.size === 0}
|
||||||
>
|
>
|
||||||
<Scissors size="16" class="mr-1" />
|
<Scissors size="16" />
|
||||||
{i18n._('menu.cut')}
|
{i18n._('menu.cut')}
|
||||||
<Shortcut key="X" ctrl={true} />
|
<Shortcut key="X" ctrl={true} />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
@@ -325,7 +325,7 @@
|
|||||||
))}
|
))}
|
||||||
onclick={pasteSelection}
|
onclick={pasteSelection}
|
||||||
>
|
>
|
||||||
<ClipboardPaste size="16" class="mr-1" />
|
<ClipboardPaste size="16" />
|
||||||
{i18n._('menu.paste')}
|
{i18n._('menu.paste')}
|
||||||
<Shortcut key="V" ctrl={true} />
|
<Shortcut key="V" ctrl={true} />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
@@ -335,7 +335,7 @@
|
|||||||
onclick={fileActions.deleteSelection}
|
onclick={fileActions.deleteSelection}
|
||||||
disabled={$selection.size == 0}
|
disabled={$selection.size == 0}
|
||||||
>
|
>
|
||||||
<Trash2 size="16" class="mr-1" />
|
<Trash2 size="16" />
|
||||||
{i18n._('menu.delete')}
|
{i18n._('menu.delete')}
|
||||||
<Shortcut key="⌫" ctrl={true} />
|
<Shortcut key="⌫" ctrl={true} />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
@@ -348,42 +348,36 @@
|
|||||||
</Menubar.Trigger>
|
</Menubar.Trigger>
|
||||||
<Menubar.Content class="border-none">
|
<Menubar.Content class="border-none">
|
||||||
<Menubar.CheckboxItem bind:checked={$elevationProfile}>
|
<Menubar.CheckboxItem bind:checked={$elevationProfile}>
|
||||||
<ChartArea size="16" class="mr-1" />
|
<ChartArea size="16" />
|
||||||
{i18n._('menu.elevation_profile')}
|
{i18n._('menu.elevation_profile')}
|
||||||
<Shortcut key="P" ctrl={true} />
|
<Shortcut key="P" ctrl={true} />
|
||||||
</Menubar.CheckboxItem>
|
</Menubar.CheckboxItem>
|
||||||
<Menubar.CheckboxItem bind:checked={$treeFileView}>
|
<Menubar.CheckboxItem bind:checked={$treeFileView}>
|
||||||
<ListTree size="16" class="mr-1" />
|
<ListTree size="16" />
|
||||||
{i18n._('menu.tree_file_view')}
|
{i18n._('menu.tree_file_view')}
|
||||||
<Shortcut key="L" ctrl={true} />
|
<Shortcut key="L" ctrl={true} />
|
||||||
</Menubar.CheckboxItem>
|
</Menubar.CheckboxItem>
|
||||||
<Menubar.Separator />
|
<Menubar.Separator />
|
||||||
<Menubar.Item inset onclick={switchBasemaps}>
|
<Menubar.Item inset onclick={switchBasemaps}>
|
||||||
<Map size="16" class="mr-1" />{i18n._('menu.switch_basemap')}<Shortcut
|
<Map size="16" />{i18n._('menu.switch_basemap')}<Shortcut key="F1" />
|
||||||
key="F1"
|
|
||||||
/>
|
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
<Menubar.Item inset onclick={toggleOverlays}>
|
<Menubar.Item inset onclick={toggleOverlays}>
|
||||||
<Layers2 size="16" class="mr-1" />{i18n._('menu.toggle_overlays')}<Shortcut
|
<Layers2 size="16" />{i18n._('menu.toggle_overlays')}<Shortcut key="F2" />
|
||||||
key="F2"
|
|
||||||
/>
|
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
<Menubar.Separator />
|
<Menubar.Separator />
|
||||||
<Menubar.CheckboxItem bind:checked={$distanceMarkers}>
|
<Menubar.CheckboxItem bind:checked={$distanceMarkers}>
|
||||||
<Coins size="16" class="mr-1" />{i18n._('menu.distance_markers')}<Shortcut
|
<Coins size="16" />{i18n._('menu.distance_markers')}<Shortcut key="F3" />
|
||||||
key="F3"
|
|
||||||
/>
|
|
||||||
</Menubar.CheckboxItem>
|
</Menubar.CheckboxItem>
|
||||||
<Menubar.CheckboxItem bind:checked={$directionMarkers}>
|
<Menubar.CheckboxItem bind:checked={$directionMarkers}>
|
||||||
<Milestone size="16" class="mr-1" />{i18n._(
|
<Milestone size="16" />{i18n._('menu.direction_markers')}<Shortcut
|
||||||
'menu.direction_markers'
|
key="F4"
|
||||||
)}<Shortcut key="F4" />
|
/>
|
||||||
</Menubar.CheckboxItem>
|
</Menubar.CheckboxItem>
|
||||||
<Menubar.Separator />
|
<Menubar.Separator />
|
||||||
<Menubar.Item inset onclick={map.toggle3D}>
|
<Menubar.Item inset onclick={map.toggle3D}>
|
||||||
<Box size="16" class="mr-1" />
|
<Box size="16" />
|
||||||
{i18n._('menu.toggle_3d')}
|
{i18n._('menu.toggle_3d')}
|
||||||
<Shortcut key="{i18n._('menu.ctrl')}+{i18n._('menu.drag')}" />
|
<Shortcut key="{i18n._('menu.ctrl')} {i18n._('menu.drag')}" />
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
</Menubar.Content>
|
</Menubar.Content>
|
||||||
</Menubar.Menu>
|
</Menubar.Menu>
|
||||||
@@ -397,7 +391,7 @@
|
|||||||
<Menubar.Content class="border-none">
|
<Menubar.Content class="border-none">
|
||||||
<Menubar.Sub>
|
<Menubar.Sub>
|
||||||
<Menubar.SubTrigger>
|
<Menubar.SubTrigger>
|
||||||
<Ruler size="16" class="mr-1" />{i18n._('menu.distance_units')}
|
<Ruler size="16" class="mr-2" />{i18n._('menu.distance_units')}
|
||||||
</Menubar.SubTrigger>
|
</Menubar.SubTrigger>
|
||||||
<Menubar.SubContent>
|
<Menubar.SubContent>
|
||||||
<Menubar.RadioGroup bind:value={$distanceUnits}>
|
<Menubar.RadioGroup bind:value={$distanceUnits}>
|
||||||
@@ -415,7 +409,7 @@
|
|||||||
</Menubar.Sub>
|
</Menubar.Sub>
|
||||||
<Menubar.Sub>
|
<Menubar.Sub>
|
||||||
<Menubar.SubTrigger>
|
<Menubar.SubTrigger>
|
||||||
<Zap size="16" class="mr-1" />{i18n._('menu.velocity_units')}
|
<Zap size="16" class="mr-2" />{i18n._('menu.velocity_units')}
|
||||||
</Menubar.SubTrigger>
|
</Menubar.SubTrigger>
|
||||||
<Menubar.SubContent>
|
<Menubar.SubContent>
|
||||||
<Menubar.RadioGroup bind:value={$velocityUnits}>
|
<Menubar.RadioGroup bind:value={$velocityUnits}>
|
||||||
@@ -430,7 +424,7 @@
|
|||||||
</Menubar.Sub>
|
</Menubar.Sub>
|
||||||
<Menubar.Sub>
|
<Menubar.Sub>
|
||||||
<Menubar.SubTrigger>
|
<Menubar.SubTrigger>
|
||||||
<Thermometer size="16" class="mr-1" />{i18n._('menu.temperature_units')}
|
<Thermometer size="16" class="mr-2" />{i18n._('menu.temperature_units')}
|
||||||
</Menubar.SubTrigger>
|
</Menubar.SubTrigger>
|
||||||
<Menubar.SubContent>
|
<Menubar.SubContent>
|
||||||
<Menubar.RadioGroup bind:value={$temperatureUnits}>
|
<Menubar.RadioGroup bind:value={$temperatureUnits}>
|
||||||
@@ -446,7 +440,7 @@
|
|||||||
<Menubar.Separator />
|
<Menubar.Separator />
|
||||||
<Menubar.Sub>
|
<Menubar.Sub>
|
||||||
<Menubar.SubTrigger>
|
<Menubar.SubTrigger>
|
||||||
<Languages size="16" class="mr-1" />
|
<Languages size="16" class="mr-2" />
|
||||||
{i18n._('menu.language')}
|
{i18n._('menu.language')}
|
||||||
</Menubar.SubTrigger>
|
</Menubar.SubTrigger>
|
||||||
<Menubar.SubContent>
|
<Menubar.SubContent>
|
||||||
@@ -462,9 +456,9 @@
|
|||||||
<Menubar.Sub>
|
<Menubar.Sub>
|
||||||
<Menubar.SubTrigger>
|
<Menubar.SubTrigger>
|
||||||
{#if mode.current === 'light' || !mode.current}
|
{#if mode.current === 'light' || !mode.current}
|
||||||
<Sun size="16" class="mr-1" />
|
<Sun size="16" class="mr-2" />
|
||||||
{:else}
|
{:else}
|
||||||
<Moon size="16" class="mr-1" />
|
<Moon size="16" class="mr-2" />
|
||||||
{/if}
|
{/if}
|
||||||
{i18n._('menu.mode')}
|
{i18n._('menu.mode')}
|
||||||
</Menubar.SubTrigger>
|
</Menubar.SubTrigger>
|
||||||
@@ -487,7 +481,7 @@
|
|||||||
<Menubar.Separator />
|
<Menubar.Separator />
|
||||||
<Menubar.Sub>
|
<Menubar.Sub>
|
||||||
<Menubar.SubTrigger>
|
<Menubar.SubTrigger>
|
||||||
<PersonStanding size="16" class="mr-1" />
|
<PersonStanding size="16" class="mr-2" />
|
||||||
{i18n._('menu.street_view_source')}
|
{i18n._('menu.street_view_source')}
|
||||||
</Menubar.SubTrigger>
|
</Menubar.SubTrigger>
|
||||||
<Menubar.SubContent>
|
<Menubar.SubContent>
|
||||||
@@ -502,7 +496,7 @@
|
|||||||
</Menubar.SubContent>
|
</Menubar.SubContent>
|
||||||
</Menubar.Sub>
|
</Menubar.Sub>
|
||||||
<Menubar.Item onclick={() => (layerSettingsOpen = true)}>
|
<Menubar.Item onclick={() => (layerSettingsOpen = true)}>
|
||||||
<Layers size="16" class="mr-1" />
|
<Layers size="16" />
|
||||||
{i18n._('menu.layers')}
|
{i18n._('menu.layers')}
|
||||||
</Menubar.Item>
|
</Menubar.Item>
|
||||||
</Menubar.Content>
|
</Menubar.Content>
|
||||||
|
|||||||
@@ -2,14 +2,24 @@
|
|||||||
import { isMac, isSafari } from '$lib/utils';
|
import { isMac, isSafari } from '$lib/utils';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
import { i18n } from '$lib/i18n.svelte';
|
import { i18n } from '$lib/i18n.svelte';
|
||||||
|
import * as Kbd from '$lib/components/ui/kbd/index.js';
|
||||||
|
|
||||||
export let key: string | undefined = undefined;
|
let {
|
||||||
export let shift: boolean = false;
|
key = undefined,
|
||||||
export let ctrl: boolean = false;
|
shift = false,
|
||||||
export let click: boolean = false;
|
ctrl = false,
|
||||||
|
click = false,
|
||||||
|
class: className = '',
|
||||||
|
}: {
|
||||||
|
key?: string;
|
||||||
|
shift?: boolean;
|
||||||
|
ctrl?: boolean;
|
||||||
|
click?: boolean;
|
||||||
|
class?: string;
|
||||||
|
} = $props();
|
||||||
|
|
||||||
let mac = false;
|
let mac = $state(false);
|
||||||
let safari = false;
|
let safari = $state(false);
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
mac = isMac();
|
mac = isMac();
|
||||||
@@ -17,20 +27,17 @@
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<Kbd.Root class="ml-auto {className}">
|
||||||
class="ml-auto pl-2 text-xs tracking-widest text-muted-foreground flex flex-row gap-0 items-baseline"
|
|
||||||
{...$$props}
|
|
||||||
>
|
|
||||||
{#if shift}
|
{#if shift}
|
||||||
<span>⇧</span>
|
⇧
|
||||||
{/if}
|
{/if}
|
||||||
{#if ctrl}
|
{#if ctrl}
|
||||||
<span>{mac && !safari ? '⌘' : i18n._('menu.ctrl') + '+'}</span>
|
{mac && !safari ? '⌘' : i18n._('menu.ctrl')}
|
||||||
{/if}
|
{/if}
|
||||||
{#if key}
|
{#if key}
|
||||||
<span class={key === '+' ? 'font-medium text-sm/4' : ''}>{key}</span>
|
{key}
|
||||||
{/if}
|
{/if}
|
||||||
{#if click}
|
{#if click}
|
||||||
<span>{i18n._('menu.click')}</span>
|
{i18n._('menu.click')}
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</Kbd.Root>
|
||||||
|
|||||||
@@ -1,19 +1,31 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import * as Tooltip from '$lib/components/ui/tooltip/index.js';
|
import * as Tooltip from '$lib/components/ui/tooltip/index.js';
|
||||||
|
import type { Snippet } from 'svelte';
|
||||||
|
|
||||||
export let label: string;
|
let {
|
||||||
export let side: 'top' | 'right' | 'bottom' | 'left' = 'top';
|
label,
|
||||||
|
side = 'top',
|
||||||
|
children,
|
||||||
|
extra,
|
||||||
|
class: className = '',
|
||||||
|
}: {
|
||||||
|
label: string;
|
||||||
|
side?: 'top' | 'right' | 'bottom' | 'left';
|
||||||
|
children: Snippet;
|
||||||
|
extra?: Snippet;
|
||||||
|
class?: string;
|
||||||
|
} = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Tooltip.Provider>
|
<Tooltip.Provider>
|
||||||
<Tooltip.Root>
|
<Tooltip.Root>
|
||||||
<Tooltip.Trigger {...$$restProps} aria-label={label}>
|
<Tooltip.Trigger class={className} aria-label={label}>
|
||||||
<slot />
|
{@render children()}
|
||||||
</Tooltip.Trigger>
|
</Tooltip.Trigger>
|
||||||
<Tooltip.Content {side}>
|
<Tooltip.Content {side}>
|
||||||
<div class="flex flex-row items-center">
|
<div class="flex flex-row items-center gap-2">
|
||||||
<span>{label}</span>
|
<span>{label}</span>
|
||||||
<slot name="extra" />
|
{@render extra?.()}
|
||||||
</div>
|
</div>
|
||||||
</Tooltip.Content>
|
</Tooltip.Content>
|
||||||
</Tooltip.Root>
|
</Tooltip.Root>
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
variant="ghost"
|
variant="ghost"
|
||||||
class="w-full flex flex-row {side === 'right'
|
class="w-full flex flex-row {side === 'right'
|
||||||
? 'justify-between'
|
? 'justify-between'
|
||||||
: 'justify-start'} py-0 px-1 h-fit {nohover
|
: 'justify-start'} p-0 has-[>svg]:px-0 h-fit {nohover
|
||||||
? 'hover:bg-background'
|
? 'hover:bg-background'
|
||||||
: ''} pointer-events-none"
|
: ''} pointer-events-none"
|
||||||
>
|
>
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
variant="ghost"
|
variant="ghost"
|
||||||
class="w-full flex flex-row {side === 'right'
|
class="w-full flex flex-row {side === 'right'
|
||||||
? 'justify-between'
|
? 'justify-between'
|
||||||
: 'justify-start'} py-0 px-1 h-fit {nohover ? 'hover:bg-background' : ''}"
|
: 'justify-start'} p-0 has-[>svg]:px-0 h-fit {nohover ? 'hover:bg-background' : ''}"
|
||||||
>
|
>
|
||||||
{#if side === 'left'}
|
{#if side === 'left'}
|
||||||
<Collapsible.Trigger>
|
<Collapsible.Trigger>
|
||||||
@@ -86,7 +86,7 @@
|
|||||||
</Button>
|
</Button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<Collapsible.Content class="ml-2">
|
<Collapsible.Content>
|
||||||
{@render props.content()}
|
{@render props.content()}
|
||||||
</Collapsible.Content>
|
</Collapsible.Content>
|
||||||
</Collapsible.Root>
|
</Collapsible.Root>
|
||||||
|
|||||||
@@ -312,10 +312,20 @@
|
|||||||
<div class="flex flex-row items-center gap-2" data-id={id}>
|
<div class="flex flex-row items-center gap-2" data-id={id}>
|
||||||
<Move size="12" />
|
<Move size="12" />
|
||||||
<span class="grow">{$customLayers[id].name}</span>
|
<span class="grow">{$customLayers[id].name}</span>
|
||||||
<Button variant="outline" onclick={() => (selectedLayerId = id)} class="p-1 h-7">
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon-sm"
|
||||||
|
onclick={() => (selectedLayerId = id)}
|
||||||
|
class="p-1 h-7"
|
||||||
|
>
|
||||||
<Pencil size="16" />
|
<Pencil size="16" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="outline" onclick={() => deleteLayer(id)} class="p-1 h-7">
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon-sm"
|
||||||
|
onclick={() => deleteLayer(id)}
|
||||||
|
class="p-1 h-7"
|
||||||
|
>
|
||||||
<Trash2 size="16" />
|
<Trash2 size="16" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@@ -338,17 +348,26 @@
|
|||||||
<div class="flex flex-row items-center gap-2" data-id={id}>
|
<div class="flex flex-row items-center gap-2" data-id={id}>
|
||||||
<Move size="12" />
|
<Move size="12" />
|
||||||
<span class="grow">{$customLayers[id].name}</span>
|
<span class="grow">{$customLayers[id].name}</span>
|
||||||
<Button variant="outline" onclick={() => (selectedLayerId = id)} class="p-1 h-7">
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon-sm"
|
||||||
|
onclick={() => (selectedLayerId = id)}
|
||||||
|
class="p-1 h-7"
|
||||||
|
>
|
||||||
<Pencil size="16" />
|
<Pencil size="16" />
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="outline" onclick={() => deleteLayer(id)} class="p-1 h-7">
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="icon-sm"
|
||||||
|
onclick={() => deleteLayer(id)}
|
||||||
|
class="p-1 h-7"
|
||||||
|
>
|
||||||
<Trash2 size="16" />
|
<Trash2 size="16" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
{/each}
|
{/each}
|
||||||
</div>
|
</div>
|
||||||
|
<Card.Root class="py-0 gap-0 shadow-none">
|
||||||
<Card.Root>
|
|
||||||
<Card.Header class="p-3">
|
<Card.Header class="p-3">
|
||||||
<Card.Title class="text-base">
|
<Card.Title class="text-base">
|
||||||
{#if selectedLayerId}
|
{#if selectedLayerId}
|
||||||
|
|||||||
@@ -179,9 +179,9 @@
|
|||||||
? 'grid-rows-[1fr] grid-cols-[1fr]'
|
? 'grid-rows-[1fr] grid-cols-[1fr]'
|
||||||
: ''} {cancelEvents ? 'pointer-events-none' : ''}"
|
: ''} {cancelEvents ? 'pointer-events-none' : ''}"
|
||||||
>
|
>
|
||||||
<ScrollArea>
|
<ScrollArea class="overflow-hidden">
|
||||||
<div class="h-fit">
|
<div class="h-fit">
|
||||||
<div class="p-2">
|
<div class="p-2 ml-1">
|
||||||
<LayerTree
|
<LayerTree
|
||||||
layerTree={$selectedBasemapTree}
|
layerTree={$selectedBasemapTree}
|
||||||
name="basemaps"
|
name="basemaps"
|
||||||
@@ -193,7 +193,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Separator class="w-full" />
|
<Separator class="w-full" />
|
||||||
<div class="p-2">
|
<div class="p-2 ml-1">
|
||||||
{#if $currentOverlays}
|
{#if $currentOverlays}
|
||||||
<LayerTree
|
<LayerTree
|
||||||
layerTree={$selectedOverlayTree}
|
layerTree={$selectedOverlayTree}
|
||||||
@@ -204,7 +204,7 @@
|
|||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
<Separator class="w-full" />
|
<Separator class="w-full" />
|
||||||
<div class="p-2">
|
<div class="p-2 ml-1">
|
||||||
{#if $currentOverpassQueries}
|
{#if $currentOverpassQueries}
|
||||||
<LayerTree
|
<LayerTree
|
||||||
layerTree={$selectedOverpassTree}
|
layerTree={$selectedOverpassTree}
|
||||||
|
|||||||
@@ -90,7 +90,7 @@
|
|||||||
<Accordion.Item value="layer-selection" class="flex flex-col">
|
<Accordion.Item value="layer-selection" class="flex flex-col">
|
||||||
<Accordion.Trigger>{i18n._('layers.selection')}</Accordion.Trigger>
|
<Accordion.Trigger>{i18n._('layers.selection')}</Accordion.Trigger>
|
||||||
<Accordion.Content class="grow flex flex-col border rounded">
|
<Accordion.Content class="grow flex flex-col border rounded">
|
||||||
<div class="py-2 pl-1 pr-2">
|
<div class="py-2 pl-3 pr-2">
|
||||||
<LayerTree
|
<LayerTree
|
||||||
layerTree={basemapTree}
|
layerTree={basemapTree}
|
||||||
name="basemapSettings"
|
name="basemapSettings"
|
||||||
@@ -99,7 +99,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Separator />
|
<Separator />
|
||||||
<div class="py-2 pl-1 pr-2">
|
<div class="py-2 pl-3 pr-2">
|
||||||
<LayerTree
|
<LayerTree
|
||||||
layerTree={overlayTree}
|
layerTree={overlayTree}
|
||||||
name="overlaySettings"
|
name="overlaySettings"
|
||||||
@@ -108,7 +108,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Separator />
|
<Separator />
|
||||||
<div class="py-2 pl-1 pr-2">
|
<div class="py-2 pl-3 pr-2">
|
||||||
<LayerTree
|
<LayerTree
|
||||||
layerTree={overpassTree}
|
layerTree={overpassTree}
|
||||||
name="overpassSettings"
|
name="overpassSettings"
|
||||||
@@ -130,7 +130,7 @@
|
|||||||
type="single"
|
type="single"
|
||||||
onValueChange={setOpacityFromSelection}
|
onValueChange={setOpacityFromSelection}
|
||||||
>
|
>
|
||||||
<Select.Trigger class="h-8 mr-1">
|
<Select.Trigger class="h-8 mr-1 w-full">
|
||||||
{#if selectedOverlay}
|
{#if selectedOverlay}
|
||||||
{#if isSelected($selectedOverlayTree, selectedOverlay)}
|
{#if isSelected($selectedOverlayTree, selectedOverlay)}
|
||||||
{i18n._(`layers.label.${selectedOverlay}`)}
|
{i18n._(`layers.label.${selectedOverlay}`)}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
import { settings } from '$lib/logic/settings';
|
import { settings } from '$lib/logic/settings';
|
||||||
import { i18n } from '$lib/i18n.svelte';
|
import { i18n } from '$lib/i18n.svelte';
|
||||||
import { onMount } from 'svelte';
|
import { onMount } from 'svelte';
|
||||||
|
import ButtonWithTooltip from '$lib/components/ButtonWithTooltip.svelte';
|
||||||
|
|
||||||
const { streetViewSource } = settings;
|
const { streetViewSource } = settings;
|
||||||
|
|
||||||
@@ -47,15 +48,21 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<CustomControl class="w-[29px] h-[29px] shrink-0">
|
<CustomControl class="w-[29px] h-[29px] shrink-0">
|
||||||
<Tooltip class="w-full h-full" side="left" label={i18n._('menu.toggle_street_view')}>
|
<ButtonWithTooltip
|
||||||
<Toggle
|
variant="ghost"
|
||||||
bind:pressed={$streetViewEnabled}
|
class="w-full h-full"
|
||||||
class="w-full h-full rounded p-0"
|
side="left"
|
||||||
aria-label={i18n._('menu.toggle_street_view')}
|
label={i18n._('menu.toggle_street_view')}
|
||||||
>
|
onclick={() => {
|
||||||
<PersonStanding size="22" />
|
$streetViewEnabled = !$streetViewEnabled;
|
||||||
</Toggle>
|
}}
|
||||||
</Tooltip>
|
>
|
||||||
|
<PersonStanding
|
||||||
|
size="22"
|
||||||
|
class="size-5.5"
|
||||||
|
color={$streetViewEnabled ? '#33b5e5' : 'currentColor'}
|
||||||
|
/>
|
||||||
|
</ButtonWithTooltip>
|
||||||
</CustomControl>
|
</CustomControl>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -26,31 +26,31 @@
|
|||||||
''}"
|
''}"
|
||||||
>
|
>
|
||||||
<ToolbarItem itemTool={Tool.ROUTING} label={i18n._('toolbar.routing.tooltip')}>
|
<ToolbarItem itemTool={Tool.ROUTING} label={i18n._('toolbar.routing.tooltip')}>
|
||||||
<Pencil size="18" />
|
<Pencil size="18" class="size-4.5" />
|
||||||
</ToolbarItem>
|
</ToolbarItem>
|
||||||
<ToolbarItem itemTool={Tool.WAYPOINT} label={i18n._('toolbar.waypoint.tooltip')}>
|
<ToolbarItem itemTool={Tool.WAYPOINT} label={i18n._('toolbar.waypoint.tooltip')}>
|
||||||
<MapPin size="18" />
|
<MapPin size="18" class="size-4.5" />
|
||||||
</ToolbarItem>
|
</ToolbarItem>
|
||||||
<ToolbarItem itemTool={Tool.SCISSORS} label={i18n._('toolbar.scissors.tooltip')}>
|
<ToolbarItem itemTool={Tool.SCISSORS} label={i18n._('toolbar.scissors.tooltip')}>
|
||||||
<Scissors size="18" />
|
<Scissors size="18" class="size-4.5" />
|
||||||
</ToolbarItem>
|
</ToolbarItem>
|
||||||
<ToolbarItem itemTool={Tool.TIME} label={i18n._('toolbar.time.tooltip')}>
|
<ToolbarItem itemTool={Tool.TIME} label={i18n._('toolbar.time.tooltip')}>
|
||||||
<CalendarClock size="18" />
|
<CalendarClock size="18" class="size-4.5" />
|
||||||
</ToolbarItem>
|
</ToolbarItem>
|
||||||
<ToolbarItem itemTool={Tool.MERGE} label={i18n._('toolbar.merge.tooltip')}>
|
<ToolbarItem itemTool={Tool.MERGE} label={i18n._('toolbar.merge.tooltip')}>
|
||||||
<Group size="18" />
|
<Group size="18" class="size-4.5" />
|
||||||
</ToolbarItem>
|
</ToolbarItem>
|
||||||
<ToolbarItem itemTool={Tool.EXTRACT} label={i18n._('toolbar.extract.tooltip')}>
|
<ToolbarItem itemTool={Tool.EXTRACT} label={i18n._('toolbar.extract.tooltip')}>
|
||||||
<Ungroup size="18" />
|
<Ungroup size="18" class="size-4.5" />
|
||||||
</ToolbarItem>
|
</ToolbarItem>
|
||||||
<ToolbarItem itemTool={Tool.ELEVATION} label={i18n._('toolbar.elevation.button')}>
|
<ToolbarItem itemTool={Tool.ELEVATION} label={i18n._('toolbar.elevation.button')}>
|
||||||
<MountainSnow size="18" />
|
<MountainSnow size="18" class="size-4.5" />
|
||||||
</ToolbarItem>
|
</ToolbarItem>
|
||||||
<ToolbarItem itemTool={Tool.REDUCE} label={i18n._('toolbar.reduce.tooltip')}>
|
<ToolbarItem itemTool={Tool.REDUCE} label={i18n._('toolbar.reduce.tooltip')}>
|
||||||
<Funnel size="18" />
|
<Funnel size="18" class="size-4.5" />
|
||||||
</ToolbarItem>
|
</ToolbarItem>
|
||||||
<ToolbarItem itemTool={Tool.CLEAN} label={i18n._('toolbar.clean.tooltip')}>
|
<ToolbarItem itemTool={Tool.CLEAN} label={i18n._('toolbar.clean.tooltip')}>
|
||||||
<SquareDashedMousePointer size="18" />
|
<SquareDashedMousePointer size="18" class="size-4.5" />
|
||||||
</ToolbarItem>
|
</ToolbarItem>
|
||||||
</div>
|
</div>
|
||||||
<ToolbarItemMenu class={props.class ?? ''} />
|
<ToolbarItemMenu class={props.class ?? ''} />
|
||||||
|
|||||||
@@ -24,13 +24,13 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Tooltip.Provider>
|
<Tooltip.Provider>
|
||||||
<Tooltip.Root delayDuration={300}>
|
<Tooltip.Root>
|
||||||
<Tooltip.Trigger>
|
<Tooltip.Trigger>
|
||||||
{#snippet child({ props })}
|
{#snippet child({ props })}
|
||||||
<Button
|
<Button
|
||||||
{...props}
|
{...props}
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
class="h-[26px] px-1 py-1.5 {$currentTool === itemTool ? 'bg-accent' : ''}"
|
class="size-[24px] {$currentTool === itemTool ? 'bg-accent' : ''}"
|
||||||
onclick={toggleTool}
|
onclick={toggleTool}
|
||||||
aria-label={label}
|
aria-label={label}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -40,8 +40,8 @@
|
|||||||
{#if $currentTool !== null}
|
{#if $currentTool !== null}
|
||||||
<div class="translate-x-1 h-full animate-in animate-out {className}">
|
<div class="translate-x-1 h-full animate-in animate-out {className}">
|
||||||
<div class="rounded-md shadow-md pointer-events-auto">
|
<div class="rounded-md shadow-md pointer-events-auto">
|
||||||
<Card.Root class="rounded-md border-none">
|
<Card.Root class="rounded-md border-none py-2.5">
|
||||||
<Card.Content class="p-2.5">
|
<Card.Content class="px-2.5">
|
||||||
{#if $currentTool === Tool.ROUTING}
|
{#if $currentTool === Tool.ROUTING}
|
||||||
<Routing {popup} {popupElement} bind:minimized={$minimizeRoutingMenu} />
|
<Routing {popup} {popupElement} bind:minimized={$minimizeRoutingMenu} />
|
||||||
{:else if $currentTool === Tool.SCISSORS}
|
{:else if $currentTool === Tool.SCISSORS}
|
||||||
|
|||||||
@@ -95,22 +95,14 @@
|
|||||||
{:else if mergeType === MergeType.TRACES && !canMergeTraces}
|
{:else if mergeType === MergeType.TRACES && !canMergeTraces}
|
||||||
{i18n._('toolbar.merge.help_cannot_merge_traces')}
|
{i18n._('toolbar.merge.help_cannot_merge_traces')}
|
||||||
{i18n._('toolbar.merge.selection_tip').split('{KEYBOARD_SHORTCUT}')[0]}
|
{i18n._('toolbar.merge.selection_tip').split('{KEYBOARD_SHORTCUT}')[0]}
|
||||||
<Shortcut
|
<Shortcut ctrl={true} click={true} class="border" />
|
||||||
ctrl={true}
|
|
||||||
click={true}
|
|
||||||
class="inline-flex text-muted-foreground text-xs border rounded p-0.5 gap-0"
|
|
||||||
/>
|
|
||||||
{i18n._('toolbar.merge.selection_tip').split('{KEYBOARD_SHORTCUT}')[1]}
|
{i18n._('toolbar.merge.selection_tip').split('{KEYBOARD_SHORTCUT}')[1]}
|
||||||
{:else if mergeType === MergeType.CONTENTS && canMergeContents}
|
{:else if mergeType === MergeType.CONTENTS && canMergeContents}
|
||||||
{i18n._('toolbar.merge.help_merge_contents')}
|
{i18n._('toolbar.merge.help_merge_contents')}
|
||||||
{:else if mergeType === MergeType.CONTENTS && !canMergeContents}
|
{:else if mergeType === MergeType.CONTENTS && !canMergeContents}
|
||||||
{i18n._('toolbar.merge.help_cannot_merge_contents')}
|
{i18n._('toolbar.merge.help_cannot_merge_contents')}
|
||||||
{i18n._('toolbar.merge.selection_tip').split('{KEYBOARD_SHORTCUT}')[0]}
|
{i18n._('toolbar.merge.selection_tip').split('{KEYBOARD_SHORTCUT}')[0]}
|
||||||
<Shortcut
|
<Shortcut ctrl={true} click={true} class="border" />
|
||||||
ctrl={true}
|
|
||||||
click={true}
|
|
||||||
class="inline-flex text-muted-foreground text-xs border rounded p-0.5 gap-0"
|
|
||||||
/>
|
|
||||||
{i18n._('toolbar.merge.selection_tip').split('{KEYBOARD_SHORTCUT}')[1]}
|
{i18n._('toolbar.merge.selection_tip').split('{KEYBOARD_SHORTCUT}')[1]}
|
||||||
{/if}
|
{/if}
|
||||||
</Help>
|
</Help>
|
||||||
|
|||||||
@@ -110,7 +110,9 @@
|
|||||||
|
|
||||||
onDestroy(() => {
|
onDestroy(() => {
|
||||||
if ($map) {
|
if ($map) {
|
||||||
fileStateCollectionObserver.destroy();
|
if (fileStateCollectionObserver) {
|
||||||
|
fileStateCollectionObserver.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
mapCursor.notify(MapCursorState.TOOL_WITH_CROSSHAIR, false);
|
mapCursor.notify(MapCursorState.TOOL_WITH_CROSSHAIR, false);
|
||||||
$map.off('click', createFileWithPoint);
|
$map.off('click', createFileWithPoint);
|
||||||
@@ -120,14 +122,14 @@
|
|||||||
|
|
||||||
{#if minimizable && minimized}
|
{#if minimizable && minimized}
|
||||||
<div class="-m-1.5 -mb-2">
|
<div class="-m-1.5 -mb-2">
|
||||||
<Button variant="ghost" class="px-1 h-[26px]" onclick={() => (minimized = false)}>
|
<Button variant="ghost" size="icon-sm" class="size-6" onclick={() => (minimized = false)}>
|
||||||
<SquareArrowOutDownRight size="18" />
|
<SquareArrowOutDownRight size="18" class="size-4.5" />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="flex flex-col gap-3 w-full max-w-80 animate-in animate-out {className ?? ''}">
|
<div class="flex flex-col gap-3 w-full max-w-80 animate-in animate-out {className ?? ''}">
|
||||||
<div class="flex flex-col gap-3">
|
<div class="flex flex-col gap-3">
|
||||||
<Label class="flex flex-row justify-between items-center gap-2">
|
<Label class="justify-between">
|
||||||
<span class="flex flex-row items-center gap-1">
|
<span class="flex flex-row items-center gap-1">
|
||||||
{#if $routing}
|
{#if $routing}
|
||||||
<Route size="16" />
|
<Route size="16" />
|
||||||
@@ -137,13 +139,15 @@
|
|||||||
{i18n._('toolbar.routing.use_routing')}
|
{i18n._('toolbar.routing.use_routing')}
|
||||||
</span>
|
</span>
|
||||||
<Tooltip label={i18n._('toolbar.routing.use_routing_tooltip')}>
|
<Tooltip label={i18n._('toolbar.routing.use_routing_tooltip')}>
|
||||||
<Switch class="scale-90" bind:checked={$routing} />
|
<Switch bind:checked={$routing} />
|
||||||
<Shortcut slot="extra" key="F5" />
|
{#snippet extra()}
|
||||||
|
<Shortcut key="F5" />
|
||||||
|
{/snippet}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</Label>
|
</Label>
|
||||||
{#if $routing}
|
{#if $routing}
|
||||||
<div class="flex flex-col gap-3" in:slide>
|
<div class="flex flex-col gap-3" in:slide>
|
||||||
<Label class="flex flex-row justify-between items-center gap-2">
|
<Label class="justify-between">
|
||||||
<span class="shrink-0 flex flex-row items-center gap-1">
|
<span class="shrink-0 flex flex-row items-center gap-1">
|
||||||
{#if $routingProfile.includes('bike') || $routingProfile.includes('motorcycle')}
|
{#if $routingProfile.includes('bike') || $routingProfile.includes('motorcycle')}
|
||||||
<Bike size="16" />
|
<Bike size="16" />
|
||||||
@@ -171,12 +175,12 @@
|
|||||||
</Select.Content>
|
</Select.Content>
|
||||||
</Select.Root>
|
</Select.Root>
|
||||||
</Label>
|
</Label>
|
||||||
<Label class="flex flex-row justify-between items-center gap-2">
|
<Label class="justify-between">
|
||||||
<span class="flex flex-row gap-1">
|
<span class="flex flex-row gap-1">
|
||||||
<TriangleAlert size="16" />
|
<TriangleAlert size="16" />
|
||||||
{i18n._('toolbar.routing.allow_private')}
|
{i18n._('toolbar.routing.allow_private')}
|
||||||
</span>
|
</span>
|
||||||
<Switch class="scale-90" bind:checked={$privateRoads} />
|
<Switch bind:checked={$privateRoads} />
|
||||||
</Label>
|
</Label>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
@@ -185,7 +189,7 @@
|
|||||||
<ButtonWithTooltip
|
<ButtonWithTooltip
|
||||||
label={i18n._('toolbar.routing.reverse.tooltip')}
|
label={i18n._('toolbar.routing.reverse.tooltip')}
|
||||||
variant="outline"
|
variant="outline"
|
||||||
class="flex flex-row gap-1 text-xs px-2"
|
class="gap-1 text-xs"
|
||||||
disabled={!validSelection}
|
disabled={!validSelection}
|
||||||
onclick={fileActions.reverseSelection}
|
onclick={fileActions.reverseSelection}
|
||||||
>
|
>
|
||||||
@@ -194,7 +198,7 @@
|
|||||||
<ButtonWithTooltip
|
<ButtonWithTooltip
|
||||||
label={i18n._('toolbar.routing.route_back_to_start.tooltip')}
|
label={i18n._('toolbar.routing.route_back_to_start.tooltip')}
|
||||||
variant="outline"
|
variant="outline"
|
||||||
class="flex flex-row gap-1 text-xs px-2"
|
class="gap-1 text-xs"
|
||||||
disabled={!validSelection}
|
disabled={!validSelection}
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
const selected = selection.getOrderedSelection();
|
const selected = selection.getOrderedSelection();
|
||||||
@@ -230,7 +234,7 @@
|
|||||||
<ButtonWithTooltip
|
<ButtonWithTooltip
|
||||||
label={i18n._('toolbar.routing.round_trip.tooltip')}
|
label={i18n._('toolbar.routing.round_trip.tooltip')}
|
||||||
variant="outline"
|
variant="outline"
|
||||||
class="flex flex-row gap-1 text-xs px-2"
|
class="gap-1 text-xs"
|
||||||
disabled={!validSelection}
|
disabled={!validSelection}
|
||||||
onclick={fileActions.createRoundTripForSelection}
|
onclick={fileActions.createRoundTripForSelection}
|
||||||
>
|
>
|
||||||
@@ -247,7 +251,8 @@
|
|||||||
</Help>
|
</Help>
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
class="px-1 h-6"
|
size="icon-sm"
|
||||||
|
class="size-6"
|
||||||
onclick={() => {
|
onclick={() => {
|
||||||
if (minimizable) {
|
if (minimizable) {
|
||||||
minimized = true;
|
minimized = true;
|
||||||
|
|||||||
@@ -1,80 +1,82 @@
|
|||||||
<script lang="ts" module>
|
<script lang="ts" module>
|
||||||
import { cn, type WithElementRef } from '$lib/utils.js';
|
import { cn, type WithElementRef } from "$lib/utils.js";
|
||||||
import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements';
|
import type { HTMLAnchorAttributes, HTMLButtonAttributes } from "svelte/elements";
|
||||||
import { type VariantProps, tv } from 'tailwind-variants';
|
import { type VariantProps, tv } from "tailwind-variants";
|
||||||
|
|
||||||
export const buttonVariants = tv({
|
export const buttonVariants = tv({
|
||||||
base: "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex shrink-0 items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium outline-none transition-all focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
base: "focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive inline-flex shrink-0 items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium outline-none transition-all focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
|
||||||
variants: {
|
variants: {
|
||||||
variant: {
|
variant: {
|
||||||
default: 'bg-primary text-primary-foreground shadow-xs hover:bg-primary/90',
|
default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
|
||||||
destructive:
|
destructive:
|
||||||
'bg-destructive shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60 text-white',
|
"bg-destructive shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60 text-white",
|
||||||
outline:
|
outline:
|
||||||
'bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 border',
|
"bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50 border",
|
||||||
secondary: 'bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80',
|
secondary: "bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
|
||||||
ghost: 'hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50',
|
ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
|
||||||
link: 'text-primary underline-offset-4 hover:underline',
|
link: "text-primary underline-offset-4 hover:underline",
|
||||||
},
|
},
|
||||||
size: {
|
size: {
|
||||||
default: 'h-9 px-4 py-2 has-[>svg]:px-3',
|
default: "h-9 px-4 py-2 has-[>svg]:px-3",
|
||||||
sm: 'h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5',
|
sm: "h-8 gap-1.5 rounded-md px-3 has-[>svg]:px-2.5",
|
||||||
lg: 'h-10 rounded-md px-6 has-[>svg]:px-4',
|
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
|
||||||
icon: 'size-9',
|
icon: "size-9",
|
||||||
},
|
"icon-sm": "size-8",
|
||||||
},
|
"icon-lg": "size-10",
|
||||||
defaultVariants: {
|
},
|
||||||
variant: 'default',
|
},
|
||||||
size: 'default',
|
defaultVariants: {
|
||||||
},
|
variant: "default",
|
||||||
});
|
size: "default",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export type ButtonVariant = VariantProps<typeof buttonVariants>['variant'];
|
export type ButtonVariant = VariantProps<typeof buttonVariants>["variant"];
|
||||||
export type ButtonSize = VariantProps<typeof buttonVariants>['size'];
|
export type ButtonSize = VariantProps<typeof buttonVariants>["size"];
|
||||||
|
|
||||||
export type ButtonProps = WithElementRef<HTMLButtonAttributes> &
|
export type ButtonProps = WithElementRef<HTMLButtonAttributes> &
|
||||||
WithElementRef<HTMLAnchorAttributes> & {
|
WithElementRef<HTMLAnchorAttributes> & {
|
||||||
variant?: ButtonVariant;
|
variant?: ButtonVariant;
|
||||||
size?: ButtonSize;
|
size?: ButtonSize;
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
let {
|
let {
|
||||||
class: className,
|
class: className,
|
||||||
variant = 'default',
|
variant = "default",
|
||||||
size = 'default',
|
size = "default",
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
href = undefined,
|
href = undefined,
|
||||||
type = 'button',
|
type = "button",
|
||||||
disabled,
|
disabled,
|
||||||
children,
|
children,
|
||||||
...restProps
|
...restProps
|
||||||
}: ButtonProps = $props();
|
}: ButtonProps = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if href}
|
{#if href}
|
||||||
<a
|
<a
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="button"
|
data-slot="button"
|
||||||
class={cn(buttonVariants({ variant, size }), className)}
|
class={cn(buttonVariants({ variant, size }), className)}
|
||||||
href={disabled ? undefined : href}
|
href={disabled ? undefined : href}
|
||||||
aria-disabled={disabled}
|
aria-disabled={disabled}
|
||||||
role={disabled ? 'link' : undefined}
|
role={disabled ? "link" : undefined}
|
||||||
tabindex={disabled ? -1 : undefined}
|
tabindex={disabled ? -1 : undefined}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
</a>
|
</a>
|
||||||
{:else}
|
{:else}
|
||||||
<button
|
<button
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="button"
|
data-slot="button"
|
||||||
class={cn(buttonVariants({ variant, size }), className)}
|
class={cn(buttonVariants({ variant, size }), className)}
|
||||||
{type}
|
{type}
|
||||||
{disabled}
|
{disabled}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
</button>
|
</button>
|
||||||
{/if}
|
{/if}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
{#if showCloseButton}
|
{#if showCloseButton}
|
||||||
<DialogPrimitive.Close
|
<DialogPrimitive.Close
|
||||||
class="ring-offset-background focus:ring-ring rounded-xs focus:outline-hidden absolute right-4 top-4 opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 disabled:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0"
|
class="ring-offset-background focus:ring-ring rounded-xs focus:outline-hidden absolute end-4 top-4 opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 disabled:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0"
|
||||||
>
|
>
|
||||||
<XIcon />
|
<XIcon />
|
||||||
<span class="sr-only">Close</span>
|
<span class="sr-only">Close</span>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
data-slot="dropdown-menu-content"
|
data-slot="dropdown-menu-content"
|
||||||
{sideOffset}
|
{sideOffset}
|
||||||
class={cn(
|
class={cn(
|
||||||
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 max-h-(--radix-dropdown-menu-content-available-height) origin-(--radix-dropdown-menu-content-transform-origin) z-50 min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border p-1 shadow-md",
|
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 max-h-(--bits-dropdown-menu-content-available-height) origin-(--bits-dropdown-menu-content-transform-origin) z-50 min-w-[8rem] overflow-y-auto overflow-x-hidden rounded-md border p-1 shadow-md outline-none",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
bind:ref
|
bind:ref
|
||||||
data-slot="dropdown-menu-sub-content"
|
data-slot="dropdown-menu-sub-content"
|
||||||
class={cn(
|
class={cn(
|
||||||
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-(--radix-dropdown-menu-content-transform-origin) z-50 min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-lg",
|
"bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-(--bits-dropdown-menu-content-transform-origin) z-50 min-w-[8rem] overflow-hidden rounded-md border p-1 shadow-lg",
|
||||||
className
|
className
|
||||||
)}
|
)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
type,
|
type,
|
||||||
files = $bindable(),
|
files = $bindable(),
|
||||||
class: className,
|
class: className,
|
||||||
|
"data-slot": dataSlot = "input",
|
||||||
...restProps
|
...restProps
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
</script>
|
</script>
|
||||||
@@ -22,9 +23,9 @@
|
|||||||
{#if type === "file"}
|
{#if type === "file"}
|
||||||
<input
|
<input
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="input"
|
data-slot={dataSlot}
|
||||||
class={cn(
|
class={cn(
|
||||||
"selection:bg-primary dark:bg-input/30 selection:text-primary-foreground border-input ring-offset-background placeholder:text-muted-foreground shadow-xs flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 pt-1.5 text-sm font-medium outline-none transition-[color,box-shadow] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
"selection:bg-primary dark:bg-input/30 selection:text-primary-foreground border-input ring-offset-background placeholder:text-muted-foreground shadow-xs flex h-9 w-full min-w-0 rounded-md border bg-transparent px-3 pt-1.5 text-sm font-medium outline-none transition-[color,box-shadow] disabled:cursor-not-allowed disabled:opacity-50",
|
||||||
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
||||||
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
"aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
|
||||||
className
|
className
|
||||||
@@ -37,7 +38,7 @@
|
|||||||
{:else}
|
{:else}
|
||||||
<input
|
<input
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="input"
|
data-slot={dataSlot}
|
||||||
class={cn(
|
class={cn(
|
||||||
"border-input bg-background selection:bg-primary dark:bg-input/30 selection:text-primary-foreground ring-offset-background placeholder:text-muted-foreground shadow-xs flex h-9 w-full min-w-0 rounded-md border px-3 py-1 text-base outline-none transition-[color,box-shadow] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
"border-input bg-background selection:bg-primary dark:bg-input/30 selection:text-primary-foreground ring-offset-background placeholder:text-muted-foreground shadow-xs flex h-9 w-full min-w-0 rounded-md border px-3 py-1 text-base outline-none transition-[color,box-shadow] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
||||||
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
"focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
|
||||||
|
|||||||
10
website/src/lib/components/ui/kbd/index.ts
Normal file
10
website/src/lib/components/ui/kbd/index.ts
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import Root from "./kbd.svelte";
|
||||||
|
import Group from "./kbd-group.svelte";
|
||||||
|
|
||||||
|
export {
|
||||||
|
Root,
|
||||||
|
Group,
|
||||||
|
//
|
||||||
|
Root as Kbd,
|
||||||
|
Group as KbdGroup,
|
||||||
|
};
|
||||||
10
website/src/lib/components/ui/kbd/kbd-group.svelte
Normal file
10
website/src/lib/components/ui/kbd/kbd-group.svelte
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { cn } from "$lib/utils.js";
|
||||||
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
|
|
||||||
|
let { class: className, children, ...restProps }: HTMLAttributes<HTMLElement> = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<kbd data-slot="kbd-group" class={cn("inline-flex items-center gap-1", className)} {...restProps}>
|
||||||
|
{@render children?.()}
|
||||||
|
</kbd>
|
||||||
19
website/src/lib/components/ui/kbd/kbd.svelte
Normal file
19
website/src/lib/components/ui/kbd/kbd.svelte
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { cn } from "$lib/utils.js";
|
||||||
|
import type { HTMLAttributes } from "svelte/elements";
|
||||||
|
|
||||||
|
let { class: className, children, ...restProps }: HTMLAttributes<HTMLElement> = $props();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<kbd
|
||||||
|
data-slot="kbd"
|
||||||
|
class={cn(
|
||||||
|
"bg-muted text-muted-foreground pointer-events-none inline-flex h-5 w-fit min-w-5 select-none items-center justify-center gap-1 rounded-sm px-1 font-sans text-xs font-medium",
|
||||||
|
"[&_svg:not([class*='size-'])]:size-3",
|
||||||
|
"[[data-slot=tooltip-content]_&]:bg-background/20 [[data-slot=tooltip-content]_&]:text-background dark:[[data-slot=tooltip-content]_&]:bg-background/10",
|
||||||
|
className
|
||||||
|
)}
|
||||||
|
{...restProps}
|
||||||
|
>
|
||||||
|
{@render children?.()}
|
||||||
|
</kbd>
|
||||||
@@ -1,40 +1,40 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ScrollArea as ScrollAreaPrimitive } from 'bits-ui';
|
import { ScrollArea as ScrollAreaPrimitive } from "bits-ui";
|
||||||
import { Scrollbar } from './index.js';
|
import { Scrollbar } from "./index.js";
|
||||||
import { cn, type WithoutChild } from '$lib/utils.js';
|
import { cn, type WithoutChild } from "$lib/utils.js";
|
||||||
|
|
||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
class: className,
|
class: className,
|
||||||
orientation = 'vertical',
|
orientation = "vertical",
|
||||||
scrollbarXClasses = '',
|
scrollbarXClasses = "",
|
||||||
scrollbarYClasses = '',
|
scrollbarYClasses = "",
|
||||||
children,
|
children,
|
||||||
...restProps
|
...restProps
|
||||||
}: WithoutChild<ScrollAreaPrimitive.RootProps> & {
|
}: WithoutChild<ScrollAreaPrimitive.RootProps> & {
|
||||||
orientation?: 'vertical' | 'horizontal' | 'both' | undefined;
|
orientation?: "vertical" | "horizontal" | "both" | undefined;
|
||||||
scrollbarXClasses?: string | undefined;
|
scrollbarXClasses?: string | undefined;
|
||||||
scrollbarYClasses?: string | undefined;
|
scrollbarYClasses?: string | undefined;
|
||||||
} = $props();
|
} = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ScrollAreaPrimitive.Root
|
<ScrollAreaPrimitive.Root
|
||||||
bind:ref
|
bind:ref
|
||||||
data-slot="scroll-area"
|
data-slot="scroll-area"
|
||||||
class={cn('relative overflow-hidden', className)}
|
class={cn("relative", className)}
|
||||||
{...restProps}
|
{...restProps}
|
||||||
>
|
>
|
||||||
<ScrollAreaPrimitive.Viewport
|
<ScrollAreaPrimitive.Viewport
|
||||||
data-slot="scroll-area-viewport"
|
data-slot="scroll-area-viewport"
|
||||||
class="ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] focus-visible:outline-1 focus-visible:ring-4"
|
class="ring-ring/10 dark:ring-ring/20 dark:outline-ring/40 outline-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] focus-visible:outline-1 focus-visible:ring-4"
|
||||||
>
|
>
|
||||||
{@render children?.()}
|
{@render children?.()}
|
||||||
</ScrollAreaPrimitive.Viewport>
|
</ScrollAreaPrimitive.Viewport>
|
||||||
{#if orientation === 'vertical' || orientation === 'both'}
|
{#if orientation === "vertical" || orientation === "both"}
|
||||||
<Scrollbar orientation="vertical" class={scrollbarYClasses} />
|
<Scrollbar orientation="vertical" class={scrollbarYClasses} />
|
||||||
{/if}
|
{/if}
|
||||||
{#if orientation === 'horizontal' || orientation === 'both'}
|
{#if orientation === "horizontal" || orientation === "both"}
|
||||||
<Scrollbar orientation="horizontal" class={scrollbarXClasses} />
|
<Scrollbar orientation="horizontal" class={scrollbarXClasses} />
|
||||||
{/if}
|
{/if}
|
||||||
<ScrollAreaPrimitive.Corner />
|
<ScrollAreaPrimitive.Corner />
|
||||||
</ScrollAreaPrimitive.Root>
|
</ScrollAreaPrimitive.Root>
|
||||||
|
|||||||
@@ -5,13 +5,14 @@
|
|||||||
let {
|
let {
|
||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
class: className,
|
class: className,
|
||||||
|
"data-slot": dataSlot = "separator",
|
||||||
...restProps
|
...restProps
|
||||||
}: SeparatorPrimitive.RootProps = $props();
|
}: SeparatorPrimitive.RootProps = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<SeparatorPrimitive.Root
|
<SeparatorPrimitive.Root
|
||||||
bind:ref
|
bind:ref
|
||||||
data-slot="separator"
|
data-slot={dataSlot}
|
||||||
class={cn(
|
class={cn(
|
||||||
"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=vertical]:h-full data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-px",
|
"bg-border shrink-0 data-[orientation=horizontal]:h-px data-[orientation=vertical]:h-full data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-px",
|
||||||
className
|
className
|
||||||
|
|||||||
@@ -8,6 +8,6 @@
|
|||||||
<Sonner
|
<Sonner
|
||||||
theme={mode.current}
|
theme={mode.current}
|
||||||
class="toaster group"
|
class="toaster group"
|
||||||
style="--normal-bg: var(--popover); --normal-text: var(--popover-foreground); --normal-border: var(--border);"
|
style="--normal-bg: var(--color-popover); --normal-text: var(--color-popover-foreground); --normal-border: var(--color-border);"
|
||||||
{...restProps}
|
{...restProps}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -6,13 +6,14 @@
|
|||||||
ref = $bindable(null),
|
ref = $bindable(null),
|
||||||
value = $bindable(),
|
value = $bindable(),
|
||||||
class: className,
|
class: className,
|
||||||
|
"data-slot": dataSlot = "textarea",
|
||||||
...restProps
|
...restProps
|
||||||
}: WithoutChildren<WithElementRef<HTMLTextareaAttributes>> = $props();
|
}: WithoutChildren<WithElementRef<HTMLTextareaAttributes>> = $props();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<textarea
|
<textarea
|
||||||
bind:this={ref}
|
bind:this={ref}
|
||||||
data-slot="textarea"
|
data-slot={dataSlot}
|
||||||
class={cn(
|
class={cn(
|
||||||
"border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 field-sizing-content shadow-xs flex min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base outline-none transition-[color,box-shadow] focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
"border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 field-sizing-content shadow-xs flex min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base outline-none transition-[color,box-shadow] focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
||||||
className
|
className
|
||||||
|
|||||||
@@ -34,9 +34,9 @@
|
|||||||
class={cn(
|
class={cn(
|
||||||
"bg-primary z-50 size-2.5 rotate-45 rounded-[2px]",
|
"bg-primary z-50 size-2.5 rotate-45 rounded-[2px]",
|
||||||
"data-[side=top]:translate-x-1/2 data-[side=top]:translate-y-[calc(-50%_+_2px)]",
|
"data-[side=top]:translate-x-1/2 data-[side=top]:translate-y-[calc(-50%_+_2px)]",
|
||||||
"data-[side=bottom]:-translate-y-[calc(-50%_+_1px)] data-[side=bottom]:translate-x-1/2",
|
"data-[side=bottom]:-translate-x-1/2 data-[side=bottom]:-translate-y-[calc(-50%_+_1px)]",
|
||||||
"data-[side=right]:translate-x-[calc(50%_+_2px)] data-[side=right]:translate-y-1/2",
|
"data-[side=right]:translate-x-[calc(50%_+_2px)] data-[side=right]:translate-y-1/2",
|
||||||
"data-[side=left]:translate-y-[calc(50%_-_3px)]",
|
"data-[side=left]:-translate-y-[calc(50%_-_3px)]",
|
||||||
arrowClasses
|
arrowClasses
|
||||||
)}
|
)}
|
||||||
{...props}
|
{...props}
|
||||||
|
|||||||
Reference in New Issue
Block a user