diff --git a/README.md b/README.md index 943ec881..22795a69 100644 --- a/README.md +++ b/README.md @@ -105,6 +105,23 @@ The navbar is hidden when the loaded URL is the logged-in user's WebID or its fragment-free profile document URL. Other URLs in the same pod and other users' profiles keep the navbar. Account-menu navigation continues to hide it. +### Friends list + +On your own editable profile, drop a friend's WebID anywhere in the social pane's +friends list, including its empty space or an existing friend card, to add a +`foaf:knows` link to your profile. The whole list is the drop target; there is no +separate target icon. Other people's lists and non-editable profiles remain +read-only. This uses solid-ui's existing attachment-list save and refresh handlers. +Navigation icons are rendered directly by solid-ui using the imported Lucide +`square-arrow-out-up-right` component in neutral gray and match the remove icons' +size and right alignment. +Remove-friend confirmations appear as compact popups centered over the list, +above its contents and outside the clipped cards, including when there is only +one friend. They do not change the list's layout. Cancel is focused when the +confirmation opens. +The pane passes solid-ui's optional `confirmationContainer` rather than relocating +the widget's popup after it opens. + ## Development To get started, make sure you have Node.js installed (for instance through [nvm](https://github.com/nvm-sh/nvm)), then: diff --git a/package-lock.json b/package-lock.json index e8cc22ac..96f7c693 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "solid-panes", - "version": "5.1.0-0", + "version": "5.1.0-1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "solid-panes", - "version": "5.1.0-0", + "version": "5.1.0-1", "license": "MIT", "dependencies": { "@solid/better-simple-slideshow": "^0.1.0", @@ -26,7 +26,7 @@ "rdflib": "2.4.1", "solid-logic": "6.0.1-1", "solid-namespace": "^0.5.4", - "solid-ui": "5.0.1", + "solid-ui": "5.0.2-0", "source-pane": "4.0.0" }, "devDependencies": { @@ -1957,9 +1957,9 @@ } }, "node_modules/@codemirror/autocomplete": { - "version": "6.20.3", - "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.20.3.tgz", - "integrity": "sha512-tlosUqb+3BbxCxZdu4tKeRghPFC+QM7q4X5YhKV2eCmPG+1r2F3f4AaSz5sCrFqUtX4Jh20VFTKecl16MgiV9g==", + "version": "6.20.4", + "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.20.4.tgz", + "integrity": "sha512-yF8RhOf2SXlg00+qtupzLhrglcas61boqaONiNcbPIebHCpJocpqTBA6dyrtUrQO47hqyTdeob/3XnYilT7TaQ==", "license": "MIT", "dependencies": { "@codemirror/language": "^6.0.0", @@ -2115,9 +2115,9 @@ "license": "MIT" }, "node_modules/@codemirror/view": { - "version": "6.43.14", - "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.43.14.tgz", - "integrity": "sha512-hC45YnmJNR1rz42OF57BLoQNFMV12/13drnvibDsR2quNDmldcb4WvYVV81hFQg56i9lcqQMEDqilhX2QDcGQQ==", + "version": "6.43.15", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.43.15.tgz", + "integrity": "sha512-HHsfpqFeHyXLs983pSRe38Xajs0vFWZQ2BuX0m7Ki8w3jZ5iD8cuR3lBz2/5/X53Dhf32SBHKh6rtSTB6tKeGw==", "license": "MIT", "dependencies": { "@codemirror/state": "^6.7.0", @@ -2337,9 +2337,9 @@ } }, "node_modules/@digitalbazaar/http-client/node_modules/undici": { - "version": "6.29.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-6.29.0.tgz", - "integrity": "sha512-R+RODBqp6i2pPflGdq+xIOUkl+RNfGgHwoinecKu/JCuf2uO06cOKoDbI2P7Dn6KcswdKwrczbU6IYJ6K8X+wg==", + "version": "6.29.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.29.1.tgz", + "integrity": "sha512-EvRlUt/QqAEvXdQeRMYUfwOQsfzpDztykrG2owGEE/rBOBoYv9uF39ZzsNDh4lTFHhTr2XOZjKkYgueD12ZmGA==", "license": "MIT", "engines": { "node": ">=18.17" @@ -2865,9 +2865,9 @@ } }, "node_modules/@lezer/markdown": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.8.0.tgz", - "integrity": "sha512-X6w3A2NpyhdtGqTWRJB8gR4QDXBaFMbTOs780ZdZ15KKCfBXOQTKcB3Vr+W6tqJHVlealt53tLmHRvOqPTQgYA==", + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.8.1.tgz", + "integrity": "sha512-M5YmEcKWO4mJ45Y1hECwqyu8cLv25EiXOK554PVOvDOWOP0olwelHHQUWr9sjF+d1bENVhy0nfJ8E57XZUTiXg==", "license": "MIT", "dependencies": { "@lezer/common": "^1.5.0", @@ -3619,17 +3619,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.71.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.71.2.tgz", - "integrity": "sha512-K72/pvT7qpm8q3k8G5u93NCSN1RcLxX5h7Gw0bQpbMXviBHeY6Nx1WEwmk9wP+eKTSQ8ecxvcgt/ZX/rB938xQ==", + "version": "8.72.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.72.0.tgz", + "integrity": "sha512-aysKgysPX9XOv/dk95UkvUDe++Q3n3dJPG9CEWT3RUccxfkPJ+Qn6nhKPDhZXU6Ofo9kgwGWwKyQCnZIXTgngg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.71.2", - "@typescript-eslint/type-utils": "8.71.2", - "@typescript-eslint/utils": "8.71.2", - "@typescript-eslint/visitor-keys": "8.71.2", + "@typescript-eslint/scope-manager": "8.72.0", + "@typescript-eslint/type-utils": "8.72.0", + "@typescript-eslint/utils": "8.72.0", + "@typescript-eslint/visitor-keys": "8.72.0", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -3642,15 +3642,15 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.71.2", + "@typescript-eslint/parser": "^8.72.0", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.12", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.12.tgz", - "integrity": "sha512-/8UvqAPU9DGTI9k4mxtf49U37Isfwr8Uts96+SBHIkFxPJnHS0Ew4f00sM4Scd8V8EjM0jUNtVDdv1kPdt35lg==", + "version": "7.0.13", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.13.tgz", + "integrity": "sha512-2E8Q6rh+1RRSq/YdaGsNfXsEZy9FVqv6BSSrkmZJP7BnaoPnRfKL+YaofPvP+5rzdk144qSm6i4+hvPgUcbV4Q==", "dev": true, "license": "MIT", "engines": { @@ -3658,15 +3658,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.71.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.71.2.tgz", - "integrity": "sha512-aTtmZjp/x3gsGHkDs04/1I8kNogBJkpQaeGaN0PfiG43NzDEmW2n+OP5im9wfsvyX0yP1UZWBrAGtDBfH9jEVw==", + "version": "8.72.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.72.0.tgz", + "integrity": "sha512-0O+x3ynciD6zuXb1CKSu165haQV6ey53DKhHHUnujP7U+XlltJG+/keT0Xhd1HXCze+IHf7Tvt39ovyepX/LNw==", "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.71.2", - "@typescript-eslint/types": "8.71.2", - "@typescript-eslint/typescript-estree": "8.71.2", - "@typescript-eslint/visitor-keys": "8.71.2", + "@typescript-eslint/scope-manager": "8.72.0", + "@typescript-eslint/types": "8.72.0", + "@typescript-eslint/typescript-estree": "8.72.0", + "@typescript-eslint/visitor-keys": "8.72.0", "debug": "^4.4.3" }, "engines": { @@ -3682,13 +3682,13 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.71.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.71.2.tgz", - "integrity": "sha512-Pd68GsLVh5ZXlcEccFPdhSOvtHZ/2WU0XsA8zmXOS3F158lVlcTLhfQ6qvtL1RzbMie0Kp8xtbVwAg4nejKPHw==", + "version": "8.72.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.72.0.tgz", + "integrity": "sha512-bzHngBbmIgzj6TsTjVUCntGx6FFLgE7mPjpO0PzHycOaZHXqS43XnrkFIHRS16LLr/xO6FHSXG3GJFo/F4bSBQ==", "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.71.2", - "@typescript-eslint/types": "^8.71.2", + "@typescript-eslint/tsconfig-utils": "^8.72.0", + "@typescript-eslint/types": "^8.72.0", "debug": "^4.4.3" }, "engines": { @@ -3703,13 +3703,13 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.71.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.71.2.tgz", - "integrity": "sha512-YF4wgg5iUX5Obywoac27B56FhozMNFhdJSbh11H5GBAwmBtfyRhmgTQqW9tRNNmHDvsZ2CX6UGzoz+YfYn2Leg==", + "version": "8.72.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.72.0.tgz", + "integrity": "sha512-JewPyJOYcXBSAS7PIgufscHOwZqhTGyBRiQJhhuDln66tMchxvvt7nJ90JKKIoOelmdHA3kAQbm9cEUHc4JSEA==", "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.71.2", - "@typescript-eslint/visitor-keys": "8.71.2" + "@typescript-eslint/types": "8.72.0", + "@typescript-eslint/visitor-keys": "8.72.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3720,9 +3720,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.71.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.71.2.tgz", - "integrity": "sha512-jz49TAWokm/7yWD9/o837nYax9DyALxIPOImdImvVzo6canBCZYzin8zJyqNR5k1j9K1DE0bVvr0XYB+99uAdg==", + "version": "8.72.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.72.0.tgz", + "integrity": "sha512-0vbxCf7xLVPSjcOdm6eQbgViH8EDJ8xnl1laLT9yoqSz2YmcSfSg5Vdl0JUvZf6rcuJ0ZivJIuMD4edTg8obaA==", "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3736,15 +3736,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.71.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.71.2.tgz", - "integrity": "sha512-cC8UaalCViJkb3rH/xLIvidEwoFRtMZMUqDjjJMGEKaTFwYRHYBcoczlEGHuvkHEO8svRDrgZ0yQgOArFmwang==", + "version": "8.72.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.72.0.tgz", + "integrity": "sha512-gEXxmmbSTSOVTC37IYYvremOM31v+UN2W772bJxmVYPhAOPSUxtacyb7wkm1EhkYKU6KzFJsdU44DCV4to0LWw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.71.2", - "@typescript-eslint/typescript-estree": "8.71.2", - "@typescript-eslint/utils": "8.71.2", + "@typescript-eslint/types": "8.72.0", + "@typescript-eslint/typescript-estree": "8.72.0", + "@typescript-eslint/utils": "8.72.0", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -3761,9 +3761,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.71.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.71.2.tgz", - "integrity": "sha512-y5Ukl3oVp7e/VGxqIoEXoeb/Roj71PAJ4WG/N/RGj+eeDvKRLM15kGr9MijLbN0i03S52zxu31Z98E5gWChJKw==", + "version": "8.72.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.72.0.tgz", + "integrity": "sha512-Adfoy59kxNEjT5E5fnyrp7GpHYuWs8ONbdohu4ez6IU46qDq8LltG90tLmkucZB2uhYL8mqBjtXqGd8yhfjXqQ==", "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3774,15 +3774,15 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.71.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.71.2.tgz", - "integrity": "sha512-DgNOEsl4pdYzwSL+N/Cl33tX1Hlw3FvId73LnKXfq7jnrF2viOEn7X+P7RBkkSWCVm92gnWd28GIC5vJuLREeA==", + "version": "8.72.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.72.0.tgz", + "integrity": "sha512-gwLfFgWcw15tN2KXDCJvxEOQjPn+P3j/n3eSqkZ5sX4VpW9Cosodr+tWwBZRvJT3TcKx6HnPRGZMCNAiP1Xhug==", "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.71.2", - "@typescript-eslint/tsconfig-utils": "8.71.2", - "@typescript-eslint/types": "8.71.2", - "@typescript-eslint/visitor-keys": "8.71.2", + "@typescript-eslint/project-service": "8.72.0", + "@typescript-eslint/tsconfig-utils": "8.72.0", + "@typescript-eslint/types": "8.72.0", + "@typescript-eslint/visitor-keys": "8.72.0", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -3801,16 +3801,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.71.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.71.2.tgz", - "integrity": "sha512-RyKa1G1M9rKHDhrk+HJtiF1MvLD5Ux2JW3TSkzw+02pRALdpJb+QzG1Y5em+LvCgzGwgg8H7mBRFKljNz7ImPw==", + "version": "8.72.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.72.0.tgz", + "integrity": "sha512-0up3oArJZBYnzOaEXKo8DmI43QvMZyPoFEt9LWzRJcyl/RcJjfKKPebknN1VbTgXBf3M/KggUh5uUMdURLnseg==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.71.2", - "@typescript-eslint/types": "8.71.2", - "@typescript-eslint/typescript-estree": "8.71.2" + "@typescript-eslint/scope-manager": "8.72.0", + "@typescript-eslint/types": "8.72.0", + "@typescript-eslint/typescript-estree": "8.72.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3825,12 +3825,12 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.71.2", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.71.2.tgz", - "integrity": "sha512-zozlN0UA32bSG2zkKAgQyRYSbEISVoyU6vvkKYo2aSny74D8Jh4e+POkJ6Lk0dlezZi5x7TtD+88Xb06IB8nhg==", + "version": "8.72.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.72.0.tgz", + "integrity": "sha512-E2mroviasaWecDzTGiGMtuEguuLVOeRggnrIn93CJuxYJzQBHbyymlT08aVQydbBal5538o+JkBKXh2sRuCyIA==", "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.71.2", + "@typescript-eslint/types": "8.72.0", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -3884,14 +3884,14 @@ } }, "node_modules/@vitest/coverage-v8": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.11.tgz", - "integrity": "sha512-8MVGEFnJIcdGjcbfKmeq8z0pZHH0JlVtoVZH9Q/qwUp6wyFnEJUBMrw9DCaj+ra3vShGmhavjalMIhPNxZAUcw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-4.1.12.tgz", + "integrity": "sha512-6S7/iVknKglLAxMFxQGNppBI0iqJS2NgM6FBxavitj7KaDq/vywOWGf6dGu7F2L1Qy0G6S3uTp7aGshHrzK8JA==", "devOptional": true, "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^1.0.2", - "@vitest/utils": "4.1.11", + "@vitest/utils": "4.1.12", "ast-v8-to-istanbul": "^1.0.0", "istanbul-lib-coverage": "^3.2.2", "istanbul-lib-report": "^3.0.1", @@ -3905,8 +3905,8 @@ "url": "https://opencollective.com/vitest" }, "peerDependencies": { - "@vitest/browser": "4.1.11", - "vitest": "4.1.11" + "@vitest/browser": "4.1.12", + "vitest": "4.1.12" }, "peerDependenciesMeta": { "@vitest/browser": { @@ -3915,15 +3915,15 @@ } }, "node_modules/@vitest/expect": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.11.tgz", - "integrity": "sha512-VX2x5vNJXET47KAFzwERI+KRMtTTCSWTfSMKsW7JsUsXV4psq++e3DvZpuTDOpHcxytiDs6p2nhVb2tVDiiUYw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.12.tgz", + "integrity": "sha512-vFlTt+YEu9WBpNjdGayNmlMVzrWPi1+sv853/7t2FU7hpO5gAFBKHzQmkCq5Xjpr+evegF2994LQT3hF3mRlqQ==", "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.1.0", "@types/chai": "^5.2.2", - "@vitest/spy": "4.1.11", - "@vitest/utils": "4.1.11", + "@vitest/spy": "4.1.12", + "@vitest/utils": "4.1.12", "chai": "^6.2.2", "tinyrainbow": "^3.1.0" }, @@ -3932,12 +3932,12 @@ } }, "node_modules/@vitest/mocker": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.11.tgz", - "integrity": "sha512-2XJVD55d1o5AZous5CCGKS74g/riOj9odEt2bQpCVZeblHyHdnMeFl4jl0XjU21stf4mbjUkew2eXQZt65g5CQ==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.12.tgz", + "integrity": "sha512-fKShNpKZzupWZuY0z7egydvL0sqW4INEZBEExMBMAa6izlENEVHwoXgdaTCaBZ5fwlr4xf2o1wXC83n9RpO+NA==", "license": "MIT", "dependencies": { - "@vitest/spy": "4.1.11", + "@vitest/spy": "4.1.12", "estree-walker": "^3.0.3", "magic-string": "^0.30.21" }, @@ -3958,9 +3958,9 @@ } }, "node_modules/@vitest/pretty-format": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.11.tgz", - "integrity": "sha512-yiZzPbGTS9Sr/JpFl8zHrcIkAofNbFV6k21vIgQN/cY/oxZeXhJv5sc/MBJ5jFKWmWs+oJHw0UXLZjmf931+Vw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.12.tgz", + "integrity": "sha512-XW9O8+Mxx4VpCtkYdMJLZQQwsVryP9wk7cPKDxtXFfwSak6yRh5+2fep/Y0XF/ElBvJHq8bcYdi6aeuai0opZA==", "license": "MIT", "dependencies": { "tinyrainbow": "^3.1.0" @@ -3970,12 +3970,12 @@ } }, "node_modules/@vitest/runner": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.11.tgz", - "integrity": "sha512-LztvUgdwMNJMIkj3hQnnxiC2Xy1zNxq928W/xhjCLaNCzqTZOudjwbQf6v9IntZGPw132i2Lq2rgTRZHD3JHNw==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.12.tgz", + "integrity": "sha512-NKlVKCr5QnCe8jijdMnmkpHHU+WTqiLFR6G0pHji9uRjXK9xJl1k1nTw6F3pOOj2PDcsDt2GKQMI7wIsaT491w==", "license": "MIT", "dependencies": { - "@vitest/utils": "4.1.11", + "@vitest/utils": "4.1.12", "pathe": "^2.0.3" }, "funding": { @@ -3983,13 +3983,13 @@ } }, "node_modules/@vitest/snapshot": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.11.tgz", - "integrity": "sha512-pN7ikn1ON7h8ee4gIAp4AzyK+zBtJPzVbqOgu5LCEh4VaJVbPQcgYQYJIMGQPXVeJJq1fnfazis7a5pFNPahog==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.12.tgz", + "integrity": "sha512-ko1y1Qgb/slzQ9mr+b89Cuqud8WG1TKtsPD8r7ZUBdvVOGt85Af2HwCqHujrhwJq95hs/9RM7fcAPg57o1vlzw==", "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.11", - "@vitest/utils": "4.1.11", + "@vitest/pretty-format": "4.1.12", + "@vitest/utils": "4.1.12", "magic-string": "^0.30.21", "pathe": "^2.0.3" }, @@ -3998,21 +3998,21 @@ } }, "node_modules/@vitest/spy": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.11.tgz", - "integrity": "sha512-apNa/prQy2qCeywhnixOHPRCgGNhvg7T4Dapfl1GahLp/R+uhBm5cPyFoNVyqsNd2h1nJxL6BqqdIjiABL60YA==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.12.tgz", + "integrity": "sha512-RGq9x4JNGNTZHEJxvN0oSiJjeSCExm0n2gZKKJZHY9cX5AVA6M7VJILBT3ZJ/tJ/0J9uWT7fETV9/btoi//vSg==", "license": "MIT", "funding": { "url": "https://opencollective.com/vitest" } }, "node_modules/@vitest/utils": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.11.tgz", - "integrity": "sha512-zTCVGpyFsGWBhllOyKlTw/vnr6D9qxsfSDyfbyZmTyjHw5N/VuvzHpHoQjm2ZJzn4RJgx5w4r7V0er69CmLgPQ==", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.12.tgz", + "integrity": "sha512-Q3awXrwOfEV+qc3WmO5ONyE0yO7Q1gQ9/oyHxGLZ/pl7N3NO/ZztqQwKLuwMkV+CA1JYSIeO3gkHnRDIo4AVaA==", "license": "MIT", "dependencies": { - "@vitest/pretty-format": "4.1.11", + "@vitest/pretty-format": "4.1.12", "convert-source-map": "^2.0.0", "tinyrainbow": "^3.1.0" }, @@ -4139,6 +4139,42 @@ "node": ">=18" } }, + "node_modules/activitystreams-pane/node_modules/solid-ui": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-5.0.1.tgz", + "integrity": "sha512-kqHYMoMN+FMSu1+1TaPqOfeuoZErS6EicFJh8erxWdRz5aNbLAGQfVlB7HaafcUvnHKDiWFtlZETfD7YqmRy8Q==", + "license": "MIT", + "dependencies": { + "@awesome.me/webawesome": "^3.9.0", + "@codemirror/commands": "^6.10.0", + "@codemirror/lang-css": "^6.3.1", + "@codemirror/lang-html": "^6.4.11", + "@codemirror/lang-javascript": "^6.2.5", + "@codemirror/lang-json": "^6.0.2", + "@codemirror/lang-markdown": "^6.3.1", + "@codemirror/lang-xml": "^6.1.0", + "@codemirror/language": "^6.12.3", + "@codemirror/legacy-modes": "^6.5.3", + "@codemirror/state": "^6.6.0", + "@codemirror/view": "^6.43.0", + "@lit/context": "^1.1.6", + "@lit/task": "^1.0.3", + "@noble/curves": "^2.2.0", + "@noble/hashes": "^2.2.0", + "@uiw/codemirror-theme-vscode": "^4.25.10", + "escape-html": "^1.0.3", + "lit": "^3.3.3", + "mime-types": "^3.0.2", + "pane-registry": "5.0.1", + "rdflib": "2.4.1", + "solid-logic": "6.0.0", + "solid-namespace": "^0.5.4", + "uuid": "^14.0.0" + }, + "optionalDependencies": { + "fsevents": "*" + } + }, "node_modules/agent-base": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", @@ -4487,9 +4523,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { - "version": "2.11.28", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.28.tgz", - "integrity": "sha512-br0LOmjJqr6Rt4AEkadbcNf67Zpo7EPwKsWbjnRrJIa1QYFHQBqM4C7F2WTbV8ahTEcg1Eo+Y0aWjjORInYFyA==", + "version": "2.11.30", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.30.tgz", + "integrity": "sha512-YJs6Pz17RMNv8HoyKREtCY38E3BV1nPkWVmIb+XN1uHC1Vqt3KZCH/uJH9ZKRoiKb/icZ6tvehyee6RZNbFfRA==", "dev": true, "license": "Apache-2.0", "bin": { @@ -4534,9 +4570,9 @@ } }, "node_modules/browserslist": { - "version": "4.29.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.3.tgz", - "integrity": "sha512-1R4kiYKXGViqEN0CnoDrXc1StD9niAwu+j2dukWzrD4bJgsD4lDmEp0CRbc6E/vYJIfTHwPmwyaKtVSudICdPA==", + "version": "4.29.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.29.4.tgz", + "integrity": "sha512-2TcbbiwXEq+N0kD36tykpCfyyQigUXmuwNQbnPp4Xk4PX9JOqVIKjJlIDjpH7uY6tmRGoAd+apeT1p60T8wsdA==", "dev": true, "funding": [ { @@ -4554,11 +4590,11 @@ ], "license": "MIT", "dependencies": { - "baseline-browser-mapping": "^2.11.26", - "caniuse-lite": "^1.0.30001813", - "electron-to-chromium": "^1.5.439", - "node-releases": "^2.0.57", - "update-browserslist-db": "^1.3.3" + "baseline-browser-mapping": "^2.11.29", + "caniuse-lite": "^1.0.30001816", + "electron-to-chromium": "^1.5.459", + "node-releases": "^2.0.59", + "update-browserslist-db": "^1.3.4" }, "bin": { "browserslist": "cli.js" @@ -4657,9 +4693,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001816", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001816.tgz", - "integrity": "sha512-+8Yx7BXCoqk6IF8yTicjfUR6D/ldJzdlsodlEOiOSPmhK844WIgk67/zIQaGAOxNkZyyvBlrRFnLvqKIoqbAFw==", + "version": "1.0.30001817", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001817.tgz", + "integrity": "sha512-uZ1JG80BwhtMalIAGPxPfmNhHyd/B/nTdr3hITWlRamSyAdUStP1Gop01e7SD5q6J90ixJvWDbvmiFVfDgn4bw==", "dev": true, "funding": [ { @@ -4752,6 +4788,42 @@ "node": ">=18" } }, + "node_modules/chat-pane/node_modules/solid-ui": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-5.0.1.tgz", + "integrity": "sha512-kqHYMoMN+FMSu1+1TaPqOfeuoZErS6EicFJh8erxWdRz5aNbLAGQfVlB7HaafcUvnHKDiWFtlZETfD7YqmRy8Q==", + "license": "MIT", + "dependencies": { + "@awesome.me/webawesome": "^3.9.0", + "@codemirror/commands": "^6.10.0", + "@codemirror/lang-css": "^6.3.1", + "@codemirror/lang-html": "^6.4.11", + "@codemirror/lang-javascript": "^6.2.5", + "@codemirror/lang-json": "^6.0.2", + "@codemirror/lang-markdown": "^6.3.1", + "@codemirror/lang-xml": "^6.1.0", + "@codemirror/language": "^6.12.3", + "@codemirror/legacy-modes": "^6.5.3", + "@codemirror/state": "^6.6.0", + "@codemirror/view": "^6.43.0", + "@lit/context": "^1.1.6", + "@lit/task": "^1.0.3", + "@noble/curves": "^2.2.0", + "@noble/hashes": "^2.2.0", + "@uiw/codemirror-theme-vscode": "^4.25.10", + "escape-html": "^1.0.3", + "lit": "^3.3.3", + "mime-types": "^3.0.2", + "pane-registry": "5.0.1", + "rdflib": "2.4.1", + "solid-logic": "6.0.0", + "solid-namespace": "^0.5.4", + "uuid": "^14.0.0" + }, + "optionalDependencies": { + "fsevents": "*" + } + }, "node_modules/ci-info": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", @@ -4864,6 +4936,42 @@ "node": ">=18" } }, + "node_modules/contacts-pane/node_modules/solid-ui": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-5.0.1.tgz", + "integrity": "sha512-kqHYMoMN+FMSu1+1TaPqOfeuoZErS6EicFJh8erxWdRz5aNbLAGQfVlB7HaafcUvnHKDiWFtlZETfD7YqmRy8Q==", + "license": "MIT", + "dependencies": { + "@awesome.me/webawesome": "^3.9.0", + "@codemirror/commands": "^6.10.0", + "@codemirror/lang-css": "^6.3.1", + "@codemirror/lang-html": "^6.4.11", + "@codemirror/lang-javascript": "^6.2.5", + "@codemirror/lang-json": "^6.0.2", + "@codemirror/lang-markdown": "^6.3.1", + "@codemirror/lang-xml": "^6.1.0", + "@codemirror/language": "^6.12.3", + "@codemirror/legacy-modes": "^6.5.3", + "@codemirror/state": "^6.6.0", + "@codemirror/view": "^6.43.0", + "@lit/context": "^1.1.6", + "@lit/task": "^1.0.3", + "@noble/curves": "^2.2.0", + "@noble/hashes": "^2.2.0", + "@uiw/codemirror-theme-vscode": "^4.25.10", + "escape-html": "^1.0.3", + "lit": "^3.3.3", + "mime-types": "^3.0.2", + "pane-registry": "5.0.1", + "rdflib": "2.4.1", + "solid-logic": "6.0.0", + "solid-namespace": "^0.5.4", + "uuid": "^14.0.0" + }, + "optionalDependencies": { + "fsevents": "*" + } + }, "node_modules/convert-source-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", @@ -4871,13 +4979,13 @@ "license": "MIT" }, "node_modules/core-js-compat": { - "version": "3.50.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.50.0.tgz", - "integrity": "sha512-XGpFGbMLHwSt74YLTKho7Ib242qi6O8MSX+sRokV4oz7iKXvQWGYZthjIhjRGMxjzVkAubBO512dKGYcefmX3Q==", + "version": "3.51.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.51.0.tgz", + "integrity": "sha512-52r6fkXgxv4GLMjmFcMWRx7X9bw071xTTdrDcdyPGRqU2oE+9pCG0bAOMifSBdLw0JRBZKEF0q3B55qPlLuE8g==", "dev": true, "license": "MIT", "dependencies": { - "browserslist": "^4.28.7" + "browserslist": "^4.29.3" }, "engines": { "node": ">=6.4.0" @@ -5198,9 +5306,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.456", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.456.tgz", - "integrity": "sha512-8hboqI6xesozteFb8aa7OGknvxUtTeRJLz0FoePysUEh/oWbddykIGdgpEJRbPRg/nIMfBf2DFos+H2MtvJl2A==", + "version": "1.5.462", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.462.tgz", + "integrity": "sha512-9qpCBlXPy5v7n1Q7WTO5rW2StI4WNQhl96HpgXRZLPlNoXAD0LbsQUflovQYAO44Yia073ISusqohncvGSMbGA==", "dev": true, "license": "ISC" }, @@ -6019,6 +6127,16 @@ "vitest-axe": "^0.1.0" } }, + "node_modules/folder-pane/node_modules/pane-registry": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pane-registry/-/pane-registry-5.0.1.tgz", + "integrity": "sha512-3aeLxm6TnRHfIDoEbpZpNe3Tlm7wWT+ipEpiV6h3cRgxyzmEtrUpS9WB8yJa/VJq0RHXEoaYlLu94fcbuOPnbA==", + "license": "MIT", + "dependencies": { + "rdflib": "2.4.1", + "solid-logic": "6.0.0" + } + }, "node_modules/folder-pane/node_modules/solid-logic": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-6.0.0.tgz", @@ -6034,6 +6152,42 @@ "node": ">=18" } }, + "node_modules/folder-pane/node_modules/solid-ui": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-5.0.1.tgz", + "integrity": "sha512-kqHYMoMN+FMSu1+1TaPqOfeuoZErS6EicFJh8erxWdRz5aNbLAGQfVlB7HaafcUvnHKDiWFtlZETfD7YqmRy8Q==", + "license": "MIT", + "dependencies": { + "@awesome.me/webawesome": "^3.9.0", + "@codemirror/commands": "^6.10.0", + "@codemirror/lang-css": "^6.3.1", + "@codemirror/lang-html": "^6.4.11", + "@codemirror/lang-javascript": "^6.2.5", + "@codemirror/lang-json": "^6.0.2", + "@codemirror/lang-markdown": "^6.3.1", + "@codemirror/lang-xml": "^6.1.0", + "@codemirror/language": "^6.12.3", + "@codemirror/legacy-modes": "^6.5.3", + "@codemirror/state": "^6.6.0", + "@codemirror/view": "^6.43.0", + "@lit/context": "^1.1.6", + "@lit/task": "^1.0.3", + "@noble/curves": "^2.2.0", + "@noble/hashes": "^2.2.0", + "@uiw/codemirror-theme-vscode": "^4.25.10", + "escape-html": "^1.0.3", + "lit": "^3.3.3", + "mime-types": "^3.0.2", + "pane-registry": "5.0.1", + "rdflib": "2.4.1", + "solid-logic": "6.0.0", + "solid-namespace": "^0.5.4", + "uuid": "^14.0.0" + }, + "optionalDependencies": { + "fsevents": "*" + } + }, "node_modules/for-each": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", @@ -7034,6 +7188,16 @@ "node": ">=20.19.2" } }, + "node_modules/issue-pane/node_modules/pane-registry": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pane-registry/-/pane-registry-5.0.1.tgz", + "integrity": "sha512-3aeLxm6TnRHfIDoEbpZpNe3Tlm7wWT+ipEpiV6h3cRgxyzmEtrUpS9WB8yJa/VJq0RHXEoaYlLu94fcbuOPnbA==", + "license": "MIT", + "dependencies": { + "rdflib": "2.4.1", + "solid-logic": "6.0.0" + } + }, "node_modules/issue-pane/node_modules/solid-logic": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-6.0.0.tgz", @@ -7049,6 +7213,42 @@ "node": ">=18" } }, + "node_modules/issue-pane/node_modules/solid-ui": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-5.0.1.tgz", + "integrity": "sha512-kqHYMoMN+FMSu1+1TaPqOfeuoZErS6EicFJh8erxWdRz5aNbLAGQfVlB7HaafcUvnHKDiWFtlZETfD7YqmRy8Q==", + "license": "MIT", + "dependencies": { + "@awesome.me/webawesome": "^3.9.0", + "@codemirror/commands": "^6.10.0", + "@codemirror/lang-css": "^6.3.1", + "@codemirror/lang-html": "^6.4.11", + "@codemirror/lang-javascript": "^6.2.5", + "@codemirror/lang-json": "^6.0.2", + "@codemirror/lang-markdown": "^6.3.1", + "@codemirror/lang-xml": "^6.1.0", + "@codemirror/language": "^6.12.3", + "@codemirror/legacy-modes": "^6.5.3", + "@codemirror/state": "^6.6.0", + "@codemirror/view": "^6.43.0", + "@lit/context": "^1.1.6", + "@lit/task": "^1.0.3", + "@noble/curves": "^2.2.0", + "@noble/hashes": "^2.2.0", + "@uiw/codemirror-theme-vscode": "^4.25.10", + "escape-html": "^1.0.3", + "lit": "^3.3.3", + "mime-types": "^3.0.2", + "pane-registry": "5.0.1", + "rdflib": "2.4.1", + "solid-logic": "6.0.0", + "solid-namespace": "^0.5.4", + "uuid": "^14.0.0" + }, + "optionalDependencies": { + "fsevents": "*" + } + }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", @@ -7900,9 +8100,9 @@ } }, "node_modules/lucide": { - "version": "1.57.0", - "resolved": "https://registry.npmjs.org/lucide/-/lucide-1.57.0.tgz", - "integrity": "sha512-M2BHuzBxnD+5AiJzEXwWxswwz0MXoQPQcehoIJAgi0Lqe0i4/kksKaHx2R+UWRAbQhjTvucCDG6sBg/TqIwa8Q==", + "version": "1.60.0", + "resolved": "https://registry.npmjs.org/lucide/-/lucide-1.60.0.tgz", + "integrity": "sha512-nS9qchK+W+c58GZk8LRR/9X2t+AuC/qs4CeXQauA3l/sqkrl0wzZDjcwLPHSdvoE1HYwnqDZUIs/lYAdWx1a8Q==", "license": "ISC" }, "node_modules/lz-string": { @@ -7992,6 +8192,16 @@ "solid-ui": "5.0.1" } }, + "node_modules/meeting-pane/node_modules/pane-registry": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pane-registry/-/pane-registry-5.0.1.tgz", + "integrity": "sha512-3aeLxm6TnRHfIDoEbpZpNe3Tlm7wWT+ipEpiV6h3cRgxyzmEtrUpS9WB8yJa/VJq0RHXEoaYlLu94fcbuOPnbA==", + "license": "MIT", + "dependencies": { + "rdflib": "2.4.1", + "solid-logic": "6.0.0" + } + }, "node_modules/meeting-pane/node_modules/solid-logic": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-6.0.0.tgz", @@ -8007,6 +8217,42 @@ "node": ">=18" } }, + "node_modules/meeting-pane/node_modules/solid-ui": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-5.0.1.tgz", + "integrity": "sha512-kqHYMoMN+FMSu1+1TaPqOfeuoZErS6EicFJh8erxWdRz5aNbLAGQfVlB7HaafcUvnHKDiWFtlZETfD7YqmRy8Q==", + "license": "MIT", + "dependencies": { + "@awesome.me/webawesome": "^3.9.0", + "@codemirror/commands": "^6.10.0", + "@codemirror/lang-css": "^6.3.1", + "@codemirror/lang-html": "^6.4.11", + "@codemirror/lang-javascript": "^6.2.5", + "@codemirror/lang-json": "^6.0.2", + "@codemirror/lang-markdown": "^6.3.1", + "@codemirror/lang-xml": "^6.1.0", + "@codemirror/language": "^6.12.3", + "@codemirror/legacy-modes": "^6.5.3", + "@codemirror/state": "^6.6.0", + "@codemirror/view": "^6.43.0", + "@lit/context": "^1.1.6", + "@lit/task": "^1.0.3", + "@noble/curves": "^2.2.0", + "@noble/hashes": "^2.2.0", + "@uiw/codemirror-theme-vscode": "^4.25.10", + "escape-html": "^1.0.3", + "lit": "^3.3.3", + "mime-types": "^3.0.2", + "pane-registry": "5.0.1", + "rdflib": "2.4.1", + "solid-logic": "6.0.0", + "solid-namespace": "^0.5.4", + "uuid": "^14.0.0" + }, + "optionalDependencies": { + "fsevents": "*" + } + }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -8362,9 +8608,9 @@ } }, "node_modules/node-releases": { - "version": "2.0.58", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.58.tgz", - "integrity": "sha512-BdiKAgbfRlvfMq/XzO/AF9NPmaA8a+YpLAyAFTVFBj3gARrAIfWvNq7Q7NE4se3KgFu0KkrvQMxTS0XVnsGzHg==", + "version": "2.0.59", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.59.tgz", + "integrity": "sha512-5qr2okC4ItAI0hG5SaV0HoYMpnM/Y6+Oqr7AmPYy/2uEoGvS+GbSKLeRxSS1uAdu59yz0ouzcuXievSgg///WA==", "dev": true, "license": "MIT", "engines": { @@ -8741,14 +8987,14 @@ } }, "node_modules/pkg-types": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.3.tgz", - "integrity": "sha512-j/lCFdcppV0JxWpCEITdbDltBxPP6cHT+yNJ6Go2OgoSA9518X847X9z0p6LtA4Nc16+eQzCZjRrWanTGvHJ5w==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.4.0.tgz", + "integrity": "sha512-07Fys7iVx0X6TcviMOgogM1Lk33ZyqOezMnU79S+kffWqwolG/5W9V8EgQSeYCIfFTYVgssRbnH630Oa2+soBA==", "dev": true, "license": "MIT", "dependencies": { "confbox": "^0.3.1", - "exsolve": "^1.1.1", + "exsolve": "^1.1.3", "pathe": "^2.0.3" } }, @@ -8772,9 +9018,9 @@ } }, "node_modules/postcss": { - "version": "8.5.30", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.30.tgz", - "integrity": "sha512-zkd+e9S1AQHhmaBKye9zlFHWjOwVgqXl1q3ECYy8561K7qxR2cREf/STLskulBFd78k6AOFeA+ff1TtEzk9bAA==", + "version": "8.5.31", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.31.tgz", + "integrity": "sha512-YUbWYCgErwnMAVkjUnYa+KlMBzGpHwiIt/DE7f0G33AuX2LH9UcTk6KgWxd3zRU+pN3u/C+Xl3EnMLM4Hea7Sg==", "funding": [ { "type": "opencollective", @@ -8914,6 +9160,67 @@ "vitest-axe": "^0.1.0" } }, + "node_modules/profile-pane/node_modules/solid-ui": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-5.0.1.tgz", + "integrity": "sha512-kqHYMoMN+FMSu1+1TaPqOfeuoZErS6EicFJh8erxWdRz5aNbLAGQfVlB7HaafcUvnHKDiWFtlZETfD7YqmRy8Q==", + "license": "MIT", + "dependencies": { + "@awesome.me/webawesome": "^3.9.0", + "@codemirror/commands": "^6.10.0", + "@codemirror/lang-css": "^6.3.1", + "@codemirror/lang-html": "^6.4.11", + "@codemirror/lang-javascript": "^6.2.5", + "@codemirror/lang-json": "^6.0.2", + "@codemirror/lang-markdown": "^6.3.1", + "@codemirror/lang-xml": "^6.1.0", + "@codemirror/language": "^6.12.3", + "@codemirror/legacy-modes": "^6.5.3", + "@codemirror/state": "^6.6.0", + "@codemirror/view": "^6.43.0", + "@lit/context": "^1.1.6", + "@lit/task": "^1.0.3", + "@noble/curves": "^2.2.0", + "@noble/hashes": "^2.2.0", + "@uiw/codemirror-theme-vscode": "^4.25.10", + "escape-html": "^1.0.3", + "lit": "^3.3.3", + "mime-types": "^3.0.2", + "pane-registry": "5.0.1", + "rdflib": "2.4.1", + "solid-logic": "6.0.0", + "solid-namespace": "^0.5.4", + "uuid": "^14.0.0" + }, + "optionalDependencies": { + "fsevents": "*" + } + }, + "node_modules/profile-pane/node_modules/solid-ui/node_modules/pane-registry": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pane-registry/-/pane-registry-5.0.1.tgz", + "integrity": "sha512-3aeLxm6TnRHfIDoEbpZpNe3Tlm7wWT+ipEpiV6h3cRgxyzmEtrUpS9WB8yJa/VJq0RHXEoaYlLu94fcbuOPnbA==", + "license": "MIT", + "dependencies": { + "rdflib": "2.4.1", + "solid-logic": "6.0.0" + } + }, + "node_modules/profile-pane/node_modules/solid-ui/node_modules/solid-logic": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-6.0.0.tgz", + "integrity": "sha512-irRWnU28Simo2WBhbCgAz4d+QawGJ4zJuiwuBQyObNwuwr4KbDC9evf0CFdnr/PJD8EhLrYT0Fk3nh1eJmQAbA==", + "license": "MIT", + "dependencies": { + "@uvdsl/solid-oidc-client-browser": "^0.2.3", + "solid-namespace": "^0.5.4", + "vite": "^8.0.16", + "vitest": "^4.1.9" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/prop-types": { "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", @@ -9003,9 +9310,9 @@ } }, "node_modules/react": { - "version": "19.3.0", - "resolved": "https://registry.npmjs.org/react/-/react-19.3.0.tgz", - "integrity": "sha512-E8LUcbtBWt20bbl2YoHfx4ZDBdxVTfOKtCZn9cDSJ4l6/nuoApcpIBcj47t2wZoVX8g2ZHuMHbiShgCR1T5Sog==", + "version": "19.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-19.3.1.tgz", + "integrity": "sha512-QNhWdt7nrgVWWQG58QuGsAR3jv3Hbe4mb4vz7w2csnHavciZJgda1CPNaldF6eVxv90ud3jUXpKlHL69gO38yw==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -9018,15 +9325,15 @@ "license": "MIT" }, "node_modules/react-dom": { - "version": "19.3.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.3.0.tgz", - "integrity": "sha512-JDk8dgif51OjFoDE70+OT9ICyYr+69HlmihNwp1+Nsfbna3t5sIiCa9ZJktDmQ4/1b/rn26hIAR2uYXDMr5r0Q==", + "version": "19.3.1", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.3.1.tgz", + "integrity": "sha512-Y0bARz53lhEC1NMCASs0/j+faB/zqt3R8hpvg1e8+61ZVJ4UL0UdC4cBbXfZMcIuhrfgeILTLe+ZeBCavQPtKQ==", "license": "MIT", "dependencies": { "scheduler": "^0.28.0" }, "peerDependencies": { - "react": "^19.3.0" + "react": "^19.3.1" } }, "node_modules/react-is": { @@ -9607,9 +9914,9 @@ "license": "MIT" }, "node_modules/solid-ui": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-5.0.1.tgz", - "integrity": "sha512-kqHYMoMN+FMSu1+1TaPqOfeuoZErS6EicFJh8erxWdRz5aNbLAGQfVlB7HaafcUvnHKDiWFtlZETfD7YqmRy8Q==", + "version": "5.0.2-0", + "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-5.0.2-0.tgz", + "integrity": "sha512-WYJCpmcamXXRBbXqq1VL+gfF86CrE7KhAgmMIEK/KfoWRKzf2mTzDUERdM+sNKCo+5ljGZMH7c0fkqSZliYFBg==", "license": "MIT", "dependencies": { "@awesome.me/webawesome": "^3.9.0", @@ -9632,9 +9939,9 @@ "escape-html": "^1.0.3", "lit": "^3.3.3", "mime-types": "^3.0.2", - "pane-registry": "5.0.1", + "pane-registry": "5.0.2-0", "rdflib": "2.4.1", - "solid-logic": "6.0.0", + "solid-logic": "6.0.1-1", "solid-namespace": "^0.5.4", "uuid": "^14.0.0" }, @@ -9642,35 +9949,10 @@ "fsevents": "*" } }, - "node_modules/solid-ui/node_modules/pane-registry": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/pane-registry/-/pane-registry-5.0.1.tgz", - "integrity": "sha512-3aeLxm6TnRHfIDoEbpZpNe3Tlm7wWT+ipEpiV6h3cRgxyzmEtrUpS9WB8yJa/VJq0RHXEoaYlLu94fcbuOPnbA==", - "license": "MIT", - "dependencies": { - "rdflib": "2.4.1", - "solid-logic": "6.0.0" - } - }, - "node_modules/solid-ui/node_modules/solid-logic": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/solid-logic/-/solid-logic-6.0.0.tgz", - "integrity": "sha512-irRWnU28Simo2WBhbCgAz4d+QawGJ4zJuiwuBQyObNwuwr4KbDC9evf0CFdnr/PJD8EhLrYT0Fk3nh1eJmQAbA==", - "license": "MIT", - "dependencies": { - "@uvdsl/solid-oidc-client-browser": "^0.2.3", - "solid-namespace": "^0.5.4", - "vite": "^8.0.16", - "vitest": "^4.1.9" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/solidos-toolkit": { - "version": "1.0.0-dev.c11da40967c5d278451118142650415d688d8d4c", - "resolved": "https://registry.npmjs.org/solidos-toolkit/-/solidos-toolkit-1.0.0-dev.c11da40967c5d278451118142650415d688d8d4c.tgz", - "integrity": "sha512-i5FOuvpBBbXfYpRKBv4ygdccO5EUUpfo2rp1HoOspG+AOKMVeFqizuPokl+RZX6AVn3AulqRfnlo+NUEWkidEA==", + "version": "1.0.0-dev.2fb6be508170f3b28ca79d738aae71cd48f6d87e", + "resolved": "https://registry.npmjs.org/solidos-toolkit/-/solidos-toolkit-1.0.0-dev.2fb6be508170f3b28ca79d738aae71cd48f6d87e.tgz", + "integrity": "sha512-EQMddD3jV0YiPdPuEfBTRc1+QynYiIBwxMs8e3+F/gEP0lfIvSUjFSXCYsJxQxY8rqsEb4YXR4JW/5b1JRtdTQ==", "dev": true, "dependencies": { "@babel/core": "^7.29.0", @@ -9692,7 +9974,7 @@ "pane-registry": "^3.1.1 || ^3.1.2-0 || >=5.0.2-0 <6.0.0", "rdflib": "^2.3.6", "solid-logic": "^4.0.7 || ^4.0.8-0 || >=6.0.1-0 <7.0.0", - "solid-ui": "^3.1.2 || ^3.1.3-0 || >=5.0.1-0 <6.0.0", + "solid-ui": "^3.1.2 || ^3.1.3-0 || >=5.0.1-0 <6.0.0 || ^5.0.2-0", "vite": "^8.0.0", "vitest": "^4.0.0" }, @@ -9769,6 +10051,42 @@ "node": ">=18" } }, + "node_modules/source-pane/node_modules/solid-ui": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/solid-ui/-/solid-ui-5.0.1.tgz", + "integrity": "sha512-kqHYMoMN+FMSu1+1TaPqOfeuoZErS6EicFJh8erxWdRz5aNbLAGQfVlB7HaafcUvnHKDiWFtlZETfD7YqmRy8Q==", + "license": "MIT", + "dependencies": { + "@awesome.me/webawesome": "^3.9.0", + "@codemirror/commands": "^6.10.0", + "@codemirror/lang-css": "^6.3.1", + "@codemirror/lang-html": "^6.4.11", + "@codemirror/lang-javascript": "^6.2.5", + "@codemirror/lang-json": "^6.0.2", + "@codemirror/lang-markdown": "^6.3.1", + "@codemirror/lang-xml": "^6.1.0", + "@codemirror/language": "^6.12.3", + "@codemirror/legacy-modes": "^6.5.3", + "@codemirror/state": "^6.6.0", + "@codemirror/view": "^6.43.0", + "@lit/context": "^1.1.6", + "@lit/task": "^1.0.3", + "@noble/curves": "^2.2.0", + "@noble/hashes": "^2.2.0", + "@uiw/codemirror-theme-vscode": "^4.25.10", + "escape-html": "^1.0.3", + "lit": "^3.3.3", + "mime-types": "^3.0.2", + "pane-registry": "5.0.1", + "rdflib": "2.4.1", + "solid-logic": "6.0.0", + "solid-namespace": "^0.5.4", + "uuid": "^14.0.0" + }, + "optionalDependencies": { + "fsevents": "*" + } + }, "node_modules/stackback": { "version": "0.0.2", "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", @@ -10084,22 +10402,22 @@ } }, "node_modules/tldts": { - "version": "7.4.18", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.18.tgz", - "integrity": "sha512-somxA8xKAUzlAxl0TX/jMSYIbRNFIVGnI96pVGJPeMc5BsHmfVXn6mOJT6U++ELnl04eGfzpfcEuZe8WiASkXg==", + "version": "7.4.19", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.4.19.tgz", + "integrity": "sha512-48dH6aSpQnpbzDUc4vIQZ1VjB8tkK+e8c1yx05/SZK+rkssgjEOlxDd/yU8/a4vGYQ9vRgJr9dwMq9TJ0b3X2Q==", "devOptional": true, "license": "MIT", "dependencies": { - "tldts-core": "^7.4.18" + "tldts-core": "^7.4.19" }, "bin": { "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { - "version": "7.4.18", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.18.tgz", - "integrity": "sha512-KI2PKvCmvQI/xD6ypPqkU0i7oxNXR/O58RLRaHR4svsgVUQ2JE/XC8BtMbG6PSehD27I8sZJRcC1ASnCy6lp3g==", + "version": "7.4.19", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.4.19.tgz", + "integrity": "sha512-goNXV6Ho9TIOfpJZanTd6CKG5DyYgYAL+k+22T0SLh8l6+KHIfBUPFuePuSZv05UttIaaLmI9tb7TmGIdK5AkQ==", "devOptional": true, "license": "MIT" }, @@ -10288,16 +10606,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.71.2", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.71.2.tgz", - "integrity": "sha512-Rz4effbMy2g9wnvOJZG6SbVavX313Lap1vNEbk1RUochzickvzP8P4HB+bkNg5e50eVz1hQGjh9K1omI1xB4Bw==", + "version": "8.72.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.72.0.tgz", + "integrity": "sha512-r26Fkc8As+mZvqp7SLsMmNFyYUup/6CjK7/eHBHmhOw6GH6n6YFxHVFrG0jN1c5CMpDzelLPxvgeCOzx7BjN+A==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.71.2", - "@typescript-eslint/parser": "8.71.2", - "@typescript-eslint/typescript-estree": "8.71.2", - "@typescript-eslint/utils": "8.71.2" + "@typescript-eslint/eslint-plugin": "8.72.0", + "@typescript-eslint/parser": "8.72.0", + "@typescript-eslint/typescript-estree": "8.72.0", + "@typescript-eslint/utils": "8.72.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10338,9 +10656,9 @@ } }, "node_modules/undici": { - "version": "7.30.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.30.0.tgz", - "integrity": "sha512-dkrQXeHSaoamnItlYbmzG0wFYrM0ZwDxCIg0A7aKjTyyhh9svRzCNFEzV+Vm05/yehjCzjDZ31KXfGEjYSztDQ==", + "version": "7.30.1", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.30.1.tgz", + "integrity": "sha512-03KrMbjIFDWQR5RNPrSw3bd1r12JpyFQl9/yxjUbJtqkjmllqC5lFjZh6ujeuJCKr8EOQvRW872Oy/az+nLYxg==", "devOptional": true, "license": "MIT", "engines": { @@ -10687,18 +11005,18 @@ } }, "node_modules/vitest": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.11.tgz", - "integrity": "sha512-fhACrNXUidIbGSBr5FlbuBkO7VWC1ZyLl0DO4CU2DrQoAPxX84Ysxs+HeGQpii5lZWV1Q4gBZTTu49mF+A6Edw==", - "license": "MIT", - "dependencies": { - "@vitest/expect": "4.1.11", - "@vitest/mocker": "4.1.11", - "@vitest/pretty-format": "4.1.11", - "@vitest/runner": "4.1.11", - "@vitest/snapshot": "4.1.11", - "@vitest/spy": "4.1.11", - "@vitest/utils": "4.1.11", + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.12.tgz", + "integrity": "sha512-5eWdz2yb3ajxWF3C8C4TjkXl7FGm3n2E/VlazALrQHzK7nYMSGFnCZto0bbPNl77AwkOZVLk0YnBAejUu0NiWA==", + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.1.12", + "@vitest/mocker": "4.1.12", + "@vitest/pretty-format": "4.1.12", + "@vitest/runner": "4.1.12", + "@vitest/snapshot": "4.1.12", + "@vitest/spy": "4.1.12", + "@vitest/utils": "4.1.12", "es-module-lexer": "^2.0.0", "expect-type": "^1.3.0", "magic-string": "^0.30.21", @@ -10726,12 +11044,12 @@ "@edge-runtime/vm": "*", "@opentelemetry/api": "^1.9.0", "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", - "@vitest/browser-playwright": "4.1.11", - "@vitest/browser-preview": "4.1.11", - "@vitest/browser-webdriverio": "4.1.11", - "@vitest/coverage-istanbul": "4.1.11", - "@vitest/coverage-v8": "4.1.11", - "@vitest/ui": "4.1.11", + "@vitest/browser-playwright": "4.1.12", + "@vitest/browser-preview": "4.1.12", + "@vitest/browser-webdriverio": "^4.1.11", + "@vitest/coverage-istanbul": "4.1.12", + "@vitest/coverage-v8": "4.1.12", + "@vitest/ui": "4.1.12", "happy-dom": "*", "jsdom": "*", "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" diff --git a/package.json b/package.json index 1da91f28..f162262f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "solid-panes", - "version": "5.1.0-0", + "version": "5.1.0-1", "description": "Solid-compatible Panes: applets and views for the mashlib and databrowser", "main": "dist/index.cjs.js", "types": "dist/index.d.ts", @@ -73,7 +73,7 @@ "rdflib": "2.4.1", "solid-logic": "6.0.1-1", "solid-namespace": "^0.5.4", - "solid-ui": "5.0.1", + "solid-ui": "5.0.2-0", "source-pane": "4.0.0" }, "overrides": { diff --git a/src/social/socialPane.css b/src/social/socialPane.css index bdb316e2..df532952 100644 --- a/src/social/socialPane.css +++ b/src/social/socialPane.css @@ -48,17 +48,6 @@ flex-wrap: wrap; } -.social-pane__header-actions--friend { - justify-content: center; -} - -.social-pane__header-actions--friend > solid-ui-button { - margin-inline: auto; - --button-border-radius: var(--border-radius-md, 0.5rem); - --button-hover-text: var(--color-primary, #7C4DFF); - --button-hover-border: var(--color-primary, #7C4DFF); -} - .social-pane__header-summary { display: flex; flex-direction: column; @@ -775,10 +764,53 @@ } .social-pane .social-friends-list { - width: 100%; + width: 99%; margin-top: 0; } +.social-pane__all-friends .social-friends-list { + border-collapse: collapse; +} + +.social-pane .social-friends-list-surface { + width: 100%; + padding: 12px; + height: 6rem; + vertical-align: top; +} + +.social-pane .social-friends-drop-hint { + margin: 0 0 12px; + color: var(--solid-ui-color-gray-600, #4a5565); + font-size: var(--solid-ui-font-size-sm, 0.875rem); + line-height: 1.4; +} + +.social-pane .social-pane__all-friends { + position: relative; +} + +.social-pane .social-friends-delete-confirmation:not(:empty) { + position: absolute; + inset: 0; + z-index: 10; + display: grid; + place-items: center; + padding: 12px; + pointer-events: none; +} + +.social-pane .social-friends-delete-confirmation > div { + width: max-content; + max-width: 100%; + pointer-events: auto; +} + +.social-pane .social-friends-delete-confirmation > div > div { + max-width: 100%; + box-sizing: border-box; +} + .social-pane .social-friends-grid { display: flex; flex-wrap: wrap; @@ -788,6 +820,7 @@ border-collapse: separate; border-spacing: 0; gap: var(--spacing-xs, 0.75rem); + margin: 5px; } .social-pane .social-friends-grid > tbody { @@ -812,7 +845,7 @@ border: 1px solid var(--gray-200, #E5E7EB); background: var(--white, #fff); border-radius: var(--border-radius-lg, 0.75rem); - overflow: visible; + overflow: clip; box-shadow: 0 1px 3px rgb(0 0 0 / 0.08); transition: box-shadow 140ms ease, border-color 140ms ease, transform 140ms ease; } @@ -847,6 +880,13 @@ vertical-align: top; } +.social-pane__all-friends .social-friends-grid > tr > td:nth-child(3) > a, +.social-pane__all-friends .social-friends-grid > tbody > tr > td:nth-child(3) > a { + float: right; + clear: right; + line-height: 0; +} + .social-pane .social-friends-grid > tr > td:first-child, .social-pane .social-friends-grid > tbody > tr > td:first-child { padding-right: 1.2rem; @@ -927,71 +967,6 @@ } } -.social-pane .social-friends-header { - display: flex; - align-items: center; - justify-content: space-between; - padding: 0 var(--spacing-xs, 0.75rem) var(--spacing-base, 0.5rem); - background-color: var(--gray-100, #F3F4F6); - caption-side: top; - margin-top: 0; -} - -.social-pane .social-friends-header-title { - font-size: var(--font-size-md, 1rem); - font-weight: var(--font-weight-bold, 600); - color: var(--color-text-primary, #364153); -} - -.social-pane .social-friends-header-actions { - display: inline-flex; - align-items: center; - justify-content: flex-end; -} - -.social-pane .social-friends-header-actions--standalone { - display: flex; - align-items: center; - gap: var(--spacing-xs, 0.75rem); - justify-content: flex-start; - padding: 0.7rem 1rem 0; -} - -.social-pane .social-friends-header-dropzone { - border-collapse: collapse; -} - -.social-pane .social-friends-header-dropzone-cell { - padding: 0; -} - -.social-pane .social-friends-header-hint { - color: var(--color-text-secondary, #4A5565); - font-size: var(--font-size-sm, 0.875rem); - line-height: 1.4; -} - -.social-pane .social-friends-header-actions button { - display: inline-flex; - align-items: center; - justify-content: center; - width: 2rem !important; - min-width: 2rem !important; - height: 2rem !important; - padding: 0 !important; - margin: 0 !important; - border-width: 0 !important; - overflow: hidden; -} - -.social-pane .social-friends-header-actions button img { - display: block; - width: 100% !important; - height: 100% !important; - object-fit: contain; - pointer-events: none; -} - /* From tabbedtab.css */ /* ***************** Social Pane **********/ @@ -1075,16 +1050,6 @@ margin-left: 0; } -:is(.social-pane-host, .social-pane)[data-layout='mobile'] .social-pane__header-actions--friend { - grid-column: 1 / -1; - grid-row: 3; - justify-self: stretch; - justify-content: center; - width: 100%; - margin-left: 0; - margin-top: 0.125rem; -} - :is(.social-pane-host, .social-pane)[data-layout='mobile'] .social-pane__header-summary { display: flex; flex-direction: column; @@ -1221,12 +1186,6 @@ line-height: var(--line-height-base, 1.5); } -:is(.social-pane-host, .social-pane)[data-layout='mobile'] .social-pane .social-friends-header-actions--standalone { - flex-wrap: wrap; - gap: var(--spacing-2xs, 0.625rem); - padding-top: 0.35rem; -} - :is(.social-pane-host, .social-pane)[data-layout='mobile'] :is(.social-pane .social-layout, .social-pane .social-primary, .social-layout, .social-primary) { display: block; } @@ -1278,16 +1237,6 @@ margin-left: 0; } - .social-pane__header-actions--friend { - grid-column: 1 / -1; - grid-row: 3; - justify-self: stretch; - justify-content: center; - width: 100%; - margin-left: 0; - margin-top: 0.125rem; - } - .social-pane__header-summary { display: flex; flex-direction: column; @@ -1438,12 +1387,6 @@ line-height: var(--line-height-base, 1.5); } - .social-pane .social-friends-header-actions--standalone { - flex-wrap: wrap; - gap: var(--spacing-2xs, 0.625rem); - padding-top: 0.35rem; - } - .social-pane .social-layout, .social-pane .social-primary { display: block; diff --git a/src/social/socialSections.ts b/src/social/socialSections.ts index 17cc8b88..c16810b5 100644 --- a/src/social/socialSections.ts +++ b/src/social/socialSections.ts @@ -9,8 +9,7 @@ import type { ViewerMode } from '../types' export type HeaderControls = { canEdit: boolean, - viewerMode: ViewerMode, - showAddFriendAction?: boolean + viewerMode: ViewerMode } export type SocialHeaderElement = HTMLElement & { @@ -64,22 +63,6 @@ export function createHeaderSection ( if (headerControls.canEdit) { // Hidden for now because the social pane header edit control does not match the new design. // Revisit later if we decide to restore profile-link editing here. - } else if (headerControls.viewerMode === 'authenticated' && headerControls.showAddFriendAction) { - headerActions.classList.add('social-pane__header-actions--friend') - - const friendDropButton = dom.createElement('button') - friendDropButton.setAttribute('title', 'Drop friend here') - friendDropButton.setAttribute('aria-label', 'Drop friend here') - const buttonImage = dom.createElement('img') - buttonImage.setAttribute('title', 'Drop friend here') - buttonImage.setAttribute('alt', 'Drop friend here') - friendDropButton.appendChild(buttonImage) - - const dropHint = dom.createElement('span') - dropHint.className = 'social-friends-header-hint' - dropHint.textContent = 'Drag a WebId on the target to add a friend.' - friendDropButton.appendChild(dropHint) - headerActions.appendChild(friendDropButton) } // const addToFriendsButton = createAddMeToYourFriendsButton(subject, context) @@ -377,6 +360,9 @@ export function createAllFriendsSection (options: { allFriends.setAttribute('role', 'tabpanel') allFriends.setAttribute('aria-labelledby', 'social-tab-all-friends') + const confirmationContainer = allFriends.appendChild(dom.createElement('div')) + confirmationContainer.className = 'social-friends-delete-confirmation' + const mainTable = allFriends.appendChild(dom.createElement('table')) mainTable.className = 'social-main' @@ -385,6 +371,7 @@ export function createAllFriendsSection (options: { modify: !!editable, predicate: ns.foaf('knows'), noun: 'friend', + confirmationContainer, // Social pane already owns the async refresh cycle for friend data in // socialPane.ts. Leave attachmentList's generic follow-up rerender disabled // here or each fetched friend profile will trigger an extra whole-table refresh @@ -396,30 +383,20 @@ export function createAllFriendsSection (options: { friendsList.classList.add('social-friends-list') friendsList.style.marginTop = '0' - const friendsListRow = friendsList.querySelector('tr') - const friendsListPromptCell = friendsListRow?.children?.[0] - const friendsListRightCell = friendsListRow?.children?.[1] - const friendsHeaderActions = dom.createElement('div') - friendsHeaderActions.classList.add('social-friends-header-actions') - - if (friendsListPromptCell instanceof HTMLTableCellElement) { - friendsListPromptCell.classList.add('social-friends-header-dropzone-cell') - const friendsHeaderDropzone = dom.createElement('table') - friendsHeaderDropzone.className = 'social-friends-header-dropzone' - friendsHeaderDropzone.setAttribute('role', 'presentation') - const friendsHeaderDropzoneBody = friendsHeaderDropzone.appendChild(dom.createElement('tbody')) - const friendsHeaderDropzoneRow = friendsHeaderDropzoneBody.appendChild(dom.createElement('tr')) - friendsHeaderDropzoneRow.appendChild(friendsListPromptCell) - friendsHeaderActions.appendChild(friendsHeaderDropzone) - } else if (friendsListPromptCell instanceof HTMLElement) { - while (friendsListPromptCell.firstChild) { - friendsHeaderActions.appendChild(friendsListPromptCell.firstChild) - } - friendsListPromptCell.remove() - } - - if (friendsListRightCell instanceof HTMLTableCellElement) { - friendsListRightCell.colSpan = 2 + const friendsListRow = friendsList.rows[0] + const dropCell = friendsListRow.cells[0] + const itemsCell = friendsListRow.cells[1] + // Keep attachmentList's wired drop cell and move the grid into it, so drops + // anywhere in the list use the widget's existing save and refresh handlers. + dropCell.replaceChildren(...Array.from(itemsCell.childNodes)) + dropCell.classList.add('social-friends-list-surface') + itemsCell.remove() + + if (editable) { + const hint = dom.createElement('p') + hint.className = 'social-friends-drop-hint' + hint.textContent = 'Drop a WebID anywhere here to add a friend.' + dropCell.prepend(hint) } const friendsItemsTable = friendsList.querySelector('td table') diff --git a/test/unit/social/socialSections.test.ts b/test/unit/social/socialSections.test.ts new file mode 100644 index 00000000..9155b62b --- /dev/null +++ b/test/unit/social/socialSections.test.ts @@ -0,0 +1,204 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import { readFileSync } from 'node:fs' +import { sym } from 'rdflib' +import { store } from 'solid-logic' +import { ns } from 'solid-ui' +import { createAllFriendsSection } from '../../../src/social/socialSections' + +vi.mock('../../../src/social/editProfileDetails', () => ({ + appendProfileLinks: vi.fn() +})) + +const subject = sym('https://friends-test.example/profile/card#me') +const profile = subject.doc() +const firstFriend = sym('https://first-friend.example/profile/card#me') +const secondFriend = sym('https://second-friend.example/profile/card#me') + +function createList (editable = true) { + const result = createAllFriendsSection({ + dom: document, + subject, + profile: editable ? profile : null, + editable, + renderSupportingInfo: () => null, + renderNameSuffix: () => null + }) + document.body.appendChild(result.section) + return result +} + +function drop (target: Element, text: string, type = 'text/uri-list') { + const event = new Event('drop', { bubbles: true, cancelable: true }) + Object.defineProperty(event, 'dataTransfer', { + value: { + types: [type], + getData: () => text, + dropEffect: 'copy' + } + }) + target.dispatchEvent(event) + return event +} + +describe('friends list drop surface', () => { + beforeEach(() => { + vi.spyOn(store.updater, 'update').mockImplementation((deletions, insertions, callback) => { + const removed = Array.isArray(deletions) ? deletions : [deletions] + removed.forEach(statement => store.removeStatement(statement)) + const statements = Array.isArray(insertions) ? insertions : [insertions] + statements.forEach(statement => store.add(statement)) + callback?.(profile.value, true, '') + }) + }) + + afterEach(() => { + store.removeMatches(subject, null, null) + document.body.replaceChildren() + vi.restoreAllMocks() + }) + + it('adds a friend when dropped onto the empty list surface', () => { + const { friendsList } = createList() + const surface = friendsList.querySelector('.social-friends-list-surface')! + expect(surface).toBeVisible() + expect(friendsList.querySelector('button[title="Drop attachments here"]')).toBeNull() + + const event = drop(surface, firstFriend.value) + + expect(event.defaultPrevented).toBe(true) + expect(store.updater.update).toHaveBeenCalledTimes(1) + expect(store.holds(subject, ns.foaf('knows'), firstFriend, profile)).toBe(true) + expect(friendsList.querySelector(`a[href="${firstFriend.value}"]`)).not.toBeNull() + }) + + it('accepts drops onto existing cards and keeps working after refresh', () => { + store.add(subject, ns.foaf('knows'), firstFriend, profile) + const { friendsList } = createList() + const card = friendsList.querySelector(`a[href="${firstFriend.value}"]`)!.closest('tr')! + + drop(card.querySelector('a')!, secondFriend.value) + + expect(store.updater.update).toHaveBeenCalledTimes(1) + expect(store.holds(subject, ns.foaf('knows'), secondFriend, profile)).toBe(true) + const refreshedCard = friendsList.querySelector(`a[href="${secondFriend.value}"]`)!.closest('tr')! + expect(refreshedCard).not.toBeNull() + expect(refreshedCard.querySelector('[title="Remove this friend"]')).not.toBeNull() + drop(refreshedCard, firstFriend.value) + expect(store.updater.update).toHaveBeenCalledTimes(2) + }) + + it('accepts multiple WebIDs and ignores URI-list comments', () => { + const { friendsList } = createList() + drop(friendsList.querySelector('.social-friends-drop-hint')!, + `# Friends\r\n${firstFriend.value}\r\n${secondFriend.value}\r\n`) + + expect(store.updater.update).toHaveBeenCalledTimes(1) + expect(store.each(subject, ns.foaf('knows'))).toHaveLength(2) + }) + + it('accepts a WebID dragged as plain text', () => { + const { friendsList } = createList() + drop(friendsList.querySelector('.social-friends-list-surface')!, + firstFriend.value, 'text/plain') + + expect(store.holds(subject, ns.foaf('knows'), firstFriend, profile)).toBe(true) + }) + + it('does not enable drops or show editable controls on read-only lists', () => { + store.add(subject, ns.foaf('knows'), firstFriend, profile) + const { friendsList } = createList(false) + expect(friendsList.querySelector('.social-friends-drop-hint')).toBeNull() + expect(friendsList.querySelector('button')).toBeNull() + expect(friendsList.querySelector('[title="Remove this friend"]')).toBeNull() + const event = drop(friendsList.querySelector('.social-friends-list-surface')!, + secondFriend.value) + + expect(event.defaultPrevented).toBe(false) + expect(store.updater.update).not.toHaveBeenCalled() + expect(store.holds(subject, ns.foaf('knows'), secondFriend)).toBe(false) + }) + + it('sizes and right-aligns the navigation icon like the remove icon only in all friends', () => { + store.add(subject, ns.foaf('knows'), firstFriend, profile) + const { section, friendsList } = createList() + const style = document.createElement('style') + style.textContent = readFileSync('src/social/socialPane.css', 'utf8') + document.body.appendChild(style) + const link = friendsList.querySelector(`a[href="${firstFriend.value}"]`)! + const image = link.querySelector('icon-lucide-square-arrow-out-up-right')! + const remove = friendsList.querySelector('[title="Remove this friend"]')! + + expect(getComputedStyle(image).width).toBe(getComputedStyle(remove).width) + expect(getComputedStyle(image).height).toBe(getComputedStyle(remove).height) + expect(getComputedStyle(image).margin).toBe(getComputedStyle(remove).margin) + expect(getComputedStyle(link).float).toBe(getComputedStyle(remove).float) + expect(getComputedStyle(link).clear).toBe('right') + expect(link.querySelector('img')).toBeNull() + expect(link.getAttribute('aria-label')).toBe('Open resource') + expect(getComputedStyle(image).color).toBe('var(--color-text-secondary, #4A5565)') + + section.classList.remove('social-pane__all-friends') + expect(getComputedStyle(image).margin).toBe('0.2em') + expect(getComputedStyle(link).float).not.toBe('right') + }) + + it('renders shared Lucide icons immediately after attachmentList refreshes its rows', () => { + const { friendsList } = createList() + drop(friendsList.querySelector('.social-friends-list-surface')!, firstFriend.value) + + const link = friendsList.querySelector(`a[href="${firstFriend.value}"]`)! + expect(link.querySelector('icon-lucide-square-arrow-out-up-right')).not.toBeNull() + expect(link.querySelector('img')).toBeNull() + }) + + it('shows confirmation outside a single friend card and cancels without deleting', () => { + store.add(subject, ns.foaf('knows'), firstFriend, profile) + const { section, friendsList } = createList() + const pane = document.body.appendChild(document.createElement('div')) + pane.className = 'social-pane' + pane.appendChild(section) + const style = document.createElement('style') + style.textContent = readFileSync('src/social/socialPane.css', 'utf8') + document.body.appendChild(style) + friendsList.querySelector('[title="Remove this friend"]')!.click() + + const confirmation = section.querySelector('[role="dialog"]')! + expect(confirmation.parentElement).toBe(section.querySelector('.social-friends-delete-confirmation')) + expect(friendsList.contains(confirmation)).toBe(false) + expect(confirmation.closest('.social-friends-grid')).toBeNull() + const overlay = confirmation.parentElement! + expect(getComputedStyle(section).position).toBe('relative') + expect(getComputedStyle(overlay).position).toBe('absolute') + expect(getComputedStyle(overlay).inset).toBe('0px') + expect(getComputedStyle(overlay).placeItems).toBe('center') + expect(getComputedStyle(overlay).zIndex).toBe('10') + expect(getComputedStyle(confirmation).width).toBe('max-content') + expect(getComputedStyle(confirmation).pointerEvents).toBe('auto') + const cancel = Array.from(confirmation.querySelectorAll('button')) + .find(button => button.textContent === 'Cancel')! + expect(document.activeElement).toBe(cancel) + cancel.click() + + expect(section.querySelector('[role="dialog"]')).toBeNull() + expect(store.updater.update).not.toHaveBeenCalled() + expect(store.holds(subject, ns.foaf('knows'), firstFriend, profile)).toBe(true) + }) + + it('confirms removal of the last friend using the original widget handler', () => { + store.add(subject, ns.foaf('knows'), firstFriend, profile) + const { section, friendsList } = createList() + const remove = friendsList.querySelector('[title="Remove this friend"]')! + remove.click() + remove.click() + expect(section.querySelectorAll('[role="dialog"]')).toHaveLength(1) + const confirmation = section.querySelector('[role="dialog"]')! + Array.from(confirmation.querySelectorAll('button')) + .find(button => button.textContent === 'Remove this friend')!.click() + + expect(store.updater.update).toHaveBeenCalledTimes(1) + expect(store.holds(subject, ns.foaf('knows'), firstFriend, profile)).toBe(false) + expect(friendsList.querySelector(`a[href="${firstFriend.value}"]`)).toBeNull() + expect(section.querySelector('[role="dialog"]')).toBeNull() + expect(friendsList.querySelector('.social-friends-drop-hint')).not.toBeNull() + }) +})