diff --git a/package-lock.json b/package-lock.json
index 5db643453..f4e203871 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -546,6 +546,7 @@
"resolved": "https://registry.npmjs.org/@aws-sdk/client-dynamodb/-/client-dynamodb-3.1028.0.tgz",
"integrity": "sha512-OkO2p9Wm+6CccOfQcdYjvCAJdUfBSWbmrIKXGh/qbBjp0B8d1MsYl1Exps5OzRSzqLVuTUVjPJCkgSMJF/mPqg==",
"license": "Apache-2.0",
+ "peer": true,
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
@@ -1848,6 +1849,7 @@
"integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@babel/code-frame": "^7.29.0",
"@babel/generator": "^7.29.0",
@@ -2231,6 +2233,7 @@
}
],
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=20.19.0"
},
@@ -2279,6 +2282,7 @@
}
],
"license": "MIT",
+ "peer": true,
"engines": {
"node": ">=20.19.0"
}
@@ -2860,6 +2864,7 @@
"resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.7.3.tgz",
"integrity": "sha512-wxNqWbqokF551WrJ9BIFouU/V5SL1oYCGx1oudcirdhadnQRFH5v1sjgGL7cUV/UsekSycygphdrF2lxBxOYKg==",
"license": "Apache-2.0",
+ "peer": true,
"dependencies": {
"tslib": "^2.1.0"
}
@@ -4656,6 +4661,7 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz",
"integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==",
"license": "Apache-2.0",
+ "peer": true,
"engines": {
"node": ">=8.0.0"
}
@@ -4665,6 +4671,7 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.49.1.tgz",
"integrity": "sha512-kaNl/T7WzyMUQHQlVq7q0oV4Kev6+0xFwqzofryC66jgGMacd0QH5TwfpbUwSTby+SdAdprAe5UKMvBw4tKS5Q==",
"license": "Apache-2.0",
+ "peer": true,
"dependencies": {
"@opentelemetry/api": "^1.0.0"
},
@@ -5145,6 +5152,7 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.40.0.tgz",
"integrity": "sha512-8WRuvGnfnbeR9ifGjLN8kklk2fkd0gBT6aN7NHO9zeYF/6qacAViD3bwAKqGXKnJgl39l1EU41I9diqUjamEEQ==",
"license": "Apache-2.0",
+ "peer": true,
"dependencies": {
"@opentelemetry/api": "^1.0.0"
},
@@ -5287,6 +5295,7 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.40.0.tgz",
"integrity": "sha512-8WRuvGnfnbeR9ifGjLN8kklk2fkd0gBT6aN7NHO9zeYF/6qacAViD3bwAKqGXKnJgl39l1EU41I9diqUjamEEQ==",
"license": "Apache-2.0",
+ "peer": true,
"dependencies": {
"@opentelemetry/api": "^1.0.0"
},
@@ -5430,6 +5439,7 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.40.0.tgz",
"integrity": "sha512-8WRuvGnfnbeR9ifGjLN8kklk2fkd0gBT6aN7NHO9zeYF/6qacAViD3bwAKqGXKnJgl39l1EU41I9diqUjamEEQ==",
"license": "Apache-2.0",
+ "peer": true,
"dependencies": {
"@opentelemetry/api": "^1.0.0"
},
@@ -8873,6 +8883,7 @@
"integrity": "sha512-gGkiNMPqerb2cJSVcruigx9eHBlLG14fSdPdqMoOcBfh+vvn4iCq2C8MzUB89PrxOXk0y3GZ1yIWb9aOzL93bw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.58.1",
"@typescript-eslint/types": "8.58.1",
@@ -9625,6 +9636,7 @@
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
"license": "MIT",
+ "peer": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -10526,6 +10538,7 @@
}
],
"license": "MIT",
+ "peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.10.12",
"caniuse-lite": "^1.0.30001782",
@@ -10747,6 +10760,7 @@
"resolved": "https://registry.npmjs.org/chai/-/chai-4.5.0.tgz",
"integrity": "sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"assertion-error": "^1.1.0",
"check-error": "^1.0.3",
@@ -12610,6 +12624,7 @@
"resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz",
"integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@@ -13290,6 +13305,7 @@
"resolved": "https://registry.npmjs.org/fengari/-/fengari-0.1.5.tgz",
"integrity": "sha512-0DS4Nn4rV8qyFlQCpKK8brT61EUtswynrpfFTcgLErcilBIBskSMQ86fO2WVuybr14ywyKdRjv91FiRZwnEuvQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"readline-sync": "^1.4.10",
"sprintf-js": "^1.1.3",
@@ -15269,6 +15285,7 @@
"resolved": "https://registry.npmjs.org/ioredis/-/ioredis-5.10.1.tgz",
"integrity": "sha512-HuEDBTI70aYdx1v6U97SbNx9F1+svQKBDo30o0b9fw055LMepzpOOd0Ccg9Q6tbqmBSJaMuY0fB7yw9/vjBYCA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@ioredis/commands": "1.5.1",
"cluster-key-slot": "^1.1.0",
@@ -20921,6 +20938,7 @@
"integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
@@ -21568,6 +21586,7 @@
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.6.tgz",
"integrity": "sha512-DkkO/dz7MGln0dHn5bmN3pPy+JmywNICWrJqVWiVOyvXjWQFIv9c2h24JrQLLFJ2aQVQf/Cvl1vblnd4r2apLQ==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"debug": "~4.4.1",
"ws": "~8.18.3"
@@ -22938,6 +22957,7 @@
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"devOptional": true,
"license": "Apache-2.0",
+ "peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -23222,6 +23242,7 @@
"integrity": "sha512-dbU7/iLVa8KZALJyLOBOQ88nOXtNG8vxKuOT4I2mD+Ya70KPceF4IAmDsmU0h1Qsn5bPrvsY9HJstCRh3hG6Uw==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"lightningcss": "^1.32.0",
"picomatch": "^4.0.4",
@@ -23430,6 +23451,7 @@
"integrity": "sha512-tFuJqTxKb8AvfyqMfnavXdzfy3h3sWZRWwfluGbkeR7n0HUev+FmNgZ8SDrRBTVrVCjgH5cA21qGbCffMNtWvg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@vitest/expect": "4.1.4",
"@vitest/mocker": "4.1.4",
@@ -23565,6 +23587,7 @@
"integrity": "sha512-Pkx5joZ9RrdgO5LBkyX1L2ZAJeK/Taz3vqZ9CbcP0wS5LEMx5QkKsEwLl29QJfihZ+DKRBFldzy1O30pJ1MDpA==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@types/eslint-scope": "^3.7.7",
"@types/estree": "^1.0.8",
@@ -23614,6 +23637,7 @@
"integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==",
"dev": true,
"license": "MIT",
+ "peer": true,
"dependencies": {
"@discoveryjs/json-ext": "^0.5.0",
"@webpack-cli/configtest": "^2.1.1",
@@ -23991,6 +24015,7 @@
"resolved": "https://registry.npmjs.org/winston/-/winston-3.19.0.tgz",
"integrity": "sha512-LZNJgPzfKR+/J3cHkxcpHKpKKvGfDZVPS4hfJCc4cCG0CgYzvlD6yE/S3CIL/Yt91ak327YCpiF/0MyeZHEHKA==",
"license": "MIT",
+ "peer": true,
"dependencies": {
"@colors/colors": "^1.6.0",
"@dabh/diagnostics": "^2.0.8",
@@ -24503,6 +24528,7 @@
"resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz",
"integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==",
"license": "MIT",
+ "peer": true,
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
@@ -24637,6 +24663,7 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.8.0.tgz",
"integrity": "sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==",
"license": "Apache-2.0",
+ "peer": true,
"engines": {
"node": ">=8.0.0"
}
diff --git a/src/docs/src/sidebar.js b/src/docs/src/sidebar.js
index 202654d65..6f98d79b1 100755
--- a/src/docs/src/sidebar.js
+++ b/src/docs/src/sidebar.js
@@ -915,18 +915,18 @@ let sidebar = [
title: 'showSpinner()',
page_title: 'puter.ui.showSpinner()',
title_tag: 'puter.ui.showSpinner()',
- icon:'/assets/img/function.svg',
+ icon: '/assets/img/function.svg',
source: '/UI/showSpinner.md',
path: '/UI/showSpinner',
},
- {
+ {
title: 'hideSpinner()',
page_title: 'puter.ui.hideSpinner()',
title_tag: 'puter.ui.hideSpinner()',
- icon:'/assets/img/function.svg',
+ icon: '/assets/img/function.svg',
source: '/UI/hideSpinner.md',
path: '/UI/hideSpinner',
- },
+ },
{
title: 'showWindow()',
page_title: 'puter.ui.showWindow()',
diff --git a/src/gui/src/UI/Dashboard/ContextMenu/ContextMenu.js b/src/gui/src/UI/Dashboard/ContextMenu/ContextMenu.js
index 7f2ff167a..4e60d3996 100644
--- a/src/gui/src/UI/Dashboard/ContextMenu/ContextMenu.js
+++ b/src/gui/src/UI/Dashboard/ContextMenu/ContextMenu.js
@@ -35,8 +35,10 @@ export default class ContextMenuModal {
* Show the modal positioned over a specific element
* @param {Array} menuItems - Array of menu item objects or '-' for separator
* @param {DOMRect} targetRect - Bounding rectangle of the tapped item
+ * @param {Object} [options] - Optional settings
+ * @param {string} [options.title] - Title displayed at the top of the menu
*/
- show (menuItems, targetRect) {
+ show (menuItems, targetRect, options = {}) {
if ( this.backdrop ) return; // Already showing
this.menuItems = menuItems;
@@ -50,7 +52,15 @@ export default class ContextMenuModal {
this.modal.className = 'context-menu-modal-dialog';
// Build modal content
+ let titleHtml = '';
+ if ( options.title ) {
+ const titleEl = document.createElement('div');
+ titleEl.className = 'context-menu-title';
+ titleEl.textContent = options.title;
+ titleHtml = titleEl.outerHTML;
+ }
this.modal.innerHTML = `
+ ${titleHtml}